@knime/product-features 4.1.1 → 5.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -112,8 +112,11 @@ function prettyBytes(number, options) {
112
112
  return applyFixedWidth(result, options.fixedWidth);
113
113
  }
114
114
  //#endregion
115
- //#region ../../node_modules/.pnpm/dompurify@3.4.13/node_modules/dompurify/dist/purify.es.mjs
116
- /*! @license DOMPurify 3.4.13 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.4.13/LICENSE */
115
+ //#region ../../node_modules/.pnpm/dompurify@3.4.16/node_modules/dompurify/dist/purify.es.mjs
116
+ /*! @license DOMPurify 3.4.16 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.4.16/LICENSE */
117
+ function _OverloadYield(e, d) {
118
+ this.v = e, this.k = d;
119
+ }
117
120
  function _arrayLikeToArray(r, a) {
118
121
  (null == a || a > r.length) && (a = r.length);
119
122
  for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
@@ -125,12 +128,14 @@ function _arrayWithHoles(r) {
125
128
  function _iterableToArrayLimit(r, l) {
126
129
  var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
127
130
  if (null != t) {
128
- var e, n, i, u, a = [], f = true, o = false;
131
+ var e, n, i, u, a = [], f = !0, o = !1;
129
132
  try {
130
- if (i = (t = t.call(r)).next, 0 === l);
131
- else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
133
+ if (i = (t = t.call(r)).next, 0 === l) {
134
+ if (Object(t) !== t) return;
135
+ f = !1;
136
+ } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
132
137
  } catch (r) {
133
- o = true, n = r;
138
+ o = !0, n = r;
134
139
  } finally {
135
140
  try {
136
141
  if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
@@ -144,6 +149,7 @@ function _iterableToArrayLimit(r, l) {
144
149
  function _nonIterableRest() {
145
150
  throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
146
151
  }
152
+ /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */
147
153
  function _slicedToArray(r, e) {
148
154
  return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
149
155
  }
@@ -154,9 +160,64 @@ function _unsupportedIterableToArray(r, a) {
154
160
  return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
155
161
  }
156
162
  }
157
- var entries = Object.entries, setPrototypeOf = Object.setPrototypeOf, isFrozen = Object.isFrozen, getPrototypeOf = Object.getPrototypeOf, getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
158
- var freeze = Object.freeze, seal = Object.seal, create = Object.create;
159
- var _ref = typeof Reflect !== "undefined" && Reflect, apply = _ref.apply, construct = _ref.construct;
163
+ function AsyncGenerator(e) {
164
+ var t, n;
165
+ function resume(t, n) {
166
+ try {
167
+ var r = e[t](n), o = r.value, u = o instanceof _OverloadYield;
168
+ Promise.resolve(u ? o.v : o).then(function(n) {
169
+ if (u) {
170
+ var i = "return" === t && o.k ? t : "next";
171
+ if (!o.k || n.done) return resume(i, n);
172
+ n = e[i](n).value;
173
+ }
174
+ settle(!!r.done, n);
175
+ }, function(e) {
176
+ resume("throw", e);
177
+ });
178
+ } catch (e) {
179
+ settle(2, e);
180
+ }
181
+ }
182
+ function settle(e, r) {
183
+ 2 === e ? t.reject(r) : t.resolve({
184
+ value: r,
185
+ done: e
186
+ }), (t = t.next) ? resume(t.key, t.arg) : n = null;
187
+ }
188
+ this._invoke = function(e, r) {
189
+ return new Promise(function(o, u) {
190
+ var i = {
191
+ key: e,
192
+ arg: r,
193
+ resolve: o,
194
+ reject: u,
195
+ next: null
196
+ };
197
+ n ? n = n.next = i : (t = n = i, resume(e, r));
198
+ });
199
+ }, "function" != typeof e.return && (this.return = void 0);
200
+ }
201
+ AsyncGenerator.prototype["function" == typeof Symbol && Symbol.asyncIterator || "@@asyncIterator"] = function() {
202
+ return this;
203
+ }, AsyncGenerator.prototype.next = function(e) {
204
+ return this._invoke("next", e);
205
+ }, AsyncGenerator.prototype.throw = function(e) {
206
+ return this._invoke("throw", e);
207
+ }, AsyncGenerator.prototype.return = function(e) {
208
+ return this._invoke("return", e);
209
+ };
210
+ var entries = Object.entries;
211
+ var setPrototypeOf = Object.setPrototypeOf;
212
+ var isFrozen = Object.isFrozen;
213
+ var getPrototypeOf = Object.getPrototypeOf;
214
+ var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
215
+ var freeze = Object.freeze;
216
+ var seal = Object.seal;
217
+ var create = Object.create;
218
+ var _ref = typeof Reflect !== "undefined" && Reflect;
219
+ var apply = _ref.apply;
220
+ var construct = _ref.construct;
160
221
  if (!freeze) freeze = function freeze(x) {
161
222
  return x;
162
223
  };
@@ -172,9 +233,11 @@ if (!construct) construct = function construct(Func) {
172
233
  return new Func(...args);
173
234
  };
174
235
  var arrayForEach = unapply(Array.prototype.forEach);
236
+ Array.prototype.indexOf;
175
237
  var arrayLastIndexOf = unapply(Array.prototype.lastIndexOf);
176
238
  var arrayPop = unapply(Array.prototype.pop);
177
239
  var arrayPush = unapply(Array.prototype.push);
240
+ Array.prototype.slice;
178
241
  var arraySplice = unapply(Array.prototype.splice);
179
242
  var arrayIsArray = Array.isArray;
180
243
  var stringToLowerCase = unapply(String.prototype.toLowerCase);
@@ -834,6 +897,7 @@ var svg = freeze([
834
897
  "patterncontentunits",
835
898
  "patterntransform",
836
899
  "patternunits",
900
+ "pointer-events",
837
901
  "points",
838
902
  "preservealpha",
839
903
  "preserveaspectratio",
@@ -888,6 +952,7 @@ var svg = freeze([
888
952
  "u2",
889
953
  "unicode",
890
954
  "values",
955
+ "vector-effect",
891
956
  "viewbox",
892
957
  "visibility",
893
958
  "version",
@@ -1001,6 +1066,24 @@ var NODE_TYPE = {
1001
1066
  documentFragment: 11,
1002
1067
  notation: 12
1003
1068
  };
1069
+ var LITERAL_TEXT_ELEMENT_NAMES = [
1070
+ "style",
1071
+ "script",
1072
+ "xmp",
1073
+ "iframe",
1074
+ "noembed",
1075
+ "noframes",
1076
+ "plaintext",
1077
+ "noscript"
1078
+ ];
1079
+ var LITERAL_TEXT_ELEMENTS = freeze(addToSet({}, LITERAL_TEXT_ELEMENT_NAMES));
1080
+ var LITERAL_TEXT_CLOSE = function() {
1081
+ const map = {};
1082
+ arrayForEach(LITERAL_TEXT_ELEMENT_NAMES, (name) => {
1083
+ map[name] = seal(new RegExp("</" + name + "(?=[\\t\\n\\f\\r />])", "i"));
1084
+ });
1085
+ return freeze(map);
1086
+ }();
1004
1087
  var getGlobal = function getGlobal() {
1005
1088
  return typeof window === "undefined" ? null : window;
1006
1089
  };
@@ -1060,10 +1143,25 @@ var _createHooksMap = function _createHooksMap() {
1060
1143
  var _resolveSetOption = function _resolveSetOption(cfg, key, fallback, options) {
1061
1144
  return objectHasOwnProperty(cfg, key) && arrayIsArray(cfg[key]) ? addToSet(options.base ? clone(options.base) : {}, cfg[key], options.transform) : fallback;
1062
1145
  };
1146
+ /**
1147
+ * Resolve an object-valued configuration option: a prototype-free clone
1148
+ * of cfg[key] when it is an own, truthy object property, else a fresh
1149
+ * fallback built by makeFallback (fresh on every parse, so a previous
1150
+ * parse can never leak state into the next one).
1151
+ *
1152
+ * @param cfg the cloned, prototype-free configuration object
1153
+ * @param key the configuration property to read
1154
+ * @param makeFallback builds the fallback value when the option is absent
1155
+ * @returns the resolved object
1156
+ */
1157
+ var _resolveObjectOption = function _resolveObjectOption(cfg, key, makeFallback) {
1158
+ const value = objectHasOwnProperty(cfg, key) ? cfg[key] : void 0;
1159
+ return value && typeof value === "object" ? clone(value) : makeFallback();
1160
+ };
1063
1161
  function createDOMPurify() {
1064
1162
  let window = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : getGlobal();
1065
1163
  const DOMPurify = (root) => createDOMPurify(root);
1066
- DOMPurify.version = "3.4.13";
1164
+ DOMPurify.version = "3.4.16";
1067
1165
  DOMPurify.removed = [];
1068
1166
  if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document || !window.Element) {
1069
1167
  DOMPurify.isSupported = false;
@@ -1080,6 +1178,7 @@ function createDOMPurify() {
1080
1178
  const ElementPrototype = Element.prototype;
1081
1179
  const cloneNode = lookupGetter(ElementPrototype, "cloneNode");
1082
1180
  const remove = lookupGetter(ElementPrototype, "remove");
1181
+ const removeAttributeNode = lookupGetter(ElementPrototype, "removeAttributeNode");
1083
1182
  const getNextSibling = lookupGetter(ElementPrototype, "nextSibling");
1084
1183
  const getChildNodes = lookupGetter(ElementPrototype, "childNodes");
1085
1184
  const getParentNode = lookupGetter(ElementPrototype, "parentNode");
@@ -1088,6 +1187,12 @@ function createDOMPurify() {
1088
1187
  const getNodeType = Node && Node.prototype ? lookupGetter(Node.prototype, "nodeType") : null;
1089
1188
  const getNodeName = Node && Node.prototype ? lookupGetter(Node.prototype, "nodeName") : null;
1090
1189
  const getOwnerDocument = Node && Node.prototype ? lookupGetter(Node.prototype, "ownerDocument") : null;
1190
+ const _readNodeType = function _readNodeType(node) {
1191
+ return getNodeType ? getNodeType(node) : node.nodeType;
1192
+ };
1193
+ const _readNodeName = function _readNodeName(node) {
1194
+ return getNodeName ? getNodeName(node) : node.nodeName;
1195
+ };
1091
1196
  if (typeof HTMLTemplateElement === "function") {
1092
1197
  const template = document.createElement("template");
1093
1198
  if (template.content && template.content.ownerDocument) document = template.content.ownerDocument;
@@ -1345,9 +1450,9 @@ function createDOMPurify() {
1345
1450
  IN_PLACE = cfg.IN_PLACE || false;
1346
1451
  IS_ALLOWED_URI$1 = isRegex(cfg.ALLOWED_URI_REGEXP) ? cfg.ALLOWED_URI_REGEXP : IS_ALLOWED_URI;
1347
1452
  NAMESPACE = typeof cfg.NAMESPACE === "string" ? cfg.NAMESPACE : HTML_NAMESPACE;
1348
- MATHML_TEXT_INTEGRATION_POINTS = objectHasOwnProperty(cfg, "MATHML_TEXT_INTEGRATION_POINTS") && cfg.MATHML_TEXT_INTEGRATION_POINTS && typeof cfg.MATHML_TEXT_INTEGRATION_POINTS === "object" ? clone(cfg.MATHML_TEXT_INTEGRATION_POINTS) : addToSet({}, DEFAULT_MATHML_TEXT_INTEGRATION_POINTS);
1349
- HTML_INTEGRATION_POINTS = objectHasOwnProperty(cfg, "HTML_INTEGRATION_POINTS") && cfg.HTML_INTEGRATION_POINTS && typeof cfg.HTML_INTEGRATION_POINTS === "object" ? clone(cfg.HTML_INTEGRATION_POINTS) : addToSet({}, DEFAULT_HTML_INTEGRATION_POINTS);
1350
- const customElementHandling = objectHasOwnProperty(cfg, "CUSTOM_ELEMENT_HANDLING") && cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING === "object" ? clone(cfg.CUSTOM_ELEMENT_HANDLING) : create(null);
1453
+ MATHML_TEXT_INTEGRATION_POINTS = _resolveObjectOption(cfg, "MATHML_TEXT_INTEGRATION_POINTS", () => addToSet({}, DEFAULT_MATHML_TEXT_INTEGRATION_POINTS));
1454
+ HTML_INTEGRATION_POINTS = _resolveObjectOption(cfg, "HTML_INTEGRATION_POINTS", () => addToSet({}, DEFAULT_HTML_INTEGRATION_POINTS));
1455
+ const customElementHandling = _resolveObjectOption(cfg, "CUSTOM_ELEMENT_HANDLING", () => create(null));
1351
1456
  CUSTOM_ELEMENT_HANDLING = create(null);
1352
1457
  if (objectHasOwnProperty(customElementHandling, "tagNameCheck") && isRegexOrFunction(customElementHandling.tagNameCheck)) CUSTOM_ELEMENT_HANDLING.tagNameCheck = customElementHandling.tagNameCheck;
1353
1458
  if (objectHasOwnProperty(customElementHandling, "attributeNameCheck") && isRegexOrFunction(customElementHandling.attributeNameCheck)) CUSTOM_ELEMENT_HANDLING.attributeNameCheck = customElementHandling.attributeNameCheck;
@@ -1394,11 +1499,6 @@ function createDOMPurify() {
1394
1499
  addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc);
1395
1500
  }
1396
1501
  }
1397
- if (objectHasOwnProperty(cfg, "ADD_URI_SAFE_ATTR") && arrayIsArray(cfg.ADD_URI_SAFE_ATTR)) addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc);
1398
- if (objectHasOwnProperty(cfg, "FORBID_CONTENTS") && arrayIsArray(cfg.FORBID_CONTENTS)) {
1399
- if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) FORBID_CONTENTS = clone(FORBID_CONTENTS);
1400
- addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc);
1401
- }
1402
1502
  if (objectHasOwnProperty(cfg, "ADD_FORBID_CONTENTS") && arrayIsArray(cfg.ADD_FORBID_CONTENTS)) {
1403
1503
  if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) FORBID_CONTENTS = clone(FORBID_CONTENTS);
1404
1504
  addToSet(FORBID_CONTENTS, cfg.ADD_FORBID_CONTENTS, transformCaseFunc);
@@ -1515,6 +1615,32 @@ function createDOMPurify() {
1515
1615
  }
1516
1616
  };
1517
1617
  /**
1618
+ * _stripAttributeNode
1619
+ *
1620
+ * Remove a single Attr node case/namespace-exactly on an attribute-teardown
1621
+ * path. Name-based removeAttribute() ASCII-lowercases its lookup key for an
1622
+ * HTML element in an HTML document and so silently misses a case-preserved
1623
+ * handler (e.g. `ONERROR` off an XML/XHTML import) - the same defect
1624
+ * _removeAttribute() was fixed for, which a name-based call would reintroduce
1625
+ * on these IN_PLACE teardown paths. Unlike _removeAttribute this does not
1626
+ * record into DOMPurify.removed: the neutralize passes intentionally do not
1627
+ * book-keep. A clobbered/detached node falls back to best-effort name-based
1628
+ * removal.
1629
+ *
1630
+ * @param element the element to strip the attribute from
1631
+ * @param attribute the Attr node to remove
1632
+ * @param name the attribute's name, for the fallback path
1633
+ */
1634
+ const _stripAttributeNode = function _stripAttributeNode(element, attribute, name) {
1635
+ try {
1636
+ removeAttributeNode(element, attribute);
1637
+ } catch (_) {
1638
+ try {
1639
+ element.removeAttribute(name);
1640
+ } catch (_) {}
1641
+ }
1642
+ };
1643
+ /**
1518
1644
  * _neutralizeRoot
1519
1645
  *
1520
1646
  * Fail-closed teardown of an in-place root after the sanitize walk aborts
@@ -1548,30 +1674,45 @@ function createDOMPurify() {
1548
1674
  if (attributes) for (let i = attributes.length - 1; i >= 0; --i) {
1549
1675
  const attribute = attributes[i];
1550
1676
  const name = attribute && attribute.name;
1551
- if (typeof name === "string") try {
1552
- root.removeAttribute(name);
1553
- } catch (_) {}
1677
+ if (typeof name === "string") _stripAttributeNode(root, attribute, name);
1554
1678
  }
1555
1679
  };
1556
1680
  /**
1557
1681
  * _removeAttribute
1558
1682
  *
1683
+ * Name-based getAttributeNode()/removeAttribute() ASCII-lowercase their
1684
+ * lookup key for HTML elements in an HTML document, so they silently miss an
1685
+ * attribute whose stored qualified name still contains uppercase ASCII
1686
+ * letters. That happens when the node came from a case-preserving source
1687
+ * (an XML/XHTML document imported via importNode(), or createAttributeNS()),
1688
+ * where e.g. `ONERROR` survives the walk: the policy check lowercases to
1689
+ * `onerror` and rejects it, but `removeAttribute('ONERROR')` looks up
1690
+ * `onerror` and finds nothing. Remove the exact Attr node instead, which is
1691
+ * case- and namespace-exact, and fall back to name-based removal only when
1692
+ * the caller could not supply the node.
1693
+ *
1559
1694
  * @param name an Attribute name
1560
1695
  * @param element a DOM node
1696
+ * @param attr the exact Attr node to remove, when the caller has it
1561
1697
  */
1562
- const _removeAttribute = function _removeAttribute(name, element) {
1698
+ const _removeAttribute = function _removeAttribute(name, element, attr) {
1699
+ if (!attr) try {
1700
+ attr = element.getAttributeNode(name);
1701
+ } catch (_) {
1702
+ attr = null;
1703
+ }
1704
+ arrayPush(DOMPurify.removed, {
1705
+ attribute: attr || null,
1706
+ from: element
1707
+ });
1563
1708
  try {
1564
- arrayPush(DOMPurify.removed, {
1565
- attribute: element.getAttributeNode(name),
1566
- from: element
1567
- });
1709
+ if (attr) removeAttributeNode(element, attr);
1710
+ else element.removeAttribute(name);
1568
1711
  } catch (_) {
1569
- arrayPush(DOMPurify.removed, {
1570
- attribute: null,
1571
- from: element
1572
- });
1712
+ try {
1713
+ element.removeAttribute(name);
1714
+ } catch (_) {}
1573
1715
  }
1574
- element.removeAttribute(name);
1575
1716
  if (name === "is") if (RETURN_DOM || RETURN_DOM_FRAGMENT) try {
1576
1717
  _forceRemove(element);
1577
1718
  } catch (_) {}
@@ -1596,9 +1737,7 @@ function createDOMPurify() {
1596
1737
  const attribute = attributes[i];
1597
1738
  const name = attribute && attribute.name;
1598
1739
  if (typeof name !== "string" || ALLOWED_ATTR[transformCaseFunc(name)]) continue;
1599
- try {
1600
- element.removeAttribute(name);
1601
- } catch (_) {}
1740
+ _stripAttributeNode(element, attribute, name);
1602
1741
  }
1603
1742
  };
1604
1743
  /**
@@ -1627,7 +1766,7 @@ function createDOMPurify() {
1627
1766
  const stack = [root];
1628
1767
  while (stack.length > 0) {
1629
1768
  const node = stack.pop();
1630
- if ((getNodeType ? getNodeType(node) : node.nodeType) === NODE_TYPE.element) _stripDisallowedAttributes(node);
1769
+ if (_readNodeType(node) === NODE_TYPE.element) _stripDisallowedAttributes(node);
1631
1770
  const childNodes = getChildNodes(node);
1632
1771
  if (childNodes) for (let i = childNodes.length - 1; i >= 0; --i) stack.push(childNodes[i]);
1633
1772
  }
@@ -1667,12 +1806,28 @@ function createDOMPurify() {
1667
1806
  *
1668
1807
  * @param root the in-place root to sweep
1669
1808
  */
1809
+ /**
1810
+ * Central policy for declarative-partial-updates patch-linkage attributes,
1811
+ * shared by the _neutralizePatchLinkage pre-pass and _isValidAttribute so
1812
+ * the two sites cannot drift: `patchsrc` always links, `for` links
1813
+ * everywhere except on <label>/<output>, and the whole policy is gated on
1814
+ * SAFE_FOR_XML (see the rationale block in _isValidAttribute).
1815
+ *
1816
+ * @param lcName the transformCaseFunc'd attribute name
1817
+ * @param lcTag the transformCaseFunc'd tag name of the carrying element
1818
+ * @return true if the attribute is patch linkage and must be dropped
1819
+ */
1820
+ const _isPatchLinkageAttribute = function _isPatchLinkageAttribute(lcName, lcTag) {
1821
+ if (!SAFE_FOR_XML) return false;
1822
+ if (lcName === "patchsrc") return true;
1823
+ return lcName === "for" && lcTag !== "label" && lcTag !== "output";
1824
+ };
1670
1825
  const _neutralizePatchLinkage = function _neutralizePatchLinkage(root) {
1671
1826
  if (!SAFE_FOR_XML) return;
1672
1827
  const stack = [root];
1673
1828
  while (stack.length > 0) {
1674
1829
  const node = stack.pop();
1675
- const nodeType = getNodeType ? getNodeType(node) : node.nodeType;
1830
+ const nodeType = _readNodeType(node);
1676
1831
  if (nodeType === NODE_TYPE.processingInstruction || nodeType === NODE_TYPE.comment && regExpTest(COMMENT_MARKUP_PROBE, node.data)) {
1677
1832
  try {
1678
1833
  remove(node);
@@ -1681,10 +1836,10 @@ function createDOMPurify() {
1681
1836
  }
1682
1837
  if (nodeType === NODE_TYPE.element) {
1683
1838
  const element = node;
1684
- const lcTag = transformCaseFunc(getNodeName ? getNodeName(node) : node.nodeName);
1839
+ const lcTag = transformCaseFunc(_readNodeName(node));
1685
1840
  try {
1686
1841
  if (element.hasAttribute && element.hasAttribute("patchsrc")) element.removeAttribute("patchsrc");
1687
- if (element.hasAttribute && element.hasAttribute("for") && lcTag !== "label" && lcTag !== "output") element.removeAttribute("for");
1842
+ if (element.hasAttribute && element.hasAttribute("for") && _isPatchLinkageAttribute("for", lcTag)) element.removeAttribute("for");
1688
1843
  } catch (_) {}
1689
1844
  }
1690
1845
  const childNodes = getChildNodes(node);
@@ -1795,7 +1950,7 @@ function createDOMPurify() {
1795
1950
  const realTagName = getNodeName ? getNodeName(element) : null;
1796
1951
  if (typeof realTagName !== "string") return false;
1797
1952
  if (transformCaseFunc(realTagName) !== "form") return false;
1798
- return typeof element.nodeName !== "string" || typeof element.textContent !== "string" || typeof element.removeChild !== "function" || element.attributes !== getAttributes(element) || typeof element.removeAttribute !== "function" || typeof element.setAttribute !== "function" || typeof element.namespaceURI !== "string" || typeof element.insertBefore !== "function" || typeof element.hasChildNodes !== "function" || element.nodeType !== getNodeType(element) || element.childNodes !== getChildNodes(element);
1953
+ return typeof element.nodeName !== "string" || typeof element.textContent !== "string" || typeof element.removeChild !== "function" || element.attributes !== getAttributes(element) || typeof element.removeAttribute !== "function" || typeof element.removeAttributeNode !== "function" || typeof element.getAttributeNode !== "function" || typeof element.setAttribute !== "function" || typeof element.namespaceURI !== "string" || typeof element.insertBefore !== "function" || typeof element.hasChildNodes !== "function" || element.nodeType !== getNodeType(element) || element.childNodes !== getChildNodes(element);
1799
1954
  };
1800
1955
  /**
1801
1956
  * Checks whether the given value is a DocumentFragment from any realm.
@@ -1853,12 +2008,32 @@ function createDOMPurify() {
1853
2008
  */
1854
2009
  const _isUnsafeNode = function _isUnsafeNode(currentNode, tagName) {
1855
2010
  if (SAFE_FOR_XML && currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(ELEMENT_MARKUP_PROBE, currentNode.textContent) && regExpTest(ELEMENT_MARKUP_PROBE, currentNode.innerHTML)) return true;
1856
- if (SAFE_FOR_XML && currentNode.namespaceURI === HTML_NAMESPACE && tagName === "style" && _isNode(currentNode.firstElementChild)) return true;
2011
+ if (SAFE_FOR_XML && currentNode.namespaceURI === HTML_NAMESPACE && LITERAL_TEXT_ELEMENTS[tagName] && (_isNode(currentNode.firstElementChild) || typeof currentNode.textContent === "string" && regExpTest(LITERAL_TEXT_CLOSE[tagName], currentNode.textContent))) return true;
1857
2012
  if (currentNode.nodeType === NODE_TYPE.processingInstruction) return true;
1858
2013
  if (SAFE_FOR_XML && currentNode.nodeType === NODE_TYPE.comment && regExpTest(COMMENT_MARKUP_PROBE, currentNode.data)) return true;
1859
2014
  return false;
1860
2015
  };
1861
2016
  /**
2017
+ * Evaluate a CUSTOM_ELEMENT_HANDLING check (a RegExp or a predicate
2018
+ * function, per the validation in _parseConfig) against a name.
2019
+ * Additional arguments are forwarded to predicate functions - the
2020
+ * attributeNameCheck predicate receives the tag name as its second
2021
+ * argument. A null/absent check never matches.
2022
+ *
2023
+ * @param check the configured tagNameCheck / attributeNameCheck value
2024
+ * @param name the name to test
2025
+ * @param args extra arguments forwarded to a predicate function
2026
+ * @return true if the check matches the name
2027
+ */
2028
+ const _matchesNameCheck = function _matchesNameCheck(check, name) {
2029
+ if (check instanceof RegExp) return regExpTest(check, name);
2030
+ if (check instanceof Function) {
2031
+ for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) args[_key - 2] = arguments[_key];
2032
+ return Boolean(check(name, ...args));
2033
+ }
2034
+ return false;
2035
+ };
2036
+ /**
1862
2037
  * Handle a node whose tag is forbidden or not allowlisted: keep
1863
2038
  * allowed custom elements (false return exits _sanitizeElements
1864
2039
  * early - the namespace and fallback-tag removal checks are
@@ -1876,10 +2051,7 @@ function createDOMPurify() {
1876
2051
  * @return true if the node was removed, false if kept
1877
2052
  */
1878
2053
  const _sanitizeDisallowedNode = function _sanitizeDisallowedNode(currentNode, tagName, root) {
1879
- if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {
1880
- if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) return false;
1881
- if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) return false;
1882
- }
2054
+ if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName) && _matchesNameCheck(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) return false;
1883
2055
  if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {
1884
2056
  const parentNode = getParentNode(currentNode);
1885
2057
  const childNodes = getChildNodes(currentNode);
@@ -1913,6 +2085,42 @@ function createDOMPurify() {
1913
2085
  return set === defaultSet || set === setConfigSet ? clone(set) : set;
1914
2086
  };
1915
2087
  /**
2088
+ * Shared guard for a node that a hook has detached from the walk tree,
2089
+ * used after each element-hook site in _sanitizeElements. Detaching is a
2090
+ * long-standing user pattern (issue #469; draw.io-style foreignObject
2091
+ * filtering). Per the cached, unclobberable parentNode getter the node is
2092
+ * genuinely out of the tree, so it can reach neither the serialized
2093
+ * output nor an IN_PLACE live tree; treat it as removed and stop
2094
+ * processing it. Without this guard, the unsafe-node / namespace checks
2095
+ * would call _forceRemove on a parentless node and hit the REPORT-3
2096
+ * fail-closed throw — which exists for nodes DOMPurify wants gone but
2097
+ * *cannot* detach (clobbered / parentless roots), the opposite of a node
2098
+ * that is already safely gone. The walk root is exempt: a detached
2099
+ * IN_PLACE root is legitimate input and must still be fully sanitized,
2100
+ * and a kill-decision on it must keep hitting the REPORT-3 throw.
2101
+ *
2102
+ * Nodes detached by hooks stay the hook's responsibility for placement:
2103
+ * they are not recorded in DOMPurify.removed, so the post-walk IN_PLACE
2104
+ * pass (which iterates DOMPurify.removed) does not reach them. But a
2105
+ * hook-detached subtree can still hold a queued resource-event handler -
2106
+ * e.g. an <img onload> that began loading when the caller built the live
2107
+ * tree - which fires in page scope after sanitize returns even though the
2108
+ * handler never reached the returned tree. That is the audit-5 F1 hazard,
2109
+ * and the documented node.remove() hook pattern walks straight into it.
2110
+ * So on the IN_PLACE path we neutralize the detached subtree inline,
2111
+ * stripping its non-allow-listed attributes before returning, exactly as
2112
+ * the post-walk pass does for _forceRemove'd subtrees.
2113
+ *
2114
+ * @param currentNode the node a hook may have detached
2115
+ * @param root the current walk root
2116
+ * @return true if the node is detached and now handled, false otherwise
2117
+ */
2118
+ const _handleHookDetachedNode = function _handleHookDetachedNode(currentNode, root) {
2119
+ if (currentNode === root || getParentNode(currentNode) !== null) return false;
2120
+ if (IN_PLACE) _neutralizeSubtree(currentNode);
2121
+ return true;
2122
+ };
2123
+ /**
1916
2124
  * _sanitizeElements
1917
2125
  *
1918
2126
  * @protect nodeName
@@ -1923,34 +2131,31 @@ function createDOMPurify() {
1923
2131
  */
1924
2132
  const _sanitizeElements = function _sanitizeElements(currentNode, root) {
1925
2133
  _executeHooks(hooks.beforeSanitizeElements, currentNode, null);
1926
- if (currentNode !== root && getParentNode(currentNode) === null) {
1927
- if (IN_PLACE) _neutralizeSubtree(currentNode);
1928
- return true;
1929
- }
2134
+ if (_handleHookDetachedNode(currentNode, root)) return true;
1930
2135
  if (_isClobbered(currentNode)) {
1931
2136
  _forceRemove(currentNode);
1932
2137
  return true;
1933
2138
  }
1934
- const tagName = transformCaseFunc(getNodeName ? getNodeName(currentNode) : currentNode.nodeName);
2139
+ const tagName = transformCaseFunc(_readNodeName(currentNode));
1935
2140
  ALLOWED_TAGS = _forkSharedAllowlist(hooks.uponSanitizeElement, ALLOWED_TAGS, DEFAULT_ALLOWED_TAGS, SET_CONFIG_ALLOWED_TAGS);
1936
2141
  _executeHooks(hooks.uponSanitizeElement, currentNode, {
1937
2142
  tagName,
1938
2143
  allowedTags: ALLOWED_TAGS
1939
2144
  });
1940
- if (currentNode !== root && getParentNode(currentNode) === null) {
1941
- if (IN_PLACE) _neutralizeSubtree(currentNode);
1942
- return true;
1943
- }
2145
+ if (_handleHookDetachedNode(currentNode, root)) return true;
1944
2146
  if (_isUnsafeNode(currentNode, tagName)) {
1945
2147
  _forceRemove(currentNode);
1946
2148
  return true;
1947
2149
  }
1948
2150
  if (FORBID_TAGS[tagName] || !(EXTRA_ELEMENT_HANDLING.tagCheck instanceof Function && EXTRA_ELEMENT_HANDLING.tagCheck(tagName)) && !ALLOWED_TAGS[tagName]) {
1949
2151
  const removed = _sanitizeDisallowedNode(currentNode, tagName, root);
1950
- if (removed === false) _executeHooks(hooks.afterSanitizeElements, currentNode, null);
2152
+ if (removed === false) {
2153
+ _executeHooks(hooks.afterSanitizeElements, currentNode, null);
2154
+ if (_handleHookDetachedNode(currentNode, root)) return true;
2155
+ }
1951
2156
  return removed;
1952
2157
  }
1953
- if ((getNodeType ? getNodeType(currentNode) : currentNode.nodeType) === NODE_TYPE.element && !_checkValidNamespace(currentNode)) {
2158
+ if (_readNodeType(currentNode) === NODE_TYPE.element && !_checkValidNamespace(currentNode)) {
1954
2159
  _forceRemove(currentNode);
1955
2160
  return true;
1956
2161
  }
@@ -1966,7 +2171,7 @@ function createDOMPurify() {
1966
2171
  }
1967
2172
  }
1968
2173
  _executeHooks(hooks.afterSanitizeElements, currentNode, null);
1969
- return false;
2174
+ return _handleHookDetachedNode(currentNode, root);
1970
2175
  };
1971
2176
  /**
1972
2177
  * _isValidAttribute
@@ -1978,20 +2183,17 @@ function createDOMPurify() {
1978
2183
  */
1979
2184
  const _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) {
1980
2185
  if (FORBID_ATTR[lcName]) return false;
1981
- if (SAFE_FOR_XML && lcName === "patchsrc") return false;
1982
- if (SAFE_FOR_XML && lcName === "for" && lcTag !== "label" && lcTag !== "output") return false;
2186
+ if (_isPatchLinkageAttribute(lcName, lcTag)) return false;
1983
2187
  if (SANITIZE_DOM && (lcName === "id" || lcName === "name") && (value in document || value in formElement)) return false;
1984
2188
  const nameIsPermitted = ALLOWED_ATTR[lcName] || EXTRA_ELEMENT_HANDLING.attributeCheck instanceof Function && EXTRA_ELEMENT_HANDLING.attributeCheck(lcName, lcTag);
1985
- if (ALLOW_DATA_ATTR && regExpTest(DATA_ATTR$1, lcName));
1986
- else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR$1, lcName));
1987
- else if (!nameIsPermitted) if (_isBasicCustomElement(lcTag) && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag)) && (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName) || CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName, lcTag)) || lcName === "is" && CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, value) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(value)));
1988
- else return false;
1989
- else if (URI_SAFE_ATTRIBUTES[lcName]);
1990
- else if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE$1, "")));
1991
- else if ((lcName === "src" || lcName === "xlink:href" || lcName === "href") && lcTag !== "script" && stringIndexOf(value, "data:") === 0 && DATA_URI_TAGS[lcTag]);
1992
- else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA$1, stringReplace(value, ATTR_WHITESPACE$1, "")));
1993
- else if (value) return false;
1994
- return true;
2189
+ if (ALLOW_DATA_ATTR && regExpTest(DATA_ATTR$1, lcName)) return true;
2190
+ if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR$1, lcName)) return true;
2191
+ if (!nameIsPermitted) return _isBasicCustomElement(lcTag) && _matchesNameCheck(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) && _matchesNameCheck(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName, lcTag) || lcName === "is" && CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements && _matchesNameCheck(CUSTOM_ELEMENT_HANDLING.tagNameCheck, value);
2192
+ if (URI_SAFE_ATTRIBUTES[lcName]) return true;
2193
+ if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE$1, ""))) return true;
2194
+ if ((lcName === "src" || lcName === "xlink:href" || lcName === "href") && lcTag !== "script" && stringIndexOf(value, "data:") === 0 && DATA_URI_TAGS[lcTag]) return true;
2195
+ if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA$1, stringReplace(value, ATTR_WHITESPACE$1, ""))) return true;
2196
+ return !value;
1995
2197
  };
