Skip to content

Commit

Permalink
apply event modifiers to <svelte:body> events (sveltejs#4279)
Browse files Browse the repository at this point in the history
  • Loading branch information
Conduitry authored and taylorzane committed Dec 17, 2020
1 parent c0c47be commit a7471cf
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 17 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* Disallow two-way binding to a variable declared by an `{#await}` block ([#4012](https://github.com/sveltejs/svelte/issues/4012))
* Allow access to `let:` variables in sibling attributes on slot root ([#4173](https://github.com/sveltejs/svelte/issues/4173))
* Add some more known globals ([#4276](https://github.com/sveltejs/svelte/pull/4276))
* Correctly apply event modifiers to `<svelte:body>` events ([#4278](https://github.com/sveltejs/svelte/issues/4278))

## 3.17.1

Expand Down
25 changes: 11 additions & 14 deletions src/compiler/compile/render_dom/wrappers/Body.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,23 @@
import Block from '../Block';
import Wrapper from './shared/Wrapper';
import { b } from 'code-red';
import { x } from 'code-red';
import Body from '../../nodes/Body';
import { Identifier } from 'estree';
import EventHandler from './Element/EventHandler';
import add_event_handlers from './shared/add_event_handlers';
import { TemplateNode } from '../../../interfaces';
import Renderer from '../Renderer';

export default class BodyWrapper extends Wrapper {
node: Body;
handlers: EventHandler[];

render(block: Block, _parent_node: Identifier, _parent_nodes: Identifier) {
this.node.handlers
.map(handler => new EventHandler(handler, this))
.forEach(handler => {
const snippet = handler.get_snippet(block);

block.chunks.init.push(b`
@_document.body.addEventListener("${handler.node.name}", ${snippet});
`);
constructor(renderer: Renderer, block: Block, parent: Wrapper, node: TemplateNode) {
super(renderer, block, parent, node);
this.handlers = this.node.handlers.map(handler => new EventHandler(handler, this));
}

block.chunks.destroy.push(b`
@_document.body.removeEventListener("${handler.node.name}", ${snippet});
`);
});
render(block: Block, _parent_node: Identifier, _parent_nodes: Identifier) {
add_event_handlers(block, x`@_document.body`, this.handlers);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import EventHandler from '../../../nodes/EventHandler';
import Wrapper from '../shared/Wrapper';
import Block from '../../Block';
import { b, x, p } from 'code-red';
import { Expression } from 'estree';

const TRUE = x`true`;
const FALSE = x`false`;
Expand Down Expand Up @@ -35,7 +36,7 @@ export default class EventHandlerWrapper {
return snippet;
}

render(block: Block, target: string) {
render(block: Block, target: string | Expression) {
let snippet = this.get_snippet(block);

if (this.node.modifiers.has('preventDefault')) snippet = x`@prevent_default(${snippet})`;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import Block from '../../Block';
import EventHandler from '../Element/EventHandler';
import { Expression } from 'estree';

export default function add_event_handlers(
block: Block,
target: string,
target: string | Expression,
handlers: EventHandler[]
) {
handlers.forEach(handler => add_event_handler(block, target, handler));
}

export function add_event_handler(
block: Block,
target: string,
target: string | Expression,
handler: EventHandler
) {
handler.render(block, target);
Expand Down
11 changes: 11 additions & 0 deletions test/runtime/samples/event-handler-modifier-body-once/_config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export default {
async test({ assert, component, window }) {
const event = new window.MouseEvent('click');

await window.document.body.dispatchEvent(event);
assert.equal(component.count, 1);

await window.document.body.dispatchEvent(event);
assert.equal(component.count, 1);
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<script>
export let count = 0;
</script>

<svelte:body on:click|once="{() => count += 1}"/>

0 comments on commit a7471cf

Please sign in to comment.