happy-dom 6.0.3 → 7.0.0

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.

Files changed (183) hide show
  1. package/lib/css/CSSParser.js +12 -6
  2. package/lib/css/CSSParser.js.map +1 -1
  3. package/lib/css/CSSRule.d.ts +15 -13
  4. package/lib/css/CSSRule.js +18 -13
  5. package/lib/css/CSSRule.js.map +1 -1
  6. package/lib/css/CSSRuleTypeEnum.d.ts +17 -0
  7. package/lib/css/CSSRuleTypeEnum.js +21 -0
  8. package/lib/css/CSSRuleTypeEnum.js.map +1 -0
  9. package/lib/css/CSSStyleSheet.d.ts +6 -16
  10. package/lib/css/CSSStyleSheet.js +11 -19
  11. package/lib/css/CSSStyleSheet.js.map +1 -1
  12. package/lib/css/declaration/AbstractCSSStyleDeclaration.d.ts +76 -0
  13. package/lib/css/declaration/AbstractCSSStyleDeclaration.js +182 -0
  14. package/lib/css/declaration/AbstractCSSStyleDeclaration.js.map +1 -0
  15. package/lib/css/declaration/CSSStyleDeclaration.d.ts +1194 -0
  16. package/lib/css/declaration/CSSStyleDeclaration.js +3566 -0
  17. package/lib/css/declaration/CSSStyleDeclaration.js.map +1 -0
  18. package/lib/css/declaration/utilities/CSSStyleDeclarationCSSParser.d.ts +12 -0
  19. package/lib/css/declaration/utilities/CSSStyleDeclarationCSSParser.js +34 -0
  20. package/lib/css/declaration/utilities/CSSStyleDeclarationCSSParser.js.map +1 -0
  21. package/lib/css/declaration/utilities/CSSStyleDeclarationElementDefaultCSS.d.ts +131 -0
  22. package/lib/css/declaration/utilities/CSSStyleDeclarationElementDefaultCSS.js +133 -0
  23. package/lib/css/declaration/utilities/CSSStyleDeclarationElementDefaultCSS.js.map +1 -0
  24. package/lib/css/declaration/utilities/CSSStyleDeclarationElementInheritedProperties.d.ts +40 -0
  25. package/lib/css/declaration/utilities/CSSStyleDeclarationElementInheritedProperties.js +42 -0
  26. package/lib/css/declaration/utilities/CSSStyleDeclarationElementInheritedProperties.js.map +1 -0
  27. package/lib/css/declaration/utilities/CSSStyleDeclarationElementStyle.d.ts +49 -0
  28. package/lib/css/declaration/utilities/CSSStyleDeclarationElementStyle.js +244 -0
  29. package/lib/css/declaration/utilities/CSSStyleDeclarationElementStyle.js.map +1 -0
  30. package/lib/css/declaration/utilities/CSSStyleDeclarationPropertyGetParser.d.ts +167 -0
  31. package/lib/css/declaration/utilities/CSSStyleDeclarationPropertyGetParser.js +537 -0
  32. package/lib/css/declaration/utilities/CSSStyleDeclarationPropertyGetParser.js.map +1 -0
  33. package/lib/css/declaration/utilities/CSSStyleDeclarationPropertyManager.d.ts +65 -0
  34. package/lib/css/declaration/utilities/CSSStyleDeclarationPropertyManager.js +565 -0
  35. package/lib/css/declaration/utilities/CSSStyleDeclarationPropertyManager.js.map +1 -0
  36. package/lib/css/declaration/utilities/CSSStyleDeclarationPropertySetParser.d.ts +809 -0
  37. package/lib/css/declaration/utilities/CSSStyleDeclarationPropertySetParser.js +2303 -0
  38. package/lib/css/declaration/utilities/CSSStyleDeclarationPropertySetParser.js.map +1 -0
  39. package/lib/css/declaration/utilities/CSSStyleDeclarationValueParser.d.ts +127 -0
  40. package/lib/css/declaration/utilities/CSSStyleDeclarationValueParser.js +411 -0
  41. package/lib/css/declaration/utilities/CSSStyleDeclarationValueParser.js.map +1 -0
  42. package/lib/css/declaration/utilities/ICSSStyleDeclarationPropertyValue.d.ts +4 -0
  43. package/lib/css/declaration/utilities/ICSSStyleDeclarationPropertyValue.js +3 -0
  44. package/lib/css/declaration/utilities/ICSSStyleDeclarationPropertyValue.js.map +1 -0
  45. package/lib/css/rules/CSSContainerRule.d.ts +15 -0
  46. package/lib/css/rules/CSSContainerRule.js +31 -0
  47. package/lib/css/rules/CSSContainerRule.js.map +1 -0
  48. package/lib/css/rules/CSSFontFaceRule.d.ts +10 -3
  49. package/lib/css/rules/CSSFontFaceRule.js +16 -0
  50. package/lib/css/rules/CSSFontFaceRule.js.map +1 -1
  51. package/lib/css/rules/CSSKeyframeRule.d.ts +10 -3
  52. package/lib/css/rules/CSSKeyframeRule.js +16 -0
  53. package/lib/css/rules/CSSKeyframeRule.js.map +1 -1
  54. package/lib/css/rules/CSSKeyframesRule.d.ts +1 -1
  55. package/lib/css/rules/CSSKeyframesRule.js +1 -1
  56. package/lib/css/rules/CSSKeyframesRule.js.map +1 -1
  57. package/lib/css/rules/CSSMediaRule.d.ts +1 -1
  58. package/lib/css/rules/CSSStyleRule.d.ts +10 -3
  59. package/lib/css/rules/CSSStyleRule.js +16 -0
  60. package/lib/css/rules/CSSStyleRule.js.map +1 -1
  61. package/lib/event/Event.d.ts +2 -3
  62. package/lib/event/Event.js.map +1 -1
  63. package/lib/event/events/IMediaQueryListInit.d.ts +5 -0
  64. package/lib/event/events/IMediaQueryListInit.js +3 -0
  65. package/lib/event/events/IMediaQueryListInit.js.map +1 -0
  66. package/lib/event/events/MediaQueryListEvent.d.ts +16 -0
  67. package/lib/event/events/MediaQueryListEvent.js +28 -0
  68. package/lib/event/events/MediaQueryListEvent.js.map +1 -0
  69. package/lib/exception/DOMException.js +5 -3
  70. package/lib/exception/DOMException.js.map +1 -1
  71. package/lib/exception/DOMExceptionNameEnum.d.ts +2 -1
  72. package/lib/exception/DOMExceptionNameEnum.js +1 -0
  73. package/lib/exception/DOMExceptionNameEnum.js.map +1 -1
  74. package/lib/fetch/Response.d.ts +4 -1
  75. package/lib/fetch/Response.js +5 -2
  76. package/lib/fetch/Response.js.map +1 -1
  77. package/lib/file/Blob.d.ts +9 -0
  78. package/lib/file/Blob.js +14 -0
  79. package/lib/file/Blob.js.map +1 -1
  80. package/lib/index.d.ts +9 -2
  81. package/lib/index.js +16 -2
  82. package/lib/index.js.map +1 -1
  83. package/lib/match-media/MediaQueryList.d.ts +19 -8
  84. package/lib/match-media/MediaQueryList.js +56 -13
  85. package/lib/match-media/MediaQueryList.js.map +1 -1
  86. package/lib/{attribute → nodes/attr}/Attr.d.ts +8 -7
  87. package/lib/{attribute → nodes/attr}/Attr.js +12 -5
  88. package/lib/nodes/attr/Attr.js.map +1 -0
  89. package/lib/nodes/attr/IAttr.d.ts +14 -0
  90. package/lib/nodes/attr/IAttr.js +3 -0
  91. package/lib/nodes/attr/IAttr.js.map +1 -0
  92. package/lib/nodes/child-node/ChildNodeUtility.js +2 -1
  93. package/lib/nodes/child-node/ChildNodeUtility.js.map +1 -1
  94. package/lib/nodes/document/Document.d.ts +4 -4
  95. package/lib/nodes/document/Document.js +5 -8
  96. package/lib/nodes/document/Document.js.map +1 -1
  97. package/lib/nodes/document/IDocument.d.ts +3 -3
  98. package/lib/nodes/element/Element.d.ts +11 -9
  99. package/lib/nodes/element/Element.js +2 -1
  100. package/lib/nodes/element/Element.js.map +1 -1
  101. package/lib/nodes/element/IElement.d.ts +10 -8
  102. package/lib/nodes/html-element/HTMLElement.d.ts +21 -5
  103. package/lib/nodes/html-element/HTMLElement.js +74 -11
  104. package/lib/nodes/html-element/HTMLElement.js.map +1 -1
  105. package/lib/nodes/html-element/IHTMLElement.d.ts +5 -1
  106. package/lib/nodes/html-link-element/HTMLLinkElement.d.ts +2 -2
  107. package/lib/nodes/html-link-element/HTMLLinkElement.js.map +1 -1
  108. package/lib/nodes/html-script-element/HTMLScriptElement.d.ts +2 -2
  109. package/lib/nodes/html-script-element/HTMLScriptElement.js.map +1 -1
  110. package/lib/nodes/html-select-element/HTMLSelectElement.js +1 -1
  111. package/lib/nodes/html-select-element/HTMLSelectElement.js.map +1 -1
  112. package/lib/nodes/html-style-element/HTMLStyleElement.js +1 -1
  113. package/lib/nodes/html-style-element/HTMLStyleElement.js.map +1 -1
  114. package/lib/nodes/node/INode.d.ts +2 -0
  115. package/lib/nodes/node/Node.d.ts +5 -1
  116. package/lib/nodes/node/Node.js +7 -1
  117. package/lib/nodes/node/Node.js.map +1 -1
  118. package/lib/nodes/node/NodeTypeEnum.d.ts +2 -0
  119. package/lib/nodes/node/NodeTypeEnum.js +2 -0
  120. package/lib/nodes/node/NodeTypeEnum.js.map +1 -1
  121. package/lib/nodes/svg-element/ISVGElement.d.ts +1 -1
  122. package/lib/nodes/svg-element/SVGElement.d.ts +4 -4
  123. package/lib/nodes/svg-element/SVGElement.js +2 -2
  124. package/lib/nodes/svg-element/SVGElement.js.map +1 -1
  125. package/lib/window/IWindow.d.ts +23 -3
  126. package/lib/window/Window.d.ts +35 -6
  127. package/lib/window/Window.js +58 -23
  128. package/lib/window/Window.js.map +1 -1
  129. package/package.json +2 -2
  130. package/src/css/CSSParser.ts +14 -6
  131. package/src/css/CSSRule.ts +15 -13
  132. package/src/css/CSSRuleTypeEnum.ts +18 -0
  133. package/src/css/CSSStyleSheet.ts +12 -22
  134. package/src/css/declaration/AbstractCSSStyleDeclaration.ts +202 -0
  135. package/src/css/declaration/CSSStyleDeclaration.ts +4743 -0
  136. package/src/css/declaration/utilities/CSSStyleDeclarationCSSParser.ts +35 -0
  137. package/src/css/declaration/utilities/CSSStyleDeclarationElementDefaultCSS.ts +130 -0
  138. package/src/css/declaration/utilities/CSSStyleDeclarationElementInheritedProperties.ts +39 -0
  139. package/src/css/declaration/utilities/CSSStyleDeclarationElementStyle.ts +282 -0
  140. package/src/css/declaration/utilities/CSSStyleDeclarationPropertyGetParser.ts +743 -0
  141. package/src/css/declaration/utilities/CSSStyleDeclarationPropertyManager.ts +592 -0
  142. package/src/css/declaration/utilities/CSSStyleDeclarationPropertySetParser.ts +3026 -0
  143. package/src/css/declaration/utilities/CSSStyleDeclarationValueParser.ts +437 -0
  144. package/src/css/declaration/utilities/ICSSStyleDeclarationPropertyValue.ts +4 -0
  145. package/src/css/rules/CSSContainerRule.ts +23 -0
  146. package/src/css/rules/CSSFontFaceRule.ts +17 -2
  147. package/src/css/rules/CSSKeyframeRule.ts +17 -2
  148. package/src/css/rules/CSSKeyframesRule.ts +1 -1
  149. package/src/css/rules/CSSStyleRule.ts +17 -2
  150. package/src/event/Event.ts +2 -3
  151. package/src/event/events/IMediaQueryListInit.ts +6 -0
  152. package/src/event/events/MediaQueryListEvent.ts +25 -0
  153. package/src/exception/DOMException.ts +3 -3
  154. package/src/exception/DOMExceptionNameEnum.ts +2 -1
  155. package/src/fetch/Response.ts +5 -2
  156. package/src/file/Blob.ts +16 -0
  157. package/src/index.ts +15 -1
  158. package/src/match-media/MediaQueryList.ts +63 -10
  159. package/src/{attribute → nodes/attr}/Attr.ts +11 -8
  160. package/src/nodes/attr/IAttr.ts +15 -0
  161. package/src/nodes/child-node/ChildNodeUtility.ts +2 -1
  162. package/src/nodes/document/Document.ts +8 -10
  163. package/src/nodes/document/IDocument.ts +3 -3
  164. package/src/nodes/element/Element.ts +13 -10
  165. package/src/nodes/element/IElement.ts +8 -8
  166. package/src/nodes/html-element/HTMLElement.ts +94 -16
  167. package/src/nodes/html-element/IHTMLElement.ts +3 -1
  168. package/src/nodes/html-link-element/HTMLLinkElement.ts +2 -2
  169. package/src/nodes/html-script-element/HTMLScriptElement.ts +2 -2
  170. package/src/nodes/html-select-element/HTMLSelectElement.ts +1 -1
  171. package/src/nodes/html-style-element/HTMLStyleElement.ts +1 -1
  172. package/src/nodes/node/INode.ts +2 -0
  173. package/src/nodes/node/Node.ts +7 -1
  174. package/src/nodes/node/NodeTypeEnum.ts +2 -0
  175. package/src/nodes/svg-element/ISVGElement.ts +1 -1
  176. package/src/nodes/svg-element/SVGElement.ts +5 -5
  177. package/src/window/IWindow.ts +23 -3
  178. package/src/window/Window.ts +51 -11
  179. package/lib/attribute/Attr.js.map +0 -1
  180. package/lib/css/CSSStyleDeclaration.d.ts +0 -3017
  181. package/lib/css/CSSStyleDeclaration.js +0 -4643
  182. package/lib/css/CSSStyleDeclaration.js.map +0 -1
  183. package/src/css/CSSStyleDeclaration.ts +0 -5026
