@ -16,7 +16,11 @@ import {
set _hydrating
set _hydrating
} from './dom/hydration.js' ;
} from './dom/hydration.js' ;
import { array _from } from './utils.js' ;
import { array _from } from './utils.js' ;
import { handle _event _propagation } from './dom/elements/events.js' ;
import {
all _registered _events ,
handle _event _propagation ,
root _event _handles
} from './dom/elements/events.js' ;
import { reset _head _anchor } from './dom/blocks/svelte-head.js' ;
import { reset _head _anchor } from './dom/blocks/svelte-head.js' ;
import * as w from './warnings.js' ;
import * as w from './warnings.js' ;
import * as e from './errors.js' ;
import * as e from './errors.js' ;
@ -24,12 +28,6 @@ import { validate_component } from '../shared/validate.js';
import { assign _nodes } from './dom/template.js' ;
import { assign _nodes } from './dom/template.js' ;
import { queue _micro _task } from './dom/task.js' ;
import { queue _micro _task } from './dom/task.js' ;
/** @type {Set<string>} */
export const all _registered _events = new Set ( ) ;
/** @type {Set<(events: Array<string>) => void>} */
export const root _event _handles = new Set ( ) ;
/ * *
/ * *
* This is normally true — block effects should run their intro transitions —
* This is normally true — block effects should run their intro transitions —
* but is false during hydration ( unless ` options.intro ` is ` true ` ) and
* but is false during hydration ( unless ` options.intro ` is ` true ` ) and
@ -182,6 +180,9 @@ export function hydrate(component, options) {
}
}
}
}
/** @type {Map<string, number>} */
const document _listeners = new Map ( ) ;
/ * *
/ * *
* @ template { Record < string , any > } Exports
* @ template { Record < string , any > } Exports
* @ param { import ( '../../index.js' ) . ComponentType < import ( '../../index.js' ) . SvelteComponent < any >> | import ( '../../index.js' ) . Component < any > } Component
* @ 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) {
function _mount ( Component , { target , anchor , props = { } , events , context , intro = true } ) {
function _mount ( Component , { target , anchor , props = { } , events , context , intro = true } ) {
init _operations ( ) ;
init _operations ( ) ;
const registered _events = new Set ( ) ;
var registered _events = new Set ( ) ;
/** @param {Array<string>} events */
/** @param {Array<string>} events */
const event _handle = ( events ) => {
var event _handle = ( events ) => {
for ( let i = 0 ; i < events . length ; i ++ ) {
for ( var i = 0 ; i < events . length ; i ++ ) {
const event _name = events [ i ] ;
var event _name = events [ i ] ;
const passive = PassiveDelegatedEvents . includes ( event _name ) ;
if ( ! registered _events . has ( event _name ) ) {
if ( registered _events . has ( event _name ) ) continue ;
registered _events . add ( event _name ) ;
registered _events . add ( event _name ) ;
// Add the event listener to both the container and the document.
var passive = PassiveDelegatedEvents . includes ( event _name ) ;
// The container listener ensures we catch events from within in case
// the outer content stops propagation of the event.
target . addEventListener ( event _name , handle _event _propagation , { passive } ) ;
// Add the event listener to both the container and the document.
// The container listener ensures we catch events from within in case
// the outer content stops propagation of the event.
target . addEventListener ( event _name , handle _event _propagation , { passive } ) ;
var n = document _listeners . get ( event _name ) ;
if ( n === undefined ) {
// The document listener ensures we catch events that originate from elements that were
// The document listener ensures we catch events that originate from elements that were
// manually moved outside of the container (e.g. via manual portals).
// manually moved outside of the container (e.g. via manual portals).
document . addEventListener ( event _name , handle _event _propagation , { passive } ) ;
document . addEventListener ( event _name , handle _event _propagation , { passive } ) ;
document _listeners . set ( event _name , 1 ) ;
} else {
document _listeners . set ( event _name , n + 1 ) ;
}
}
}
}
} ;
} ;
@ -226,9 +234,9 @@ function _mount(Component, { target, anchor, props = {}, events, context, intro
/** @type {Exports} */
/** @type {Exports} */
// @ts-expect-error will be defined because the render effect runs synchronously
// @ts-expect-error will be defined because the render effect runs synchronously
let component = undefined ;
var component = undefined ;
const unmount = effect _root ( ( ) => {
var unmount = effect _root ( ( ) => {
branch ( ( ) => {
branch ( ( ) => {
if ( context ) {
if ( context ) {
push ( { } ) ;
push ( { } ) ;
@ -262,9 +270,17 @@ function _mount(Component, { target, anchor, props = {}, events, context, intro
} ) ;
} ) ;
return ( ) => {
return ( ) => {
for ( const event _name of registered _events ) {
for ( var event _name of registered _events ) {
target . removeEventListener ( event _name , handle _event _propagation ) ;
target . removeEventListener ( event _name , handle _event _propagation ) ;
document . removeEventListener ( event _name , handle _event _propagation ) ;
var n = /** @type {number} */ ( document _listeners . get ( event _name ) ) ;
if ( -- n === 0 ) {
document . removeEventListener ( event _name , handle _event _propagation ) ;
document _listeners . delete ( event _name ) ;
} else {
document _listeners . set ( event _name , n ) ;
}
}
}
root _event _handles . delete ( event _handle ) ;
root _event _handles . delete ( event _handle ) ;