@@ -16,20 +16,18 @@ import {
16
16
set_hydrating
17
17
} from './dom/hydration.js' ;
18
18
import { array_from } from './utils.js' ;
19
- import { handle_event_propagation } from './dom/elements/events.js' ;
19
+ import {
20
+ all_registered_events ,
21
+ handle_event_propagation ,
22
+ root_event_handles
23
+ } from './dom/elements/events.js' ;
20
24
import { reset_head_anchor } from './dom/blocks/svelte-head.js' ;
21
25
import * as w from './warnings.js' ;
22
26
import * as e from './errors.js' ;
23
27
import { validate_component } from '../shared/validate.js' ;
24
28
import { assign_nodes } from './dom/template.js' ;
25
29
import { queue_micro_task } from './dom/task.js' ;
26
30
27
- /** @type {Set<string> } */
28
- export const all_registered_events = new Set ( ) ;
29
-
30
- /** @type {Set<(events: Array<string>) => void> } */
31
- export const root_event_handles = new Set ( ) ;
32
-
33
31
/**
34
32
* This is normally true — block effects should run their intro transitions —
35
33
* but is false during hydration (unless `options.intro` is `true`) and
@@ -182,6 +180,9 @@ export function hydrate(component, options) {
182
180
}
183
181
}
184
182
183
+ /** @type {Map<string, number> } */
184
+ const document_listeners = new Map ( ) ;
185
+
185
186
/**
186
187
* @template {Record<string, any>} Exports
187
188
* @param {import('../../index.js').ComponentType<import('../../index.js').SvelteComponent<any>> | import('../../index.js').Component<any> } Component
@@ -198,25 +199,32 @@ export function hydrate(component, options) {
198
199
function _mount ( Component , { target, anchor, props = { } , events, context, intro = true } ) {
199
200
init_operations ( ) ;
200
201
201
- const registered_events = new Set ( ) ;
202
+ var registered_events = new Set ( ) ;
202
203
203
204
/** @param {Array<string> } events */
204
- const event_handle = ( events ) => {
205
- for ( let i = 0 ; i < events . length ; i ++ ) {
206
- const event_name = events [ i ] ;
207
- const passive = PassiveDelegatedEvents . includes ( event_name ) ;
205
+ var event_handle = ( events ) => {
206
+ for ( var i = 0 ; i < events . length ; i ++ ) {
207
+ var event_name = events [ i ] ;
208
208
209
- if ( ! registered_events . has ( event_name ) ) {
210
- registered_events . add ( event_name ) ;
209
+ if ( registered_events . has ( event_name ) ) continue ;
210
+ registered_events . add ( event_name ) ;
211
211
212
- // Add the event listener to both the container and the document.
213
- // The container listener ensures we catch events from within in case
214
- // the outer content stops propagation of the event.
215
- target . addEventListener ( event_name , handle_event_propagation , { passive } ) ;
212
+ var passive = PassiveDelegatedEvents . includes ( event_name ) ;
216
213
214
+ // Add the event listener to both the container and the document.
215
+ // The container listener ensures we catch events from within in case
216
+ // the outer content stops propagation of the event.
217
+ target . addEventListener ( event_name , handle_event_propagation , { passive } ) ;
218
+
219
+ var n = document_listeners . get ( event_name ) ;
220
+
221
+ if ( n === undefined ) {
217
222
// The document listener ensures we catch events that originate from elements that were
218
223
// manually moved outside of the container (e.g. via manual portals).
219
224
document . addEventListener ( event_name , handle_event_propagation , { passive } ) ;
225
+ document_listeners . set ( event_name , 1 ) ;
226
+ } else {
227
+ document_listeners . set ( event_name , n + 1 ) ;
220
228
}
221
229
}
222
230
} ;
@@ -226,9 +234,9 @@ function _mount(Component, { target, anchor, props = {}, events, context, intro
226
234
227
235
/** @type {Exports } */
228
236
// @ts -expect-error will be defined because the render effect runs synchronously
229
- let component = undefined ;
237
+ var component = undefined ;
230
238
231
- const unmount = effect_root ( ( ) => {
239
+ var unmount = effect_root ( ( ) => {
232
240
branch ( ( ) => {
233
241
if ( context ) {
234
242
push ( { } ) ;
@@ -262,9 +270,17 @@ function _mount(Component, { target, anchor, props = {}, events, context, intro
262
270
} ) ;
263
271
264
272
return ( ) => {
265
- for ( const event_name of registered_events ) {
273
+ for ( var event_name of registered_events ) {
266
274
target . removeEventListener ( event_name , handle_event_propagation ) ;
267
- document . removeEventListener ( event_name , handle_event_propagation ) ;
275
+
276
+ var n = /** @type {number } */ ( document_listeners . get ( event_name ) ) ;
277
+
278
+ if ( -- n === 0 ) {
279
+ document . removeEventListener ( event_name , handle_event_propagation ) ;
280
+ document_listeners . delete ( event_name ) ;
281
+ } else {
282
+ document_listeners . set ( event_name , n ) ;
283
+ }
268
284
}
269
285
270
286
root_event_handles . delete ( event_handle ) ;
0 commit comments