diff --git a/src/generators/Generator.js b/src/generators/Generator.js index f1aef70eea..370771eb39 100644 --- a/src/generators/Generator.js +++ b/src/generators/Generator.js @@ -60,7 +60,7 @@ export default class Generator { return alias; } - contextualise ( block, expression, isEventHandler ) { + contextualise ( block, expression, context, isEventHandler ) { this.addSourcemapLocations( expression ); const usedContexts = []; @@ -70,17 +70,24 @@ export default class Generator { const { contextDependencies, contexts, indexes } = block; let scope = annotateWithScopes( expression ); + let lexicalDepth = 0; const self = this; walk( expression, { enter ( node, parent, key ) { + if ( /^Function/.test( node.type ) ) lexicalDepth += 1; + if ( node._scope ) { scope = node._scope; return; } - if ( isReference( node, parent ) ) { + if ( node.type === 'ThisExpression' ) { + if ( lexicalDepth === 0 && context ) code.overwrite( node.start, node.end, context, true ); + } + + else if ( isReference( node, parent ) ) { const { name } = flattenReference( node ); if ( scope.has( name ) ) return; @@ -93,10 +100,10 @@ export default class Generator { } else if ( contexts.has( name ) ) { - const context = contexts.get( name ); - if ( context !== name ) { + const contextName = contexts.get( name ); + if ( contextName !== name ) { // this is true for 'reserved' names like `root` and `component` - code.overwrite( node.start, node.start + name.length, context, true ); + code.overwrite( node.start, node.start + name.length, contextName, true ); } dependencies.push( ...contextDependencies.get( name ) ); @@ -133,6 +140,7 @@ export default class Generator { }, leave ( node ) { + if ( /^Function/.test( node.type ) ) lexicalDepth -= 1; if ( node._scope ) scope = scope.parent; } }); diff --git a/src/generators/dom/Block.js b/src/generators/dom/Block.js index 90329c6c21..3d57cc7395 100644 --- a/src/generators/dom/Block.js +++ b/src/generators/dom/Block.js @@ -53,6 +53,10 @@ export default class Block { return new Block( Object.assign( {}, this, options, { parent: this } ) ); } + contextualise ( expression, context, isEventHandler ) { + return this.generator.contextualise( this, expression, context, isEventHandler ); + } + createAnchor ( name, parentNode ) { const renderStatement = `${this.generator.helper( 'createComment' )}()`; this.addElement( name, renderStatement, parentNode, true ); diff --git a/src/generators/dom/index.js b/src/generators/dom/index.js index fcb540d679..dbb054e7c6 100644 --- a/src/generators/dom/index.js +++ b/src/generators/dom/index.js @@ -271,7 +271,7 @@ export default function dom ( parsed, source, options ) { throw new Error( `Components with shared helpers must be compiled to ES2015 modules (format: 'es')` ); } - const names = Array.from( generator.uses ).map( name => { + const names = Array.from( generator.uses ).sort().map( name => { return name !== generator.alias( name ) ? `${name} as ${generator.alias( name )}` : name; }); diff --git a/src/generators/dom/visitors/Component/attributes/addComponentAttributes.js b/src/generators/dom/visitors/Component/attributes/addComponentAttributes.js index 0bc983c2f7..88a4d9ddf2 100644 --- a/src/generators/dom/visitors/Component/attributes/addComponentAttributes.js +++ b/src/generators/dom/visitors/Component/attributes/addComponentAttributes.js @@ -82,7 +82,7 @@ export default function addComponentAttributes ( generator, block, node, local ) const usedContexts = []; attribute.expression.arguments.forEach( arg => { - const { contexts } = generator.contextualise( block, arg, true ); + const { contexts } = generator.contextualise( block, arg, null, true ); contexts.forEach( context => { if ( !~usedContexts.indexOf( context ) ) usedContexts.push( context ); diff --git a/src/generators/dom/visitors/EachBlock.js b/src/generators/dom/visitors/EachBlock.js index cef7478dfc..f11b2fb929 100644 --- a/src/generators/dom/visitors/EachBlock.js +++ b/src/generators/dom/visitors/EachBlock.js @@ -134,7 +134,7 @@ export default function visitEachBlock ( generator, block, state, node ) { } } - destroyEach( ${localVars.iterations}, true, ${listName}.length ); + ${generator.helper( 'destroyEach' )}( ${localVars.iterations}, true, ${listName}.length ); ${localVars.iterations}.length = ${listName}.length; ` ); @@ -154,7 +154,7 @@ export default function visitEachBlock ( generator, block, state, node ) { } block.builders.destroy.addBlock( - `${generator.helper( 'destroyEach' )}( ${localVars.iterations}, ${isToplevel ? 'detach' : 'false'} );` ); + `${generator.helper( 'destroyEach' )}( ${localVars.iterations}, ${isToplevel ? 'detach' : 'false'}, 0 );` ); if ( node.else ) { block.builders.destroy.addBlock( deindent` @@ -197,7 +197,8 @@ export default function visitEachBlock ( generator, block, state, node ) { }); const childState = Object.assign( {}, state, { - parentNode: null + parentNode: null, + inEachBlock: true }); node.children.forEach( child => { diff --git a/src/generators/dom/visitors/Element/Binding.js b/src/generators/dom/visitors/Element/Binding.js index 61c275f55e..c9e2c66cbe 100644 --- a/src/generators/dom/visitors/Element/Binding.js +++ b/src/generators/dom/visitors/Element/Binding.js @@ -21,7 +21,7 @@ export default function visitBinding ( generator, block, state, node, attribute const value = getBindingValue( generator, block, state, node, attribute, isMultipleSelect, bindingGroup, type ); const eventName = getBindingEventName( node ); - let setter = getSetter({ block, name, keypath, context: '__svelte', attribute, dependencies, value }); + let setter = getSetter({ block, name, keypath, context: '_svelte', attribute, dependencies, value }); let updateElement; //