diff --git a/src/generators/dom/visitors/Component.js b/src/generators/dom/visitors/Component.js index 05ea49fad1..ff67eb475f 100644 --- a/src/generators/dom/visitors/Component.js +++ b/src/generators/dom/visitors/Component.js @@ -49,7 +49,7 @@ export default { const statements = []; - if ( local.staticAttributes.length || local.dynamicAttributes.length || local.bindings.length ) { + if ( local.staticAttributes.length || local.dynamicAttributes.length || local.spreadAttributes.length || local.bindings.length ) { const initialProps = local.staticAttributes .concat( local.dynamicAttributes ) .map( attribute => `${attribute.name}: ${attribute.value}` ); @@ -73,7 +73,14 @@ export default { statements.push( bindings.join( '\n' ) ); } - componentInitProperties.push(`data: ${name}_initialData`); + + if ( local.spreadAttributes.length ) { + local.spreadAttributes.forEach( name => { + statements.push( `Object.assign( ${local.name}_initialData, root.${name} );` ); + }); + } + + componentInitProperties.push( `data: ${name}_initialData` ); } local.init.addBlockAtStart( deindent` diff --git a/src/generators/dom/visitors/attributes/addComponentAttributes.js b/src/generators/dom/visitors/attributes/addComponentAttributes.js index e3471c6d37..34f74bc85c 100644 --- a/src/generators/dom/visitors/attributes/addComponentAttributes.js +++ b/src/generators/dom/visitors/attributes/addComponentAttributes.js @@ -4,6 +4,7 @@ import deindent from '../../../../utils/deindent.js'; export default function addComponentAttributes ( generator, node, local ) { local.staticAttributes = []; local.dynamicAttributes = []; + local.spreadAttributes = []; local.bindings = []; node.attributes.forEach( attribute => { @@ -127,6 +128,11 @@ export default function addComponentAttributes ( generator, node, local ) { ` ); } + else if ( attribute.type === 'Spread' ) { + local.spreadAttributes.push( attribute.name ); + local.update.addLine( `${local.name}.set( root.${attribute.name} );` ); + } + else { throw new Error( `Not implemented: ${attribute.type}` ); } diff --git a/src/generators/dom/visitors/attributes/addElementAttributes.js b/src/generators/dom/visitors/attributes/addElementAttributes.js index 36869a202f..45a66e6419 100644 --- a/src/generators/dom/visitors/attributes/addElementAttributes.js +++ b/src/generators/dom/visitors/attributes/addElementAttributes.js @@ -221,7 +221,10 @@ export default function addElementAttributes ( generator, node, local ) { // we have to include setXLinkAttibute and setAttribute because the data is dynamic // we have no idea at compile time what is being used - local.init.addLine( `spreadAttributes( ${local.name}, root.${name} );` ); + const statement = `spreadAttributes( ${local.name}, root.${name} );`; + + local.init.addLine( statement ); + local.update.addLine( statement ); } else { diff --git a/src/generators/server-side-rendering/visitors/Element.js b/src/generators/server-side-rendering/visitors/Element.js index e9adec7e4e..d7828fea99 100644 --- a/src/generators/server-side-rendering/visitors/Element.js +++ b/src/generators/server-side-rendering/visitors/Element.js @@ -15,6 +15,7 @@ export default { openingTag += ` \${Object.keys( root.${attribute.name} ).map( prop => \`\${prop}="\${root.${attribute.name}[prop]}"\` ).join( ' ' )}`; return; } + if ( attribute.type !== 'Attribute' ) return; let str = ` ${attribute.name}`; diff --git a/test/generator/attribute-spread/_config.js b/test/generator/attribute-spread/_config.js index c9c42a1e3a..849ccdb406 100644 --- a/test/generator/attribute-spread/_config.js +++ b/test/generator/attribute-spread/_config.js @@ -1,3 +1,15 @@ export default { html: '', + + test ( assert, component, target ) { + component.set({ + options: { + type: 'text', + value: 'changed' + } + }); + + assert.htmlEqual( target.innerHTML, `` ); + component.teardown(); + } }; diff --git a/test/generator/attribute-spread/main.html b/test/generator/attribute-spread/main.html index eabb52e0a8..48d2bdec24 100644 --- a/test/generator/attribute-spread/main.html +++ b/test/generator/attribute-spread/main.html @@ -4,8 +4,8 @@ export default { data: () => ({ options: { - type: 'text', - value: 'Hello World' + type: 'text', + value: 'Hello World' } }) }; diff --git a/test/generator/component-attribute-spread/Widget.html b/test/generator/component-attribute-spread/Widget.html index d767d2c07a..6821108309 100644 --- a/test/generator/component-attribute-spread/Widget.html +++ b/test/generator/component-attribute-spread/Widget.html @@ -1 +1,2 @@ - +

foo: {{foo}}

+

bar: {{bar}}

diff --git a/test/generator/component-attribute-spread/_config.js b/test/generator/component-attribute-spread/_config.js index c9c42a1e3a..b15a0b935d 100644 --- a/test/generator/component-attribute-spread/_config.js +++ b/test/generator/component-attribute-spread/_config.js @@ -1,3 +1,22 @@ export default { - html: '', + html: ` +

foo: 1

+

bar: 2

+ `, + + test ( assert, component, target ) { + component.set({ + options: { + foo: 3, + bar: 4 + } + }); + + assert.equal( component.refs.widget.get( 'foo' ), 3 ); + assert.htmlEqual( target.innerHTML, ` +

foo: 3

+

bar: 4

+ ` ); + component.teardown(); + } }; diff --git a/test/generator/component-attribute-spread/main.html b/test/generator/component-attribute-spread/main.html index 946a1c4cf5..98ef2bcaef 100644 --- a/test/generator/component-attribute-spread/main.html +++ b/test/generator/component-attribute-spread/main.html @@ -1,4 +1,4 @@ - +