happy-dom 5.4.0 → 6.0.2

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 (141) 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-element/DatasetUtility.js +3 -1
  50. package/lib/nodes/html-element/DatasetUtility.js.map +1 -1
  51. package/lib/nodes/html-template-element/HTMLTemplateElement.d.ts +1 -10
  52. package/lib/nodes/html-template-element/HTMLTemplateElement.js +2 -15
  53. package/lib/nodes/html-template-element/HTMLTemplateElement.js.map +1 -1
  54. package/lib/nodes/node/INode.d.ts +8 -6
  55. package/lib/nodes/node/Node.d.ts +20 -17
  56. package/lib/nodes/node/Node.js +19 -15
  57. package/lib/nodes/node/Node.js.map +1 -1
  58. package/lib/nodes/node/NodeTypeEnum.d.ts +10 -0
  59. package/lib/nodes/node/NodeTypeEnum.js +14 -0
  60. package/lib/nodes/node/NodeTypeEnum.js.map +1 -0
  61. package/lib/nodes/node/NodeUtility.d.ts +59 -0
  62. package/lib/nodes/node/NodeUtility.js +123 -0
  63. package/lib/nodes/node/NodeUtility.js.map +1 -0
  64. package/lib/nodes/text/IText.d.ts +9 -0
  65. package/lib/nodes/text/Text.d.ts +10 -1
  66. package/lib/nodes/text/Text.js +24 -0
  67. package/lib/nodes/text/Text.js.map +1 -1
  68. package/lib/query-selector/SelectorItem.js +3 -2
  69. package/lib/query-selector/SelectorItem.js.map +1 -1
  70. package/lib/range/IRangeBoundaryPoint.d.ts +8 -0
  71. package/lib/range/IRangeBoundaryPoint.js +3 -0
  72. package/lib/range/IRangeBoundaryPoint.js.map +1 -0
  73. package/lib/range/Range.d.ts +249 -0
  74. package/lib/range/Range.js +820 -0
  75. package/lib/range/Range.js.map +1 -0
  76. package/lib/range/RangeHowEnum.d.ts +7 -0
  77. package/lib/range/RangeHowEnum.js +11 -0
  78. package/lib/range/RangeHowEnum.js.map +1 -0
  79. package/lib/range/RangeUtility.d.ts +46 -0
  80. package/lib/range/RangeUtility.js +92 -0
  81. package/lib/range/RangeUtility.js.map +1 -0
  82. package/lib/selection/Selection.d.ts +167 -44
  83. package/lib/selection/Selection.js +369 -58
  84. package/lib/selection/Selection.js.map +1 -1
  85. package/lib/selection/SelectionDirectionEnum.d.ts +6 -0
  86. package/lib/selection/SelectionDirectionEnum.js +10 -0
  87. package/lib/selection/SelectionDirectionEnum.js.map +1 -0
  88. package/lib/window/IWindow.d.ts +20 -0
  89. package/lib/window/Window.d.ts +23 -9
  90. package/lib/window/Window.js +83 -35
  91. package/lib/window/Window.js.map +1 -1
  92. package/lib/xml-parser/XMLParser.d.ts +2 -2
  93. package/lib/xml-parser/XMLParser.js +5 -3
  94. package/lib/xml-parser/XMLParser.js.map +1 -1
  95. package/lib/xml-serializer/XMLSerializer.js +4 -1
  96. package/lib/xml-serializer/XMLSerializer.js.map +1 -1
  97. package/package.json +2 -2
  98. package/src/base64/Base64.ts +97 -0
  99. package/src/config/NonImplemenetedElementClasses.ts +0 -1
  100. package/src/dom-implementation/DOMImplementation.ts +13 -2
  101. package/src/dom-parser/DOMParser.ts +20 -7
  102. package/src/exception/DOMExceptionNameEnum.ts +5 -1
  103. package/src/fetch/Request.ts +16 -6
  104. package/src/fetch/Response.ts +13 -6
  105. package/src/file/FileReader.ts +14 -4
  106. package/src/index.ts +2 -0
  107. package/src/nodes/document/Document.ts +47 -39
  108. package/src/nodes/document/IDocument.ts +8 -0
  109. package/src/nodes/element/DOMRectListFactory.ts +33 -0
  110. package/src/nodes/element/Element.ts +10 -11
  111. package/src/nodes/element/IDOMRectList.ts +11 -0
  112. package/src/nodes/element/IElement.ts +5 -4
  113. package/src/nodes/html-dialog-element/HTMLDialogElement.ts +4 -9
  114. package/src/nodes/html-dialog-element/IHTMLDialogElement.ts +14 -0
  115. package/src/nodes/html-element/DatasetUtility.ts +3 -1
  116. package/src/nodes/html-template-element/HTMLTemplateElement.ts +3 -21
  117. package/src/nodes/node/INode.ts +8 -6
  118. package/src/nodes/node/Node.ts +24 -19
  119. package/src/nodes/node/NodeTypeEnum.ts +11 -0
  120. package/src/nodes/node/NodeUtility.ts +139 -0
  121. package/src/nodes/text/IText.ts +10 -0
  122. package/src/nodes/text/Text.ts +33 -0
  123. package/src/query-selector/SelectorItem.ts +3 -2
  124. package/src/range/IRangeBoundaryPoint.ts +9 -0
  125. package/src/range/Range.ts +1057 -0
  126. package/src/range/RangeHowEnum.ts +8 -0
  127. package/src/range/RangeUtility.ts +114 -0
  128. package/src/selection/Selection.ts +444 -60
  129. package/src/selection/SelectionDirectionEnum.ts +7 -0
  130. package/src/window/IWindow.ts +22 -0
  131. package/src/window/Window.ts +102 -32
  132. package/src/xml-parser/XMLParser.ts +15 -7
  133. package/src/xml-serializer/XMLSerializer.ts +6 -1
  134. package/lib/nodes/element/Range.d.ts +0 -167
  135. package/lib/nodes/element/Range.js +0 -215
  136. package/lib/nodes/element/Range.js.map +0 -1
  137. package/lib/window/WindowBase64.d.ts +0 -19
  138. package/lib/window/WindowBase64.js +0 -88
  139. package/lib/window/WindowBase64.js.map +0 -1
  140. package/src/nodes/element/Range.ts +0 -237
  141. 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;
