diff --git a/src/generators/Generator.js b/src/generators/Generator.js index 37d8de90b6..370771eb39 100644 --- a/src/generators/Generator.js +++ b/src/generators/Generator.js @@ -60,27 +60,34 @@ export default class Generator { return alias; } - contextualise ( fragment, expression, isEventHandler ) { + contextualise ( block, expression, context, isEventHandler ) { this.addSourcemapLocations( expression ); const usedContexts = []; const dependencies = []; const { code, helpers } = this; - const { contextDependencies, contexts, indexes } = fragment; + 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 3f5b838bbb..3d57cc7395 100644 --- a/src/generators/dom/Block.js +++ b/src/generators/dom/Block.js @@ -39,7 +39,7 @@ export default class Block { `var ${name} = ${renderStatement};` ); - this.createMountStatement( name, parentNode ); + this.mount( name, parentNode ); } else { this.builders.create.addLine( `${this.generator.helper( 'appendNode' )}( ${renderStatement}, ${parentNode} );` ); } @@ -53,12 +53,16 @@ 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 ); } - createMountStatement ( name, parentNode ) { + mount ( name, parentNode ) { if ( parentNode ) { this.builders.create.addLine( `${this.generator.helper( 'appendNode' )}( ${name}, ${parentNode} );` ); } else { 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/Attribute.js b/src/generators/dom/visitors/Component/Attribute.js new file mode 100644 index 0000000000..601bc7049f --- /dev/null +++ b/src/generators/dom/visitors/Component/Attribute.js @@ -0,0 +1,67 @@ +export default function visitAttribute ( generator, block, state, node, attribute, local ) { + if ( attribute.value === true ) { + // attributes without values, e.g.