@quanta-intellect/vessel-browser 0.1.148 → 0.1.153

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.
@@ -6626,6 +6626,10 @@ const ATTR_WHITESPACE = seal(
6626
6626
  );
6627
6627
  const DOCTYPE_NAME = seal(/^html$/i);
6628
6628
  const CUSTOM_ELEMENT = seal(/^[a-z][.\w]*(-[.\w]+)+$/i);
6629
+ const ELEMENT_MARKUP_PROBE = seal(/<[/\w!]/g);
6630
+ const COMMENT_MARKUP_PROBE = seal(/<[/\w]/g);
6631
+ const FALLBACK_TAG_CLOSE = seal(/<\/no(script|embed|frames)/i);
6632
+ const SELF_CLOSING_TAG = seal(/\/>/i);
6629
6633
  const NODE_TYPE = {
6630
6634
  element: 1,
6631
6635
  attribute: 2,
@@ -6635,7 +6639,7 @@ const NODE_TYPE = {
6635
6639
  // Deprecated
6636
6640
  entityNode: 6,
6637
6641
  // Deprecated
6638
- progressingInstruction: 7,
6642
+ processingInstruction: 7,
6639
6643
  comment: 8,
6640
6644
  document: 9,
6641
6645
  documentType: 10,
@@ -6683,10 +6687,13 @@ const _createHooksMap = function _createHooksMap2() {
6683
6687
  uponSanitizeShadowNode: []
6684
6688
  };
6685
6689
  };
6690
+ const _resolveSetOption = function _resolveSetOption2(cfg, key, fallback, options) {
6691
+ return objectHasOwnProperty(cfg, key) && arrayIsArray(cfg[key]) ? addToSet(options.base ? clone(options.base) : {}, cfg[key], options.transform) : fallback;
6692
+ };
6686
6693
  function createDOMPurify() {
6687
6694
  let window2 = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : getGlobal();
6688
6695
  const DOMPurify = (root2) => createDOMPurify(root2);
6689
- DOMPurify.version = "3.4.7";
6696
+ DOMPurify.version = "3.4.11";
6690
6697
  DOMPurify.removed = [];
6691
6698
  if (!window2 || !window2.document || window2.document.nodeType !== NODE_TYPE.document || !window2.Element) {
6692
6699
  DOMPurify.isSupported = false;
@@ -6718,6 +6725,39 @@ function createDOMPurify() {
6718
6725
  }
6719
6726
  let trustedTypesPolicy;
6720
6727
  let emptyHTML = "";
6728
+ let defaultTrustedTypesPolicy;
6729
+ let defaultTrustedTypesPolicyResolved = false;
6730
+ let IN_TRUSTED_TYPES_POLICY = 0;
6731
+ const _assertNotInTrustedTypesPolicy = function _assertNotInTrustedTypesPolicy2() {
6732
+ if (IN_TRUSTED_TYPES_POLICY > 0) {
6733
+ throw typeErrorCreate('A configured TRUSTED_TYPES_POLICY callback (createHTML or createScriptURL) must not call DOMPurify.sanitize, as that causes infinite recursion. Do not pass a policy whose callbacks wrap DOMPurify as TRUSTED_TYPES_POLICY; see the "DOMPurify and Trusted Types" section of the README.');
6734
+ }
6735
+ };
6736
+ const _createTrustedHTML = function _createTrustedHTML2(html2) {
6737
+ _assertNotInTrustedTypesPolicy();
6738
+ IN_TRUSTED_TYPES_POLICY++;
6739
+ try {
6740
+ return trustedTypesPolicy.createHTML(html2);
6741
+ } finally {
6742
+ IN_TRUSTED_TYPES_POLICY--;
6743
+ }
6744
+ };
6745
+ const _createTrustedScriptURL = function _createTrustedScriptURL2(scriptUrl) {
6746
+ _assertNotInTrustedTypesPolicy();
6747
+ IN_TRUSTED_TYPES_POLICY++;
6748
+ try {
6749
+ return trustedTypesPolicy.createScriptURL(scriptUrl);
6750
+ } finally {
6751
+ IN_TRUSTED_TYPES_POLICY--;
6752
+ }
6753
+ };
6754
+ const _getDefaultTrustedTypesPolicy = function _getDefaultTrustedTypesPolicy2() {
6755
+ if (!defaultTrustedTypesPolicyResolved) {
6756
+ defaultTrustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, currentScript);
6757
+ defaultTrustedTypesPolicyResolved = true;
6758
+ }
6759
+ return defaultTrustedTypesPolicy;
6760
+ };
6721
6761
  const _document = document2, implementation = _document.implementation, createNodeIterator = _document.createNodeIterator, createDocumentFragment = _document.createDocumentFragment, getElementsByTagName = _document.getElementsByTagName;
6722
6762
  const importNode = originalDocument.importNode;
6723
6763
  let hooks = _createHooksMap();
@@ -6772,6 +6812,8 @@ function createDOMPurify() {
6772
6812
  let SAFE_FOR_XML = true;
6773
6813
  let WHOLE_DOCUMENT = false;
6774
6814
  let SET_CONFIG = false;
6815
+ let SET_CONFIG_ALLOWED_TAGS = null;
6816
+ let SET_CONFIG_ALLOWED_ATTR = null;
6775
6817
  let FORCE_BODY = false;
6776
6818
  let RETURN_DOM = false;
6777
6819
  let RETURN_DOM_FRAGMENT = false;
@@ -6783,7 +6825,43 @@ function createDOMPurify() {
6783
6825
  let IN_PLACE = false;
6784
6826
  let USE_PROFILES = {};
6785
6827
  let FORBID_CONTENTS = null;
6786
- const DEFAULT_FORBID_CONTENTS = addToSet({}, ["annotation-xml", "audio", "colgroup", "desc", "foreignobject", "head", "iframe", "math", "mi", "mn", "mo", "ms", "mtext", "noembed", "noframes", "noscript", "plaintext", "script", "style", "svg", "template", "thead", "title", "video", "xmp"]);
6828
+ const DEFAULT_FORBID_CONTENTS = addToSet({}, [
6829
+ "annotation-xml",
6830
+ "audio",
6831
+ "colgroup",
6832
+ "desc",
6833
+ "foreignobject",
6834
+ "head",
6835
+ "iframe",
6836
+ "math",
6837
+ "mi",
6838
+ "mn",
6839
+ "mo",
6840
+ "ms",
6841
+ "mtext",
6842
+ "noembed",
6843
+ "noframes",
6844
+ "noscript",
6845
+ "plaintext",
6846
+ "script",
6847
+ // <selectedcontent> mirrors the selected <option>'s subtree, cloned by
6848
+ // the UA (customizable <select>) — including any on* handlers — and the
6849
+ // engine re-mirrors synchronously whenever a removal changes which
6850
+ // option/selectedcontent is current, even inside DOMPurify's inert
6851
+ // DOMParser document. Hoisting its children on removal re-inserts a fresh
6852
+ // mirror target ahead of the walk, which the engine refills, looping
6853
+ // forever (DoS) and amplifying output. Dropping its content on removal
6854
+ // (rather than hoisting) breaks that cascade; the content is a duplicate
6855
+ // of the option, which is sanitized on its own. See campaign-3 F1/F6.
6856
+ "selectedcontent",
6857
+ "style",
6858
+ "svg",
6859
+ "template",
6860
+ "thead",
6861
+ "title",
6862
+ "video",
6863
+ "xmp"
6864
+ ]);
6787
6865
  let DATA_URI_TAGS = null;
6788
6866
  const DEFAULT_DATA_URI_TAGS = addToSet({}, ["audio", "video", "img", "source", "image", "track"]);
6789
6867
  let URI_SAFE_ATTRIBUTES = null;
@@ -6795,8 +6873,10 @@ function createDOMPurify() {
6795
6873
  let IS_EMPTY_INPUT = false;
6796
6874
  let ALLOWED_NAMESPACES = null;
6797
6875
  const DEFAULT_ALLOWED_NAMESPACES = addToSet({}, [MATHML_NAMESPACE, SVG_NAMESPACE2, HTML_NAMESPACE], stringToString);
6798
- let MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ["mi", "mo", "mn", "ms", "mtext"]);
6799
- let HTML_INTEGRATION_POINTS = addToSet({}, ["annotation-xml"]);
6876
+ const DEFAULT_MATHML_TEXT_INTEGRATION_POINTS = freeze(["mi", "mo", "mn", "ms", "mtext"]);
6877
+ let MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, DEFAULT_MATHML_TEXT_INTEGRATION_POINTS);
6878
+ const DEFAULT_HTML_INTEGRATION_POINTS = freeze(["annotation-xml"]);
6879
+ let HTML_INTEGRATION_POINTS = addToSet({}, DEFAULT_HTML_INTEGRATION_POINTS);
6800
6880
  const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, ["title", "style", "font", "a", "script"]);
6801
6881
  let PARSER_MEDIA_TYPE = null;
6802
6882
  const SUPPORTED_PARSER_MEDIA_TYPES = ["application/xhtml+xml", "text/html"];
@@ -6819,14 +6899,32 @@ function createDOMPurify() {
6819
6899
  PARSER_MEDIA_TYPE = // eslint-disable-next-line unicorn/prefer-includes
6820
6900
  SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? DEFAULT_PARSER_MEDIA_TYPE : cfg.PARSER_MEDIA_TYPE;
6821
6901
  transformCaseFunc = PARSER_MEDIA_TYPE === "application/xhtml+xml" ? stringToString : stringToLowerCase;
6822
- ALLOWED_TAGS = objectHasOwnProperty(cfg, "ALLOWED_TAGS") && arrayIsArray(cfg.ALLOWED_TAGS) ? addToSet({}, cfg.ALLOWED_TAGS, transformCaseFunc) : DEFAULT_ALLOWED_TAGS;
6823
- ALLOWED_ATTR = objectHasOwnProperty(cfg, "ALLOWED_ATTR") && arrayIsArray(cfg.ALLOWED_ATTR) ? addToSet({}, cfg.ALLOWED_ATTR, transformCaseFunc) : DEFAULT_ALLOWED_ATTR;
6824
- ALLOWED_NAMESPACES = objectHasOwnProperty(cfg, "ALLOWED_NAMESPACES") && arrayIsArray(cfg.ALLOWED_NAMESPACES) ? addToSet({}, cfg.ALLOWED_NAMESPACES, stringToString) : DEFAULT_ALLOWED_NAMESPACES;
6825
- URI_SAFE_ATTRIBUTES = objectHasOwnProperty(cfg, "ADD_URI_SAFE_ATTR") && arrayIsArray(cfg.ADD_URI_SAFE_ATTR) ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR, transformCaseFunc) : DEFAULT_URI_SAFE_ATTRIBUTES;
6826
- DATA_URI_TAGS = objectHasOwnProperty(cfg, "ADD_DATA_URI_TAGS") && arrayIsArray(cfg.ADD_DATA_URI_TAGS) ? addToSet(clone(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS, transformCaseFunc) : DEFAULT_DATA_URI_TAGS;
6827
- FORBID_CONTENTS = objectHasOwnProperty(cfg, "FORBID_CONTENTS") && arrayIsArray(cfg.FORBID_CONTENTS) ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc) : DEFAULT_FORBID_CONTENTS;
6828
- FORBID_TAGS = objectHasOwnProperty(cfg, "FORBID_TAGS") && arrayIsArray(cfg.FORBID_TAGS) ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : clone({});
6829
- FORBID_ATTR = objectHasOwnProperty(cfg, "FORBID_ATTR") && arrayIsArray(cfg.FORBID_ATTR) ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : clone({});
6902
+ ALLOWED_TAGS = _resolveSetOption(cfg, "ALLOWED_TAGS", DEFAULT_ALLOWED_TAGS, {
6903
+ transform: transformCaseFunc
6904
+ });
6905
+ ALLOWED_ATTR = _resolveSetOption(cfg, "ALLOWED_ATTR", DEFAULT_ALLOWED_ATTR, {
6906
+ transform: transformCaseFunc
6907
+ });
6908
+ ALLOWED_NAMESPACES = _resolveSetOption(cfg, "ALLOWED_NAMESPACES", DEFAULT_ALLOWED_NAMESPACES, {
6909
+ transform: stringToString
6910
+ });
6911
+ URI_SAFE_ATTRIBUTES = _resolveSetOption(cfg, "ADD_URI_SAFE_ATTR", DEFAULT_URI_SAFE_ATTRIBUTES, {
6912
+ transform: transformCaseFunc,
6913
+ base: DEFAULT_URI_SAFE_ATTRIBUTES
6914
+ });
6915
+ DATA_URI_TAGS = _resolveSetOption(cfg, "ADD_DATA_URI_TAGS", DEFAULT_DATA_URI_TAGS, {
6916
+ transform: transformCaseFunc,
6917
+ base: DEFAULT_DATA_URI_TAGS
6918
+ });
6919
+ FORBID_CONTENTS = _resolveSetOption(cfg, "FORBID_CONTENTS", DEFAULT_FORBID_CONTENTS, {
6920
+ transform: transformCaseFunc
6921
+ });
6922
+ FORBID_TAGS = _resolveSetOption(cfg, "FORBID_TAGS", clone({}), {
6923
+ transform: transformCaseFunc
6924
+ });
6925
+ FORBID_ATTR = _resolveSetOption(cfg, "FORBID_ATTR", clone({}), {
6926
+ transform: transformCaseFunc
6927
+ });
6830
6928
  USE_PROFILES = objectHasOwnProperty(cfg, "USE_PROFILES") ? cfg.USE_PROFILES && typeof cfg.USE_PROFILES === "object" ? clone(cfg.USE_PROFILES) : cfg.USE_PROFILES : false;
6831
6929
  ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false;
6832
6930
  ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false;
@@ -6845,8 +6943,8 @@ function createDOMPurify() {
6845
6943
  IN_PLACE = cfg.IN_PLACE || false;
6846
6944
  IS_ALLOWED_URI$1 = isRegex(cfg.ALLOWED_URI_REGEXP) ? cfg.ALLOWED_URI_REGEXP : IS_ALLOWED_URI;
6847
6945
  NAMESPACE = typeof cfg.NAMESPACE === "string" ? cfg.NAMESPACE : HTML_NAMESPACE;
6848
- 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({}, ["mi", "mo", "mn", "ms", "mtext"]);
6849
- HTML_INTEGRATION_POINTS = objectHasOwnProperty(cfg, "HTML_INTEGRATION_POINTS") && cfg.HTML_INTEGRATION_POINTS && typeof cfg.HTML_INTEGRATION_POINTS === "object" ? clone(cfg.HTML_INTEGRATION_POINTS) : addToSet({}, ["annotation-xml"]);
6946
+ 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);
6947
+ 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);
6850
6948
  const customElementHandling = objectHasOwnProperty(cfg, "CUSTOM_ELEMENT_HANDLING") && cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING === "object" ? clone(cfg.CUSTOM_ELEMENT_HANDLING) : create(null);
6851
6949
  CUSTOM_ELEMENT_HANDLING = create(null);
6852
6950
  if (objectHasOwnProperty(customElementHandling, "tagNameCheck") && isRegexOrFunction(customElementHandling.tagNameCheck)) {
@@ -6858,6 +6956,7 @@ function createDOMPurify() {
6858
6956
  if (objectHasOwnProperty(customElementHandling, "allowCustomizedBuiltInElements") && typeof customElementHandling.allowCustomizedBuiltInElements === "boolean") {
6859
6957
  CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = customElementHandling.allowCustomizedBuiltInElements;
6860
6958
  }
6959
+ seal(CUSTOM_ELEMENT_HANDLING);
6861
6960
  if (SAFE_FOR_TEMPLATES) {
6862
6961
  ALLOW_DATA_ATTR = false;
6863
6962
  }
@@ -6941,22 +7040,25 @@ function createDOMPurify() {
6941
7040
  if (typeof cfg.TRUSTED_TYPES_POLICY.createScriptURL !== "function") {
6942
7041
  throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');
6943
7042
  }
7043
+ const previousTrustedTypesPolicy = trustedTypesPolicy;
6944
7044
  trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY;
6945
- emptyHTML = trustedTypesPolicy.createHTML("");
7045
+ try {
7046
+ emptyHTML = _createTrustedHTML("");
7047
+ } catch (error) {
7048
+ trustedTypesPolicy = previousTrustedTypesPolicy;
7049
+ throw error;
7050
+ }
7051
+ } else if (cfg.TRUSTED_TYPES_POLICY === null) {
7052
+ trustedTypesPolicy = void 0;
7053
+ emptyHTML = "";
6946
7054
  } else {
6947
7055
  if (trustedTypesPolicy === void 0) {
6948
- trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, currentScript);
7056
+ trustedTypesPolicy = _getDefaultTrustedTypesPolicy();
6949
7057
  }
6950
- if (trustedTypesPolicy !== null && typeof emptyHTML === "string") {
6951
- emptyHTML = trustedTypesPolicy.createHTML("");
7058
+ if (trustedTypesPolicy && typeof emptyHTML === "string") {
7059
+ emptyHTML = _createTrustedHTML("");
6952
7060
  }
6953
7061
  }
6954
- if ((hooks.uponSanitizeElement.length > 0 || hooks.uponSanitizeAttribute.length > 0) && ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {
6955
- ALLOWED_TAGS = clone(ALLOWED_TAGS);
6956
- }
6957
- if (hooks.uponSanitizeAttribute.length > 0 && ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {
6958
- ALLOWED_ATTR = clone(ALLOWED_ATTR);
6959
- }
6960
7062
  if (freeze) {
6961
7063
  freeze(cfg);
6962
7064
  }
@@ -6964,6 +7066,33 @@ function createDOMPurify() {
6964
7066
  };
6965
7067
  const ALL_SVG_TAGS = addToSet({}, [...svg$1, ...svgFilters, ...svgDisallowed]);
6966
7068
  const ALL_MATHML_TAGS = addToSet({}, [...mathMl$1, ...mathMlDisallowed]);
7069
+ const _checkSvgNamespace = function _checkSvgNamespace2(tagName, parent, parentTagName) {
7070
+ if (parent.namespaceURI === HTML_NAMESPACE) {
7071
+ return tagName === "svg";
7072
+ }
7073
+ if (parent.namespaceURI === MATHML_NAMESPACE) {
7074
+ return tagName === "svg" && (parentTagName === "annotation-xml" || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]);
7075
+ }
7076
+ return Boolean(ALL_SVG_TAGS[tagName]);
7077
+ };
7078
+ const _checkMathMlNamespace = function _checkMathMlNamespace2(tagName, parent, parentTagName) {
7079
+ if (parent.namespaceURI === HTML_NAMESPACE) {
7080
+ return tagName === "math";
7081
+ }
7082
+ if (parent.namespaceURI === SVG_NAMESPACE2) {
7083
+ return tagName === "math" && HTML_INTEGRATION_POINTS[parentTagName];
7084
+ }
7085
+ return Boolean(ALL_MATHML_TAGS[tagName]);
7086
+ };
7087
+ const _checkHtmlNamespace = function _checkHtmlNamespace2(tagName, parent, parentTagName) {
7088
+ if (parent.namespaceURI === SVG_NAMESPACE2 && !HTML_INTEGRATION_POINTS[parentTagName]) {
7089
+ return false;
7090
+ }
7091
+ if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) {
7092
+ return false;
7093
+ }
7094
+ return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]);
7095
+ };
6967
7096
  const _checkValidNamespace = function _checkValidNamespace2(element) {
6968
7097
  let parent = getParentNode(element);
6969
7098
  if (!parent || !parent.tagName) {
@@ -6978,31 +7107,13 @@ function createDOMPurify() {
6978
7107
  return false;
6979
7108
  }
6980
7109
  if (element.namespaceURI === SVG_NAMESPACE2) {
6981
- if (parent.namespaceURI === HTML_NAMESPACE) {
6982
- return tagName === "svg";
6983
- }
6984
- if (parent.namespaceURI === MATHML_NAMESPACE) {
6985
- return tagName === "svg" && (parentTagName === "annotation-xml" || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]);
6986
- }
6987
- return Boolean(ALL_SVG_TAGS[tagName]);
7110
+ return _checkSvgNamespace(tagName, parent, parentTagName);
6988
7111
  }
6989
7112
  if (element.namespaceURI === MATHML_NAMESPACE) {
6990
- if (parent.namespaceURI === HTML_NAMESPACE) {
6991
- return tagName === "math";
6992
- }
6993
- if (parent.namespaceURI === SVG_NAMESPACE2) {
6994
- return tagName === "math" && HTML_INTEGRATION_POINTS[parentTagName];
6995
- }
6996
- return Boolean(ALL_MATHML_TAGS[tagName]);
7113
+ return _checkMathMlNamespace(tagName, parent, parentTagName);
6997
7114
  }
6998
7115
  if (element.namespaceURI === HTML_NAMESPACE) {
6999
- if (parent.namespaceURI === SVG_NAMESPACE2 && !HTML_INTEGRATION_POINTS[parentTagName]) {
7000
- return false;
7001
- }
7002
- if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) {
7003
- return false;
7004
- }
7005
- return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]);
7116
+ return _checkHtmlNamespace(tagName, parent, parentTagName);
7006
7117
  }
