implement :Window events

pull/391/head
Rich-Harris 8 years ago
parent 89f0fb00e6
commit 9f832c2e37

@ -2,9 +2,18 @@ import CodeBuilder from '../../../utils/CodeBuilder.js';
import deindent from '../../../utils/deindent.js';
import addElementAttributes from './attributes/addElementAttributes.js';
import Component from './Component.js';
import Window from './meta/Window.js';
const meta = {
':Window': Window
};
export default {
enter ( generator, node ) {
if ( node.name in meta ) {
return meta[ node.name ].enter( generator, node );
}
const isComponent = node.name in generator.components || node.name === ':Self';
if ( isComponent ) {
return Component.enter( generator, node );
@ -100,6 +109,10 @@ export default {
},
leave ( generator, node ) {
if ( node.name in meta ) {
return meta[ node.name ].leave( generator, node );
}
const isComponent = node.name in generator.components;
if ( isComponent ) {
return Component.leave( generator, node );

@ -0,0 +1,32 @@
import flattenReference from '../../../../utils/flattenReference.js';
import deindent from '../../../../utils/deindent.js';
export default {
enter ( generator, node ) {
node.attributes.forEach( attribute => {
if ( attribute.type === 'EventHandler' ) {
// TODO verify that it's a valid callee (i.e. built-in or declared method)
generator.addSourcemapLocations( attribute.expression );
const flattened = flattenReference( attribute.expression.callee );
if ( flattened.name !== 'event' && flattened.name !== 'this' ) {
// allow event.stopPropagation(), this.select() etc
generator.code.prependRight( attribute.expression.start, 'component.' );
}
const handlerName = generator.current.getUniqueName( `onwindow${attribute.name}` );
generator.current.builders.init.addBlock( deindent`
var ${handlerName} = function ( event ) {
[${attribute.expression.start}-${attribute.expression.end}];
};
window.addEventListener( '${attribute.name}', ${handlerName} );
` );
generator.current.builders.teardown.addBlock( deindent`
window.removeEventListener( '${attribute.name}', ${handlerName} );
` );
}
});
}
};

@ -93,6 +93,8 @@ describe( 'generate', () => {
return env()
.then( window => {
global.window = window;
// Put the constructor on window for testing
window.SvelteComponent = SvelteComponent;

@ -0,0 +1,26 @@
export default {
html: `<div>undefinedxundefined</div>`,
test ( assert, component, target, window ) {
const event = new window.Event( 'resize' );
// JSDOM executes window event listeners with `global` rather than
// `window` (bug?) so we need to do this
Object.defineProperties( global, {
innerWidth: {
value: 567,
configurable: true
},
innerHeight: {
value: 456,
configurable: true
}
});
window.dispatchEvent( event );
assert.htmlEqual( target.innerHTML, `
<div>567x456</div>
`);
}
};

@ -0,0 +1,3 @@
<:Window on:resize='set({ width: this.innerWidth, height: this.innerHeight })'/>
<div>{{width}}x{{height}}</div>
Loading…
Cancel
Save