package/src/index.ts CHANGED
@@ -13,7 +13,7 @@ import File from './file/File';
13
13
  import FileReader from './file/FileReader';
14
14
  import DOMException from './exception/DOMException';
15
15
  import History from './history/History';
16
- import CSSStyleDeclaration from './css/CSSStyleDeclaration';
16
+ import CSSStyleDeclaration from './css/declaration/CSSStyleDeclaration';
17
17
  import Screen from './screen/Screen';
18
18
  import AsyncTaskManager from './async-task-manager/AsyncTaskManager';
19
19
  import NodeFilter from './tree-walker/NodeFilter';
@@ -100,6 +100,13 @@ import CustomElementRegistry from './custom-element/CustomElementRegistry';
100
100
  import XMLParser from './xml-parser/XMLParser';
101
101
  import XMLSerializer from './xml-serializer/XMLSerializer';
102
102
  import CSSStyleSheet from './css/CSSStyleSheet';
103
+ import CSSRule from './css/CSSRule';
104
+ import CSSContainerRule from './css/rules/CSSContainerRule';
105
+ import CSSFontFaceRule from './css/rules/CSSFontFaceRule';
106
+ import CSSKeyframeRule from './css/rules/CSSKeyframeRule';
107
+ import CSSKeyframesRule from './css/rules/CSSKeyframesRule';
108
+ import CSSMediaRule from './css/rules/CSSMediaRule';
109
+ import CSSStyleRule from './css/rules/CSSStyleRule';
103
110
  import Storage from './storage/Storage';
