diff --git a/src/dom_components/model/Component.js b/src/dom_components/model/Component.js index e2336dc7a..c8b856a90 100644 --- a/src/dom_components/model/Component.js +++ b/src/dom_components/model/Component.js @@ -115,6 +115,23 @@ module.exports = Backbone.Model.extend(Styleable).extend({ initialize(props = {}, opt = {}) { const em = opt.sm || opt.em || {}; + // Propagate properties from parent if indicated + const parent = this.parent(); + const parentAttr = parent && parent.attributes; + + if (parentAttr && parentAttr.propagate) { + let newAttr = {}; + const toPropagate = parentAttr.propagate; + toPropagate.forEach(prop => newAttr[prop] = parent.get(prop)); + newAttr.propagate = toPropagate; + newAttr = {...newAttr, ...props}; + this.set(newAttr); + } + + const propagate = this.get('propagate'); + propagate && this.set('propagate', isArray(propagate) ? propagate : [propagate]); + + // Check void elements if(opt && opt.config && opt.config.voidElements.indexOf(this.get('tagName')) >= 0) { @@ -145,8 +162,6 @@ module.exports = Backbone.Model.extend(Styleable).extend({ }, this); this.set('status', ''); - const propagate = this.get('propagate'); - propagate && this.set('propagate', isArray(propagate) ? propagate : [propagate]); this.init(); }, @@ -223,8 +238,11 @@ module.exports = Backbone.Model.extend(Styleable).extend({ initComponents() { - let comps = new Components(this.get('components'), this.opt); + // Have to add components after the init, otherwise the parent + // is not visible + const comps = new Components(null, this.opt); comps.parent = this; + comps.reset(this.get('components')); this.set('components', comps); return this; }, @@ -279,6 +297,16 @@ module.exports = Backbone.Model.extend(Styleable).extend({ }, + /** + * Get parent model + * @return {Component} + */ + parent() { + const coll = this.collection; + return coll && coll.parent; + }, + + /** * Script updated */ diff --git a/src/dom_components/model/Components.js b/src/dom_components/model/Components.js index 736871202..af22b929e 100644 --- a/src/dom_components/model/Components.js +++ b/src/dom_components/model/Components.js @@ -18,6 +18,9 @@ module.exports = Backbone.Collection.extend({ if(!options.sm && opt && opt.sm) options.sm = opt.sm; + if(!options.em && opt && opt.em) + options.em = opt.em; + if(opt && opt.config) options.config = opt.config; diff --git a/test/specs/dom_components/model/Component.js b/test/specs/dom_components/model/Component.js index cf7b0585d..c0c57a787 100644 --- a/test/specs/dom_components/model/Component.js +++ b/test/specs/dom_components/model/Component.js @@ -216,15 +216,57 @@ module.exports = { }); - it.only('Propagate properties to children', () => { + it('Propagate properties to children', () => { obj.append({propagate: 'removable'}); const result = obj.components(); const newObj = result.models[0]; expect(newObj.get('removable')).toEqual(true); newObj.set('removable', false); - newObj.append({}); + newObj.append({draggable: false}); const child = newObj.components().models[0]; expect(child.get('removable')).toEqual(false); + expect(child.get('propagate')).toEqual(['removable']); + }); + + it('Ability to stop/change propagation chain', () => { + obj.append({ + removable: false, + draggable: false, + propagate: ['removable', 'draggable'] + }); + const result = obj.components(); + const newObj = result.models[0]; + newObj.components(` +
+
comp1
+
+
comp21
+
comp22
+
+
+
comp31
+
comp32
+
+
+
TEST
`); + const notInhereted = model => { + expect(model.get('stop')).toEqual(1); + expect(model.get('removable')).toEqual(true); + expect(model.get('draggable')).toEqual(true); + expect(model.get('propagate')).toEqual(['stop']); + model.components().each(model => inhereted(model)) + }; + const inhereted = model => { + if (model.get('stop')) { + notInhereted(model); + } else { + expect(model.get('removable')).toEqual(false); + expect(model.get('draggable')).toEqual(false); + expect(model.get('propagate')).toEqual(['removable', 'draggable']); + model.components().each(model => inhereted(model)) + } + } + newObj.components().each(model => inhereted(model)) }); });