Skip to content

Commit 4234efa

Browse files
committed
fix: events with modifiers called once for every event listener on event
1 parent b6ea06f commit 4234efa

File tree

1 file changed

+24
-7
lines changed

1 file changed

+24
-7
lines changed

packages/common/forwardEventsBuilder.js

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,15 @@ export function forwardEventsBuilder(component) {
1919
const componentOn = component.$on;
2020

2121
// And we override the $on function to forward all bound events.
22-
component.$on = (fullEventType, ...args) => {
22+
component.$on = (fullEventType, callback) => {
2323
let eventType = fullEventType;
2424
let destructor = () => {};
2525
if ($on) {
2626
// The event was bound programmatically.
27-
destructor = $on(eventType);
27+
destructor = $on(eventType, callback);
2828
} else {
2929
// The event was bound before mount by Svelte.
30-
events.push(eventType);
30+
events.push([eventType, callback]);
3131
}
3232
const oldModifierMatch = eventType.match(oldModifierRegex);
3333
const newModifierMatch = eventType.match(newModifierRegex);
@@ -47,7 +47,11 @@ export function forwardEventsBuilder(component) {
4747
}
4848

4949
// Call the original $on function.
50-
const componentDestructor = componentOn.call(component, eventType, ...args);
50+
const componentDestructor = componentOn.call(
51+
component,
52+
eventType,
53+
callback
54+
);
5155

5256
return (...args) => {
5357
destructor();
@@ -62,11 +66,12 @@ export function forwardEventsBuilder(component) {
6266

6367
return (node) => {
6468
const destructors = [];
69+
const forwardDestructors = {};
6570

6671
// This function is responsible for forwarding all bound events.
67-
$on = (fullEventType) => {
72+
$on = (fullEventType, callback) => {
6873
let eventType = fullEventType;
69-
let handler = forward;
74+
let handler = callback;
7075
// DOM addEventListener options argument.
7176
let options = false;
7277
const oldModifierMatch = eventType.match(oldModifierRegex);
@@ -98,6 +103,7 @@ export function forwardEventsBuilder(component) {
98103
}
99104
}
100105

106+
// Listen for the event directly, with the given options.
101107
const off = listen(node, eventType, handler, options);
102108
const destructor = () => {
103109
off();
@@ -108,12 +114,18 @@ export function forwardEventsBuilder(component) {
108114
};
109115

110116
destructors.push(destructor);
117+
118+
// Forward the event from Svelte.
119+
if (!eventType in forwardDestructors) {
120+
forwardDestructors[eventType] = listen(node, eventType, forward);
121+
}
122+
111123
return destructor;
112124
};
113125

114126
for (let i = 0; i < events.length; i++) {
115127
// Listen to all the events added before mount.
116-
$on(events[i]);
128+
$on(events[i][0], events[i][1]);
117129
}
118130

119131
return {
@@ -122,6 +134,11 @@ export function forwardEventsBuilder(component) {
122134
for (let i = 0; i < destructors.length; i++) {
123135
destructors[i]();
124136
}
137+
138+
// Remove all event forwarders.
139+
for (let entry of Object.entries(forwardDestructors)) {
140+
entry[1]();
141+
}
125142
},
126143
};
127144
};

0 commit comments

Comments
 (0)