happy-dom 5.3.4 → 6.0.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.

Files changed (144) 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/ElementTag.d.ts +2 -1
  6. package/lib/config/ElementTag.js +2 -1
  7. package/lib/config/ElementTag.js.map +1 -1
  8. package/lib/config/NonImplemenetedElementClasses.js +0 -1
  9. package/lib/config/NonImplemenetedElementClasses.js.map +1 -1
  10. package/lib/dom-implementation/DOMImplementation.d.ts +7 -1
  11. package/lib/dom-implementation/DOMImplementation.js +10 -2
  12. package/lib/dom-implementation/DOMImplementation.js.map +1 -1
  13. package/lib/dom-parser/DOMParser.d.ts +9 -4
  14. package/lib/dom-parser/DOMParser.js +13 -2
  15. package/lib/dom-parser/DOMParser.js.map +1 -1
  16. package/lib/exception/DOMExceptionNameEnum.d.ts +5 -1
  17. package/lib/exception/DOMExceptionNameEnum.js +4 -0
  18. package/lib/exception/DOMExceptionNameEnum.js.map +1 -1
  19. package/lib/fetch/Request.d.ts +8 -0
  20. package/lib/fetch/Request.js +15 -6
  21. package/lib/fetch/Request.js.map +1 -1
  22. package/lib/fetch/Response.d.ts +5 -0
  23. package/lib/fetch/Response.js +12 -6
  24. package/lib/fetch/Response.js.map +1 -1
  25. package/lib/file/FileReader.d.ts +7 -2
  26. package/lib/file/FileReader.js +9 -3
  27. package/lib/file/FileReader.js.map +1 -1
  28. package/lib/index.d.ts +4 -1
  29. package/lib/index.js +5 -1
  30. package/lib/index.js.map +1 -1
  31. package/lib/nodes/comment/Comment.d.ts +1 -1
  32. package/lib/nodes/document/Document.d.ts +18 -15
  33. package/lib/nodes/document/Document.js +36 -33
  34. package/lib/nodes/document/Document.js.map +1 -1
  35. package/lib/nodes/document/IDocument.d.ts +7 -0
  36. package/lib/nodes/document-fragment/DocumentFragment.d.ts +1 -1
  37. package/lib/nodes/document-type/DocumentType.d.ts +1 -1
  38. package/lib/nodes/element/DOMRectListFactory.d.ts +23 -0
  39. package/lib/nodes/element/DOMRectListFactory.js +33 -0
  40. package/lib/nodes/element/DOMRectListFactory.js.map +1 -0
  41. package/lib/nodes/element/Element.d.ts +6 -5
  42. package/lib/nodes/element/Element.js +9 -11
  43. package/lib/nodes/element/Element.js.map +1 -1
  44. package/lib/nodes/element/IDOMRectList.d.ts +11 -0
  45. package/lib/nodes/element/IDOMRectList.js +3 -0
  46. package/lib/nodes/element/IDOMRectList.js.map +1 -0
  47. package/lib/nodes/element/IElement.d.ts +5 -4
  48. package/lib/nodes/html-dialog-element/HTMLDialogElement.d.ts +31 -0
  49. package/lib/nodes/html-dialog-element/HTMLDialogElement.js +51 -0
  50. package/lib/nodes/html-dialog-element/HTMLDialogElement.js.map +1 -0
  51. package/lib/nodes/html-dialog-element/IHTMLDialogElement.d.ts +25 -0
  52. package/lib/nodes/html-dialog-element/IHTMLDialogElement.js +3 -0
  53. package/lib/nodes/html-dialog-element/IHTMLDialogElement.js.map +1 -0
  54. package/lib/nodes/html-element/DatasetUtility.js +3 -1
  55. package/lib/nodes/html-element/DatasetUtility.js.map +1 -1
  56. package/lib/nodes/html-template-element/HTMLTemplateElement.d.ts +1 -10
  57. package/lib/nodes/html-template-element/HTMLTemplateElement.js +2 -15
  58. package/lib/nodes/html-template-element/HTMLTemplateElement.js.map +1 -1
  59. package/lib/nodes/node/INode.d.ts +8 -6
  60. package/lib/nodes/node/Node.d.ts +20 -17
  61. package/lib/nodes/node/Node.js +19 -15
  62. package/lib/nodes/node/Node.js.map +1 -1
  63. package/lib/nodes/node/NodeTypeEnum.d.ts +10 -0
  64. package/lib/nodes/node/NodeTypeEnum.js +14 -0
  65. package/lib/nodes/node/NodeTypeEnum.js.map +1 -0
  66. package/lib/nodes/node/NodeUtility.d.ts +59 -0
  67. package/lib/nodes/node/NodeUtility.js +123 -0
  68. package/lib/nodes/node/NodeUtility.js.map +1 -0
  69. package/lib/nodes/text/IText.d.ts +9 -0
  70. package/lib/nodes/text/Text.d.ts +10 -1
  71. package/lib/nodes/text/Text.js +24 -0
  72. package/lib/nodes/text/Text.js.map +1 -1
  73. package/lib/range/IRangeBoundaryPoint.d.ts +8 -0
  74. package/lib/range/IRangeBoundaryPoint.js +3 -0
  75. package/lib/range/IRangeBoundaryPoint.js.map +1 -0
  76. package/lib/range/Range.d.ts +249 -0
  77. package/lib/range/Range.js +820 -0
  78. package/lib/range/Range.js.map +1 -0
  79. package/lib/range/RangeHowEnum.d.ts +7 -0
  80. package/lib/range/RangeHowEnum.js +11 -0
  81. package/lib/range/RangeHowEnum.js.map +1 -0
  82. package/lib/range/RangeUtility.d.ts +46 -0
  83. package/lib/range/RangeUtility.js +92 -0
  84. package/lib/range/RangeUtility.js.map +1 -0
  85. package/lib/selection/Selection.d.ts +167 -44
  86. package/lib/selection/Selection.js +369 -58
  87. package/lib/selection/Selection.js.map +1 -1
  88. package/lib/selection/SelectionDirectionEnum.d.ts +6 -0
  89. package/lib/selection/SelectionDirectionEnum.js +10 -0
  90. package/lib/selection/SelectionDirectionEnum.js.map +1 -0
  91. package/lib/window/IWindow.d.ts +22 -0
  92. package/lib/window/Window.d.ts +25 -9
  93. package/lib/window/Window.js +85 -35
  94. package/lib/window/Window.js.map +1 -1
  95. package/lib/xml-parser/XMLParser.d.ts +2 -2
  96. package/lib/xml-parser/XMLParser.js +5 -3
  97. package/lib/xml-parser/XMLParser.js.map +1 -1
  98. package/lib/xml-serializer/XMLSerializer.js +4 -1
  99. package/lib/xml-serializer/XMLSerializer.js.map +1 -1
  100. package/package.json +2 -2
  101. package/src/base64/Base64.ts +97 -0
  102. package/src/config/ElementTag.ts +2 -1
  103. package/src/config/NonImplemenetedElementClasses.ts +0 -1
  104. package/src/dom-implementation/DOMImplementation.ts +13 -2
  105. package/src/dom-parser/DOMParser.ts +20 -7
  106. package/src/exception/DOMExceptionNameEnum.ts +5 -1
  107. package/src/fetch/Request.ts +16 -6
  108. package/src/fetch/Response.ts +13 -6
  109. package/src/file/FileReader.ts +14 -4
  110. package/src/index.ts +7 -1
  111. package/src/nodes/document/Document.ts +47 -39
  112. package/src/nodes/document/IDocument.ts +8 -0
  113. package/src/nodes/element/DOMRectListFactory.ts +33 -0
  114. package/src/nodes/element/Element.ts +10 -11
  115. package/src/nodes/element/IDOMRectList.ts +11 -0
  116. package/src/nodes/element/IElement.ts +5 -4
  117. package/src/nodes/html-dialog-element/HTMLDialogElement.ts +47 -0
  118. package/src/nodes/html-dialog-element/IHTMLDialogElement.ts +29 -0
  119. package/src/nodes/html-element/DatasetUtility.ts +3 -1
  120. package/src/nodes/html-template-element/HTMLTemplateElement.ts +3 -21
  121. package/src/nodes/node/INode.ts +8 -6
  122. package/src/nodes/node/Node.ts +24 -19
  123. package/src/nodes/node/NodeTypeEnum.ts +11 -0
  124. package/src/nodes/node/NodeUtility.ts +139 -0
  125. package/src/nodes/text/IText.ts +10 -0
  126. package/src/nodes/text/Text.ts +33 -0
  127. package/src/range/IRangeBoundaryPoint.ts +9 -0
  128. package/src/range/Range.ts +1057 -0
  129. package/src/range/RangeHowEnum.ts +8 -0
  130. package/src/range/RangeUtility.ts +114 -0
  131. package/src/selection/Selection.ts +444 -60
  132. package/src/selection/SelectionDirectionEnum.ts +7 -0
  133. package/src/window/IWindow.ts +24 -0
  134. package/src/window/Window.ts +104 -32
  135. package/src/xml-parser/XMLParser.ts +15 -7
  136. package/src/xml-serializer/XMLSerializer.ts +6 -1
  137. package/lib/nodes/element/Range.d.ts +0 -167
  138. package/lib/nodes/element/Range.js +0 -215
  139. package/lib/nodes/element/Range.js.map +0 -1
  140. package/lib/window/WindowBase64.d.ts +0 -19
  141. package/lib/window/WindowBase64.js +0 -88
  142. package/lib/window/WindowBase64.js.map +0 -1
  143. package/src/nodes/element/Range.ts +0 -237
  144. package/src/window/WindowBase64.ts +0 -95
