pull/280/merge
Paul Sauve 9 years ago committed by GitHub
commit e345937d3e

@ -79,7 +79,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}` );
@ -101,6 +101,13 @@ export default {
statements.push( bindings.join( '\n' ) );
}
if ( local.spreadAttributes.length ) {
local.spreadAttributes.forEach( name => {
statements.push( `Object.assign( ${local.name}_initialData, root.${name} );` );
});
}
componentInitProperties.push( `data: ${name}_initialData` );
}

@ -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}` );
}

@ -22,7 +22,6 @@ export default function addElementAttributes ( generator, node, local ) {
// namespaced attributes but I'm not sure that's applicable in
// HTML5?
const helper = isXlink ? 'setXlinkAttribute' : 'setAttribute';
if ( attribute.value === true ) {
// attributes without values, e.g. <textarea readonly>
if ( propertyName ) {
@ -226,6 +225,20 @@ export default function addElementAttributes ( generator, node, local ) {
` );
}
else if ( attribute.type === 'Spread' ) {
// spread, turns <input {{obj}}/> where obj = {type: text, value: hello world} -> <input type="text" value="hello world"/>
generator.uses.spreadAttributes = true;
generator.uses.setXlinkAttribute = true;
generator.uses.setAttribute = true;
// we have to include setXLinkAttibute and setAttribute because the data is dynamic
// we have no idea at compile time what is being used
const statement = `spreadAttributes( ${local.name}, root.${name} );`;
local.init.addLine( statement );
local.update.addLine( statement );
}
else {
throw new Error( `Not implemented: ${attribute.type}` );
}

@ -10,12 +10,15 @@ export default {
const attributes = [];
const bindings = [];
const spreads = [];
node.attributes.forEach( attribute => {
if ( attribute.type === 'Attribute' ) {
attributes.push( attribute );
} else if ( attribute.type === 'Binding' ) {
bindings.push( attribute );
} else if ( attribute.type === 'Spread' ) {
spreads.push( attribute );
}
});
@ -47,7 +50,11 @@ export default {
generator.addBinding( binding, node.name );
});
let open = `\${template.components.${node.name}.render({${props}}`;
const spreadProps = spreads.map( spread => `root.${spread.name}` ).join( ', ' );
const data = spreads.length ? `Object.assign({${props}}, ${spreadProps})` : `{${props}}`;
let open = `\${template.components.${node.name}.render(${data}`;
if ( node.children.length ) {
open += `, { yield: () => \``;

@ -11,6 +11,11 @@ export default {
let openingTag = `<${node.name}`;
node.attributes.forEach( attribute => {
if ( attribute.type === 'Spread' ) {
openingTag += ` \${Object.keys( root.${attribute.name} ).map( prop => \`\${prop}="\${root.${attribute.name}[prop]}"\` ).join( ' ' )}`;
return;
}
if ( attribute.type !== 'Attribute' ) return;
let str = ` ${attribute.name}`;

@ -169,6 +169,15 @@ function readAttribute ( parser, uniqueNames ) {
};
}
if ( name.indexOf( '{{' ) === 0 && name.indexOf( '}}' ) === name.length - 2 ) {
return {
start,
end: parser.index,
type: 'Spread',
name: name.slice( 2, -2 )
};
}
const value = parser.eat( '=' ) ? readAttributeValue( parser ) : true;
return {

@ -22,6 +22,20 @@ export function teardownEach ( iterations, detach, start ) {
}
}
export function spreadAttributes ( node, obj ) {
if (obj !== null && typeof obj === 'object') {
for ( var property in obj ) {
if ( obj.hasOwnProperty( property ) ) {
if ( property.slice( 0, 6 ) === 'xlink:' ) {
setXlinkAttribute( node, property, obj[property] );
} else {
setAttribute( node, property, obj[property] );
}
}
}
}
}
export function createElement ( name ) {
return document.createElement( name );
}

@ -0,0 +1,15 @@
export default {
html: '<input type="text" value="Hello World"/>',
test ( assert, component, target ) {
component.set({
options: {
type: 'text',
value: 'changed'
}
});
assert.htmlEqual( target.innerHTML, `<input type="text" value="changed"/>` );
component.teardown();
}
};

@ -0,0 +1,12 @@
<input {{options}}/>
<script>
export default {
data: () => ({
options: {
type: 'text',
value: 'Hello World'
}
})
};
</script>

@ -0,0 +1,2 @@
<p>foo: {{foo}}</p>
<p>bar: {{bar}}</p>

@ -0,0 +1,22 @@
export default {
html: `
<p>foo: 1</p>
<p>bar: 2</p>
`,
test ( assert, component, target ) {
component.set({
options: {
foo: 3,
bar: 4
}
});
assert.equal( component.refs.widget.get( 'foo' ), 3 );
assert.htmlEqual( target.innerHTML, `
<p>foo: 3</p>
<p>bar: 4</p>
` );
component.teardown();
}
};

@ -0,0 +1,18 @@
<Widget ref:widget {{options}}/>
<script>
import Widget from './Widget.html';
export default {
data: () => ({
options: {
foo: 1,
bar: 2
}
}),
components: {
Widget
}
};
</script>

@ -0,0 +1,19 @@
export default {
html: `
<svg>
<defs>
<circle id='stamp' r='10' fill='blue'/>
</defs>
<use xlink:href='#stamp' x='20' y='20'/>
</svg>
`,
test ( assert, component, target ) {
const use = target.querySelector( 'use' );
const href = use.attributes[ 'xlink:href' ];
assert.equal( href.namespaceURI, 'http://www.w3.org/1999/xlink' );
component.teardown();
}
};

@ -0,0 +1,19 @@
<svg>
<defs>
<circle id='stamp' r='10' fill='blue'/>
</defs>
<use {{options}}/>
</svg>
<script>
export default {
data: () => ({
options: {
'xlink:href': '#stamp',
x: '20',
y: '20'
}
})
};
</script>

After

Width:  |  Height:  |  Size: 229 B

Loading…
Cancel
Save