@@ -16,20 +16,18 @@ import {
1616 set_hydrating
1717} from './dom/hydration.js' ;
1818import { 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' ;
2024import { reset_head_anchor } from './dom/blocks/svelte-head.js' ;
2125import * as w from './warnings.js' ;
2226import * as e from './errors.js' ;
2327import { validate_component } from '../shared/validate.js' ;
2428import { assign_nodes } from './dom/template.js' ;
2529import { queue_micro_task } from './dom/task.js' ;
2630
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-
3331/**
3432 * This is normally true — block effects should run their intro transitions —
3533 * but is false during hydration (unless `options.intro` is `true`) and
@@ -182,6 +180,9 @@ export function hydrate(component, options) {
182180 }
183181}
184182
183+ /** @type {Map<string, number> } */
184+ const document_listeners = new Map ( ) ;
185+
185186/**
186187 * @template {Record<string, any>} Exports
187188 * @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) {
198199function _mount ( Component , { target, anchor, props = { } , events, context, intro = true } ) {
199200 init_operations ( ) ;
200201
201- const registered_events = new Set ( ) ;
202+ var registered_events = new Set ( ) ;
202203
203204 /** @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 ] ;
208208
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 ) ;
211211
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 ) ;
216213
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 ) {
217222 // The document listener ensures we catch events that originate from elements that were
218223 // manually moved outside of the container (e.g. via manual portals).
219224 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 ) ;
220228 }
221229 }
222230 } ;
@@ -226,9 +234,9 @@ function _mount(Component, { target, anchor, props = {}, events, context, intro
226234
227235 /** @type {Exports } */
228236 // @ts -expect-error will be defined because the render effect runs synchronously
229- let component = undefined ;
237+ var component = undefined ;
230238
231- const unmount = effect_root ( ( ) => {
239+ var unmount = effect_root ( ( ) => {
232240 branch ( ( ) => {
233241 if ( context ) {
234242 push ( { } ) ;
@@ -262,9 +270,17 @@ function _mount(Component, { target, anchor, props = {}, events, context, intro
262270 } ) ;
263271
264272 return ( ) => {
265- for ( const event_name of registered_events ) {
273+ for ( var event_name of registered_events ) {
266274 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+ }
268284 }
269285
270286 root_event_handles . delete ( event_handle ) ;
0 commit comments