@coveo/atomic-react 3.11.21 → 3.11.22

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.
@@ -465,24 +465,65 @@ const renderBreadcrumbContainer = ({ props })=>(children)=>{
465
465
  </div>`;
466
466
  };
467
467
 
468
- /*! @license DOMPurify 3.4.1 | (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.1/LICENSE */
469
-
470
- const {
471
- entries,
472
- setPrototypeOf,
473
- isFrozen,
474
- getPrototypeOf,
475
- getOwnPropertyDescriptor
476
- } = Object;
477
- let {
478
- freeze,
479
- seal,
480
- create
481
- } = Object; // eslint-disable-line import/no-mutable-exports
482
- let {
483
- apply,
484
- construct
485
- } = typeof Reflect !== 'undefined' && Reflect;
468
+ /*! @license DOMPurify 3.4.5 | (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.5/LICENSE */
469
+
470
+ function _arrayLikeToArray$1(r, a) {
471
+ (null == a || a > r.length) && (a = r.length);
472
+ for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
473
+ return n;
474
+ }
475
+ function _arrayWithHoles(r) {
476
+ if (Array.isArray(r)) return r;
477
+ }
478
+ function _iterableToArrayLimit(r, l) {
479
+ var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
480
+ if (null != t) {
481
+ var e,
482
+ n,
483
+ i,
484
+ u,
485
+ a = [],
486
+ f = true,
487
+ o = false;
488
+ try {
489
+ if (i = (t = t.call(r)).next, 0 === l) ; else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
490
+ } catch (r) {
491
+ o = true, n = r;
492
+ } finally {
493
+ try {
494
+ if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
495
+ } finally {
496
+ if (o) throw n;
497
+ }
498
+ }
499
+ return a;
500
+ }
501
+ }
502
+ function _nonIterableRest() {
503
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
504
+ }
505
+ function _slicedToArray(r, e) {
506
+ return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray$1(r, e) || _nonIterableRest();
507
+ }
508
+ function _unsupportedIterableToArray$1(r, a) {
509
+ if (r) {
510
+ if ("string" == typeof r) return _arrayLikeToArray$1(r, a);
511
+ var t = {}.toString.call(r).slice(8, -1);
512
+ 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$1(r, a) : void 0;
513
+ }
514
+ }
515
+
516
+ const entries = Object.entries,
517
+ setPrototypeOf = Object.setPrototypeOf,
518
+ isFrozen = Object.isFrozen,
519
+ getPrototypeOf = Object.getPrototypeOf,
520
+ getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
521
+ let freeze = Object.freeze,
522
+ seal = Object.seal,
523
+ create = Object.create; // eslint-disable-line import/no-mutable-exports
524
+ let _ref = typeof Reflect !== 'undefined' && Reflect,
525
+ apply = _ref.apply,
526
+ construct = _ref.construct;
486
527
  if (!freeze) {
487
528
  freeze = function freeze(x) {
488
529
  return x;
@@ -619,7 +660,10 @@ function cleanArray(array) {
619
660
  */
620
661
  function clone$1(object) {
621
662
  const newObject = create(null);
622
- for (const [property, value] of entries(object)) {
663
+ for (const _ref2 of entries(object)) {
664
+ var _ref3 = _slicedToArray(_ref2, 2);
665
+ const property = _ref3[0];
666
+ const value = _ref3[1];
623
667
  const isPropertyExist = objectHasOwnProperty(object, property);
624
668
  if (isPropertyExist) {
625
669
  if (arrayIsArray(value)) {
@@ -733,15 +777,14 @@ const mathMl$1 = freeze(['math', 'menclose', 'merror', 'mfenced', 'mfrac', 'mgly
733
777
  const mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']);
734
778
  const text = freeze(['#text']);
735
779
 
736
- const html = freeze(['accept', 'action', 'align', 'alt', 'autocapitalize', 'autocomplete', 'autopictureinpicture', 'autoplay', 'background', 'bgcolor', 'border', 'capture', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'controls', 'controlslist', 'coords', 'crossorigin', 'datetime', 'decoding', 'default', 'dir', 'disabled', 'disablepictureinpicture', 'disableremoteplayback', 'download', 'draggable', 'enctype', 'enterkeyhint', 'exportparts', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'inert', 'inputmode', 'integrity', 'ismap', 'kind', 'label', 'lang', 'list', 'loading', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'muted', 'name', 'nonce', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'part', 'pattern', 'placeholder', 'playsinline', 'popover', 'popovertarget', 'popovertargetaction', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'slot', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'translate', 'type', 'usemap', 'valign', 'value', 'width', 'wrap', 'xmlns']);
780
+ const html = freeze(['accept', 'action', 'align', 'alt', 'autocapitalize', 'autocomplete', 'autopictureinpicture', 'autoplay', 'background', 'bgcolor', 'border', 'capture', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'command', 'commandfor', 'controls', 'controlslist', 'coords', 'crossorigin', 'datetime', 'decoding', 'default', 'dir', 'disabled', 'disablepictureinpicture', 'disableremoteplayback', 'download', 'draggable', 'enctype', 'enterkeyhint', 'exportparts', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'inert', 'inputmode', 'integrity', 'ismap', 'kind', 'label', 'lang', 'list', 'loading', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'muted', 'name', 'nonce', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'part', 'pattern', 'placeholder', 'playsinline', 'popover', 'popovertarget', 'popovertargetaction', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'slot', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'translate', 'type', 'usemap', 'valign', 'value', 'width', 'wrap', 'xmlns']);
737
781
  const svg = freeze(['accent-height', 'accumulate', 'additive', 'alignment-baseline', 'amplitude', 'ascent', 'attributename', 'attributetype', 'azimuth', 'basefrequency', 'baseline-shift', 'begin', 'bias', 'by', 'class', 'clip', 'clippathunits', 'clip-path', 'clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cx', 'cy', 'd', 'dx', 'dy', 'diffuseconstant', 'direction', 'display', 'divisor', 'dur', 'edgemode', 'elevation', 'end', 'exponent', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'filterunits', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'fx', 'fy', 'g1', 'g2', 'glyph-name', 'glyphref', 'gradientunits', 'gradienttransform', 'height', 'href', 'id', 'image-rendering', 'in', 'in2', 'intercept', 'k', 'k1', 'k2', 'k3', 'k4', 'kerning', 'keypoints', 'keysplines', 'keytimes', 'lang', 'lengthadjust', 'letter-spacing', 'kernelmatrix', 'kernelunitlength', 'lighting-color', 'local', 'marker-end', 'marker-mid', 'marker-start', 'markerheight', 'markerunits', 'markerwidth', 'maskcontentunits', 'maskunits', 'max', 'mask', 'mask-type', 'media', 'method', 'mode', 'min', 'name', 'numoctaves', 'offset', 'operator', 'opacity', 'order', 'orient', 'orientation', 'origin', 'overflow', 'paint-order', 'path', 'pathlength', 'patterncontentunits', 'patterntransform', 'patternunits', 'points', 'preservealpha', 'preserveaspectratio', 'primitiveunits', 'r', 'rx', 'ry', 'radius', 'refx', 'refy', 'repeatcount', 'repeatdur', 'restart', 'result', 'rotate', 'scale', 'seed', 'shape-rendering', 'slope', 'specularconstant', 'specularexponent', 'spreadmethod', 'startoffset', 'stddeviation', 'stitchtiles', 'stop-color', 'stop-opacity', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke', 'stroke-width', 'style', 'surfacescale', 'systemlanguage', 'tabindex', 'tablevalues', 'targetx', 'targety', 'transform', 'transform-origin', 'text-anchor', 'text-decoration', 'text-rendering', 'textlength', 'type', 'u1', 'u2', 'unicode', 'values', 'viewbox', 'visibility', 'version', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'width', 'word-spacing', 'wrap', 'writing-mode', 'xchannelselector', 'ychannelselector', 'x', 'x1', 'x2', 'xmlns', 'y', 'y1', 'y2', 'z', 'zoomandpan']);
738
782
  const mathMl = freeze(['accent', 'accentunder', 'align', 'bevelled', 'close', 'columnalign', 'columnlines', 'columnspacing', 'columnspan', 'denomalign', 'depth', 'dir', 'display', 'displaystyle', 'encoding', 'fence', 'frame', 'height', 'href', 'id', 'largeop', 'length', 'linethickness', 'lquote', 'lspace', 'mathbackground', 'mathcolor', 'mathsize', 'mathvariant', 'maxsize', 'minsize', 'movablelimits', 'notation', 'numalign', 'open', 'rowalign', 'rowlines', 'rowspacing', 'rowspan', 'rspace', 'rquote', 'scriptlevel', 'scriptminsize', 'scriptsizemultiplier', 'selection', 'separator', 'separators', 'stretchy', 'subscriptshift', 'supscriptshift', 'symmetric', 'voffset', 'width', 'xmlns']);
739
783
  const xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']);
740
784
 
741
- // eslint-disable-next-line unicorn/better-regex
742
- const MUSTACHE_EXPR = seal(/\{\{[\w\W]*|[\w\W]*\}\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode
743
- const ERB_EXPR = seal(/<%[\w\W]*|[\w\W]*%>/gm);
744
- const TMPLIT_EXPR = seal(/\$\{[\w\W]*/gm); // eslint-disable-line unicorn/better-regex
785
+ const MUSTACHE_EXPR = seal(/{{[\w\W]*|^[\w\W]*}}/g);
786
+ const ERB_EXPR = seal(/<%[\w\W]*|^[\w\W]*%>/g);
787
+ const TMPLIT_EXPR = seal(/\${[\w\W]*/g);
745
788
  const DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]+$/); // eslint-disable-line no-useless-escape
746
789
  const ARIA_ATTR = seal(/^aria-[\-\w]+$/); // eslint-disable-line no-useless-escape
747
790
  const IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i // eslint-disable-line no-useless-escape
@@ -752,20 +795,6 @@ const ATTR_WHITESPACE = seal(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205
752
795
  const DOCTYPE_NAME = seal(/^html$/i);
753
796
  const CUSTOM_ELEMENT = seal(/^[a-z][.\w]*(-[.\w]+)+$/i);
754
797
 
755
- var EXPRESSIONS = /*#__PURE__*/Object.freeze({
756
- __proto__: null,
757
- ARIA_ATTR: ARIA_ATTR,
758
- ATTR_WHITESPACE: ATTR_WHITESPACE,
759
- CUSTOM_ELEMENT: CUSTOM_ELEMENT,
760
- DATA_ATTR: DATA_ATTR,
761
- DOCTYPE_NAME: DOCTYPE_NAME,
762
- ERB_EXPR: ERB_EXPR,
763
- IS_ALLOWED_URI: IS_ALLOWED_URI,
764
- IS_SCRIPT_OR_DATA: IS_SCRIPT_OR_DATA,
765
- MUSTACHE_EXPR: MUSTACHE_EXPR,
766
- TMPLIT_EXPR: TMPLIT_EXPR
767
- });
768
-
769
798
  /* eslint-disable @typescript-eslint/indent */
770
799
  // https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType
771
800
  const NODE_TYPE = {
@@ -832,7 +861,7 @@ const _createHooksMap = function _createHooksMap() {
832
861
  function createDOMPurify() {
833
862
  let window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal();
834
863
  const DOMPurify = root => createDOMPurify(root);
835
- DOMPurify.version = '3.4.1';
864
+ DOMPurify.version = '3.4.5';
836
865
  DOMPurify.removed = [];
837
866
  if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document || !window.Element) {
838
867
  // Not running in a browser, provide a factory function
@@ -840,28 +869,26 @@ function createDOMPurify() {
840
869
  DOMPurify.isSupported = false;
841
870
  return DOMPurify;
842
871
  }
843
- let {
844
- document
845
- } = window;
872
+ let document = window.document;
846
873
  const originalDocument = document;
847
874
  const currentScript = originalDocument.currentScript;
848
- const {
849
- DocumentFragment,
850
- HTMLTemplateElement,
851
- Node,
852
- Element,
853
- NodeFilter,
854
- NamedNodeMap = window.NamedNodeMap || window.MozNamedAttrMap,
855
- HTMLFormElement,
856
- DOMParser,
857
- trustedTypes
858
- } = window;
875
+ const DocumentFragment = window.DocumentFragment,
876
+ HTMLTemplateElement = window.HTMLTemplateElement,
877
+ Node = window.Node,
878
+ Element = window.Element,
879
+ NodeFilter = window.NodeFilter,
880
+ _window$NamedNodeMap = window.NamedNodeMap,
881
+ NamedNodeMap = _window$NamedNodeMap === void 0 ? window.NamedNodeMap || window.MozNamedAttrMap : _window$NamedNodeMap,
882
+ HTMLFormElement = window.HTMLFormElement,
883
+ DOMParser = window.DOMParser,
884
+ trustedTypes = window.trustedTypes;
859
885
  const ElementPrototype = Element.prototype;
860
886
  const cloneNode = lookupGetter(ElementPrototype, 'cloneNode');
861
887
  const remove = lookupGetter(ElementPrototype, 'remove');
862
888
  const getNextSibling = lookupGetter(ElementPrototype, 'nextSibling');
863
889
  const getChildNodes = lookupGetter(ElementPrototype, 'childNodes');
864
890
  const getParentNode = lookupGetter(ElementPrototype, 'parentNode');
891
+ const getNodeType = Node && Node.prototype ? lookupGetter(Node.prototype, 'nodeType') : null;
865
892
  // As per issue #47, the web-components registry is inherited by a
866
893
  // new document created via createHTMLDocument. As per the spec
867
894
  // (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries)
@@ -876,33 +903,26 @@ function createDOMPurify() {
876
903
  }
877
904
  let trustedTypesPolicy;
878
905
  let emptyHTML = '';
879
- const {
880
- implementation,
881
- createNodeIterator,
882
- createDocumentFragment,
883
- getElementsByTagName
884
- } = document;
885
- const {
886
- importNode
887
- } = originalDocument;
906
+ const _document = document,
907
+ implementation = _document.implementation,
908
+ createNodeIterator = _document.createNodeIterator,
909
+ createDocumentFragment = _document.createDocumentFragment,
910
+ getElementsByTagName = _document.getElementsByTagName;
911
+ const importNode = originalDocument.importNode;
888
912
  let hooks = _createHooksMap();
889
913
  /**
890
914
  * Expose whether this browser supports running the full DOMPurify.
891
915
  */
892
916
  DOMPurify.isSupported = typeof entries === 'function' && typeof getParentNode === 'function' && implementation && implementation.createHTMLDocument !== undefined;
893
- const {
894
- MUSTACHE_EXPR,
895
- ERB_EXPR,
896
- TMPLIT_EXPR,
897
- DATA_ATTR,
898
- ARIA_ATTR,
899
- IS_SCRIPT_OR_DATA,
900
- ATTR_WHITESPACE,
901
- CUSTOM_ELEMENT
902
- } = EXPRESSIONS;
903
- let {
904
- IS_ALLOWED_URI: IS_ALLOWED_URI$1
905
- } = EXPRESSIONS;
917
+ const MUSTACHE_EXPR$1 = MUSTACHE_EXPR,
918
+ ERB_EXPR$1 = ERB_EXPR,
919
+ TMPLIT_EXPR$1 = TMPLIT_EXPR,
920
+ DATA_ATTR$1 = DATA_ATTR,
921
+ ARIA_ATTR$1 = ARIA_ATTR,
922
+ IS_SCRIPT_OR_DATA$1 = IS_SCRIPT_OR_DATA,
923
+ ATTR_WHITESPACE$1 = ATTR_WHITESPACE,
924
+ CUSTOM_ELEMENT$1 = CUSTOM_ELEMENT;
925
+ let IS_ALLOWED_URI$1 = IS_ALLOWED_URI;
906
926
  /**
907
927
  * We consider the elements and attributes below to be safe. Ideally
908
928
  * don't add any new ones but feel free to remove unwanted ones.
@@ -1422,6 +1442,40 @@ function createDOMPurify() {
1422
1442
  // eslint-disable-next-line no-bitwise
1423
1443
  NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT | NodeFilter.SHOW_PROCESSING_INSTRUCTION | NodeFilter.SHOW_CDATA_SECTION, null);
1424
1444
  };
1445
+ /**
1446
+ * Strip template-engine expressions ({{...}}, ${...}, <%...%>) from the
1447
+ * character data of an element subtree. Used as the final safety net for
1448
+ * SAFE_FOR_TEMPLATES on every DOM-returning code path so that expressions
1449
+ * which only form after text-node normalization (e.g. fragments split across
1450
+ * stripped elements) cannot survive into a template-evaluating framework.
1451
+ *
1452
+ * Walks text/comment/CDATA/processing-instruction nodes and mutates `.data`
1453
+ * in place rather than round-tripping through innerHTML. This preserves
1454
+ * descendant node references (important for IN_PLACE callers), avoids a
1455
+ * serialize/reparse cycle, and reads literal character data — which means
1456
+ * `<%...%>` in text content matches the ERB regex against its real bytes
1457
+ * instead of the HTML-entity-escaped form innerHTML would produce.
1458
+ *
1459
+ * Attribute values are not visited here; SAFE_FOR_TEMPLATES handling for
1460
+ * attributes is performed during the per-node `_sanitizeAttributes` pass.
1461
+ *
1462
+ * @param node The root element whose character data should be scrubbed.
1463
+ */
1464
+ const _scrubTemplateExpressions = function _scrubTemplateExpressions(node) {
1465
+ node.normalize();
1466
+ const walker = createNodeIterator.call(node.ownerDocument || node, node,
1467
+ // eslint-disable-next-line no-bitwise
1468
+ NodeFilter.SHOW_TEXT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_CDATA_SECTION | NodeFilter.SHOW_PROCESSING_INSTRUCTION, null);
1469
+ let currentNode = walker.nextNode();
1470
+ while (currentNode) {
1471
+ let data = currentNode.data;
1472
+ arrayForEach([MUSTACHE_EXPR$1, ERB_EXPR$1, TMPLIT_EXPR$1], expr => {
1473
+ data = stringReplace(data, expr, ' ');
1474
+ });
1475
+ currentNode.data = data;
1476
+ currentNode = walker.nextNode();
1477
+ }
1478
+ };
1425
1479
  /**
1426
1480
  * _isClobbered
1427
1481
  *
@@ -1432,13 +1486,31 @@ function createDOMPurify() {
1432
1486
  return element instanceof HTMLFormElement && (typeof element.nodeName !== 'string' || typeof element.textContent !== 'string' || typeof element.removeChild !== 'function' || !(element.attributes instanceof NamedNodeMap) || typeof element.removeAttribute !== 'function' || typeof element.setAttribute !== 'function' || typeof element.namespaceURI !== 'string' || typeof element.insertBefore !== 'function' || typeof element.hasChildNodes !== 'function');
1433
1487
  };
1434
1488
  /**
1435
- * Checks whether the given object is a DOM node.
1489
+ * Checks whether the given object is a DOM node, including nodes that
1490
+ * originate from a different window/realm (e.g. an iframe's
1491
+ * contentDocument). The previous `value instanceof Node` check was
1492
+ * realm-bound: nodes from a different window failed it, causing
1493
+ * sanitize() to silently stringify them and reset IN_PLACE to false,
1494
+ * returning the original node unsanitized. See GHSA-4w3q-35jp-p934.
1495
+ *
1496
+ * Implementation: call the cached `nodeType` getter from Node.prototype
1497
+ * directly on the value. This bypasses any clobbered instance property
1498
+ * (e.g. a child element named "nodeType") and works across realms
1499
+ * because the WebIDL `nodeType` getter reads an internal slot that
1500
+ * every real Node has, regardless of which window minted it.
1436
1501
  *
1437
1502
  * @param value object to check whether it's a DOM node
1438
- * @return true is object is a DOM node
1503
+ * @return true if value is a DOM node from any realm
1439
1504
  */
1440
1505
  const _isNode = function _isNode(value) {
1441
- return typeof Node === 'function' && value instanceof Node;
1506
+ if (!getNodeType || typeof value !== 'object' || value === null) {
1507
+ return false;
1508
+ }
1509
+ try {
1510
+ return typeof getNodeType(value) === 'number';
1511
+ } catch (_) {
1512
+ return false;
1513
+ }
1442
1514
  };
1443
1515
  function _executeHooks(hooks, currentNode, data) {
1444
1516
  arrayForEach(hooks, hook => {
@@ -1530,7 +1602,7 @@ function createDOMPurify() {
1530
1602
  if (SAFE_FOR_TEMPLATES && currentNode.nodeType === NODE_TYPE.text) {
1531
1603
  /* Get the element's text content */
1532
1604
  content = currentNode.textContent;
1533
- arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
1605
+ arrayForEach([MUSTACHE_EXPR$1, ERB_EXPR$1, TMPLIT_EXPR$1], expr => {
1534
1606
  content = stringReplace(content, expr, ' ');
1535
1607
  });
1536
1608
  if (currentNode.textContent !== content) {
@@ -1562,11 +1634,12 @@ function createDOMPurify() {
1562
1634
  if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) {
1563
1635
  return false;
1564
1636
  }
1637
+ const nameIsPermitted = ALLOWED_ATTR[lcName] || EXTRA_ELEMENT_HANDLING.attributeCheck instanceof Function && EXTRA_ELEMENT_HANDLING.attributeCheck(lcName, lcTag);
1565
1638
  /* Allow valid data-* attributes: At least one character after "-"
1566
1639
  (https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)
1567
1640
  XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)
1568
1641
  We don't need to check the value; it's always URI safe. */
1569
- if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR, lcName)) ; else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR, lcName)) ; else if (EXTRA_ELEMENT_HANDLING.attributeCheck instanceof Function && EXTRA_ELEMENT_HANDLING.attributeCheck(lcName, lcTag)) ; else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) {
1642
+ if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR$1, lcName)) ; else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR$1, lcName)) ; else if (!nameIsPermitted || FORBID_ATTR[lcName]) {
1570
1643
  if (
1571
1644
  // First condition does a very basic check if a) it's basically a valid custom element tagname AND
1572
1645
  // b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
@@ -1578,7 +1651,7 @@ function createDOMPurify() {
1578
1651
  return false;
1579
1652
  }
1580
1653
  /* Check value is safe. First, is attr inert? If so, is safe */
1581
- } else if (URI_SAFE_ATTRIBUTES[lcName]) ; else if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE, ''))) ; else if ((lcName === 'src' || lcName === 'xlink:href' || lcName === 'href') && lcTag !== 'script' && stringIndexOf(value, 'data:') === 0 && DATA_URI_TAGS[lcTag]) ; else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA, stringReplace(value, ATTR_WHITESPACE, ''))) ; else if (value) {
1654
+ } else if (URI_SAFE_ATTRIBUTES[lcName]) ; else if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE$1, ''))) ; else if ((lcName === 'src' || lcName === 'xlink:href' || lcName === 'href') && lcTag !== 'script' && stringIndexOf(value, 'data:') === 0 && DATA_URI_TAGS[lcTag]) ; else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA$1, stringReplace(value, ATTR_WHITESPACE$1, ''))) ; else if (value) {
1582
1655
  return false;
1583
1656
  } else ;
1584
1657
  return true;
@@ -1596,7 +1669,7 @@ function createDOMPurify() {
1596
1669
  * @returns Returns true if the tag name meets the basic criteria for a custom element, otherwise false.
1597
1670
  */
1598
1671
  const _isBasicCustomElement = function _isBasicCustomElement(tagName) {
1599
- return !RESERVED_CUSTOM_ELEMENT_NAMES[stringToLowerCase(tagName)] && regExpTest(CUSTOM_ELEMENT, tagName);
1672
+ return !RESERVED_CUSTOM_ELEMENT_NAMES[stringToLowerCase(tagName)] && regExpTest(CUSTOM_ELEMENT$1, tagName);
1600
1673
  };
1601
1674
  /**
1602
1675
  * _sanitizeAttributes
@@ -1611,9 +1684,7 @@ function createDOMPurify() {
1611
1684
  const _sanitizeAttributes = function _sanitizeAttributes(currentNode) {
1612
1685
  /* Execute a hook if present */
1613
1686
  _executeHooks(hooks.beforeSanitizeAttributes, currentNode, null);
1614
- const {
1615
- attributes
1616
- } = currentNode;
1687
+ const attributes = currentNode.attributes;
1617
1688
  /* Check if we have attributes; if not we might have a text node */
1618
1689
  if (!attributes || _isClobbered(currentNode)) {
1619
1690
  return;
@@ -1629,11 +1700,9 @@ function createDOMPurify() {
1629
1700
  /* Go backwards over all attributes; safely remove bad ones */
1630
1701
  while (l--) {
1631
1702
  const attr = attributes[l];
1632
- const {
1633
- name,
1634
- namespaceURI,
1635
- value: attrValue
1636
- } = attr;
1703
+ const name = attr.name,
1704
+ namespaceURI = attr.namespaceURI,
1705
+ attrValue = attr.value;
1637
1706
  const lcName = transformCaseFunc(name);
1638
1707
  const initValue = attrValue;
1639
1708
  let value = name === 'value' ? initValue : stringTrim(initValue);
@@ -1681,7 +1750,7 @@ function createDOMPurify() {
1681
1750
  }
1682
1751
  /* Sanitize attribute content to be template-safe */
1683
1752
  if (SAFE_FOR_TEMPLATES) {
1684
- arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
1753
+ arrayForEach([MUSTACHE_EXPR$1, ERB_EXPR$1, TMPLIT_EXPR$1], expr => {
1685
1754
  value = stringReplace(value, expr, ' ');
1686
1755
  });
1687
1756
  }
@@ -1755,6 +1824,49 @@ function createDOMPurify() {
1755
1824
  /* Execute a hook if present */
1756
1825
  _executeHooks(hooks.afterSanitizeShadowDOM, fragment, null);
1757
1826
  };
1827
+ /**
1828
+ * _sanitizeAttachedShadowRoots
1829
+ *
1830
+ * Walks `root` and feeds every attached shadow root we encounter into
1831
+ * the existing _sanitizeShadowDOM pipeline. The default node iterator
1832
+ * does not descend into shadow trees, so nodes inside an attached
1833
+ * shadow root would otherwise be skipped entirely.
1834
+ *
1835
+ * Two real input paths put attached shadow roots in front of us:
1836
+ * 1. IN_PLACE on a DOM node that already has shadow roots attached.
1837
+ * 2. DOM-node input where importNode(dirty, true) deep-clones the
1838
+ * shadow root because it was created with `clonable: true`.
1839
+ *
1840
+ * This pass runs once, up front, so the main iteration loop (and the
1841
+ * existing _sanitizeShadowDOM template-content recursion) stay
1842
+ * untouched — string-input paths are not affected.
1843
+ *
1844
+ * @param root the subtree root to walk for attached shadow roots
1845
+ */
1846
+ const _sanitizeAttachedShadowRoots2 = function _sanitizeAttachedShadowRoots(root) {
1847
+ if (root.nodeType === NODE_TYPE.element && root.shadowRoot instanceof DocumentFragment) {
1848
+ const sr = root.shadowRoot;
1849
+ // Recurse first so that nested shadow roots are reached even if
1850
+ // _sanitizeShadowDOM removes hosts at this level.
1851
+ _sanitizeAttachedShadowRoots2(sr);
1852
+ _sanitizeShadowDOM2(sr);
1853
+ }
1854
+ // Snapshot children before recursing. Sanitization of one subtree
1855
+ // (e.g. via an uponSanitizeShadowNode hook) may detach siblings,
1856
+ // and naive nextSibling traversal would silently skip the rest of
1857
+ // the list once a node is detached.
1858
+ const childNodes = root.childNodes;
1859
+ if (!childNodes) {
1860
+ return;
1861
+ }
1862
+ const snapshot = [];
1863
+ arrayForEach(childNodes, child => {
1864
+ arrayPush(snapshot, child);
1865
+ });
1866
+ for (const child of snapshot) {
1867
+ _sanitizeAttachedShadowRoots2(child);
1868
+ }
1869
+ };
1758
1870
  // eslint-disable-next-line complexity
1759
1871
  DOMPurify.sanitize = function (dirty) {
1760
1872
  let cfg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
@@ -1799,7 +1911,10 @@ function createDOMPurify() {
1799
1911
  throw typeErrorCreate('root node is forbidden and cannot be sanitized in-place');
1800
1912
  }
1801
1913
  }
1802
- } else if (dirty instanceof Node) {
1914
+ /* Sanitize attached shadow roots before the main iterator runs.
1915
+ The iterator does not descend into shadow trees. */
1916
+ _sanitizeAttachedShadowRoots2(dirty);
1917
+ } else if (_isNode(dirty)) {
1803
1918
  /* If dirty is a DOM element, append to an empty document to avoid
1804
1919
  elements being stripped by the parser */
1805
1920
  body = _initDocument('<!---->');
@@ -1813,6 +1928,10 @@ function createDOMPurify() {
1813
1928
  // eslint-disable-next-line unicorn/prefer-dom-node-append
1814
1929
  body.appendChild(importedNode);
1815
1930
  }
1931
+ /* Clonable shadow roots are deep-cloned by importNode(); sanitize
1932
+ them before the main iterator runs, since the iterator does not
1933
+ descend into shadow trees. */
1934
+ _sanitizeAttachedShadowRoots2(importedNode);
1816
1935
  } else {
1817
1936
  /* Exit directly if we have nothing to do */
1818
1937
  if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT &&
@@ -1846,17 +1965,15 @@ function createDOMPurify() {
1846
1965
  }
1847
1966
  /* If we sanitized `dirty` in-place, return it. */
1848
1967
  if (IN_PLACE) {
1968
+ if (SAFE_FOR_TEMPLATES) {
1969
+ _scrubTemplateExpressions(dirty);
1970
+ }
1849
1971
  return dirty;
1850
1972
  }
1851
1973
  /* Return sanitized string or DOM */
1852
1974
  if (RETURN_DOM) {
1853
1975
  if (SAFE_FOR_TEMPLATES) {
1854
- body.normalize();
1855
- let html = body.innerHTML;
1856
- arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
1857
- html = stringReplace(html, expr, ' ');
1858
- });
1859
- body.innerHTML = html;
1976
+ _scrubTemplateExpressions(body);
1860
1977
  }
1861
1978
  if (RETURN_DOM_FRAGMENT) {
1862
1979
  returnNode = createDocumentFragment.call(body.ownerDocument);
@@ -1886,7 +2003,7 @@ function createDOMPurify() {
1886
2003
  }
1887
2004
  /* Sanitize final string template-safe */
1888
2005
  if (SAFE_FOR_TEMPLATES) {
1889
- arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
2006
+ arrayForEach([MUSTACHE_EXPR$1, ERB_EXPR$1, TMPLIT_EXPR$1], expr => {
1890
2007
  serializedHTML = stringReplace(serializedHTML, expr, ' ');
1891
2008
  });
1892
2009
  }
@@ -8552,7 +8669,7 @@ function getWindow() {
8552
8669
  }
8553
8670
  function getAtomicEnvironment(headlessVersion) {
8554
8671
  return {
8555
- version: "3.58.0",
8672
+ version: "3.58.1",
8556
8673
  headlessVersion
8557
8674
  };
8558
8675
  }
@@ -11537,7 +11654,7 @@ const bindAnalyticsToLink = (link, { onSelect, onBeginDelayedSelect, onCancelPen
11537
11654
  };
11538
11655
 
11539
11656
  const renderLinkWithItemAnalytics = ({ props })=>(children)=>{
11540
- const { href, className, part, title, stopPropagation = true, ref: refCallback, attributes, tabIndex, target = '_self', rel, onMouseOver, onMouseLeave, onFocus, onBlur, onSelect, onBeginDelayedSelect, onCancelPendingSelect, onInitializeLink } = props;
11657
+ const { href, className, part, title, ariaLabel, stopPropagation = true, ref: refCallback, attributes, tabIndex, target = '_self', rel, onMouseOver, onMouseLeave, onFocus, onBlur, onSelect, onBeginDelayedSelect, onCancelPendingSelect, onInitializeLink } = props;
11541
11658
  return lit.html`
11542
11659
  <a
11543
11660
  class=${ifDefined_js.ifDefined(className)}
@@ -11545,6 +11662,7 @@ const renderLinkWithItemAnalytics = ({ props })=>(children)=>{
11545
11662
  href=${filterProtocol(href)}
11546
11663
  target=${target}
11547
11664
  title=${ifDefined_js.ifDefined(title)}
11665
+ aria-label=${ifDefined_js.ifDefined(ariaLabel)}
11548
11666
  rel=${ifDefined_js.ifDefined(rel)}
11549
11667
  ${ref_js.ref((el)=>{
11550
11668
  if (!el) return;