@@ -0,0 +1,7 @@
1
+ enum SelectionDirectionEnum {
2
+ forwards = 1,
3
+ backwards = -1,
4
+ directionless = 0
5
+ }
6
+
7
+ export default SelectionDirectionEnum;
@@ -24,6 +24,7 @@ import HTMLBaseElement from '../nodes/html-base-element/HTMLBaseElement';
24
24
  import SVGSVGElement from '../nodes/svg-element/SVGSVGElement';
25
25
  import SVGElement from '../nodes/svg-element/SVGElement';
26
26
  import HTMLScriptElement from '../nodes/html-script-element/HTMLScriptElement';
27
+ import HTMLDialogElement from '../nodes/html-dialog-element/HTMLDialogElement';
27
28
  import HTMLImageElement from '../nodes/html-image-element/HTMLImageElement';
28
29
  import Image from '../nodes/html-image-element/Image';
29
30
  import DocumentFragment from '../nodes/document-fragment/DocumentFragment';
@@ -79,6 +80,7 @@ import IRequest from '../fetch/IRequest';
79
80
  import IHeaders from '../fetch/IHeaders';
80
81
  import IRequestInit from '../fetch/IRequestInit';
81
82
  import IResponse from '../fetch/IResponse';
83
+ import Range from '../range/Range';
82
84
  import MediaQueryList from '../match-media/MediaQueryList';
