Skip to content

Commit b39282a

Browse files
authored
apply event modifiers to <svelte:body> events (#4279)
1 parent bda254e commit b39282a

File tree

6 files changed

+33
-17
lines changed

6 files changed

+33
-17
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* Disallow two-way binding to a variable declared by an `{#await}` block ([#4012](https://github.com/sveltejs/svelte/issues/4012))
66
* Allow access to `let:` variables in sibling attributes on slot root ([#4173](https://github.com/sveltejs/svelte/issues/4173))
77
* Add some more known globals ([#4276](https://github.com/sveltejs/svelte/pull/4276))
8+
* Correctly apply event modifiers to `<svelte:body>` events ([#4278](https://github.com/sveltejs/svelte/issues/4278))
89

910
## 3.17.1
1011

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,23 @@
11
import Block from '../Block';
22
import Wrapper from './shared/Wrapper';
3-
import { b } from 'code-red';
3+
import { x } from 'code-red';
44
import Body from '../../nodes/Body';
55
import { Identifier } from 'estree';
66
import EventHandler from './Element/EventHandler';
7+
import add_event_handlers from './shared/add_event_handlers';
8+
import { TemplateNode } from '../../../interfaces';
9+
import Renderer from '../Renderer';
710

811
export default class BodyWrapper extends Wrapper {
912
node: Body;
13+
handlers: EventHandler[];
1014

11-
render(block: Block, _parent_node: Identifier, _parent_nodes: Identifier) {
12-
this.node.handlers
13-
.map(handler => new EventHandler(handler, this))
14-
.forEach(handler => {
15-
const snippet = handler.get_snippet(block);
16-
17-
block.chunks.init.push(b`
18-
@_document.body.addEventListener("${handler.node.name}", ${snippet});
19-
`);
15+
constructor(renderer: Renderer, block: Block, parent: Wrapper, node: TemplateNode) {
16+
super(renderer, block, parent, node);
17+
this.handlers = this.node.handlers.map(handler => new EventHandler(handler, this));
18+
}
2019

21-
block.chunks.destroy.push(b`
22-
@_document.body.removeEventListener("${handler.node.name}", ${snippet});
23-
`);
24-
});
20+
render(block: Block, _parent_node: Identifier, _parent_nodes: Identifier) {
21+
add_event_handlers(block, x`@_document.body`, this.handlers);
2522
}
2623
}

src/compiler/compile/render_dom/wrappers/Element/EventHandler.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import EventHandler from '../../../nodes/EventHandler';
22
import Wrapper from '../shared/Wrapper';
33
import Block from '../../Block';
44
import { b, x, p } from 'code-red';
5+
import { Expression } from 'estree';
56

67
const TRUE = x`true`;
78
const FALSE = x`false`;
@@ -35,7 +36,7 @@ export default class EventHandlerWrapper {
3536
return snippet;
3637
}
3738

38-
render(block: Block, target: string) {
39+
render(block: Block, target: string | Expression) {
3940
let snippet = this.get_snippet(block);
4041

4142
if (this.node.modifiers.has('preventDefault')) snippet = x`@prevent_default(${snippet})`;

src/compiler/compile/render_dom/wrappers/shared/add_event_handlers.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
import Block from '../../Block';
22
import EventHandler from '../Element/EventHandler';
3+
import { Expression } from 'estree';
34

45
export default function add_event_handlers(
56
block: Block,
6-
target: string,
7+
target: string | Expression,
78
handlers: EventHandler[]
89
) {
910
handlers.forEach(handler => add_event_handler(block, target, handler));
1011
}
1112

1213
export function add_event_handler(
1314
block: Block,
14-
target: string,
15+
target: string | Expression,
1516
handler: EventHandler
1617
) {
1718
handler.render(block, target);
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
export default {
2+
async test({ assert, component, window }) {
3+
const event = new window.MouseEvent('click');
4+
5+
await window.document.body.dispatchEvent(event);
6+
assert.equal(component.count, 1);
7+
8+
await window.document.body.dispatchEvent(event);
9+
assert.equal(component.count, 1);
10+
}
11+
};
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<script>
2+
export let count = 0;
3+
</script>
4+
5+
<svelte:body on:click|once="{() => count += 1}"/>

0 commit comments

Comments
 (0)