104
111
  import DOMRect from './nodes/element/DOMRect';
105
112
  import { URLSearchParams } from 'url';
@@ -211,6 +218,13 @@ export {
211
218
  XMLParser,
212
219
  XMLSerializer,
213
220
  CSSStyleSheet,
221
+ CSSRule,
222
+ CSSContainerRule,
223
+ CSSFontFaceRule,
224
+ CSSKeyframeRule,
225
+ CSSKeyframesRule,
226
+ CSSMediaRule,
227
+ CSSStyleRule,
214
228
  Storage,
215
229
  DOMRect,
216
230
  URLSearchParams,
@@ -1,5 +1,11 @@
1
1
  import EventTarget from '../event/EventTarget';
2
2
  import Event from '../event/Event';
3
+ import IWindow from '../window/IWindow';
4
+ import IEventListener from '../event/IEventListener';
5
+ import MediaQueryListEvent from '../event/events/MediaQueryListEvent';
6
+
7
+ const MEDIA_REGEXP =
8
+ /min-width: *([0-9]+) *px|max-width: *([0-9]+) *px|min-height: *([0-9]+) *px|max-height: *([0-9]+) *px/;
3
9
 
4
10
  /**
5
11
  * Media Query List.
@@ -8,26 +14,41 @@ import Event from '../event/Event';
8
14
  * https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList.
9
15
  */
10
16
  export default class MediaQueryList extends EventTarget {
11
- public _matches = false;
12
- public _media = '';
17
+ public readonly media: string = '';
13
18
  public onchange: (event: Event) => void = null;
19
+ private _ownerWindow: IWindow;
14
20
 
15
21
  /**
16
- * Returns "true" if the document matches.
22
+ * Constructor.
17
23
  *
18
- * @returns Matches.
24
+ * @param ownerWindow Window.
25
+ * @param media Media.
19
26
  */
20
- public get matches(): boolean {
21
- return this._matches;
27
+ constructor(ownerWindow: IWindow, media: string) {
28
+ super();
29
+ this._ownerWindow = ownerWindow;
30
+ this.media = media;
22
31
  }
23
32
 
24
33
  /**
25
- * Returns the serialized media query.
34
+ * Returns "true" if the document matches.
26
35
  *
27
- * @returns Serialized media query.
36
+ * @returns Matches.
28
37
  */
29
- public get media(): string {
30
- return this._media;
38
+ public get matches(): boolean {
39
+ const match = MEDIA_REGEXP.exec(this.media);
40
+ if (match) {
41
+ if (match[1]) {
42
+ return this._ownerWindow.innerWidth >= parseInt(match[1]);
43
+ } else if (match[2]) {
44
+ return this._ownerWindow.innerWidth <= parseInt(match[2]);
45
+ } else if (match[3]) {
46
+ return this._ownerWindow.innerHeight >= parseInt(match[3]);
47
+ } else if (match[4]) {
48
+ return this._ownerWindow.innerHeight <= parseInt(match[4]);
49
+ }
50
+ }
51
+ return false;
31
52
  }
32
53
 
33
54
  /**
@@ -49,4 +70,36 @@ export default class MediaQueryList extends EventTarget {
49
70
  public removeListener(callback: (event: Event) => void): void {
50
71
  this.removeEventListener('change', callback);
51
72
  }
73
+
74
+ /**
75
+ * @override
76
+ */
77
+ public addEventListener(type: string, listener: IEventListener | ((event: Event) => void)): void {
78
+ super.addEventListener(type, listener);
79
+ if (type === 'change') {
80
+ let matchesState = false;
81
+ const resizeListener = (): void => {
82
+ const matches = this.matches;
83
+ if (matches !== matchesState) {
84
+ matchesState = matches;
85
+ this.dispatchEvent(new MediaQueryListEvent('change', { matches, media: this.media }));
86
+ }
87
+ };
88
+ listener['_windowResizeListener'] = resizeListener;
89
+ this._ownerWindow.addEventListener('resize', resizeListener);
90
+ }
91
+ }
92
+
93
+ /**
94
+ * @override
95
+ */
96
+ public removeEventListener(
97
+ type: string,
98
+ listener: IEventListener | ((event: Event) => void)
99
+ ): void {
100
+ super.removeEventListener(type, listener);
101
+ if (type === 'change' && listener['_windowResizeListener']) {
102
+ this._ownerWindow.removeEventListener('resize', listener['_windowResizeListener']);
103
+ }
104
+ }
52
105
  }
@@ -1,12 +1,13 @@
1
- import IDocument from '../nodes/document/IDocument';
2
- import IElement from '../nodes/element/IElement';
1
+ import IElement from '../element/IElement';
2
+ import Node from '../node/Node';
3
+ import IAttr from './IAttr';
3
4
 
4
5
  /**
5
6
  * Attribute node interface.
6
7
  *
7
8
  * Reference: https://developer.mozilla.org/en-US/docs/Web/API/Attr.
8
9
  */
9
- export default class Attr {
10
+ export default class Attr extends Node implements IAttr {
10
11
  public value: string = null;
11
12
  public name: string = null;
12
13
  public namespaceURI: string = null;
@@ -16,11 +17,6 @@ export default class Attr {
16
17
  */
17
18
  public readonly ownerElement: IElement = null;
18
19
 
19
- /**
20
- * @deprecated
21
- */
22
- public readonly ownerDocument: IDocument = null;
23
-
24
20
  /**
25
21
  * @deprecated
26
22
  */
@@ -43,4 +39,11 @@ export default class Attr {
43
39
  public get prefix(): string {
44
40
  return this.name ? this.name.split(':')[0] : null;
45
41
  }
42
+
43
+ /**
44
+ * @override
45
+ */
46
+ public get textContent(): string {
47
+ return this.value;
48
+ }
46
49
  }
@@ -0,0 +1,15 @@
1
+ import IElement from '../element/IElement';
2
+ import INode from './../node/INode';
3
+
4
+ /**
5
+ * Attr.
6
+ */
7
+ export default interface IAttr extends INode {
8
+ value: string;
9
+ name: string;
10
+ namespaceURI: string;
11
+ readonly ownerElement: IElement;
12
+ readonly specified: boolean;
13
+ readonly localName: string;
14
+ readonly prefix: string;
15
+ }
@@ -1,3 +1,4 @@
1
+ import DOMException from '../../exception/DOMException';
1
2
  import XMLParser from '../../xml-parser/XMLParser';
2
3
  import Document from '../document/Document';
3
4
  import INode from '../node/INode';
@@ -29,7 +30,7 @@ export default class ChildNodeUtility {
29
30
  const parent = <IParentNode>childNode.parentNode;
30
31
 
31
32
  if (!parent) {
32
- return;
33
+ throw new DOMException('This element has no parent node.');
33
34
  }
34
35
 
35
36
  for (const node of nodes) {
@@ -11,7 +11,7 @@ import Event from '../../event/Event';
11
11
  import DOMImplementation from '../../dom-implementation/DOMImplementation';
12
12
  import ElementTag from '../../config/ElementTag';
13
13
  import INodeFilter from '../../tree-walker/INodeFilter';
14
- import Attr from '../../attribute/Attr';
14
+ import Attr from '../attr/Attr';
15
15
  import NamespaceURI from '../../config/NamespaceURI';
16
16
  import DocumentType from '../document-type/DocumentType';
17
17
  import ParentNodeUtility from '../parent-node/ParentNodeUtility';
@@ -40,6 +40,7 @@ import Selection from '../../selection/Selection';
40
40
  import IShadowRoot from '../shadow-root/IShadowRoot';
41
41
  import Range from '../../range/Range';
42
42
  import IHTMLBaseElement from '../html-base-element/IHTMLBaseElement';
43
+ import IAttr from '../attr/IAttr';
43
44
 
44
45
  /**
45
46
  * Document.
@@ -716,14 +717,11 @@ export default class Document extends Node implements IDocument {
716
717
  /**
717
718
  * Creates an Attr node.
718
719
  *
719
- * @param name Name.
720
+ * @param qualifiedName Name.
720
721
  * @returns Attribute.
721
722
  */
722
- public createAttribute(name: string): Attr {
723
- const attribute = new Attr();
724
- attribute.name = name.toLowerCase();
725
- (<IDocument>attribute.ownerDocument) = this;
726
- return attribute;
723
+ public createAttribute(qualifiedName: string): IAttr {
724
+ return this.createAttributeNS(null, qualifiedName.toLowerCase());
727
725
  }
728
726
 
729
727
  /**
@@ -733,12 +731,12 @@ export default class Document extends Node implements IDocument {
733
731
  * @param qualifiedName Qualified name.
734
732
  * @returns Element.
735
733
  */
736
- public createAttributeNS(namespaceURI: string, qualifiedName: string): Attr {
734
+ public createAttributeNS(namespaceURI: string, qualifiedName: string): IAttr {
735
+ Attr._ownerDocument = this;
737
736
  const attribute = new Attr();
738
737
  attribute.namespaceURI = namespaceURI;
739
738
  attribute.name = qualifiedName;
740
- (<IDocument>attribute.ownerDocument) = this;
741
- return attribute;
739
+ return <IAttr>attribute;
742
740
  }
743
741
 
744
742
  /**
@@ -5,7 +5,7 @@ import TreeWalker from '../../tree-walker/TreeWalker';
5
5
  import Event from '../../event/Event';
6
6
  import DOMImplementation from '../../dom-implementation/DOMImplementation';
7
7
  import INodeFilter from '../../tree-walker/INodeFilter';
8
- import Attr from '../../attribute/Attr';
8
+ import IAttr from '../attr/IAttr';
9
9
  import IDocumentType from '../document-type/IDocumentType';
10
10
  import IParentNode from '../parent-node/IParentNode';
11
11
  import INode from '../node/INode';
@@ -125,7 +125,7 @@ export default interface IDocument extends IParentNode {
125
125
  * @param name Name.
126
126
  * @returns Attribute.
127
127
  */
128
- createAttribute(name: string): Attr;
128
+ createAttribute(name: string): IAttr;
129
129
 
130
130
  /**
131
131
  * Creates a namespaced Attr node.
@@ -134,7 +134,7 @@ export default interface IDocument extends IParentNode {
134
134
  * @param qualifiedName Qualified name.
135
135
  * @returns Element.
136
136
  */
137
- createAttributeNS(namespaceURI: string, qualifiedName: string): Attr;
137
+ createAttributeNS(namespaceURI: string, qualifiedName: string): IAttr;
138
138
 
139
139
  /**
140
140
  * Imports a node.
@@ -1,6 +1,6 @@
1
1
  import Node from '../node/Node';
2
2
  import ShadowRoot from '../shadow-root/ShadowRoot';
3
- import Attr from '../../attribute/Attr';
3
+ import Attr from '../attr/Attr';
4
4
  import DOMRect from './DOMRect';
5
5
  import DOMTokenList from '../../dom-token-list/DOMTokenList';
6
6
  import IDOMTokenList from '../../dom-token-list/IDOMTokenList';
@@ -26,6 +26,7 @@ import { TInsertAdjacentPositions } from './IElement';
26
26
  import IText from '../text/IText';
27
27
  import IDOMRectList from './IDOMRectList';
28
28
  import DOMRectListFactory from './DOMRectListFactory';
29
+ import IAttr from '../attr/IAttr';
29
30
 
30
31
  /**
31
32
  * Element.
@@ -46,7 +47,7 @@ export default class Element extends Node implements IElement {
46
47
 
47
48
  // Used for being able to access closed shadow roots
48
49
  public _shadowRoot: IShadowRoot = null;
49
- public _attributes: { [k: string]: Attr } = {};
50
+ public _attributes: { [k: string]: IAttr } = {};
50
51
 
51
52
  private _classList: DOMTokenList = null;
52
53
  public _isValue?: string;
@@ -211,7 +212,7 @@ export default class Element extends Node implements IElement {
211
212
  *
212
213
  * @returns Attributes.
213
214
  */
214
- public get attributes(): { [k: string]: Attr | number } {
215
+ public get attributes(): { [k: string | number]: IAttr } & { length: number } {
215
216
  const attributes = Object.values(this._attributes);
216
217
  return Object.assign({}, this._attributes, attributes, {
217
218
  length: attributes.length
@@ -302,6 +303,8 @@ export default class Element extends Node implements IElement {
302
303
  public cloneNode(deep = false): IElement {
303
304
  const clone = <Element | IElement>super.cloneNode(deep);
304
305
 
306
+ Attr._ownerDocument = this.ownerDocument;
307
+
305
308
  for (const key of Object.keys(this._attributes)) {
306
309
  const attr = Object.assign(new Attr(), this._attributes[key]);
307
310
  (<IElement>attr.ownerElement) = clone;
@@ -802,13 +805,13 @@ export default class Element extends Node implements IElement {
802
805
  * @param attribute Attribute.
803
806
  * @returns Replaced attribute.
804
807
  */
805
- public setAttributeNode(attribute: Attr): Attr {
808
+ public setAttributeNode(attribute: IAttr): IAttr {
806
809
  const name = this._getAttributeName(attribute.name);
807
810
  const replacedAttribute = this._attributes[name];
808
811
  const oldValue = replacedAttribute ? replacedAttribute.value : null;
809
812
 
810
813
  attribute.name = name;
811
- (<IElement>attribute.ownerElement) = this;
814
+ (<IElement>attribute.ownerElement) = <IElement>this;
812
815
  (<IDocument>attribute.ownerDocument) = this.ownerDocument;
813
816
 
814
817
  this._attributes[name] = attribute;
@@ -849,7 +852,7 @@ export default class Element extends Node implements IElement {
849
852
  * @param attribute Attribute.
850
853
  * @returns Replaced attribute.
851
854
  */
852
- public setAttributeNodeNS(attribute: Attr): Attr {
855
+ public setAttributeNodeNS(attribute: IAttr): IAttr {
853
856
  return this.setAttributeNode(attribute);
854
857
  }
855
858
 
@@ -859,7 +862,7 @@ export default class Element extends Node implements IElement {
859
862
  * @param name Name.
860
863
  * @returns Replaced attribute.
861
864
  */
862
- public getAttributeNode(name: string): Attr {
865
+ public getAttributeNode(name: string): IAttr {
863
866
  return this._attributes[this._getAttributeName(name)] || null;
864
867
  }
865
868
 
@@ -870,7 +873,7 @@ export default class Element extends Node implements IElement {
870
873
  * @param name Name.
871
874
  * @returns Replaced attribute.
872
875
  */
873
- public getAttributeNodeNS(namespace: string, name: string): Attr {
876
+ public getAttributeNodeNS(namespace: string, name: string): IAttr {
874
877
  const attributeName = this._getAttributeName(name);
875
878
  if (
876
879
  this._attributes[attributeName] &&
@@ -893,7 +896,7 @@ export default class Element extends Node implements IElement {
893
896
  *
894
897
  * @param attribute Attribute.
895
898
  */
896
- public removeAttributeNode(attribute: Attr): void {
899
+ public removeAttributeNode(attribute: IAttr): void {
897
900
  delete this._attributes[attribute.name];
898
901
 
899
902
  this._updateDomListIndices();
@@ -930,7 +933,7 @@ export default class Element extends Node implements IElement {
930
933
  *
931
934
  * @param attribute Attribute.
932
935
  */
933
- public removeAttributeNodeNS(attribute: Attr): void {
936
+ public removeAttributeNodeNS(attribute: IAttr): void {
934
937
  this.removeAttributeNode(attribute);
935
938
  }
936
939
 
@@ -1,5 +1,5 @@
1
1
  import IShadowRoot from '../shadow-root/IShadowRoot';
2
- import Attr from '../../attribute/Attr';
2
+ import IAttr from '../attr/IAttr';
3
3
  import DOMRect from './DOMRect';
4
4
  import IDOMTokenList from '../../dom-token-list/IDOMTokenList';
5
5
  import INode from './../node/INode';
@@ -27,7 +27,7 @@ export default interface IElement extends IChildNode, INonDocumentTypeChildNode,
27
27
  slot: string;
28
28
  readonly nodeName: string;
29
29
  readonly localName: string;
30
- readonly attributes: { [k: string]: Attr | number };
30
+ readonly attributes: { [k: string | number]: IAttr } & { length: number };
31
31
 
32
32
  /**
33
33
  * Attribute changed callback.
@@ -190,7 +190,7 @@ export default interface IElement extends IChildNode, INonDocumentTypeChildNode,
190
190
  * @param attribute Attribute.
191
191
  * @returns Replaced attribute.
192
192
  */
193
- setAttributeNode(attribute: Attr): Attr;
193
+ setAttributeNode(attribute: IAttr): IAttr;
194
194
 
195
195
  /**
196
196
  * The setAttributeNodeNS() method adds a new Attr node to the specified element.
@@ -198,7 +198,7 @@ export default interface IElement extends IChildNode, INonDocumentTypeChildNode,
198
198
  * @param attribute Attribute.
199
199
  * @returns Replaced attribute.
200
200
  */
201
- setAttributeNodeNS(attribute: Attr): Attr;
201
+ setAttributeNodeNS(attribute: IAttr): IAttr;
202
202
 
203
203
  /**
204
204
  * Returns an Attr node.
@@ -206,7 +206,7 @@ export default interface IElement extends IChildNode, INonDocumentTypeChildNode,
206
206
  * @param name Name.
207
207
  * @returns Replaced attribute.
208
208
  */
209
- getAttributeNode(name: string): Attr;
209
+ getAttributeNode(name: string): IAttr;
210
210
 
211
211
  /**
212
212
  * Returns a namespaced Attr node.
@@ -215,21 +215,21 @@ export default interface IElement extends IChildNode, INonDocumentTypeChildNode,
215
215
  * @param nodeName Node name.
216
216
  * @returns Replaced attribute.
217
217
  */
218
- getAttributeNodeNS(namespace: string, nodeName: string): Attr;
218
+ getAttributeNodeNS(namespace: string, nodeName: string): IAttr;
219
219
 
220
220
  /**
221
221
  * Removes an Attr node.
222
222
  *
223
223
  * @param attribute Attribute.
224
224
  */
225
- removeAttributeNode(attribute: Attr): void;
225
+ removeAttributeNode(attribute: IAttr): void;
226
226
 
227
227
  /**
228
228
  * Removes an Attr node.
229
229
  *
230
230
  * @param attribute Attribute.
231
231
  */
232
- removeAttributeNodeNS(attribute: Attr): void;
232
+ removeAttributeNodeNS(attribute: IAttr): void;
233
233
 
234
234
  /**
235
235
  * Clones a node.
@@ -1,11 +1,12 @@
1
1
  import Element from '../element/Element';
2
2
  import IHTMLElement from './IHTMLElement';
3
- import CSSStyleDeclaration from '../../css/CSSStyleDeclaration';
4
- import Attr from '../../attribute/Attr';
3
+ import CSSStyleDeclaration from '../../css/declaration/CSSStyleDeclaration';
4
+ import IAttr from '../attr/IAttr';
5
5
  import FocusEvent from '../../event/events/FocusEvent';
6
6
  import PointerEvent from '../../event/events/PointerEvent';
7
- import Node from '../node/Node';
8
7
  import DatasetUtility from './DatasetUtility';
8
+ import NodeTypeEnum from '../node/NodeTypeEnum';
9
+ import DOMException from '../../exception/DOMException';
9
10
 
10
11
  /**
11
12
  * HTML Element.
@@ -54,32 +55,109 @@ export default class HTMLElement extends Element implements IHTMLElement {
54
55
  /**
55
56
  * Returns inner text, which is the rendered appearance of text.
56
57
  *
58
+ * @see https://html.spec.whatwg.org/multipage/dom.html#the-innertext-idl-attribute
57
59
  * @returns Inner text.
58
60
  */
59
61
  public get innerText(): string {
62
+ if (!this.isConnected) {
63
+ return this.textContent;
64
+ }
65
+
60
66
  let result = '';
67
+
61
68
  for (const childNode of this.childNodes) {
62
- if (childNode instanceof HTMLElement) {
63
- if (childNode.tagName !== 'SCRIPT' && childNode.tagName !== 'STYLE') {
64
- result += childNode.innerText;
69
+ if (childNode.nodeType === NodeTypeEnum.elementNode) {
70
+ const childElement = <IHTMLElement>childNode;
71
+ const computedStyle = this.ownerDocument.defaultView.getComputedStyle(childElement);
72
+
73
+ if (childElement.tagName !== 'SCRIPT' && childElement.tagName !== 'STYLE') {
74
+ const display = computedStyle.display;
75
+ if (display !== 'none') {
76
+ const textTransform = computedStyle.textTransform;
77
+
78
+ if ((display === 'block' || display === 'flex') && result) {
79
+ result += '\n';
80
+ }
81
+
82
+ let text = childElement.innerText;
83
+
84
+ switch (textTransform) {
85
+ case 'uppercase':
86
+ text = text.toUpperCase();
87
+ break;
88
+ case 'lowercase':
89
+ text = text.toLowerCase();
90
+ break;
91
+ case 'capitalize':
92
+ text = text.replace(/(^|\s)\S/g, (l) => l.toUpperCase());
93
+ break;
94
+ }
95
+
96
+ result += text;
97
+ }
65
98
  }
66
- } else if (
67
- childNode.nodeType === Node.ELEMENT_NODE ||
68
- childNode.nodeType === Node.TEXT_NODE
69
- ) {
70
- result += childNode.textContent;
99
+ } else if (childNode.nodeType === NodeTypeEnum.textNode) {
100
+ result += childNode.textContent.replace(/[\n\r]/, '');
71
101
  }
72
102
  }
103
+
73
104
  return result;
74
105
  }
75
106
 
76
107
  /**
77
108
  * Sets the inner text, which is the rendered appearance of text.
78
109
  *
110
+ * @see https://html.spec.whatwg.org/multipage/dom.html#the-innertext-idl-attribute
79
111
  * @param innerText Inner text.
80
112
  */
81
- public set innerText(innerText: string) {
82
- this.textContent = innerText;
113
+ public set innerText(text: string) {
114
+ for (const child of this.childNodes.slice()) {
115
+ this.removeChild(child);
116
+ }
117
+
118
+ const texts = text.split(/[\n\r]/);
119
+
120
+ for (let i = 0, max = texts.length; i < max; i++) {
121
+ if (i !== 0) {
122
+ this.appendChild(this.ownerDocument.createElement('br'));
123
+ }
124
+ this.appendChild(this.ownerDocument.createTextNode(texts[i]));
125
+ }
126
+ }
127
+
128
+ /**
129
+ * Returns outer text.
130
+ *
131
+ * @see https://html.spec.whatwg.org/multipage/dom.html#the-innertext-idl-attribute
132
+ * @returns HTML.
133
+ */
134
+ public get outerText(): string {
135
+ return this.innerText;
136
+ }
137
+
138
+ /**
139
+ * Sets outer text.
140
+ *
141
+ * @see https://html.spec.whatwg.org/multipage/dom.html#the-innertext-idl-attribute
142
+ * @param text Text.
143
+ */
144
+ public set outerText(text: string) {
145
+ if (!this.parentNode) {
146
+ throw new DOMException(
147
+ "Failed to set the 'outerHTML' property on 'Element': This element has no parent node."
148
+ );
149
+ }
150
+
151
+ const texts = text.split(/[\n\r]/);
152
+
153
+ for (let i = 0, max = texts.length; i < max; i++) {
154
+ if (i !== 0) {
155
+ this.parentNode.insertBefore(this.ownerDocument.createElement('br'), this);
156
+ }
157
+ this.parentNode.insertBefore(this.ownerDocument.createTextNode(texts[i]), this);
158
+ }
159
+
160
+ this.parentNode.removeChild(this);
83
161
  }
84
162
 
85
163
  /**
@@ -89,7 +167,7 @@ export default class HTMLElement extends Element implements IHTMLElement {
89
167
  */
90
168
  public get style(): CSSStyleDeclaration {
91
169
  if (!this._style) {
92
- this._style = new CSSStyleDeclaration(this._attributes);
170
+ this._style = new CSSStyleDeclaration(this);
93
171
  }
94
172
  return this._style;
95
173
  }
@@ -311,7 +389,7 @@ export default class HTMLElement extends Element implements IHTMLElement {
311
389
  * @param attribute Attribute.
312
390
  * @returns Replaced attribute.
313
391
  */
314
- public setAttributeNode(attribute: Attr): Attr {
392
+ public setAttributeNode(attribute: IAttr): IAttr {
315
393
  const replacedAttribute = super.setAttributeNode(attribute);
316
394
 
317
395
  if (attribute.name === 'style' && this._style) {
@@ -327,7 +405,7 @@ export default class HTMLElement extends Element implements IHTMLElement {
327
405
  * @override
328
406
  * @param attribute Attribute.
329
407
  */
330
- public removeAttributeNode(attribute: Attr): void {
408
+ public removeAttributeNode(attribute: IAttr): void {
331
409
  super.removeAttributeNode(attribute);
332
410
 
333
411
  if (attribute.name === 'style' && this._style) {
@@ -1,4 +1,4 @@
1
- import CSSStyleDeclaration from '../../css/CSSStyleDeclaration';
1
+ import CSSStyleDeclaration from '../../css/declaration/CSSStyleDeclaration';
2
2
  import IElement from '../element/IElement';
3
3
 
4
4
  /**
@@ -9,6 +9,7 @@ import IElement from '../element/IElement';
9
9
  */
10
10
  export default interface IHTMLElement extends IElement {
11
11
  style: CSSStyleDeclaration;
12
+ dataset: { [key: string]: string };
12
13
  tabIndex: number;
13
14
  offsetHeight: number;
14
15
  offsetWidth: number;
@@ -17,6 +18,7 @@ export default interface IHTMLElement extends IElement {
17
18
  clientHeight: number;
18
19
  clientWidth: number;
19
20
  innerText: string;
21
+ outerText: string;
20
22
 
21
23
  /**
22
24
  * Triggers a click event.
@@ -1,4 +1,4 @@
1
- import Attr from '../../attribute/Attr';
1
+ import IAttr from '../attr/IAttr';
2
2
  import CSSStyleSheet from '../../css/CSSStyleSheet';
3
3
  import ResourceFetchHandler from '../../fetch/ResourceFetchHandler';
4
4
  import HTMLElement from '../html-element/HTMLElement';
@@ -186,7 +186,7 @@ export default class HTMLLinkElement extends HTMLElement implements IHTMLLinkEle
186
186
  * @param attribute Attribute.
187
187
  * @returns Replaced attribute.
188
188
  */
189
- public setAttributeNode(attribute: Attr): Attr {
189
+ public setAttributeNode(attribute: IAttr): IAttr {
190
190
  const replacedAttribute = super.setAttributeNode(attribute);
191
191
  const rel = this.getAttributeNS(null, 'rel');
192
192
  const href = this.getAttributeNS(null, 'href');
@@ -1,4 +1,4 @@
1
- import Attr from '../../attribute/Attr';
1
+ import IAttr from '../attr/IAttr';
2
2
  import HTMLElement from '../html-element/HTMLElement';
3
3
  import IHTMLScriptElement from './IHTMLScriptElement';
4
4
  import ScriptUtility from './ScriptUtility';
@@ -158,7 +158,7 @@ export default class HTMLScriptElement extends HTMLElement implements IHTMLScrip
158
158
  * @param attribute Attribute.
159
159
  * @returns Replaced attribute.
160
160
  */
161
- public setAttributeNode(attribute: Attr): Attr {
161
+ public setAttributeNode(attribute: IAttr): IAttr {
162
162
  const replacedAttribute = super.setAttributeNode(attribute);
163
163
 
164
164
  if (attribute.name === 'src' && attribute.value !== null && this.isConnected) {