diff --git a/src/generators/dom/visitors/Element/meta/Window.js b/src/generators/dom/visitors/Element/meta/Window.js index 269596432c..1363fccb9a 100644 --- a/src/generators/dom/visitors/Element/meta/Window.js +++ b/src/generators/dom/visitors/Element/meta/Window.js @@ -29,6 +29,13 @@ export default function visitWindow ( generator, block, node ) { // TODO verify that it's a valid callee (i.e. built-in or declared method) generator.addSourcemapLocations( attribute.expression ); + let usesState = false; + + attribute.expression.arguments.forEach( arg => { + const { contexts } = block.contextualise( arg, null, true ); + if ( contexts.length ) usesState = true; + }); + const flattened = flattenReference( attribute.expression.callee ); if ( flattened.name !== 'event' && flattened.name !== 'this' ) { // allow event.stopPropagation(), this.select() etc @@ -36,10 +43,12 @@ export default function visitWindow ( generator, block, node ) { } const handlerName = block.getUniqueName( `onwindow${attribute.name}` ); + const handlerBody = ( usesState ? `var root = ${block.component}.get();\n` : '' ) + + `[✂${attribute.expression.start}-${attribute.expression.end}✂];`; block.builders.create.addBlock( deindent` - var ${handlerName} = function ( event ) { - [✂${attribute.expression.start}-${attribute.expression.end}✂]; + function ${handlerName} ( event ) { + ${handlerBody} }; window.addEventListener( '${attribute.name}', ${handlerName} ); ` ); diff --git a/test/runtime/samples/window-event-context/_config.js b/test/runtime/samples/window-event-context/_config.js new file mode 100644 index 0000000000..ac0fd953bf --- /dev/null +++ b/test/runtime/samples/window-event-context/_config.js @@ -0,0 +1,24 @@ +export default { + data: { + foo: true + }, + + html: `true`, + + skip: /^v4/.test( process.version ), // node 4 apparently does some dumb stuff + 'skip-ssr': true, // there's some kind of weird bug with this test... it compiles with the wrong require.extensions hook for some bizarre reason + + test ( assert, component, target, window ) { + const event = new window.Event( 'click' ); + + window.dispatchEvent( event ); + assert.equal( component.get( 'foo' ), false ); + assert.htmlEqual( target.innerHTML, `false` ); + + window.dispatchEvent( event ); + assert.equal( component.get( 'foo' ), true ); + assert.htmlEqual( target.innerHTML, `true` ); + + component.destroy(); + } +}; \ No newline at end of file diff --git a/test/runtime/samples/window-event-context/main.html b/test/runtime/samples/window-event-context/main.html new file mode 100644 index 0000000000..85cc75f875 --- /dev/null +++ b/test/runtime/samples/window-event-context/main.html @@ -0,0 +1,3 @@ +<:Window on:click='set({ foo: !foo })'/> + +{{foo}} \ No newline at end of file