Merge pull request #1315 from sveltejs/gh-1268

support custom events on <:Window>
pull/1332/head
Rich Harris 7 years ago committed by GitHub
commit 84019b5cea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -51,6 +51,8 @@ export default class Window extends Node {
// TODO verify that it's a valid callee (i.e. built-in or declared method)
generator.addSourcemapLocations(attribute.expression);
const isCustomEvent = generator.events.has(attribute.name);
let usesState = false;
attribute.expression.arguments.forEach((arg: Node) => {
@ -74,16 +76,39 @@ export default class Window extends Node {
[${attribute.expression.start}-${attribute.expression.end}];
`;
block.builders.init.addBlock(deindent`
function ${handlerName}(event) {
${handlerBody}
if (isCustomEvent) {
// TODO dry this out
block.addVariable(handlerName);
block.builders.hydrate.addBlock(deindent`
${handlerName} = %events-${attribute.name}.call(#component, window, function(event) {
${handlerBody}
});
`);
if (generator.options.dev) {
block.builders.hydrate.addBlock(deindent`
if (${handlerName}.teardown) {
console.warn("Return 'destroy()' from custom event handlers. Returning 'teardown()' has been deprecated and will be unsupported in Svelte 2");
}
`);
}
window.addEventListener("${attribute.name}", ${handlerName});
`);
block.builders.destroy.addBlock(deindent`
window.removeEventListener("${attribute.name}", ${handlerName});
`);
block.builders.destroy.addLine(deindent`
${handlerName}[${handlerName}.destroy ? 'destroy' : 'teardown']();
`);
} else {
block.builders.init.addBlock(deindent`
function ${handlerName}(event) {
${handlerBody}
}
window.addEventListener("${attribute.name}", ${handlerName});
`);
block.builders.destroy.addBlock(deindent`
window.removeEventListener("${attribute.name}", ${handlerName});
`);
}
}
if (attribute.type === 'Binding') {

@ -51,6 +51,7 @@ export default function validateWindow(validator: Validator, node: Node, refs: M
}
}
} else if (attribute.type === 'EventHandler') {
validator.used.events.add(attribute.name);
validateEventHandler(validator, attribute, refCallees);
}
});

@ -0,0 +1,15 @@
export default {
html: `<p>escaped: false</p>`,
test(assert, component, target, window) {
const event = new window.KeyboardEvent('keydown', {
which: 27
});
window.dispatchEvent(event);
assert.htmlEqual(target.innerHTML, `
<p>escaped: true</p>
`);
},
};

@ -0,0 +1,25 @@
<:Window on:esc="set({ escaped: true })" />
<p>escaped: {{escaped}}</p>
<script>
export default {
data() {
return { escaped: false };
},
events: {
esc(node, callback) {
function onKeyDown(event) {
if (event.which === 27) callback(event);
}
node.addEventListener('keydown', onKeyDown);
return {
destroy() {
node.removeEventListener('keydown', onKeyDown);
}
};
}
}
};
</script>
Loading…
Cancel
Save