happy-dom 5.4.0 → 6.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 (135) hide show
  1. package/.eslintrc.js +2 -2
  2. package/lib/base64/Base64.d.ts +23 -0
  3. package/lib/base64/Base64.js +89 -0
  4. package/lib/base64/Base64.js.map +1 -0
  5. package/lib/config/NonImplemenetedElementClasses.js +0 -1
  6. package/lib/config/NonImplemenetedElementClasses.js.map +1 -1
  7. package/lib/dom-implementation/DOMImplementation.d.ts +7 -1
  8. package/lib/dom-implementation/DOMImplementation.js +10 -2
  9. package/lib/dom-implementation/DOMImplementation.js.map +1 -1
  10. package/lib/dom-parser/DOMParser.d.ts +9 -4
  11. package/lib/dom-parser/DOMParser.js +13 -2
  12. package/lib/dom-parser/DOMParser.js.map +1 -1
  13. package/lib/exception/DOMExceptionNameEnum.d.ts +5 -1
  14. package/lib/exception/DOMExceptionNameEnum.js +4 -0
  15. package/lib/exception/DOMExceptionNameEnum.js.map +1 -1
  16. package/lib/fetch/Request.d.ts +8 -0
  17. package/lib/fetch/Request.js +15 -6
  18. package/lib/fetch/Request.js.map +1 -1
  19. package/lib/fetch/Response.d.ts +5 -0
  20. package/lib/fetch/Response.js +12 -6
  21. package/lib/fetch/Response.js.map +1 -1
  22. package/lib/file/FileReader.d.ts +7 -2
  23. package/lib/file/FileReader.js +9 -3
  24. package/lib/file/FileReader.js.map +1 -1
  25. package/lib/index.d.ts +2 -1
  26. package/lib/index.js +3 -1
  27. package/lib/index.js.map +1 -1
  28. package/lib/nodes/comment/Comment.d.ts +1 -1
  29. package/lib/nodes/document/Document.d.ts +18 -15
  30. package/lib/nodes/document/Document.js +36 -33
  31. package/lib/nodes/document/Document.js.map +1 -1
  32. package/lib/nodes/document/IDocument.d.ts +7 -0
  33. package/lib/nodes/document-fragment/DocumentFragment.d.ts +1 -1
  34. package/lib/nodes/document-type/DocumentType.d.ts +1 -1
  35. package/lib/nodes/element/DOMRectListFactory.d.ts +23 -0
  36. package/lib/nodes/element/DOMRectListFactory.js +33 -0
  37. package/lib/nodes/element/DOMRectListFactory.js.map +1 -0
  38. package/lib/nodes/element/Element.d.ts +6 -5
  39. package/lib/nodes/element/Element.js +9 -11
  40. package/lib/nodes/element/Element.js.map +1 -1
  41. package/lib/nodes/element/IDOMRectList.d.ts +11 -0
  42. package/lib/nodes/element/IDOMRectList.js +3 -0
  43. package/lib/nodes/element/IDOMRectList.js.map +1 -0
  44. package/lib/nodes/element/IElement.d.ts +5 -4
  45. package/lib/nodes/html-dialog-element/HTMLDialogElement.d.ts +1 -6
  46. package/lib/nodes/html-dialog-element/HTMLDialogElement.js +7 -3
  47. package/lib/nodes/html-dialog-element/HTMLDialogElement.js.map +1 -1
  48. package/lib/nodes/html-dialog-element/IHTMLDialogElement.d.ts +11 -0
  49. package/lib/nodes/html-template-element/HTMLTemplateElement.d.ts +1 -10
  50. package/lib/nodes/html-template-element/HTMLTemplateElement.js +2 -15
  51. package/lib/nodes/html-template-element/HTMLTemplateElement.js.map +1 -1
  52. package/lib/nodes/node/INode.d.ts +8 -6
  53. package/lib/nodes/node/Node.d.ts +20 -17
  54. package/lib/nodes/node/Node.js +19 -15
  55. package/lib/nodes/node/Node.js.map +1 -1
  56. package/lib/nodes/node/NodeTypeEnum.d.ts +10 -0
  57. package/lib/nodes/node/NodeTypeEnum.js +14 -0
  58. package/lib/nodes/node/NodeTypeEnum.js.map +1 -0
  59. package/lib/nodes/node/NodeUtility.d.ts +59 -0
  60. package/lib/nodes/node/NodeUtility.js +123 -0
  61. package/lib/nodes/node/NodeUtility.js.map +1 -0
  62. package/lib/nodes/text/IText.d.ts +9 -0
  63. package/lib/nodes/text/Text.d.ts +10 -1
  64. package/lib/nodes/text/Text.js +24 -0
  65. package/lib/nodes/text/Text.js.map +1 -1
  66. package/lib/range/IRangeBoundaryPoint.d.ts +8 -0
  67. package/lib/range/IRangeBoundaryPoint.js +3 -0
  68. package/lib/range/IRangeBoundaryPoint.js.map +1 -0
  69. package/lib/range/Range.d.ts +249 -0
  70. package/lib/range/Range.js +820 -0
  71. package/lib/range/Range.js.map +1 -0
  72. package/lib/range/RangeHowEnum.d.ts +7 -0
  73. package/lib/range/RangeHowEnum.js +11 -0
  74. package/lib/range/RangeHowEnum.js.map +1 -0
  75. package/lib/range/RangeUtility.d.ts +46 -0
  76. package/lib/range/RangeUtility.js +92 -0
  77. package/lib/range/RangeUtility.js.map +1 -0
  78. package/lib/selection/Selection.d.ts +167 -44
  79. package/lib/selection/Selection.js +369 -58
  80. package/lib/selection/Selection.js.map +1 -1
  81. package/lib/selection/SelectionDirectionEnum.d.ts +6 -0
  82. package/lib/selection/SelectionDirectionEnum.js +10 -0
  83. package/lib/selection/SelectionDirectionEnum.js.map +1 -0
  84. package/lib/window/IWindow.d.ts +20 -0
  85. package/lib/window/Window.d.ts +23 -9
  86. package/lib/window/Window.js +83 -35
  87. package/lib/window/Window.js.map +1 -1
  88. package/lib/xml-parser/XMLParser.d.ts +2 -2
  89. package/lib/xml-parser/XMLParser.js +5 -3
  90. package/lib/xml-parser/XMLParser.js.map +1 -1
  91. package/lib/xml-serializer/XMLSerializer.js +4 -1
  92. package/lib/xml-serializer/XMLSerializer.js.map +1 -1
  93. package/package.json +2 -2
  94. package/src/base64/Base64.ts +97 -0
  95. package/src/config/NonImplemenetedElementClasses.ts +0 -1
  96. package/src/dom-implementation/DOMImplementation.ts +13 -2
  97. package/src/dom-parser/DOMParser.ts +20 -7
  98. package/src/exception/DOMExceptionNameEnum.ts +5 -1
  99. package/src/fetch/Request.ts +16 -6
  100. package/src/fetch/Response.ts +13 -6
  101. package/src/file/FileReader.ts +14 -4
  102. package/src/index.ts +2 -0
  103. package/src/nodes/document/Document.ts +47 -39
  104. package/src/nodes/document/IDocument.ts +8 -0
  105. package/src/nodes/element/DOMRectListFactory.ts +33 -0
  106. package/src/nodes/element/Element.ts +10 -11
  107. package/src/nodes/element/IDOMRectList.ts +11 -0
  108. package/src/nodes/element/IElement.ts +5 -4
  109. package/src/nodes/html-dialog-element/HTMLDialogElement.ts +4 -9
  110. package/src/nodes/html-dialog-element/IHTMLDialogElement.ts +14 -0
  111. package/src/nodes/html-template-element/HTMLTemplateElement.ts +3 -21
  112. package/src/nodes/node/INode.ts +8 -6
  113. package/src/nodes/node/Node.ts +24 -19
  114. package/src/nodes/node/NodeTypeEnum.ts +11 -0
  115. package/src/nodes/node/NodeUtility.ts +139 -0
  116. package/src/nodes/text/IText.ts +10 -0
  117. package/src/nodes/text/Text.ts +33 -0
  118. package/src/range/IRangeBoundaryPoint.ts +9 -0
  119. package/src/range/Range.ts +1057 -0
  120. package/src/range/RangeHowEnum.ts +8 -0
  121. package/src/range/RangeUtility.ts +114 -0
  122. package/src/selection/Selection.ts +444 -60
  123. package/src/selection/SelectionDirectionEnum.ts +7 -0
  124. package/src/window/IWindow.ts +22 -0
  125. package/src/window/Window.ts +102 -32
  126. package/src/xml-parser/XMLParser.ts +15 -7
  127. package/src/xml-serializer/XMLSerializer.ts +6 -1
  128. package/lib/nodes/element/Range.d.ts +0 -167
  129. package/lib/nodes/element/Range.js +0 -215
  130. package/lib/nodes/element/Range.js.map +0 -1
  131. package/lib/window/WindowBase64.d.ts +0 -19
  132. package/lib/window/WindowBase64.js +0 -88
  133. package/lib/window/WindowBase64.js.map +0 -1
  134. package/src/nodes/element/Range.ts +0 -237
  135. package/src/window/WindowBase64.ts +0 -95
