Skip to content

Commit

Permalink
support custom events on <:Window> - fixes #1268
Browse files Browse the repository at this point in the history
  • Loading branch information
Rich-Harris committed Apr 4, 2018
1 parent 8717ff8 commit 6ef808c
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 8 deletions.
41 changes: 33 additions & 8 deletions src/generators/nodes/Window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand All @@ -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') {
Expand Down
1 change: 1 addition & 0 deletions src/validate/html/validateWindow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
});
Expand Down
15 changes: 15 additions & 0 deletions test/runtime/samples/window-event-custom/_config.js
Original file line number Diff line number Diff line change
@@ -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>
`);
},
};
25 changes: 25 additions & 0 deletions test/runtime/samples/window-event-custom/main.html
Original file line number Diff line number Diff line change
@@ -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>

0 comments on commit 6ef808c

Please sign in to comment.