1996
2198
  const RESERVED_CUSTOM_ELEMENT_NAMES = addToSet({}, [
1997
2199
  "annotation-xml",
@@ -2036,24 +2238,38 @@ function createDOMPurify() {
2036
2238
  /**
2037
2239
  * Write a modified attribute value back onto the element. On
2038
2240
  * success, re-probe for clobbering introduced by the new value and
2039
- * remove the element when found; otherwise pop the removal entry
2040
- * recorded by the earlier _removeAttribute (long-standing pairing
2041
- * with the SANITIZE_NAMED_PROPS path - do not "fix" casually). On
2241
+ * remove the element when found; otherwise, when this writeback is the
2242
+ * recreate half of the SANITIZE_NAMED_PROPS remove-and-recreate, pop the
2243
+ * removal entry that path recorded so it does not show as removed. On
2042
2244
  * failure, remove the attribute instead.
2043
2245
  *
2246
+ * Returns true only on a clean write (the value was set and the new value
2247
+ * introduced no clobbering). The caller uses that, together with its own
2248
+ * knowledge of whether this attribute pushed a DOMPurify.removed record, to
2249
+ * decide whether to pop that record. The pop must happen ONLY for the
2250
+ * named-prop remove-and-recreate; popping on any other value change (trim,
2251
+ * template scrubbing, Trusted Types) would consume an unrelated _forceRemove
2252
+ * subtree-cleanup record and let that detached subtree keep a live event
2253
+ * handler through the IN_PLACE neutralization pass (SO-001).
2254
+ *
2044
2255
  * @param currentNode the element carrying the attribute
2045
2256
  * @param name the attribute name as present on the element
2046
2257
  * @param namespaceURI the attribute's namespace, if any
2047
2258
  * @param value the new attribute value
2259
+ * @return true if the value was written without introducing clobbering
2048
2260
  */
2049
2261
  const _setAttributeValue = function _setAttributeValue(currentNode, name, namespaceURI, value) {
2050
2262
  try {
2051
2263
  if (namespaceURI) currentNode.setAttributeNS(namespaceURI, name, value);
2052
2264
  else currentNode.setAttribute(name, value);
2053
- if (_isClobbered(currentNode)) _forceRemove(currentNode);
2054
- else arrayPop(DOMPurify.removed);
2265
+ if (_isClobbered(currentNode)) {
2266
+ _forceRemove(currentNode);
2267
+ return false;
2268
+ }
2269
+ return true;
2055
2270
  } catch (_) {
2056
2271
  _removeAttribute(name, currentNode);
2272
+ return false;
2057
2273
  }
2058
2274
  };
2059
2275
  /**
@@ -2065,9 +2281,11 @@ function createDOMPurify() {
2065
2281
  * @protect setAttribute
2066
2282
  *
2067
2283
  * @param currentNode to sanitize
2284
+ * @param root the current walk root
2068
2285
  */
2069
- const _sanitizeAttributes = function _sanitizeAttributes(currentNode) {
2286
+ const _sanitizeAttributes = function _sanitizeAttributes(currentNode, root) {
2070
2287
  _executeHooks(hooks.beforeSanitizeAttributes, currentNode, null);
2288
+ if (_handleHookDetachedNode(currentNode, root)) return;
2071
2289
  const attributes = currentNode.attributes;
2072
2290
  if (!attributes || _isClobbered(currentNode)) return;
2073
2291
  ALLOWED_ATTR = _forkSharedAllowlist(hooks.uponSanitizeAttribute, ALLOWED_ATTR, DEFAULT_ALLOWED_ATTR, SET_CONFIG_ALLOWED_ATTR);
@@ -2086,6 +2304,7 @@ function createDOMPurify() {
2086
2304
  const lcName = transformCaseFunc(name);
2087
2305
  const initValue = attrValue;
2088
2306
  let value = name === "value" ? initValue : stringTrim(initValue);
2307
+ let recreatedNamedProp = false;
2089
2308
  hookEvent.attrName = lcName;
2090
2309
  hookEvent.attrValue = value;
2091
2310
  hookEvent.keepAttr = true;
@@ -2093,35 +2312,39 @@ function createDOMPurify() {
2093
2312
  _executeHooks(hooks.uponSanitizeAttribute, currentNode, hookEvent);
2094
2313
  value = hookEvent.attrValue;
2095
2314
  if (SANITIZE_NAMED_PROPS && (lcName === "id" || lcName === "name") && stringIndexOf(value, SANITIZE_NAMED_PROPS_PREFIX) !== 0) {
2096
- _removeAttribute(name, currentNode);
2315
+ _removeAttribute(name, currentNode, attr);
2097
2316
  value = SANITIZE_NAMED_PROPS_PREFIX + value;
2317
+ recreatedNamedProp = true;
2098
2318
  }
2099
2319
  if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|script|title|xmp|textarea|noscript|iframe|noembed|noframes)/i, value)) {
2100
- _removeAttribute(name, currentNode);
2320
+ _removeAttribute(name, currentNode, attr);
2101
2321
  continue;
2102
2322
  }
2103
2323
  if (lcName === "attributename" && stringMatch(value, "href")) {
2104
- _removeAttribute(name, currentNode);
2324
+ _removeAttribute(name, currentNode, attr);
2105
2325
  continue;
2106
2326
  }
2107
2327
  if (hookEvent.forceKeepAttr) continue;
2108
2328
  if (!hookEvent.keepAttr) {
2109
- _removeAttribute(name, currentNode);
2329
+ _removeAttribute(name, currentNode, attr);
2110
2330
  continue;
2111
2331
  }
2112
2332
  if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(SELF_CLOSING_TAG, value)) {
2113
- _removeAttribute(name, currentNode);
2333
+ _removeAttribute(name, currentNode, attr);
2114
2334
  continue;
2115
2335
  }
2116
2336
  if (SAFE_FOR_TEMPLATES) value = _stripTemplateExpressions(value);
2117
2337
  if (!_isValidAttribute(lcTag, lcName, value)) {
2118
- _removeAttribute(name, currentNode);
2338
+ _removeAttribute(name, currentNode, attr);
2119
2339
  continue;
2120
2340
  }
2121
2341
  value = _applyTrustedTypesToAttribute(lcTag, lcName, namespaceURI, value);
2122
- if (value !== initValue) _setAttributeValue(currentNode, name, namespaceURI, value);
2342
+ if (value !== initValue) {
2343
+ if (_setAttributeValue(currentNode, name, namespaceURI, value) && recreatedNamedProp) arrayPop(DOMPurify.removed);
2344
+ }
2123
2345
  }
2124
2346
  _executeHooks(hooks.afterSanitizeAttributes, currentNode, null);
2347
+ _handleHookDetachedNode(currentNode, root);
2125
2348
  };
2126
2349
  /**
2127
2350
  * _sanitizeShadowDOM
@@ -2135,9 +2358,9 @@ function createDOMPurify() {
2135
2358
  while (shadowNode = shadowIterator.nextNode()) {
2136
2359
  _executeHooks(hooks.uponSanitizeShadowNode, shadowNode, null);
2137
2360
  _sanitizeElements(shadowNode, fragment);
2138
- _sanitizeAttributes(shadowNode);
2361
+ _sanitizeAttributes(shadowNode, fragment);
2139
2362
  if (_isDocumentFragment(shadowNode.content)) _sanitizeShadowDOM2(shadowNode.content);
2140
- if ((getNodeType ? getNodeType(shadowNode) : shadowNode.nodeType) === NODE_TYPE.element) {
2363
+ if (_readNodeType(shadowNode) === NODE_TYPE.element) {
2141
2364
  const innerSr = getShadowRoot(shadowNode);
2142
2365
  if (_isDocumentFragment(innerSr)) {
2143
2366
  _sanitizeAttachedShadowRoots(innerSr);
@@ -2178,7 +2401,7 @@ function createDOMPurify() {
2178
2401
  continue;
2179
2402
  }
2180
2403
  const node = item.node;
2181
- const isElement = (getNodeType ? getNodeType(node) : node.nodeType) === NODE_TYPE.element;
2404
+ const isElement = _readNodeType(node) === NODE_TYPE.element;
2182
2405
  const childNodes = getChildNodes(node);
2183
2406
  if (childNodes) for (let i = childNodes.length - 1; i >= 0; --i) stack.push({
2184
2407
  node: childNodes[i],
@@ -2229,7 +2452,7 @@ function createDOMPurify() {
2229
2452
  const inPlace = IN_PLACE && typeof dirty !== "string" && _isNode(dirty);
2230
2453
  if (inPlace) {
2231
2454
  _neutralizePatchLinkage(dirty);
2232
- const nn = getNodeName ? getNodeName(dirty) : dirty.nodeName;
2455
+ const nn = _readNodeName(dirty);
2233
2456
  if (typeof nn === "string") {
2234
2457
  const tagName = transformCaseFunc(nn);
2235
2458
  if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
@@ -2253,7 +2476,7 @@ function createDOMPurify() {
2253
2476
  if (importedNode.nodeType === NODE_TYPE.element && importedNode.nodeName === "BODY") body = importedNode;
2254
2477
  else if (importedNode.nodeName === "HTML") body = importedNode;
2255
2478
  else body.appendChild(importedNode);
2256
- _sanitizeAttachedShadowRoots(importedNode);
2479
+ _sanitizeAttachedShadowRoots(body);
2257
2480
  } else {
2258
2481
  if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT && dirty.indexOf("<") === -1) return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? _createTrustedHTML(dirty) : dirty;
2259
2482
  body = _initDocument(dirty);
@@ -2265,7 +2488,7 @@ function createDOMPurify() {
2265
2488
  const nodeIterator = _createNodeIterator(walkRoot);
2266
2489
  while (currentNode = nodeIterator.nextNode()) {
2267
2490
  _sanitizeElements(currentNode, walkRoot);
2268
- _sanitizeAttributes(currentNode);
2491
+ _sanitizeAttributes(currentNode, walkRoot);
2269
2492
  if (_isDocumentFragment(currentNode.content)) _sanitizeShadowDOM2(currentNode.content);
2270
2493
  }
2271
2494
  } catch (error) {
@@ -2278,9 +2501,14 @@ function createDOMPurify() {
2278
2501
  throw error;
2279
2502
  }
2280
2503
  if (inPlace) {
2504
+ let rootWasRemoved = false;
2281
2505
  arrayForEach(DOMPurify.removed, (entry) => {
2282
- if (entry.element) _neutralizeSubtree(entry.element);
2506
+ if (entry.element) {
2507
+ if (entry.element === dirty) rootWasRemoved = true;
2508
+ _neutralizeSubtree(entry.element);
2509
+ }
2283
2510
  });
2511
+ if (rootWasRemoved) throw typeErrorCreate("a node selected for removal could not be safely returned; refusing to sanitize in place");
2284
2512
  if (SAFE_FOR_TEMPLATES) _scrubTemplateExpressions2(dirty);
2285
2513
  return dirty;
2286
2514
  }
@@ -2675,4 +2903,4 @@ Object.values({
2675
2903
  //#endregion
2676
2904
  export { getFileExtension as a, promise_exports as c, formatLocalDateTimeString as i, sleep as l, formatDateTimeString as n, getFileMimeType as o, formatFileSize as r, knimeFileFormats as s, capitalize as t, truncateString_default as u };
2677
2905
 
2678
- //# sourceMappingURL=dist-DvDWkkNg.js.map
2906
+ //# sourceMappingURL=dist-DtdyvuFe.js.map