@@ -80,6 +80,7 @@ import IRequest from '../fetch/IRequest';
80
80
  import IHeaders from '../fetch/IHeaders';
81
81
  import IRequestInit from '../fetch/IRequestInit';
82
82
  import IResponse from '../fetch/IResponse';
83
+ import Range from '../range/Range';
83
84
  import MediaQueryList from '../match-media/MediaQueryList';
84
85
  import DOMRect from '../nodes/element/DOMRect';
85
86
  import Window from './Window';
@@ -176,6 +177,7 @@ export default interface IWindow extends IEventTarget, NodeJS.Global {
176
177
  readonly Headers: { new (init?: string[][] | Record<string, string> | IHeaders): IHeaders };
177
178
  readonly Request: { new (input: string | IRequest, init?: IRequestInit): IRequest };
178
179
  readonly Response: { new (body?: unknown | null, init?: IResponseInit): IResponse };
180
+ readonly Range: typeof Range;
179
181
  readonly DOMRect: typeof DOMRect;
180
182
 
181
183
  // Events
@@ -303,4 +305,24 @@ export default interface IWindow extends IEventTarget, NodeJS.Global {
303
305
  * @returns Promise.
304
306
  */
305
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;
306
328
  }
@@ -26,7 +26,7 @@ import SVGSVGElement from '../nodes/svg-element/SVGSVGElement';
26
26
  import SVGElement from '../nodes/svg-element/SVGElement';
27
27
  import HTMLScriptElement from '../nodes/html-script-element/HTMLScriptElement';
28
28
  import HTMLImageElement from '../nodes/html-image-element/HTMLImageElement';
29
- import Image from '../nodes/html-image-element/Image';
29
+ import { default as ImageImplementation } from '../nodes/html-image-element/Image';
30
30
  import DocumentFragment from '../nodes/document-fragment/DocumentFragment';
31
31
  import CharacterData from '../nodes/character-data/CharacterData';
32
32
  import TreeWalker from '../tree-walker/TreeWalker';
@@ -41,13 +41,13 @@ import Location from '../location/Location';
41
41
  import NonImplementedEventTypes from '../event/NonImplementedEventTypes';
42
42
  import MutationObserver from '../mutation-observer/MutationObserver';
43
43
  import NonImplemenetedElementClasses from '../config/NonImplemenetedElementClasses';
44
- import DOMParser from '../dom-parser/DOMParser';
44
+ import { default as DOMParserImplementation } from '../dom-parser/DOMParser';
45
45
  import XMLSerializer from '../xml-serializer/XMLSerializer';
46
46
  import ResizeObserver from '../resize-observer/ResizeObserver';
47
47
  import Blob from '../file/Blob';
48
48
  import File from '../file/File';
49
49
  import DOMException from '../exception/DOMException';
50
- import FileReader from '../file/FileReader';
50
+ import { default as FileReaderImplementation } from '../file/FileReader';
51
51
  import History from '../history/History';
52
52
  import CSSStyleSheet from '../css/CSSStyleSheet';
53
53
  import CSSStyleDeclaration from '../css/CSSStyleDeclaration';
@@ -73,8 +73,8 @@ import IRequestInit from '../fetch/IRequestInit';
73
73
  import IHeaders from '../fetch/IHeaders';
74
74
  import IHeadersInit from '../fetch/IHeadersInit';
75
75
  import Headers from '../fetch/Headers';
76
- import Request from '../fetch/Request';
77
- import Response from '../fetch/Response';
76
+ import { default as RequestImplementation } from '../fetch/Request';
77
+ import { default as ResponseImplementation } from '../fetch/Response';
78
78
  import Storage from '../storage/Storage';
79
79
  import IWindow from './IWindow';
80
80
  import HTMLCollection from '../nodes/element/HTMLCollection';
@@ -88,12 +88,19 @@ import Plugin from '../navigator/Plugin';
88
88
  import PluginArray from '../navigator/PluginArray';
89
89
  import { URLSearchParams } from 'url';
90
90
  import FetchHandler from '../fetch/FetchHandler';
91
+ import { default as RangeImplementation } from '../range/Range';
91
92
  import DOMRect from '../nodes/element/DOMRect';
92
93
  import VMGlobalPropertyScript from './VMGlobalPropertyScript';
93
94
  import * as PerfHooks from 'perf_hooks';
94
95
  import VM from 'vm';
95
96
  import { Buffer } from 'buffer';
96
- 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;
97
104
 
98
105
  /**
99
106
  * Browser window.
@@ -102,7 +109,7 @@ import { atob, btoa } from './WindowBase64';
102
109
  * https://developer.mozilla.org/en-US/docs/Web/API/Window.
103
110
  */
104
111
  export default class Window extends EventTarget implements IWindow {
105
- // Public Properties
112
+ // The Happy DOM property
106
113
  public readonly happyDOM = {
107
114
  whenAsyncComplete: async (): Promise<void> => {
108
115
  return await this.happyDOM.asyncTaskManager.whenComplete();
@@ -122,7 +129,6 @@ export default class Window extends EventTarget implements IWindow {
122
129
  public readonly HTMLInputElement = HTMLInputElement;
123
130
  public readonly HTMLTextAreaElement = HTMLTextAreaElement;
124
131
  public readonly HTMLImageElement = HTMLImageElement;
125
- public readonly Image = Image;
126
132
  public readonly HTMLScriptElement = HTMLScriptElement;
127
133
  public readonly HTMLLinkElement = HTMLLinkElement;
128
134
  public readonly HTMLStyleElement = HTMLStyleElement;
@@ -141,7 +147,6 @@ export default class Window extends EventTarget implements IWindow {
141
147
  public readonly CharacterData = CharacterData;
142
148
  public readonly NodeFilter = NodeFilter;
143
149
  public readonly TreeWalker = TreeWalker;
144
- public readonly DOMParser = DOMParser;
145
150
  public readonly MutationObserver = MutationObserver;
146
151
  public readonly Document = Document;
147
152
  public readonly HTMLDocument = HTMLDocument;
@@ -173,7 +178,6 @@ export default class Window extends EventTarget implements IWindow {
173
178
  public readonly CSSStyleSheet = CSSStyleSheet;
174
179
  public readonly Blob = Blob;
175
180
  public readonly File = File;
176
- public readonly FileReader = FileReader;
177
181
  public readonly DOMException = DOMException;
178
182
  public readonly History = History;
179
183
  public readonly Screen = Screen;
@@ -190,13 +194,17 @@ export default class Window extends EventTarget implements IWindow {
190
194
  public readonly Plugin = Plugin;
191
195
  public readonly PluginArray = PluginArray;
192
196
  public readonly Headers: { new (init?: IHeadersInit): IHeaders } = Headers;
197
+ public readonly DOMRect: typeof DOMRect;
193
198
  public readonly Request: {
194
199
  new (input: string | { href: string } | IRequest, init?: IRequestInit): IRequest;
195
- } = Request;
200
+ };
196
201
  public readonly Response: {
197
202
  new (body?: NodeJS.ReadableStream | null, init?: IResponseInit): IResponse;
198
- } = Response;
199
- public readonly DOMRect: typeof DOMRect;
203
+ };
204
+ public readonly DOMParser;
205
+ public readonly Range;
206
+ public readonly FileReader;
207
+ public readonly Image;
200
208
 
201
209
  // Events
202
210
  public onload: (event: Event) => void = null;
@@ -222,10 +230,6 @@ export default class Window extends EventTarget implements IWindow {
222
230
  public readonly localStorage = new Storage();
223
231
  public readonly performance = PerfHooks.performance;
224
232
 
225
- // Atob & btoa
226
- public atob = atob;
227
- public btoa = btoa;
228
-
229
233
  // Node.js Globals
230
234
  public ArrayBuffer;
231
235
  public Boolean;
@@ -290,10 +294,10 @@ export default class Window extends EventTarget implements IWindow {
290
294
  public Function;
291
295
 
292
296
  // Private properties
293
- private _setTimeout = setTimeout;
294
- private _clearTimeout = clearTimeout;
295
- private _setInterval = setInterval;
296
- private _clearInterval = clearInterval;
297
+ private _setTimeout;
298
+ private _clearTimeout;
299
+ private _setInterval;
300
+ private _clearInterval;
297
301
 
298
302
  /**
299
303
  * Constructor.
@@ -301,24 +305,19 @@ export default class Window extends EventTarget implements IWindow {
301
305
  constructor() {
302
306
  super();
303
307
 
304
- this.document = new HTMLDocument();
305
- this.document.defaultView = this;
306
- this.document._readyStateManager.whenComplete().then(() => {
307
- this.dispatchEvent(new Event('load'));
308
- });
309
-
310
- DOMParser._ownerDocument = this.document;
311
- FileReader._ownerDocument = this.document;
312
- Image.ownerDocument = this.document;
313
- Request._ownerDocument = this.document;
314
- 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;
315
312
 
313
+ // Non-implemented event types
316
314
  for (const eventType of NonImplementedEventTypes) {
317
315
  if (!this[eventType]) {
318
316
  this[eventType] = Event;
319
317
  }
320
318
  }
321
319
 
320
+ // Non implemented element classes
322
321
  for (const className of NonImplemenetedElementClasses) {
323
322
  if (!this[className]) {
324
323
  this[className] = HTMLElement;
@@ -339,7 +338,54 @@ export default class Window extends EventTarget implements IWindow {
339
338
  }
340
339
  }
341
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
+
342
386
  this._setupVMContext();
387
+
388
+ this.document._onWindowReady();
343
389
  }
344
390
 
345
391
  /**
@@ -529,6 +575,30 @@ export default class Window extends EventTarget implements IWindow {
529
575
  return await FetchHandler.fetch(this.document, url, init);
530
576
  }
531
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
+
532
602
  /**
533
603
  * Setup of VM context.
534
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
- }