happy-dom 13.3.8 → 13.4.1
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/README.md +3 -0
- package/cjs/PropertySymbol.cjs +3 -1
- package/cjs/PropertySymbol.cjs.map +1 -1
- package/cjs/PropertySymbol.d.ts +2 -0
- package/cjs/PropertySymbol.d.ts.map +1 -1
- package/cjs/browser/detached-browser/DetachedBrowserPage.cjs +5 -3
- package/cjs/browser/detached-browser/DetachedBrowserPage.cjs.map +1 -1
- package/cjs/browser/detached-browser/DetachedBrowserPage.d.ts.map +1 -1
- package/cjs/browser/utilities/BrowserFrameExceptionObserver.cjs +6 -0
- package/cjs/browser/utilities/BrowserFrameExceptionObserver.cjs.map +1 -1
- package/cjs/browser/utilities/BrowserFrameExceptionObserver.d.ts.map +1 -1
- package/cjs/browser/utilities/BrowserFrameFactory.cjs +14 -6
- package/cjs/browser/utilities/BrowserFrameFactory.cjs.map +1 -1
- package/cjs/browser/utilities/BrowserFrameFactory.d.ts.map +1 -1
- package/cjs/config/HTMLElementLocalNameToClass.cjs +122 -0
- package/{lib/config/ElementTag.js.map → cjs/config/HTMLElementLocalNameToClass.cjs.map} +1 -1
- package/cjs/config/{ElementTag.d.ts → HTMLElementLocalNameToClass.d.ts} +1 -1
- package/cjs/config/HTMLElementLocalNameToClass.d.ts.map +1 -0
- package/cjs/config/{PlainTextElements.cjs → HTMLElementPlainText.cjs} +1 -1
- package/cjs/config/HTMLElementPlainText.cjs.map +1 -0
- package/{lib/config/PlainTextElements.d.ts → cjs/config/HTMLElementPlainText.d.ts} +1 -1
- package/cjs/config/HTMLElementPlainText.d.ts.map +1 -0
- package/cjs/config/{UnnestableElements.cjs → HTMLElementUnnestable.cjs} +1 -1
- package/cjs/config/HTMLElementUnnestable.cjs.map +1 -0
- package/{lib/config/UnnestableElements.d.ts → cjs/config/HTMLElementUnnestable.d.ts} +1 -1
- package/cjs/config/HTMLElementUnnestable.d.ts.map +1 -0
- package/cjs/config/{VoidElements.cjs → HTMLElementVoid.cjs} +1 -1
- package/cjs/config/HTMLElementVoid.cjs.map +1 -0
- package/{lib/config/VoidElements.d.ts → cjs/config/HTMLElementVoid.d.ts} +1 -1
- package/cjs/config/HTMLElementVoid.d.ts.map +1 -0
- package/cjs/config/NamespaceURI.cjs +2 -1
- package/cjs/config/NamespaceURI.cjs.map +1 -1
- package/cjs/config/NamespaceURI.d.ts +1 -0
- package/cjs/config/NamespaceURI.d.ts.map +1 -1
- package/cjs/custom-element/CustomElementRegistry.cjs +67 -30
- package/cjs/custom-element/CustomElementRegistry.cjs.map +1 -1
- package/cjs/custom-element/CustomElementRegistry.d.ts +18 -10
- package/cjs/custom-element/CustomElementRegistry.d.ts.map +1 -1
- package/cjs/navigator/Navigator.cjs +2 -2
- package/cjs/navigator/Navigator.cjs.map +1 -1
- package/cjs/navigator/Navigator.d.ts.map +1 -1
- package/cjs/nodes/document/Document.cjs +44 -16
- package/cjs/nodes/document/Document.cjs.map +1 -1
- package/cjs/nodes/document/Document.d.ts.map +1 -1
- package/cjs/nodes/element/Element.cjs +8 -6
- package/cjs/nodes/element/Element.cjs.map +1 -1
- package/cjs/nodes/element/Element.d.ts +1 -0
- package/cjs/nodes/element/Element.d.ts.map +1 -1
- package/cjs/nodes/html-element/HTMLElement.cjs +89 -2
- package/cjs/nodes/html-element/HTMLElement.cjs.map +1 -1
- package/cjs/nodes/html-element/HTMLElement.d.ts +8 -0
- package/cjs/nodes/html-element/HTMLElement.d.ts.map +1 -1
- package/cjs/nodes/html-unknown-element/HTMLUnknownElement.cjs +0 -126
- package/cjs/nodes/html-unknown-element/HTMLUnknownElement.cjs.map +1 -1
- package/cjs/nodes/html-unknown-element/HTMLUnknownElement.d.ts +0 -9
- package/cjs/nodes/html-unknown-element/HTMLUnknownElement.d.ts.map +1 -1
- package/cjs/nodes/parent-node/ParentNodeUtility.cjs +5 -3
- package/cjs/nodes/parent-node/ParentNodeUtility.cjs.map +1 -1
- package/cjs/nodes/parent-node/ParentNodeUtility.d.ts.map +1 -1
- package/cjs/nodes/svg-element/SVGElement.cjs +1 -1
- package/cjs/nodes/svg-element/SVGElement.cjs.map +1 -1
- package/cjs/version.cjs +1 -1
- package/cjs/window/BrowserWindow.cjs +10 -1
- package/cjs/window/BrowserWindow.cjs.map +1 -1
- package/cjs/window/BrowserWindow.d.ts.map +1 -1
- package/cjs/window/DetachedWindowAPI.cjs +6 -0
- package/cjs/window/DetachedWindowAPI.cjs.map +1 -1
- package/cjs/window/DetachedWindowAPI.d.ts +4 -0
- package/cjs/window/DetachedWindowAPI.d.ts.map +1 -1
- package/cjs/xml-parser/XMLParser.cjs +17 -13
- package/cjs/xml-parser/XMLParser.cjs.map +1 -1
- package/cjs/xml-parser/XMLParser.d.ts.map +1 -1
- package/cjs/xml-serializer/XMLSerializer.cjs +6 -6
- package/cjs/xml-serializer/XMLSerializer.cjs.map +1 -1
- package/lib/PropertySymbol.d.ts +2 -0
- package/lib/PropertySymbol.d.ts.map +1 -1
- package/lib/PropertySymbol.js +2 -0
- package/lib/PropertySymbol.js.map +1 -1
- package/lib/browser/detached-browser/DetachedBrowserPage.d.ts.map +1 -1
- package/lib/browser/detached-browser/DetachedBrowserPage.js +5 -3
- package/lib/browser/detached-browser/DetachedBrowserPage.js.map +1 -1
- package/lib/browser/utilities/BrowserFrameExceptionObserver.d.ts.map +1 -1
- package/lib/browser/utilities/BrowserFrameExceptionObserver.js +6 -0
- package/lib/browser/utilities/BrowserFrameExceptionObserver.js.map +1 -1
- package/lib/browser/utilities/BrowserFrameFactory.d.ts.map +1 -1
- package/lib/browser/utilities/BrowserFrameFactory.js +14 -6
- package/lib/browser/utilities/BrowserFrameFactory.js.map +1 -1
- package/lib/config/{ElementTag.d.ts → HTMLElementLocalNameToClass.d.ts} +1 -1
- package/lib/config/HTMLElementLocalNameToClass.d.ts.map +1 -0
- package/lib/config/HTMLElementLocalNameToClass.js +120 -0
- package/lib/config/HTMLElementLocalNameToClass.js.map +1 -0
- package/{cjs/config/PlainTextElements.d.ts → lib/config/HTMLElementPlainText.d.ts} +1 -1
- package/lib/config/HTMLElementPlainText.d.ts.map +1 -0
- package/lib/config/{PlainTextElements.js → HTMLElementPlainText.js} +1 -1
- package/lib/config/HTMLElementPlainText.js.map +1 -0
- package/{cjs/config/UnnestableElements.d.ts → lib/config/HTMLElementUnnestable.d.ts} +1 -1
- package/lib/config/HTMLElementUnnestable.d.ts.map +1 -0
- package/lib/config/{UnnestableElements.js → HTMLElementUnnestable.js} +1 -1
- package/lib/config/HTMLElementUnnestable.js.map +1 -0
- package/{cjs/config/VoidElements.d.ts → lib/config/HTMLElementVoid.d.ts} +1 -1
- package/lib/config/HTMLElementVoid.d.ts.map +1 -0
- package/lib/config/{VoidElements.js → HTMLElementVoid.js} +1 -1
- package/lib/config/HTMLElementVoid.js.map +1 -0
- package/lib/config/NamespaceURI.d.ts +1 -0
- package/lib/config/NamespaceURI.d.ts.map +1 -1
- package/lib/config/NamespaceURI.js +2 -1
- package/lib/config/NamespaceURI.js.map +1 -1
- package/lib/custom-element/CustomElementRegistry.d.ts +18 -10
- package/lib/custom-element/CustomElementRegistry.d.ts.map +1 -1
- package/lib/custom-element/CustomElementRegistry.js +67 -30
- package/lib/custom-element/CustomElementRegistry.js.map +1 -1
- package/lib/navigator/Navigator.d.ts.map +1 -1
- package/lib/navigator/Navigator.js +2 -2
- package/lib/navigator/Navigator.js.map +1 -1
- package/lib/nodes/document/Document.d.ts.map +1 -1
- package/lib/nodes/document/Document.js +44 -16
- package/lib/nodes/document/Document.js.map +1 -1
- package/lib/nodes/element/Element.d.ts +1 -0
- package/lib/nodes/element/Element.d.ts.map +1 -1
- package/lib/nodes/element/Element.js +8 -6
- package/lib/nodes/element/Element.js.map +1 -1
- package/lib/nodes/html-element/HTMLElement.d.ts +8 -0
- package/lib/nodes/html-element/HTMLElement.d.ts.map +1 -1
- package/lib/nodes/html-element/HTMLElement.js +90 -4
- package/lib/nodes/html-element/HTMLElement.js.map +1 -1
- package/lib/nodes/html-unknown-element/HTMLUnknownElement.d.ts +0 -9
- package/lib/nodes/html-unknown-element/HTMLUnknownElement.d.ts.map +1 -1
- package/lib/nodes/html-unknown-element/HTMLUnknownElement.js +0 -103
- package/lib/nodes/html-unknown-element/HTMLUnknownElement.js.map +1 -1
- package/lib/nodes/parent-node/ParentNodeUtility.d.ts.map +1 -1
- package/lib/nodes/parent-node/ParentNodeUtility.js +5 -3
- package/lib/nodes/parent-node/ParentNodeUtility.js.map +1 -1
- package/lib/nodes/svg-element/SVGElement.js +1 -1
- package/lib/nodes/svg-element/SVGElement.js.map +1 -1
- package/lib/version.js +1 -1
- package/lib/window/BrowserWindow.d.ts.map +1 -1
- package/lib/window/BrowserWindow.js +10 -1
- package/lib/window/BrowserWindow.js.map +1 -1
- package/lib/window/DetachedWindowAPI.d.ts +4 -0
- package/lib/window/DetachedWindowAPI.d.ts.map +1 -1
- package/lib/window/DetachedWindowAPI.js +6 -0
- package/lib/window/DetachedWindowAPI.js.map +1 -1
- package/lib/xml-parser/XMLParser.d.ts.map +1 -1
- package/lib/xml-parser/XMLParser.js +17 -13
- package/lib/xml-parser/XMLParser.js.map +1 -1
- package/lib/xml-serializer/XMLSerializer.js +6 -6
- package/lib/xml-serializer/XMLSerializer.js.map +1 -1
- package/package.json +1 -1
- package/src/PropertySymbol.ts +2 -0
- package/src/browser/detached-browser/DetachedBrowserPage.ts +4 -3
- package/src/browser/utilities/BrowserFrameExceptionObserver.ts +12 -0
- package/src/browser/utilities/BrowserFrameFactory.ts +14 -7
- package/src/config/HTMLElementLocalNameToClass.ts +119 -0
- package/src/config/NamespaceURI.ts +2 -1
- package/src/custom-element/CustomElementRegistry.ts +76 -28
- package/src/navigator/Navigator.ts +4 -2
- package/src/nodes/document/Document.ts +61 -17
- package/src/nodes/element/Element.ts +3 -1
- package/src/nodes/html-element/HTMLElement.ts +127 -0
- package/src/nodes/html-unknown-element/HTMLUnknownElement.ts +1 -129
- package/src/nodes/parent-node/ParentNodeUtility.ts +5 -3
- package/src/nodes/svg-element/SVGElement.ts +1 -1
- package/src/window/BrowserWindow.ts +13 -1
- package/src/window/DetachedWindowAPI.ts +7 -0
- package/src/xml-parser/XMLParser.ts +20 -14
- package/src/xml-serializer/XMLSerializer.ts +6 -6
- package/cjs/config/ElementTag.cjs +0 -133
- package/cjs/config/ElementTag.cjs.map +0 -1
- package/cjs/config/ElementTag.d.ts.map +0 -1
- package/cjs/config/PlainTextElements.cjs.map +0 -1
- package/cjs/config/PlainTextElements.d.ts.map +0 -1
- package/cjs/config/UnnestableElements.cjs.map +0 -1
- package/cjs/config/UnnestableElements.d.ts.map +0 -1
- package/cjs/config/VoidElements.cjs.map +0 -1
- package/cjs/config/VoidElements.d.ts.map +0 -1
- package/lib/config/ElementTag.d.ts.map +0 -1
- package/lib/config/ElementTag.js +0 -131
- package/lib/config/PlainTextElements.d.ts.map +0 -1
- package/lib/config/PlainTextElements.js.map +0 -1
- package/lib/config/UnnestableElements.d.ts.map +0 -1
- package/lib/config/UnnestableElements.js.map +0 -1
- package/lib/config/VoidElements.d.ts.map +0 -1
- package/lib/config/VoidElements.js.map +0 -1
- package/src/config/ElementTag.ts +0 -130
- /package/src/config/{PlainTextElements.ts → HTMLElementPlainText.ts} +0 -0
- /package/src/config/{UnnestableElements.ts → HTMLElementUnnestable.ts} +0 -0
- /package/src/config/{VoidElements.ts → HTMLElementVoid.ts} +0 -0
@@ -10,44 +10,54 @@ export default class CustomElementRegistry {
|
|
10
10
|
public [PropertySymbol.registry]: {
|
11
11
|
[k: string]: { elementClass: typeof HTMLElement; extends: string };
|
12
12
|
} = {};
|
13
|
+
public [PropertySymbol.registedClass]: Map<typeof HTMLElement, string> = new Map();
|
13
14
|
public [PropertySymbol.callbacks]: { [k: string]: (() => void)[] } = {};
|
14
15
|
|
15
16
|
/**
|
16
17
|
* Defines a custom element class.
|
17
18
|
*
|
18
|
-
* @param
|
19
|
+
* @param name Tag name of element.
|
19
20
|
* @param elementClass Element class.
|
20
21
|
* @param [options] Options.
|
21
|
-
* @param options.extends
|
22
|
+
* @param [options.extends] Extends tag name.
|
22
23
|
*/
|
23
24
|
public define(
|
24
|
-
|
25
|
+
name: string,
|
25
26
|
elementClass: typeof HTMLElement,
|
26
|
-
options?: { extends
|
27
|
+
options?: { extends?: string }
|
27
28
|
): void {
|
28
|
-
|
29
|
+
if (!this.#isValidCustomElementName(name)) {
|
30
|
+
throw new DOMException(
|
31
|
+
`Failed to execute 'define' on 'CustomElementRegistry': "${name}" is not a valid custom element name`
|
32
|
+
);
|
33
|
+
}
|
34
|
+
|
35
|
+
if (this[PropertySymbol.registry][name]) {
|
36
|
+
throw new DOMException(
|
37
|
+
`Failed to execute 'define' on 'CustomElementRegistry': the name "${name}" has already been used with this registry`
|
38
|
+
);
|
39
|
+
}
|
29
40
|
|
30
|
-
if (
|
41
|
+
if (this[PropertySymbol.registedClass].has(elementClass)) {
|
31
42
|
throw new DOMException(
|
32
|
-
"Failed to execute 'define' on 'CustomElementRegistry':
|
33
|
-
tagName +
|
34
|
-
'" is not a valid custom element name.'
|
43
|
+
"Failed to execute 'define' on 'CustomElementRegistry': this constructor has already been used with this registry"
|
35
44
|
);
|
36
45
|
}
|
37
46
|
|
38
|
-
this[PropertySymbol.registry][
|
47
|
+
this[PropertySymbol.registry][name] = {
|
39
48
|
elementClass,
|
40
49
|
extends: options && options.extends ? options.extends.toLowerCase() : null
|
41
50
|
};
|
51
|
+
this[PropertySymbol.registedClass].set(elementClass, name);
|
42
52
|
|
43
53
|
// ObservedAttributes should only be called once by CustomElementRegistry (see #117)
|
44
54
|
if (elementClass.prototype.attributeChangedCallback) {
|
45
55
|
elementClass[PropertySymbol.observedAttributes] = elementClass.observedAttributes;
|
46
56
|
}
|
47
57
|
|
48
|
-
if (this[PropertySymbol.callbacks][
|
49
|
-
const callbacks = this[PropertySymbol.callbacks][
|
50
|
-
delete this[PropertySymbol.callbacks][
|
58
|
+
if (this[PropertySymbol.callbacks][name]) {
|
59
|
+
const callbacks = this[PropertySymbol.callbacks][name];
|
60
|
+
delete this[PropertySymbol.callbacks][name];
|
51
61
|
for (const callback of callbacks) {
|
52
62
|
callback();
|
53
63
|
}
|
@@ -57,14 +67,11 @@ export default class CustomElementRegistry {
|
|
57
67
|
/**
|
58
68
|
* Returns a defined element class.
|
59
69
|
*
|
60
|
-
* @param
|
61
|
-
* @
|
70
|
+
* @param name Tag name of element.
|
71
|
+
* @returns HTMLElement Class defined or undefined.
|
62
72
|
*/
|
63
|
-
public get(
|
64
|
-
|
65
|
-
return this[PropertySymbol.registry][upperTagName]
|
66
|
-
? this[PropertySymbol.registry][upperTagName].elementClass
|
67
|
-
: undefined;
|
73
|
+
public get(name: string): typeof HTMLElement | undefined {
|
74
|
+
return this[PropertySymbol.registry][name]?.elementClass;
|
68
75
|
}
|
69
76
|
|
70
77
|
/**
|
@@ -81,18 +88,59 @@ export default class CustomElementRegistry {
|
|
81
88
|
/**
|
82
89
|
* When defined.
|
83
90
|
*
|
84
|
-
* @param
|
85
|
-
* @returns Promise.
|
91
|
+
* @param name Tag name of element.
|
86
92
|
*/
|
87
|
-
public whenDefined(
|
88
|
-
|
89
|
-
|
93
|
+
public whenDefined(name: string): Promise<void> {
|
94
|
+
if (!this.#isValidCustomElementName(name)) {
|
95
|
+
return Promise.reject(new DOMException(`Invalid custom element name: "${name}"`));
|
96
|
+
}
|
97
|
+
if (this.get(name)) {
|
90
98
|
return Promise.resolve();
|
91
99
|
}
|
92
100
|
return new Promise((resolve) => {
|
93
|
-
this[PropertySymbol.callbacks][
|
94
|
-
|
95
|
-
this[PropertySymbol.callbacks][upperTagName].push(resolve);
|
101
|
+
this[PropertySymbol.callbacks][name] = this[PropertySymbol.callbacks][name] || [];
|
102
|
+
this[PropertySymbol.callbacks][name].push(resolve);
|
96
103
|
});
|
97
104
|
}
|
105
|
+
|
106
|
+
/**
|
107
|
+
* Reverse lookup searching for name by given element class.
|
108
|
+
*
|
109
|
+
* @param elementClass Class constructor.
|
110
|
+
* @returns Found tag name or `null`.
|
111
|
+
*/
|
112
|
+
public getName(elementClass: typeof HTMLElement): string | null {
|
113
|
+
return this[PropertySymbol.registedClass].get(elementClass) || null;
|
114
|
+
}
|
115
|
+
|
116
|
+
/**
|
117
|
+
* Validates the correctness of custom element tag names.
|
118
|
+
*
|
119
|
+
* @param name Custom element tag name.
|
120
|
+
* @returns True, if tag name is standard compliant.
|
121
|
+
*/
|
122
|
+
#isValidCustomElementName(name: string): boolean {
|
123
|
+
// Validation criteria based on:
|
124
|
+
// https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name
|
125
|
+
const PCENChar =
|
126
|
+
'[-_.]|[0-9]|[a-z]|\u{B7}|[\u{C0}-\u{D6}]|[\u{D8}-\u{F6}]' +
|
127
|
+
'|[\u{F8}-\u{37D}]|[\u{37F}-\u{1FFF}]' +
|
128
|
+
'|[\u{200C}-\u{200D}]|[\u{203F}-\u{2040}]|[\u{2070}-\u{218F}]' +
|
129
|
+
'|[\u{2C00}-\u{2FEF}]|[\u{3001}-\u{D7FF}]' +
|
130
|
+
'|[\u{F900}-\u{FDCF}]|[\u{FDF0}-\u{FFFD}]|[\u{10000}-\u{EFFFF}]';
|
131
|
+
|
132
|
+
const PCEN = new RegExp(`^[a-z](${PCENChar})*-(${PCENChar})*$`, 'u');
|
133
|
+
|
134
|
+
const reservedNames = [
|
135
|
+
'annotation-xml',
|
136
|
+
'color-profile',
|
137
|
+
'font-face',
|
138
|
+
'font-face-src',
|
139
|
+
'font-face-uri',
|
140
|
+
'font-face-format',
|
141
|
+
'font-face-name',
|
142
|
+
'missing-glyph'
|
143
|
+
];
|
144
|
+
return PCEN.test(name) && !reservedNames.includes(name);
|
145
|
+
}
|
98
146
|
}
|
@@ -77,7 +77,9 @@ export default class Navigator {
|
|
77
77
|
* Maximum number of simultaneous touch contact points are supported by the current device.
|
78
78
|
*/
|
79
79
|
public get maxTouchPoints(): number {
|
80
|
-
return
|
80
|
+
return (
|
81
|
+
WindowBrowserSettingsReader.getSettings(this.#ownerWindow)?.navigator.maxTouchPoints || 0
|
82
|
+
);
|
81
83
|
}
|
82
84
|
|
83
85
|
/**
|
@@ -154,7 +156,7 @@ export default class Navigator {
|
|
154
156
|
* "appCodeName/appVersion number (Platform; Security; OS-or-CPU; Localization; rv: revision-version-number) product/productSub Application-Name Application-Name-version".
|
155
157
|
*/
|
156
158
|
public get userAgent(): string {
|
157
|
-
return WindowBrowserSettingsReader.getSettings(this.#ownerWindow)
|
159
|
+
return WindowBrowserSettingsReader.getSettings(this.#ownerWindow)?.navigator.userAgent || '';
|
158
160
|
}
|
159
161
|
|
160
162
|
/**
|
@@ -1,6 +1,5 @@
|
|
1
1
|
import Element from '../element/Element.js';
|
2
2
|
import * as PropertySymbol from '../../PropertySymbol.js';
|
3
|
-
import HTMLUnknownElement from '../html-unknown-element/HTMLUnknownElement.js';
|
4
3
|
import IBrowserWindow from '../../window/IBrowserWindow.js';
|
5
4
|
import Node from '../node/Node.js';
|
6
5
|
import NodeIterator from '../../tree-walker/NodeIterator.js';
|
@@ -9,7 +8,7 @@ import DocumentFragment from '../document-fragment/DocumentFragment.js';
|
|
9
8
|
import XMLParser from '../../xml-parser/XMLParser.js';
|
10
9
|
import Event from '../../event/Event.js';
|
11
10
|
import DOMImplementation from '../../dom-implementation/DOMImplementation.js';
|
12
|
-
import
|
11
|
+
import HTMLElementLocalNameToClass from '../../config/HTMLElementLocalNameToClass.js';
|
13
12
|
import INodeFilter from '../../tree-walker/INodeFilter.js';
|
14
13
|
import NamespaceURI from '../../config/NamespaceURI.js';
|
15
14
|
import DocumentType from '../document-type/DocumentType.js';
|
@@ -879,28 +878,73 @@ export default class Document extends Node implements IDocument {
|
|
879
878
|
qualifiedName: string,
|
880
879
|
options?: { is?: string }
|
881
880
|
): IElement {
|
882
|
-
|
881
|
+
qualifiedName = String(qualifiedName);
|
883
882
|
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
883
|
+
if (!qualifiedName) {
|
884
|
+
throw new DOMException(
|
885
|
+
"Failed to execute 'createElementNS' on 'Document': The qualified name provided is empty."
|
886
|
+
);
|
887
|
+
}
|
888
|
+
|
889
|
+
// SVG element
|
890
|
+
if (namespaceURI === NamespaceURI.svg) {
|
891
|
+
const element = NodeFactory.createNode<IElement>(
|
892
|
+
this,
|
893
|
+
qualifiedName === 'svg'
|
894
|
+
? this[PropertySymbol.ownerWindow].SVGSVGElement
|
895
|
+
: this[PropertySymbol.ownerWindow].SVGElement
|
896
|
+
);
|
897
|
+
element[PropertySymbol.tagName] = qualifiedName;
|
898
|
+
element[PropertySymbol.localName] = qualifiedName;
|
899
|
+
element[PropertySymbol.namespaceURI] = namespaceURI;
|
900
|
+
element[PropertySymbol.isValue] = options && options.is ? String(options.is) : null;
|
901
|
+
return element;
|
889
902
|
}
|
890
903
|
|
891
|
-
|
892
|
-
|
893
|
-
this[PropertySymbol.ownerWindow][
|
894
|
-
|
904
|
+
// Custom HTML element
|
905
|
+
const customElement =
|
906
|
+
this[PropertySymbol.ownerWindow].customElements[PropertySymbol.registry]?.[
|
907
|
+
options && options.is ? String(options.is) : qualifiedName
|
908
|
+
];
|
909
|
+
|
910
|
+
if (customElement) {
|
911
|
+
const element = NodeFactory.createNode<IElement>(this, customElement.elementClass);
|
912
|
+
element[PropertySymbol.tagName] = qualifiedName.toUpperCase();
|
913
|
+
element[PropertySymbol.localName] = qualifiedName;
|
914
|
+
element[PropertySymbol.namespaceURI] = namespaceURI;
|
915
|
+
element[PropertySymbol.isValue] = options && options.is ? String(options.is) : null;
|
916
|
+
return element;
|
917
|
+
}
|
895
918
|
|
896
|
-
const
|
897
|
-
|
919
|
+
const localName = qualifiedName.toLowerCase();
|
920
|
+
const elementClass = this[PropertySymbol.ownerWindow][HTMLElementLocalNameToClass[localName]];
|
898
921
|
|
899
|
-
|
900
|
-
if (
|
901
|
-
element
|
922
|
+
// Known HTML element
|
923
|
+
if (elementClass) {
|
924
|
+
const element = NodeFactory.createNode<IElement>(this, elementClass);
|
925
|
+
|
926
|
+
element[PropertySymbol.tagName] = qualifiedName.toUpperCase();
|
927
|
+
element[PropertySymbol.localName] = localName;
|
928
|
+
element[PropertySymbol.namespaceURI] = namespaceURI;
|
929
|
+
element[PropertySymbol.isValue] = options && options.is ? String(options.is) : null;
|
930
|
+
|
931
|
+
return element;
|
902
932
|
}
|
903
933
|
|
934
|
+
// Unknown HTML element
|
935
|
+
const element = NodeFactory.createNode<IElement>(
|
936
|
+
this,
|
937
|
+
// If the tag name contains a hyphen, it is an unknown custom element and we should use HTMLElement.
|
938
|
+
localName.includes('-')
|
939
|
+
? this[PropertySymbol.ownerWindow].HTMLElement
|
940
|
+
: this[PropertySymbol.ownerWindow].HTMLUnknownElement
|
941
|
+
);
|
942
|
+
|
943
|
+
element[PropertySymbol.tagName] = qualifiedName.toUpperCase();
|
944
|
+
element[PropertySymbol.localName] = localName;
|
945
|
+
element[PropertySymbol.namespaceURI] = namespaceURI;
|
946
|
+
element[PropertySymbol.isValue] = options && options.is ? String(options.is) : null;
|
947
|
+
|
904
948
|
return element;
|
905
949
|
}
|
906
950
|
|
@@ -87,6 +87,7 @@ export default class Element extends Node implements IElement {
|
|
87
87
|
public [PropertySymbol.computedStyle]: CSSStyleDeclaration | null = null;
|
88
88
|
public [PropertySymbol.nodeType] = NodeTypeEnum.elementNode;
|
89
89
|
public [PropertySymbol.tagName]: string | null = null;
|
90
|
+
public [PropertySymbol.localName]: string | null = null;
|
90
91
|
public [PropertySymbol.prefix]: string | null = null;
|
91
92
|
public [PropertySymbol.shadowRoot]: IShadowRoot | null = null;
|
92
93
|
public [PropertySymbol.scrollHeight] = 0;
|
@@ -266,7 +267,7 @@ export default class Element extends Node implements IElement {
|
|
266
267
|
* @returns Local name.
|
267
268
|
*/
|
268
269
|
public get localName(): string {
|
269
|
-
return this[PropertySymbol.
|
270
|
+
return this[PropertySymbol.localName];
|
270
271
|
}
|
271
272
|
|
272
273
|
/**
|
@@ -486,6 +487,7 @@ export default class Element extends Node implements IElement {
|
|
486
487
|
}
|
487
488
|
|
488
489
|
clone[PropertySymbol.tagName] = this[PropertySymbol.tagName];
|
490
|
+
clone[PropertySymbol.localName] = this[PropertySymbol.localName];
|
489
491
|
clone[PropertySymbol.namespaceURI] = this[PropertySymbol.namespaceURI];
|
490
492
|
|
491
493
|
return <IElement>clone;
|
@@ -10,6 +10,12 @@ import Event from '../../event/Event.js';
|
|
10
10
|
import HTMLElementUtility from './HTMLElementUtility.js';
|
11
11
|
import INamedNodeMap from '../../named-node-map/INamedNodeMap.js';
|
12
12
|
import HTMLElementNamedNodeMap from './HTMLElementNamedNodeMap.js';
|
13
|
+
import INodeList from '../node/INodeList.js';
|
14
|
+
import INode from '../node/INode.js';
|
15
|
+
import IHTMLCollection from '../element/IHTMLCollection.js';
|
16
|
+
import IElement from '../element/IElement.js';
|
17
|
+
import NodeList from '../node/NodeList.js';
|
18
|
+
import HTMLCollection from '../element/HTMLCollection.js';
|
13
19
|
|
14
20
|
/**
|
15
21
|
* HTML Element.
|
@@ -62,6 +68,7 @@ export default class HTMLElement extends Element implements IHTMLElement {
|
|
62
68
|
|
63
69
|
// Private properties
|
64
70
|
#dataset: Dataset = null;
|
71
|
+
#customElementDefineCallback: () => void = null;
|
65
72
|
|
66
73
|
/**
|
67
74
|
* Returns access key.
|
@@ -473,4 +480,124 @@ export default class HTMLElement extends Element implements IHTMLElement {
|
|
473
480
|
|
474
481
|
return clone;
|
475
482
|
}
|
483
|
+
|
484
|
+
/**
|
485
|
+
* Connects this element to another element.
|
486
|
+
*
|
487
|
+
* @see https://html.spec.whatwg.org/multipage/dom.html#htmlelement
|
488
|
+
* @param parentNode Parent node.
|
489
|
+
*/
|
490
|
+
public [PropertySymbol.connectToNode](parentNode: INode = null): void {
|
491
|
+
const localName = this[PropertySymbol.localName];
|
492
|
+
|
493
|
+
// This element can potentially be a custom element that has not been defined yet
|
494
|
+
// Therefore we need to register a callback for when it is defined in CustomElementRegistry and replace it with the registered element (see #404)
|
495
|
+
if (
|
496
|
+
this.constructor === HTMLElement &&
|
497
|
+
localName.includes('-') &&
|
498
|
+
this[PropertySymbol.ownerDocument][PropertySymbol.ownerWindow].customElements[
|
499
|
+
PropertySymbol.callbacks
|
500
|
+
]
|
501
|
+
) {
|
502
|
+
const callbacks =
|
503
|
+
this[PropertySymbol.ownerDocument][PropertySymbol.ownerWindow].customElements[
|
504
|
+
PropertySymbol.callbacks
|
505
|
+
];
|
506
|
+
|
507
|
+
if (parentNode && !this.#customElementDefineCallback) {
|
508
|
+
const callback = (): void => {
|
509
|
+
if (this[PropertySymbol.parentNode]) {
|
510
|
+
const newElement = <HTMLElement>(
|
511
|
+
this[PropertySymbol.ownerDocument].createElement(localName)
|
512
|
+
);
|
513
|
+
(<INodeList<INode>>newElement[PropertySymbol.childNodes]) =
|
514
|
+
this[PropertySymbol.childNodes];
|
515
|
+
(<IHTMLCollection<IElement>>newElement[PropertySymbol.children]) =
|
516
|
+
this[PropertySymbol.children];
|
517
|
+
(<boolean>newElement[PropertySymbol.isConnected]) = this[PropertySymbol.isConnected];
|
518
|
+
|
519
|
+
newElement[PropertySymbol.rootNode] = this[PropertySymbol.rootNode];
|
520
|
+
newElement[PropertySymbol.formNode] = this[PropertySymbol.formNode];
|
521
|
+
newElement[PropertySymbol.selectNode] = this[PropertySymbol.selectNode];
|
522
|
+
newElement[PropertySymbol.textAreaNode] = this[PropertySymbol.textAreaNode];
|
523
|
+
newElement[PropertySymbol.observers] = this[PropertySymbol.observers];
|
524
|
+
newElement[PropertySymbol.isValue] = this[PropertySymbol.isValue];
|
525
|
+
|
526
|
+
for (let i = 0, max = this[PropertySymbol.attributes].length; i < max; i++) {
|
527
|
+
newElement[PropertySymbol.attributes].setNamedItem(
|
528
|
+
this[PropertySymbol.attributes][i]
|
529
|
+
);
|
530
|
+
}
|
531
|
+
|
532
|
+
(<INodeList<INode>>this[PropertySymbol.childNodes]) = new NodeList();
|
533
|
+
(<IHTMLCollection<IElement>>this[PropertySymbol.children]) = new HTMLCollection();
|
534
|
+
this[PropertySymbol.rootNode] = null;
|
535
|
+
this[PropertySymbol.formNode] = null;
|
536
|
+
this[PropertySymbol.selectNode] = null;
|
537
|
+
this[PropertySymbol.textAreaNode] = null;
|
538
|
+
this[PropertySymbol.observers] = [];
|
539
|
+
this[PropertySymbol.isValue] = null;
|
540
|
+
(<HTMLElementNamedNodeMap>this[PropertySymbol.attributes]) =
|
541
|
+
new HTMLElementNamedNodeMap(this);
|
542
|
+
|
543
|
+
for (
|
544
|
+
let i = 0,
|
545
|
+
max = (<HTMLElement>this[PropertySymbol.parentNode])[PropertySymbol.childNodes]
|
546
|
+
.length;
|
547
|
+
i < max;
|
548
|
+
i++
|
549
|
+
) {
|
550
|
+
if (
|
551
|
+
(<HTMLElement>this[PropertySymbol.parentNode])[PropertySymbol.childNodes][i] ===
|
552
|
+
this
|
553
|
+
) {
|
554
|
+
(<HTMLElement>this[PropertySymbol.parentNode])[PropertySymbol.childNodes][i] =
|
555
|
+
newElement;
|
556
|
+
break;
|
557
|
+
}
|
558
|
+
}
|
559
|
+
|
560
|
+
if ((<HTMLElement>this[PropertySymbol.parentNode])[PropertySymbol.children]) {
|
561
|
+
for (
|
562
|
+
let i = 0,
|
563
|
+
max = (<HTMLElement>this[PropertySymbol.parentNode])[PropertySymbol.children]
|
564
|
+
.length;
|
565
|
+
i < max;
|
566
|
+
i++
|
567
|
+
) {
|
568
|
+
if (
|
569
|
+
(<HTMLElement>this[PropertySymbol.parentNode])[PropertySymbol.children][i] ===
|
570
|
+
this
|
571
|
+
) {
|
572
|
+
(<HTMLElement>this[PropertySymbol.parentNode])[PropertySymbol.children][i] =
|
573
|
+
newElement;
|
574
|
+
break;
|
575
|
+
}
|
576
|
+
}
|
577
|
+
}
|
578
|
+
|
579
|
+
if (newElement[PropertySymbol.isConnected] && newElement.connectedCallback) {
|
580
|
+
newElement.connectedCallback();
|
581
|
+
}
|
582
|
+
|
583
|
+
this[PropertySymbol.connectToNode](null);
|
584
|
+
}
|
585
|
+
};
|
586
|
+
callbacks[localName] = callbacks[localName] || [];
|
587
|
+
callbacks[localName].push(callback);
|
588
|
+
this.#customElementDefineCallback = callback;
|
589
|
+
} else if (!parentNode && callbacks[localName] && this.#customElementDefineCallback) {
|
590
|
+
const index = callbacks[localName].indexOf(this.#customElementDefineCallback);
|
591
|
+
if (index !== -1) {
|
592
|
+
callbacks[localName].splice(index, 1);
|
593
|
+
}
|
594
|
+
if (!callbacks[localName].length) {
|
595
|
+
delete callbacks[localName];
|
596
|
+
}
|
597
|
+
this.#customElementDefineCallback = null;
|
598
|
+
}
|
599
|
+
}
|
600
|
+
|
601
|
+
super[PropertySymbol.connectToNode](parentNode);
|
602
|
+
}
|
476
603
|
}
|
@@ -1,13 +1,5 @@
|
|
1
1
|
import HTMLElement from '../html-element/HTMLElement.js';
|
2
|
-
import * as PropertySymbol from '../../PropertySymbol.js';
|
3
|
-
import INode from '../node/INode.js';
|
4
2
|
import IHTMLElement from '../html-element/IHTMLElement.js';
|
5
|
-
import INodeList from '../node/INodeList.js';
|
6
|
-
import IHTMLCollection from '../element/IHTMLCollection.js';
|
7
|
-
import IElement from '../element/IElement.js';
|
8
|
-
import NodeList from '../node/NodeList.js';
|
9
|
-
import HTMLCollection from '../element/HTMLCollection.js';
|
10
|
-
import HTMLElementNamedNodeMap from '../html-element/HTMLElementNamedNodeMap.js';
|
11
3
|
|
12
4
|
/**
|
13
5
|
* HTML Unknown Element.
|
@@ -15,124 +7,4 @@ import HTMLElementNamedNodeMap from '../html-element/HTMLElementNamedNodeMap.js'
|
|
15
7
|
* Reference:
|
16
8
|
* https://developer.mozilla.org/en-US/docs/Web/API/HTMLUnknownElement.
|
17
9
|
*/
|
18
|
-
export default class HTMLUnknownElement extends HTMLElement implements IHTMLElement {
|
19
|
-
#customElementDefineCallback: () => void = null;
|
20
|
-
|
21
|
-
/**
|
22
|
-
* Connects this element to another element.
|
23
|
-
*
|
24
|
-
* @param parentNode Parent node.
|
25
|
-
*/
|
26
|
-
public [PropertySymbol.connectToNode](parentNode: INode = null): void {
|
27
|
-
const tagName = this[PropertySymbol.tagName];
|
28
|
-
|
29
|
-
// This element can potentially be a custom element that has not been defined yet
|
30
|
-
// Therefore we need to register a callback for when it is defined in CustomElementRegistry and replace it with the registered element (see #404)
|
31
|
-
if (
|
32
|
-
tagName.includes('-') &&
|
33
|
-
this[PropertySymbol.ownerDocument][PropertySymbol.ownerWindow].customElements[
|
34
|
-
PropertySymbol.callbacks
|
35
|
-
]
|
36
|
-
) {
|
37
|
-
const callbacks =
|
38
|
-
this[PropertySymbol.ownerDocument][PropertySymbol.ownerWindow].customElements[
|
39
|
-
PropertySymbol.callbacks
|
40
|
-
];
|
41
|
-
|
42
|
-
if (parentNode && !this.#customElementDefineCallback) {
|
43
|
-
const callback = (): void => {
|
44
|
-
if (this[PropertySymbol.parentNode]) {
|
45
|
-
const newElement = <HTMLElement>(
|
46
|
-
this[PropertySymbol.ownerDocument].createElement(tagName)
|
47
|
-
);
|
48
|
-
(<INodeList<INode>>newElement[PropertySymbol.childNodes]) =
|
49
|
-
this[PropertySymbol.childNodes];
|
50
|
-
(<IHTMLCollection<IElement>>newElement[PropertySymbol.children]) =
|
51
|
-
this[PropertySymbol.children];
|
52
|
-
(<boolean>newElement[PropertySymbol.isConnected]) = this[PropertySymbol.isConnected];
|
53
|
-
|
54
|
-
newElement[PropertySymbol.rootNode] = this[PropertySymbol.rootNode];
|
55
|
-
newElement[PropertySymbol.formNode] = this[PropertySymbol.formNode];
|
56
|
-
newElement[PropertySymbol.selectNode] = this[PropertySymbol.selectNode];
|
57
|
-
newElement[PropertySymbol.textAreaNode] = this[PropertySymbol.textAreaNode];
|
58
|
-
newElement[PropertySymbol.observers] = this[PropertySymbol.observers];
|
59
|
-
newElement[PropertySymbol.isValue] = this[PropertySymbol.isValue];
|
60
|
-
|
61
|
-
for (let i = 0, max = this[PropertySymbol.attributes].length; i < max; i++) {
|
62
|
-
newElement[PropertySymbol.attributes].setNamedItem(
|
63
|
-
this[PropertySymbol.attributes][i]
|
64
|
-
);
|
65
|
-
}
|
66
|
-
|
67
|
-
(<INodeList<INode>>this[PropertySymbol.childNodes]) = new NodeList();
|
68
|
-
(<IHTMLCollection<IElement>>this[PropertySymbol.children]) = new HTMLCollection();
|
69
|
-
this[PropertySymbol.rootNode] = null;
|
70
|
-
this[PropertySymbol.formNode] = null;
|
71
|
-
this[PropertySymbol.selectNode] = null;
|
72
|
-
this[PropertySymbol.textAreaNode] = null;
|
73
|
-
this[PropertySymbol.observers] = [];
|
74
|
-
this[PropertySymbol.isValue] = null;
|
75
|
-
(<HTMLElementNamedNodeMap>this[PropertySymbol.attributes]) =
|
76
|
-
new HTMLElementNamedNodeMap(this);
|
77
|
-
|
78
|
-
for (
|
79
|
-
let i = 0,
|
80
|
-
max = (<HTMLElement>this[PropertySymbol.parentNode])[PropertySymbol.childNodes]
|
81
|
-
.length;
|
82
|
-
i < max;
|
83
|
-
i++
|
84
|
-
) {
|
85
|
-
if (
|
86
|
-
(<HTMLElement>this[PropertySymbol.parentNode])[PropertySymbol.childNodes][i] ===
|
87
|
-
this
|
88
|
-
) {
|
89
|
-
(<HTMLElement>this[PropertySymbol.parentNode])[PropertySymbol.childNodes][i] =
|
90
|
-
newElement;
|
91
|
-
break;
|
92
|
-
}
|
93
|
-
}
|
94
|
-
|
95
|
-
if ((<HTMLElement>this[PropertySymbol.parentNode])[PropertySymbol.children]) {
|
96
|
-
for (
|
97
|
-
let i = 0,
|
98
|
-
max = (<HTMLElement>this[PropertySymbol.parentNode])[PropertySymbol.children]
|
99
|
-
.length;
|
100
|
-
i < max;
|
101
|
-
i++
|
102
|
-
) {
|
103
|
-
if (
|
104
|
-
(<HTMLElement>this[PropertySymbol.parentNode])[PropertySymbol.children][i] ===
|
105
|
-
this
|
106
|
-
) {
|
107
|
-
(<HTMLElement>this[PropertySymbol.parentNode])[PropertySymbol.children][i] =
|
108
|
-
newElement;
|
109
|
-
break;
|
110
|
-
}
|
111
|
-
}
|
112
|
-
}
|
113
|
-
|
114
|
-
if (newElement[PropertySymbol.isConnected] && newElement.connectedCallback) {
|
115
|
-
newElement.connectedCallback();
|
116
|
-
}
|
117
|
-
|
118
|
-
this[PropertySymbol.connectToNode](null);
|
119
|
-
}
|
120
|
-
};
|
121
|
-
callbacks[tagName] = callbacks[tagName] || [];
|
122
|
-
callbacks[tagName].push(callback);
|
123
|
-
this.#customElementDefineCallback = callback;
|
124
|
-
} else if (!parentNode && callbacks[tagName] && this.#customElementDefineCallback) {
|
125
|
-
const index = callbacks[tagName].indexOf(this.#customElementDefineCallback);
|
126
|
-
if (index !== -1) {
|
127
|
-
callbacks[tagName].splice(index, 1);
|
128
|
-
}
|
129
|
-
if (!callbacks[tagName].length) {
|
130
|
-
delete callbacks[tagName];
|
131
|
-
}
|
132
|
-
this.#customElementDefineCallback = null;
|
133
|
-
}
|
134
|
-
}
|
135
|
-
|
136
|
-
super[PropertySymbol.connectToNode](parentNode);
|
137
|
-
}
|
138
|
-
}
|
10
|
+
export default class HTMLUnknownElement extends HTMLElement implements IHTMLElement {}
|
@@ -7,6 +7,7 @@ import IHTMLCollection from '../element/IHTMLCollection.js';
|
|
7
7
|
import INode from '../node/INode.js';
|
8
8
|
import HTMLCollection from '../element/HTMLCollection.js';
|
9
9
|
import DocumentFragment from '../document-fragment/DocumentFragment.js';
|
10
|
+
import NamespaceURI from '../../config/NamespaceURI.js';
|
10
11
|
|
11
12
|
/**
|
12
13
|
* Parent node utility.
|
@@ -115,7 +116,7 @@ export default class ParentNodeUtility {
|
|
115
116
|
let matches = new HTMLCollection<IElement>();
|
116
117
|
|
117
118
|
for (const child of (<DocumentFragment>parentNode)[PropertySymbol.children]) {
|
118
|
-
if (includeAll || child[PropertySymbol.tagName] === upperTagName) {
|
119
|
+
if (includeAll || child[PropertySymbol.tagName].toUpperCase() === upperTagName) {
|
119
120
|
matches.push(child);
|
120
121
|
}
|
121
122
|
matches = <HTMLCollection<IElement>>(
|
@@ -139,13 +140,14 @@ export default class ParentNodeUtility {
|
|
139
140
|
namespaceURI: string,
|
140
141
|
tagName: string
|
141
142
|
): IHTMLCollection<IElement> {
|
142
|
-
|
143
|
+
// When the namespace is HTML, the tag name is case-insensitive.
|
144
|
+
const formattedTagName = namespaceURI === NamespaceURI.html ? tagName.toUpperCase() : tagName;
|
143
145
|
const includeAll = tagName === '*';
|
144
146
|
let matches = new HTMLCollection<IElement>();
|
145
147
|
|
146
148
|
for (const child of (<DocumentFragment>parentNode)[PropertySymbol.children]) {
|
147
149
|
if (
|
148
|
-
(includeAll || child[PropertySymbol.tagName] ===
|
150
|
+
(includeAll || child[PropertySymbol.tagName] === formattedTagName) &&
|
149
151
|
child[PropertySymbol.namespaceURI] === namespaceURI
|
150
152
|
) {
|
151
153
|
matches.push(child);
|
@@ -48,7 +48,7 @@ export default class SVGElement extends Element implements ISVGElement {
|
|
48
48
|
public get ownerSVGElement(): ISVGSVGElement {
|
49
49
|
let parent = this[PropertySymbol.parentNode];
|
50
50
|
while (parent) {
|
51
|
-
if (parent[
|
51
|
+
if (parent[PropertySymbol.localName] === 'svg') {
|
52
52
|
return <ISVGSVGElement>parent;
|
53
53
|
}
|
54
54
|
|
@@ -935,6 +935,7 @@ export default class BrowserWindow extends EventTarget implements IBrowserWindow
|
|
935
935
|
// When using a Window instance directly, the Window instance is the main frame and we will close the page and destroy the browser.
|
936
936
|
// When using the Browser API we should only close the page when the Window instance is connected to the main frame (we should not close child frames such as iframes).
|
937
937
|
if (this.#browserFrame.page?.mainFrame === this.#browserFrame) {
|
938
|
+
this[PropertySymbol.destroy]();
|
938
939
|
this.#browserFrame.page.close();
|
939
940
|
}
|
940
941
|
}
|
@@ -1241,16 +1242,27 @@ export default class BrowserWindow extends EventTarget implements IBrowserWindow
|
|
1241
1242
|
* Destroys the window.
|
1242
1243
|
*/
|
1243
1244
|
public [PropertySymbol.destroy](): void {
|
1245
|
+
if (!this.Audio[PropertySymbol.ownerDocument]) {
|
1246
|
+
return;
|
1247
|
+
}
|
1248
|
+
|
1244
1249
|
(<boolean>this.closed) = true;
|
1245
1250
|
this.Audio[PropertySymbol.ownerDocument] = null;
|
1246
1251
|
this.Image[PropertySymbol.ownerDocument] = null;
|
1247
1252
|
this.DocumentFragment[PropertySymbol.ownerDocument] = null;
|
1248
|
-
|
1253
|
+
|
1254
|
+
const mutationObservers = this[PropertySymbol.mutationObservers];
|
1255
|
+
|
1256
|
+
for (const mutationObserver of mutationObservers) {
|
1249
1257
|
mutationObserver.disconnect();
|
1250
1258
|
}
|
1251
1259
|
|
1252
1260
|
// Disconnects nodes from the document, so that they can be garbage collected.
|
1253
1261
|
for (const node of this.document[PropertySymbol.childNodes].slice()) {
|
1262
|
+
// Makes sure that something won't be triggered by the disconnect.
|
1263
|
+
if (node.disconnectedCallback) {
|
1264
|
+
delete node.disconnectedCallback;
|
1265
|
+
}
|
1254
1266
|
this.document.removeChild(node);
|
1255
1267
|
}
|
1256
1268
|
|