@xmldom/xmldom 0.9.2 → 0.9.4

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.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,55 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [0.9.4](https://github.com/xmldom/xmldom/compare/0.9.3...0.9.4)
8
+
9
+ ### Fixed
10
+
11
+ - restore performance for large amount of child nodes [`#748`](https://github.com/xmldom/xmldom/issues/748) / [`#760`](https://github.com/xmldom/xmldom/pull/760)
12
+ - types: correct error handler level to `warning` (#759) [`#754`](https://github.com/xmldom/xmldom/issues/754) / [`#759`](https://github.com/xmldom/xmldom/pull/759)
13
+
14
+ ### Docs
15
+
16
+ - test: verify BOM handling [`#758`](https://github.com/xmldom/xmldom/pull/758)
17
+
18
+ Thank you,
19
+ [@luffynando](https://github.com/luffynando),
20
+ [@mattiasw](https://github.com/mattiasw),
21
+ [@JoinerDev](https://github.com/JoinerDev),
22
+ for your contributions.
23
+
24
+
25
+ ## [0.9.3](https://github.com/xmldom/xmldom/compare/0.9.2...0.9.3)
26
+
27
+ ### Fixed
28
+
29
+ - restore more `Node` and `ProcessingInstruction` types [`#725`](https://github.com/xmldom/xmldom/issues/725) / [`#726`](https://github.com/xmldom/xmldom/pull/726)
30
+ - `getElements*` methods return `LiveNodeList<Element>` [`#731`](https://github.com/xmldom/xmldom/issues/731) / [`#734`](https://github.com/xmldom/xmldom/pull/734)
31
+ - Add more missing `Node` props [`#728`](https://github.com/xmldom/xmldom/pull/728), triggered by unclosed [`#724`](https://github.com/xmldom/xmldom/pull/724)
32
+
33
+ ### Docs
34
+
35
+ - Update supported runtimes in readme (NodeJS >= 14.6 and other [ES5 compatible runtimes](https://compat-table.github.io/compat-table/es5/))
36
+
37
+ ### Chore
38
+
39
+ - updates devDependencies
40
+
41
+ Thank you,
42
+ [@Ponynjaa](https://github.com/Ponynjaa),
43
+ [@ayZagen](https://github.com/ayZagen),
44
+ [@sserdyuk](https://github.com/sserdyuk),
45
+ [@wydengyre](https://github.com/wydengyre),
46
+ [@mykola-mokhnach](https://github.com/mykola-mokhnach),
47
+ [@benkroeger](https://github.com/benkroeger),
48
+ for your contributions.
49
+
50
+ # Changelog
51
+
52
+ All notable changes to this project will be documented in this file.
53
+
54
+ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
55
+
7
56
  ## [0.9.2](https://github.com/xmldom/xmldom/compare/0.9.1...0.9.2)
8
57
 
9
58
  ### Feature
package/index.d.ts CHANGED
@@ -333,6 +333,11 @@ declare module '@xmldom/xmldom' {
333
333
  // instanceof post ts 5.3
334
334
  [Symbol.hasInstance](val: unknown): val is T;
335
335
  };
336
+
337
+ type GetRootNodeOptions = {
338
+ composed?: boolean;
339
+ };
340
+
336
341
  /**
337
342
  * The DOM Node interface is an abstract base class upon which many other DOM API objects are
338
343
  * based, thus letting those object types to be used similarly and often interchangeably. As an
@@ -350,8 +355,7 @@ declare module '@xmldom/xmldom' {
350
355
  * cannot have children will throw an exception.
351
356
  *
352
357
  * **This behavior is slightly different from the in the specs**:
353
- * - undeclared properties: nodeType, baseURI, isConnected, parentElement, textContent
354
- * - missing methods: contains, getRootNode, isEqualNode, isSameNode
358
+ * - unimplemented interfaces: EventTarget
355
359
  *
356
360
  * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247
357
361
  * @see https://dom.spec.whatwg.org/#node
@@ -380,6 +384,18 @@ declare module '@xmldom/xmldom' {
380
384
  * The local part of the qualified name of this node.
381
385
  */
382
386
  localName: string | null;
387
+ /**
388
+ * Always returns `about:blank` currently.
389
+ *
390
+ * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Node/baseURI)
391
+ */
392
+ readonly baseURI: 'about:blank';
393
+ /**
394
+ * Returns true if this node is inside of a document or is the document node itself.
395
+ *
396
+ * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Node/isConnected)
397
+ */
398
+ readonly isConnected: boolean;
383
399
  /**
384
400
  * The namespace URI of this node.
385
401
  */
@@ -396,6 +412,12 @@ declare module '@xmldom/xmldom' {
396
412
  * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/nodeName)
397
413
  */
398
414
  readonly nodeName: string;
415
+ /**
416
+ * Returns the type of node.
417
+ *
418
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/nodeType)
419
+ */
420
+ readonly nodeType: number;
399
421
  /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/nodeValue) */
400
422
  nodeValue: string | null;
401
423
  /**
@@ -410,6 +432,12 @@ declare module '@xmldom/xmldom' {
410
432
  * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/parentNode)
411
433
  */
412
434
  readonly parentNode: Node | null;
435
+ /**
436
+ * Returns the parent `Node` if it is of type `Element`, otherwise `null`.
437
+ *
438
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/parentElement)
439
+ */
440
+ readonly parentElement: Element | null;
413
441
  /**
414
442
  * The prefix of the namespace for this node.
415
443
  */
@@ -420,10 +448,57 @@ declare module '@xmldom/xmldom' {
420
448
  * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/previousSibling)
421
449
  */
422
450
  readonly previousSibling: Node | null;
451
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/textContent) */
452
+ textContent: string | null;
453
+
454
+ /**
455
+ * Zero based line position inside the parsed source,
456
+ * if the `locator` was not disabled.
457
+ */
458
+ lineNumber?: number;
459
+ /**
460
+ * One based column position inside the parsed source,
461
+ * if the `locator` was not disabled.
462
+ */
463
+ columnNumber?: number;
423
464
 
424
465
  /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/appendChild) */
425
466
  appendChild(node: Node): Node;
426
467
 
468
+ /**
469
+ * Checks whether `other` is an inclusive descendant of this node.
470
+ *
471
+ * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Node/contains)
472
+ */
473
+ contains(other: Node | null | undefined): boolean;
474
+ /**
475
+ * Searches for the root node of this node.
476
+ *
477
+ * **This behavior is slightly different from the one in the specs**:
478
+ * - ignores `options.composed`, since `ShadowRoot`s are unsupported, therefore always
479
+ * returning root.
480
+ *
481
+ * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Node/getRootNode)
482
+ *
483
+ * @see https://dom.spec.whatwg.org/#dom-node-getrootnode
484
+ * @see https://dom.spec.whatwg.org/#concept-shadow-including-root
485
+ */
486
+ getRootNode(options: GetRootNodeOptions): Node;
487
+
488
+ /**
489
+ * Checks whether the given node is equal to this node.
490
+ *
491
+ * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Node/isEqualNode)
492
+ */
493
+ isEqualNode(other: Node): boolean;
494
+
495
+ /**
496
+ * Checks whether the given node is this node.
497
+ *
498
+ * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Node/isSameNode)
499
+ */
500
+ isSameNode(other: Node): boolean;
501
+
427
502
  /**
428
503
  * Returns a copy of node. If deep is true, the copy also includes the node's descendants.
429
504
  *
@@ -618,23 +693,12 @@ declare module '@xmldom/xmldom' {
618
693
  * Get an attribute by name. Note: Name is in lower case in case of HTML namespace and
619
694
  * document.
620
695
  *
621
- * @param {string} localName
622
- * The local name of the attribute.
623
- * @returns {Attr | null}
624
- * The attribute with the given local name, or null if no such attribute exists.
625
696
  * @see https://dom.spec.whatwg.org/#concept-element-attributes-get-by-name
626
697
  */
627
698
  getNamedItem(qualifiedName: string): Attr | null;
628
699
  /**
629
700
  * Get an attribute by namespace and local name.
630
701
  *
631
- * @param {string | null} namespaceURI
632
- * The namespace URI of the attribute.
633
- * @param {string} localName
634
- * The local name of the attribute.
635
- * @returns {Attr | null}
636
- * The attribute with the given namespace URI and local name, or null if no such attribute
637
- * exists.
638
702
  * @see https://dom.spec.whatwg.org/#concept-element-attributes-get-by-namespace
639
703
  */
640
704
  getNamedItemNS(namespace: string | null, localName: string): Attr | null;
@@ -644,10 +708,6 @@ declare module '@xmldom/xmldom' {
644
708
  /**
645
709
  * Removes an attribute specified by the local name.
646
710
  *
647
- * @param {string} localName
648
- * The local name of the attribute to be removed.
649
- * @returns {Attr}
650
- * The attribute node that was removed.
651
711
  * @throws {DOMException}
652
712
  * With code:
653
713
  * - {@link DOMException.NOT_FOUND_ERR} if no attribute with the given name is found.
@@ -658,12 +718,6 @@ declare module '@xmldom/xmldom' {
658
718
  /**
659
719
  * Removes an attribute specified by the namespace and local name.
660
720
  *
661
- * @param {string | null} namespaceURI
662
- * The namespace URI of the attribute to be removed.
663
- * @param {string} localName
664
- * The local name of the attribute to be removed.
665
- * @returns {Attr}
666
- * The attribute node that was removed.
667
721
  * @throws {DOMException}
668
722
  * With code:
669
723
  * - {@link DOMException.NOT_FOUND_ERR} if no attribute with the given namespace URI and
@@ -675,11 +729,6 @@ declare module '@xmldom/xmldom' {
675
729
  /**
676
730
  * Set an attribute.
677
731
  *
678
- * @param {Attr} attr
679
- * The attribute to set.
680
- * @returns {Attr | null}
681
- * The old attribute with the same local name and namespace URI as the new one, or null if no
682
- * such attribute exists.
683
732
  * @throws {DOMException}
684
733
  * With code:
685
734
  * - {@link INUSE_ATTRIBUTE_ERR} - If the attribute is already an attribute of another
@@ -691,11 +740,6 @@ declare module '@xmldom/xmldom' {
691
740
  * Set an attribute, replacing an existing attribute with the same local name and namespace
692
741
  * URI if one exists.
693
742
  *
694
- * @param {Attr} attr
695
- * The attribute to set.
696
- * @returns {Attr | null}
697
- * The old attribute with the same local name and namespace URI as the new one, or null if no
698
- * such attribute exists.
699
743
  * @throws {DOMException}
700
744
  * Throws a DOMException with the name "InUseAttributeError" if the attribute is already an
701
745
  * attribute of another element.
@@ -712,7 +756,7 @@ declare module '@xmldom/xmldom' {
712
756
  *
713
757
  * [MDN Reference](https://developer.mozilla.org/docs/Web/API/NodeList)
714
758
  */
715
- class NodeList implements Iterable<Node> {
759
+ class NodeList<T extends Node = Node> implements Iterable<T> {
716
760
  /**
717
761
  * Returns the number of nodes in the collection.
718
762
  *
@@ -724,34 +768,40 @@ declare module '@xmldom/xmldom' {
724
768
  *
725
769
  * [MDN Reference](https://developer.mozilla.org/docs/Web/API/NodeList/item)
726
770
  */
727
- item(index: number): Node | null;
771
+ item(index: number): T | null;
728
772
  /**
729
773
  * Returns a string representation of the NodeList.
730
774
  */
731
- toString(nodeFilter: (node: Node) => Node | undefined): string;
775
+ toString(nodeFilter: (node: T) => T | undefined): string;
732
776
  /**
733
777
  * Filters the NodeList based on a predicate.
734
778
  *
735
779
  * @private
736
780
  */
737
- filter(predicate: (node: Node) => boolean): Node[];
781
+ filter(predicate: (node: T) => boolean): T[];
738
782
  /**
739
783
  * Returns the first index at which a given node can be found in the NodeList, or -1 if it is
740
784
  * not present.
741
785
  *
742
786
  * @private
743
787
  */
744
- indexOf(node: Node): number;
745
- [index: number]: Node | undefined;
788
+ indexOf(node: T): number;
746
789
 
747
- [Symbol.iterator](): Iterator<Node>;
790
+ /**
791
+ * Index based access returns `undefined`, when accessing indexes >= `length`.
792
+ * But it would break a lot of code (like `Array.from` usages),
793
+ * if it would be typed as `T | undefined`.
794
+ */
795
+ [index: number]: T;
796
+
797
+ [Symbol.iterator](): Iterator<T>;
748
798
  }
749
799
 
750
800
  /**
751
801
  * Represents a live collection of nodes that is automatically updated when its associated
752
802
  * document changes.
753
803
  */
754
- interface LiveNodeList extends NodeList {}
804
+ interface LiveNodeList<T extends Node = Node> extends NodeList<T> {}
755
805
  /**
756
806
  * Represents a live collection of nodes that is automatically updated when its associated
757
807
  * document changes.
@@ -819,7 +869,7 @@ declare module '@xmldom/xmldom' {
819
869
  * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/getElementsByClassName
820
870
  * @see https://dom.spec.whatwg.org/#concept-getelementsbyclassname
821
871
  */
822
- getElementsByClassName(classNames: string): LiveNodeList;
872
+ getElementsByClassName(classNames: string): LiveNodeList<Element>;
823
873
 
824
874
  /**
825
875
  * Returns a LiveNodeList of elements with the given qualifiedName.
@@ -843,7 +893,7 @@ declare module '@xmldom/xmldom' {
843
893
  * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/getElementsByTagName
844
894
  * @see https://dom.spec.whatwg.org/#concept-getelementsbytagname
845
895
  */
846
- getElementsByTagName(qualifiedName: string): LiveNodeList;
896
+ getElementsByTagName(qualifiedName: string): LiveNodeList<Element>;
847
897
 
848
898
  /**
849
899
  * Returns a `LiveNodeList` of elements with the given tag name belonging to the given
@@ -855,7 +905,7 @@ declare module '@xmldom/xmldom' {
855
905
  getElementsByTagNameNS(
856
906
  namespaceURI: string | null,
857
907
  localName: string
858
- ): LiveNodeList;
908
+ ): LiveNodeList<Element>;
859
909
 
860
910
  getQualifiedName(): string;
861
911
  /**
@@ -956,12 +1006,7 @@ declare module '@xmldom/xmldom' {
956
1006
  *
957
1007
  * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData)
958
1008
  */
959
- var CharacterData: {
960
- // instanceof pre ts 5.3
961
- (val: unknown): val is CharacterData;
962
- // instanceof post ts 5.3
963
- [Symbol.hasInstance](val: unknown): val is CharacterData;
964
- };
1009
+ var CharacterData: InstanceOf<CharacterData>;
965
1010
 
966
1011
  /**
967
1012
  * The textual content of Element or Attr. If an element has no markup within its content, it has
@@ -1059,8 +1104,20 @@ declare module '@xmldom/xmldom' {
1059
1104
  }
1060
1105
  var Notation: InstanceOf<Notation>;
1061
1106
 
1062
- interface ProcessingInstruction extends Node {
1107
+ interface ProcessingInstruction extends CharacterData {
1063
1108
  nodeType: typeof Node.PROCESSING_INSTRUCTION_NODE;
1109
+ /**
1110
+ * A string representing the textual data contained in this object.
1111
+ * For `ProcessingInstruction`, that means everything that goes after the `target`, excluding
1112
+ * `?>`.
1113
+ *
1114
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData/data)
1115
+ */
1116
+ data: string;
1117
+ /**
1118
+ * A string containing the name of the application.
1119
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ProcessingInstruction/target) */
1120
+ readonly target: string;
1064
1121
  }
1065
1122
  var ProcessingInstruction: InstanceOf<ProcessingInstruction>;
1066
1123
 
@@ -1081,7 +1138,6 @@ declare module '@xmldom/xmldom' {
1081
1138
  /**
1082
1139
  * The implementation that created this document.
1083
1140
  *
1084
- * @type DOMImplementation
1085
1141
  * @readonly
1086
1142
  */
1087
1143
  readonly implementation: DOMImplementation;
@@ -1099,9 +1155,6 @@ declare module '@xmldom/xmldom' {
1099
1155
  /**
1100
1156
  * Creates an attribute object with a specified name.
1101
1157
  *
1102
- * @param name
1103
- * String that sets the attribute object's name.
1104
- *
1105
1158
  * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/createAttribute)
1106
1159
  */
1107
1160
  createAttribute(localName: string): Attr;
@@ -1119,9 +1172,6 @@ declare module '@xmldom/xmldom' {
1119
1172
  /**
1120
1173
  * Creates a comment object with the specified data.
1121
1174
  *
1122
- * @param data
1123
- * Sets the comment object's data.
1124
- *
1125
1175
  * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/createComment)
1126
1176
  */
1127
1177
  createComment(data: string): Comment;
@@ -1156,6 +1206,23 @@ declare module '@xmldom/xmldom' {
1156
1206
  * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/createElementNS)
1157
1207
  */
1158
1208
  createElementNS(namespace: string | null, qualifiedName: string): Element;
1209
+ /**
1210
+ * Creates an EntityReference object.
1211
+ * The current implementation does not fill the `childNodes` with those of the corresponding
1212
+ * `Entity`
1213
+ *
1214
+ * The name of the entity to reference. No namespace well-formedness checks are performed.
1215
+ *
1216
+ * @deprecated
1217
+ * In DOM Level 4.
1218
+ * @returns {EntityReference}
1219
+ * @throws {DOMException}
1220
+ * With code `INVALID_CHARACTER_ERR` when `name` is not valid.
1221
+ * @throws {DOMException}
1222
+ * with code `NOT_SUPPORTED_ERR` when the document is of type `html`
1223
+ * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-392B75AE
1224
+ */
1225
+ createEntityReference(name: string): EntityReference;
1159
1226
 
1160
1227
  /**
1161
1228
  * Returns a ProcessingInstruction node whose target is target and data is data. If target does
@@ -1182,9 +1249,6 @@ declare module '@xmldom/xmldom' {
1182
1249
 
1183
1250
  /**
1184
1251
  * Returns a reference to the first object with the specified value of the ID attribute.
1185
- *
1186
- * @param elementId
1187
- * String that specifies the ID value.
1188
1252
  */
1189
1253
  getElementById(elementId: string): Element | null;
1190
1254
 
@@ -1203,7 +1267,7 @@ declare module '@xmldom/xmldom' {
1203
1267
  * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName
1204
1268
  * @see https://dom.spec.whatwg.org/#concept-getelementsbyclassname
1205
1269
  */
1206
- getElementsByClassName(classNames: string): LiveNodeList;
1270
+ getElementsByClassName(classNames: string): LiveNodeList<Element>;
1207
1271
 
1208
1272
  /**
1209
1273
  * Returns a LiveNodeList of elements with the given qualifiedName.
@@ -1227,7 +1291,7 @@ declare module '@xmldom/xmldom' {
1227
1291
  * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/getElementsByTagName
1228
1292
  * @see https://dom.spec.whatwg.org/#concept-getelementsbytagname
1229
1293
  */
1230
- getElementsByTagName(qualifiedName: string): LiveNodeList;
1294
+ getElementsByTagName(qualifiedName: string): LiveNodeList<Element>;
1231
1295
 
1232
1296
  /**
1233
1297
  * Returns a `LiveNodeList` of elements with the given tag name belonging to the given
@@ -1242,7 +1306,7 @@ declare module '@xmldom/xmldom' {
1242
1306
  getElementsByTagNameNS(
1243
1307
  namespaceURI: string | null,
1244
1308
  localName: string
1245
- ): LiveNodeList;
1309
+ ): LiveNodeList<Element>;
1246
1310
  /**
1247
1311
  * Returns a copy of node. If deep is true, the copy also includes the node's descendants.
1248
1312
  *
@@ -1368,7 +1432,6 @@ declare module '@xmldom/xmldom' {
1368
1432
  class XMLSerializer {
1369
1433
  serializeToString(node: Node, nodeFilter?: (node: Node) => boolean): string;
1370
1434
  }
1371
-
1372
1435
  // END ./lib/dom.js
1373
1436
 
1374
1437
  // START ./lib/dom-parser.js
@@ -1502,7 +1565,11 @@ declare module '@xmldom/xmldom' {
1502
1565
  }
1503
1566
 
1504
1567
  interface ErrorHandlerFunction {
1505
- (level: 'warn' | 'error' | 'fatalError', msg: string, context: any): void;
1568
+ (
1569
+ level: 'warning' | 'error' | 'fatalError',
1570
+ msg: string,
1571
+ context: any
1572
+ ): void;
1506
1573
  }
1507
1574
 
1508
1575
  /**
package/lib/dom.js CHANGED
@@ -22,6 +22,7 @@ var PDC = Symbol();
22
22
 
23
23
  var errors = require('./errors');
24
24
  var DOMException = errors.DOMException;
25
+ var DOMExceptionName = errors.DOMExceptionName;
25
26
 
26
27
  var g = require('./grammar');
27
28
 
@@ -870,7 +871,7 @@ DOMImplementation.prototype = {
870
871
  * Creates an empty DocumentType node. Entity declarations and notations are not made
871
872
  * available. Entity reference expansions and default attribute additions do not occur.
872
873
  *
873
- * **This behavior is slightly different from the in the specs**:
874
+ * **This behavior is slightly different from the one in the specs**:
874
875
  * - `encoding`, `mode`, `origin`, `url` fields are currently not declared.
875
876
  * - `publicId` and `systemId` contain the raw data including any possible quotes,
876
877
  * so they can always be serialized back to the original value
@@ -919,6 +920,7 @@ DOMImplementation.prototype = {
919
920
  node.publicId = publicId || '';
920
921
  node.systemId = systemId || '';
921
922
  node.internalSubset = internalSubset || '';
923
+ node.childNodes = new NodeList();
922
924
 
923
925
  return node;
924
926
  },
@@ -979,8 +981,7 @@ DOMImplementation.prototype = {
979
981
  * cannot have children will throw an exception.
980
982
  *
981
983
  * **This behavior is slightly different from the in the specs**:
982
- * - undeclared properties: nodeType, baseURI, isConnected, parentElement, textContent
983
- * - missing methods: contains, getRootNode, isEqualNode, isSameNode
984
+ * - unimplemented interfaces: `EventTarget`
984
985
  *
985
986
  * @class
986
987
  * @abstract
@@ -1024,10 +1025,18 @@ Node.prototype = {
1024
1025
  * @type {Node | null}
1025
1026
  */
1026
1027
  parentNode: null,
1028
+ /**
1029
+ * The parent element of this node.
1030
+ *
1031
+ * @type {Element | null}
1032
+ */
1033
+ get parentElement() {
1034
+ return this.parentNode && this.parentNode.nodeType === this.ELEMENT_NODE ? this.parentNode : null;
1035
+ },
1027
1036
  /**
1028
1037
  * The child nodes of this node.
1029
1038
  *
1030
- * @type {NodeList | null}
1039
+ * @type {NodeList}
1031
1040
  */
1032
1041
  childNodes: null,
1033
1042
  /**
@@ -1060,6 +1069,131 @@ Node.prototype = {
1060
1069
  * @type {string | null}
1061
1070
  */
1062
1071
  localName: null,
1072
+ /**
1073
+ * The baseURI is currently always `about:blank`,
1074
+ * since that's what happens when you create a document from scratch.
1075
+ *
1076
+ * @type {'about:blank'}
1077
+ */
1078
+ baseURI: 'about:blank',
1079
+ /**
1080
+ * Is true if this node is part of a document.
1081
+ *
1082
+ * @type {boolean}
1083
+ */
1084
+ get isConnected() {
1085
+ var rootNode = this.getRootNode();
1086
+ return rootNode && rootNode.nodeType === rootNode.DOCUMENT_NODE;
1087
+ },
1088
+ /**
1089
+ * Checks whether `other` is an inclusive descendant of this node.
1090
+ *
1091
+ * @param {Node | null | undefined} other
1092
+ * The node to check.
1093
+ * @returns {boolean}
1094
+ * True if `other` is an inclusive descendant of this node; false otherwise.
1095
+ * @see https://dom.spec.whatwg.org/#dom-node-contains
1096
+ */
1097
+ contains: function (other) {
1098
+ if (!other) return false;
1099
+ var parent = other;
1100
+ do {
1101
+ if (this === parent) return true;
1102
+ parent = other.parentNode;
1103
+ } while (parent);
1104
+ return false;
1105
+ },
1106
+ /**
1107
+ * @typedef GetRootNodeOptions
1108
+ * @property {boolean} [composed=false]
1109
+ */
1110
+ /**
1111
+ * Searches for the root node of this node.
1112
+ *
1113
+ * **This behavior is slightly different from the in the specs**:
1114
+ * - ignores `options.composed`, since `ShadowRoot`s are unsupported, always returns root.
1115
+ *
1116
+ * @param {GetRootNodeOptions} [options]
1117
+ * @returns {Node}
1118
+ * Root node.
1119
+ * @see https://dom.spec.whatwg.org/#dom-node-getrootnode
1120
+ * @see https://dom.spec.whatwg.org/#concept-shadow-including-root
1121
+ */
1122
+ getRootNode: function (options) {
1123
+ var parent = this;
1124
+ do {
1125
+ if (!parent.parentNode) {
1126
+ return parent;
1127
+ }
1128
+ parent = parent.parentNode;
1129
+ } while (parent);
1130
+ },
1131
+ /**
1132
+ * Checks whether the given node is equal to this node.
1133
+ *
1134
+ * @param {Node} [otherNode]
1135
+ * @see https://dom.spec.whatwg.org/#concept-node-equals
1136
+ */
1137
+ isEqualNode: function (otherNode) {
1138
+ if (!otherNode) return false;
1139
+
1140
+ if (this.nodeType !== otherNode.nodeType) return false;
1141
+
1142
+ switch (this.nodeType) {
1143
+ case this.DOCUMENT_TYPE_NODE:
1144
+ if (this.name !== otherNode.name) return false;
1145
+ if (this.publicId !== otherNode.publicId) return false;
1146
+ if (this.systemId !== otherNode.systemId) return false;
1147
+ break;
1148
+ case this.ELEMENT_NODE:
1149
+ if (this.namespaceURI !== otherNode.namespaceURI) return false;
1150
+ if (this.prefix !== otherNode.prefix) return false;
1151
+ if (this.localName !== otherNode.localName) return false;
1152
+ if (this.attributes.length !== otherNode.attributes.length) return false;
1153
+ for (var i = 0; i < this.attributes.length; i++) {
1154
+ var attr = this.attributes.item(i);
1155
+ if (!attr.isEqualNode(otherNode.getAttributeNodeNS(attr.namespaceURI, attr.localName))) {
1156
+ return false;
1157
+ }
1158
+ }
1159
+ break;
1160
+ case this.ATTRIBUTE_NODE:
1161
+ if (this.namespaceURI !== otherNode.namespaceURI) return false;
1162
+ if (this.localName !== otherNode.localName) return false;
1163
+ if (this.value !== otherNode.value) return false;
1164
+
1165
+ break;
1166
+ case this.PROCESSING_INSTRUCTION_NODE:
1167
+ if (this.target !== otherNode.target || this.data !== otherNode.data) {
1168
+ return false;
1169
+ }
1170
+ break;
1171
+ case this.TEXT_NODE:
1172
+ case this.COMMENT_NODE:
1173
+ if (this.data !== otherNode.data) return false;
1174
+ break;
1175
+ }
1176
+
1177
+ if (this.childNodes.length !== otherNode.childNodes.length) {
1178
+ return false;
1179
+ }
1180
+
1181
+ for (var i = 0; i < this.childNodes.length; i++) {
1182
+ if (!this.childNodes[i].isEqualNode(otherNode.childNodes[i])) {
1183
+ return false;
1184
+ }
1185
+ }
1186
+
1187
+ return true;
1188
+ },
1189
+ /**
1190
+ * Checks whether or not the given node is this node.
1191
+ *
1192
+ * @param {Node} [otherNode]
1193
+ */
1194
+ isSameNode: function (otherNode) {
1195
+ return this === otherNode;
1196
+ },
1063
1197
  /**
1064
1198
  * Inserts a node before a reference node as a child of this node.
1065
1199
  *
@@ -1545,7 +1679,6 @@ function _removeChild(parentNode, child) {
1545
1679
  if (parentNode !== child.parentNode) {
1546
1680
  throw new DOMException(DOMException.NOT_FOUND_ERR, "child's parent is not parent");
1547
1681
  }
1548
- //var index = parentNode.childNodes.
1549
1682
  var oldPreviousSibling = child.previousSibling;
1550
1683
  var oldNextSibling = child.nextSibling;
1551
1684
  if (oldPreviousSibling) {
@@ -1587,12 +1720,13 @@ function hasValidParentNodeType(node) {
1587
1720
  function hasInsertableNodeType(node) {
1588
1721
  return (
1589
1722
  node &&
1590
- (isElementNode(node) ||
1591
- node instanceof CharacterData ||
1592
- isDocTypeNode(node) ||
1593
- node.nodeType === Node.DOCUMENT_FRAGMENT_NODE ||
1723
+ (node.nodeType === Node.CDATA_SECTION_NODE ||
1594
1724
  node.nodeType === Node.COMMENT_NODE ||
1595
- node.nodeType === Node.PROCESSING_INSTRUCTION_NODE)
1725
+ node.nodeType === Node.DOCUMENT_FRAGMENT_NODE ||
1726
+ node.nodeType === Node.DOCUMENT_TYPE_NODE ||
1727
+ node.nodeType === Node.ELEMENT_NODE ||
1728
+ node.nodeType === Node.PROCESSING_INSTRUCTION_NODE ||
1729
+ node.nodeType === Node.TEXT_NODE)
1596
1730
  );
1597
1731
  }
1598
1732
 
@@ -1920,11 +2054,11 @@ function _insertBefore(parent, node, child, _inDocumentAssertion) {
1920
2054
  do {
1921
2055
  newFirst.parentNode = parent;
1922
2056
  } while (newFirst !== newLast && (newFirst = newFirst.nextSibling));
1923
- _onUpdateChild(parent.ownerDocument || parent, parent);
1924
- //console.log(parent.lastChild.nextSibling == null)
2057
+ _onUpdateChild(parent.ownerDocument || parent, parent, node);
1925
2058
  if (node.nodeType == DOCUMENT_FRAGMENT_NODE) {
1926
2059
  node.firstChild = node.lastChild = null;
1927
2060
  }
2061
+
1928
2062
  return node;
1929
2063
  }
1930
2064
 
@@ -2038,33 +2172,57 @@ Document.prototype = {
2038
2172
  attrs._ownerElement = node;
2039
2173
  return node;
2040
2174
  },
2175
+ /**
2176
+ * @returns {DocumentFragment}
2177
+ */
2041
2178
  createDocumentFragment: function () {
2042
2179
  var node = new DocumentFragment(PDC);
2043
2180
  node.ownerDocument = this;
2044
2181
  node.childNodes = new NodeList();
2045
2182
  return node;
2046
2183
  },
2184
+ /**
2185
+ * @param {string} data
2186
+ * @returns {Text}
2187
+ */
2047
2188
  createTextNode: function (data) {
2048
2189
  var node = new Text(PDC);
2049
2190
  node.ownerDocument = this;
2191
+ node.childNodes = new NodeList();
2050
2192
  node.appendData(data);
2051
2193
  return node;
2052
2194
  },
2195
+ /**
2196
+ * @param {string} data
2197
+ * @returns {Comment}
2198
+ */
2053
2199
  createComment: function (data) {
2054
2200
  var node = new Comment(PDC);
2055
2201
  node.ownerDocument = this;
2202
+ node.childNodes = new NodeList();
2056
2203
  node.appendData(data);
2057
2204
  return node;
2058
2205
  },
2206
+ /**
2207
+ * @param {string} data
2208
+ * @returns {CDATASection}
2209
+ */
2059
2210
  createCDATASection: function (data) {
2060
2211
  var node = new CDATASection(PDC);
2061
2212
  node.ownerDocument = this;
2213
+ node.childNodes = new NodeList();
2062
2214
  node.appendData(data);
2063
2215
  return node;
2064
2216
  },
2217
+ /**
2218
+ * @param {string} target
2219
+ * @param {string} data
2220
+ * @returns {ProcessingInstruction}
2221
+ */
2065
2222
  createProcessingInstruction: function (target, data) {
2066
2223
  var node = new ProcessingInstruction(PDC);
2067
2224
  node.ownerDocument = this;
2225
+ node.childNodes = new NodeList();
2068
2226
  node.nodeName = node.target = target;
2069
2227
  node.nodeValue = node.data = data;
2070
2228
  return node;
@@ -2095,19 +2253,49 @@ Document.prototype = {
2095
2253
  _createAttribute: function (name) {
2096
2254
  var node = new Attr(PDC);
2097
2255
  node.ownerDocument = this;
2256
+ node.childNodes = new NodeList();
2098
2257
  node.name = name;
2099
2258
  node.nodeName = name;
2100
2259
  node.localName = name;
2101
2260
  node.specified = true;
2102
2261
  return node;
2103
2262
  },
2263
+ /**
2264
+ * Creates an EntityReference object.
2265
+ * The current implementation does not fill the `childNodes` with those of the corresponding
2266
+ * `Entity`
2267
+ *
2268
+ * @deprecated
2269
+ * In DOM Level 4.
2270
+ * @param {string} name
2271
+ * The name of the entity to reference. No namespace well-formedness checks are performed.
2272
+ * @returns {EntityReference}
2273
+ * @throws {DOMException}
2274
+ * With code `INVALID_CHARACTER_ERR` when `name` is not valid.
2275
+ * @throws {DOMException}
2276
+ * with code `NOT_SUPPORTED_ERR` when the document is of type `html`
2277
+ * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-392B75AE
2278
+ */
2104
2279
  createEntityReference: function (name) {
2280
+ if (!g.Name.test(name)) {
2281
+ throw new DOMException(DOMException.INVALID_CHARACTER_ERR, 'not a valid xml name "' + name + '"');
2282
+ }
2283
+ if (this.type === 'html') {
2284
+ throw new DOMException('document is an html document', DOMExceptionName.NotSupportedError);
2285
+ }
2286
+
2105
2287
  var node = new EntityReference(PDC);
2106
2288
  node.ownerDocument = this;
2289
+ node.childNodes = new NodeList();
2107
2290
  node.nodeName = name;
2108
2291
  return node;
2109
2292
  },
2110
2293
  // Introduced in DOM Level 2:
2294
+ /**
2295
+ * @param {string} namespaceURI
2296
+ * @param {string} qualifiedName
2297
+ * @returns {Element}
2298
+ */
2111
2299
  createElementNS: function (namespaceURI, qualifiedName) {
2112
2300
  var validated = validateAndExtract(namespaceURI, qualifiedName);
2113
2301
  var node = new Element(PDC);
@@ -2123,10 +2311,16 @@ Document.prototype = {
2123
2311
  return node;
2124
2312
  },
2125
2313
  // Introduced in DOM Level 2:
2314
+ /**
2315
+ * @param {string} namespaceURI
2316
+ * @param {string} qualifiedName
2317
+ * @returns {Attr}
2318
+ */
2126
2319
  createAttributeNS: function (namespaceURI, qualifiedName) {
2127
2320
  var validated = validateAndExtract(namespaceURI, qualifiedName);
2128
2321
  var node = new Attr(PDC);
2129
2322
  node.ownerDocument = this;
2323
+ node.childNodes = new NodeList();
2130
2324
  node.nodeName = qualifiedName;
2131
2325
  node.name = qualifiedName;
2132
2326
  node.specified = true;
@@ -2481,7 +2675,7 @@ function ProcessingInstruction(symbol) {
2481
2675
  checkSymbol(symbol);
2482
2676
  }
2483
2677
  ProcessingInstruction.prototype.nodeType = PROCESSING_INSTRUCTION_NODE;
2484
- _extends(ProcessingInstruction, Node);
2678
+ _extends(ProcessingInstruction, CharacterData);
2485
2679
  function XMLSerializer() {}
2486
2680
  XMLSerializer.prototype.serializeToString = function (node, nodeFilter) {
2487
2681
  return nodeSerializeToString.call(node, nodeFilter);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xmldom/xmldom",
3
- "version": "0.9.2",
3
+ "version": "0.9.4",
4
4
  "description": "A pure JavaScript W3C standard-based (XML DOM Level 2 Core) DOMParser and XMLSerializer module.",
5
5
  "keywords": [
6
6
  "w3c",
@@ -40,22 +40,22 @@
40
40
  "release": "np --no-yarn --test-script testrelease"
41
41
  },
42
42
  "engines": {
43
- "node": ">=14.0.0"
43
+ "node": ">=14.6"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@homer0/prettier-plugin-jsdoc": "9.0.2",
47
47
  "@jazzer.js/core": "2.1.0",
48
48
  "@jazzer.js/jest-runner": "2.1.0",
49
- "auto-changelog": "2.4.0",
50
- "eslint": "8.57.0",
49
+ "auto-changelog": "2.5.0",
50
+ "eslint": "8.57.1",
51
51
  "eslint-config-prettier": "9.1.0",
52
52
  "eslint-plugin-anti-trojan-source": "1.1.1",
53
53
  "eslint-plugin-es5": "1.5.0",
54
- "eslint-plugin-n": "17.10.2",
54
+ "eslint-plugin-n": "17.11.1",
55
55
  "eslint-plugin-prettier": "5.2.1",
56
56
  "get-stream": "6.0.1",
57
57
  "jest": "29.7.0",
58
- "nodemon": "3.1.4",
58
+ "nodemon": "3.1.7",
59
59
  "np": "8.0.4",
60
60
  "prettier": "3.3.3",
61
61
  "rxjs": "7.8.1",
package/readme.md CHANGED
@@ -34,7 +34,7 @@ xmldom is a javascript [ponyfill](https://ponyfill.com/) to provide the followin
34
34
  new XMLSerializer().serializeToString(node) => string
35
35
  ```
36
36
 
37
- The target runtimes `xmldom` supports are currently Node >= v10 (ES5) and Rhino ([not tested as part of CI](https://github.com/xmldom/xmldom/discussions/214)).
37
+ The target runtimes `xmldom` supports are currently Node >= v14.6 (and very likely any other [ES5 compatible runtime](https://compat-table.github.io/compat-table/es5/)).
38
38
 
39
39
  When deciding how to fix bugs or implement features, `xmldom` tries to stay as close as possible to the various [related specifications/standards](#specs).
40
40
  As indicated by the version starting with `0.`, this implementation is not feature complete and some implemented features differ from what the specifications describe.
@@ -99,7 +99,7 @@ import { DOMParser } from '@xmldom/xmldom'
99
99
  readonly class properties (aka `NodeType`),
100
100
  these can be accessed from any `Node` instance `node`:
101
101
  `if (node.nodeType === node.ELEMENT_NODE) {...`
102
-
102
+
103
103
  1. `ELEMENT_NODE` (`1`)
104
104
  2. `ATTRIBUTE_NODE` (`2`)
105
105
  3. `TEXT_NODE` (`3`)
@@ -112,14 +112,14 @@ import { DOMParser } from '@xmldom/xmldom'
112
112
  10. `DOCUMENT_TYPE_NODE` (`10`)
113
113
  11. `DOCUMENT_FRAGMENT_NODE` (`11`)
114
114
  12. `NOTATION_NODE` (`12`)
115
-
115
+
116
116
  attribute:
117
- - `nodeValue` | `prefix`
118
-
117
+ - `nodeValue` | `prefix` | `textContent`
118
+
119
119
  readonly attribute:
120
- - `nodeName` | `nodeType` | `parentNode` | `childNodes` | `firstChild` | `lastChild` | `previousSibling` | `nextSibling` | `attributes` | `ownerDocument` | `namespaceURI` | `localName`
121
-
122
- method:
120
+ - `nodeName` | `nodeType` | `parentNode` | `parentElement` | `childNodes` | `firstChild` | `lastChild` | `previousSibling` | `nextSibling` | `attributes` | `ownerDocument` | `namespaceURI` | `localName` | `isConnected` | `baseURI`
121
+
122
+ method:
123
123
  * `insertBefore(newChild, refChild)`
124
124
  * `replaceChild(newChild, oldChild)`
125
125
  * `removeChild(oldChild)`
@@ -127,6 +127,10 @@ import { DOMParser } from '@xmldom/xmldom'
127
127
  * `hasChildNodes()`
128
128
  * `cloneNode(deep)`
129
129
  * `normalize()`
130
+ * `contains(otherNode)`
131
+ * `getRootNode()`
132
+ * `isEqualNode(otherNode)`
133
+ * `isSameNode(otherNode)`
130
134
  * `isSupported(feature, version)`
131
135
  * `hasAttributes()`
132
136
  * [DOMException](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/ecma-script-binding.html)
@@ -149,7 +153,7 @@ import { DOMParser } from '@xmldom/xmldom'
149
153
  - `INVALID_MODIFICATION_ERR` (`13`)
150
154
  - `NAMESPACE_ERR` (`14`)
151
155
  - `INVALID_ACCESS_ERR` (`15`)
152
-
156
+
153
157
  attributes:
154
158
  - `code` with a value matching one of the above constants.
155
159
 
@@ -183,7 +187,7 @@ import { DOMParser } from '@xmldom/xmldom'
183
187
 
184
188
  * [DocumentFragment](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-B63ED1A3) : Node
185
189
  * [Element](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-745549614) : Node
186
-
190
+
187
191
  readonly attribute:
188
192
  - `tagName`
189
193
 
@@ -317,23 +321,23 @@ The original author claims that xmldom implements [DOM Level 2] in a "fully comp
317
321
  In the past, there have been multiple (even breaking) changes to align xmldom with the living standard,
318
322
  so if you find a difference that is not documented, any contribution to resolve the difference is very welcome (even just reporting it as an issue).
319
323
 
320
- xmldom implements the following interfaces (only the ones marked with `*` are currently exposed):
321
- - `Attr` *
324
+ xmldom implements the following interfaces:
325
+ - `Attr`
322
326
  - `CDATASection`
323
327
  - `CharacterData`
324
328
  - `Comment`
325
- - `Document` *
329
+ - `Document`
326
330
  - `DocumentFragment`
327
- - `DocumentType` *
328
- - `DOMException` *
329
- - `DOMImplementation` *
330
- - `Element` *
331
+ - `DocumentType`
332
+ - `DOMException`
333
+ - `DOMImplementation`
334
+ - `Element`
331
335
  - `Entity`
332
336
  - `EntityReference`
333
337
  - `LiveNodeList`
334
- - `NamedNodeMap` *
335
- - `Node` *
336
- - `NodeList` *
338
+ - `NamedNodeMap`
339
+ - `Node`
340
+ - `NodeList`
337
341
  - `Notation`
338
342
  - `ProcessingInstruction`
339
343
  - `Text`