happy-dom 9.8.0 → 9.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of happy-dom might be problematic. Click here for more details.
- package/lib/event/Event.d.ts.map +1 -1
- package/lib/event/Event.js +15 -14
- package/lib/event/Event.js.map +1 -1
- package/lib/event/EventTarget.d.ts +9 -0
- package/lib/event/EventTarget.d.ts.map +1 -1
- package/lib/event/EventTarget.js +73 -6
- package/lib/event/EventTarget.js.map +1 -1
- package/lib/nodes/document/Document.d.ts +0 -7
- package/lib/nodes/document/Document.d.ts.map +1 -1
- package/lib/nodes/document/Document.js +0 -13
- package/lib/nodes/document/Document.js.map +1 -1
- package/lib/nodes/element/Element.d.ts.map +1 -1
- package/lib/nodes/element/Element.js +8 -3
- package/lib/nodes/element/Element.js.map +1 -1
- package/lib/nodes/html-button-element/HTMLButtonElement.d.ts.map +1 -1
- package/lib/nodes/html-button-element/HTMLButtonElement.js +7 -2
- package/lib/nodes/html-button-element/HTMLButtonElement.js.map +1 -1
- package/lib/nodes/html-input-element/HTMLInputElement.d.ts.map +1 -1
- package/lib/nodes/html-input-element/HTMLInputElement.js +11 -2
- package/lib/nodes/html-input-element/HTMLInputElement.js.map +1 -1
- package/lib/nodes/node/Node.d.ts +0 -18
- package/lib/nodes/node/Node.d.ts.map +1 -1
- package/lib/nodes/node/Node.js +0 -75
- package/lib/nodes/node/Node.js.map +1 -1
- package/lib/window/Window.d.ts +3 -0
- package/lib/window/Window.d.ts.map +1 -1
- package/lib/window/Window.js +4 -0
- package/lib/window/Window.js.map +1 -1
- package/package.json +1 -1
- package/src/event/Event.ts +15 -14
- package/src/event/EventTarget.ts +92 -8
- package/src/nodes/document/Document.ts +0 -19
- package/src/nodes/element/Element.ts +11 -3
- package/src/nodes/html-button-element/HTMLButtonElement.ts +9 -2
- package/src/nodes/html-input-element/HTMLInputElement.ts +14 -2
- package/src/nodes/node/Node.ts +0 -105
- package/src/window/Window.ts +6 -0
package/src/event/Event.ts
CHANGED
@@ -6,6 +6,7 @@ import IEventTarget from './IEventTarget';
|
|
6
6
|
import NodeTypeEnum from '../nodes/node/NodeTypeEnum';
|
7
7
|
import { performance } from 'perf_hooks';
|
8
8
|
import EventPhaseEnum from './EventPhaseEnum';
|
9
|
+
import IDocument from '../nodes/document/IDocument';
|
9
10
|
|
10
11
|
/**
|
11
12
|
* Event.
|
@@ -77,28 +78,28 @@ export default class Event {
|
|
77
78
|
* @returns Composed path.
|
78
79
|
*/
|
79
80
|
public composedPath(): IEventTarget[] {
|
80
|
-
if (!this.
|
81
|
+
if (!this._target) {
|
81
82
|
return [];
|
82
83
|
}
|
83
84
|
|
84
85
|
const composedPath = [];
|
85
|
-
let eventTarget: INode | IShadowRoot | IWindow = <INode | IShadowRoot>(<unknown>this.
|
86
|
+
let eventTarget: INode | IShadowRoot | IWindow = <INode | IShadowRoot>(<unknown>this._target);
|
86
87
|
|
87
88
|
while (eventTarget) {
|
88
89
|
composedPath.push(eventTarget);
|
89
90
|
|
90
|
-
if (
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
)
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
91
|
+
if ((<INode>(<unknown>eventTarget)).parentNode) {
|
92
|
+
eventTarget = (<INode>(<unknown>eventTarget)).parentNode;
|
93
|
+
} else if (
|
94
|
+
this.composed &&
|
95
|
+
(<INode>eventTarget).nodeType === NodeTypeEnum.documentFragmentNode &&
|
96
|
+
(<IShadowRoot>eventTarget).host
|
97
|
+
) {
|
98
|
+
eventTarget = (<IShadowRoot>eventTarget).host;
|
99
|
+
} else if ((<INode>eventTarget).nodeType === NodeTypeEnum.documentNode) {
|
100
|
+
eventTarget = (<IDocument>(<unknown>eventTarget)).defaultView;
|
101
|
+
} else {
|
102
|
+
break;
|
102
103
|
}
|
103
104
|
}
|
104
105
|
|
package/src/event/EventTarget.ts
CHANGED
@@ -3,6 +3,9 @@ import Event from './Event';
|
|
3
3
|
import IEventTarget from './IEventTarget';
|
4
4
|
import IEventListenerOptions from './IEventListenerOptions';
|
5
5
|
import EventPhaseEnum from './EventPhaseEnum';
|
6
|
+
import INode from '../nodes/node/INode';
|
7
|
+
import IDocument from '../nodes/document/IDocument';
|
8
|
+
import IWindow from '../window/IWindow';
|
6
9
|
|
7
10
|
/**
|
8
11
|
* Handles events.
|
@@ -28,13 +31,23 @@ export default abstract class EventTarget implements IEventTarget {
|
|
28
31
|
listener: ((event: Event) => void) | IEventListener,
|
29
32
|
options?: boolean | IEventListenerOptions
|
30
33
|
): void {
|
34
|
+
const listenerOptions = typeof options === 'boolean' ? { capture: options } : options || null;
|
35
|
+
|
31
36
|
this._listeners[type] = this._listeners[type] || [];
|
32
37
|
this._listenerOptions[type] = this._listenerOptions[type] || [];
|
33
38
|
|
34
39
|
this._listeners[type].push(listener);
|
35
|
-
this._listenerOptions[type].push(
|
36
|
-
|
37
|
-
|
40
|
+
this._listenerOptions[type].push(listenerOptions);
|
41
|
+
|
42
|
+
// Tracks the amount of capture event listeners to improve performance when they are not used.
|
43
|
+
if (listenerOptions && listenerOptions.capture) {
|
44
|
+
const window = this._getWindow();
|
45
|
+
if (window) {
|
46
|
+
window['_captureEventListenerCount'][type] =
|
47
|
+
window['_captureEventListenerCount'][type] ?? 0;
|
48
|
+
window['_captureEventListenerCount'][type]++;
|
49
|
+
}
|
50
|
+
}
|
38
51
|
}
|
39
52
|
|
40
53
|
/**
|
@@ -50,6 +63,14 @@ export default abstract class EventTarget implements IEventTarget {
|
|
50
63
|
if (this._listeners[type]) {
|
51
64
|
const index = this._listeners[type].indexOf(listener);
|
52
65
|
if (index !== -1) {
|
66
|
+
// Tracks the amount of capture event listeners to improve performance when they are not used.
|
67
|
+
if (this._listenerOptions[type][index] && this._listenerOptions[type][index].capture) {
|
68
|
+
const window = this._getWindow();
|
69
|
+
if (window && window['_captureEventListenerCount'][type]) {
|
70
|
+
window['_captureEventListenerCount'][type]--;
|
71
|
+
}
|
72
|
+
}
|
73
|
+
|
53
74
|
this._listeners[type].splice(index, 1);
|
54
75
|
this._listenerOptions[type].splice(index, 1);
|
55
76
|
}
|
@@ -59,21 +80,63 @@ export default abstract class EventTarget implements IEventTarget {
|
|
59
80
|
/**
|
60
81
|
* Dispatches an event.
|
61
82
|
*
|
83
|
+
* @see https://www.w3.org/TR/DOM-Level-3-Events/#event-flow
|
84
|
+
* @see https://www.quirksmode.org/js/events_order.html#link4
|
62
85
|
* @param event Event.
|
63
86
|
* @returns The return value is false if event is cancelable and at least one of the event handlers which handled this event called Event.preventDefault().
|
64
87
|
*/
|
65
88
|
public dispatchEvent(event: Event): boolean {
|
66
|
-
if (
|
89
|
+
if (event.eventPhase === EventPhaseEnum.none) {
|
67
90
|
event._target = this;
|
91
|
+
|
92
|
+
const composedPath = event.composedPath();
|
93
|
+
const window = this._getWindow();
|
94
|
+
|
95
|
+
// Capturing phase
|
96
|
+
|
97
|
+
// We only need to iterate over the composed path if there are capture event listeners.
|
98
|
+
if (window && window['_captureEventListenerCount'][event.type]) {
|
99
|
+
event.eventPhase = EventPhaseEnum.capturing;
|
100
|
+
|
101
|
+
for (let i = composedPath.length - 1; i >= 0; i--) {
|
102
|
+
composedPath[i].dispatchEvent(event);
|
103
|
+
if (event._propagationStopped || event._immediatePropagationStopped) {
|
104
|
+
break;
|
105
|
+
}
|
106
|
+
}
|
107
|
+
}
|
108
|
+
|
109
|
+
// At target phase
|
68
110
|
event.eventPhase = EventPhaseEnum.atTarget;
|
111
|
+
|
112
|
+
this.dispatchEvent(event);
|
113
|
+
|
114
|
+
// Bubbling phase
|
115
|
+
if (event.bubbles && !event._propagationStopped && !event._immediatePropagationStopped) {
|
116
|
+
event.eventPhase = EventPhaseEnum.bubbling;
|
117
|
+
|
118
|
+
for (let i = 1; i < composedPath.length; i++) {
|
119
|
+
composedPath[i].dispatchEvent(event);
|
120
|
+
if (event._propagationStopped || event._immediatePropagationStopped) {
|
121
|
+
break;
|
122
|
+
}
|
123
|
+
}
|
124
|
+
}
|
125
|
+
|
126
|
+
// None phase (completed)
|
127
|
+
event.eventPhase = EventPhaseEnum.none;
|
128
|
+
|
129
|
+
return !(event.cancelable && event.defaultPrevented);
|
69
130
|
}
|
70
131
|
|
71
132
|
event._currentTarget = this;
|
72
133
|
|
73
|
-
|
134
|
+
if (event.eventPhase !== EventPhaseEnum.capturing) {
|
135
|
+
const onEventName = 'on' + event.type.toLowerCase();
|
74
136
|
|
75
|
-
|
76
|
-
|
137
|
+
if (typeof this[onEventName] === 'function') {
|
138
|
+
this[onEventName].call(this, event);
|
139
|
+
}
|
77
140
|
}
|
78
141
|
|
79
142
|
if (this._listeners[event.type]) {
|
@@ -85,7 +148,10 @@ export default abstract class EventTarget implements IEventTarget {
|
|
85
148
|
const listener = listeners[i];
|
86
149
|
const options = listenerOptions[i];
|
87
150
|
|
88
|
-
if (
|
151
|
+
if (
|
152
|
+
(options?.capture && event.eventPhase !== EventPhaseEnum.capturing) ||
|
153
|
+
(!options?.capture && event.eventPhase === EventPhaseEnum.capturing)
|
154
|
+
) {
|
89
155
|
continue;
|
90
156
|
}
|
91
157
|
|
@@ -141,4 +207,22 @@ export default abstract class EventTarget implements IEventTarget {
|
|
141
207
|
public detachEvent(type: string, listener: ((event: Event) => void) | IEventListener): void {
|
142
208
|
this.removeEventListener(type.replace('on', ''), listener);
|
143
209
|
}
|
210
|
+
|
211
|
+
/**
|
212
|
+
* Finds and returns window if possible.
|
213
|
+
*
|
214
|
+
* @returns Window.
|
215
|
+
*/
|
216
|
+
public _getWindow(): IWindow | null {
|
217
|
+
if ((<INode>(<unknown>this)).ownerDocument) {
|
218
|
+
return (<INode>(<unknown>this)).ownerDocument.defaultView;
|
219
|
+
}
|
220
|
+
if ((<IDocument>(<unknown>this)).defaultView) {
|
221
|
+
return (<IDocument>(<unknown>this)).defaultView;
|
222
|
+
}
|
223
|
+
if ((<IWindow>(<unknown>this)).document) {
|
224
|
+
return <IWindow>(<unknown>this);
|
225
|
+
}
|
226
|
+
return null;
|
227
|
+
}
|
144
228
|
}
|
@@ -70,12 +70,6 @@ export default class Document extends Node implements IDocument {
|
|
70
70
|
// Public in order to be accessible by the fetch and xhr.
|
71
71
|
public _cookie = new CookieJar();
|
72
72
|
|
73
|
-
// List of all nodes that has capture listeners.
|
74
|
-
// We need to keep track of them globally as capture listeners are called before other listeners.
|
75
|
-
public readonly _captureEventListenerNodes: {
|
76
|
-
[eventType: string]: INode[];
|
77
|
-
} = {};
|
78
|
-
|
79
73
|
protected _isFirstWrite = true;
|
80
74
|
protected _isFirstWriteAfterOpen = false;
|
81
75
|
|
@@ -969,19 +963,6 @@ export default class Document extends Node implements IDocument {
|
|
969
963
|
return !!this.activeElement;
|
970
964
|
}
|
971
965
|
|
972
|
-
/**
|
973
|
-
* @override
|
974
|
-
*/
|
975
|
-
public dispatchEvent(event: Event): boolean {
|
976
|
-
const returnValue = super.dispatchEvent(event);
|
977
|
-
|
978
|
-
if (event.bubbles && !event._propagationStopped) {
|
979
|
-
return this.defaultView.dispatchEvent(event);
|
980
|
-
}
|
981
|
-
|
982
|
-
return returnValue;
|
983
|
-
}
|
984
|
-
|
985
966
|
/**
|
986
967
|
* Triggered by window when it is ready.
|
987
968
|
*/
|
@@ -31,6 +31,7 @@ import Event from '../../event/Event';
|
|
31
31
|
import ElementUtility from './ElementUtility';
|
32
32
|
import HTMLCollection from './HTMLCollection';
|
33
33
|
import CharacterDataUtility from '../character-data/CharacterDataUtility';
|
34
|
+
import EventPhaseEnum from '../../event/EventPhaseEnum';
|
34
35
|
|
35
36
|
/**
|
36
37
|
* Element.
|
@@ -1041,10 +1042,17 @@ export default class Element extends Node implements IElement {
|
|
1041
1042
|
*/
|
1042
1043
|
public override dispatchEvent(event: Event): boolean {
|
1043
1044
|
const returnValue = super.dispatchEvent(event);
|
1044
|
-
const attribute = this.getAttribute('on' + event.type);
|
1045
1045
|
|
1046
|
-
if (
|
1047
|
-
|
1046
|
+
if (
|
1047
|
+
(event.eventPhase === EventPhaseEnum.atTarget ||
|
1048
|
+
event.eventPhase === EventPhaseEnum.bubbling) &&
|
1049
|
+
!event._immediatePropagationStopped
|
1050
|
+
) {
|
1051
|
+
const attribute = this.getAttribute('on' + event.type);
|
1052
|
+
|
1053
|
+
if (attribute && !event._immediatePropagationStopped) {
|
1054
|
+
this.ownerDocument.defaultView.eval(attribute);
|
1055
|
+
}
|
1048
1056
|
}
|
1049
1057
|
|
1050
1058
|
return returnValue;
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import Event from '../../event/Event';
|
2
|
+
import EventPhaseEnum from '../../event/EventPhaseEnum';
|
2
3
|
import ValidityState from '../../validity-state/ValidityState';
|
3
4
|
import IAttr from '../attr/IAttr';
|
4
5
|
import IDocument from '../document/IDocument';
|
@@ -210,13 +211,19 @@ export default class HTMLButtonElement extends HTMLElement implements IHTMLButto
|
|
210
211
|
* @override
|
211
212
|
*/
|
212
213
|
public override dispatchEvent(event: Event): boolean {
|
213
|
-
if (event.type === 'click' && this.disabled) {
|
214
|
+
if (event.type === 'click' && event.eventPhase === EventPhaseEnum.none && this.disabled) {
|
214
215
|
return false;
|
215
216
|
}
|
216
217
|
|
217
218
|
const returnValue = super.dispatchEvent(event);
|
218
219
|
|
219
|
-
if (
|
220
|
+
if (
|
221
|
+
event.type === 'click' &&
|
222
|
+
(event.eventPhase === EventPhaseEnum.atTarget ||
|
223
|
+
event.eventPhase === EventPhaseEnum.bubbling) &&
|
224
|
+
this._formNode &&
|
225
|
+
this.isConnected
|
226
|
+
) {
|
220
227
|
const form = <IHTMLFormElement>this._formNode;
|
221
228
|
switch (this.type) {
|
222
229
|
case 'submit':
|
@@ -21,6 +21,7 @@ import IHTMLLabelElement from '../html-label-element/IHTMLLabelElement';
|
|
21
21
|
import IDocument from '../document/IDocument';
|
22
22
|
import IShadowRoot from '../shadow-root/IShadowRoot';
|
23
23
|
import NodeList from '../node/NodeList';
|
24
|
+
import EventPhaseEnum from '../../event/EventPhaseEnum';
|
24
25
|
|
25
26
|
/**
|
26
27
|
* HTML Input Element.
|
@@ -1039,19 +1040,30 @@ export default class HTMLInputElement extends HTMLElement implements IHTMLInputE
|
|
1039
1040
|
* @override
|
1040
1041
|
*/
|
1041
1042
|
public override dispatchEvent(event: Event): boolean {
|
1042
|
-
if (event.type === 'click' && this.disabled) {
|
1043
|
+
if (event.type === 'click' && event.eventPhase === EventPhaseEnum.none && this.disabled) {
|
1043
1044
|
return false;
|
1044
1045
|
}
|
1045
1046
|
|
1047
|
+
if (
|
1048
|
+
event.type === 'click' &&
|
1049
|
+
(event.eventPhase === EventPhaseEnum.atTarget ||
|
1050
|
+
event.eventPhase === EventPhaseEnum.bubbling) &&
|
1051
|
+
this.isConnected &&
|
1052
|
+
(this.type === 'checkbox' || this.type === 'radio')
|
1053
|
+
) {
|
1054
|
+
this.checked = this.type === 'checkbox' ? !this.checked : true;
|
1055
|
+
}
|
1056
|
+
|
1046
1057
|
const returnValue = super.dispatchEvent(event);
|
1047
1058
|
|
1048
1059
|
if (
|
1049
1060
|
event.type === 'click' &&
|
1061
|
+
(event.eventPhase === EventPhaseEnum.atTarget ||
|
1062
|
+
event.eventPhase === EventPhaseEnum.bubbling) &&
|
1050
1063
|
this.isConnected &&
|
1051
1064
|
(!this.readOnly || this.type === 'checkbox' || this.type === 'radio')
|
1052
1065
|
) {
|
1053
1066
|
if (this.type === 'checkbox' || this.type === 'radio') {
|
1054
|
-
this.checked = this.type === 'checkbox' ? !this.checked : true;
|
1055
1067
|
this.dispatchEvent(new Event('input', { bubbles: true, cancelable: true }));
|
1056
1068
|
this.dispatchEvent(new Event('change', { bubbles: true, cancelable: true }));
|
1057
1069
|
} else if (this.type === 'submit') {
|
package/src/nodes/node/Node.ts
CHANGED
@@ -2,7 +2,6 @@ import EventTarget from '../../event/EventTarget';
|
|
2
2
|
import MutationRecord from '../../mutation-observer/MutationRecord';
|
3
3
|
import MutationTypeEnum from '../../mutation-observer/MutationTypeEnum';
|
4
4
|
import MutationListener from '../../mutation-observer/MutationListener';
|
5
|
-
import Event from '../../event/Event';
|
6
5
|
import INode from './INode';
|
7
6
|
import DOMException from '../../exception/DOMException';
|
8
7
|
import IDocument from '../document/IDocument';
|
@@ -14,10 +13,6 @@ import NodeUtility from './NodeUtility';
|
|
14
13
|
import IAttr from '../attr/IAttr';
|
15
14
|
import NodeList from './NodeList';
|
16
15
|
import INodeList from './INodeList';
|
17
|
-
import IShadowRoot from '../shadow-root/IShadowRoot';
|
18
|
-
import IEventListener from '../../event/IEventListener';
|
19
|
-
import IEventListenerOptions from '../../event/IEventListenerOptions';
|
20
|
-
import EventPhaseEnum from '../../event/EventPhaseEnum';
|
21
16
|
|
22
17
|
const JSON_CIRCULAR_PROPERTIES = [
|
23
18
|
'ownerDocument',
|
@@ -481,106 +476,6 @@ export default class Node extends EventTarget implements INode {
|
|
481
476
|
return oldChild;
|
482
477
|
}
|
483
478
|
|
484
|
-
/**
|
485
|
-
* @override
|
486
|
-
*/
|
487
|
-
public override addEventListener(
|
488
|
-
type: string,
|
489
|
-
listener: ((event: Event) => void) | IEventListener,
|
490
|
-
options?: boolean | IEventListenerOptions
|
491
|
-
): void {
|
492
|
-
super.addEventListener(type, listener, options);
|
493
|
-
|
494
|
-
if (options === true || (options && options.capture)) {
|
495
|
-
const captureEventListenerNodes = this.ownerDocument
|
496
|
-
? <{ [eventType: string]: INode[] }>this.ownerDocument['_captureEventListenerNodes']
|
497
|
-
: <{ [eventType: string]: INode[] }>this['_captureEventListenerNodes'];
|
498
|
-
|
499
|
-
captureEventListenerNodes[type] = captureEventListenerNodes[type] || [];
|
500
|
-
|
501
|
-
if (!captureEventListenerNodes[type].includes(this)) {
|
502
|
-
captureEventListenerNodes[type].push(this);
|
503
|
-
}
|
504
|
-
}
|
505
|
-
}
|
506
|
-
|
507
|
-
/**
|
508
|
-
* Adds an event listener.
|
509
|
-
*
|
510
|
-
* @param type Event type.
|
511
|
-
* @param listener Listener.
|
512
|
-
*/
|
513
|
-
public override removeEventListener(
|
514
|
-
type: string,
|
515
|
-
listener: ((event: Event) => void) | IEventListener
|
516
|
-
): void {
|
517
|
-
const index = this._listeners[type]?.indexOf(listener) || -1;
|
518
|
-
const options = index !== -1 ? this._listenerOptions[type][index] : null;
|
519
|
-
|
520
|
-
if (options?.capture) {
|
521
|
-
const captureEventListenerNodes = this.ownerDocument
|
522
|
-
? <{ [eventType: string]: INode[] }>this.ownerDocument['_captureEventListenerNodes']
|
523
|
-
: <{ [eventType: string]: INode[] }>this['_captureEventListenerNodes'];
|
524
|
-
|
525
|
-
if (captureEventListenerNodes[type]) {
|
526
|
-
const index = captureEventListenerNodes[type].indexOf(this);
|
527
|
-
if (index !== -1) {
|
528
|
-
captureEventListenerNodes[type].splice(index, 1);
|
529
|
-
}
|
530
|
-
}
|
531
|
-
}
|
532
|
-
|
533
|
-
super.removeEventListener(type, listener);
|
534
|
-
}
|
535
|
-
|
536
|
-
/**
|
537
|
-
* @override
|
538
|
-
*/
|
539
|
-
public override dispatchEvent(event: Event): boolean {
|
540
|
-
// Capture phase
|
541
|
-
if (!event._target) {
|
542
|
-
const captureEventListenerNodes = this.ownerDocument
|
543
|
-
? <{ [eventType: string]: INode[] }>this.ownerDocument['_captureEventListenerNodes']
|
544
|
-
: <{ [eventType: string]: INode[] }>this['_captureEventListenerNodes'];
|
545
|
-
|
546
|
-
if (captureEventListenerNodes[event.type]) {
|
547
|
-
event._target = this;
|
548
|
-
event.eventPhase = EventPhaseEnum.capturing;
|
549
|
-
|
550
|
-
for (const node of captureEventListenerNodes[event.type]) {
|
551
|
-
if (node !== this && NodeUtility.contains(node, this, event.composed)) {
|
552
|
-
node.dispatchEvent(event);
|
553
|
-
}
|
554
|
-
}
|
555
|
-
|
556
|
-
event.eventPhase = EventPhaseEnum.atTarget;
|
557
|
-
}
|
558
|
-
}
|
559
|
-
|
560
|
-
const returnValue = super.dispatchEvent(event);
|
561
|
-
|
562
|
-
// Bubbling phase
|
563
|
-
if (event.bubbles && !event._propagationStopped && !event._immediatePropagationStopped) {
|
564
|
-
event.eventPhase = EventPhaseEnum.bubbling;
|
565
|
-
|
566
|
-
if (this.parentNode) {
|
567
|
-
return this.parentNode.dispatchEvent(event);
|
568
|
-
}
|
569
|
-
|
570
|
-
// eslint-disable-next-line
|
571
|
-
if (
|
572
|
-
event.composed &&
|
573
|
-
this.nodeType === NodeTypeEnum.documentFragmentNode &&
|
574
|
-
(<IShadowRoot>(<unknown>this)).host
|
575
|
-
) {
|
576
|
-
// eslint-disable-next-line
|
577
|
-
return (<IShadowRoot>(<unknown>this)).host.dispatchEvent(event);
|
578
|
-
}
|
579
|
-
}
|
580
|
-
|
581
|
-
return returnValue;
|
582
|
-
}
|
583
|
-
|
584
479
|
/**
|
585
480
|
* Converts the node to a string.
|
586
481
|
*
|
package/src/window/Window.ts
CHANGED
@@ -393,6 +393,12 @@ export default class Window extends EventTarget implements IWindow {
|
|
393
393
|
public Object;
|
394
394
|
public Function;
|
395
395
|
|
396
|
+
// Public internal properties
|
397
|
+
|
398
|
+
// Used for tracking capture event listeners to improve performance when they are not used.
|
399
|
+
// See EventTarget class.
|
400
|
+
public _captureEventListenerCount: { [eventType: string]: number } = {};
|
401
|
+
|
396
402
|
// Private properties
|
397
403
|
private _setTimeout;
|
398
404
|
private _clearTimeout;
|