@openplayerjs/ads 3.4.2 → 3.4.3

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/dist/index.js CHANGED
@@ -5720,6 +5720,11 @@ function requireGrammar () {
5720
5720
  // eslint-disable-next-line es5/no-unicode-code-point-escape
5721
5721
  Char = reg('[', chars(Char), '\\u{10000}-\\u{10FFFF}', ']');
5722
5722
  }
5723
+ // Negation of Char: matches any character that is NOT a valid XML 1.0 Char.
5724
+ // Derived directly from the Char character class above (after the unicode-support extension).
5725
+ // XML 1.0 Char production [2]: #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
5726
+ // @see https://www.w3.org/TR/xml/#NT-Char
5727
+ var InvalidChar = new RegExp('[^' + chars(Char) + ']', UNICODE_SUPPORT ? 'u' : '');
5723
5728
 
5724
5729
  var _SChar = /[\x20\x09\x0D\x0A]/;
5725
5730
  var SChar_s = chars(_SChar);
@@ -5981,6 +5986,12 @@ function requireGrammar () {
5981
5986
  regg(PUBLIC, S, '(?<PubidLiteral>', PubidLiteral, ')', S, '(?<SystemLiteral>', SystemLiteral, ')')
5982
5987
  )
5983
5988
  );
5989
+ // Full-string anchored matcher for requireWellFormed serializer checks
5990
+ // https://w3c.github.io/DOM-Parsing/#xml-serializing-a-document-node
5991
+ var PubidLiteral_match = reg('^', PubidLiteral, '$');
5992
+ // Full-string anchored matcher for requireWellFormed serializer checks
5993
+ // https://w3c.github.io/DOM-Parsing/#xml-serializing-a-document-node
5994
+ var SystemLiteral_match = reg('^', SystemLiteral, '$');
5984
5995
 
5985
5996
  // https://www.w3.org/TR/xml11/#NT-NDataDecl
5986
5997
  // `[76] NDataDecl ::= S 'NDATA' S Name` [VC: Notation Declared]