83
85
  import DOMRect from '../nodes/element/DOMRect';
84
86
  import Window from './Window';
@@ -112,6 +114,7 @@ export default interface IWindow extends IEventTarget, NodeJS.Global {
112
114
  readonly HTMLLabelElement: typeof HTMLLabelElement;
113
115
  readonly HTMLMetaElement: typeof HTMLMetaElement;
114
116
  readonly HTMLBaseElement: typeof HTMLBaseElement;
117
+ readonly HTMLDialogElement: typeof HTMLDialogElement;
115
118
  readonly SVGSVGElement: typeof SVGSVGElement;
116
119
  readonly SVGElement: typeof SVGElement;
117
120
  readonly Image: typeof Image;
@@ -174,6 +177,7 @@ export default interface IWindow extends IEventTarget, NodeJS.Global {
174
177
  readonly Headers: { new (init?: string[][] | Record<string, string> | IHeaders): IHeaders };
175
178
  readonly Request: { new (input: string | IRequest, init?: IRequestInit): IRequest };
176
179
  readonly Response: { new (body?: unknown | null, init?: IResponseInit): IResponse };
180
+ readonly Range: typeof Range;
177
181
  readonly DOMRect: typeof DOMRect;
178
182
 
179
183
  // Events
@@ -301,4 +305,24 @@ export default interface IWindow extends IEventTarget, NodeJS.Global {
301
305
  * @returns Promise.
302
306
  */
303
307
  fetch(url: string, init?: IRequestInit): Promise<IResponse>;
308
+
309
+ /**
310
+ * Creates a Base64-encoded ASCII string from a binary string (i.e., a string in which each character in the string is treated as a byte of binary data).
311
+ *
312
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/btoa
313
+ * @param data Binay data.
314
+ * @returns Base64-encoded string.
315
+ */
316
+ btoa(data: unknown): string;
317
+
318
+ /**
319
+ * Decodes a string of data which has been encoded using Base64 encoding.
320
+ *
321
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/atob
322
+ * @see https://infra.spec.whatwg.org/#forgiving-base64-encode.
323
+ * @see Https://html.spec.whatwg.org/multipage/webappapis.html#btoa.
324
+ * @param data Binay string.
325
+ * @returns An ASCII string containing decoded data from encodedData.
326
+ */
327
+ atob(data: unknown): string;
304
328
  }
@@ -21,11 +21,12 @@ import HTMLSlotElement from '../nodes/html-slot-element/HTMLSlotElement';
21
21
  import HTMLLabelElement from '../nodes/html-label-element/HTMLLabelElement';
22
22
  import HTMLMetaElement from '../nodes/html-meta-element/HTMLMetaElement';
23
23
  import HTMLBaseElement from '../nodes/html-base-element/HTMLBaseElement';
24
+ import HTMLDialogElement from '../nodes/html-dialog-element/HTMLDialogElement';
24
25
  import SVGSVGElement from '../nodes/svg-element/SVGSVGElement';
25
26
  import SVGElement from '../nodes/svg-element/SVGElement';
26
27
  import HTMLScriptElement from '../nodes/html-script-element/HTMLScriptElement';
27
28
  import HTMLImageElement from '../nodes/html-image-element/HTMLImageElement';
28
- import Image from '../nodes/html-image-element/Image';
29
+ import { default as ImageImplementation } from '../nodes/html-image-element/Image';
29
30
  import DocumentFragment from '../nodes/document-fragment/DocumentFragment';
30
31
  import CharacterData from '../nodes/character-data/CharacterData';
31
32
  import TreeWalker from '../tree-walker/TreeWalker';
@@ -40,13 +41,13 @@ import Location from '../location/Location';
40
41
  import NonImplementedEventTypes from '../event/NonImplementedEventTypes';
41
42
  import MutationObserver from '../mutation-observer/MutationObserver';
42
43
  import NonImplemenetedElementClasses from '../config/NonImplemenetedElementClasses';
43
- import DOMParser from '../dom-parser/DOMParser';
44
+ import { default as DOMParserImplementation } from '../dom-parser/DOMParser';
44
45
  import XMLSerializer from '../xml-serializer/XMLSerializer';
45
46
  import ResizeObserver from '../resize-observer/ResizeObserver';
46
47
  import Blob from '../file/Blob';
47
48
  import File from '../file/File';
48
49
  import DOMException from '../exception/DOMException';
49
- import FileReader from '../file/FileReader';
50
+ import { default as FileReaderImplementation } from '../file/FileReader';
50
51
  import History from '../history/History';
51
52
  import CSSStyleSheet from '../css/CSSStyleSheet';
52
53
  import CSSStyleDeclaration from '../css/CSSStyleDeclaration';
@@ -72,8 +73,8 @@ import IRequestInit from '../fetch/IRequestInit';
72
73
  import IHeaders from '../fetch/IHeaders';
73
74
  import IHeadersInit from '../fetch/IHeadersInit';
74
75
  import Headers from '../fetch/Headers';
75
- import Request from '../fetch/Request';
76
- import Response from '../fetch/Response';
76
+ import { default as RequestImplementation } from '../fetch/Request';
77
+ import { default as ResponseImplementation } from '../fetch/Response';
77
78
  import Storage from '../storage/Storage';
78
79
  import IWindow from './IWindow';
79
80
  import HTMLCollection from '../nodes/element/HTMLCollection';
@@ -87,12 +88,19 @@ import Plugin from '../navigator/Plugin';
87
88
  import PluginArray from '../navigator/PluginArray';
88
89
  import { URLSearchParams } from 'url';
89
90
  import FetchHandler from '../fetch/FetchHandler';
91
+ import { default as RangeImplementation } from '../range/Range';
90
92
  import DOMRect from '../nodes/element/DOMRect';
91
93
  import VMGlobalPropertyScript from './VMGlobalPropertyScript';
92
94
  import * as PerfHooks from 'perf_hooks';
93
95
  import VM from 'vm';
94
96
  import { Buffer } from 'buffer';
95
- import { atob, btoa } from './WindowBase64';
97
+ import Base64 from '../base64/Base64';
98
+ import IDocument from '../nodes/document/IDocument';
99
+
100
+ const ORIGINAL_SET_TIMEOUT = setTimeout;
101
+ const ORIGINAL_CLEAR_TIMEOUT = clearTimeout;
102
+ const ORIGINAL_SET_INTERVAL = setInterval;
103
+ const ORIGINAL_CLEAR_INTERVAL = clearInterval;
96
104
 
97
105
  /**
98
106
  * Browser window.
@@ -101,7 +109,7 @@ import { atob, btoa } from './WindowBase64';
101
109
  * https://developer.mozilla.org/en-US/docs/Web/API/Window.
102
110
  */
103
111
  export default class Window extends EventTarget implements IWindow {
104
- // Public Properties
112
+ // The Happy DOM property
105
113
  public readonly happyDOM = {
106
114
  whenAsyncComplete: async (): Promise<void> => {
107
115
  return await this.happyDOM.asyncTaskManager.whenComplete();
@@ -121,7 +129,6 @@ export default class Window extends EventTarget implements IWindow {
121
129
  public readonly HTMLInputElement = HTMLInputElement;
122
130
  public readonly HTMLTextAreaElement = HTMLTextAreaElement;
123
131
  public readonly HTMLImageElement = HTMLImageElement;
124
- public readonly Image = Image;
125
132
  public readonly HTMLScriptElement = HTMLScriptElement;
126
133
  public readonly HTMLLinkElement = HTMLLinkElement;
127
134
  public readonly HTMLStyleElement = HTMLStyleElement;
@@ -129,6 +136,7 @@ export default class Window extends EventTarget implements IWindow {
129
136
  public readonly HTMLSlotElement = HTMLSlotElement;
130
137
  public readonly HTMLMetaElement = HTMLMetaElement;
131
138
  public readonly HTMLBaseElement = HTMLBaseElement;
139
+ public readonly HTMLDialogElement = HTMLDialogElement;
132
140
  public readonly SVGSVGElement = SVGSVGElement;
133
141
  public readonly SVGElement = SVGElement;
134
142
  public readonly Text = Text;
@@ -139,7 +147,6 @@ export default class Window extends EventTarget implements IWindow {
139
147
  public readonly CharacterData = CharacterData;
140
148
  public readonly NodeFilter = NodeFilter;
141
149
  public readonly TreeWalker = TreeWalker;
142
- public readonly DOMParser = DOMParser;
143
150
  public readonly MutationObserver = MutationObserver;
144
151
  public readonly Document = Document;
145
152
  public readonly HTMLDocument = HTMLDocument;
@@ -171,7 +178,6 @@ export default class Window extends EventTarget implements IWindow {
171
178
  public readonly CSSStyleSheet = CSSStyleSheet;
172
179
  public readonly Blob = Blob;
173
180
  public readonly File = File;
174
- public readonly FileReader = FileReader;
175
181
  public readonly DOMException = DOMException;
176
182
  public readonly History = History;
177
183
  public readonly Screen = Screen;
@@ -188,13 +194,17 @@ export default class Window extends EventTarget implements IWindow {
188
194
  public readonly Plugin = Plugin;
189
195
  public readonly PluginArray = PluginArray;
190
196
  public readonly Headers: { new (init?: IHeadersInit): IHeaders } = Headers;
197
+ public readonly DOMRect: typeof DOMRect;
191
198
  public readonly Request: {
192
199
  new (input: string | { href: string } | IRequest, init?: IRequestInit): IRequest;
193
- } = Request;
200
+ };
194
201
  public readonly Response: {
195
202
  new (body?: NodeJS.ReadableStream | null, init?: IResponseInit): IResponse;
196
- } = Response;
197
- public readonly DOMRect: typeof DOMRect;
203
+ };
204
+ public readonly DOMParser;
205
+ public readonly Range;
206
+ public readonly FileReader;
207
+ public readonly Image;
198
208
 
199
209
  // Events
200
210
  public onload: (event: Event) => void = null;
@@ -220,10 +230,6 @@ export default class Window extends EventTarget implements IWindow {
220
230
  public readonly localStorage = new Storage();
221
231
  public readonly performance = PerfHooks.performance;
222
232
 
223
- // Atob & btoa
224
- public atob = atob;
225
- public btoa = btoa;
226
-
227
233
  // Node.js Globals
228
234
  public ArrayBuffer;
229
235
  public Boolean;
@@ -288,10 +294,10 @@ export default class Window extends EventTarget implements IWindow {
288
294
  public Function;
289
295
 
290
296
  // Private properties
291
- private _setTimeout = setTimeout;
292
- private _clearTimeout = clearTimeout;
293
- private _setInterval = setInterval;
294
- private _clearInterval = clearInterval;
297
+ private _setTimeout;
298
+ private _clearTimeout;
299
+ private _setInterval;
300
+ private _clearInterval;
295
301
 
296
302
  /**
297
303
  * Constructor.
@@ -299,24 +305,19 @@ export default class Window extends EventTarget implements IWindow {
299
305
  constructor() {
300
306
  super();
301
307
 
302
- this.document = new HTMLDocument();
303
- this.document.defaultView = this;
304
- this.document._readyStateManager.whenComplete().then(() => {
305
- this.dispatchEvent(new Event('load'));
306
- });
307
-
308
- DOMParser._ownerDocument = this.document;
309
- FileReader._ownerDocument = this.document;
310
- Image.ownerDocument = this.document;
311
- Request._ownerDocument = this.document;
312
- Response._ownerDocument = this.document;
308
+ this._setTimeout = ORIGINAL_SET_TIMEOUT;
309
+ this._clearTimeout = ORIGINAL_CLEAR_TIMEOUT;
310
+ this._setInterval = ORIGINAL_SET_INTERVAL;
311
+ this._clearInterval = ORIGINAL_CLEAR_INTERVAL;
313
312
 
313
+ // Non-implemented event types
314
314
  for (const eventType of NonImplementedEventTypes) {
315
315
  if (!this[eventType]) {
316
316
  this[eventType] = Event;
317
317
  }
318
318
  }
319
319
 
320
+ // Non implemented element classes
320
321
  for (const className of NonImplemenetedElementClasses) {
321
322
  if (!this[className]) {
322
323
  this[className] = HTMLElement;
@@ -337,7 +338,54 @@ export default class Window extends EventTarget implements IWindow {
337
338
  }
338
339
  }
339
340
 
341
+ HTMLDocument._defaultView = this;
342
+
343
+ const document = new HTMLDocument();
344
+
345
+ this.document = document;
346
+
347
+ // We need to set the correct owner document when the class is constructed.
348
+ // To achieve this we will extend the original implementation with a class that sets the owner document.
349
+
350
+ ResponseImplementation._ownerDocument = document;
351
+ RequestImplementation._ownerDocument = document;
352
+ ImageImplementation._ownerDocument = document;
353
+ FileReaderImplementation._ownerDocument = document;
354
+ DOMParserImplementation._ownerDocument = document;
355
+ RangeImplementation._ownerDocument = document;
356
+
357
+ /* eslint-disable jsdoc/require-jsdoc */
358
+ class Response extends ResponseImplementation {
359
+ public static _ownerDocument: IDocument = document;
360
+ }
361
+ class Request extends RequestImplementation {
362
+ public static _ownerDocument: IDocument = document;
363
+ }
364
+ class Image extends ImageImplementation {
365
+ public static _ownerDocument: IDocument = document;
366
+ }
367
+ class FileReader extends FileReaderImplementation {
368
+ public static _ownerDocument: IDocument = document;
369
+ }
370
+ class DOMParser extends DOMParserImplementation {
371
+ public static _ownerDocument: IDocument = document;
372
+ }
373
+ class Range extends RangeImplementation {
374
+ public static _ownerDocument: IDocument = document;
375
+ }
376
+
377
+ /* eslint-enable jsdoc/require-jsdoc */
378
+
379
+ this.Response = Response;
380
+ this.Request = Request;
381
+ this.Image = Image;
382
+ this.FileReader = FileReader;
383
+ this.DOMParser = DOMParser;
384
+ this.Range = Range;
385
+
340
386
  this._setupVMContext();
387
+
388
+ this.document._onWindowReady();
341
389
  }
342
390
 
343
391
  /**
@@ -527,6 +575,30 @@ export default class Window extends EventTarget implements IWindow {
527
575
  return await FetchHandler.fetch(this.document, url, init);
528
576
  }
529
577
 
578
+ /**
579
+ * Creates a Base64-encoded ASCII string from a binary string (i.e., a string in which each character in the string is treated as a byte of binary data).
580
+ *
581
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/btoa
582
+ * @param data Binay data.
583
+ * @returns Base64-encoded string.
584
+ */
585
+ public btoa(data: unknown): string {
586
+ return Base64.btoa(data);
587
+ }
588
+
589
+ /**
590
+ * Decodes a string of data which has been encoded using Base64 encoding.
591
+ *
592
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/atob
593
+ * @see https://infra.spec.whatwg.org/#forgiving-base64-encode.
594
+ * @see Https://html.spec.whatwg.org/multipage/webappapis.html#btoa.
595
+ * @param data Binay string.
596
+ * @returns An ASCII string containing decoded data from encodedData.
597
+ */
598
+ public atob(data: unknown): string {
599
+ return Base64.atob(data);
600
+ }
601
+
530
602
  /**
531
603
  * Setup of VM context.
532
604
  */
@@ -10,6 +10,7 @@ import HTMLScriptElement from '../nodes/html-script-element/HTMLScriptElement';
10
10
  import INode from '../nodes/node/INode';
11
11
  import IElement from '../nodes/element/IElement';
12
12
  import HTMLLinkElement from '../nodes/html-link-element/HTMLLinkElement';
13
+ import IDocumentFragment from '../nodes/document-fragment/IDocumentFragment';
13
14
 
14
15
  const MARKUP_REGEXP = /<(\/?)([a-z][-.0-9_a-z]*)\s*([^<>]*?)(\/?)>/gi;
15
16
  const COMMENT_REGEXP = /<!--(.*?)-->|<([!?])([^>]*)>/gi;
@@ -28,11 +29,15 @@ export default class XMLParser {
28
29
  * @param [evaluateScripts = false] Set to "true" to enable script execution.
29
30
  * @returns Root element.
30
31
  */
31
- public static parse(document: IDocument, data: string, evaluateScripts = false): IElement {
32
- const root = document.createElement('root');
33
- const stack = [root];
32
+ public static parse(
33
+ document: IDocument,
34
+ data: string,
35
+ evaluateScripts = false
36
+ ): IDocumentFragment {
37
+ const root = document.createDocumentFragment();
38
+ const stack: Array<IElement | IDocumentFragment> = [root];
34
39
  const markupRegexp = new RegExp(MARKUP_REGEXP, 'gi');
35
- let parent = root;
40
+ let parent: IDocumentFragment | IElement = root;
36
41
  let parentUnnestableTagName = null;
37
42
  let lastTextIndex = 0;
38
43
  let match: RegExpExecArray;
@@ -47,7 +52,10 @@ export default class XMLParser {
47
52
  }
48
53
 
49
54
  if (isStartTag) {
50
- const namespaceURI = tagName === 'svg' ? NamespaceURI.svg : parent.namespaceURI;
55
+ const namespaceURI =
56
+ tagName === 'svg'
57
+ ? NamespaceURI.svg
58
+ : (<IElement>parent).namespaceURI || NamespaceURI.html;
51
59
  const newElement = document.createElementNS(namespaceURI, tagName);
52
60
 
53
61
  // Scripts are not allowed to be executed when they are parsed using innerHTML, outerHTML, replaceWith() etc.
@@ -115,8 +123,8 @@ export default class XMLParser {
115
123
  * @param element Element.
116
124
  * @returns Tag name if element is unnestable.
117
125
  */
118
- private static getUnnestableTagName(element: IElement): string {
119
- const tagName = element.tagName.toLowerCase();
126
+ private static getUnnestableTagName(element: IElement | IDocumentFragment): string {
127
+ const tagName = (<IElement>element).tagName ? (<IElement>element).tagName.toLowerCase() : null;
120
128
  return tagName && UnnestableElements.includes(tagName) ? tagName : null;
121
129
  }
122
130
 
@@ -5,6 +5,7 @@ import DocumentType from '../nodes/document-type/DocumentType';
5
5
  import { escape } from 'he';
6
6
  import INode from '../nodes/node/INode';
7
7
  import IElement from '../nodes/element/IElement';
8
+ import IHTMLTemplateElement from '../nodes/html-template-element/IHTMLTemplateElement';
8
9
 
9
10
  /**
10
11
  * Utility for converting an element to string.
@@ -28,9 +29,13 @@ export default class XMLSerializer {
28
29
  return `<${tagName}${this._getAttributes(element)}>`;
29
30
  }
30
31
 
32
+ const childNodes =
33
+ element.tagName === 'TEMPLATE'
34
+ ? (<IHTMLTemplateElement>root).content.childNodes
35
+ : root.childNodes;
31
36
  let innerHTML = '';
32
37
 
33
- for (const node of root.childNodes) {
38
+ for (const node of childNodes) {
34
39
  innerHTML += this.serializeToString(node, options);
35
40
  }
36
41
 
@@ -1,167 +0,0 @@
1
- import Node from '../node/Node';
2
- import DocumentFragment from '../document-fragment/DocumentFragment';
3
- import DOMRect from './DOMRect';
4
- /**
5
- * Range object.
6
- *
7
- * @see https://developer.mozilla.org/en-US/docs/Web/API/Range
8
- */
9
- export default class Range {
10
- private _startContainer;
11
- private _endContainer;
12
- private _startOffset;
13
- private _endOffset;
14
- private _collapsed;
15
- /**
16
- * Returns collapsed.
17
- *
18
- * @returns "true" if collapsed.
19
- */
20
- get collapsed(): boolean;
21
- /**
22
- * Returns common ancestor container.
23
- *
24
- * @returns Node.
25
- */
26
- get commonAncestorContainer(): Node;
27
- /**
28
- * Returns end container.
29
- *
30
- * @returns Node.
31
- */
32
- get endContainer(): Node;
33
- /**
34
- * Returns start container.
35
- *
36
- * @returns Node.
37
- */
38
- get startContainer(): Node;
39
- /**
40
- * Returns end offset.
41
- *
42
- * @returns Offset.
43
- */
44
- get endOffset(): number;
45
- /**
46
- * Returns start offset.
47
- *
48
- * @returns Offset.
49
- */
50
- get startOffset(): number;
51
- /**
52
- * Sets start.
53
- *
54
- * @param startNode Start node.
55
- * @param startOffset Start offset.
56
- */
57
- setStart(startNode: Node, startOffset: number): void;
58
- /**
59
- * Sets end.
60
- *
61
- * @param endNode End node.
62
- * @param endOffset End offset.
63
- */
64
- setEnd(endNode: Node, endOffset: number): void;
65
- /**
66
- * Sets start before.
67
- */
68
- setStartBefore(): void;
69
- /**
70
- * Sets start after.
71
- */
72
- setStartAfter(): void;
73
- /**
74
- * Sets end before.
75
- */
76
- setEndBefore(): void;
77
- /**
78
- * Sets end after.
79
- */
80
- setEndAfter(): void;
81
- /**
82
- * Selects a node.
83
- */
84
- selectNode(): void;
85
- /**
86
- * Selects node content.
87
- */
88
- selectNodeContents(): void;
89
- /**
90
- * Collapses the Range to one of its boundary points.
91
- */
92
- collapse(): void;
93
- /**
94
- * Removes the contents of a Range from the Document.
95
- */
96
- deleteContents(): void;
97
- /**
98
- * Moves contents of a Range from the document tree into a DocumentFragment.
99
- */
100
- extractContents(): DocumentFragment;
101
- /**
102
- * Insert a Node at the start of a Range.
103
- */
104
- insertNode(): void;
105
- /**
106
- * Moves content of a Range into a new Node.
107
- */
108
- surroundContents(): void;
109
- /**
110
- * Compares the boundary points of the Range with another Range.
111
- *
112
- * @returns "true" when equal.
113
- */
114
- compareBoundaryPoints(): boolean;
115
- /**
116
- * Clones the range.
117
- *
118
- * @returns Range.
119
- */
120
- cloneRange(): Range;
121
- /**
122
- * Releases the Range from use to improve performance.
123
- */
124
- detach(): void;
125
- /**
126
- * Returns the text of the Range.
127
- *
128
- * @returns Text.
129
- */
130
- toString(): string;
131
- /**
132
- * Returns -1, 0, or 1 indicating whether the point occurs before, inside, or after the Range.
133
- *
134
- * @returns Number.
135
- */
136
- comparePoint(): number;
137
- /**
138
- * Returns a DocumentFragment created from a given string of code.
139
- *
140
- * @returns Document fragment.
141
- */
142
- createContextualFragment(): DocumentFragment;
143
- /**
144
- * Returns a DOMRect object which bounds the entire contents of the Range; this would be the union of all the rectangles returned by range.getClientRects().
145
- *
146
- * @returns DOM rect.
147
- */
148
- getBoundingClientRect(): DOMRect;
149
- /**
150
- * Returns a list of DOMRect objects that aggregates the results of Element.getClientRects() for all the elements in the Range.
151
- *
152
- * @returns DOM rect.
153
- */
154
- getClientRects(): DOMRect;
155
- /**
156
- * Returns a boolean indicating whether the given node intersects the Range.
157
- *
158
- * @returns "true" when intersecting.
159
- */
160
- intersectsNode(): boolean;
161
- /**
162
- * Returns a boolean indicating whether the given point is in the Range.
163
- *
164
- * @returns "true" when in range.
165
- */
166
- isPointInRange(): boolean;
167
- }