@@ -19,7 +19,9 @@ import { withNullAsUndefined } from 'vs/base/common/types';
19
19
import { URI } from 'vs/base/common/uri' ;
20
20
21
21
export function clearNode ( node : HTMLElement ) : void {
22
- node . replaceChildren ( ) ;
22
+ while ( node . firstChild ) {
23
+ node . firstChild . remove ( ) ;
24
+ }
23
25
}
24
26
25
27
/**
@@ -29,20 +31,40 @@ export function isInDOM(node: Node | null): boolean {
29
31
return node ?. isConnected ?? false ;
30
32
}
31
33
32
- export function addDisposableListener < K extends keyof GlobalEventHandlersEventMap > ( node : EventTarget , type : K , handler : ( event : GlobalEventHandlersEventMap [ K ] ) => void , useCaptureOrOptions ?: boolean | AddEventListenerOptions ) : IDisposable ;
33
- export function addDisposableListener ( node : EventTarget , type : string , handler : ( event : any ) => void , useCaptureOrOptions ?: boolean | AddEventListenerOptions ) : IDisposable ;
34
- export function addDisposableListener ( node : EventTarget , type : string , handler : ( event : any ) => void , useCaptureOrOptions ?: boolean | AddEventListenerOptions ) : IDisposable {
35
- let controller : AbortController | undefined = new AbortController ( ) ;
34
+ class DomListener implements IDisposable {
36
35
37
- const opts : AddEventListenerOptions = typeof useCaptureOrOptions === 'boolean'
38
- ? { capture : useCaptureOrOptions , signal : controller . signal }
39
- : { signal : controller . signal , ...( useCaptureOrOptions ?? { } ) } ;
36
+ private _handler : ( e : any ) => void ;
37
+ private _node : EventTarget ;
38
+ private readonly _type : string ;
39
+ private readonly _options : boolean | AddEventListenerOptions ;
40
40
41
- node . addEventListener ( type , handler , opts ) ;
42
- return toDisposable ( ( ) => {
43
- controller ?. abort ( ) ;
44
- controller = undefined ;
45
- } ) ;
41
+ constructor ( node : EventTarget , type : string , handler : ( e : any ) => void , options ?: boolean | AddEventListenerOptions ) {
42
+ this . _node = node ;
43
+ this . _type = type ;
44
+ this . _handler = handler ;
45
+ this . _options = ( options || false ) ;
46
+ this . _node . addEventListener ( this . _type , this . _handler , this . _options ) ;
47
+ }
48
+
49
+ public dispose ( ) : void {
50
+ if ( ! this . _handler ) {
51
+ // Already disposed
52
+ return ;
53
+ }
54
+
55
+ this . _node . removeEventListener ( this . _type , this . _handler , this . _options ) ;
56
+
57
+ // Prevent leakers from holding on to the dom or handler func
58
+ this . _node = null ! ;
59
+ this . _handler = null ! ;
60
+ }
61
+ }
62
+
63
+ export function addDisposableListener < K extends keyof GlobalEventHandlersEventMap > ( node : EventTarget , type : K , handler : ( event : GlobalEventHandlersEventMap [ K ] ) => void , useCapture ?: boolean ) : IDisposable ;
64
+ export function addDisposableListener ( node : EventTarget , type : string , handler : ( event : any ) => void , useCapture ?: boolean ) : IDisposable ;
65
+ export function addDisposableListener ( node : EventTarget , type : string , handler : ( event : any ) => void , options : AddEventListenerOptions ) : IDisposable ;
66
+ export function addDisposableListener ( node : EventTarget , type : string , handler : ( event : any ) => void , useCaptureOrOptions ?: boolean | AddEventListenerOptions ) : IDisposable {
67
+ return new DomListener ( node , type , handler , useCaptureOrOptions ) ;
46
68
}
47
69
48
70
export interface IAddStandardDisposableListenerSignature {
0 commit comments