@@ -6104,6 +6115,7 @@ function requireGrammar () {
6104
6115
  grammar.PI = PI;
6105
6116
  grammar.PUBLIC = PUBLIC;
6106
6117
  grammar.PubidLiteral = PubidLiteral;
6118
+ grammar.PubidLiteral_match = PubidLiteral_match;
6107
6119
  grammar.QName = QName;
6108
6120
  grammar.QName_exact = QName_exact;
6109
6121
  grammar.QName_group = QName_group;
@@ -6112,6 +6124,8 @@ function requireGrammar () {
6112
6124
  grammar.S_OPT = S_OPT;
6113
6125
  grammar.SYSTEM = SYSTEM;
6114
6126
  grammar.SystemLiteral = SystemLiteral;
6127
+ grammar.SystemLiteral_match = SystemLiteral_match;
6128
+ grammar.InvalidChar = InvalidChar;
6115
6129
  grammar.UNICODE_REPLACEMENT_CHARACTER = UNICODE_REPLACEMENT_CHARACTER;
6116
6130
  grammar.UNICODE_SUPPORT = UNICODE_SUPPORT;
6117
6131
  grammar.XMLDecl = XMLDecl;
@@ -6454,14 +6468,31 @@ function requireDom () {
6454
6468
  /**
6455
6469
  * Returns a string representation of the NodeList.
6456
6470
  *
6457
- * @param {unknown} nodeFilter
6458
- * __A filter function? Not implemented according to the spec?__.
6471
+ * Accepts the same `options` object as `XMLSerializer.prototype.serializeToString`
6472
+ * (`requireWellFormed`, `splitCDATASections`, `nodeFilter`). Passing a function is treated as
6473
+ * a legacy `nodeFilter` for backward compatibility.
6474
+ *
6475
+ * @param {Object | function} [options]
6476
+ * @param {boolean} [options.requireWellFormed=false]
6477
+ * @param {boolean} [options.splitCDATASections=true]
6478
+ * @param {function} [options.nodeFilter]
6459
6479
  * @returns {string}
6460
- * A string representation of the NodeList.
6461
6480
  */
6462
- toString: function (nodeFilter) {
6481
+ toString: function (options) {
6482
+ var opts;
6483
+ if (typeof options === 'function') {
6484
+ opts = { requireWellFormed: false, splitCDATASections: true, nodeFilter: options };
6485
+ } else if (!!options) {
6486
+ opts = {
6487
+ requireWellFormed: !!options.requireWellFormed,
6488
+ splitCDATASections: options.splitCDATASections !== false,
6489
+ nodeFilter: options.nodeFilter || null,
6490
+ };
6491
+ } else {
6492
+ opts = { requireWellFormed: false, splitCDATASections: true, nodeFilter: null };
6493
+ }
6463
6494
  for (var buf = [], i = 0; i < this.length; i++) {
6464
- serializeToString(this[i], buf, nodeFilter);
6495
+ serializeToString(this[i], buf, null, opts);
6465
6496
  }
6466
6497
  return buf.join('');
6467
6498
  },
@@ -6990,11 +7021,21 @@ function requireDom () {
6990
7021
  * The {@link https://www.w3.org/TR/DOM-Level-3-Core/glossary.html#dt-qualifiedname qualified
6991
7022
  * name} of the document type to be created.
6992
7023
  * @param {string} [publicId]
6993
- * The external subset public identifier.
7024
+ * The external subset public identifier. Stored verbatim including surrounding quotes.
7025
+ * When serialized with `requireWellFormed: true`, the serializer throws `InvalidStateError`
7026
+ * if the value is non-empty and does not match the XML `PubidLiteral` production
7027
+ * (W3C DOM Parsing §3.2.1.3; XML 1.0 production [12]). Creation-time validation is not
7028
+ * enforced — deferred to a future breaking release.
6994
7029
  * @param {string} [systemId]
6995
- * The external subset system identifier.
7030
+ * The external subset system identifier. Stored verbatim including surrounding quotes.
7031
+ * When serialized with `requireWellFormed: true`, the serializer throws `InvalidStateError`
7032
+ * if the value is non-empty and does not match the XML `SystemLiteral` production
7033
+ * (W3C DOM Parsing §3.2.1.3; XML 1.0 production [11]). Creation-time validation is not
7034
+ * enforced — deferred to a future breaking release.
6996
7035
  * @param {string} [internalSubset]
6997
- * the internal subset or an empty string if it is not present
7036
+ * The internal subset or an empty string if it is not present. Stored verbatim.
7037
+ * When serialized with `requireWellFormed: true`, the serializer throws `InvalidStateError`
7038
+ * if the value contains `"]>"`. Creation-time validation is not enforced.
6998
7039
  * @returns {DocumentType}
6999
7040
  * A new {@link DocumentType} node with {@link Node#ownerDocument} set to null.
7000
7041
  * @throws {DOMException}
@@ -7238,56 +7279,68 @@ function requireDom () {
7238
7279
  /**
7239
7280
  * Checks whether the given node is equal to this node.
7240
7281
  *
7282
+ * Two nodes are equal when they have the same type, defining characteristics (for the type),
7283
+ * and the same childNodes. The comparison is iterative to avoid stack overflows on
7284
+ * deeply-nested trees. Attribute nodes of each Element pair are also pushed onto the stack
7285
+ * and compared the same way.
7286
+ *
7241
7287
  * @param {Node} [otherNode]
7288
+ * @returns {boolean}
7242
7289
  * @see https://dom.spec.whatwg.org/#concept-node-equals
7290
+ * @see ../docs/walk-dom.md.
7243
7291
  */
7244
7292
  isEqualNode: function (otherNode) {
7245
7293
  if (!otherNode) return false;
7246
7294
 
7247
- if (this.nodeType !== otherNode.nodeType) return false;
7295
+ // Use an explicit {node, other} pair stack to avoid call-stack overflow on deep trees.
7296
+ // walkDOM cannot be used here — parallel two-tree traversal requires pairing
7297
+ // corresponding nodes at each step across both trees simultaneously.
7298
+ var stack = [{ node: this, other: otherNode }];
7299
+ while (stack.length > 0) {
7300
+ var pair = stack.pop();
7301
+ var node = pair.node;
7302
+ var other = pair.other;
7248
7303
 
7249
- switch (this.nodeType) {
7250
- case this.DOCUMENT_TYPE_NODE:
7251
- if (this.name !== otherNode.name) return false;
7252
- if (this.publicId !== otherNode.publicId) return false;
7253
- if (this.systemId !== otherNode.systemId) return false;
7254
- break;
7255
- case this.ELEMENT_NODE:
7256
- if (this.namespaceURI !== otherNode.namespaceURI) return false;
7257
- if (this.prefix !== otherNode.prefix) return false;
7258
- if (this.localName !== otherNode.localName) return false;
7259
- if (this.attributes.length !== otherNode.attributes.length) return false;
7260
- for (var i = 0; i < this.attributes.length; i++) {
7261
- var attr = this.attributes.item(i);
7262
- if (!attr.isEqualNode(otherNode.getAttributeNodeNS(attr.namespaceURI, attr.localName))) {
7263
- return false;
7264
- }
7265
- }
7266
- break;
7267
- case this.ATTRIBUTE_NODE:
7268
- if (this.namespaceURI !== otherNode.namespaceURI) return false;
7269
- if (this.localName !== otherNode.localName) return false;
7270
- if (this.value !== otherNode.value) return false;
7304
+ if (node.nodeType !== other.nodeType) return false;
7271
7305
 
7272
- break;
7273
- case this.PROCESSING_INSTRUCTION_NODE:
7274
- if (this.target !== otherNode.target || this.data !== otherNode.data) {
7275
- return false;
7276
- }
7277
- break;
7278
- case this.TEXT_NODE:
7279
- case this.COMMENT_NODE:
7280
- if (this.data !== otherNode.data) return false;
7281
- break;
7282
- }
7306
+ switch (node.nodeType) {
7307
+ case node.DOCUMENT_TYPE_NODE:
7308
+ if (node.name !== other.name) return false;
7309
+ if (node.publicId !== other.publicId) return false;
7310
+ if (node.systemId !== other.systemId) return false;
7311
+ break;
7312
+ case node.ELEMENT_NODE:
7313
+ if (node.namespaceURI !== other.namespaceURI) return false;
7314
+ if (node.prefix !== other.prefix) return false;
7315
+ if (node.localName !== other.localName) return false;
7316
+ if (node.attributes.length !== other.attributes.length) return false;
7317
+ for (var i = 0; i < node.attributes.length; i++) {
7318
+ var attr = node.attributes.item(i);
7319
+ var otherAttr = other.getAttributeNodeNS(attr.namespaceURI, attr.localName);
7320
+ if (!otherAttr) return false;
7321
+ stack.push({ node: attr, other: otherAttr });
7322
+ }
7323
+ break;
7324
+ case node.ATTRIBUTE_NODE:
7325
+ if (node.namespaceURI !== other.namespaceURI) return false;
7326
+ if (node.localName !== other.localName) return false;
7327
+ if (node.value !== other.value) return false;
7328
+ break;
7329
+ case node.PROCESSING_INSTRUCTION_NODE:
7330
+ if (node.target !== other.target || node.data !== other.data) return false;
7331
+ break;
7332
+ case node.TEXT_NODE:
7333
+ case node.CDATA_SECTION_NODE:
7334
+ case node.COMMENT_NODE:
7335
+ if (node.data !== other.data) return false;
7336
+ break;
7337
+ }
7283
7338
 
7284
- if (this.childNodes.length !== otherNode.childNodes.length) {
7285
- return false;
7286
- }
7339
+ if (node.childNodes.length !== other.childNodes.length) return false;
7287
7340
 
7288
- for (var i = 0; i < this.childNodes.length; i++) {
7289
- if (!this.childNodes[i].isEqualNode(otherNode.childNodes[i])) {
7290
- return false;
7341
+ // Push children in reverse order so index 0 is processed first (LIFO).
7342
+ for (var i = node.childNodes.length - 1; i >= 0; i--) {
7343
+ stack.push({ node: node.childNodes[i], other: other.childNodes[i] });
7291
7344
  }
7292
7345
  }
7293
7346
 
@@ -7407,7 +7460,7 @@ function requireDom () {
7407
7460
  * is `TEXT_NODE`) into a single node with the combined data. It also removes any empty text
7408
7461
  * nodes.
7409
7462
  *
7410
- * This method operates recursively, so it also normalizes any and all descendent nodes within
7463
+ * This method iterativly traverses all child nodes to normalize all descendent nodes within
7411
7464
  * the subtree.
7412
7465
  *
7413
7466
  * @throws {DOMException}
@@ -7416,19 +7469,28 @@ function requireDom () {
7416
7469
  * @since Modified in DOM Level 2
7417
7470
  * @see {@link Node.removeChild}
7418
7471
  * @see {@link CharacterData.appendData}
7472
+ * @see ../docs/walk-dom.md.
7419
7473
  */
7420
7474
  normalize: function () {
7421
- var child = this.firstChild;
7422
- while (child) {
7423
- var next = child.nextSibling;
7424
- if (next && next.nodeType == TEXT_NODE && child.nodeType == TEXT_NODE) {
7425
- this.removeChild(next);
7426
- child.appendData(next.data);
7427
- } else {
7428
- child.normalize();
7429
- child = next;
7430
- }
7431
- }
7475
+ walkDOM(this, null, {
7476
+ enter: function (node) {
7477
+ // Merge adjacent text children of node before walkDOM schedules them.
7478
+ // walkDOM reads lastChild/previousSibling after enter returns, so the
7479
+ // surviving post-merge children are what it descends into.
7480
+ var child = node.firstChild;
7481
+ while (child) {
7482
+ var next = child.nextSibling;
7483
+ if (next !== null && next.nodeType === TEXT_NODE && child.nodeType === TEXT_NODE) {
7484
+ node.removeChild(next);
7485
+ child.appendData(next.data);
7486
+ // Do not advance child: re-check new nextSibling for another text run
7487
+ } else {
7488
+ child = next;
7489
+ }
7490
+ }
7491
+ return true; // descend into surviving children
7492
+ },
7493
+ });
7432
7494
  },
7433
7495
  /**
7434
7496
  * Checks whether the DOM implementation implements a specific feature and its version.
@@ -7645,24 +7707,112 @@ function requireDom () {
7645
7707
  copy(DocumentPosition, Node.prototype);
7646
7708
 
7647
7709
  /**
7648
- * @param callback
7649
- * Return true for continue,false for break.
7650
- * @returns
7651
- * boolean true: break visit;
7710
+ * Visits every node in the subtree rooted at `node` in depth-first pre-order.
7711
+ *
7712
+ * Delegates to {@link walkDOM} for traversal. The `callback` is called on each node;
7713
+ * if it returns a truthy value, traversal stops immediately.
7714
+ *
7715
+ * @param {Node} node
7716
+ * Root of the subtree to visit.
7717
+ * @param {function(Node): *} callback
7718
+ * Called for each node. A truthy return value stops traversal early.
7652
7719
  */
7653
7720
  function _visitNode(node, callback) {
7654
- if (callback(node)) {
7655
- return true;
7656
- }
7657
- if ((node = node.firstChild)) {
7658
- do {
7659
- if (_visitNode(node, callback)) {
7660
- return true;
7721
+ walkDOM(node, null, {
7722
+ enter: function (n) {
7723
+ return callback(n) ? walkDOM.STOP : true;
7724
+ },
7725
+ });
7726
+ }
7727
+
7728
+ /**
7729
+ * Depth-first pre/post-order DOM tree walker.
7730
+ *
7731
+ * Visits every node in the subtree rooted at `node`. For each node:
7732
+ *
7733
+ * 1. Calls `callbacks.enter(node, context)` before descending into the node's children. The
7734
+ * return value becomes the `context` passed to each child's `enter` call and to the matching
7735
+ * `exit` call.
7736
+ * 2. If `enter` returns `null` or `undefined`, the node's children are skipped;
7737
+ * sibling traversal continues normally.
7738
+ * 3. If `enter` returns `walkDOM.STOP`, the entire traversal is aborted immediately — no
7739
+ * further `enter` or `exit` calls are made.
7740
+ * 4. `lastChild` and `previousSibling` are read **after** `enter` returns, so `enter` may
7741
+ * safely modify the node's own child list before the walker descends. Modifying siblings of
7742
+ * the current node or any other part of the tree produces unpredictable results: nodes already
7743
+ * queued on the stack are visited regardless of DOM changes, and newly inserted nodes outside
7744
+ * the current child list are never visited.
7745
+ * 5. Calls `callbacks.exit(node, context)` (if provided) after all of a node's children have
7746
+ * been visited, passing the same `context` that `enter`
7747
+ * returned for that node.
7748
+ *
7749
+ * This implementation uses an explicit stack and does not recurse — it is safe on arbitrarily
7750
+ * deep trees.
7751
+ *
7752
+ * @param {Node} node
7753
+ * Root of the subtree to walk.
7754
+ * @param {*} context
7755
+ * Initial context value passed to the root node's `enter`.
7756
+ * @param {{ enter: function(Node, *): *, exit?: function(Node, *): void }} callbacks
7757
+ * @returns {void | walkDOM.STOP}
7758
+ * @see ../docs/walk-dom.md.
7759
+ */
7760
+ function walkDOM(node, context, callbacks) {
7761
+ // Each stack frame is {node, context, phase}:
7762
+ // walkDOM.ENTER — call enter, then push children
7763
+ // walkDOM.EXIT — call exit
7764
+ var stack = [{ node: node, context: context, phase: walkDOM.ENTER }];
7765
+ while (stack.length > 0) {
7766
+ var frame = stack.pop();
7767
+ if (frame.phase === walkDOM.ENTER) {
7768
+ var childContext = callbacks.enter(frame.node, frame.context);
7769
+ if (childContext === walkDOM.STOP) {
7770
+ return walkDOM.STOP;
7771
+ }
7772
+ // Push exit frame before children so it fires after all children are processed (Last In First Out)
7773
+ stack.push({ node: frame.node, context: childContext, phase: walkDOM.EXIT });
7774
+ if (childContext === null || childContext === undefined) {
7775
+ continue; // skip children
7776
+ }
7777
+ // lastChild is read after enter returns, so enter may modify the child list.
7778
+ var child = frame.node.lastChild;
7779
+ // Traverse from lastChild backwards so that pushing onto the stack
7780
+ // naturally yields firstChild on top (processed first).
7781
+ while (child) {
7782
+ stack.push({ node: child, context: childContext, phase: walkDOM.ENTER });
7783
+ child = child.previousSibling;
7784
+ }
7785
+ } else {
7786
+ // frame.phase === walkDOM.EXIT
7787
+ if (callbacks.exit) {
7788
+ callbacks.exit(frame.node, frame.context);
7661
7789
  }
7662
- } while ((node = node.nextSibling));
7790
+ }
7663
7791
  }
7664
7792
  }
7665
7793
 
7794
+ /**
7795
+ * Sentinel value returned from a `walkDOM` `enter` callback to abort the entire traversal
7796
+ * immediately.
7797
+ *
7798
+ * @type {symbol}
7799
+ */
7800
+ walkDOM.STOP = Symbol('walkDOM.STOP');
7801
+ /**
7802
+ * Phase constant for a stack frame that has not yet been visited.
7803
+ * The `enter` callback is called and children are scheduled.
7804
+ *
7805
+ * @type {number}
7806
+ */
7807
+ walkDOM.ENTER = 0;
7808
+ /**
7809
+ * Phase constant for a stack frame whose subtree has been fully visited.
7810
+ * The `exit` callback is called.
7811
+ *
7812
+ * @type {number}
7813
+ */
7814
+ walkDOM.EXIT = 1;
7815
+
7666
7816
  /**
7667
7817
  * @typedef DocumentOptions
7668
7818
  * @property {string} [contentType=MIME_TYPE.XML_APPLICATION]
@@ -8249,7 +8399,20 @@ function requireDom () {
8249
8399
  this.documentElement = newChild;
8250
8400
  }
8251
8401
  },
8252
- // Introduced in DOM Level 2:
8402
+ /**
8403
+ * Imports a node from another document into this document, creating a new copy owned by this
8404
+ * document. The source node and its subtree are not modified.
8405
+ *
8406
+ * @param {Node} importedNode
8407
+ * The node to import.
8408
+ * @param {boolean} deep
8409
+ * If true, the contents of the node are recursively imported.
8410
+ * If false, only the node itself (and its attributes, if it is an element) are imported.
8411
+ * @returns {Node}
8412
+ * Returns the newly created import of the node.
8413
+ * @see {@link importNode}
8414
+ * @see {@link https://dom.spec.whatwg.org/#dom-document-importnode}
8415
+ */
8253
8416
  importNode: function (importedNode, deep) {
8254
8417
  return importNode(this, importedNode, deep);
8255
8418
  },
@@ -8325,6 +8488,15 @@ function requireDom () {
8325
8488
  /**
8326
8489
  * @param {string} data
8327
8490
  * @returns {Comment}
8491
+ * @see https://dom.spec.whatwg.org/#dom-document-createcomment
8492
+ * @see https://www.w3.org/TR/xml/#NT-Comment XML 1.0 production [15]
8493
+ * @see https://www.w3.org/TR/DOM-Parsing/#dfn-concept-serialize-xml §3.2.1.3
8494
+ *
8495
+ * Note: no validation is performed at creation time. When the resulting document is
8496
+ * serialized with `requireWellFormed: true`, the serializer throws `InvalidStateError`
8497
+ * if the comment data contains `--` anywhere, ends with `-`, or contains characters
8498
+ * outside the XML Char production (W3C DOM Parsing §3.2.1.3). Without that option the
8499
+ * data is emitted verbatim.
8328
8500
  */
8329
8501
  createComment: function (data) {
8330
8502
  var node = new Comment(PDC);
@@ -8357,9 +8529,24 @@ function requireDom () {
8357
8529
  return node;
8358
8530
  },
8359
8531
  /**
8532
+ * Returns a ProcessingInstruction node whose target is target and data is data.
8533
+ *
8534
+ * __This behavior is slightly different from the in the specs__:
8535
+ * - it does not do any input validation on the arguments and doesn't throw
8536
+ * "InvalidCharacterError".
8537
+ *
8538
+ * Note: When the resulting document is serialized with `requireWellFormed: true`, the
8539
+ * serializer throws `InvalidStateError` if `.target` contains `:` or is an ASCII
8540
+ * case-insensitive match for `"xml"`, or if `.data` contains `?>` or characters outside the
8541
+ * XML Char production (W3C DOM Parsing §3.2.1.7). Without that option the data is emitted
8542
+ * verbatim.
8543
+ *
8360
8544
  * @param {string} target
8361
8545
  * @param {string} data
8362
8546
  * @returns {ProcessingInstruction}
8547
+ * @see https://developer.mozilla.org/docs/Web/API/Document/createProcessingInstruction
8548
+ * @see https://dom.spec.whatwg.org/#dom-document-createprocessinginstruction
8549
+ * @see https://www.w3.org/TR/DOM-Parsing/#dfn-concept-serialize-xml §3.2.1.7
8363
8550
  */
8364
8551
  createProcessingInstruction: function (target, data) {
8365
8552
  var node = new ProcessingInstruction(PDC);
@@ -8792,6 +8979,31 @@ function requireDom () {
8792
8979
  };
8793
8980
  _extends(CDATASection, Text);
8794
8981
 
8982
+ /**
8983
+ * @class DocumentType
8984
+ * @augments Node
8985
+ * @property {string} publicId
8986
+ * The external subset public identifier, stored verbatim (including surrounding quotes).
8987
+ * Declared `readonly` by the WHATWG DOM spec; xmldom does not enforce this constraint —
8988
+ * direct property writes succeed and the written value is serialized verbatim.
8989
+ * When serialized with `requireWellFormed: true`, the serializer validates the value against
8990
+ * the XML `PubidLiteral` production and throws `InvalidStateError` if it does not match.
8991
+ * @property {string} systemId
8992
+ * The external subset system identifier, stored verbatim (including surrounding quotes).
8993
+ * Declared `readonly` by the WHATWG DOM spec; xmldom does not enforce this constraint —
8994
+ * direct property writes succeed and the written value is serialized verbatim.
8995
+ * When serialized with `requireWellFormed: true`, the serializer validates the value against
8996
+ * the XML `SystemLiteral` production and throws `InvalidStateError` if it does not match.
8997
+ * @property {string} internalSubset
8998
+ * The internal subset string (the raw content between `[` and `]`), or an empty string.
8999
+ * Declared `readonly` by the WHATWG DOM spec; xmldom does not enforce this constraint —
9000
+ * direct property writes succeed and the written value is serialized verbatim.
9001
+ * When serialized with `requireWellFormed: true`, the serializer throws `InvalidStateError`
9002
+ * if the value contains `"]>"`.
9003
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/DocumentType MDN
9004
+ * @see https://dom.spec.whatwg.org/#interface-documenttype WHATWG DOM
9005
+ * @prettierignore
9006
+ */
8795
9007
  function DocumentType(symbol) {
8796
9008
  checkSymbol(symbol);
8797
9009
  }
@@ -8832,21 +9044,79 @@ function requireDom () {
8832
9044
  /**
8833
9045
  * Returns the result of serializing `node` to XML.
8834
9046
  *
8835
- * __This implementation differs from the specification:__ - CDATASection nodes whose data
8836
- * contains `]]>` are serialized by splitting the section at each `]]>` occurrence (following
8837
- * W3C DOM Level 3 Core `split-cdata-sections`
8838
- * default behaviour). A configurable option is not yet implemented.
9047
+ * When `options.requireWellFormed` is `true`, the serializer throws `InvalidStateError` for
9048
+ * content that would produce ill-formed XML (e.g. CDATASection data containing `"]]>"`, Text
9049
+ * data containing characters outside the XML Char production, or a Document with no
9050
+ * `documentElement`).
9051
+ *
9052
+ * When `options.splitCDATASections` is `false`, CDATASection data is emitted verbatim even
9053
+ * when it contains `"]]>"`. When `true` (the default), `"]]>"` sequences are split across
9054
+ * concatenated CDATA sections — this behavior is **deprecated** and will be removed in the
9055
+ * next breaking release. Callers should migrate to `{ requireWellFormed: true }`, which throws
9056
+ * `InvalidStateError` instead of transforming.
9057
+ *
9058
+ * __This implementation differs from the specification:__ - CDATASection serialization is not
9059
+ * specified by W3C DOM Parsing or WHATWG DOM Parsing (see
9060
+ * {@link https://github.com/w3c/DOM-Parsing/issues/38 w3c/DOM-Parsing#38}).
9061
+ * When `splitCDATASections` is `true` (the default), `"]]>"` sequences in CDATASection data
9062
+ * are split across concatenated CDATA sections — this mechanism is derived from DOM Level 3
9063
+ * Core and is **deprecated**. The split mechanics will be removed in the next breaking
9064
+ * release. Callers that rely on this behavior should migrate to `{ requireWellFormed: true }`.
9065
+ * - W3C DOM Parsing §3.2.1.1 requires well-formedness checks on Element `localName`s,
9066
+ * prefixes,
9067
+ * and attribute serialization (duplicate attributes, namespace declarations, attribute value
9068
+ * characters) when `requireWellFormed` is `true`. These checks are **not implemented** in this
9069
+ * release — see the tracking issue filed against the next breaking milestone.
8839
9070
  *
8840
9071
  * @param {Node} node
8841
- * @param {function} [nodeFilter]
9072
+ * @param {Object | function} [options]
9073
+ * Options object, or a legacy nodeFilter function (backward compatible).
9074
+ * @param {boolean} [options.requireWellFormed=false]
9075
+ * When `true`, throws `InvalidStateError` for content that would produce ill-formed XML.
9076
+ * @param {boolean} [options.splitCDATASections=true]
9077
+ * When `true` (default), splits `"]]>"` sequences in CDATASection data across concatenated
9078
+ * CDATA sections. **Deprecated** — will be removed in the next breaking release.
9079
+ * @param {function} [options.nodeFilter]
9080
+ * A filter function applied to each node before serialization.
8842
9081
  * @returns {string}
9082
+ * @throws {DOMException}
9083
+ * With name `InvalidStateError` when `requireWellFormed` is `true` and any of the following
9084
+ * conditions hold:
9085
+ * - CDATASection data contains `"]]>"`
9086
+ * - Text data contains characters outside the XML Char production
9087
+ * - a Comment node's data contains `--` anywhere or ends with `-`
9088
+ * - a ProcessingInstruction's target contains `:` or is an ASCII case-insensitive match for
9089
+ * `"xml"`, or its data contains `?>` or characters outside the XML Char production
9090
+ * - a DocumentType's `publicId` is non-empty and does not match the XML `PubidLiteral`
9091
+ * production (W3C DOM Parsing §3.2.1.3; XML 1.0 production [12])
9092
+ * - a DocumentType's `systemId` is non-empty and does not match the XML `SystemLiteral`
9093
+ * production (W3C DOM Parsing §3.2.1.3; XML 1.0 production [11])
9094
+ * - a DocumentType's `internalSubset` contains `"]>"`
9095
+ * - the Document has no `documentElement`
9096
+ * @see https://developer.mozilla.org/docs/Web/API/XMLSerializer/serializeToString
8843
9097
  * @see https://html.spec.whatwg.org/#dom-xmlserializer-serializetostring
9098
+ * @see https://github.com/w3c/DOM-Parsing/issues/84
9099
+ * @prettierignore
8844
9100
  */
8845
- XMLSerializer.prototype.serializeToString = function (node, nodeFilter) {
8846
- return nodeSerializeToString.call(node, nodeFilter);
9101
+ XMLSerializer.prototype.serializeToString = function (node, options) {
9102
+ return nodeSerializeToString.call(node, options);
8847
9103
  };
8848
9104
  Node.prototype.toString = nodeSerializeToString;
8849
- function nodeSerializeToString(nodeFilter) {
9105
+ function nodeSerializeToString(options) {
9106
+ // Normalize the user-supplied options into a single internal opts object so that the
9107
+ // internal serializer always works with a consistent shape rather than positional flags.
9108
+ var opts;
9109
+ if (typeof options === 'function') {
9110
+ opts = { requireWellFormed: false, splitCDATASections: true, nodeFilter: options };
9111
+ } else if (options != null) {
9112
+ opts = {
9113
+ requireWellFormed: !!options.requireWellFormed,
9114
+ splitCDATASections: options.splitCDATASections !== false,
9115
+ nodeFilter: options.nodeFilter || null,
9116
+ };
9117
+ } else {
9118
+ opts = { requireWellFormed: false, splitCDATASections: true, nodeFilter: null };
9119
+ }
8850
9120
  var buf = [];
8851
9121
  var refNode = (this.nodeType === DOCUMENT_NODE && this.documentElement) || this;
8852
9122
  var prefix = refNode.prefix;
@@ -8861,7 +9131,7 @@ function requireDom () {
8861
9131
  ];
8862
9132
  }
8863
9133
  }
8864
- serializeToString(this, buf, nodeFilter, visibleNamespaces);
9134
+ serializeToString(this, buf, visibleNamespaces, opts);
8865
9135
  return buf.join('');
8866
9136
  }
8867
9137
 
@@ -8911,235 +9181,317 @@ function requireDom () {
8911
9181
  buf.push(' ', qualifiedName, '="', value.replace(/[<>&"\t\n\r]/g, _xmlEncoder), '"');
8912
9182
  }
8913
9183
 
8914
- function serializeToString(node, buf, nodeFilter, visibleNamespaces) {
9184
+ function serializeToString(node, buf, visibleNamespaces, opts) {
8915
9185
  if (!visibleNamespaces) {
8916
9186
  visibleNamespaces = [];
8917
9187
  }
9188
+ var nodeFilter = opts.nodeFilter;
9189
+ var requireWellFormed = opts.requireWellFormed;
9190
+ var splitCDATASections = opts.splitCDATASections;
8918
9191
  var doc = node.nodeType === DOCUMENT_NODE ? node : node.ownerDocument;
8919
9192
  var isHTML = doc.type === 'html';
8920
9193
 
8921
- if (nodeFilter) {
8922
- node = nodeFilter(node);
8923
- if (node) {
8924
- if (typeof node == 'string') {
8925
- buf.push(node);
8926
- return;
8927
- }
8928
- } else {
8929
- return;
8930
- }
8931
- //buf.sort.apply(attrs, attributeSorter);
8932
- }
8933
-
8934
- switch (node.nodeType) {
8935
- case ELEMENT_NODE:
8936
- var attrs = node.attributes;
8937
- var len = attrs.length;
8938
- var child = node.firstChild;
8939
- var nodeName = node.tagName;
8940
-
8941
- var prefixedNodeName = nodeName;
8942
- if (!isHTML && !node.prefix && node.namespaceURI) {
8943
- var defaultNS;
8944
- // lookup current default ns from `xmlns` attribute
8945
- for (var ai = 0; ai < attrs.length; ai++) {
8946
- if (attrs.item(ai).name === 'xmlns') {
8947
- defaultNS = attrs.item(ai).value;
8948
- break;
8949
- }
8950
- }
8951
- if (!defaultNS) {
8952
- // lookup current default ns in visibleNamespaces
8953
- for (var nsi = visibleNamespaces.length - 1; nsi >= 0; nsi--) {
8954
- var namespace = visibleNamespaces[nsi];
8955
- if (namespace.prefix === '' && namespace.namespace === node.namespaceURI) {
8956
- defaultNS = namespace.namespace;
8957
- break;
9194
+ walkDOM(
9195
+ node,
9196
+ { ns: visibleNamespaces },
9197
+ {
9198
+ enter: function (n, ctx) {
9199
+ var namespaces = ctx.ns;
9200
+
9201
+ if (nodeFilter) {
9202
+ n = nodeFilter(n);
9203
+ if (n) {
9204
+ if (typeof n == 'string') {
9205
+ buf.push(n);
9206
+ return null;
8958
9207
  }
9208
+ } else {
9209
+ return null;
8959
9210
  }
8960
9211
  }
8961
- if (defaultNS !== node.namespaceURI) {
8962
- for (var nsi = visibleNamespaces.length - 1; nsi >= 0; nsi--) {
8963
- var namespace = visibleNamespaces[nsi];
8964
- if (namespace.namespace === node.namespaceURI) {
8965
- if (namespace.prefix) {
8966
- prefixedNodeName = namespace.prefix + ':' + nodeName;
9212
+
9213
+ switch (n.nodeType) {
9214
+ case ELEMENT_NODE:
9215
+ var attrs = n.attributes;
9216
+ var len = attrs.length;
9217
+ var nodeName = n.tagName;
9218
+
9219
+ var prefixedNodeName = nodeName;
9220
+ if (!isHTML && !n.prefix && n.namespaceURI) {
9221
+ var defaultNS;
9222
+ // lookup current default ns from `xmlns` attribute
9223
+ for (var ai = 0; ai < attrs.length; ai++) {
9224
+ if (attrs.item(ai).name === 'xmlns') {
9225
+ defaultNS = attrs.item(ai).value;
9226
+ break;
9227
+ }
9228
+ }
9229
+ if (!defaultNS) {
9230
+ // lookup current default ns in visibleNamespaces
9231
+ for (var nsi = namespaces.length - 1; nsi >= 0; nsi--) {
9232
+ var nsEntry = namespaces[nsi];
9233
+ if (nsEntry.prefix === '' && nsEntry.namespace === n.namespaceURI) {
9234
+ defaultNS = nsEntry.namespace;
9235
+ break;
9236
+ }
9237
+ }
9238
+ }
9239
+ if (defaultNS !== n.namespaceURI) {
9240
+ for (var nsi = namespaces.length - 1; nsi >= 0; nsi--) {
9241
+ var nsEntry = namespaces[nsi];
9242
+ if (nsEntry.namespace === n.namespaceURI) {
9243
+ if (nsEntry.prefix) {
9244
+ prefixedNodeName = nsEntry.prefix + ':' + nodeName;
9245
+ }
9246
+ break;
9247
+ }
9248
+ }
8967
9249
  }
8968
- break;
8969
9250
  }
8970
- }
8971
- }
8972
- }
8973
9251
 
8974
- buf.push('<', prefixedNodeName);
9252
+ buf.push('<', prefixedNodeName);
8975
9253
 
8976
- for (var i = 0; i < len; i++) {
8977
- // add namespaces for attributes
8978
- var attr = attrs.item(i);
8979
- if (attr.prefix == 'xmlns') {
8980
- visibleNamespaces.push({
8981
- prefix: attr.localName,
8982
- namespace: attr.value,
8983
- });
8984
- } else if (attr.nodeName == 'xmlns') {
8985
- visibleNamespaces.push({ prefix: '', namespace: attr.value });
8986
- }
8987
- }
9254
+ // Build a fresh namespace snapshot for this element's children.
9255
+ // The slice prevents sibling elements from inheriting each other's declarations.
9256
+ var childNamespaces = namespaces.slice();
8988
9257
 
8989
- for (var i = 0; i < len; i++) {
8990
- var attr = attrs.item(i);
8991
- if (needNamespaceDefine(attr, isHTML, visibleNamespaces)) {
8992
- var prefix = attr.prefix || '';
8993
- var uri = attr.namespaceURI;
8994
- addSerializedAttribute(buf, prefix ? 'xmlns:' + prefix : 'xmlns', uri);
8995
- visibleNamespaces.push({ prefix: prefix, namespace: uri });
8996
- }
8997
- serializeToString(attr, buf, nodeFilter, visibleNamespaces);
8998
- }
9258
+ for (var i = 0; i < len; i++) {
9259
+ // add namespaces for attributes
9260
+ var attr = attrs.item(i);
9261
+ if (attr.prefix == 'xmlns') {
9262
+ childNamespaces.push({
9263
+ prefix: attr.localName,
9264
+ namespace: attr.value,
9265
+ });
9266
+ } else if (attr.nodeName == 'xmlns') {
9267
+ childNamespaces.push({ prefix: '', namespace: attr.value });
9268
+ }
9269
+ }
8999
9270
 
9000
- // add namespace for current node
9001
- if (nodeName === prefixedNodeName && needNamespaceDefine(node, isHTML, visibleNamespaces)) {
9002
- var prefix = node.prefix || '';
9003
- var uri = node.namespaceURI;
9004
- addSerializedAttribute(buf, prefix ? 'xmlns:' + prefix : 'xmlns', uri);
9005
- visibleNamespaces.push({ prefix: prefix, namespace: uri });
9006
- }
9007
- // in XML elements can be closed when they have no children
9008
- var canCloseTag = !child;
9009
- if (canCloseTag && (isHTML || node.namespaceURI === NAMESPACE.HTML)) {
9010
- // in HTML (doc or ns) only void elements can be closed right away
9011
- canCloseTag = isHTMLVoidElement(nodeName);
9012
- }
9013
- if (canCloseTag) {
9014
- buf.push('/>');
9015
- } else {
9016
- buf.push('>');
9017
- //if is cdata child node
9018
- if (isHTML && isHTMLRawTextElement(nodeName)) {
9019
- while (child) {
9020
- if (child.data) {
9021
- buf.push(child.data);
9271
+ for (var i = 0; i < len; i++) {
9272
+ var attr = attrs.item(i);
9273
+ if (needNamespaceDefine(attr, isHTML, childNamespaces)) {
9274
+ var attrPrefix = attr.prefix || '';
9275
+ var uri = attr.namespaceURI;
9276
+ addSerializedAttribute(buf, attrPrefix ? 'xmlns:' + attrPrefix : 'xmlns', uri);
9277
+ childNamespaces.push({ prefix: attrPrefix, namespace: uri });
9278
+ }
9279
+ // Apply nodeFilter and serialize the attribute.
9280
+ var filteredAttr = nodeFilter ? nodeFilter(attr) : attr;
9281
+ if (filteredAttr) {
9282
+ if (typeof filteredAttr === 'string') {
9283
+ buf.push(filteredAttr);
9284
+ } else {
9285
+ addSerializedAttribute(buf, filteredAttr.name, filteredAttr.value);
9286
+ }
9287
+ }
9288
+ }
9289
+
9290
+ // add namespace for current node
9291
+ if (nodeName === prefixedNodeName && needNamespaceDefine(n, isHTML, childNamespaces)) {
9292
+ var nodePrefix = n.prefix || '';
9293
+ var uri = n.namespaceURI;
9294
+ addSerializedAttribute(buf, nodePrefix ? 'xmlns:' + nodePrefix : 'xmlns', uri);
9295
+ childNamespaces.push({ prefix: nodePrefix, namespace: uri });
9296
+ }
9297
+
9298
+ // in XML elements can be closed when they have no children
9299
+ var canCloseTag = !n.firstChild;
9300
+ if (canCloseTag && (isHTML || n.namespaceURI === NAMESPACE.HTML)) {
9301
+ // in HTML (doc or ns) only void elements can be closed right away
9302
+ canCloseTag = isHTMLVoidElement(nodeName);
9303
+ }
9304
+ if (canCloseTag) {
9305
+ buf.push('/>');
9306
+ // Self-closing: no children and no closing tag needed from exit.
9307
+ return null;
9308
+ }
9309
+
9310
+ buf.push('>');
9311
+
9312
+ // HTML raw text elements: serialize children as raw data without further descent.
9313
+ if (isHTML && isHTMLRawTextElement(nodeName)) {
9314
+ var child = n.firstChild;
9315
+ while (child) {
9316
+ if (child.data) {
9317
+ buf.push(child.data);
9318
+ } else {
9319
+ serializeToString(child, buf, childNamespaces.slice(), opts);
9320
+ }
9321
+ child = child.nextSibling;
9322
+ }
9323
+ buf.push('</', prefixedNodeName, '>');
9324
+ // Children handled manually above; prevent walkDOM from also traversing them.
9325
+ return null;
9326
+ }
9327
+
9328
+ // Return child context so walkDOM descends; exit will emit the closing tag.
9329
+ return { ns: childNamespaces, tag: prefixedNodeName };
9330
+ case DOCUMENT_NODE:
9331
+ case DOCUMENT_FRAGMENT_NODE:
9332
+ if (requireWellFormed && n.nodeType === DOCUMENT_NODE && n.documentElement == null) {
9333
+ throw new DOMException('The Document has no documentElement', DOMExceptionName.InvalidStateError);
9334
+ }
9335
+ // Pass namespaces through; each child element will slice independently.
9336
+ return { ns: namespaces };
9337
+ case ATTRIBUTE_NODE:
9338
+ addSerializedAttribute(buf, n.name, n.value);
9339
+ return null;
9340
+ case TEXT_NODE:
9341
+ /*
9342
+ * The ampersand character (&) and the left angle bracket (<) must not appear in their literal form,
9343
+ * except when used as markup delimiters, or within a comment, a processing instruction,
9344
+ * or a CDATA section.
9345
+ * If they are needed elsewhere, they must be escaped using either numeric character
9346
+ * references or the strings `&amp;` and `&lt;` respectively.
9347
+ * The right angle bracket (>) may be represented using the string " &gt; ",
9348
+ * and must, for compatibility, be escaped using either `&gt;`,
9349
+ * or a character reference when it appears in the string `]]>` in content,
9350
+ * when that string is not marking the end of a CDATA section.
9351
+ *
9352
+ * In the content of elements, character data is any string of characters which does not
9353
+ * contain the start-delimiter of any markup and does not include the CDATA-section-close
9354
+ * delimiter, `]]>`.
9355
+ *
9356
+ * @see https://www.w3.org/TR/xml/#NT-CharData
9357
+ * @see https://w3c.github.io/DOM-Parsing/#xml-serializing-a-text-node
9358
+ */
9359
+ if (requireWellFormed && g.InvalidChar.test(n.data)) {
9360
+ throw new DOMException(
9361
+ 'The Text node data contains characters outside the XML Char production',
9362
+ DOMExceptionName.InvalidStateError
9363
+ );
9364
+ }
9365
+ buf.push(n.data.replace(/[<&>]/g, _xmlEncoder));
9366
+ return null;
9367
+ case CDATA_SECTION_NODE:
9368
+ if (requireWellFormed && n.data.indexOf(']]>') !== -1) {
9369
+ throw new DOMException('The CDATASection data contains "]]>"', DOMExceptionName.InvalidStateError);
9370
+ }
9371
+ if (splitCDATASections) {
9372
+ buf.push(g.CDATA_START, n.data.replace(/]]>/g, ']]]]><![CDATA[>'), g.CDATA_END);
9022
9373
  } else {
9023
- serializeToString(child, buf, nodeFilter, visibleNamespaces.slice());
9374
+ buf.push(g.CDATA_START, n.data, g.CDATA_END);
9024
9375
  }
9025
- child = child.nextSibling;
9026
- }
9027
- } else {
9028
- while (child) {
9029
- serializeToString(child, buf, nodeFilter, visibleNamespaces.slice());
9030
- child = child.nextSibling;
9031
- }
9376
+ return null;
9377
+ case COMMENT_NODE:
9378
+ if (requireWellFormed) {
9379
+ if (g.InvalidChar.test(n.data)) {
9380
+ throw new DOMException(
9381
+ 'The comment node data contains characters outside the XML Char production',
9382
+ DOMExceptionName.InvalidStateError
9383
+ );
9384
+ }
9385
+ if (n.data.indexOf('--') !== -1 || n.data[n.data.length - 1] === '-') {
9386
+ throw new DOMException(
9387
+ 'The comment node data contains "--" or ends with "-"',
9388
+ DOMExceptionName.InvalidStateError
9389
+ );
9390
+ }
9391
+ }
9392
+ buf.push(g.COMMENT_START, n.data, g.COMMENT_END);
9393
+ return null;
9394
+ case DOCUMENT_TYPE_NODE:
9395
+ var pubid = n.publicId;
9396
+ var sysid = n.systemId;
9397
+ if (requireWellFormed) {
9398
+ if (pubid && !g.PubidLiteral_match.test(pubid)) {
9399
+ throw new DOMException('DocumentType publicId is not a valid PubidLiteral', DOMExceptionName.InvalidStateError);
9400
+ }
9401
+ if (sysid && sysid !== '.' && !g.SystemLiteral_match.test(sysid)) {
9402
+ throw new DOMException('DocumentType systemId is not a valid SystemLiteral', DOMExceptionName.InvalidStateError);
9403
+ }
9404
+ if (n.internalSubset && n.internalSubset.indexOf(']>') !== -1) {
9405
+ throw new DOMException('DocumentType internalSubset contains "]>"', DOMExceptionName.InvalidStateError);
9406
+ }
9407
+ }
9408
+ buf.push(g.DOCTYPE_DECL_START, ' ', n.name);
9409
+ if (pubid) {
9410
+ buf.push(' ', g.PUBLIC, ' ', pubid);
9411
+ if (sysid && sysid !== '.') {
9412
+ buf.push(' ', sysid);
9413
+ }
9414
+ } else if (sysid && sysid !== '.') {
9415
+ buf.push(' ', g.SYSTEM, ' ', sysid);
9416
+ }
9417
+ if (n.internalSubset) {
9418
+ buf.push(' [', n.internalSubset, ']');
9419
+ }
9420
+ buf.push('>');
9421
+ return null;
9422
+ case PROCESSING_INSTRUCTION_NODE:
9423
+ if (requireWellFormed) {
9424
+ if (n.target.indexOf(':') !== -1 || n.target.toLowerCase() === 'xml') {
9425
+ throw new DOMException('The ProcessingInstruction target is not well-formed', DOMExceptionName.InvalidStateError);
9426
+ }
9427
+ if (g.InvalidChar.test(n.data)) {
9428
+ throw new DOMException(
9429
+ 'The ProcessingInstruction data contains characters outside the XML Char production',
9430
+ DOMExceptionName.InvalidStateError
9431
+ );
9432
+ }
9433
+ if (n.data.indexOf('?>') !== -1) {
9434
+ throw new DOMException('The ProcessingInstruction data contains "?>"', DOMExceptionName.InvalidStateError);
9435
+ }
9436
+ }
9437
+ buf.push('<?', n.target, ' ', n.data, '?>');
9438
+ return null;
9439
+ case ENTITY_REFERENCE_NODE:
9440
+ buf.push('&', n.nodeName, ';');
9441
+ return null;
9442
+ //case ENTITY_NODE:
9443
+ //case NOTATION_NODE:
9444
+ default:
9445
+ buf.push('??', n.nodeName);
9446
+ return null;
9032
9447
  }
9033
- buf.push('</', prefixedNodeName, '>');
9034
- }
9035
- // remove added visible namespaces
9036
- //visibleNamespaces.length = startVisibleNamespaces;
9037
- return;
9038
- case DOCUMENT_NODE:
9039
- case DOCUMENT_FRAGMENT_NODE:
9040
- var child = node.firstChild;
9041
- while (child) {
9042
- serializeToString(child, buf, nodeFilter, visibleNamespaces.slice());
9043
- child = child.nextSibling;
9044
- }
9045
- return;
9046
- case ATTRIBUTE_NODE:
9047
- return addSerializedAttribute(buf, node.name, node.value);
9048
- case TEXT_NODE:
9049
- /*
9050
- * The ampersand character (&) and the left angle bracket (<) must not appear in their literal form,
9051
- * except when used as markup delimiters, or within a comment, a processing instruction,
9052
- * or a CDATA section.
9053
- * If they are needed elsewhere, they must be escaped using either numeric character
9054
- * references or the strings `&amp;` and `&lt;` respectively.
9055
- * The right angle bracket (>) may be represented using the string " &gt; ",
9056
- * and must, for compatibility, be escaped using either `&gt;`,
9057
- * or a character reference when it appears in the string `]]>` in content,
9058
- * when that string is not marking the end of a CDATA section.
9059
- *
9060
- * In the content of elements, character data is any string of characters which does not
9061
- * contain the start-delimiter of any markup and does not include the CDATA-section-close
9062
- * delimiter, `]]>`.
9063
- *
9064
- * @see https://www.w3.org/TR/xml/#NT-CharData
9065
- * @see https://w3c.github.io/DOM-Parsing/#xml-serializing-a-text-node
9066
- */
9067
- return buf.push(node.data.replace(/[<&>]/g, _xmlEncoder));
9068
- case CDATA_SECTION_NODE:
9069
- return buf.push(g.CDATA_START, node.data.replace(/]]>/g, ']]]]><![CDATA[>'), g.CDATA_END);
9070
- case COMMENT_NODE:
9071
- return buf.push(g.COMMENT_START, node.data, g.COMMENT_END);
9072
- case DOCUMENT_TYPE_NODE:
9073
- var pubid = node.publicId;
9074
- var sysid = node.systemId;
9075
- buf.push(g.DOCTYPE_DECL_START, ' ', node.name);
9076
- if (pubid) {
9077
- buf.push(' ', g.PUBLIC, ' ', pubid);
9078
- if (sysid && sysid !== '.') {
9079
- buf.push(' ', sysid);
9448
+ },
9449
+ exit: function (n, childCtx) {
9450
+ // Emit the closing tag for elements that were opened (not self-closed, not raw text).
9451
+ if (childCtx && childCtx.tag) {
9452
+ buf.push('</', childCtx.tag, '>');
9080
9453
  }
9081
- } else if (sysid && sysid !== '.') {
9082
- buf.push(' ', g.SYSTEM, ' ', sysid);
9083
- }
9084
- if (node.internalSubset) {
9085
- buf.push(' [', node.internalSubset, ']');
9086
- }
9087
- buf.push('>');
9088
- return;
9089
- case PROCESSING_INSTRUCTION_NODE:
9090
- return buf.push('<?', node.target, ' ', node.data, '?>');
9091
- case ENTITY_REFERENCE_NODE:
9092
- return buf.push('&', node.nodeName, ';');
9093
- //case ENTITY_NODE:
9094
- //case NOTATION_NODE:
9095
- default:
9096
- buf.push('??', node.nodeName);
9097
- }
9454
+ },
9455
+ }
9456
+ );
9098
9457
  }
9458
+ /**
9459
+ * Imports a node from a different document into `doc`, creating a new copy.
9460
+ * Delegates to {@link walkDOM} for traversal. Each node in the subtree is shallow-cloned,
9461
+ * stamped with `doc` as its `ownerDocument`, and detached (`parentNode` set to `null`).
9462
+ * Children are imported recursively when `deep` is `true`; for {@link Attr} nodes `deep` is
9463
+ * always forced to `true`
9464
+ * because an attribute's value lives in a child text node.
9465
+ *
9466
+ * @param {Document} doc
9467
+ * The document that will own the imported node.
9468
+ * @param {Node} node
9469
+ * The node to import.
9470
+ * @param {boolean} deep
9471
+ * If `true`, descendants are imported recursively.
9472
+ * @returns {Node}
9473
+ * The newly imported node, now owned by `doc`.
9474
+ */
9099
9475
  function importNode(doc, node, deep) {
9100
- var node2;
9101
- switch (node.nodeType) {
9102
- case ELEMENT_NODE:
9103
- node2 = node.cloneNode(false);
9104
- node2.ownerDocument = doc;
9105
- //var attrs = node2.attributes;
9106
- //var len = attrs.length;
9107
- //for(var i=0;i<len;i++){
9108
- //node2.setAttributeNodeNS(importNode(doc,attrs.item(i),deep));
9109
- //}
9110
- case DOCUMENT_FRAGMENT_NODE:
9111
- break;
9112
- case ATTRIBUTE_NODE:
9113
- deep = true;
9114
- break;
9115
- //case ENTITY_REFERENCE_NODE:
9116
- //case PROCESSING_INSTRUCTION_NODE:
9117
- ////case TEXT_NODE:
9118
- //case CDATA_SECTION_NODE:
9119
- //case COMMENT_NODE:
9120
- // deep = false;
9121
- // break;
9122
- //case DOCUMENT_NODE:
9123
- //case DOCUMENT_TYPE_NODE:
9124
- //cannot be imported.
9125
- //case ENTITY_NODE:
9126
- //case NOTATION_NODE:
9127
- //can not hit in level3
9128
- //default:throw e;
9129
- }
9130
- if (!node2) {
9131
- node2 = node.cloneNode(false); //false
9132
- }
9133
- node2.ownerDocument = doc;
9134
- node2.parentNode = null;
9135
- if (deep) {
9136
- var child = node.firstChild;
9137
- while (child) {
9138
- node2.appendChild(importNode(doc, child, deep));
9139
- child = child.nextSibling;
9140
- }
9141
- }
9142
- return node2;
9476
+ var destRoot;
9477
+ walkDOM(node, null, {
9478
+ enter: function (srcNode, destParent) {
9479
+ // Shallow-clone the node and stamp it into the target document.
9480
+ var destNode = srcNode.cloneNode(false);
9481
+ destNode.ownerDocument = doc;
9482
+ destNode.parentNode = null;
9483
+ // capture as the root of the imported subtree or attach to parent.
9484
+ if (destParent === null) {
9485
+ destRoot = destNode;
9486
+ } else {
9487
+ destParent.appendChild(destNode);
9488
+ }
9489
+ // ATTRIBUTE_NODE must always be imported deeply: its value lives in a child text node.
9490
+ var shouldDeep = srcNode.nodeType === ATTRIBUTE_NODE || deep;
9491
+ return shouldDeep ? destNode : null;
9492
+ },
9493
+ });
9494
+ return destRoot;
9143
9495
  }
9144
9496
 
9145
9497
  /**
@@ -9159,42 +9511,55 @@ function requireDom () {
9159
9511
  * potentially invoked in this function) do not meet their specific constraints.
9160
9512
  */
9161
9513
  function cloneNode(doc, node, deep) {
9162
- var node2 = new node.constructor(PDC);
9163
- for (var n in node) {
9164
- if (hasOwn(node, n)) {
9165
- var v = node[n];
9166
- if (typeof v != 'object') {
9167
- if (v != node2[n]) {
9168
- node2[n] = v;
9514
+ var destRoot;
9515
+ walkDOM(node, null, {
9516
+ enter: function (srcNode, destParent) {
9517
+ // 1. Create a blank node of the same type and copy all scalar own properties.
9518
+ var destNode = new srcNode.constructor(PDC);
9519
+ for (var n in srcNode) {
9520
+ if (hasOwn(srcNode, n)) {
9521
+ var v = srcNode[n];
9522
+ if (typeof v != 'object') {
9523
+ if (v != destNode[n]) {
9524
+ destNode[n] = v;
9525
+ }
9526
+ }
9169
9527
  }
9170
9528
  }
9171
- }
9172
- }
9173
- if (node.childNodes) {
9174
- node2.childNodes = new NodeList();
9175
- }
9176
- node2.ownerDocument = doc;
9177
- switch (node2.nodeType) {
9178
- case ELEMENT_NODE:
9179
- var attrs = node.attributes;
9180
- var attrs2 = (node2.attributes = new NamedNodeMap());
9181
- var len = attrs.length;
9182
- attrs2._ownerElement = node2;
9183
- for (var i = 0; i < len; i++) {
9184
- node2.setAttributeNode(cloneNode(doc, attrs.item(i), true));
9529
+ if (srcNode.childNodes) {
9530
+ destNode.childNodes = new NodeList();
9185
9531
  }
9186
- break;
9187
- case ATTRIBUTE_NODE:
9188
- deep = true;
9189
- }
9190
- if (deep) {
9191
- var child = node.firstChild;
9192
- while (child) {
9193
- node2.appendChild(cloneNode(doc, child, deep));
9194
- child = child.nextSibling;
9195
- }
9196
- }
9197
- return node2;
9532
+ destNode.ownerDocument = doc;
9533
+ // 2. Handle node-type-specific setup.
9534
+ // Attributes are not DOM children, so they are cloned inline here
9535
+ // rather than by walkDOM descent.
9536
+ // ATTRIBUTE_NODE forces deep=true so its own children are walked.
9537
+ var shouldDeep = deep;
9538
+ switch (destNode.nodeType) {
9539
+ case ELEMENT_NODE:
9540
+ var attrs = srcNode.attributes;
9541
+ var attrs2 = (destNode.attributes = new NamedNodeMap());
9542
+ var len = attrs.length;
9543
+ attrs2._ownerElement = destNode;
9544
+ for (var i = 0; i < len; i++) {
9545
+ destNode.setAttributeNode(cloneNode(doc, attrs.item(i), true));
9546
+ }
9547
+ break;
9548
+ case ATTRIBUTE_NODE:
9549
+ shouldDeep = true;
9550
+ }
9551
+ // 3. Attach to parent, or capture as the root of the cloned subtree.
9552
+ if (destParent !== null) {
9553
+ destParent.appendChild(destNode);
9554
+ } else {
9555
+ destRoot = destNode;
9556
+ }
9557
+ // 4. Return destNode as the context for children (causes walkDOM to descend),
9558
+ // or null to skip children (shallow clone).
9559
+ return shouldDeep ? destNode : null;
9560
+ },
9561
+ });
9562
+ return destRoot;
9198
9563
  }
9199
9564
 
9200
9565
  function __set__(object, key, value) {
@@ -9226,9 +9591,37 @@ function requireDom () {
9226
9591
  },
9227
9592
  });
9228
9593
 
9594
+ /**
9595
+ * The text content of this node and its descendants.
9596
+ *
9597
+ * For {@link Element} and {@link DocumentFragment} nodes, returns the concatenation of the
9598
+ * `nodeValue` of every descendant text node, excluding processing instruction and comment
9599
+ * nodes. For all other node types, returns `nodeValue`.
9600
+ *
9601
+ * Setting `textContent` on an element or document fragment replaces all child nodes with a
9602
+ * single text node; on other nodes it sets `data`, `value`, and `nodeValue` directly.
9603
+ *
9604
+ * @type {string | null}
9605
+ * @see {@link https://dom.spec.whatwg.org/#dom-node-textcontent}
9606
+ */
9229
9607
  Object.defineProperty(Node.prototype, 'textContent', {
9230
9608
  get: function () {
9231
- return getTextContent(this);
9609
+ if (this.nodeType === ELEMENT_NODE || this.nodeType === DOCUMENT_FRAGMENT_NODE) {
9610
+ var buf = [];
9611
+ walkDOM(this, null, {
9612
+ enter: function (n) {
9613
+ if (n.nodeType === ELEMENT_NODE || n.nodeType === DOCUMENT_FRAGMENT_NODE) {
9614
+ return true; // enter children
9615
+ }
9616
+ if (n.nodeType === PROCESSING_INSTRUCTION_NODE || n.nodeType === COMMENT_NODE) {
9617
+ return null; // excluded from text content
9618
+ }
9619
+ buf.push(n.nodeValue);
9620
+ },
9621
+ });
9622
+ return buf.join('');
9623
+ }
9624
+ return this.nodeValue;
9232
9625
  },
9233
9626
 
9234
9627
  set: function (data) {
@@ -9251,24 +9644,6 @@ function requireDom () {
9251
9644
  },
9252
9645
  });
9253
9646
 
9254
- function getTextContent(node) {
9255
- switch (node.nodeType) {
9256
- case ELEMENT_NODE:
9257
- case DOCUMENT_FRAGMENT_NODE:
9258
- var buf = [];
9259
- node = node.firstChild;
9260
- while (node) {
9261
- if (node.nodeType !== 7 && node.nodeType !== 8) {
9262
- buf.push(getTextContent(node));
9263
- }
9264
- node = node.nextSibling;
9265
- }
9266
- return buf.join('');
9267
- default:
9268
- return node.nodeValue;
9269
- }
9270
- }
9271
-
9272
9647
  Object.defineProperty(Element.prototype, 'children', {
9273
9648
  get: function () {
9274
9649
  return new LiveNodeList(this, childrenRefresh);
@@ -9313,6 +9688,7 @@ function requireDom () {
9313
9688
  dom.Notation = Notation;
9314
9689
  dom.Text = Text;
9315
9690
  dom.ProcessingInstruction = ProcessingInstruction;
9691
+ dom.walkDOM = walkDOM;
9316
9692
  dom.XMLSerializer = XMLSerializer;
9317
9693
  return dom;
9318
9694
  }
@@ -9326,7 +9702,7 @@ var hasRequiredEntities;
9326
9702
  function requireEntities () {
9327
9703
  if (hasRequiredEntities) return entities;
9328
9704
  hasRequiredEntities = 1;
9329
- (function (exports$1) {
9705
+ (function (exports) {
9330
9706
 
9331
9707
  var freeze = /*@__PURE__*/ requireConventions().freeze;
9332
9708
 
@@ -9338,7 +9714,7 @@ function requireEntities () {
9338
9714
  * @see https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references#Predefined_entities_in_XML
9339
9715
  * Wikipedia
9340
9716
  */
9341
- exports$1.XML_ENTITIES = freeze({
9717
+ exports.XML_ENTITIES = freeze({
9342
9718
  amp: '&',
9343
9719
  apos: "'",
9344
9720
  gt: '>',
@@ -9363,7 +9739,7 @@ function requireEntities () {
9363
9739
  * @see https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references#Entities_representing_special_characters_in_XHTML
9364
9740
  * Wikpedia (XHTML)
9365
9741
  */
9366
- exports$1.HTML_ENTITIES = freeze({
9742
+ exports.HTML_ENTITIES = freeze({
9367
9743
  Aacute: '\u00C1',
9368
9744
  aacute: '\u00E1',
9369
9745
  Abreve: '\u0102',
@@ -11496,7 +11872,7 @@ function requireEntities () {
11496
11872
  * Use `HTML_ENTITIES` instead.
11497
11873
  * @see {@link HTML_ENTITIES}
11498
11874
  */
11499
- exports$1.entityMap = exports$1.HTML_ENTITIES;
11875
+ exports.entityMap = exports.HTML_ENTITIES;
11500
11876
  } (entities));
11501
11877
  return entities;
11502
11878
  }