Merge pull request #511 from sveltejs/gh-507

rename root to state, and allow state to be used as context
pull/515/head
Rich Harris 8 years ago committed by GitHub
commit 1fd3c21194

@ -102,7 +102,7 @@ export default class Generator {
else if ( contexts.has( name ) ) {
const contextName = contexts.get( name );
if ( contextName !== name ) {
// this is true for 'reserved' names like `root` and `component`
// this is true for 'reserved' names like `state` and `component`
code.overwrite( node.start, node.start + name.length, contextName, true );
}
@ -124,13 +124,13 @@ export default class Generator {
}
if ( globalWhitelist.has( name ) ) {
code.prependRight( node.start, `( '${name}' in root ? root.` );
code.prependRight( node.start, `( '${name}' in state ? state.` );
code.appendLeft( node.object ? node.object.end : node.end, ` : ${name} )` );
} else {
code.prependRight( node.start, `root.` );
code.prependRight( node.start, `state.` );
}
if ( !~usedContexts.indexOf( 'root' ) ) usedContexts.push( 'root' );
if ( !~usedContexts.indexOf( 'state' ) ) usedContexts.push( 'state' );
}
this.skip();

@ -191,7 +191,7 @@ export default function preprocess ( generator, node ) {
indexes: new Map(),
contextDependencies: new Map(),
params: [ 'root' ],
params: [ 'state' ],
indexNames: new Map(),
listNames: new Map(),

@ -24,7 +24,7 @@ export default function visitBinding ( generator, block, state, node, attribute,
prop = `'[✂${attribute.value.property.start}-${attribute.value.property.end}✂]'`;
obj = `[✂${attribute.value.object.start}-${attribute.value.object.end}✂]`;
} else {
obj = 'root';
obj = 'state';
prop = `'${name}'`;
}

@ -66,7 +66,7 @@ export default function visitComponent ( generator, block, state, node ) {
if ( local.allUsedContexts.length ) {
const initialProps = local.allUsedContexts.map( contextName => {
if ( contextName === 'root' ) return `root: root`;
if ( contextName === 'state' ) return `state: state`;
const listName = block.listNames.get( contextName );
const indexName = block.indexNames.get( contextName );
@ -75,7 +75,7 @@ export default function visitComponent ( generator, block, state, node ) {
}).join( ',\n' );
const updates = local.allUsedContexts.map( contextName => {
if ( contextName === 'root' ) return `${name}._context.root = root;`;
if ( contextName === 'state' ) return `${name}._context.state = state;`;
const listName = block.listNames.get( contextName );
const indexName = block.indexNames.get( contextName );

@ -17,7 +17,7 @@ export default function visitEventHandler ( generator, block, state, node, attri
// TODO hoist event handlers? can do `this.__component.method(...)`
const declarations = usedContexts.map( name => {
if ( name === 'root' ) return 'var root = this._context.root;';
if ( name === 'state' ) return 'var state = this._context.state;';
const listName = block.listNames.get( name );
const indexName = block.indexNames.get( name );

@ -86,7 +86,7 @@ export default function visitElement ( generator, block, state, node ) {
}
childState.allUsedContexts.forEach( contextName => {
if ( contextName === 'root' ) return;
if ( contextName === 'state' ) return;
const listName = block.listNames.get( contextName );
const indexName = block.indexNames.get( contextName );

@ -30,9 +30,9 @@ export default function visitEventHandler ( generator, block, state, node, attri
const _this = context || 'this';
const declarations = usedContexts.map( name => {
if ( name === 'root' ) {
if ( name === 'state' ) {
if ( shouldHoist ) state.usesComponent = true;
return `var root = ${block.component}.get();`;
return `var state = ${block.component}.get();`;
}
const listName = block.listNames.get( name );

@ -43,7 +43,7 @@ export default function visitWindow ( generator, block, node ) {
}
const handlerName = block.getUniqueName( `onwindow${attribute.name}` );
const handlerBody = ( usesState ? `var root = ${block.component}.get();\n` : '' ) +
const handlerBody = ( usesState ? `var state = ${block.component}.get();\n` : '' ) +
`[✂${attribute.expression.start}-${attribute.expression.end}✂];`;
block.builders.create.addBlock( deindent`

@ -7,7 +7,7 @@ export default class Block {
}
addBinding ( binding, name ) {
const conditions = [ `!( '${binding.name}' in root )`].concat( // TODO handle contextual bindings...
const conditions = [ `!( '${binding.name}' in state )`].concat( // TODO handle contextual bindings...
this.conditions.map( c => `(${c})` )
);
@ -17,7 +17,7 @@ export default class Block {
if ( ${conditions.join( '&&' )} ) {
tmp = ${name}.data();
if ( '${keypath}' in tmp ) {
root.${binding.name} = tmp.${keypath};
state.${binding.name} = tmp.${keypath};
settled = false;
}
}

@ -44,12 +44,12 @@ export default function ssr ( parsed, source, options ) {
});
builders.render.addLine(
templateProperties.data ? `root = Object.assign( ${generator.alias( 'template' )}.data(), root || {} );` : `root = root || {};`
templateProperties.data ? `state = Object.assign( ${generator.alias( 'template' )}.data(), state || {} );` : `state = state || {};`
);
computations.forEach( ({ key, deps }) => {
builders.render.addLine(
`root.${key} = ${generator.alias( 'template' )}.computed.${key}( ${deps.map( dep => `root.${dep}` ).join( ', ' )} );`
`state.${key} = ${generator.alias( 'template' )}.computed.${key}( ${deps.map( dep => `state.${dep}` ).join( ', ' )} );`
);
});
@ -129,7 +129,7 @@ export default function ssr ( parsed, source, options ) {
return ${templateProperties.data ? `${generator.alias( 'template' )}.data()` : `{}`};
};
${name}.render = function ( root, options ) {
${name}.render = function ( state, options ) {
${builders.render}
};

@ -45,7 +45,7 @@ export default function visitComponent ( generator, block, node ) {
})
.concat( bindings.map( binding => {
const { name, keypath } = flattenReference( binding.value );
const value = block.contexts.has( name ) ? keypath : `root.${keypath}`;
const value = block.contexts.has( name ) ? keypath : `state.${keypath}`;
return `${binding.name}: ${value}`;
}))
.join( ', ' );

@ -1 +1,6 @@
export default new Set( [ 'arguments', 'await', 'break', 'case', 'catch', 'class', 'const', 'continue', 'debugger', 'default', 'delete', 'do', 'else', 'enum', 'eval', 'export', 'extends', 'false', 'finally', 'for', 'function', 'if', 'implements', 'import', 'in', 'instanceof', 'interface', 'let', 'new', 'null', 'package', 'private', 'protected', 'public', 'return', 'static', 'super', 'switch', 'this', 'throw', 'true', 'try', 'typeof', 'var', 'void', 'while', 'with', 'yield' ] );
const reservedNames = new Set( [ 'arguments', 'await', 'break', 'case', 'catch', 'class', 'const', 'continue', 'debugger', 'default', 'delete', 'do', 'else', 'enum', 'eval', 'export', 'extends', 'false', 'finally', 'for', 'function', 'if', 'implements', 'import', 'in', 'instanceof', 'interface', 'let', 'new', 'null', 'package', 'private', 'protected', 'public', 'return', 'static', 'super', 'switch', 'this', 'throw', 'true', 'try', 'typeof', 'var', 'void', 'while', 'with', 'yield' ] );
// prevent e.g. `{{#each states as state}}` breaking
reservedNames.add( 'state' );
export default reservedNames;

@ -63,14 +63,6 @@ export default function validateJs ( validator, js ) {
validator.defaultExport = node;
}
if ( node.type === 'ImportDeclaration' ) {
node.specifiers.forEach( specifier => {
if ( specifier.local.name === 'root' ) {
validator.error( `Imported identifiers cannot have a name of 'root' due to technical limitations`, specifier.start );
}
});
}
});
[ 'components', 'methods', 'helpers' ].forEach( key => {

@ -11,6 +11,10 @@ export default function components ( validator, prop ) {
checkForComputedKeys( validator, prop.value.properties );
prop.value.properties.forEach( component => {
if ( component.key.name === 'state' ) {
validator.error( `Component constructors cannot be called 'state' due to technical limitations`, component.start );
}
if ( !/^[A-Z]/.test( component.key.name ) ) {
validator.warn( `Component names should be capitalised`, component.start );
}

@ -17,12 +17,12 @@ function add_css () {
added_css = true;
}
function create_main_fragment ( root, component ) {
function create_main_fragment ( state, component ) {
var text_value;
var p = createElement( 'p' );
setAttribute( p, 'svelte-3842350206', '' );
var text = createText( text_value = root.foo );
var text = createText( text_value = state.foo );
appendNode( text, p );
return {
@ -30,8 +30,8 @@ function create_main_fragment ( root, component ) {
insertNode( p, target, anchor );
},
update: function ( changed, root ) {
if ( text_value !== ( text_value = root.foo ) ) {
update: function ( changed, state ) {
if ( text_value !== ( text_value = state.foo ) ) {
text.data = text_value;
}
},

@ -16,7 +16,7 @@ var template = (function () {
};
}());
function create_main_fragment ( root, component ) {
function create_main_fragment ( state, component ) {
return {

@ -1,19 +1,19 @@
import { appendNode, assign, createComment, createElement, createText, destroyEach, detachBetween, detachNode, dispatchObservers, insertNode, proto } from "svelte/shared.js";
function create_main_fragment ( root, component ) {
function create_main_fragment ( state, component ) {
var text_1_value;
var each_block_anchor = createComment();
var each_block_value = root.comments;
var each_block_value = state.comments;
var each_block_iterations = [];
for ( var i = 0; i < each_block_value.length; i += 1 ) {
each_block_iterations[i] = create_each_block( root, each_block_value, each_block_value[i], i, component );
each_block_iterations[i] = create_each_block( state, each_block_value, each_block_value[i], i, component );
}
var text = createText( "\n\n" );
var p = createElement( 'p' );
var text_1 = createText( text_1_value = root.foo );
var text_1 = createText( text_1_value = state.foo );
appendNode( text_1, p );
return {
@ -28,15 +28,15 @@ function create_main_fragment ( root, component ) {
insertNode( p, target, anchor );
},
update: function ( changed, root ) {
var each_block_value = root.comments;
update: function ( changed, state ) {
var each_block_value = state.comments;
if ( 'comments' in changed || 'elapsed' in changed || 'time' in changed ) {
for ( var i = 0; i < each_block_value.length; i += 1 ) {
if ( each_block_iterations[i] ) {
each_block_iterations[i].update( changed, root, each_block_value, each_block_value[i], i );
each_block_iterations[i].update( changed, state, each_block_value, each_block_value[i], i );
} else {
each_block_iterations[i] = create_each_block( root, each_block_value, each_block_value[i], i, component );
each_block_iterations[i] = create_each_block( state, each_block_value, each_block_value[i], i, component );
each_block_iterations[i].mount( each_block_anchor.parentNode, each_block_anchor );
}
}
@ -46,7 +46,7 @@ function create_main_fragment ( root, component ) {
each_block_iterations.length = each_block_value.length;
}
if ( text_1_value !== ( text_1_value = root.foo ) ) {
if ( text_1_value !== ( text_1_value = state.foo ) ) {
text_1.data = text_1_value;
}
},
@ -63,7 +63,7 @@ function create_main_fragment ( root, component ) {
};
}
function create_each_block ( root, each_block_value, comment, i, component ) {
function create_each_block ( state, each_block_value, comment, i, component ) {
var text_value, text_2_value, text_4_value;
var div = createElement( 'div' );
@ -79,7 +79,7 @@ function create_each_block ( root, each_block_value, comment, i, component ) {
var text_2 = createText( text_2_value = comment.author );
appendNode( text_2, span );
appendNode( createText( " wrote " ), span );
var text_4 = createText( text_4_value = root.elapsed(comment.time, root.time) );
var text_4 = createText( text_4_value = state.elapsed(comment.time, state.time) );
appendNode( text_4, span );
appendNode( createText( " ago:" ), span );
appendNode( createText( "\n\n\t\t" ), div );
@ -95,7 +95,7 @@ function create_each_block ( root, each_block_value, comment, i, component ) {
insertNode( div, target, anchor );
},
update: function ( changed, root, each_block_value, comment, i ) {
update: function ( changed, state, each_block_value, comment, i ) {
if ( text_value !== ( text_value = i ) ) {
text.data = text_value;
}
@ -104,7 +104,7 @@ function create_each_block ( root, each_block_value, comment, i, component ) {
text_2.data = text_2_value;
}
if ( text_4_value !== ( text_4_value = root.elapsed(comment.time, root.time) ) ) {
if ( text_4_value !== ( text_4_value = state.elapsed(comment.time, state.time) ) ) {
text_4.data = text_4_value;
}
@ -164,4 +164,4 @@ SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = functio
this._torndown = true;
};
export default SvelteComponent;
export default SvelteComponent;

@ -15,12 +15,12 @@ var template = (function () {
};
}());
function create_main_fragment ( root, component ) {
function create_main_fragment ( state, component ) {
var button = createElement( 'button' );
var foo_handler = template.events.foo.call( component, button, function ( event ) {
var root = component.get();
component.foo( root.bar );
var state = component.get();
component.foo( state.bar );
});
appendNode( createText( "foo" ), button );

@ -1,15 +1,15 @@
import { appendNode, assign, createComment, createElement, createText, detachNode, dispatchObservers, insertNode, proto } from "svelte/shared.js";
function create_main_fragment ( root, component ) {
function create_main_fragment ( state, component ) {
var if_block_anchor = createComment();
function get_block ( root ) {
if ( root.foo ) return create_if_block;
function get_block ( state ) {
if ( state.foo ) return create_if_block;
return create_if_block_1;
}
var current_block = get_block( root );
var if_block = current_block && current_block( root, component );
var current_block = get_block( state );
var if_block = current_block && current_block( state, component );
return {
mount: function ( target, anchor ) {
@ -17,10 +17,10 @@ function create_main_fragment ( root, component ) {
if ( if_block ) if_block.mount( target, if_block_anchor );
},
update: function ( changed, root ) {
if ( current_block !== ( current_block = get_block( root ) ) ) {
update: function ( changed, state ) {
if ( current_block !== ( current_block = get_block( state ) ) ) {
if ( if_block ) if_block.destroy( true );
if_block = current_block && current_block( root, component );
if_block = current_block && current_block( state, component );
if ( if_block ) if_block.mount( if_block_anchor.parentNode, if_block_anchor );
}
},
@ -35,7 +35,7 @@ function create_main_fragment ( root, component ) {
};
}
function create_if_block ( root, component ) {
function create_if_block ( state, component ) {
var p = createElement( 'p' );
appendNode( createText( "foo!" ), p );
@ -52,7 +52,7 @@ function create_if_block ( root, component ) {
};
}
function create_if_block_1 ( root, component ) {
function create_if_block_1 ( state, component ) {
var p = createElement( 'p' );
appendNode( createText( "not foo!" ), p );

@ -1,9 +1,9 @@
import { appendNode, assign, createComment, createElement, createText, detachNode, dispatchObservers, insertNode, proto } from "svelte/shared.js";
function create_main_fragment ( root, component ) {
function create_main_fragment ( state, component ) {
var if_block_anchor = createComment();
var if_block = root.foo && create_if_block( root, component );
var if_block = state.foo && create_if_block( state, component );
return {
mount: function ( target, anchor ) {
@ -11,10 +11,10 @@ function create_main_fragment ( root, component ) {
if ( if_block ) if_block.mount( target, if_block_anchor );
},
update: function ( changed, root ) {
if ( root.foo ) {
update: function ( changed, state ) {
if ( state.foo ) {
if ( !if_block ) {
if_block = create_if_block( root, component );
if_block = create_if_block( state, component );
if_block.mount( if_block_anchor.parentNode, if_block_anchor );
}
} else if ( if_block ) {
@ -33,7 +33,7 @@ function create_main_fragment ( root, component ) {
};
}
function create_if_block ( root, component ) {
function create_if_block ( state, component ) {
var p = createElement( 'p' );
appendNode( createText( "foo!" ), p );

@ -0,0 +1,54 @@
export default {
data: {
state: 'deconflicted',
states: [
'Alabama',
'Alaska',
'Arizona',
'Arkansas',
'...and some others'
]
},
html: `
<p>Current state: deconflicted</p>
<ul>
<li>Alabama</li>
<li>Alaska</li>
<li>Arizona</li>
<li>Arkansas</li>
<li>...and some others</li>
</ul>
`,
test ( assert, component, target ) {
component.set({
states: [
'Maine',
'Maryland',
'Massachusetts',
'Michigan',
'Minnesota',
'Mississippi',
'Missouri',
'Montana'
]
});
assert.htmlEqual( target.innerHTML, `
<p>Current state: deconflicted</p>
<ul>
<li>Maine</li>
<li>Maryland</li>
<li>Massachusetts</li>
<li>Michigan</li>
<li>Minnesota</li>
<li>Mississippi</li>
<li>Missouri</li>
<li>Montana</li>
</ul>
` );
}
};

@ -0,0 +1,7 @@
<p>Current state: {{state}}</p>
<ul>
{{#each states as state}}
<li>{{state}}</li>
{{/each}}
</ul>

@ -0,0 +1,8 @@
[{
"message": "Component constructors cannot be called 'state' due to technical limitations",
"pos": 73,
"loc": {
"line": 6,
"column": 3
}
}]

@ -0,0 +1,9 @@
<script>
import state from 'foo';
export default {
components: {
state
}
};
</script>

@ -1,8 +0,0 @@
[{
"message": "Imported identifiers cannot have a name of 'root' due to technical limitations",
"pos": 17,
"loc": {
"line": 2,
"column": 8
}
}]

@ -1,3 +0,0 @@
<script>
import root from 'foo';
</script>
Loading…
Cancel
Save