7007
7118
  if (PARSER_MEDIA_TYPE === "application/xhtml+xml" && ALLOWED_NAMESPACES[element.namespaceURI]) {
7008
7119
  return true;
@@ -7017,6 +7128,37 @@ function createDOMPurify() {
7017
7128
  getParentNode(node).removeChild(node);
7018
7129
  } catch (_) {
7019
7130
  remove(node);
7131
+ if (!getParentNode(node)) {
7132
+ throw typeErrorCreate("a node selected for removal could not be detached from its tree and cannot be safely returned; refusing to sanitize in place");
7133
+ }
7134
+ }
7135
+ };
7136
+ const _neutralizeRoot = function _neutralizeRoot2(root2) {
7137
+ const childNodes = getChildNodes(root2);
7138
+ if (childNodes) {
7139
+ const snapshot = [];
7140
+ arrayForEach(childNodes, (child) => {
7141
+ arrayPush(snapshot, child);
7142
+ });
7143
+ arrayForEach(snapshot, (child) => {
7144
+ try {
7145
+ remove(child);
7146
+ } catch (_) {
7147
+ }
7148
+ });
7149
+ }
7150
+ const attributes = getAttributes(root2);
7151
+ if (attributes) {
7152
+ for (let i = attributes.length - 1; i >= 0; --i) {
7153
+ const attribute = attributes[i];
7154
+ const name = attribute && attribute.name;
7155
+ if (typeof name === "string") {
7156
+ try {
7157
+ root2.removeAttribute(name);
7158
+ } catch (_) {
7159
+ }
7160
+ }
7161
+ }
7020
7162
  }
7021
7163
  };
