@ukic/web-components 3.29.0 → 3.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/ic-accordion.js +53 -38
- package/components/ic-accordion.js.map +1 -1
- package/components/ic-button2.js +1 -1
- package/components/ic-button2.js.map +1 -1
- package/components/ic-link2.js +1 -1
- package/components/ic-link2.js.map +1 -1
- package/components/ic-menu-item2.js +1 -1
- package/components/ic-menu-item2.js.map +1 -1
- package/components/ic-menu2.js +276 -37
- package/components/ic-menu2.js.map +1 -1
- package/components/ic-navigation-button.js +8 -5
- package/components/ic-navigation-button.js.map +1 -1
- package/components/ic-navigation-group.js +9 -5
- package/components/ic-navigation-group.js.map +1 -1
- package/components/ic-radio-group.js +3 -3
- package/components/ic-radio-group.js.map +1 -1
- package/components/ic-side-navigation.js.map +1 -1
- package/components/ic-switch.js.map +1 -1
- package/dist/cjs/ic-accordion.cjs.entry.js +53 -38
- package/dist/cjs/ic-accordion.cjs.entry.js.map +1 -1
- package/dist/cjs/ic-button_3.cjs.entry.js +1 -1
- package/dist/cjs/ic-button_3.cjs.entry.js.map +1 -1
- package/dist/cjs/ic-input-component-container_3.cjs.entry.js +276 -37
- package/dist/cjs/ic-input-component-container_3.cjs.entry.js.map +1 -1
- package/dist/cjs/ic-link.cjs.entry.js +1 -1
- package/dist/cjs/ic-link.cjs.entry.js.map +1 -1
- package/dist/cjs/ic-menu-item.cjs.entry.js +1 -1
- package/dist/cjs/ic-menu-item.cjs.entry.js.map +1 -1
- package/dist/cjs/ic-navigation-button.cjs.entry.js +8 -5
- package/dist/cjs/ic-navigation-button.cjs.entry.js.map +1 -1
- package/dist/cjs/ic-navigation-group.cjs.entry.js +9 -5
- package/dist/cjs/ic-navigation-group.cjs.entry.js.map +1 -1
- package/dist/cjs/ic-radio-group.cjs.entry.js +3 -3
- package/dist/cjs/ic-radio-group.cjs.entry.js.map +1 -1
- package/dist/cjs/ic-section-container.cjs.entry.js.map +1 -1
- package/dist/collection/components/ic-accordion/ic-accordion.js +53 -38
- package/dist/collection/components/ic-accordion/ic-accordion.js.map +1 -1
- package/dist/collection/components/ic-button/ic-button.css +6 -0
- package/dist/collection/components/ic-link/ic-link.css +4 -0
- package/dist/collection/components/ic-menu/ic-menu.css +14 -5
- package/dist/collection/components/ic-menu-item/ic-menu-item.css +13 -6
- package/dist/collection/components/ic-navigation-button/ic-navigation-button.js +8 -5
- package/dist/collection/components/ic-navigation-button/ic-navigation-button.js.map +1 -1
- package/dist/collection/components/ic-navigation-group/ic-navigation-group.js +9 -5
- package/dist/collection/components/ic-navigation-group/ic-navigation-group.js.map +1 -1
- package/dist/collection/components/ic-radio-group/ic-radio-group.js +3 -3
- package/dist/collection/components/ic-radio-group/ic-radio-group.js.map +1 -1
- package/dist/collection/utils/common-helpers.js +1 -1
- package/dist/collection/utils/common-helpers.js.map +1 -1
- package/dist/components/ic-accordion.js +53 -38
- package/dist/components/ic-accordion.js.map +1 -1
- package/dist/components/ic-button2.js +1 -1
- package/dist/components/ic-button2.js.map +1 -1
- package/dist/components/ic-hero.js.map +1 -1
- package/dist/components/ic-link2.js +1 -1
- package/dist/components/ic-link2.js.map +1 -1
- package/dist/components/ic-menu-item2.js +1 -1
- package/dist/components/ic-menu-item2.js.map +1 -1
- package/dist/components/ic-menu2.js +276 -37
- package/dist/components/ic-menu2.js.map +1 -1
- package/dist/components/ic-navigation-button.js +8 -5
- package/dist/components/ic-navigation-button.js.map +1 -1
- package/dist/components/ic-navigation-group.js +9 -5
- package/dist/components/ic-navigation-group.js.map +1 -1
- package/dist/components/ic-radio-group.js +3 -3
- package/dist/components/ic-radio-group.js.map +1 -1
- package/dist/components/ic-switch.js.map +1 -1
- package/dist/core/core.esm.js +1 -1
- package/dist/core/{p-9ced00a7.entry.js → p-41bbdc4c.entry.js} +2 -2
- package/dist/core/{p-9ced00a7.entry.js.map → p-41bbdc4c.entry.js.map} +1 -1
- package/dist/core/p-51fc7809.entry.js +2 -0
- package/dist/core/p-51fc7809.entry.js.map +1 -0
- package/dist/core/{p-e5266c19.entry.js → p-67048b2e.entry.js} +2 -2
- package/dist/core/{p-e5266c19.entry.js.map → p-67048b2e.entry.js.map} +1 -1
- package/dist/core/p-756b4cb3.entry.js +2 -0
- package/dist/core/p-756b4cb3.entry.js.map +1 -0
- package/dist/core/p-78e56db1.entry.js +2 -0
- package/dist/core/p-78e56db1.entry.js.map +1 -0
- package/dist/core/{p-1cfaa962.entry.js → p-95849ac2.entry.js} +2 -2
- package/dist/core/p-95849ac2.entry.js.map +1 -0
- package/dist/core/{p-fc4b7d2b.entry.js → p-9cf35c23.entry.js} +2 -2
- package/dist/core/p-9cf35c23.entry.js.map +1 -0
- package/dist/core/p-a8d98164.entry.js.map +1 -1
- package/dist/core/p-e5178830.entry.js +3 -0
- package/dist/core/p-e5178830.entry.js.map +1 -0
- package/dist/esm/ic-accordion.entry.js +53 -38
- package/dist/esm/ic-accordion.entry.js.map +1 -1
- package/dist/esm/ic-button_3.entry.js +1 -1
- package/dist/esm/ic-button_3.entry.js.map +1 -1
- package/dist/esm/ic-input-component-container_3.entry.js +276 -37
- package/dist/esm/ic-input-component-container_3.entry.js.map +1 -1
- package/dist/esm/ic-link.entry.js +1 -1
- package/dist/esm/ic-link.entry.js.map +1 -1
- package/dist/esm/ic-menu-item.entry.js +1 -1
- package/dist/esm/ic-menu-item.entry.js.map +1 -1
- package/dist/esm/ic-navigation-button.entry.js +8 -5
- package/dist/esm/ic-navigation-button.entry.js.map +1 -1
- package/dist/esm/ic-navigation-group.entry.js +9 -5
- package/dist/esm/ic-navigation-group.entry.js.map +1 -1
- package/dist/esm/ic-radio-group.entry.js +3 -3
- package/dist/esm/ic-radio-group.entry.js.map +1 -1
- package/dist/esm/ic-section-container.entry.js.map +1 -1
- package/dist/types/components/ic-accordion/ic-accordion.d.ts +2 -0
- package/dist/types/components/ic-navigation-group/ic-navigation-group.d.ts +1 -0
- package/hydrate/index.js +351 -90
- package/hydrate/index.mjs +351 -90
- package/package.json +4 -2
- package/dist/core/p-1cfaa962.entry.js.map +0 -1
- package/dist/core/p-305d9639.entry.js +0 -3
- package/dist/core/p-305d9639.entry.js.map +0 -1
- package/dist/core/p-98dee727.entry.js +0 -2
- package/dist/core/p-98dee727.entry.js.map +0 -1
- package/dist/core/p-be8bbed8.entry.js +0 -2
- package/dist/core/p-be8bbed8.entry.js.map +0 -1
- package/dist/core/p-c0b70c08.entry.js +0 -2
- package/dist/core/p-c0b70c08.entry.js.map +0 -1
- package/dist/core/p-fc4b7d2b.entry.js.map +0 -1
package/components/ic-menu2.js
CHANGED
|
@@ -11,7 +11,7 @@ var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof win
|
|
|
11
11
|
|
|
12
12
|
var purify = {exports: {}};
|
|
13
13
|
|
|
14
|
-
/*! @license DOMPurify 3.4.
|
|
14
|
+
/*! @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 */
|
|
15
15
|
|
|
16
16
|
(function (module, exports) {
|
|
17
17
|
(function (global, factory) {
|
|
@@ -328,7 +328,7 @@ var purify = {exports: {}};
|
|
|
328
328
|
const text = freeze(['#text']);
|
|
329
329
|
|
|
330
330
|
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']);
|
|
331
|
-
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']);
|
|
331
|
+
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', 'dominant-baseline', '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-orientation', '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']);
|
|
332
332
|
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']);
|
|
333
333
|
const xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']);
|
|
334
334
|
|
|
@@ -441,7 +441,7 @@ var purify = {exports: {}};
|
|
|
441
441
|
function createDOMPurify() {
|
|
442
442
|
let window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal();
|
|
443
443
|
const DOMPurify = root => createDOMPurify(root);
|
|
444
|
-
DOMPurify.version = '3.4.
|
|
444
|
+
DOMPurify.version = '3.4.13';
|
|
445
445
|
DOMPurify.removed = [];
|
|
446
446
|
if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document || !window.Element) {
|
|
447
447
|
// Not running in a browser, provide a factory function
|
|
@@ -468,6 +468,7 @@ var purify = {exports: {}};
|
|
|
468
468
|
const getAttributes = lookupGetter(ElementPrototype, 'attributes');
|
|
469
469
|
const getNodeType = Node && Node.prototype ? lookupGetter(Node.prototype, 'nodeType') : null;
|
|
470
470
|
const getNodeName = Node && Node.prototype ? lookupGetter(Node.prototype, 'nodeName') : null;
|
|
471
|
+
const getOwnerDocument = Node && Node.prototype ? lookupGetter(Node.prototype, 'ownerDocument') : null;
|
|
471
472
|
// As per issue #47, the web-components registry is inherited by a
|
|
472
473
|
// new document created via createHTMLDocument. As per the spec
|
|
473
474
|
// (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries)
|
|
@@ -1119,6 +1120,13 @@ var purify = {exports: {}};
|
|
|
1119
1120
|
* @param root the in-place root to empty
|
|
1120
1121
|
*/
|
|
1121
1122
|
const _neutralizeRoot = function _neutralizeRoot(root) {
|
|
1123
|
+
/* Strip every disallowed attribute (on* handlers included) off the whole
|
|
1124
|
+
subtree BEFORE detaching anything. Detaching first would hand back
|
|
1125
|
+
handler-bearing originals (e.g. an already-loading `<img onerror>`)
|
|
1126
|
+
whose queued resource event still fires in page scope after we throw.
|
|
1127
|
+
Clobber-safe reads; a doomed clobbered node's own attributes are
|
|
1128
|
+
irrelevant while its non-clobbered descendants are reached and scrubbed. */
|
|
1129
|
+
_neutralizeSubtree(root);
|
|
1122
1130
|
const childNodes = getChildNodes(root);
|
|
1123
1131
|
if (childNodes) {
|
|
1124
1132
|
const snapshot = [];
|
|
@@ -1246,6 +1254,82 @@ var purify = {exports: {}};
|
|
|
1246
1254
|
}
|
|
1247
1255
|
}
|
|
1248
1256
|
};
|
|
1257
|
+
/**
|
|
1258
|
+
* _neutralizePatchLinkage
|
|
1259
|
+
*
|
|
1260
|
+
* IN_PLACE entry pre-pass (declarative-partial-updates / streaming
|
|
1261
|
+
* hardening, https://github.com/WICG/declarative-partial-updates).
|
|
1262
|
+
*
|
|
1263
|
+
* The main walk strips patch linkage (`for`/`patchsrc`) and removes range
|
|
1264
|
+
* markers (PIs / markup comments) node-by-node, in document order, AS it
|
|
1265
|
+
* reaches each node. On a live in-place root that leaves a window: from the
|
|
1266
|
+
* moment the root is connected until the walk arrives at a given node, that
|
|
1267
|
+
* node's linkage is live. A patch applied on connection/stream can fire as
|
|
1268
|
+
* a microtask during the walk and inject or teleport an unsanitized DOM
|
|
1269
|
+
* range into a region the iterator has already passed and will not revisit,
|
|
1270
|
+
* so the post-return "tree is sanitized" contract is violated. Sweep the
|
|
1271
|
+
* whole tree once up front and sever every linkage before the walk begins,
|
|
1272
|
+
* closing that window.
|
|
1273
|
+
*
|
|
1274
|
+
* This CANNOT undo a patch that already fired before sanitize ran — that is
|
|
1275
|
+
* the irreducible "do not IN_PLACE a live-connected attacker tree" caveat —
|
|
1276
|
+
* but it closes everything from sanitize-start onward. Gated on SAFE_FOR_XML
|
|
1277
|
+
* to group with the rest of the declarative-partial-updates handling and
|
|
1278
|
+
* stay overridable, consistent with the codebase.
|
|
1279
|
+
*
|
|
1280
|
+
* Clobber-safe traversal (cached childNodes getter); per-node try/catch so a
|
|
1281
|
+
* clobbered root cannot defeat the sweep of its non-clobbered descendants.
|
|
1282
|
+
*
|
|
1283
|
+
* NOTE (pending real-Chrome confirmation, see test/declarative-patch-probe
|
|
1284
|
+
* .html Q1): this mirrors the existing policy of keeping `for` on
|
|
1285
|
+
* <label>/<output>. If the shipping feature can drive a patch through a
|
|
1286
|
+
* surviving `for`-on-label/output + `id` pair, this pre-pass and the
|
|
1287
|
+
* attribute check at _isBasicCustomElement's caller must additionally drop
|
|
1288
|
+
* that pair on the IN_PLACE path. Left as-is until the taxonomy is verified.
|
|
1289
|
+
*
|
|
1290
|
+
* @param root the in-place root to sweep
|
|
1291
|
+
*/
|
|
1292
|
+
const _neutralizePatchLinkage = function _neutralizePatchLinkage(root) {
|
|
1293
|
+
if (!SAFE_FOR_XML) {
|
|
1294
|
+
return;
|
|
1295
|
+
}
|
|
1296
|
+
const stack = [root];
|
|
1297
|
+
while (stack.length > 0) {
|
|
1298
|
+
const node = stack.pop();
|
|
1299
|
+
const nodeType = getNodeType ? getNodeType(node) : node.nodeType;
|
|
1300
|
+
/* Remove range markers (the target side of a patch linkage): every
|
|
1301
|
+
processing instruction, and any markup-bearing comment. */
|
|
1302
|
+
if (nodeType === NODE_TYPE.processingInstruction || nodeType === NODE_TYPE.comment && regExpTest(COMMENT_MARKUP_PROBE, node.data)) {
|
|
1303
|
+
try {
|
|
1304
|
+
remove(node);
|
|
1305
|
+
} catch (_) {
|
|
1306
|
+
/* Best-effort */
|
|
1307
|
+
}
|
|
1308
|
+
continue;
|
|
1309
|
+
}
|
|
1310
|
+
/* Strip patch-source attributes (the source side) off elements. */
|
|
1311
|
+
if (nodeType === NODE_TYPE.element) {
|
|
1312
|
+
const element = node;
|
|
1313
|
+
const lcTag = transformCaseFunc(getNodeName ? getNodeName(node) : node.nodeName);
|
|
1314
|
+
try {
|
|
1315
|
+
if (element.hasAttribute && element.hasAttribute('patchsrc')) {
|
|
1316
|
+
element.removeAttribute('patchsrc');
|
|
1317
|
+
}
|
|
1318
|
+
if (element.hasAttribute && element.hasAttribute('for') && lcTag !== 'label' && lcTag !== 'output') {
|
|
1319
|
+
element.removeAttribute('for');
|
|
1320
|
+
}
|
|
1321
|
+
} catch (_) {
|
|
1322
|
+
/* Clobbered removeAttribute/hasAttribute on a doomed node — ignore */
|
|
1323
|
+
}
|
|
1324
|
+
}
|
|
1325
|
+
const childNodes = getChildNodes(node);
|
|
1326
|
+
if (childNodes) {
|
|
1327
|
+
for (let i = childNodes.length - 1; i >= 0; --i) {
|
|
1328
|
+
stack.push(childNodes[i]);
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1332
|
+
};
|
|
1249
1333
|
/**
|
|
1250
1334
|
* _initDocument
|
|
1251
1335
|
*
|
|
@@ -1303,7 +1387,17 @@ var purify = {exports: {}};
|
|
|
1303
1387
|
* @return The created NodeIterator
|
|
1304
1388
|
*/
|
|
1305
1389
|
const _createNodeIterator = function _createNodeIterator(root) {
|
|
1306
|
-
|
|
1390
|
+
/* Read ownerDocument through the cached Node.prototype getter, never the
|
|
1391
|
+
direct property. HTMLFormElement has [LegacyOverrideBuiltIns], so a
|
|
1392
|
+
clobbering child (<input name="ownerDocument"> or a form-associated
|
|
1393
|
+
external input) shadows the prototype getter and makes a direct read
|
|
1394
|
+
return that <input>. createNodeIterator.call(<input>, ...) then throws
|
|
1395
|
+
"Illegal invocation", and on the IN_PLACE path that throw lands before
|
|
1396
|
+
the walk's fail-closed barrier - leaving the caller's live tree, with
|
|
1397
|
+
any already-armed handler in it, un-neutralized. The cached getter
|
|
1398
|
+
returns the real Document regardless of the clobber. */
|
|
1399
|
+
const doc = getOwnerDocument ? getOwnerDocument(root) : root.ownerDocument;
|
|
1400
|
+
return createNodeIterator.call(doc || root, root,
|
|
1307
1401
|
// eslint-disable-next-line no-bitwise
|
|
1308
1402
|
NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT | NodeFilter.SHOW_PROCESSING_INSTRUCTION | NodeFilter.SHOW_CDATA_SECTION, null);
|
|
1309
1403
|
};
|
|
@@ -1343,7 +1437,11 @@ var purify = {exports: {}};
|
|
|
1343
1437
|
const _scrubTemplateExpressions2 = function _scrubTemplateExpressions(node) {
|
|
1344
1438
|
var _node$querySelectorAl;
|
|
1345
1439
|
node.normalize();
|
|
1346
|
-
|
|
1440
|
+
/* Clobber-safe ownerDocument read, same reasoning as _createNodeIterator:
|
|
1441
|
+
under SAFE_FOR_TEMPLATES this runs on the live IN_PLACE root, which may
|
|
1442
|
+
carry a form-named-getter override of ownerDocument. */
|
|
1443
|
+
const doc = getOwnerDocument ? getOwnerDocument(node) : node.ownerDocument;
|
|
1444
|
+
const walker = createNodeIterator.call(doc || node, node,
|
|
1347
1445
|
// eslint-disable-next-line no-bitwise
|
|
1348
1446
|
NodeFilter.SHOW_TEXT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_CDATA_SECTION | NodeFilter.SHOW_PROCESSING_INSTRUCTION, null);
|
|
1349
1447
|
let currentNode = walker.nextNode();
|
|
@@ -1496,15 +1594,21 @@ var purify = {exports: {}};
|
|
|
1496
1594
|
/**
|
|
1497
1595
|
* Handle a node whose tag is forbidden or not allowlisted: keep
|
|
1498
1596
|
* allowed custom elements (false return exits _sanitizeElements
|
|
1499
|
-
* early - namespace
|
|
1500
|
-
*
|
|
1501
|
-
*
|
|
1597
|
+
* early - the namespace and fallback-tag removal checks are
|
|
1598
|
+
* intentionally skipped for kept custom elements), else hoist
|
|
1599
|
+
* content per KEEP_CONTENT and remove.
|
|
1600
|
+
*
|
|
1601
|
+
* A kept custom element is the ONLY case in which this function
|
|
1602
|
+
* returns false, so the caller uses that return value to run the
|
|
1603
|
+
* afterSanitizeElements hook on the kept element and keep the
|
|
1604
|
+
* element-hook lifecycle consistent with normal allowlisted
|
|
1605
|
+
* elements (GHSA-c2j3-45gr-mqc4).
|
|
1502
1606
|
*
|
|
1503
1607
|
* @param currentNode the disallowed node
|
|
1504
1608
|
* @param tagName the node's transformCaseFunc'd tag name
|
|
1505
1609
|
* @return true if the node was removed, false if kept
|
|
1506
1610
|
*/
|
|
1507
|
-
const _sanitizeDisallowedNode = function _sanitizeDisallowedNode(currentNode, tagName) {
|
|
1611
|
+
const _sanitizeDisallowedNode = function _sanitizeDisallowedNode(currentNode, tagName, root) {
|
|
1508
1612
|
/* Check if we have a custom element to handle */
|
|
1509
1613
|
if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {
|
|
1510
1614
|
if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) {
|
|
@@ -1527,27 +1631,26 @@ var purify = {exports: {}};
|
|
|
1527
1631
|
const childNodes = getChildNodes(currentNode);
|
|
1528
1632
|
if (childNodes && parentNode) {
|
|
1529
1633
|
const childCount = childNodes.length;
|
|
1530
|
-
/*
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
event to neutralise.
|
|
1634
|
+
/* Hoist by moving each child up one level rather than deep-cloning
|
|
1635
|
+
it. Moving transfers every descendant exactly once, so a chain of
|
|
1636
|
+
nested disallowed elements costs O(n) instead of the O(n^2) that
|
|
1637
|
+
re-cloning the shrinking subtree at each level produced; it also
|
|
1638
|
+
empties the removed original, so `DOMPurify.removed` no longer
|
|
1639
|
+
pins whole subtrees. Moving preserves the in-place guarantee too:
|
|
1640
|
+
an original carrying already-queued resource events (`<img
|
|
1641
|
+
onerror>`, `<video>`/`<audio>` error, lazy/`onload`, …) is
|
|
1642
|
+
relocated and sanitised rather than left detached but still armed.
|
|
1643
|
+
The sole case that must clone is removing the walk root itself.
|
|
1644
|
+
The result is serialised from the root's subtree, so a restrictive
|
|
1645
|
+
ALLOWED_TAGS that strips the root (`body` on the string path) must
|
|
1646
|
+
leave the content inside it, which only cloning does. In IN_PLACE
|
|
1647
|
+
the root is pre-validated as an allowed tag and so is never removed
|
|
1648
|
+
here, so that path always takes the move branch.
|
|
1546
1649
|
`childNodes` is live; a tail-to-head walk keeps `childNodes[i]`
|
|
1547
1650
|
valid whether we move (drops the trailing entry) or clone (leaves
|
|
1548
1651
|
the list intact). */
|
|
1549
1652
|
for (let i = childCount - 1; i >= 0; --i) {
|
|
1550
|
-
const hoisted =
|
|
1653
|
+
const hoisted = currentNode === root ? cloneNode(childNodes[i], true) : childNodes[i];
|
|
1551
1654
|
parentNode.insertBefore(hoisted, getNextSibling(currentNode));
|
|
1552
1655
|
}
|
|
1553
1656
|
}
|
|
@@ -1555,6 +1658,26 @@ var purify = {exports: {}};
|
|
|
1555
1658
|
_forceRemove(currentNode);
|
|
1556
1659
|
return true;
|
|
1557
1660
|
};
|
|
1661
|
+
/**
|
|
1662
|
+
* Fork a hook-mutable allowlist off its shared binding the first time a
|
|
1663
|
+
* (possibly lazily-installed) uponSanitize* hook is about to see it, so the
|
|
1664
|
+
* hook cannot widen the per-instance default or the setConfig binding by
|
|
1665
|
+
* reference and leak past the call. Returns the set unchanged once it is
|
|
1666
|
+
* already call-local, so repeated calls across elements are idempotent.
|
|
1667
|
+
*
|
|
1668
|
+
* @param hookList the uponSanitize* hook array for this event
|
|
1669
|
+
* @param set the current ALLOWED_TAGS / ALLOWED_ATTR binding
|
|
1670
|
+
* @param defaultSet the per-instance DEFAULT_ALLOWED_* constant
|
|
1671
|
+
* @param setConfigSet the captured setConfig() binding, or null
|
|
1672
|
+
* @return a call-local clone if a hook is present and set is still shared,
|
|
1673
|
+
* else set unchanged
|
|
1674
|
+
*/
|
|
1675
|
+
const _forkSharedAllowlist = function _forkSharedAllowlist(hookList, set, defaultSet, setConfigSet) {
|
|
1676
|
+
if (hookList.length === 0) {
|
|
1677
|
+
return set;
|
|
1678
|
+
}
|
|
1679
|
+
return set === defaultSet || set === setConfigSet ? clone(set) : set;
|
|
1680
|
+
};
|
|
1558
1681
|
/**
|
|
1559
1682
|
* _sanitizeElements
|
|
1560
1683
|
*
|
|
@@ -1564,9 +1687,20 @@ var purify = {exports: {}};
|
|
|
1564
1687
|
* @param currentNode to check for permission to exist
|
|
1565
1688
|
* @return true if node was killed, false if left alive
|
|
1566
1689
|
*/
|
|
1567
|
-
|
|
1690
|
+
// eslint-disable-next-line complexity
|
|
1691
|
+
const _sanitizeElements = function _sanitizeElements(currentNode, root) {
|
|
1568
1692
|
/* Execute a hook if present */
|
|
1569
1693
|
_executeHooks(hooks.beforeSanitizeElements, currentNode, null);
|
|
1694
|
+
/* A hook may have detached the node - treat it as removed (see the
|
|
1695
|
+
detached-node comment after the uponSanitizeElement hook below). On
|
|
1696
|
+
the IN_PLACE path, neutralize the detached subtree first so a queued
|
|
1697
|
+
resource handler on it cannot fire in page scope after we return. */
|
|
1698
|
+
if (currentNode !== root && getParentNode(currentNode) === null) {
|
|
1699
|
+
if (IN_PLACE) {
|
|
1700
|
+
_neutralizeSubtree(currentNode);
|
|
1701
|
+
}
|
|
1702
|
+
return true;
|
|
1703
|
+
}
|
|
1570
1704
|
/* Check if element is clobbered or can clobber */
|
|
1571
1705
|
if (_isClobbered(currentNode)) {
|
|
1572
1706
|
_forceRemove(currentNode);
|
|
@@ -1574,11 +1708,47 @@ var purify = {exports: {}};
|
|
|
1574
1708
|
}
|
|
1575
1709
|
/* Now let's check the element's type and name */
|
|
1576
1710
|
const tagName = transformCaseFunc(getNodeName ? getNodeName(currentNode) : currentNode.nodeName);
|
|
1711
|
+
/* Close the pre-walk clone-guard's timing gap: an uponSanitizeElement
|
|
1712
|
+
hook may have been installed after that guard sampled the hook arrays
|
|
1713
|
+
(e.g. lazily from beforeSanitizeElements), leaving ALLOWED_TAGS still
|
|
1714
|
+
aliasing a shared binding that a widening hook would mutate by
|
|
1715
|
+
reference. Fork it before exposing it to the hook. */
|
|
1716
|
+
ALLOWED_TAGS = _forkSharedAllowlist(hooks.uponSanitizeElement, ALLOWED_TAGS, DEFAULT_ALLOWED_TAGS, SET_CONFIG_ALLOWED_TAGS);
|
|
1577
1717
|
/* Execute a hook if present */
|
|
1578
1718
|
_executeHooks(hooks.uponSanitizeElement, currentNode, {
|
|
1579
1719
|
tagName,
|
|
1580
1720
|
allowedTags: ALLOWED_TAGS
|
|
1581
1721
|
});
|
|
1722
|
+
/* A hook may have detached the node from the tree — a long-standing
|
|
1723
|
+
user pattern (issue #469; draw.io-style foreignObject filtering).
|
|
1724
|
+
Per the cached, unclobberable parentNode getter the node is
|
|
1725
|
+
genuinely out of the tree, so it can reach neither the serialized
|
|
1726
|
+
output nor an IN_PLACE live tree; treat it as removed and stop
|
|
1727
|
+
processing it. Without this guard, the unsafe-node / namespace
|
|
1728
|
+
checks below would call _forceRemove on a parentless node and hit
|
|
1729
|
+
the REPORT-3 fail-closed throw — which exists for nodes DOMPurify
|
|
1730
|
+
wants gone but *cannot* detach (clobbered / parentless roots), the
|
|
1731
|
+
opposite of a node that is already safely gone. The walk root is
|
|
1732
|
+
exempt: a detached IN_PLACE root is legitimate input and must still
|
|
1733
|
+
be fully sanitized, and a kill-decision on it must keep hitting the
|
|
1734
|
+
REPORT-3 throw. Nodes detached by hooks stay the hook's
|
|
1735
|
+
responsibility for placement: they are not recorded in
|
|
1736
|
+
DOMPurify.removed, so the post-walk IN_PLACE pass (which iterates
|
|
1737
|
+
DOMPurify.removed) does not reach them. But a hook-detached subtree
|
|
1738
|
+
can still hold a queued resource-event handler - e.g. an <img onload>
|
|
1739
|
+
that began loading when the caller built the live tree - which fires
|
|
1740
|
+
in page scope after sanitize returns even though the handler never
|
|
1741
|
+
reached the returned tree. That is the audit-5 F1 hazard, and the
|
|
1742
|
+
documented node.remove() hook pattern walks straight into it. So on
|
|
1743
|
+
the IN_PLACE path we neutralize the detached subtree inline here,
|
|
1744
|
+
stripping its non-allow-listed attributes before returning, exactly
|
|
1745
|
+
as the post-walk pass does for _forceRemove'd subtrees. */
|
|
1746
|
+
if (currentNode !== root && getParentNode(currentNode) === null) {
|
|
1747
|
+
if (IN_PLACE) {
|
|
1748
|
+
_neutralizeSubtree(currentNode);
|
|
1749
|
+
}
|
|
1750
|
+
return true;
|
|
1751
|
+
}
|
|
1582
1752
|
/* Remove mXSS vectors, processing instructions and risky comments */
|
|
1583
1753
|
if (_isUnsafeNode(currentNode, tagName)) {
|
|
1584
1754
|
_forceRemove(currentNode);
|
|
@@ -1586,7 +1756,22 @@ var purify = {exports: {}};
|
|
|
1586
1756
|
}
|
|
1587
1757
|
/* Remove element if anything forbids its presence */
|
|
1588
1758
|
if (FORBID_TAGS[tagName] || !(EXTRA_ELEMENT_HANDLING.tagCheck instanceof Function && EXTRA_ELEMENT_HANDLING.tagCheck(tagName)) && !ALLOWED_TAGS[tagName]) {
|
|
1589
|
-
|
|
1759
|
+
const removed = _sanitizeDisallowedNode(currentNode, tagName, root);
|
|
1760
|
+
/* A false return means the node is a custom element kept via
|
|
1761
|
+
CUSTOM_ELEMENT_HANDLING - the only keep path through
|
|
1762
|
+
_sanitizeDisallowedNode. Run afterSanitizeElements on it so the
|
|
1763
|
+
element-hook lifecycle matches normal allowlisted elements: a
|
|
1764
|
+
security policy applied in this hook (e.g. stripping an attribute
|
|
1765
|
+
from every surviving element) must not silently skip kept custom
|
|
1766
|
+
elements (GHSA-c2j3-45gr-mqc4). This mirrors the normal-element
|
|
1767
|
+
tail below - the hook runs, then the walker's subsequent
|
|
1768
|
+
_sanitizeAttributes pass sanitizes the element's attributes. The
|
|
1769
|
+
deliberately skipped namespace and fallback-tag removal checks stay
|
|
1770
|
+
skipped; they are removal decisions, not the hook contract. */
|
|
1771
|
+
if (removed === false) {
|
|
1772
|
+
_executeHooks(hooks.afterSanitizeElements, currentNode, null);
|
|
1773
|
+
}
|
|
1774
|
+
return removed;
|
|
1590
1775
|
}
|
|
1591
1776
|
/* Check whether element has a valid namespace.
|
|
1592
1777
|
Realm-safe check (GHSA-hpcv-96wg-7vj8): use the cached Node.prototype
|
|
@@ -1633,6 +1818,33 @@ var purify = {exports: {}};
|
|
|
1633
1818
|
if (FORBID_ATTR[lcName]) {
|
|
1634
1819
|
return false;
|
|
1635
1820
|
}
|
|
1821
|
+
/* Reject declarative-partial-updates patch-linkage attributes
|
|
1822
|
+
(https://github.com/WICG/declarative-partial-updates).
|
|
1823
|
+
Empirical note (Chrome 150, verified — see
|
|
1824
|
+
test/declarative-patch-probe-v3.html): expansion is NOT applied after
|
|
1825
|
+
sanitization. For the string path it fires during sanitize()'s own
|
|
1826
|
+
parse, so the walk sees and sanitizes the fully materialized expanded
|
|
1827
|
+
tree — teleports into MathML/SVG integration points included; a
|
|
1828
|
+
weaponized `<template for>`->`<img onerror>` comes back with the handler
|
|
1829
|
+
stripped. For the IN_PLACE path it fires on connection, before the walk.
|
|
1830
|
+
Either way DOMPurify is NOT blind to the patch.
|
|
1831
|
+
This removal is therefore defense-in-depth rather than the sole barrier:
|
|
1832
|
+
it prevents live linkage from surviving into the OUTPUT and re-expanding
|
|
1833
|
+
in the caller's context, and keeps behaviour deterministic if a future
|
|
1834
|
+
engine defers expansion. `for` is legitimate only on <label>/<output>;
|
|
1835
|
+
anywhere else (notably <template for>) it links the element to a patch
|
|
1836
|
+
target and teleports or removes an arbitrary DOM range by id/marker name.
|
|
1837
|
+
`patchsrc` fetches remote markup and is treated as a script-loading
|
|
1838
|
+
mechanism (CSP). Gated on SAFE_FOR_XML so the removal groups with the
|
|
1839
|
+
other structural-threat checks and stays overridable, consistent with
|
|
1840
|
+
the rest of the codebase. PI range markers are already removed by
|
|
1841
|
+
_isUnsafeNode. */
|
|
1842
|
+
if (SAFE_FOR_XML && lcName === 'patchsrc') {
|
|
1843
|
+
return false;
|
|
1844
|
+
}
|
|
1845
|
+
if (SAFE_FOR_XML && lcName === 'for' && lcTag !== 'label' && lcTag !== 'output') {
|
|
1846
|
+
return false;
|
|
1847
|
+
}
|
|
1636
1848
|
/* Make sure attribute cannot clobber */
|
|
1637
1849
|
if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) {
|
|
1638
1850
|
return false;
|
|
@@ -1749,6 +1961,9 @@ var purify = {exports: {}};
|
|
|
1749
1961
|
if (!attributes || _isClobbered(currentNode)) {
|
|
1750
1962
|
return;
|
|
1751
1963
|
}
|
|
1964
|
+
/* Same lazy-install guard as uponSanitizeElement (see there): fork the
|
|
1965
|
+
attribute allowlist off its shared binding before a hook can see it. */
|
|
1966
|
+
ALLOWED_ATTR = _forkSharedAllowlist(hooks.uponSanitizeAttribute, ALLOWED_ATTR, DEFAULT_ALLOWED_ATTR, SET_CONFIG_ALLOWED_ATTR);
|
|
1752
1967
|
const hookEvent = {
|
|
1753
1968
|
attrName: '',
|
|
1754
1969
|
attrValue: '',
|
|
@@ -1842,7 +2057,7 @@ var purify = {exports: {}};
|
|
|
1842
2057
|
/* Execute a hook if present */
|
|
1843
2058
|
_executeHooks(hooks.uponSanitizeShadowNode, shadowNode, null);
|
|
1844
2059
|
/* Sanitize tags and elements */
|
|
1845
|
-
_sanitizeElements(shadowNode);
|
|
2060
|
+
_sanitizeElements(shadowNode, fragment);
|
|
1846
2061
|
/* Check attributes next */
|
|
1847
2062
|
_sanitizeAttributes(shadowNode);
|
|
1848
2063
|
/* Deep shadow DOM detected.
|
|
@@ -2033,6 +2248,11 @@ var purify = {exports: {}};
|
|
|
2033
2248
|
keep using and whose return value they ignore — unsanitized. REPORT-2. */
|
|
2034
2249
|
const inPlace = IN_PLACE && typeof dirty !== 'string' && _isNode(dirty);
|
|
2035
2250
|
if (inPlace) {
|
|
2251
|
+
/* Declarative-partial-updates / streaming pre-pass: sever every patch
|
|
2252
|
+
linkage across the live tree BEFORE the walk, so no patch can fire
|
|
2253
|
+
mid-walk and inject into an already-processed region. Runs first, so
|
|
2254
|
+
it also covers the forbidden/clobbered roots that throw below. */
|
|
2255
|
+
_neutralizePatchLinkage(dirty);
|
|
2036
2256
|
/* Do some early pre-sanitization to avoid unsafe root nodes.
|
|
2037
2257
|
Read nodeName through the cached prototype getter — a clobbering
|
|
2038
2258
|
child named "nodeName" on the form root would otherwise shadow
|
|
@@ -2042,6 +2262,9 @@ var purify = {exports: {}};
|
|
|
2042
2262
|
if (typeof nn === 'string') {
|
|
2043
2263
|
const tagName = transformCaseFunc(nn);
|
|
2044
2264
|
if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
|
|
2265
|
+
/* Fail closed on a live root: neutralize handlers/children before
|
|
2266
|
+
throwing, exactly as the mid-walk abort path does. */
|
|
2267
|
+
_neutralizeRoot(dirty);
|
|
2045
2268
|
throw typeErrorCreate('root node is forbidden and cannot be sanitized in-place');
|
|
2046
2269
|
}
|
|
2047
2270
|
}
|
|
@@ -2056,6 +2279,10 @@ var purify = {exports: {}};
|
|
|
2056
2279
|
the application unsanitized. Refuse to sanitize such a root
|
|
2057
2280
|
the same way we refuse a forbidden tag. GHSA-r47g-fvhr-h676. */
|
|
2058
2281
|
if (_isClobbered(dirty)) {
|
|
2282
|
+
/* Fail closed on a live clobbered root before throwing.
|
|
2283
|
+
_neutralizeRoot's reads are clobber-safe (cached getters); the
|
|
2284
|
+
form's non-clobbered descendants, e.g. an armed <img>, are scrubbed. */
|
|
2285
|
+
_neutralizeRoot(dirty);
|
|
2059
2286
|
throw typeErrorCreate('root node is clobbered and cannot be sanitized in-place');
|
|
2060
2287
|
}
|
|
2061
2288
|
/* Sanitize attached shadow roots before the main iterator runs.
|
|
@@ -2108,20 +2335,24 @@ var purify = {exports: {}};
|
|
|
2108
2335
|
_forceRemove(body.firstChild);
|
|
2109
2336
|
}
|
|
2110
2337
|
/* Get node iterator */
|
|
2111
|
-
const
|
|
2338
|
+
const walkRoot = inPlace ? dirty : body;
|
|
2112
2339
|
/* Now start iterating over the created document.
|
|
2113
2340
|
The walk runs inside an exception barrier (campaign-3 F2): a re-entrant
|
|
2114
2341
|
engine/custom-element mutation can detach a node mid-walk so
|
|
2115
2342
|
`_forceRemove`'s parentless guard throws, aborting the loop. Without the
|
|
2116
2343
|
barrier the caller's in-place tree would be left half-sanitized with the
|
|
2117
|
-
unvisited tail still armed.
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2344
|
+
unvisited tail still armed. _createNodeIterator itself is inside the
|
|
2345
|
+
barrier too: constructing the iterator dereferences the root's document,
|
|
2346
|
+
and any failure there (e.g. an exotic/clobbered root) must still fail
|
|
2347
|
+
closed rather than skip the neutralize. On any throw we fail closed -
|
|
2348
|
+
strip the in-place root bare - then rethrow so the existing throw
|
|
2349
|
+
contract is preserved. (String/DOM-copy paths never return the partial
|
|
2350
|
+
body, so the propagating throw is already fail-closed there.) */
|
|
2121
2351
|
try {
|
|
2352
|
+
const nodeIterator = _createNodeIterator(walkRoot);
|
|
2122
2353
|
while (currentNode = nodeIterator.nextNode()) {
|
|
2123
2354
|
/* Sanitize tags and elements */
|
|
2124
|
-
_sanitizeElements(currentNode);
|
|
2355
|
+
_sanitizeElements(currentNode, walkRoot);
|
|
2125
2356
|
/* Check attributes next */
|
|
2126
2357
|
_sanitizeAttributes(currentNode);
|
|
2127
2358
|
/* Shadow DOM detected, sanitize it.
|
|
@@ -2135,6 +2366,14 @@ var purify = {exports: {}};
|
|
|
2135
2366
|
} catch (error) {
|
|
2136
2367
|
if (inPlace) {
|
|
2137
2368
|
_neutralizeRoot(dirty);
|
|
2369
|
+
/* Nodes _forceRemove'd earlier in the aborted walk are already
|
|
2370
|
+
detached from the root, so _neutralizeRoot's subtree pass does not
|
|
2371
|
+
reach them. Defuse them too, mirroring the success-path loop below. */
|
|
2372
|
+
arrayForEach(DOMPurify.removed, entry => {
|
|
2373
|
+
if (entry.element) {
|
|
2374
|
+
_neutralizeSubtree(entry.element);
|
|
2375
|
+
}
|
|
2376
|
+
});
|
|
2138
2377
|
}
|
|
2139
2378
|
throw error;
|
|
2140
2379
|
}
|
|
@@ -2271,7 +2510,7 @@ const getCustomElementHandling = (allowICPrefix) => ({
|
|
|
2271
2510
|
CUSTOM_ELEMENT_HANDLING: {
|
|
2272
2511
|
tagNameCheck: (tagName) => (allowICPrefix && tagName.startsWith("ic-")) ||
|
|
2273
2512
|
IC_CUSTOM_ALLOWED_COMPONENTS.includes(tagName),
|
|
2274
|
-
attributeNameCheck:
|
|
2513
|
+
attributeNameCheck: /^(?!on).+$/i,
|
|
2275
2514
|
},
|
|
2276
2515
|
});
|
|
2277
2516
|
const sanitizeHTMLString = (html) => {
|
|
@@ -2281,7 +2520,7 @@ const sanitizeHTMLIconString = (html) => {
|
|
|
2281
2520
|
return purifier.sanitize(html, getCustomElementHandling(false));
|
|
2282
2521
|
};
|
|
2283
2522
|
|
|
2284
|
-
const icMenuCss = "html.sc-ic-menu{line-height:1.15;-webkit-text-size-adjust:100%}body.sc-ic-menu{margin:0}main.sc-ic-menu{display:block}h1.sc-ic-menu{font-size:2em;margin:0.67em 0}hr.sc-ic-menu{box-sizing:content-box;height:0;overflow:visible}pre.sc-ic-menu{font-family:monospace, monospace;font-size:1em}a.sc-ic-menu{background-color:transparent}abbr[title].sc-ic-menu{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b.sc-ic-menu,strong.sc-ic-menu{font-weight:bolder}code.sc-ic-menu,kbd.sc-ic-menu,samp.sc-ic-menu{font-family:monospace, monospace;font-size:1em}small.sc-ic-menu{font-size:80%}sub.sc-ic-menu,sup.sc-ic-menu{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub.sc-ic-menu{bottom:-0.25em}sup.sc-ic-menu{top:-0.5em}img.sc-ic-menu{border-style:none}button.sc-ic-menu,input.sc-ic-menu,optgroup.sc-ic-menu,select.sc-ic-menu,textarea.sc-ic-menu{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button.sc-ic-menu,input.sc-ic-menu{overflow:visible}button.sc-ic-menu,select.sc-ic-menu{text-transform:none}button.sc-ic-menu,[type=\"button\"].sc-ic-menu,[type=\"reset\"].sc-ic-menu,[type=\"submit\"].sc-ic-menu{-webkit-appearance:button}button.sc-ic-menu::-moz-focus-inner,[type=\"button\"].sc-ic-menu::-moz-focus-inner,[type=\"reset\"].sc-ic-menu::-moz-focus-inner,[type=\"submit\"].sc-ic-menu::-moz-focus-inner{border-style:none;padding:0}button.sc-ic-menu:-moz-focusring,[type=\"button\"].sc-ic-menu:-moz-focusring,[type=\"reset\"].sc-ic-menu:-moz-focusring,[type=\"submit\"].sc-ic-menu:-moz-focusring{outline:1px dotted ButtonText}fieldset.sc-ic-menu{padding:0.35em 0.75em 0.625em}legend.sc-ic-menu{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress.sc-ic-menu{vertical-align:baseline}textarea.sc-ic-menu{overflow:auto}[type=\"checkbox\"].sc-ic-menu,[type=\"radio\"].sc-ic-menu{box-sizing:border-box;padding:0}[type=\"number\"].sc-ic-menu::-webkit-inner-spin-button,[type=\"number\"].sc-ic-menu::-webkit-outer-spin-button{height:auto}[type=\"search\"].sc-ic-menu{-webkit-appearance:textfield;outline-offset:-2px}[type=\"search\"].sc-ic-menu::-webkit-search-decoration{-webkit-appearance:none}.sc-ic-menu::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details.sc-ic-menu{display:block}summary.sc-ic-menu{display:list-item}template.sc-ic-menu{display:none}[hidden].sc-ic-menu{display:none}html.sc-ic-menu,body.sc-ic-menu,div.sc-ic-menu,span.sc-ic-menu,applet.sc-ic-menu,object.sc-ic-menu,iframe.sc-ic-menu,h1.sc-ic-menu,h2.sc-ic-menu,h3.sc-ic-menu,h4.sc-ic-menu,h5.sc-ic-menu,h6.sc-ic-menu,p.sc-ic-menu,blockquote.sc-ic-menu,pre.sc-ic-menu,a.sc-ic-menu,abbr.sc-ic-menu,acronym.sc-ic-menu,address.sc-ic-menu,big.sc-ic-menu,cite.sc-ic-menu,code.sc-ic-menu,del.sc-ic-menu,dfn.sc-ic-menu,em.sc-ic-menu,img.sc-ic-menu,ins.sc-ic-menu,kbd.sc-ic-menu,q.sc-ic-menu,s.sc-ic-menu,samp.sc-ic-menu,small.sc-ic-menu,strike.sc-ic-menu,strong.sc-ic-menu,sub.sc-ic-menu,sup.sc-ic-menu,tt.sc-ic-menu,var.sc-ic-menu,b.sc-ic-menu,u.sc-ic-menu,i.sc-ic-menu,center.sc-ic-menu,dl.sc-ic-menu,dt.sc-ic-menu,dd.sc-ic-menu,ol.sc-ic-menu,ul.sc-ic-menu,li.sc-ic-menu,fieldset.sc-ic-menu,form.sc-ic-menu,label.sc-ic-menu,legend.sc-ic-menu,table.sc-ic-menu,caption.sc-ic-menu,tbody.sc-ic-menu,tfoot.sc-ic-menu,thead.sc-ic-menu,tr.sc-ic-menu,th.sc-ic-menu,td.sc-ic-menu,article.sc-ic-menu,aside.sc-ic-menu,canvas.sc-ic-menu,details.sc-ic-menu,embed.sc-ic-menu,figure.sc-ic-menu,figcaption.sc-ic-menu,footer.sc-ic-menu,header.sc-ic-menu,hgroup.sc-ic-menu,menu.sc-ic-menu,nav.sc-ic-menu,output.sc-ic-menu,ruby.sc-ic-menu,section.sc-ic-menu,summary.sc-ic-menu,time.sc-ic-menu,mark.sc-ic-menu,audio.sc-ic-menu,video.sc-ic-menu{margin:0;padding:0;border:0;font-size:100%;font-style:inherit;vertical-align:baseline}@media (prefers-reduced-motion: no-preference){.ic-menu-open.sc-ic-menu-h .menu.sc-ic-menu{transition:max-height var(--ic-transition-duration-slow)}}.sc-ic-menu-h{max-height:0;width:var(--menu-width, var(--input-width, 20rem));color:var(--menu-item-text-color, var(--ic-menu-list-option-text-color));--ic-typography-color:var(\n --menu-item-text-color,\n var(--ic-menu-list-option-text-color)\n );background-color:var(\n --menu-bg-color,\n var(--ic-menu-list-option-background-color)\n );position:relative;z-index:var(--ic-z-index-menu);box-sizing:border-box;box-shadow:var(--ic-elevation-overlay);border-radius:var(--ic-border-radius)}.ic-menu-open.sc-ic-menu-h:not(.ic-menu-no-focus):focus-within{box-shadow:var(--ic-border-focus);outline:var(--ic-hc-focus-outline)}.ic-select-select-all-focused.sc-ic-menu-h{box-shadow:var(--ic-elevation-overlay) !important}#retry-button.sc-ic-menu::part(button){height:var(--ic-space-lg)}.small.sc-ic-menu #retry-button.sc-ic-menu::part(button){height:var(--ic-space-md)}.on-dialog.sc-ic-menu-h{inset:auto !important}.menu.sc-ic-menu{text-decoration:none;list-style-type:none;border-radius:1px;background-color:var(\n --menu-bg-color,\n var(--ic-menu-list-option-background-color)\n );visibility:hidden;max-height:0;overflow-y:hidden}.menu.sc-ic-menu:has(+.option-bar).sc-ic-menu{border-radius:0 0 1px 1px}.menu-scroll.sc-ic-menu{overflow-y:auto}.menu.sc-ic-menu:focus-visible{outline:none}.ic-menu-open.sc-ic-menu-h{max-height:none;display:flex;flex-direction:column-reverse;border:var(--ic-border-width) solid\n var(--menu-border-color, var(--ic-menu-border-color));transition:box-shadow var(--ic-easing-transition-fast)}.ic-menu-open.sc-ic-menu-h .menu.sc-ic-menu{visibility:visible;max-height:calc(var(--ic-space-xl) * 10 + var(--ic-space-xxxs))}.ic-menu-open.sc-ic-menu-h .option-bar.sc-ic-menu{visibility:visible}.ic-menu-open.sc-ic-menu-h .select-all-button.sc-ic-menu{display:block}.ic-menu-full-width.sc-ic-menu-h{width:100%}.option.sc-ic-menu{padding:var(--ic-space-xs) calc(var(--ic-space-xs) - var(--ic-space-1px));cursor:pointer;display:flex;align-items:center;gap:var(--ic-space-xs)}.loading-option.sc-ic-menu p.sc-ic-menu{margin-bottom:0 !important}.option.sc-ic-menu:not(.loading-option){justify-content:space-between}.ic-menu-small.sc-ic-menu-h .option.sc-ic-menu{padding:var(--ic-space-xxs) calc(var(--ic-space-xs) - var(--ic-space-1px))}.ic-menu-large.sc-ic-menu-h .option.sc-ic-menu{padding:var(--ic-space-sm) calc(var(--ic-space-xs) - var(--ic-space-1px))}.option.sc-ic-menu:last-child{border-radius:0 0 1px 1px}.sc-ic-menu:not(.menu:has(+.option-bar)).sc-ic-menu .option.sc-ic-menu:first-child{border-radius:1px 1px 0 0}.option.sc-ic-menu:not(.disabled-option):hover{background-color:var(--ic-menu-list-option-hover-background-color)}.option.sc-ic-menu:not(.disabled-option):active{background-color:var(--ic-menu-list-option-pressed-background-color)}.option.sc-ic-menu:focus-visible{outline:var(--ic-hc-focus-outline)}.option.sc-ic-menu:not(.disabled-option) .option-description.sc-ic-menu{--ic-typography-color:var(\n --menu-item-desc-text-color,\n var(--ic-menu-list-option-description-text-color)\n )}.option.sc-ic-menu .option-label.sc-ic-menu{display:flex;flex-direction:row;align-items:top}.option.sc-ic-menu .option-label.sc-ic-menu ic-typography.sc-ic-menu{max-width:100%;word-wrap:break-word}.option.sc-ic-menu .option-element.sc-ic-menu{margin-top:var(--ic-space-xxs)}.option.sc-ic-menu .option-icon.sc-ic-menu{height:var(--ic-space-md);width:var(--ic-space-md);margin-top:var(--ic-space-xxs);margin-right:var(--ic-space-xxs)}.option-text-container.sc-ic-menu{pointer-events:none;width:100%}.option-text-container.show-check-icon.sc-ic-menu{flex-grow:1}.option.loading-option.sc-ic-menu .option-text-container.sc-ic-menu{margin-left:calc(var(--ic-space-xs) + var(--ic-space-xxxs));color:var(--ic-menu-loading-list-option-text-color);--ic-typography-color:var(--ic-menu-loading-list-option-text-color)}.error-icon-svg.sc-ic-menu{height:var(--ic-space-md);width:var(--ic-space-md);fill:var(--ic-atoms-status-icon-error);align-self:center;display:flex;margin-right:calc(var(--ic-space-xxs) * 1.2)}.loading-error-info.sc-ic-menu{display:flex}.check-icon.sc-ic-menu{height:var(--ic-space-lg);min-width:var(--ic-space-lg);width:var(--ic-space-lg);pointer-events:none}.focused-option.sc-ic-menu .check-icon.sc-ic-menu *.sc-ic-menu{fill:currentcolor}.sc-ic-menu:first-child>.option-group-title.sc-ic-menu{padding:var(--ic-space-xs) calc(var(--ic-space-xs) - var(--ic-space-1px))\n var(--ic-space-xs)}.option-group-title.sc-ic-menu{padding:var(--ic-space-lg) calc(var(--ic-space-xs) - var(--ic-space-1px))\n var(--ic-space-xs);--ic-typography-color:var(--ic-menu-option-group-label-text-color)}.ic-menu-small.sc-ic-menu-h .option-group-title.sc-ic-menu{padding:var(--ic-space-sm) calc(var(--ic-space-xs) - var(--ic-space-1px))\n var(--ic-space-xxs)}.last-recommended-option.sc-ic-menu{border-bottom:var(--ic-menu-last-recommended-option-border)}.disabled-option.sc-ic-menu{color:var(--ic-atoms-list-option-text-disabled-light);--ic-typography-color:var(--ic-atoms-list-option-text-disabled-light);cursor:default;pointer-events:none}.focus-border.sc-ic-menu{border-radius:var(--ic-border-radius);padding:var(--ic-space-xxs);border:var(--ic-space-xxxs) dashed transparent;border-color:var(--ic-popover-menu-border);background-color:var(--ic-color-focus-inner) !important;--icon-height:auto}.focus-disabled.sc-ic-menu{background-color:var(--ic-color-focus-inner) !important;padding:calc(var(--ic-space-xs) - var(--ic-space-xxxs) - var(--ic-space-xxs))\n calc(\n var(--ic-space-xs) - var(--ic-space-1px) - var(--ic-space-xxxs) -\n var(--ic-space-xxs)\n )}.focused-option.sc-ic-menu,.focused-option.sc-ic-menu .option-description.sc-ic-menu{background-color:var(--ic-color-focus-inner) !important;color:var(--ic-atoms-list-option-text-focused-light) !important;--ic-typography-color:var(\n --ic-atoms-list-option-text-focused-light\n ) !important}.no-results.sc-ic-menu-h li.sc-ic-menu{cursor:no-drop}.no-results.sc-ic-menu-h li.sc-ic-menu:hover{background-color:transparent}.option-bar.sc-ic-menu{padding:var(--ic-space-xxs) var(--ic-space-xs);display:flex;align-items:center;justify-content:space-between;background-color:var(--ic-menu-option-bar-background-color);visibility:hidden;border-bottom:var(--ic-border-width) solid\n var(--ic-menu-option-bar-divider-color);border-radius:1px 1px 0 0}.option-bar.sc-ic-menu p.sc-ic-menu{margin-bottom:0 !important}.ic-menu-large.sc-ic-menu-h .option-bar.sc-ic-menu{padding:var(--ic-space-xs)}.select-all-button.sc-ic-menu{display:none}.select-all-button.sc-ic-menu:focus{z-index:calc(var(--ic-z-index-menu) + 1)}@media (forced-colors: active){.focused-option.sc-ic-menu{outline:none;border:0.125rem solid transparent}.disabled-option.sc-ic-menu{color:GrayText;--ic-typography-color:GrayText}}@media screen AND (max-width: 22rem){.sc-ic-menu-h{max-width:var(--menu-width, var(--input-width, 20rem));width:100%}}@media (prefers-reduced-motion: reduce){.ic-menu-open.sc-ic-menu-h{transition:none}}";
|
|
2523
|
+
const icMenuCss = "html.sc-ic-menu{line-height:1.15;-webkit-text-size-adjust:100%}body.sc-ic-menu{margin:0}main.sc-ic-menu{display:block}h1.sc-ic-menu{font-size:2em;margin:0.67em 0}hr.sc-ic-menu{box-sizing:content-box;height:0;overflow:visible}pre.sc-ic-menu{font-family:monospace, monospace;font-size:1em}a.sc-ic-menu{background-color:transparent}abbr[title].sc-ic-menu{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b.sc-ic-menu,strong.sc-ic-menu{font-weight:bolder}code.sc-ic-menu,kbd.sc-ic-menu,samp.sc-ic-menu{font-family:monospace, monospace;font-size:1em}small.sc-ic-menu{font-size:80%}sub.sc-ic-menu,sup.sc-ic-menu{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub.sc-ic-menu{bottom:-0.25em}sup.sc-ic-menu{top:-0.5em}img.sc-ic-menu{border-style:none}button.sc-ic-menu,input.sc-ic-menu,optgroup.sc-ic-menu,select.sc-ic-menu,textarea.sc-ic-menu{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button.sc-ic-menu,input.sc-ic-menu{overflow:visible}button.sc-ic-menu,select.sc-ic-menu{text-transform:none}button.sc-ic-menu,[type=\"button\"].sc-ic-menu,[type=\"reset\"].sc-ic-menu,[type=\"submit\"].sc-ic-menu{-webkit-appearance:button}button.sc-ic-menu::-moz-focus-inner,[type=\"button\"].sc-ic-menu::-moz-focus-inner,[type=\"reset\"].sc-ic-menu::-moz-focus-inner,[type=\"submit\"].sc-ic-menu::-moz-focus-inner{border-style:none;padding:0}button.sc-ic-menu:-moz-focusring,[type=\"button\"].sc-ic-menu:-moz-focusring,[type=\"reset\"].sc-ic-menu:-moz-focusring,[type=\"submit\"].sc-ic-menu:-moz-focusring{outline:1px dotted ButtonText}fieldset.sc-ic-menu{padding:0.35em 0.75em 0.625em}legend.sc-ic-menu{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress.sc-ic-menu{vertical-align:baseline}textarea.sc-ic-menu{overflow:auto}[type=\"checkbox\"].sc-ic-menu,[type=\"radio\"].sc-ic-menu{box-sizing:border-box;padding:0}[type=\"number\"].sc-ic-menu::-webkit-inner-spin-button,[type=\"number\"].sc-ic-menu::-webkit-outer-spin-button{height:auto}[type=\"search\"].sc-ic-menu{-webkit-appearance:textfield;outline-offset:-2px}[type=\"search\"].sc-ic-menu::-webkit-search-decoration{-webkit-appearance:none}.sc-ic-menu::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details.sc-ic-menu{display:block}summary.sc-ic-menu{display:list-item}template.sc-ic-menu{display:none}[hidden].sc-ic-menu{display:none}html.sc-ic-menu,body.sc-ic-menu,div.sc-ic-menu,span.sc-ic-menu,applet.sc-ic-menu,object.sc-ic-menu,iframe.sc-ic-menu,h1.sc-ic-menu,h2.sc-ic-menu,h3.sc-ic-menu,h4.sc-ic-menu,h5.sc-ic-menu,h6.sc-ic-menu,p.sc-ic-menu,blockquote.sc-ic-menu,pre.sc-ic-menu,a.sc-ic-menu,abbr.sc-ic-menu,acronym.sc-ic-menu,address.sc-ic-menu,big.sc-ic-menu,cite.sc-ic-menu,code.sc-ic-menu,del.sc-ic-menu,dfn.sc-ic-menu,em.sc-ic-menu,img.sc-ic-menu,ins.sc-ic-menu,kbd.sc-ic-menu,q.sc-ic-menu,s.sc-ic-menu,samp.sc-ic-menu,small.sc-ic-menu,strike.sc-ic-menu,strong.sc-ic-menu,sub.sc-ic-menu,sup.sc-ic-menu,tt.sc-ic-menu,var.sc-ic-menu,b.sc-ic-menu,u.sc-ic-menu,i.sc-ic-menu,center.sc-ic-menu,dl.sc-ic-menu,dt.sc-ic-menu,dd.sc-ic-menu,ol.sc-ic-menu,ul.sc-ic-menu,li.sc-ic-menu,fieldset.sc-ic-menu,form.sc-ic-menu,label.sc-ic-menu,legend.sc-ic-menu,table.sc-ic-menu,caption.sc-ic-menu,tbody.sc-ic-menu,tfoot.sc-ic-menu,thead.sc-ic-menu,tr.sc-ic-menu,th.sc-ic-menu,td.sc-ic-menu,article.sc-ic-menu,aside.sc-ic-menu,canvas.sc-ic-menu,details.sc-ic-menu,embed.sc-ic-menu,figure.sc-ic-menu,figcaption.sc-ic-menu,footer.sc-ic-menu,header.sc-ic-menu,hgroup.sc-ic-menu,menu.sc-ic-menu,nav.sc-ic-menu,output.sc-ic-menu,ruby.sc-ic-menu,section.sc-ic-menu,summary.sc-ic-menu,time.sc-ic-menu,mark.sc-ic-menu,audio.sc-ic-menu,video.sc-ic-menu{margin:0;padding:0;border:0;font-size:100%;font-style:inherit;vertical-align:baseline}@media (prefers-reduced-motion: no-preference){.ic-menu-open.sc-ic-menu-h .menu.sc-ic-menu{transition:max-height var(--ic-transition-duration-slow)}}.sc-ic-menu-h{max-height:0;width:var(--menu-width, var(--input-width, 20rem));color:var(--menu-item-text-color, var(--ic-menu-list-option-text-color));--ic-typography-color:var(\n --menu-item-text-color,\n var(--ic-menu-list-option-text-color)\n );background-color:var(\n --menu-bg-color,\n var(--ic-menu-list-option-background-color)\n );position:relative;z-index:var(--ic-z-index-menu);box-sizing:border-box;box-shadow:var(--ic-elevation-overlay);border-radius:var(--ic-border-radius)}.ic-menu-open.sc-ic-menu-h:not(.ic-menu-no-focus):focus-within{box-shadow:var(--ic-border-focus);outline:var(--ic-hc-focus-outline)}.ic-select-select-all-focused.sc-ic-menu-h{box-shadow:var(--ic-elevation-overlay) !important}#retry-button.sc-ic-menu::part(button){height:var(--ic-space-lg)}.small.sc-ic-menu #retry-button.sc-ic-menu::part(button){height:var(--ic-space-md)}.on-dialog.sc-ic-menu-h{inset:auto !important}.menu.sc-ic-menu{text-decoration:none;list-style-type:none;border-radius:1px;background-color:var(\n --menu-bg-color,\n var(--ic-menu-list-option-background-color)\n );visibility:hidden;max-height:0;overflow-y:hidden}.menu.sc-ic-menu:has(+.option-bar).sc-ic-menu{border-radius:0 0 1px 1px}.menu-scroll.sc-ic-menu{overflow-y:auto}.menu.sc-ic-menu:focus-visible{outline:none}.ic-menu-open.sc-ic-menu-h{max-height:none;display:flex;flex-direction:column-reverse;border:var(--ic-border-width) solid\n var(--menu-border-color, var(--ic-menu-border-color));transition:box-shadow var(--ic-easing-transition-fast)}.ic-menu-open.sc-ic-menu-h .menu.sc-ic-menu{visibility:visible;max-height:calc(var(--ic-space-xl) * 10 + var(--ic-space-xxxs))}.ic-menu-open.sc-ic-menu-h .option-bar.sc-ic-menu{visibility:visible}.ic-menu-open.sc-ic-menu-h .select-all-button.sc-ic-menu{display:block}.ic-menu-full-width.sc-ic-menu-h{width:100%}.option.sc-ic-menu{padding:var(--ic-space-xs) calc(var(--ic-space-xs) - var(--ic-space-1px));cursor:pointer;display:flex;align-items:center;gap:var(--ic-space-xs)}.loading-option.sc-ic-menu p.sc-ic-menu{margin-bottom:0 !important}.option.sc-ic-menu:not(.loading-option){justify-content:space-between}.ic-menu-small.sc-ic-menu-h .option.sc-ic-menu{padding:var(--ic-space-xxs) calc(var(--ic-space-xs) - var(--ic-space-1px))}.ic-menu-large.sc-ic-menu-h .option.sc-ic-menu{padding:var(--ic-space-sm) calc(var(--ic-space-xs) - var(--ic-space-1px))}.option.sc-ic-menu:last-child{border-radius:0 0 1px 1px}.sc-ic-menu:not(.menu:has(+.option-bar)).sc-ic-menu .option.sc-ic-menu:first-child{border-radius:1px 1px 0 0}.option.sc-ic-menu:not(.disabled-option):hover{background-color:var(--ic-menu-list-option-hover-background-color)}.option.sc-ic-menu:not(.disabled-option):active{background-color:var(--ic-menu-list-option-pressed-background-color)}.option.sc-ic-menu:focus-visible{outline:var(--ic-hc-focus-outline)}.option.sc-ic-menu:not(.disabled-option) .option-description.sc-ic-menu{--ic-typography-color:var(\n --menu-item-desc-text-color,\n var(--ic-menu-list-option-description-text-color)\n )}.option.sc-ic-menu .option-label.sc-ic-menu{display:flex;flex-direction:row;align-items:flex-start;gap:var(--ic-space-xs)}.option.sc-ic-menu .option-label.sc-ic-menu ic-typography.sc-ic-menu{max-width:100%;word-wrap:break-word}.option.sc-ic-menu .option-element.sc-ic-menu{margin-top:var(--ic-space-xxs)}.option.sc-ic-menu .option-icon.sc-ic-menu{height:var(--ic-space-lg);width:var(--ic-space-lg);min-width:var(--ic-space-lg)}.option.sc-ic-menu .option-icon.sc-ic-menu>svg.sc-ic-menu{height:100%;width:100%}.option-label.sc-ic-menu:has(.option-icon)+.option-description.sc-ic-menu{margin-left:calc(var(--ic-space-lg) + var(--ic-space-xs))}.option-text-container.sc-ic-menu{pointer-events:none;width:100%}.option-text-container.show-check-icon.sc-ic-menu{flex-grow:1}.option.loading-option.sc-ic-menu .option-text-container.sc-ic-menu{margin-left:calc(var(--ic-space-xs) + var(--ic-space-xxxs));color:var(--ic-menu-loading-list-option-text-color);--ic-typography-color:var(--ic-menu-loading-list-option-text-color)}.error-icon-svg.sc-ic-menu{height:var(--ic-space-md);width:var(--ic-space-md);fill:var(--ic-atoms-status-icon-error);align-self:center;display:flex;margin-right:calc(var(--ic-space-xxs) * 1.2)}.loading-error-info.sc-ic-menu{display:flex}.check-icon.sc-ic-menu{height:var(--ic-space-lg);min-width:var(--ic-space-lg);width:var(--ic-space-lg);pointer-events:none}.focused-option.sc-ic-menu .check-icon.sc-ic-menu *.sc-ic-menu{fill:currentcolor}.sc-ic-menu:first-child>.option-group-title.sc-ic-menu{padding:var(--ic-space-xs) calc(var(--ic-space-xs) - var(--ic-space-1px))\n var(--ic-space-xs)}.option-group-title.sc-ic-menu{padding:var(--ic-space-lg) calc(var(--ic-space-xs) - var(--ic-space-1px))\n var(--ic-space-xs);--ic-typography-color:var(--ic-menu-option-group-label-text-color)}.ic-menu-small.sc-ic-menu-h .option-group-title.sc-ic-menu{padding:var(--ic-space-sm) calc(var(--ic-space-xs) - var(--ic-space-1px))\n var(--ic-space-xxs)}.last-recommended-option.sc-ic-menu{border-bottom:var(--ic-menu-last-recommended-option-border)}.disabled-option.sc-ic-menu{color:var(--ic-atoms-list-option-text-disabled-light);--ic-typography-color:var(--ic-atoms-list-option-text-disabled-light);cursor:default;pointer-events:none}.focus-border.sc-ic-menu{border-radius:var(--ic-border-radius);padding:var(--ic-space-xxs);border:var(--ic-space-xxxs) dashed transparent;border-color:var(--ic-popover-menu-border);background-color:var(--ic-color-focus-inner) !important;--icon-height:auto}.focus-disabled.sc-ic-menu{background-color:var(--ic-color-focus-inner) !important;padding:calc(var(--ic-space-xs) - var(--ic-space-xxxs) - var(--ic-space-xxs))\n calc(\n var(--ic-space-xs) - var(--ic-space-1px) - var(--ic-space-xxxs) -\n var(--ic-space-xxs)\n )}.focused-option.sc-ic-menu,.focused-option.sc-ic-menu .option-description.sc-ic-menu{background-color:var(--ic-color-focus-inner) !important;color:var(--ic-atoms-list-option-text-focused-light) !important;--ic-typography-color:var(\n --ic-atoms-list-option-text-focused-light\n ) !important}.no-results.sc-ic-menu-h li.sc-ic-menu{cursor:no-drop}.no-results.sc-ic-menu-h li.sc-ic-menu:hover{background-color:transparent}.option-bar.sc-ic-menu{padding:var(--ic-space-xxs) var(--ic-space-xs);display:flex;align-items:center;justify-content:space-between;background-color:var(--ic-menu-option-bar-background-color);visibility:hidden;border-bottom:var(--ic-border-width) solid\n var(--ic-menu-option-bar-divider-color);border-radius:1px 1px 0 0}.option-bar.sc-ic-menu p.sc-ic-menu{margin-bottom:0 !important}.ic-menu-large.sc-ic-menu-h .option-bar.sc-ic-menu{padding:var(--ic-space-xs)}.select-all-button.sc-ic-menu{display:none}.select-all-button.sc-ic-menu:focus{z-index:calc(var(--ic-z-index-menu) + 1)}@media (forced-colors: active){.focused-option.sc-ic-menu{outline:none;border:0.125rem solid transparent}.disabled-option.sc-ic-menu{color:GrayText;--ic-typography-color:GrayText}}@media screen AND (max-width: 22rem){.sc-ic-menu-h{max-width:var(--menu-width, var(--input-width, 20rem));width:100%}}@media (prefers-reduced-motion: reduce){.ic-menu-open.sc-ic-menu-h{transition:none}}";
|
|
2285
2524
|
const IcMenuStyle0 = icMenuCss;
|
|
2286
2525
|
|
|
2287
2526
|
const Menu = /*@__PURE__*/ proxyCustomElement(class Menu extends HTMLElement {
|