Skip to content

Commit

Permalink
add changes from #112 to #111
Browse files Browse the repository at this point in the history
  • Loading branch information
Rich-Harris committed Dec 5, 2016
2 parents b75bb29 + d94209b commit f699b61
Show file tree
Hide file tree
Showing 23 changed files with 241 additions and 37 deletions.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,19 @@ const { code, map } = svelte.compile( source, {
console.error( err.message );
},

onwarning: warning => {
onwarn: warning => {
console.warn( warning.message );
}
});
```


## Example/starter repos

* [charpeni/svelte-example](https://github.com/charpeni/svelte-example) - Some Svelte examples with configured Rollup, Babel, ESLint, directives, Two-Way binding, and nested components
* [EmilTholin/svelte-test](https://github.com/EmilTholin/svelte-test)


## License

[MIT](LICENSE)
10 changes: 8 additions & 2 deletions compiler/generate/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ export default function generate ( parsed, source, options ) {
` );
}
if ( isToplevel ) {
generator.current.teardownStatements.push( deindent`
if ( detach ) ${name}.parentNode.removeChild( ${name} );
generator.current.detachStatements.push( deindent`
${name}.parentNode.removeChild( ${name} );
` );
}
},
Expand Down Expand Up @@ -72,6 +72,10 @@ export default function generate ( parsed, source, options ) {
teardown: function ( detach ) {
${fragment.teardownStatements.join( '\n\n' )}
if ( detach ) {
${fragment.detachStatements.join( '\n\n' )}
}
}
};
}
Expand Down Expand Up @@ -255,6 +259,7 @@ export default function generate ( parsed, source, options ) {
initStatements: [],
mountStatements: [],
updateStatements: [],
detachStatements: [],
teardownStatements: [],

contexts: {},
Expand Down Expand Up @@ -516,6 +521,7 @@ export default function generate ( parsed, source, options ) {
};
this.root = options.root;
this.yield = options.yield;
${initStatements.join( '\n\n' )}
}
Expand Down
67 changes: 48 additions & 19 deletions compiler/generate/visitors/Component.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import deindent from '../utils/deindent.js';
import addComponentAttributes from './attributes/addComponentAttributes.js';
import counter from '../utils/counter.js';

export default {
enter ( generator, node ) {
const hasChildren = node.children.length > 0;
const name = generator.current.counter( `${node.name[0].toLowerCase()}${node.name.slice( 1 )}` );

const local = {
Expand All @@ -24,13 +26,49 @@ export default {

addComponentAttributes( generator, node, local );

const componentInitProperties = [
`target: ${!isToplevel ? generator.current.target: 'null'}`,
'root: component.root || component'
];
// Component has children
if ( hasChildren ) {
const yieldName = `render${name}YieldFragment`;

// {{YIELD STUFF}}
generator.push({
useAnchor: true,
name: generator.current.counter(yieldName),
target: 'target',
localElementDepth: 0,

initStatements: [],
mountStatements: [],
updateStatements: [],
teardownStatements: [],

counter: counter()
});

node.children.forEach( generator.visit );
generator.addRenderer( generator.current );
generator.pop();

// Don't render children twice
node.children = [];

generator.current.initStatements.push(`var ${name}_yieldFragment = ${yieldName}( root, component );`);
generator.current.updateStatements.push(`${name}_yieldFragment.update ( changed, root );`);

componentInitProperties.push(`yield: ${name}_yieldFragment`);
}

const statements = [];

if ( local.staticAttributes.length || local.dynamicAttributes.length || local.bindings.length ) {
const initialProps = local.staticAttributes
.concat( local.dynamicAttributes )
.map( attribute => `${attribute.name}: ${attribute.value}` );

const statements = [];

if ( initialProps.length ) {
statements.push( deindent`
var ${name}_initialData = {
Expand All @@ -50,25 +88,16 @@ export default {

statements.push( bindings.join( '\n' ) );
}

local.init.unshift( deindent`
${statements.join( '\n\n' )}
var ${name} = new template.components.${node.name}({
target: ${!isToplevel ? generator.current.target: 'null'},
root: component.root || component,
data: ${name}_initialData
});
` );
} else {
local.init.unshift( deindent`
var ${name} = new template.components.${node.name}({
target: ${!isToplevel ? generator.current.target: 'null'},
root: component.root || component
});
` );
componentInitProperties.push(`data: ${name}_initialData`);
}

local.init.unshift( deindent`
${statements.join( '\n\n' )}
var ${name} = new template.components.${node.name}({
${componentInitProperties.join(',\n')}
});
` );

if ( isToplevel ) {
local.mount.unshift( `${name}.mount( target, anchor );` );
}
Expand Down
1 change: 1 addition & 0 deletions compiler/generate/visitors/EachBlock.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ export default {

return `var ${contextName} = ${listName}[${indexName}];`;
}).join( '\n' ) ],
detachStatements: [],
teardownStatements: [],

counter: counter(),
Expand Down
2 changes: 2 additions & 0 deletions compiler/generate/visitors/Element.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export default {
init: [],
mount: [],
update: [],
detach: [],
teardown: []
};