@@ -1,10 +1,11 @@
1
- import Document from '../nodes/document/Document';
1
+ import IDocument from '../nodes/document/IDocument';
2
2
  import XMLParser from '../xml-parser/XMLParser';
3
3
  import Node from '../nodes/node/Node';
4
4
  import DOMException from '../exception/DOMException';
5
5
  import HTMLDocument from '../nodes/html-document/HTMLDocument';
6
6
  import XMLDocument from '../nodes/xml-document/XMLDocument';
7
7
  import SVGDocument from '../nodes/svg-document/SVGDocument';
8
+ import IWindow from '../window/IWindow';
8
9
 
9
10
  /**
10
11
  * DOM parser.
@@ -13,7 +14,16 @@ import SVGDocument from '../nodes/svg-document/SVGDocument';
13
14
  * https://developer.mozilla.org/en-US/docs/Web/API/DOMParser.
14
15
  */
15
16
  export default class DOMParser {
16
- public static _ownerDocument: Document = null;
17
+ // Owner document is set by a sub-class in the Window constructor
18
+ public static _ownerDocument: IDocument = null;
19
+ public readonly _ownerDocument: IDocument = null;
20
+
21
+ /**
22
+ * Constructor.
23
+ */
24
+ constructor() {
25
+ this._ownerDocument = (<typeof DOMParser>this.constructor)._ownerDocument;
26
+ }
17
27
 
18
28
  /**
19
29
  * Parses HTML and returns a root element.
@@ -22,15 +32,15 @@ export default class DOMParser {
22
32
  * @param mimeType Mime type.
23
33
  * @returns Root element.
24
34
  */
25
- public parseFromString(string: string, mimeType: string): Document {
35
+ public parseFromString(string: string, mimeType: string): IDocument {
26
36
  if (!mimeType) {
27
37
  throw new DOMException('Second parameter "mimeType" is mandatory.');
28
38
  }
29
39
 
30
- const ownerDocument = (<typeof DOMParser>(<unknown>this.constructor))._ownerDocument;
40
+ const ownerDocument = this._ownerDocument;
31
41
  const newDocument = this._createDocument(mimeType);
32
42
 
33
- newDocument.defaultView = ownerDocument.defaultView;
43
+ (<IWindow>newDocument.defaultView) = ownerDocument.defaultView;
34
44
  newDocument.childNodes.length = 0;
35
45
  newDocument.children.length = 0;
36
46
 
@@ -81,17 +91,20 @@ export default class DOMParser {
81
91
  /**
82
92
  *
83
93
  * @param mimeType Mime type.
84
- * @returns Document.
94
+ * @returns IDocument.
85
95
  */
86
- private _createDocument(mimeType: string): Document {
96
+ private _createDocument(mimeType: string): IDocument {
87
97
  switch (mimeType) {
88
98
  case 'text/html':
99
+ HTMLDocument._defaultView = this._ownerDocument.defaultView;
89
100
  return new HTMLDocument();
90
101
  case 'image/svg+xml':
102
+ SVGDocument._defaultView = this._ownerDocument.defaultView;
91
103
  return new SVGDocument();
92
104
  case 'text/xml':
93
105
  case 'application/xml':
94
106
  case 'application/xhtml+xml':
107
+ XMLDocument._defaultView = this._ownerDocument.defaultView;
95
108
  return new XMLDocument();
96
109
  default:
97
110
  throw new DOMException(`Unknown mime type "${mimeType}".`);
@@ -3,6 +3,10 @@ enum DOMExceptionNameEnum {
3
3
  indexSizeError = 'IndexSizeError',
4
4
  syntaxError = 'SyntaxError',
5
5
  hierarchyRequestError = 'HierarchyRequestError',
6
- invalidCharacterError = 'InvalidCharacterError'
6
+ notSupportedError = 'NotSupportedError',
7
+ wrongDocumentError = 'WrongDocumentError',
8
+ invalidNodeTypeError = 'InvalidNodeTypeError',
9
+ invalidCharacterError = 'InvalidCharacterError',
10
+ notFoundError = 'NotFoundError'
7
11
  }
8
12
  export default DOMExceptionNameEnum;
@@ -7,7 +7,20 @@ import IDocument from '../nodes/document/IDocument';
7
7
  * Fetch request.
8
8
  */
9
9
  export default class Request extends NodeFetch.Request implements IRequest {
10
+ // Owner document is set by a sub-class in the Window constructor
10
11
  public static _ownerDocument: IDocument = null;
12
+ public readonly _ownerDocument: IDocument = null;
13
+
14
+ /**
15
+ * Constructor.
16
+ *
17
+ * @param input Input.
18
+ * @param [init] Init.
19
+ */
20
+ constructor(input: NodeFetch.RequestInfo, init?: NodeFetch.RequestInit) {
21
+ super(input, init);
22
+ this._ownerDocument = (<typeof Request>this.constructor)._ownerDocument;
23
+ }
11
24
 
12
25
  /**
13
26
  * Returns array buffer.
@@ -105,8 +118,7 @@ export default class Request extends NodeFetch.Request implements IRequest {
105
118
  * @returns Task ID.
106
119
  */
107
120
  private _handlePromiseStart(): number {
108
- const taskManager = (<typeof Request>this.constructor)._ownerDocument.defaultView.happyDOM
109
- .asyncTaskManager;
121
+ const taskManager = this._ownerDocument.defaultView.happyDOM.asyncTaskManager;
110
122
  return taskManager.startTask();
111
123
  }
112
124
 
@@ -124,8 +136,7 @@ export default class Request extends NodeFetch.Request implements IRequest {
124
136
  taskID: number,
125
137
  response: unknown
126
138
  ): void {
127
- const taskManager = (<typeof Request>this.constructor)._ownerDocument.defaultView.happyDOM
128
- .asyncTaskManager;
139
+ const taskManager = this._ownerDocument.defaultView.happyDOM.asyncTaskManager;
129
140
  if (taskManager.getTaskCount() === 0) {
130
141
  reject(new Error('Failed to complete fetch request. Task was canceled.'));
131
142
  } else {
@@ -141,8 +152,7 @@ export default class Request extends NodeFetch.Request implements IRequest {
141
152
  * @param reject
142
153
  */
143
154
  private _handlePromiseError(reject: (error: Error) => void, error: Error): void {
144
- const taskManager = (<typeof Request>this.constructor)._ownerDocument.defaultView.happyDOM
145
- .asyncTaskManager;
155
+ const taskManager = this._ownerDocument.defaultView.happyDOM.asyncTaskManager;
146
156
  reject(error);
147
157
  taskManager.cancelAll(error);
148
158
  }
@@ -7,7 +7,17 @@ import * as NodeFetch from 'node-fetch';
7
7
  * Fetch response.
8
8
  */
9
9
  export default class Response extends NodeFetch.Response implements IResponse {
10
+ // Owner document is set by a sub-class in the Window constructor
10
11
  public static _ownerDocument: IDocument = null;
12
+ public readonly _ownerDocument: IDocument = null;
13
+
14
+ /**
15
+ * Constructor.
16
+ */
17
+ constructor() {
18
+ super();
19
+ this._ownerDocument = (<typeof Response>this.constructor)._ownerDocument;
20
+ }
11
21
 
12
22
  /**
13
23
  * Returns array buffer.
@@ -105,8 +115,7 @@ export default class Response extends NodeFetch.Response implements IResponse {
105
115
  * @returns Task ID.
106
116
  */
107
117
  private _handlePromiseStart(): number {
108
- const taskManager = (<typeof Response>this.constructor)._ownerDocument.defaultView.happyDOM
109
- .asyncTaskManager;
118
+ const taskManager = this._ownerDocument.defaultView.happyDOM.asyncTaskManager;
110
119
  return taskManager.startTask();
111
120
  }
112
121
 
@@ -124,8 +133,7 @@ export default class Response extends NodeFetch.Response implements IResponse {
124
133
  taskID: number,
125
134
  response: unknown
126
135
  ): void {
127
- const taskManager = (<typeof Response>this.constructor)._ownerDocument.defaultView.happyDOM
128
- .asyncTaskManager;
136
+ const taskManager = this._ownerDocument.defaultView.happyDOM.asyncTaskManager;
129
137
  if (taskManager.getTaskCount() === 0) {
130
138
  reject(new Error('Failed to complete fetch request. Task was canceled.'));
131
139
  } else {
@@ -141,8 +149,7 @@ export default class Response extends NodeFetch.Response implements IResponse {
141
149
  * @param reject
142
150
  */
143
151
  private _handlePromiseError(reject: (error: Error) => void, error: Error): void {
144
- const taskManager = (<typeof Response>this.constructor)._ownerDocument.defaultView.happyDOM
145
- .asyncTaskManager;
152
+ const taskManager = this._ownerDocument.defaultView.happyDOM.asyncTaskManager;
146
153
  reject(error);
147
154
  taskManager.cancelAll(error);
148
155
  }
@@ -1,6 +1,6 @@
1
1
  import WhatwgMIMEType from 'whatwg-mimetype';
2
2
  import WhatwgEncoding from 'whatwg-encoding';
3
- import Document from '../nodes/document/Document';
3
+ import IDocument from '../nodes/document/IDocument';
4
4
  import ProgressEvent from '../event/events/ProgressEvent';
5
5
  import DOMException from '../exception/DOMException';
6
6
  import DOMExceptionNameEnum from '../exception/DOMExceptionNameEnum';
@@ -18,7 +18,8 @@ import FileReaderEventTypeEnum from './FileReaderEventTypeEnum';
18
18
  * https://github.com/jsdom/jsdom/blob/master/lib/jsdom/living/file-api/FileReader-impl.js (MIT licensed).
19
19
  */
20
20
  export default class FileReader extends EventTarget {
21
- public static _ownerDocument: Document = null;
21
+ // Owner document is set by a sub-class in the Window constructor
22
+ public static _ownerDocument: IDocument = null;
22
23
  public readonly error: Error = null;
23
24
  public readonly result: Buffer | ArrayBuffer | string = null;
24
25
  public readonly readyState: number = FileReaderReadyStateEnum.empty;
@@ -28,10 +29,19 @@ export default class FileReader extends EventTarget {
28
29
  public readonly onloadstart: (event: ProgressEvent) => void = null;
29
30
  public readonly onloadend: (event: ProgressEvent) => void = null;
30
31
  public readonly onprogress: (event: ProgressEvent) => void = null;
32
+ public readonly _ownerDocument: IDocument = null;
31
33
  private _isTerminated = false;
32
34
  private _loadTimeout: NodeJS.Timeout = null;
33
35
  private _parseTimeout: NodeJS.Timeout = null;
34
36
 
37
+ /**
38
+ * Constructor.
39
+ */
40
+ constructor() {
41
+ super();
42
+ this._ownerDocument = (<typeof FileReader>this.constructor)._ownerDocument;
43
+ }
44
+
35
45
  /**
36
46
  * Reads as ArrayBuffer.
37
47
  *
@@ -77,7 +87,7 @@ export default class FileReader extends EventTarget {
77
87
  * Aborts the file reader.
78
88
  */
79
89
  public abort(): void {
80
- const window = (<typeof FileReader>this.constructor)._ownerDocument.defaultView;
90
+ const window = this._ownerDocument.defaultView;
81
91
 
82
92
  window.clearTimeout(this._loadTimeout);
83
93
  window.clearTimeout(this._parseTimeout);
@@ -108,7 +118,7 @@ export default class FileReader extends EventTarget {
108
118
  * @param [encoding] Encoding.
109
119
  */
110
120
  private _readFile(blob: Blob, format: FileReaderFormatEnum, encoding: string = null): void {
111
- const window = (<typeof FileReader>this.constructor)._ownerDocument.defaultView;
121
+ const window = this._ownerDocument.defaultView;
112
122
 
113
123
  if (this.readyState === FileReaderReadyStateEnum.loading) {
114
124
  throw new DOMException(
package/src/index.ts CHANGED
@@ -104,6 +104,7 @@ import Storage from './storage/Storage';
104
104
  import DOMRect from './nodes/element/DOMRect';
105
105
  import { URLSearchParams } from 'url';
106
106
  import Selection from './selection/Selection';
107
+ import Range from './range/Range';
107
108
  import HTMLDialogElement from './nodes/html-dialog-element/HTMLDialogElement';
108
109
  import IHTMLDialogElement from './nodes/html-dialog-element/IHTMLDialogElement';
109
110
 
@@ -214,6 +215,7 @@ export {
214
215
  DOMRect,
215
216
  URLSearchParams,
216
217
  Selection,
218
+ Range,
217
219
  HTMLDialogElement,
218
220
  IHTMLDialogElement
219
221
  };
@@ -38,12 +38,14 @@ import DocumentReadyStateManager from './DocumentReadyStateManager';
38
38
  import Location from '../../location/Location';
39
39
  import Selection from '../../selection/Selection';
40
40
  import IShadowRoot from '../shadow-root/IShadowRoot';
41
+ import Range from '../../range/Range';
41
42
  import IHTMLBaseElement from '../html-base-element/IHTMLBaseElement';
42
43
 
43
44
  /**
44
45
  * Document.
45
46
  */
46
47
  export default class Document extends Node implements IDocument {
48
+ public static _defaultView: IWindow = null;
47
49
  public onreadystatechange: (event: Event) => void = null;
48
50
  public nodeType = Node.DOCUMENT_NODE;
49
51
  public adoptedStyleSheets: CSSStyleSheet[] = [];
@@ -51,21 +53,26 @@ export default class Document extends Node implements IDocument {
51
53
  public readonly children: IHTMLCollection<IElement> = HTMLCollectionFactory.create();
52
54
  public readonly readyState = DocumentReadyStateEnum.interactive;
53
55
  public readonly isConnected: boolean = true;
54
- public _readyStateManager: DocumentReadyStateManager = null;
56
+ public readonly defaultView: IWindow;
57
+ public readonly _readyStateManager: DocumentReadyStateManager;
55
58
  public _activeElement: IHTMLElement = null;
56
59
  protected _isFirstWrite = true;
57
60
  protected _isFirstWriteAfterOpen = false;
58
- private _defaultView: IWindow = null;
59
61
  private _cookie = '';
62
+ private _selection: Selection = null;
60
63
 
61
64
  /**
62
65
  * Creates an instance of Document.
66
+ *
67
+ * @param defaultView Default view.
63
68
  */
64
69
  constructor() {
65
70
  super();
66
71
 
67
- this.implementation = new DOMImplementation();
68
- this.implementation._ownerDocument = this;
72
+ this.defaultView = (<typeof Document>this.constructor)._defaultView;
73
+ this.implementation = new DOMImplementation(this);
74
+
75
+ this._readyStateManager = new DocumentReadyStateManager(this.defaultView);
69
76
 
70
77
  const doctype = this.implementation.createDocumentType('html', '', '');
71
78
  const documentElement = this.createElement('html');
@@ -99,29 +106,6 @@ export default class Document extends Node implements IDocument {
99
106
  return charset ? charset : 'UTF-8';
100
107
  }
101
108
 
102
- /**
103
- * Returns default view.
104
- *
105
- * @returns Default view.
106
- */
107
- public get defaultView(): IWindow {
108
- return this._defaultView;
109
- }
110
-
111
- /**
112
- * Sets a default view.
113
- *
114
- * @param defaultView Default view.
115
- */
116
- public set defaultView(defaultView: IWindow) {
117
- this._defaultView = defaultView;
118
- this._readyStateManager = new DocumentReadyStateManager(defaultView);
119
- this._readyStateManager.whenComplete().then(() => {
120
- (<DocumentReadyStateEnum>this.readyState) = DocumentReadyStateEnum.complete;
121
- this.dispatchEvent(new Event('readystatechange'));
122
- });
123
- }
124
-
125
109
  /**
126
110
  * Last element child.
127
111
  *
@@ -271,7 +255,7 @@ export default class Document extends Node implements IDocument {
271
255
  * @returns Location.
272
256
  */
273
257
  public get location(): Location {
274
- return this._defaultView.location;
258
+ return this.defaultView.location;
275
259
  }
276
260
 
277
261
  /**
@@ -418,6 +402,8 @@ export default class Document extends Node implements IDocument {
418
402
  * @returns Cloned node.
419
403
  */
420
404
  public cloneNode(deep = false): IDocument {
405
+ (<typeof Document>this.constructor)._defaultView = this.defaultView;
406
+
421
407
  const clone = <Document>super.cloneNode(deep);
422
408
 
423
409
  if (deep) {
@@ -428,8 +414,6 @@ export default class Document extends Node implements IDocument {
428
414
  }
429
415
  }
430
416
 
431
- clone.defaultView = this.defaultView;
432
-
433
417
  return clone;
434
418
  }
435
419
 
@@ -654,14 +638,15 @@ export default class Document extends Node implements IDocument {
654
638
  customElementClass = this.defaultView.customElements.get(tagName);
655
639
  }
656
640
 
657
- const elementClass = customElementClass || ElementTag[tagName] || HTMLUnknownElement;
641
+ const elementClass: typeof Element =
642
+ customElementClass || ElementTag[tagName] || HTMLUnknownElement;
658
643
 
659
- elementClass.ownerDocument = this;
644
+ elementClass._ownerDocument = this;
660
645
 
661
646
  const element = new elementClass();
662
647
  element.tagName = tagName;
663
- element.ownerDocument = this;
664
- element.namespaceURI = namespaceURI;
648
+ (<IDocument>element.ownerDocument) = this;
649
+ (<string>element.namespaceURI) = namespaceURI;
665
650
  if (element instanceof Element && options && options.is) {
666
651
  element._isValue = String(options.is);
667
652
  }
@@ -678,7 +663,7 @@ export default class Document extends Node implements IDocument {
678
663
  * @returns Text node.
679
664
  */
680
665
  public createTextNode(data?: string): IText {
681
- Text.ownerDocument = this;
666
+ Text._ownerDocument = this;
682
667
  return new Text(data);
683
668
  }
684
669
 
@@ -689,7 +674,7 @@ export default class Document extends Node implements IDocument {
689
674
  * @returns Text node.
690
675
  */
691
676
  public createComment(data?: string): IComment {
692
- Comment.ownerDocument = this;
677
+ Comment._ownerDocument = this;
693
678
  return new Comment(data);
694
679
  }
695
680
 
@@ -699,7 +684,7 @@ export default class Document extends Node implements IDocument {
699
684
  * @returns Document fragment.
700
685
  */
701
686
  public createDocumentFragment(): IDocumentFragment {
702
- DocumentFragment.ownerDocument = this;
687
+ DocumentFragment._ownerDocument = this;
703
688
  return new DocumentFragment();
704
689
  }
705
690
 
@@ -722,7 +707,7 @@ export default class Document extends Node implements IDocument {
722
707
  * @returns Event.
723
708
  */
724
709
  public createEvent(type: string): Event {
725
- if (this.defaultView[type]) {
710
+ if (typeof this.defaultView[type] === 'function') {
726
711
  return new this.defaultView[type]('init');
727
712
  }
728
713
  return new Event('init');
@@ -772,6 +757,15 @@ export default class Document extends Node implements IDocument {
772
757
  return clone;
773
758
  }
774
759
 
760
+ /**
761
+ * Creates a range.
762
+ *
763
+ * @returns Range.
764
+ */
765
+ public createRange(): Range {
766
+ return new this.defaultView.Range();
767
+ }
768
+
775
769
  /**
776
770
  * Adopts a node.
777
771
  *
@@ -794,7 +788,10 @@ export default class Document extends Node implements IDocument {
794
788
  * @returns Selection.
795
789
  */
796
790
  public getSelection(): Selection {
797
- return new Selection();
791
+ if (!this._selection) {
792
+ this._selection = new Selection(this);
793
+ }
794
+ return this._selection;
798
795
  }
799
796
 
800
797
  /**
@@ -818,4 +815,15 @@ export default class Document extends Node implements IDocument {
818
815
 
819
816
  return returnValue;
820
817
  }
818
+
819
+ /**
820
+ * Triggered by window when it is ready.
821
+ */
822
+ public _onWindowReady(): void {
823
+ this._readyStateManager.whenComplete().then(() => {
824
+ (<DocumentReadyStateEnum>this.readyState) = DocumentReadyStateEnum.complete;
825
+ this.dispatchEvent(new Event('readystatechange'));
826
+ this.dispatchEvent(new Event('load', { bubbles: true }));
827
+ });
828
+ }
821
829
  }
@@ -18,6 +18,7 @@ import CSSStyleSheet from '../../css/CSSStyleSheet';
18
18
  import Location from '../../location/Location';
19
19
  import DocumentReadyStateEnum from './DocumentReadyStateEnum';
20
20
  import INodeList from '../node/INodeList';
21
+ import Range from '../../range/Range';
21
22
 
22
23
  /**
23
24
  * Document.
@@ -143,6 +144,13 @@ export default interface IDocument extends IParentNode {
143
144
  */
144
145
  importNode(node: INode): INode;
145
146
 
147
+ /**
148
+ * Creates a range.
149
+ *
150
+ * @returns Range.
151
+ */
152
+ createRange(): Range;
153
+
146
154
  /**
147
155
  * Returns an element by ID.
148
156
  *
@@ -0,0 +1,33 @@
1
+ import DOMRect from './DOMRect';
2
+ import IDOMRectList from './IDOMRectList';
3
+
4
+ /**
5
+ * DOM rect list factory.
6
+ *
7
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/getClientRects
8
+ */
9
+ export default class DOMRectListFactory {
10
+ /**
11
+ * Creates an HTMLCollection.
12
+ *
13
+ * @param list Nodes.
14
+ * @returns HTMLCollection.
15
+ */
16
+ public static create(list?: DOMRect[]): IDOMRectList<DOMRect> {
17
+ list = list ? list.slice() : [];
18
+ Object.defineProperty(list, 'item', {
19
+ value: this.getItem.bind(null, list)
20
+ });
21
+ return <IDOMRectList<DOMRect>>list;
22
+ }
23
+
24
+ /**
25
+ * Returns node by index.
26
+ *
27
+ * @param list
28
+ * @param index Index.
29
+ */
30
+ private static getItem(list: DOMRect[], index: number): DOMRect {
31
+ return list[index] || null;
32
+ }
33
+ }
@@ -2,7 +2,6 @@ import Node from '../node/Node';
2
2
  import ShadowRoot from '../shadow-root/ShadowRoot';
3
3
  import Attr from '../../attribute/Attr';
4
4
  import DOMRect from './DOMRect';
5
- import Range from './Range';
6
5
  import DOMTokenList from '../../dom-token-list/DOMTokenList';
7
6
  import IDOMTokenList from '../../dom-token-list/IDOMTokenList';
8
7
  import QuerySelector from '../../query-selector/QuerySelector';
@@ -25,6 +24,8 @@ import INodeList from '../node/INodeList';
25
24
  import HTMLCollectionFactory from './HTMLCollectionFactory';
26
25
  import { TInsertAdjacentPositions } from './IElement';
27
26
  import IText from '../text/IText';
27
+ import IDOMRectList from './IDOMRectList';
28
+ import DOMRectListFactory from './DOMRectListFactory';
28
29
 
29
30
  /**
30
31
  * Element.
@@ -169,12 +170,7 @@ export default class Element extends Node implements IElement {
169
170
  * @returns HTML.
170
171
  */
171
172
  public get innerHTML(): string {
172
- const xmlSerializer = new XMLSerializer();
173
- let xml = '';
174
- for (const node of this.childNodes) {
175
- xml += xmlSerializer.serializeToString(node);
176
- }
177
- return xml;
173
+ return this.getInnerHTML();
178
174
  }
179
175
 
180
176
  /**
@@ -685,16 +681,19 @@ export default class Element extends Node implements IElement {
685
681
  * @returns DOM rect.
686
682
  */
687
683
  public getBoundingClientRect(): DOMRect {
684
+ // TODO: Not full implementation
688
685
  return new DOMRect();
689
686
  }
690
687
 
691
688
  /**
692
- * Returns a range.
689
+ * Returns a collection of DOMRect objects that indicate the bounding rectangles for each CSS border box in a client.
693
690
  *
694
- * @returns Range.
691
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/getClientRects
692
+ * @returns DOM rect list.
695
693
  */
696
- public createTextRange(): Range {
697
- return new Range();
694
+ public getClientRects(): IDOMRectList<DOMRect> {
695
+ // TODO: Not full implementation
696
+ return DOMRectListFactory.create([this.getBoundingClientRect()]);
698
697
  }
699
698
 
700
699
  /**
@@ -0,0 +1,11 @@
1
+ /**
2
+ * HTMLCollection.
3
+ */
4
+ export default interface IDOMRectList<T> extends Array<T> {
5
+ /**
6
+ * Returns item by index.
7
+ *
8
+ * @param index Index.
9
+ */
10
+ item(index: number): T;
11
+ }
@@ -1,12 +1,12 @@
1
1
  import IShadowRoot from '../shadow-root/IShadowRoot';
2
2
  import Attr from '../../attribute/Attr';
3
3
  import DOMRect from './DOMRect';
4
- import Range from './Range';
5
4
  import IDOMTokenList from '../../dom-token-list/IDOMTokenList';
6
5
  import INode from './../node/INode';
7
6
  import IChildNode from '../child-node/IChildNode';
8
7
  import IParentNode from '../parent-node/IParentNode';
9
8
  import INonDocumentTypeChildNode from '../child-node/INonDocumentTypeChildNode';
9
+ import IDOMRectList from './IDOMRectList';
10
10
 
11
11
  export type TInsertAdjacentPositions = 'beforebegin' | 'afterbegin' | 'beforeend' | 'afterend';
12
12
 
@@ -161,11 +161,12 @@ export default interface IElement extends IChildNode, INonDocumentTypeChildNode,
161
161
  getBoundingClientRect(): DOMRect;
162
162
 
163
163
  /**
164
- * Returns a range.
164
+ * Returns a collection of DOMRect objects that indicate the bounding rectangles for each CSS border box in a client.
165
165
  *
166
- * @returns Range.
166
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/getClientRects
167
+ * @returns DOM rect list.
167
168
  */
168
- createTextRange(): Range;
169
+ getClientRects(): IDOMRectList<DOMRect>;
169
170
 
170
171
  /**
171
172
  * The matches() method checks to see if the Element would be selected by the provided selectorString.
@@ -9,12 +9,7 @@ import IHTMLDialogElement from './IHTMLDialogElement';
9
9
  * https://developer.mozilla.org/en-US/docs/Web/API/HTMLDialogElement.
10
10
  */
11
11
  export default class HTMLDialogElement extends HTMLElement implements IHTMLDialogElement {
12
- /**
13
- * Returns returnValue.
14
- *
15
- * @returns ReturnValue.
16
- */
17
- public returnValue: string;
12
+ public returnValue = '';
18
13
 
19
14
  /**
20
15
  * Returns open.
@@ -28,12 +23,12 @@ export default class HTMLDialogElement extends HTMLElement implements IHTMLDialo
28
23
  /**
29
24
  * Closes the dialog.
30
25
  *
31
- * @param returnValue ReturnValue.
26
+ * @param [returnValue] ReturnValue.
32
27
  */
33
- public close(returnValue?: string): void {
28
+ public close(returnValue = ''): void {
34
29
  this.removeAttributeNS(null, 'open');
35
30
  this.returnValue = returnValue;
36
- this.dispatchEvent(new Event('close', { bubbles: false, cancelable: false }));
31
+ this.dispatchEvent(new Event('close'));
37
32
  }
38
33
 
39
34
  /**
@@ -9,7 +9,21 @@ import IHTMLElement from '../html-element/IHTMLElement';
9
9
  export default interface IHTMLDialogElement extends IHTMLElement {
10
10
  open: boolean;
11
11
  returnValue: string;
12
+
13
+ /**
14
+ * Closes the dialog.
15
+ *
16
+ * @param [returnValue] ReturnValue.
17
+ */
12
18
  close(returnValue?: string): void;
19
+
20
+ /**
21
+ * Shows the modal.
22
+ */
13
23
  showModal(): void;
24
+
25
+ /**
26
+ * Shows the dialog.
27
+ */
14
28
  show(): void;
15
29
  }