happy-dom 2.24.3 → 2.25.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/lib/css/CSSStyleSheet.d.ts +5 -1
- package/lib/css/CSSStyleSheet.js +21 -10
- package/lib/css/CSSStyleSheet.js.map +1 -1
- package/lib/event/EventTarget.d.ts +9 -0
- package/lib/event/EventTarget.js +11 -0
- package/lib/event/EventTarget.js.map +1 -1
- package/lib/event/NonImplementedEventTypes.js +0 -1
- package/lib/event/NonImplementedEventTypes.js.map +1 -1
- package/lib/event/events/IPointerEventInit.d.ts +13 -0
- package/lib/event/events/IPointerEventInit.js +3 -0
- package/lib/event/events/IPointerEventInit.js.map +1 -0
- package/lib/event/events/PointerEvent.d.ts +24 -0
- package/lib/event/events/PointerEvent.js +64 -0
- package/lib/event/events/PointerEvent.js.map +1 -0
- package/lib/exception/DOMExceptionNameEnum.d.ts +4 -1
- package/lib/exception/DOMExceptionNameEnum.js +3 -0
- package/lib/exception/DOMExceptionNameEnum.js.map +1 -1
- package/lib/nodes/document/Document.d.ts +8 -1
- package/lib/nodes/document/Document.js +14 -1
- package/lib/nodes/document/Document.js.map +1 -1
- package/lib/nodes/document/IDocument.d.ts +1 -0
- package/lib/nodes/document-fragment/DocumentFragment.d.ts +1 -0
- package/lib/nodes/document-fragment/DocumentFragment.js +1 -0
- package/lib/nodes/document-fragment/DocumentFragment.js.map +1 -1
- package/lib/nodes/element/Element.d.ts +7 -0
- package/lib/nodes/element/Element.js +39 -3
- package/lib/nodes/element/Element.js.map +1 -1
- package/lib/nodes/element/IElement.d.ts +7 -0
- package/lib/nodes/html-element/HTMLElement.js +16 -4
- package/lib/nodes/html-element/HTMLElement.js.map +1 -1
- package/lib/nodes/html-input-element/HTMLInputElement.d.ts +9 -6
- package/lib/nodes/html-input-element/HTMLInputElement.js +18 -8
- package/lib/nodes/html-input-element/HTMLInputElement.js.map +1 -1
- package/lib/nodes/html-input-element/IHTMLInputElement.d.ts +0 -1
- package/lib/nodes/html-link-element/HTMLLinkElement.d.ts +5 -12
- package/lib/nodes/html-link-element/HTMLLinkElement.js +39 -68
- package/lib/nodes/html-link-element/HTMLLinkElement.js.map +1 -1
- package/lib/nodes/html-script-element/HTMLScriptElement.d.ts +5 -12
- package/lib/nodes/html-script-element/HTMLScriptElement.js +21 -49
- package/lib/nodes/html-script-element/HTMLScriptElement.js.map +1 -1
- package/lib/nodes/html-style-element/HTMLStyleElement.js +1 -1
- package/lib/nodes/html-style-element/HTMLStyleElement.js.map +1 -1
- package/lib/nodes/node/INode.d.ts +1 -1
- package/lib/nodes/node/Node.d.ts +8 -13
- package/lib/nodes/node/Node.js +58 -64
- package/lib/nodes/node/Node.js.map +1 -1
- package/lib/nodes/shadow-root/ShadowRoot.d.ts +7 -0
- package/lib/nodes/shadow-root/ShadowRoot.js +16 -0
- package/lib/nodes/shadow-root/ShadowRoot.js.map +1 -1
- package/lib/query-selector/SelectorItem.d.ts +8 -0
- package/lib/query-selector/SelectorItem.js +29 -11
- package/lib/query-selector/SelectorItem.js.map +1 -1
- package/lib/window/Window.d.ts +2 -0
- package/lib/window/Window.js +2 -0
- package/lib/window/Window.js.map +1 -1
- package/package.json +2 -2
- package/src/css/CSSStyleSheet.ts +33 -4
- package/src/event/EventTarget.ts +12 -0
- package/src/event/NonImplementedEventTypes.ts +0 -1
- package/src/event/events/IPointerEventInit.ts +14 -0
- package/src/event/events/PointerEvent.ts +42 -0
- package/src/exception/DOMExceptionNameEnum.ts +4 -1
- package/src/nodes/document/Document.ts +11 -1
- package/src/nodes/document/IDocument.ts +1 -0
- package/src/nodes/document-fragment/DocumentFragment.ts +1 -0
- package/src/nodes/element/Element.ts +42 -3
- package/src/nodes/element/IElement.ts +8 -0
- package/src/nodes/html-element/HTMLElement.ts +21 -4
- package/src/nodes/html-input-element/HTMLInputElement.ts +21 -9
- package/src/nodes/html-input-element/IHTMLInputElement.ts +0 -1
- package/src/nodes/html-link-element/HTMLLinkElement.ts +46 -73
- package/src/nodes/html-script-element/HTMLScriptElement.ts +24 -49
- package/src/nodes/html-style-element/HTMLStyleElement.ts +1 -1
- package/src/nodes/node/INode.ts +1 -1
- package/src/nodes/node/Node.ts +61 -63
- package/src/nodes/shadow-root/ShadowRoot.ts +14 -0
- package/src/query-selector/SelectorItem.ts +38 -19
- package/src/window/Window.ts +2 -0
package/src/event/EventTarget.ts
CHANGED
@@ -67,4 +67,16 @@ export default abstract class EventTarget implements IEventTarget {
|
|
67
67
|
|
68
68
|
return !(event.cancelable && event.defaultPrevented);
|
69
69
|
}
|
70
|
+
|
71
|
+
/**
|
72
|
+
* Adds an event listener.
|
73
|
+
*
|
74
|
+
* This is only supported by IE8- and Opera, but for some reason React uses it and calls it, so therefore we will keep support for it until they stop using it.
|
75
|
+
*
|
76
|
+
* @param type Event type.
|
77
|
+
* @param listener Listener.
|
78
|
+
*/
|
79
|
+
public attachEvent(type: string, listener: ((event: Event) => void) | IEventListener): void {
|
80
|
+
this.addEventListener(type.replace('on', ''), listener);
|
81
|
+
}
|
70
82
|
}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
import IMouseEventInit from './IMouseEventInit';
|
2
|
+
|
3
|
+
export default interface IPointerEventInit extends IMouseEventInit {
|
4
|
+
pointerId?: number;
|
5
|
+
width?: number;
|
6
|
+
height?: number;
|
7
|
+
pressure?: number;
|
8
|
+
tangentialPressure?: number;
|
9
|
+
tiltX?: number;
|
10
|
+
tiltY?: number;
|
11
|
+
twist?: number;
|
12
|
+
pointerType?: string;
|
13
|
+
isPrimary?: boolean;
|
14
|
+
}
|
@@ -0,0 +1,42 @@
|
|
1
|
+
import MouseEvent from './MouseEvent';
|
2
|
+
import IPointerEventInit from './IPointerEventInit';
|
3
|
+
|
4
|
+
/**
|
5
|
+
*
|
6
|
+
*/
|
7
|
+
export default class PointerEvent extends MouseEvent {
|
8
|
+
public readonly pointerId: number = 0;
|
9
|
+
public readonly width: number = 0;
|
10
|
+
public readonly height: number = 0;
|
11
|
+
public readonly pressure: number = 0;
|
12
|
+
public readonly tangentialPressure: number = 0;
|
13
|
+
public readonly tiltX: number = 0;
|
14
|
+
public readonly tiltY: number = 0;
|
15
|
+
public readonly twist: number = 0;
|
16
|
+
public readonly pointerType: string = '';
|
17
|
+
public readonly isPrimary: boolean = false;
|
18
|
+
|
19
|
+
/**
|
20
|
+
* Constructor.
|
21
|
+
*
|
22
|
+
* @param type Event type.
|
23
|
+
* @param [eventInit] Event init.
|
24
|
+
*/
|
25
|
+
constructor(type: string, eventInit: IPointerEventInit = null) {
|
26
|
+
super(type, eventInit);
|
27
|
+
|
28
|
+
if (eventInit) {
|
29
|
+
this.pointerId = eventInit.pointerId !== undefined ? eventInit.pointerId : 0;
|
30
|
+
this.width = eventInit.width !== undefined ? eventInit.width : 0;
|
31
|
+
this.height = eventInit.height !== undefined ? eventInit.height : 0;
|
32
|
+
this.pressure = eventInit.pressure !== undefined ? eventInit.pressure : 0;
|
33
|
+
this.tangentialPressure =
|
34
|
+
eventInit.tangentialPressure !== undefined ? eventInit.tangentialPressure : 0;
|
35
|
+
this.tiltX = eventInit.tiltX !== undefined ? eventInit.tiltX : 0;
|
36
|
+
this.tiltY = eventInit.tiltY !== undefined ? eventInit.tiltY : 0;
|
37
|
+
this.twist = eventInit.twist !== undefined ? eventInit.twist : 0;
|
38
|
+
this.pointerType = eventInit.pointerType !== undefined ? eventInit.pointerType : '';
|
39
|
+
this.isPrimary = eventInit.isPrimary || eventInit.isPrimary;
|
40
|
+
}
|
41
|
+
}
|
42
|
+
}
|
@@ -1,4 +1,7 @@
|
|
1
1
|
enum DOMExceptionNameEnum {
|
2
|
-
invalidStateError = 'InvalidStateError'
|
2
|
+
invalidStateError = 'InvalidStateError',
|
3
|
+
indexSizeError = 'IndexSizeError',
|
4
|
+
syntaxError = 'SyntaxError',
|
5
|
+
hierarchyRequestError = 'HierarchyRequestError'
|
3
6
|
}
|
4
7
|
export default DOMExceptionNameEnum;
|
@@ -44,8 +44,9 @@ export default class Document extends Node implements IDocument {
|
|
44
44
|
public implementation: DOMImplementation;
|
45
45
|
public readonly children: IHTMLCollection<IElement> = HTMLCollectionFactory.create();
|
46
46
|
public readonly readyState = DocumentReadyStateEnum.interactive;
|
47
|
+
public readonly isConnected: boolean = true;
|
47
48
|
public _readyStateManager: DocumentReadyStateManager = null;
|
48
|
-
|
49
|
+
public _activeElement: IHTMLElement = null;
|
49
50
|
protected _isFirstWrite = true;
|
50
51
|
protected _isFirstWriteAfterOpen = false;
|
51
52
|
private _defaultView: Window = null;
|
@@ -209,6 +210,15 @@ export default class Document extends Node implements IDocument {
|
|
209
210
|
return styleSheets;
|
210
211
|
}
|
211
212
|
|
213
|
+
/**
|
214
|
+
* Returns active element.
|
215
|
+
*
|
216
|
+
* @returns Active element.
|
217
|
+
*/
|
218
|
+
public get activeElement(): IHTMLElement {
|
219
|
+
return this._activeElement || this.body || this.documentElement || null;
|
220
|
+
}
|
221
|
+
|
212
222
|
/**
|
213
223
|
* Inserts a set of Node objects or DOMString objects after the last child of the ParentNode. DOMString objects are inserted as equivalent Text nodes.
|
214
224
|
*
|
@@ -13,6 +13,7 @@ import HTMLCollectionFactory from '../element/HTMLCollectionFactory';
|
|
13
13
|
export default class DocumentFragment extends Node implements IDocumentFragment {
|
14
14
|
public nodeType = Node.DOCUMENT_FRAGMENT_NODE;
|
15
15
|
public readonly children: IHTMLCollection<IElement> = HTMLCollectionFactory.create();
|
16
|
+
public _rootNode: INode = this;
|
16
17
|
|
17
18
|
/**
|
18
19
|
* Last element child.
|
@@ -94,7 +94,7 @@ export default class Element extends Node implements IElement {
|
|
94
94
|
* @returns Local name.
|
95
95
|
*/
|
96
96
|
public get localName(): string {
|
97
|
-
return this.tagName.toLowerCase();
|
97
|
+
return this.tagName ? this.tagName.toLowerCase() : 'unknown';
|
98
98
|
}
|
99
99
|
|
100
100
|
/**
|
@@ -598,7 +598,7 @@ export default class Element extends Node implements IElement {
|
|
598
598
|
(<IDocument>this.shadowRoot.ownerDocument) = this.ownerDocument;
|
599
599
|
(<Element>this.shadowRoot.host) = this;
|
600
600
|
(<string>this.shadowRoot.mode) = shadowRootInit.mode;
|
601
|
-
this.shadowRoot.
|
601
|
+
(<ShadowRoot>this.shadowRoot)._connectToNode(this);
|
602
602
|
return this.shadowRoot;
|
603
603
|
}
|
604
604
|
|
@@ -636,7 +636,46 @@ export default class Element extends Node implements IElement {
|
|
636
636
|
* @returns "true" if matching.
|
637
637
|
*/
|
638
638
|
public matches(selector: string): boolean {
|
639
|
-
|
639
|
+
for (const part of selector.split(',')) {
|
640
|
+
if (new SelectorItem(part.trim()).match(this)) {
|
641
|
+
return true;
|
642
|
+
}
|
643
|
+
}
|
644
|
+
return false;
|
645
|
+
}
|
646
|
+
|
647
|
+
/**
|
648
|
+
* Traverses the Element and its parents (heading toward the document root) until it finds a node that matches the provided selector string.
|
649
|
+
*
|
650
|
+
* @param selector Selector.
|
651
|
+
* @returns Closest matching element.
|
652
|
+
*/
|
653
|
+
public closest(selector: string): IElement {
|
654
|
+
let rootElement: IElement = this.ownerDocument.documentElement;
|
655
|
+
if (!this.isConnected) {
|
656
|
+
rootElement = this;
|
657
|
+
while (rootElement.parentNode) {
|
658
|
+
rootElement = <IElement>rootElement.parentNode;
|
659
|
+
}
|
660
|
+
}
|
661
|
+
const elements = rootElement.querySelectorAll(selector);
|
662
|
+
|
663
|
+
// eslint-disable-next-line
|
664
|
+
let parent: IElement = this;
|
665
|
+
while (parent) {
|
666
|
+
if (elements.includes(parent)) {
|
667
|
+
return parent;
|
668
|
+
}
|
669
|
+
parent = parent.parentElement;
|
670
|
+
}
|
671
|
+
|
672
|
+
// QuerySelectorAll() will not match the element it is looking in when searched for
|
673
|
+
// Therefore we need to check if it matches the root
|
674
|
+
if (rootElement.matches(selector)) {
|
675
|
+
return rootElement;
|
676
|
+
}
|
677
|
+
|
678
|
+
return null;
|
640
679
|
}
|
641
680
|
|
642
681
|
/**
|
@@ -152,6 +152,14 @@ export default interface IElement extends IChildNode, INonDocumentTypeChildNode,
|
|
152
152
|
*/
|
153
153
|
matches(selector: string): boolean;
|
154
154
|
|
155
|
+
/**
|
156
|
+
* Traverses the Element and its parents (heading toward the document root) until it finds a node that matches the provided selector string.
|
157
|
+
*
|
158
|
+
* @param selector Selector.
|
159
|
+
* @returns Closest matching element.
|
160
|
+
*/
|
161
|
+
closest(selector: string): IElement;
|
162
|
+
|
155
163
|
/**
|
156
164
|
* The setAttributeNode() method adds a new Attr node to the specified element.
|
157
165
|
*
|
@@ -1,8 +1,9 @@
|
|
1
1
|
import Element from '../element/Element';
|
2
|
-
import Event from '../../event/Event';
|
3
2
|
import IHTMLElement from './IHTMLElement';
|
4
3
|
import CSSStyleDeclaration from '../../css/CSSStyleDeclaration';
|
5
4
|
import Attr from '../../attribute/Attr';
|
5
|
+
import FocusEvent from '../../event/events/FocusEvent';
|
6
|
+
import PointerEvent from '../../event/events/PointerEvent';
|
6
7
|
|
7
8
|
/**
|
8
9
|
* HTML Element.
|
@@ -172,7 +173,7 @@ export default class HTMLElement extends Element implements IHTMLElement {
|
|
172
173
|
* Triggers a click event.
|
173
174
|
*/
|
174
175
|
public click(): void {
|
175
|
-
const event = new
|
176
|
+
const event = new PointerEvent('click', {
|
176
177
|
bubbles: true,
|
177
178
|
composed: true
|
178
179
|
});
|
@@ -185,8 +186,14 @@ export default class HTMLElement extends Element implements IHTMLElement {
|
|
185
186
|
* Triggers a blur event.
|
186
187
|
*/
|
187
188
|
public blur(): void {
|
189
|
+
if (this.ownerDocument['_activeElement'] !== this || !this.isConnected) {
|
190
|
+
return;
|
191
|
+
}
|
192
|
+
|
193
|
+
this.ownerDocument['_activeElement'] = null;
|
194
|
+
|
188
195
|
for (const eventType of ['blur', 'focusout']) {
|
189
|
-
const event = new
|
196
|
+
const event = new FocusEvent(eventType, {
|
190
197
|
bubbles: true,
|
191
198
|
composed: true
|
192
199
|
});
|
@@ -200,8 +207,18 @@ export default class HTMLElement extends Element implements IHTMLElement {
|
|
200
207
|
* Triggers a focus event.
|
201
208
|
*/
|
202
209
|
public focus(): void {
|
210
|
+
if (this.ownerDocument['_activeElement'] === this || !this.isConnected) {
|
211
|
+
return;
|
212
|
+
}
|
213
|
+
|
214
|
+
if (this.ownerDocument['_activeElement'] !== null) {
|
215
|
+
this.ownerDocument['_activeElement'].blur();
|
216
|
+
}
|
217
|
+
|
218
|
+
this.ownerDocument['_activeElement'] = this;
|
219
|
+
|
203
220
|
for (const eventType of ['focus', 'focusin']) {
|
204
|
-
const event = new
|
221
|
+
const event = new FocusEvent(eventType, {
|
205
222
|
bubbles: true,
|
206
223
|
composed: true
|
207
224
|
});
|
@@ -37,9 +37,6 @@ export default class HTMLInputElement extends HTMLElement implements IHTMLInputE
|
|
37
37
|
// Type specific: file
|
38
38
|
public files: File[] = [];
|
39
39
|
|
40
|
-
// Not categorized
|
41
|
-
public defaultValue = '';
|
42
|
-
|
43
40
|
// Type specific: text/password/search/tel/url/week/month
|
44
41
|
private _selectionStart = null;
|
45
42
|
private _selectionEnd = null;
|
@@ -384,21 +381,21 @@ export default class HTMLInputElement extends HTMLElement implements IHTMLInputE
|
|
384
381
|
}
|
385
382
|
|
386
383
|
/**
|
387
|
-
* Returns
|
384
|
+
* Returns defaultValue.
|
388
385
|
*
|
389
386
|
* @returns Defaultvalue.
|
390
387
|
*/
|
391
|
-
public get
|
388
|
+
public get defaultValue(): string {
|
392
389
|
return this.getAttributeNS(null, 'defaultvalue') || '';
|
393
390
|
}
|
394
391
|
|
395
392
|
/**
|
396
|
-
* Sets
|
393
|
+
* Sets defaultValue.
|
397
394
|
*
|
398
|
-
* @param
|
395
|
+
* @param defaultValue Defaultvalue.
|
399
396
|
*/
|
400
|
-
public set
|
401
|
-
this.setAttributeNS(null, 'defaultvalue',
|
397
|
+
public set defaultValue(defaultValue: string) {
|
398
|
+
this.setAttributeNS(null, 'defaultvalue', defaultValue);
|
402
399
|
}
|
403
400
|
|
404
401
|
/**
|
@@ -780,6 +777,21 @@ export default class HTMLInputElement extends HTMLElement implements IHTMLInputE
|
|
780
777
|
return this.value ? parseFloat(this.value) : NaN;
|
781
778
|
}
|
782
779
|
|
780
|
+
/**
|
781
|
+
* Selects the text.
|
782
|
+
*/
|
783
|
+
public select(): void {
|
784
|
+
if (!this._isSelectionSupported()) {
|
785
|
+
return null;
|
786
|
+
}
|
787
|
+
|
788
|
+
this._selectionStart = 0;
|
789
|
+
this._selectionEnd = this.value.length;
|
790
|
+
this._selectionDirection = HTMLInputElementSelectionDirectionEnum.none;
|
791
|
+
|
792
|
+
this.dispatchEvent(new Event('select', { bubbles: true, cancelable: true }));
|
793
|
+
}
|
794
|
+
|
783
795
|
/**
|
784
796
|
* Set selection range.
|
785
797
|
*
|
@@ -6,6 +6,7 @@ import Document from '../document/Document';
|
|
6
6
|
import IHTMLLinkElement from './IHTMLLinkElement';
|
7
7
|
import Event from '../../event/Event';
|
8
8
|
import ErrorEvent from '../../event/events/ErrorEvent';
|
9
|
+
import INode from '../../nodes/node/INode';
|
9
10
|
|
10
11
|
/**
|
11
12
|
* HTML Link Element.
|
@@ -19,79 +20,6 @@ export default class HTMLLinkElement extends HTMLElement implements IHTMLLinkEle
|
|
19
20
|
public readonly sheet: CSSStyleSheet = null;
|
20
21
|
public _evaluateCSS = true;
|
21
22
|
|
22
|
-
/**
|
23
|
-
* Returns "true" if connected to DOM.
|
24
|
-
*
|
25
|
-
* @returns "true" if connected.
|
26
|
-
*/
|
27
|
-
public get isConnected(): boolean {
|
28
|
-
return this._isConnected;
|
29
|
-
}
|
30
|
-
|
31
|
-
/**
|
32
|
-
* Sets the connected state.
|
33
|
-
*
|
34
|
-
* @param isConnected "true" if connected.
|
35
|
-
*/
|
36
|
-
public set isConnected(isConnected) {
|
37
|
-
if (this._isConnected !== isConnected) {
|
38
|
-
this._isConnected = isConnected;
|
39
|
-
|
40
|
-
for (const child of this.childNodes) {
|
41
|
-
child.isConnected = isConnected;
|
42
|
-
}
|
43
|
-
|
44
|
-
// eslint-disable-next-line
|
45
|
-
if (this.shadowRoot) {
|
46
|
-
// eslint-disable-next-line
|
47
|
-
this.shadowRoot.isConnected = isConnected;
|
48
|
-
}
|
49
|
-
|
50
|
-
if (isConnected && this._evaluateCSS) {
|
51
|
-
const href = this.getAttributeNS(null, 'href');
|
52
|
-
const rel = this.getAttributeNS(null, 'rel');
|
53
|
-
if (href !== null && rel && rel.toLowerCase() === 'stylesheet') {
|
54
|
-
(<Document>this.ownerDocument)._readyStateManager.startTask();
|
55
|
-
ResourceFetcher.fetch({ window: this.ownerDocument.defaultView, url: href })
|
56
|
-
.then(code => {
|
57
|
-
const styleSheet = new CSSStyleSheet();
|
58
|
-
styleSheet.replaceSync(code);
|
59
|
-
(<CSSStyleSheet>this.sheet) = styleSheet;
|
60
|
-
this.dispatchEvent(new Event('load'));
|
61
|
-
(<Document>this.ownerDocument)._readyStateManager.endTask();
|
62
|
-
})
|
63
|
-
.catch(error => {
|
64
|
-
this.dispatchEvent(
|
65
|
-
new ErrorEvent('error', {
|
66
|
-
message: error.message,
|
67
|
-
error
|
68
|
-
})
|
69
|
-
);
|
70
|
-
this.ownerDocument.defaultView.dispatchEvent(
|
71
|
-
new ErrorEvent('error', {
|
72
|
-
message: error.message,
|
73
|
-
error
|
74
|
-
})
|
75
|
-
);
|
76
|
-
(<Document>this.ownerDocument)._readyStateManager.endTask();
|
77
|
-
if (
|
78
|
-
!this._listeners['error'] &&
|
79
|
-
!this.ownerDocument.defaultView._listeners['error']
|
80
|
-
) {
|
81
|
-
this.ownerDocument.defaultView.console.error(error);
|
82
|
-
}
|
83
|
-
});
|
84
|
-
}
|
85
|
-
}
|
86
|
-
|
87
|
-
if (isConnected && this.connectedCallback) {
|
88
|
-
this.connectedCallback();
|
89
|
-
} else if (!isConnected && this.disconnectedCallback) {
|
90
|
-
this.disconnectedCallback();
|
91
|
-
}
|
92
|
-
}
|
93
|
-
}
|
94
|
-
|
95
23
|
/**
|
96
24
|
* Returns as.
|
97
25
|
*
|
@@ -286,4 +214,49 @@ export default class HTMLLinkElement extends HTMLElement implements IHTMLLinkEle
|
|
286
214
|
|
287
215
|
return replacedAttribute;
|
288
216
|
}
|
217
|
+
|
218
|
+
/**
|
219
|
+
* @override
|
220
|
+
*/
|
221
|
+
public _connectToNode(parentNode: INode = null): void {
|
222
|
+
const isConnected = this.isConnected;
|
223
|
+
const isParentConnected = parentNode ? parentNode.isConnected : false;
|
224
|
+
|
225
|
+
super._connectToNode(parentNode);
|
226
|
+
|
227
|
+
if (isConnected !== isParentConnected && this._evaluateCSS) {
|
228
|
+
const href = this.getAttributeNS(null, 'href');
|
229
|
+
const rel = this.getAttributeNS(null, 'rel');
|
230
|
+
|
231
|
+
if (href !== null && rel && rel.toLowerCase() === 'stylesheet') {
|
232
|
+
(<Document>this.ownerDocument)._readyStateManager.startTask();
|
233
|
+
ResourceFetcher.fetch({ window: this.ownerDocument.defaultView, url: href })
|
234
|
+
.then(code => {
|
235
|
+
const styleSheet = new CSSStyleSheet();
|
236
|
+
styleSheet.replaceSync(code);
|
237
|
+
(<CSSStyleSheet>this.sheet) = styleSheet;
|
238
|
+
this.dispatchEvent(new Event('load'));
|
239
|
+
(<Document>this.ownerDocument)._readyStateManager.endTask();
|
240
|
+
})
|
241
|
+
.catch(error => {
|
242
|
+
this.dispatchEvent(
|
243
|
+
new ErrorEvent('error', {
|
244
|
+
message: error.message,
|
245
|
+
error
|
246
|
+
})
|
247
|
+
);
|
248
|
+
this.ownerDocument.defaultView.dispatchEvent(
|
249
|
+
new ErrorEvent('error', {
|
250
|
+
message: error.message,
|
251
|
+
error
|
252
|
+
})
|
253
|
+
);
|
254
|
+
(<Document>this.ownerDocument)._readyStateManager.endTask();
|
255
|
+
if (!this._listeners['error'] && !this.ownerDocument.defaultView._listeners['error']) {
|
256
|
+
this.ownerDocument.defaultView.console.error(error);
|
257
|
+
}
|
258
|
+
});
|
259
|
+
}
|
260
|
+
}
|
261
|
+
}
|
289
262
|
}
|
@@ -4,6 +4,7 @@ import IHTMLScriptElement from './IHTMLScriptElement';
|
|
4
4
|
import ScriptUtility from './ScriptUtility';
|
5
5
|
import Event from '../../event/Event';
|
6
6
|
import ErrorEvent from '../../event/events/ErrorEvent';
|
7
|
+
import INode from '../../nodes/node/INode';
|
7
8
|
|
8
9
|
/**
|
9
10
|
* HTML Script Element.
|
@@ -16,55 +17,6 @@ export default class HTMLScriptElement extends HTMLElement implements IHTMLScrip
|
|
16
17
|
public onload: (event: Event) => void = null;
|
17
18
|
public _evaluateScript = true;
|
18
19
|
|
19
|
-
/**
|
20
|
-
* Returns "true" if connected to DOM.
|
21
|
-
*
|
22
|
-
* @returns "true" if connected.
|
23
|
-
*/
|
24
|
-
public get isConnected(): boolean {
|
25
|
-
return this._isConnected;
|
26
|
-
}
|
27
|
-
|
28
|
-
/**
|
29
|
-
* Sets the connected state.
|
30
|
-
*
|
31
|
-
* @param isConnected "true" if connected.
|
32
|
-
*/
|
33
|
-
public set isConnected(isConnected) {
|
34
|
-
if (this._isConnected !== isConnected) {
|
35
|
-
this._isConnected = isConnected;
|
36
|
-
|
37
|
-
for (const child of this.childNodes) {
|
38
|
-
child.isConnected = isConnected;
|
39
|
-
}
|
40
|
-
|
41
|
-
// eslint-disable-next-line
|
42
|
-
if (this.shadowRoot) {
|
43
|
-
// eslint-disable-next-line
|
44
|
-
this.shadowRoot.isConnected = isConnected;
|
45
|
-
}
|
46
|
-
|
47
|
-
if (isConnected && this._evaluateScript) {
|
48
|
-
const src = this.getAttributeNS(null, 'src');
|
49
|
-
|
50
|
-
if (src !== null) {
|
51
|
-
ScriptUtility.loadExternalScript(this);
|
52
|
-
} else {
|
53
|
-
const textContent = this.textContent;
|
54
|
-
if (textContent) {
|
55
|
-
this.ownerDocument.defaultView.eval(textContent);
|
56
|
-
}
|
57
|
-
}
|
58
|
-
}
|
59
|
-
|
60
|
-
if (isConnected && this.connectedCallback) {
|
61
|
-
this.connectedCallback();
|
62
|
-
} else if (!isConnected && this.disconnectedCallback) {
|
63
|
-
this.disconnectedCallback();
|
64
|
-
}
|
65
|
-
}
|
66
|
-
}
|
67
|
-
|
68
20
|
/**
|
69
21
|
* Returns type.
|
70
22
|
*
|
@@ -226,4 +178,27 @@ export default class HTMLScriptElement extends HTMLElement implements IHTMLScrip
|
|
226
178
|
public cloneNode(deep = false): IHTMLScriptElement {
|
227
179
|
return <IHTMLScriptElement>super.cloneNode(deep);
|
228
180
|
}
|
181
|
+
|
182
|
+
/**
|
183
|
+
* @override
|
184
|
+
*/
|
185
|
+
public _connectToNode(parentNode: INode = null): void {
|
186
|
+
const isConnected = this.isConnected;
|
187
|
+
const isParentConnected = parentNode ? parentNode.isConnected : false;
|
188
|
+
|
189
|
+
super._connectToNode(parentNode);
|
190
|
+
|
191
|
+
if (isConnected !== isParentConnected && this._evaluateScript) {
|
192
|
+
const src = this.getAttributeNS(null, 'src');
|
193
|
+
|
194
|
+
if (src !== null) {
|
195
|
+
ScriptUtility.loadExternalScript(this);
|
196
|
+
} else {
|
197
|
+
const textContent = this.textContent;
|
198
|
+
if (textContent) {
|
199
|
+
this.ownerDocument.defaultView.eval(textContent);
|
200
|
+
}
|
201
|
+
}
|
202
|
+
}
|
203
|
+
}
|
229
204
|
}
|
@@ -15,7 +15,7 @@ export default class HTMLStyleElement extends HTMLElement implements IHTMLStyleE
|
|
15
15
|
* @returns CSS style sheet.
|
16
16
|
*/
|
17
17
|
public get sheet(): CSSStyleSheet {
|
18
|
-
if (!this.
|
18
|
+
if (!this.isConnected) {
|
19
19
|
return null;
|
20
20
|
}
|
21
21
|
const styleSheet = new CSSStyleSheet();
|
package/src/nodes/node/INode.ts
CHANGED
@@ -8,7 +8,7 @@ export default interface INode extends IEventTarget {
|
|
8
8
|
readonly parentElement: IElement;
|
9
9
|
readonly nodeType: number;
|
10
10
|
readonly childNodes: INode[];
|
11
|
-
isConnected: boolean;
|
11
|
+
readonly isConnected: boolean;
|
12
12
|
readonly nodeValue: string;
|
13
13
|
readonly nodeName: string;
|
14
14
|
readonly previousSibling: INode;
|