Expand Down Expand Up @@ -81,6 +82,7 @@ export default {
generator.current.initStatements.push( local.init.join( '\n' ) );
if ( local.update.length ) generator.current.updateStatements.push( local.update.join( '\n' ) );
if ( local.mount.length ) generator.current.mountStatements.push( local.mount.join( '\n' ) );
generator.current.detachStatements.push( local.detach.join( '\n' ) );
generator.current.teardownStatements.push( local.teardown.join( '\n' ) );

generator.createMountStatement( name );
Expand Down
1 change: 1 addition & 0 deletions compiler/generate/visitors/IfBlock.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ function generateBlock ( generator, node, name ) {
initStatements: [],
mountStatements: [],
updateStatements: [],
detachStatements: [],
teardownStatements: [],

counter: counter()
Expand Down
7 changes: 7 additions & 0 deletions compiler/generate/visitors/YieldTag.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default {
enter ( generator ) {
const anchor = generator.createAnchor( 'yield', 'yield' );
generator.current.mountStatements.push(`component.yield && component.yield.mount( ${generator.current.target}, ${anchor} );`);
generator.current.teardownStatements.push(`component.yield && component.yield.teardown( detach );`);
}
};
4 changes: 3 additions & 1 deletion compiler/generate/visitors/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ import Element from './Element.js';
import IfBlock from './IfBlock.js';
import MustacheTag from './MustacheTag.js';
import Text from './Text.js';
import YieldTag from './YieldTag.js';

export default {
Comment,
EachBlock,
Element,
IfBlock,
MustacheTag,
Text
Text,
YieldTag
};
13 changes: 13 additions & 0 deletions compiler/parse/state/mustache.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,19 @@ export default function mustache ( parser ) {
parser.stack.push( block );
}

// {{yield}}
else if ( parser.eat( 'yield' ) ) {

parser.allowWhitespace();
parser.eat( '}}', true );

parser.current().children.push({
start,
end: parser.index,
type: 'YieldTag'
});
}

else {
const expression = readExpression( parser );

Expand Down
9 changes: 8 additions & 1 deletion compiler/validate/js/propValidators/computed.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,14 @@ export default function computed ( validator, prop ) {
return;
}

computation.value.params.forEach( param => {
const params = computation.value.params;

if ( params.length === 0 ) {
validator.error( `A computed value must depend on at least one property`, computation.value.start );
return;
}

params.forEach( param => {
const valid = param.type === 'Identifier' || param.type === 'AssignmentPattern' && param.left.type === 'Identifier';

if ( !valid ) {
Expand Down
15 changes: 15 additions & 0 deletions test/compiler/component-yield-if/Widget.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<p>
{{#if show}}
{{yield}}
{{/if}}
</p>

<script>
export default {
data () {
return {
show: false
}
}
};
</script>
24 changes: 24 additions & 0 deletions test/compiler/component-yield-if/_config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
export default {
html: '<div><p></p></div>',

test ( assert, component, target ) {
const widget = component.refs.widget;

assert.equal( widget.get( 'show' ), false );

widget.set({show: true});
assert.htmlEqual( target.innerHTML, '<div><p>Hello</p></div>' );

component.set({data: 'World'});
assert.htmlEqual( target.innerHTML, '<div><p>World</p></div>' );

widget.set({show: false});
assert.htmlEqual( target.innerHTML, '<div><p></p></div>' );

component.set({data: 'Goodbye'});
assert.htmlEqual( target.innerHTML, '<div><p></p></div>' );

widget.set({show: true});
assert.htmlEqual( target.innerHTML, '<div><p>Goodbye</p></div>' );
}
};
14 changes: 14 additions & 0 deletions test/compiler/component-yield-if/main.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<div>
<Widget ref:widget>{{data}}</Widget>
</div>
<script>
import Widget from './Widget.html'
export default {
components: { Widget },
data(){
return {
data: "Hello"
}
}
}
</script>
1 change: 1 addition & 0 deletions test/compiler/component-yield-parent/Widget.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<p>{{yield}}</p>
9 changes: 9 additions & 0 deletions test/compiler/component-yield-parent/_config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export default {
html: '<div><p>Hello</p></div>',
test ( assert, component, target ) {
assert.equal( component.get( 'data' ), 'Hello' );
component.set({data: 'World'})
assert.equal( component.get( 'data' ), 'World' );
assert.equal( target.innerHTML, '<div><p>World<!--yield--></p></div>' );
}
}
14 changes: 14 additions & 0 deletions test/compiler/component-yield-parent/main.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<div>
<Widget>{{data}}</Widget>
</div>
<script>
import Widget from './Widget.html'
export default {
components: { Widget },
data(){
return {
data: "Hello"
}
}
}
</script>
3 changes: 3 additions & 0 deletions test/compiler/component-yield/_config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default {
html: '<p>Hello</p>'
}
15 changes: 15 additions & 0 deletions test/compiler/component-yield/main.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<p>
Hello
{{#if test}}
{{yield}}
{{/if}}
</p>
<script>
export default {
data(){
return {
test: true
}
}
}
</script>
1 change: 1 addition & 0 deletions test/parser/yield/input.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{yield}}
14 changes: 14 additions & 0 deletions test/parser/yield/output.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"html": {
"start": 0,
"end": 9,
"type": "Fragment",
"children": [
{
"start": 0,
"end": 9,
"type": "YieldTag"
}
]
}
}
Loading

0 comments on commit f699b61

Please sign in to comment.