7022
7164
  const _removeAttribute = function _removeAttribute2(name, element) {
@@ -7046,6 +7188,39 @@ function createDOMPurify() {
7046
7188
  }
7047
7189
  }
7048
7190
  };
7191
+ const _stripDisallowedAttributes = function _stripDisallowedAttributes2(element) {
7192
+ const attributes = getAttributes(element);
7193
+ if (!attributes) {
7194
+ return;
7195
+ }
7196
+ for (let i = attributes.length - 1; i >= 0; --i) {
7197
+ const attribute = attributes[i];
7198
+ const name = attribute && attribute.name;
7199
+ if (typeof name !== "string" || ALLOWED_ATTR[transformCaseFunc(name)]) {
7200
+ continue;
7201
+ }
7202
+ try {
7203
+ element.removeAttribute(name);
7204
+ } catch (_) {
7205
+ }
7206
+ }
7207
+ };
7208
+ const _neutralizeSubtree = function _neutralizeSubtree2(root2) {
7209
+ const stack = [root2];
7210
+ while (stack.length > 0) {
7211
+ const node = stack.pop();
7212
+ const nodeType = getNodeType ? getNodeType(node) : node.nodeType;
7213
+ if (nodeType === NODE_TYPE.element) {
7214
+ _stripDisallowedAttributes(node);
7215
+ }
7216
+ const childNodes = getChildNodes(node);
7217
+ if (childNodes) {
7218
+ for (let i = childNodes.length - 1; i >= 0; --i) {
7219
+ stack.push(childNodes[i]);
7220
+ }
7221
+ }
7222
+ }
7223
+ };
7049
7224
  const _initDocument = function _initDocument2(dirty) {
7050
7225
  let doc = null;
7051
7226
  let leadingWhitespace = null;
@@ -7058,7 +7233,7 @@ function createDOMPurify() {
7058
7233
  if (PARSER_MEDIA_TYPE === "application/xhtml+xml" && NAMESPACE === HTML_NAMESPACE) {
7059
7234
  dirty = '<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>' + dirty + "</body></html>";
7060
7235
  }
7061
- const dirtyPayload = trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty;
7236
+ const dirtyPayload = trustedTypesPolicy ? _createTrustedHTML(dirty) : dirty;
7062
7237
  if (NAMESPACE === HTML_NAMESPACE) {
7063
7238
  try {
7064
7239
  doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE);
@@ -7090,7 +7265,14 @@ function createDOMPurify() {
7090
7265
  null
7091
7266
  );
7092
7267
  };
7093
- const _scrubTemplateExpressions = function _scrubTemplateExpressions2(node) {
7268
+ const _stripTemplateExpressions = function _stripTemplateExpressions2(value) {
7269
+ value = stringReplace(value, MUSTACHE_EXPR$1, " ");
7270
+ value = stringReplace(value, ERB_EXPR$1, " ");
7271
+ value = stringReplace(value, TMPLIT_EXPR$1, " ");
7272
+ return value;
7273
+ };
7274
+ const _scrubTemplateExpressions2 = function _scrubTemplateExpressions(node) {
7275
+ var _node$querySelectorAl;
7094
7276
  node.normalize();
7095
7277
  const walker = createNodeIterator.call(
7096
7278
  node.ownerDocument || node,
@@ -7101,13 +7283,17 @@ function createDOMPurify() {
7101
7283
  );
7102
7284
  let currentNode = walker.nextNode();
7103
7285
  while (currentNode) {
7104
- let data = currentNode.data;
7105
- arrayForEach([MUSTACHE_EXPR$1, ERB_EXPR$1, TMPLIT_EXPR$1], (expr) => {
7106
- data = stringReplace(data, expr, " ");
7107
- });
7108
- currentNode.data = data;
7286
+ currentNode.data = _stripTemplateExpressions(currentNode.data);
7109
7287
  currentNode = walker.nextNode();
7110
7288
  }
7289
+ const templates = (_node$querySelectorAl = node.querySelectorAll) === null || _node$querySelectorAl === void 0 ? void 0 : _node$querySelectorAl.call(node, "template");
7290
+ if (templates) {
7291
+ arrayForEach(templates, (tmpl) => {
7292
+ if (_isDocumentFragment(tmpl.content)) {
7293
+ _scrubTemplateExpressions2(tmpl.content);
7294
+ }
7295
+ });
7296
+ }
7111
7297
  };
7112
7298
  const _isClobbered = function _isClobbered2(element) {
7113
7299
  const realTagName = getNodeName ? getNodeName(element) : null;
@@ -7163,75 +7349,80 @@ function createDOMPurify() {
7163
7349
  }
7164
7350
  };
7165
7351
  function _executeHooks(hooks2, currentNode, data) {
7352
+ if (hooks2.length === 0) {
7353
+ return;
7354
+ }
7166
7355
  arrayForEach(hooks2, (hook) => {
7167
7356
  hook.call(DOMPurify, currentNode, data, CONFIG);
7168
7357
  });
7169
7358
  }
7170
- const _sanitizeElements = function _sanitizeElements2(currentNode) {
7171
- let content = null;
7172
- _executeHooks(hooks.beforeSanitizeElements, currentNode, null);
7173
- if (_isClobbered(currentNode)) {
7174
- _forceRemove(currentNode);
7175
- return true;
7176
- }
7177
- const tagName = transformCaseFunc(currentNode.nodeName);
7178
- _executeHooks(hooks.uponSanitizeElement, currentNode, {
7179
- tagName,
7180
- allowedTags: ALLOWED_TAGS
7181
- });
7182
- if (SAFE_FOR_XML && currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(/<[/\w!]/g, currentNode.innerHTML) && regExpTest(/<[/\w!]/g, currentNode.textContent)) {
7183
- _forceRemove(currentNode);
7359
+ const _isUnsafeNode = function _isUnsafeNode2(currentNode, tagName) {
7360
+ if (SAFE_FOR_XML && currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(ELEMENT_MARKUP_PROBE, currentNode.textContent) && regExpTest(ELEMENT_MARKUP_PROBE, currentNode.innerHTML)) {
7184
7361
  return true;
7185
7362
  }
7186
7363
  if (SAFE_FOR_XML && currentNode.namespaceURI === HTML_NAMESPACE && tagName === "style" && _isNode(currentNode.firstElementChild)) {
7187
- _forceRemove(currentNode);
7188
7364
  return true;
7189
7365
  }
7190
- if (currentNode.nodeType === NODE_TYPE.progressingInstruction) {
7191
- _forceRemove(currentNode);
7366
+ if (currentNode.nodeType === NODE_TYPE.processingInstruction) {
7192
7367
  return true;
7193
7368
  }
7194
- if (SAFE_FOR_XML && currentNode.nodeType === NODE_TYPE.comment && regExpTest(/<[/\w]/g, currentNode.data)) {
7195
- _forceRemove(currentNode);
7369
+ if (SAFE_FOR_XML && currentNode.nodeType === NODE_TYPE.comment && regExpTest(COMMENT_MARKUP_PROBE, currentNode.data)) {
7196
7370
  return true;
7197
7371
  }
7198
- if (FORBID_TAGS[tagName] || !(EXTRA_ELEMENT_HANDLING.tagCheck instanceof Function && EXTRA_ELEMENT_HANDLING.tagCheck(tagName)) && !ALLOWED_TAGS[tagName]) {
7199
- if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {
7200
- if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) {
7201
- return false;
7202
- }
7203
- if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) {
7204
- return false;
7205
- }
7372
+ return false;
7373
+ };
7374
+ const _sanitizeDisallowedNode = function _sanitizeDisallowedNode2(currentNode, tagName) {
7375
+ if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {
7376
+ if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) {
7377
+ return false;
7206
7378
  }
7207
- if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {
7208
- const parentNode = getParentNode(currentNode);
7209
- const childNodes = getChildNodes(currentNode);
7210
- if (childNodes && parentNode) {
7211
- const childCount = childNodes.length;
7212
- for (let i = childCount - 1; i >= 0; --i) {
7213
- const childClone = cloneNode(childNodes[i], true);
7214
- parentNode.insertBefore(childClone, getNextSibling(currentNode));
7215
- }
7379
+ if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) {
7380
+ return false;
7381
+ }
7382
+ }
7383
+ if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {
7384
+ const parentNode = getParentNode(currentNode);
7385
+ const childNodes = getChildNodes(currentNode);
7386
+ if (childNodes && parentNode) {
7387
+ const childCount = childNodes.length;
7388
+ for (let i = childCount - 1; i >= 0; --i) {
7389
+ const hoisted = IN_PLACE ? childNodes[i] : cloneNode(childNodes[i], true);
7390
+ parentNode.insertBefore(hoisted, getNextSibling(currentNode));
7216
7391
  }
7217
7392
  }
7393
+ }
7394
+ _forceRemove(currentNode);
7395
+ return true;
7396
+ };
7397
+ const _sanitizeElements = function _sanitizeElements2(currentNode) {
7398
+ _executeHooks(hooks.beforeSanitizeElements, currentNode, null);
7399
+ if (_isClobbered(currentNode)) {
7400
+ _forceRemove(currentNode);
7401
+ return true;
7402
+ }
7403
+ const tagName = transformCaseFunc(getNodeName ? getNodeName(currentNode) : currentNode.nodeName);
7404
+ _executeHooks(hooks.uponSanitizeElement, currentNode, {
7405
+ tagName,
7406
+ allowedTags: ALLOWED_TAGS
7407
+ });
7408
+ if (_isUnsafeNode(currentNode, tagName)) {
7218
7409
  _forceRemove(currentNode);
7219
7410
  return true;
7220
7411
  }
7412
+ if (FORBID_TAGS[tagName] || !(EXTRA_ELEMENT_HANDLING.tagCheck instanceof Function && EXTRA_ELEMENT_HANDLING.tagCheck(tagName)) && !ALLOWED_TAGS[tagName]) {
7413
+ return _sanitizeDisallowedNode(currentNode, tagName);
7414
+ }
7221
7415
  const nt = getNodeType ? getNodeType(currentNode) : currentNode.nodeType;
7222
7416
  if (nt === NODE_TYPE.element && !_checkValidNamespace(currentNode)) {
7223
7417
  _forceRemove(currentNode);
7224
7418
  return true;
7225
7419
  }
7226
- if ((tagName === "noscript" || tagName === "noembed" || tagName === "noframes") && regExpTest(/<\/no(script|embed|frames)/i, currentNode.innerHTML)) {
7420
+ if ((tagName === "noscript" || tagName === "noembed" || tagName === "noframes") && regExpTest(FALLBACK_TAG_CLOSE, currentNode.innerHTML)) {
7227
7421
  _forceRemove(currentNode);
7228
7422
  return true;
7229
7423
  }
7230
7424
  if (SAFE_FOR_TEMPLATES && currentNode.nodeType === NODE_TYPE.text) {
7231
- content = currentNode.textContent;
7232
- arrayForEach([MUSTACHE_EXPR$1, ERB_EXPR$1, TMPLIT_EXPR$1], (expr) => {
7233
- content = stringReplace(content, expr, " ");
7234
- });
7425
+ const content = _stripTemplateExpressions(currentNode.textContent);
7235
7426
  if (currentNode.textContent !== content) {
7236
7427
  arrayPush(DOMPurify.removed, {
7237
7428
  element: currentNode.cloneNode()
@@ -7250,9 +7441,9 @@ function createDOMPurify() {
7250
7441
  return false;
7251
7442
  }
7252
7443
  const nameIsPermitted = ALLOWED_ATTR[lcName] || EXTRA_ELEMENT_HANDLING.attributeCheck instanceof Function && EXTRA_ELEMENT_HANDLING.attributeCheck(lcName, lcTag);
7253
- if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR$1, lcName)) ;
7444
+ if (ALLOW_DATA_ATTR && regExpTest(DATA_ATTR$1, lcName)) ;
7254
7445
  else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR$1, lcName)) ;
7255
- else if (!nameIsPermitted || FORBID_ATTR[lcName]) {
7446
+ else if (!nameIsPermitted) {
7256
7447
  if (
7257
7448
  // First condition does a very basic check if a) it's basically a valid custom element tagname AND
7258
7449
  // b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
@@ -7277,6 +7468,35 @@ function createDOMPurify() {
7277
7468
  const _isBasicCustomElement = function _isBasicCustomElement2(tagName) {
7278
7469
  return !RESERVED_CUSTOM_ELEMENT_NAMES[stringToLowerCase(tagName)] && regExpTest(CUSTOM_ELEMENT$1, tagName);
7279
7470
  };
7471
+ const _applyTrustedTypesToAttribute = function _applyTrustedTypesToAttribute2(lcTag, lcName, namespaceURI, value) {
7472
+ if (trustedTypesPolicy && typeof trustedTypes === "object" && typeof trustedTypes.getAttributeType === "function" && !namespaceURI) {
7473
+ switch (trustedTypes.getAttributeType(lcTag, lcName)) {
7474
+ case "TrustedHTML": {
7475
+ return _createTrustedHTML(value);
7476
+ }
7477
+ case "TrustedScriptURL": {
7478
+ return _createTrustedScriptURL(value);
7479
+ }
7480
+ }
7481
+ }
7482
+ return value;
7483
+ };
7484
+ const _setAttributeValue = function _setAttributeValue2(currentNode, name, namespaceURI, value) {
7485
+ try {
7486
+ if (namespaceURI) {
7487
+ currentNode.setAttributeNS(namespaceURI, name, value);
7488
+ } else {
7489
+ currentNode.setAttribute(name, value);
7490
+ }
7491
+ if (_isClobbered(currentNode)) {
7492
+ _forceRemove(currentNode);
7493
+ } else {
7494
+ arrayPop(DOMPurify.removed);
7495
+ }
7496
+ } catch (_) {
7497
+ _removeAttribute(name, currentNode);
7498
+ }
7499
+ };
7280
7500
  const _sanitizeAttributes = function _sanitizeAttributes2(currentNode) {
7281
7501
  _executeHooks(hooks.beforeSanitizeAttributes, currentNode, null);
7282
7502
  const attributes = currentNode.attributes;
@@ -7291,6 +7511,7 @@ function createDOMPurify() {
7291
7511
  forceKeepAttr: void 0
7292
7512
  };
7293
7513
  let l = attributes.length;
7514
+ const lcTag = transformCaseFunc(currentNode.nodeName);
7294
7515
  while (l--) {
7295
7516
  const attr = attributes[l];
7296
7517
  const name = attr.name, namespaceURI = attr.namespaceURI, attrValue = attr.value;
@@ -7322,50 +7543,20 @@ function createDOMPurify() {
7322
7543
  _removeAttribute(name, currentNode);
7323
7544
  continue;
7324
7545
  }
7325
- if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(/\/>/i, value)) {
7546
+ if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(SELF_CLOSING_TAG, value)) {
7326
7547
  _removeAttribute(name, currentNode);
7327
7548
  continue;
7328
7549
  }
7329
7550
  if (SAFE_FOR_TEMPLATES) {
7330
- arrayForEach([MUSTACHE_EXPR$1, ERB_EXPR$1, TMPLIT_EXPR$1], (expr) => {
7331
- value = stringReplace(value, expr, " ");
7332
- });
7551
+ value = _stripTemplateExpressions(value);
7333
7552
  }
7334
- const lcTag = transformCaseFunc(currentNode.nodeName);
7335
7553
  if (!_isValidAttribute(lcTag, lcName, value)) {
7336
7554
  _removeAttribute(name, currentNode);
7337
7555
  continue;
7338
7556
  }
7339
- if (trustedTypesPolicy && typeof trustedTypes === "object" && typeof trustedTypes.getAttributeType === "function") {
7340
- if (namespaceURI) ;
7341
- else {
7342
- switch (trustedTypes.getAttributeType(lcTag, lcName)) {
7343
- case "TrustedHTML": {
7344
- value = trustedTypesPolicy.createHTML(value);
7345
- break;
7346
- }
7347
- case "TrustedScriptURL": {
7348
- value = trustedTypesPolicy.createScriptURL(value);
7349
- break;
7350
- }
7351
- }
7352
- }
7353
- }
7557
+ value = _applyTrustedTypesToAttribute(lcTag, lcName, namespaceURI, value);
7354
7558
  if (value !== initValue) {
7355
- try {
7356
- if (namespaceURI) {
7357
- currentNode.setAttributeNS(namespaceURI, name, value);
7358
- } else {
7359
- currentNode.setAttribute(name, value);
7360
- }
7361
- if (_isClobbered(currentNode)) {
7362
- _forceRemove(currentNode);
7363
- } else {
7364
- arrayPop(DOMPurify.removed);
7365
- }
7366
- } catch (_) {
7367
- _removeAttribute(name, currentNode);
7368
- }
7559
+ _setAttributeValue(currentNode, name, namespaceURI, value);
7369
7560
  }
7370
7561
  }
7371
7562
  _executeHooks(hooks.afterSanitizeAttributes, currentNode, null);
@@ -7383,41 +7574,60 @@ function createDOMPurify() {
7383
7574
  }
7384
7575
  const shadowNodeType = getNodeType ? getNodeType(shadowNode) : shadowNode.nodeType;
7385
7576
  if (shadowNodeType === NODE_TYPE.element) {
7386
- const innerSr = getShadowRoot ? getShadowRoot(shadowNode) : shadowNode.shadowRoot;
7577
+ const innerSr = getShadowRoot(shadowNode);
7387
7578
  if (_isDocumentFragment(innerSr)) {
7388
- _sanitizeAttachedShadowRoots2(innerSr);
7579
+ _sanitizeAttachedShadowRoots(innerSr);
7389
7580
  _sanitizeShadowDOM2(innerSr);
7390
7581
  }
7391
7582
  }
7392
7583
  }
7393
7584
  _executeHooks(hooks.afterSanitizeShadowDOM, fragment, null);
7394
7585
  };
7395
- const _sanitizeAttachedShadowRoots2 = function _sanitizeAttachedShadowRoots(root2) {
7396
- const nodeType = getNodeType ? getNodeType(root2) : root2.nodeType;
7397
- if (nodeType === NODE_TYPE.element) {
7398
- const sr = getShadowRoot ? getShadowRoot(root2) : root2.shadowRoot;
7399
- if (_isDocumentFragment(sr)) {
7400
- _sanitizeAttachedShadowRoots2(sr);
7401
- _sanitizeShadowDOM2(sr);
7586
+ const _sanitizeAttachedShadowRoots = function _sanitizeAttachedShadowRoots2(root2) {
7587
+ const stack = [{
7588
+ node: root2,
7589
+ shadow: null
7590
+ }];
7591
+ while (stack.length > 0) {
7592
+ const item = stack.pop();
7593
+ if (item.shadow) {
7594
+ _sanitizeShadowDOM2(item.shadow);
7595
+ continue;
7402
7596
  }
7403
- }
7404
- const childNodes = getChildNodes ? getChildNodes(root2) : root2.childNodes;
7405
- if (!childNodes) {
7406
- return;
7407
- }
7408
- const snapshot = [];
7409
- arrayForEach(childNodes, (child) => {
7410
- arrayPush(snapshot, child);
7411
- });
7412
- for (const child of snapshot) {
7413
- _sanitizeAttachedShadowRoots2(child);
7414
- }
7415
- if (nodeType === NODE_TYPE.element) {
7416
- const rootName = getNodeName ? getNodeName(root2) : null;
7417
- if (typeof rootName === "string" && transformCaseFunc(rootName) === "template") {
7418
- const content = root2.content;
7419
- if (_isDocumentFragment(content)) {
7420
- _sanitizeAttachedShadowRoots2(content);
7597
+ const node = item.node;
7598
+ const nodeType = getNodeType ? getNodeType(node) : node.nodeType;
7599
+ const isElement = nodeType === NODE_TYPE.element;
7600
+ const childNodes = getChildNodes(node);
7601
+ if (childNodes) {
7602
+ for (let i = childNodes.length - 1; i >= 0; --i) {
7603
+ stack.push({
7604
+ node: childNodes[i],
7605
+ shadow: null
7606
+ });
7607
+ }
7608
+ }
7609
+ if (isElement) {
7610
+ const rootName = getNodeName ? getNodeName(node) : null;
7611
+ if (typeof rootName === "string" && transformCaseFunc(rootName) === "template") {
7612
+ const content = node.content;
7613
+ if (_isDocumentFragment(content)) {
7614
+ stack.push({
7615
+ node: content,
7616
+ shadow: null
7617
+ });
7618
+ }
7619
+ }
7620
+ }
7621
+ if (isElement) {
7622
+ const sr = getShadowRoot(node);
7623
+ if (_isDocumentFragment(sr)) {
7624
+ stack.push({
7625
+ node: null,
7626
+ shadow: sr
7627
+ }, {
7628
+ node: sr,
7629
+ shadow: null
7630
+ });
7421
7631
  }
7422
7632
  }
7423
7633
  }
@@ -7441,14 +7651,21 @@ function createDOMPurify() {
7441
7651
  if (!DOMPurify.isSupported) {
7442
7652
  return dirty;
7443
7653
  }
7444
- if (!SET_CONFIG) {
7654
+ if (SET_CONFIG) {
7655
+ ALLOWED_TAGS = SET_CONFIG_ALLOWED_TAGS;
7656
+ ALLOWED_ATTR = SET_CONFIG_ALLOWED_ATTR;
7657
+ } else {
7445
7658
  _parseConfig(cfg);
7446
7659
  }
7447
- DOMPurify.removed = [];
7448
- if (typeof dirty === "string") {
7449
- IN_PLACE = false;
7660
+ if (hooks.uponSanitizeElement.length > 0 || hooks.uponSanitizeAttribute.length > 0) {
7661
+ ALLOWED_TAGS = clone(ALLOWED_TAGS);
7450
7662
  }
7451
- if (IN_PLACE) {
7663
+ if (hooks.uponSanitizeAttribute.length > 0) {
7664
+ ALLOWED_ATTR = clone(ALLOWED_ATTR);
7665
+ }
7666
+ DOMPurify.removed = [];
7667
+ const inPlace = IN_PLACE && typeof dirty !== "string" && _isNode(dirty);
7668
+ if (inPlace) {
7452
7669
  const nn = getNodeName ? getNodeName(dirty) : dirty.nodeName;
7453
7670
  if (typeof nn === "string") {
7454
7671
  const tagName = transformCaseFunc(nn);
@@ -7459,7 +7676,12 @@ function createDOMPurify() {
7459
7676
  if (_isClobbered(dirty)) {
7460
7677
  throw typeErrorCreate("root node is clobbered and cannot be sanitized in-place");
7461
7678
  }
7462
- _sanitizeAttachedShadowRoots2(dirty);
7679
+ try {
7680
+ _sanitizeAttachedShadowRoots(dirty);
7681
+ } catch (error) {
7682
+ _neutralizeRoot(dirty);
7683
+ throw error;
7684
+ }
7463
7685
  } else if (_isNode(dirty)) {
7464
7686
  body = _initDocument("<!---->");
7465
7687
  importedNode = body.ownerDocument.importNode(dirty, true);
@@ -7470,11 +7692,11 @@ function createDOMPurify() {
7470
7692
  } else {
7471
7693
  body.appendChild(importedNode);
7472
7694
  }
7473
- _sanitizeAttachedShadowRoots2(importedNode);
7695
+ _sanitizeAttachedShadowRoots(importedNode);
7474
7696
  } else {
7475
7697
  if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT && // eslint-disable-next-line unicorn/prefer-includes
7476
7698
  dirty.indexOf("<") === -1) {
7477
- return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(dirty) : dirty;
7699
+ return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? _createTrustedHTML(dirty) : dirty;
7478
7700
  }
7479
7701
  body = _initDocument(dirty);
7480
7702
  if (!body) {
@@ -7484,23 +7706,35 @@ function createDOMPurify() {
7484
7706
  if (body && FORCE_BODY) {
7485
7707
  _forceRemove(body.firstChild);
7486
7708
  }
7487
- const nodeIterator = _createNodeIterator(IN_PLACE ? dirty : body);
7488
- while (currentNode = nodeIterator.nextNode()) {
7489
- _sanitizeElements(currentNode);
7490
- _sanitizeAttributes(currentNode);
7491
- if (_isDocumentFragment(currentNode.content)) {
7492
- _sanitizeShadowDOM2(currentNode.content);
7709
+ const nodeIterator = _createNodeIterator(inPlace ? dirty : body);
7710
+ try {
7711
+ while (currentNode = nodeIterator.nextNode()) {
7712
+ _sanitizeElements(currentNode);
7713
+ _sanitizeAttributes(currentNode);
7714
+ if (_isDocumentFragment(currentNode.content)) {
7715
+ _sanitizeShadowDOM2(currentNode.content);
7716
+ }
7717
+ }
7718
+ } catch (error) {
7719
+ if (inPlace) {
7720
+ _neutralizeRoot(dirty);
7493
7721
  }
7722
+ throw error;
7494
7723
  }
7495
- if (IN_PLACE) {
7724
+ if (inPlace) {
7725
+ arrayForEach(DOMPurify.removed, (entry) => {
7726
+ if (entry.element) {
7727
+ _neutralizeSubtree(entry.element);
7728
+ }
7729
+ });
7496
7730
  if (SAFE_FOR_TEMPLATES) {
7497
- _scrubTemplateExpressions(dirty);
7731
+ _scrubTemplateExpressions2(dirty);
7498
7732
  }
7499
7733
  return dirty;
7500
7734
  }
7501
7735
  if (RETURN_DOM) {
7502
7736
  if (SAFE_FOR_TEMPLATES) {
7503
- _scrubTemplateExpressions(body);
7737
+ _scrubTemplateExpressions2(body);
7504
7738
  }
7505
7739
  if (RETURN_DOM_FRAGMENT) {
7506
7740
  returnNode = createDocumentFragment.call(body.ownerDocument);
@@ -7520,20 +7754,24 @@ function createDOMPurify() {
7520
7754
  serializedHTML = "<!DOCTYPE " + body.ownerDocument.doctype.name + ">\n" + serializedHTML;
7521
7755
  }
7522
7756
  if (SAFE_FOR_TEMPLATES) {
7523
- arrayForEach([MUSTACHE_EXPR$1, ERB_EXPR$1, TMPLIT_EXPR$1], (expr) => {
7524
- serializedHTML = stringReplace(serializedHTML, expr, " ");
7525
- });
7757
+ serializedHTML = _stripTemplateExpressions(serializedHTML);
7526
7758
  }
7527
- return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(serializedHTML) : serializedHTML;
7759
+ return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? _createTrustedHTML(serializedHTML) : serializedHTML;
7528
7760
  };
7529
7761
  DOMPurify.setConfig = function() {
7530
7762
  let cfg = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
7531
7763
  _parseConfig(cfg);
7532
7764
  SET_CONFIG = true;
7765
+ SET_CONFIG_ALLOWED_TAGS = ALLOWED_TAGS;
7766
+ SET_CONFIG_ALLOWED_ATTR = ALLOWED_ATTR;
7533
7767
  };
7534
7768
  DOMPurify.clearConfig = function() {
7535
7769
  CONFIG = null;
7536
7770
  SET_CONFIG = false;
7771
+ SET_CONFIG_ALLOWED_TAGS = null;
7772
+ SET_CONFIG_ALLOWED_ATTR = null;
7773
+ trustedTypesPolicy = defaultTrustedTypesPolicy;
7774
+ emptyHTML = "";
7537
7775
  };
7538
7776
  DOMPurify.isValidAttribute = function(tag, attr, value) {
7539
7777
  if (!CONFIG) {
@@ -7547,9 +7785,15 @@ function createDOMPurify() {
7547
7785
  if (typeof hookFunction !== "function") {
7548
7786
  return;
7549
7787
  }
7788
+ if (!objectHasOwnProperty(hooks, entryPoint)) {
7789
+ return;
7790
+ }
7550
7791
  arrayPush(hooks[entryPoint], hookFunction);
7551
7792
  };
7552
7793
  DOMPurify.removeHook = function(entryPoint, hookFunction) {
7794
+ if (!objectHasOwnProperty(hooks, entryPoint)) {
7795
+ return void 0;
7796
+ }
7553
7797
  if (hookFunction !== void 0) {
7554
7798
  const index = arrayLastIndexOf(hooks[entryPoint], hookFunction);
7555
7799
  return index === -1 ? void 0 : arraySplice(hooks[entryPoint], index, 1)[0];
@@ -7557,6 +7801,9 @@ function createDOMPurify() {
7557
7801
  return arrayPop(hooks[entryPoint]);
7558
7802
  };
7559
7803
  DOMPurify.removeHooks = function(entryPoint) {
7804
+ if (!objectHasOwnProperty(hooks, entryPoint)) {
7805
+ return;
7806
+ }
7560
7807
  hooks[entryPoint] = [];
7561
7808
  };
7562
7809
  DOMPurify.removeAllHooks = function() {