@ionic/core 8.8.12-dev.11782342444.186b6e9c → 8.8.12-dev.11782931922.18ba507c

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.
Files changed (64) hide show
  1. package/components/index.js +1 -1
  2. package/components/ion-action-sheet.js +1 -1
  3. package/components/ion-alert.js +1 -1
  4. package/components/ion-infinite-scroll-content.js +1 -1
  5. package/components/ion-loading.js +1 -1
  6. package/components/ion-refresher-content.js +1 -1
  7. package/components/ion-select-modal.js +1 -1
  8. package/components/ion-select-option.js +1 -1
  9. package/components/ion-select-popover.js +1 -1
  10. package/components/ion-select.js +1 -1
  11. package/components/ion-toast.js +1 -1
  12. package/components/{p-VlRjwhIK.js → p-279dFMvg.js} +1 -1
  13. package/components/{p-CWo79Ftj.js → p-C-Rx1zny.js} +1 -1
  14. package/components/{p-C6x7QJKS.js → p-COdmnpcX.js} +1 -1
  15. package/components/{p-CgGiBa26.js → p-LMGfIvTf.js} +1 -1
  16. package/components/{p-DiCu-HwG.js → p-j9Da6cYO.js} +1 -1
  17. package/components/p-jOtMJMv8.js +4 -0
  18. package/dist/cjs/{index-C147NqgL.js → index-Cueg3U4w.js} +37 -22
  19. package/dist/cjs/index.cjs.js +1 -1
  20. package/dist/cjs/ion-action-sheet.cjs.entry.js +2 -2
  21. package/dist/cjs/ion-alert.cjs.entry.js +2 -2
  22. package/dist/cjs/ion-infinite-scroll_2.cjs.entry.js +1 -1
  23. package/dist/cjs/ion-loading.cjs.entry.js +1 -1
  24. package/dist/cjs/ion-refresher_2.cjs.entry.js +1 -1
  25. package/dist/cjs/ion-select-modal.cjs.entry.js +2 -2
  26. package/dist/cjs/ion-select_3.cjs.entry.js +4 -4
  27. package/dist/cjs/ion-toast.cjs.entry.js +1 -1
  28. package/dist/cjs/{select-option-render-BUmJxlqW.js → select-option-render-DTF50t5r.js} +9 -1
  29. package/dist/collection/components/select-option/select-option.js +3 -3
  30. package/dist/collection/utils/sanitization/index.js +37 -22
  31. package/dist/collection/utils/select-option-render.js +8 -0
  32. package/dist/docs.json +2 -2
  33. package/dist/esm/{index-CtAGDdQq.js → index-DQSkZyOJ.js} +37 -22
  34. package/dist/esm/index.js +1 -1
  35. package/dist/esm/ion-action-sheet.entry.js +2 -2
  36. package/dist/esm/ion-alert.entry.js +2 -2
  37. package/dist/esm/ion-infinite-scroll_2.entry.js +1 -1
  38. package/dist/esm/ion-loading.entry.js +1 -1
  39. package/dist/esm/ion-refresher_2.entry.js +1 -1
  40. package/dist/esm/ion-select-modal.entry.js +2 -2
  41. package/dist/esm/ion-select_3.entry.js +4 -4
  42. package/dist/esm/ion-toast.entry.js +1 -1
  43. package/dist/esm/{select-option-render-CZcvbJ--.js → select-option-render-B8nWZRnd.js} +9 -1
  44. package/dist/html.html-data.json +1 -1
  45. package/dist/ionic/index.esm.js +1 -1
  46. package/dist/ionic/ionic.esm.js +1 -1
  47. package/dist/ionic/{p-5be4fdc3.entry.js → p-038eb991.entry.js} +1 -1
  48. package/dist/ionic/{p-1c5a5a59.entry.js → p-4ace7762.entry.js} +1 -1
  49. package/dist/ionic/{p-c11135d4.entry.js → p-4e9ec5c5.entry.js} +1 -1
  50. package/dist/ionic/{p-74c540f5.entry.js → p-913b218a.entry.js} +1 -1
  51. package/dist/ionic/p-BDtODLZ4.js +4 -0
  52. package/dist/ionic/{p-D3I30-jC.js → p-DCOvXkOm.js} +1 -1
  53. package/dist/ionic/{p-8e00858b.entry.js → p-a9a33367.entry.js} +1 -1
  54. package/dist/ionic/{p-c4156e73.entry.js → p-ad728198.entry.js} +1 -1
  55. package/dist/ionic/{p-0feac19e.entry.js → p-bfc8c629.entry.js} +1 -1
  56. package/dist/ionic/{p-aedf1108.entry.js → p-c08e666a.entry.js} +1 -1
  57. package/dist/types/components/select-option/select-option.d.ts +1 -1
  58. package/dist/types/components.d.ts +2 -2
  59. package/dist/types/utils/sanitization/index.d.ts +9 -5
  60. package/hydrate/index.js +47 -24
  61. package/hydrate/index.mjs +47 -24
  62. package/package.json +1 -1
  63. package/components/p-CMpqV7Co.js +0 -4
  64. package/dist/ionic/p-5x6vmGTf.js +0 -4
package/hydrate/index.js CHANGED
@@ -8765,13 +8765,17 @@ const FOCUS_TRAP_DISABLE_CLASS = 'ion-disable-focus-trap';
8765
8765
  * Sanitize an untrusted HTML string.
8766
8766
  *
8767
8767
  * Parses the string into a detached DOM, removes blocked tags, strips
8768
- * attributes outside the `allowedAttributes` list (refer `sanitizeElement`),
8769
- * and scrubs script-scheme URLs. Returns the sanitized HTML string.
8768
+ * attributes outside the narrow `domStringAllowedAttributes` list (refer
8769
+ * `sanitizeElement`), and scrubs script-scheme URLs. Returns the sanitized
8770
+ * HTML string.
8770
8771
  *
8771
8772
  * Use this when you have an HTML string from an unknown source and need to
8772
8773
  * render it via `innerHTML`. Use `sanitizeDOMTree` instead when you already
8773
8774
  * have a DOM tree and want to sanitize it in place without a string round
8774
- * trip; both apply the same attribute policy.
8775
+ * trip. The two apply the same dangerous-vector scrubbing but different
8776
+ * attribute allowlists: this path stays narrow so existing consumers
8777
+ * (toast, loading, alert message, etc.) are unaffected, while
8778
+ * `sanitizeDOMTree` uses the wider rich-content allowlist.
8775
8779
  *
8776
8780
  * @param untrustedString - The HTML string to sanitize. Pass an
8777
8781
  * `IonicSafeString` to bypass sanitization, or `undefined` to short-circuit.
@@ -8827,7 +8831,7 @@ const sanitizeDOMString = (untrustedString) => {
8827
8831
  const childElements = getElementChildren(element);
8828
8832
  /* eslint-disable-next-line */
8829
8833
  for (let childIndex = 0; childIndex < childElements.length; childIndex++) {
8830
- sanitizeElement(childElements[childIndex]);
8834
+ sanitizeElement(childElements[childIndex], domStringAllowedAttributes);
8831
8835
  }
8832
8836
  }
8833
8837
  });
@@ -8839,7 +8843,7 @@ const sanitizeDOMString = (untrustedString) => {
8839
8843
  const dfChildren = getElementChildren(documentFragment);
8840
8844
  /* eslint-disable-next-line */
8841
8845
  for (let childIndex = 0; childIndex < dfChildren.length; childIndex++) {
8842
- sanitizeElement(dfChildren[childIndex]);
8846
+ sanitizeElement(dfChildren[childIndex], domStringAllowedAttributes);
8843
8847
  }
8844
8848
  // Append document fragment to div
8845
8849
  const fragmentDiv = document.createElement('div');
@@ -8857,8 +8861,8 @@ const sanitizeDOMString = (untrustedString) => {
8857
8861
  * Sanitize an entire trusted DOM tree in place.
8858
8862
  *
8859
8863
  * Removes blocked tags (`script`, `iframe`, etc.) from the subtree and
8860
- * then sanitizes attributes on every remaining element using the same
8861
- * allowlist policy as `sanitizeDOMString` (refer `sanitizeElement`).
8864
+ * then sanitizes attributes on every remaining element using the wider
8865
+ * `richContentAllowedAttributes` allowlist (refer `sanitizeElement`).
8862
8866
  * Component presentational attributes (`size`, `color`, `shape`, inline
8863
8867
  * SVG, `aria-*`, `data-*`) are preserved; `style`, event handlers (`on*`),
8864
8868
  * form/navigation-hijack attributes, script-scheme URLs, and non-image
@@ -8881,7 +8885,7 @@ const sanitizeDOMTree = (root) => {
8881
8885
  matches[i].remove();
8882
8886
  }
8883
8887
  });
8884
- sanitizeElement(root);
8888
+ sanitizeElement(root, richContentAllowedAttributes, richContentAllowedAttributePrefixes);
8885
8889
  };
8886
8890
  /**
8887
8891
  * Clean up current element based on allowed attributes
@@ -8889,7 +8893,7 @@ const sanitizeDOMTree = (root) => {
8889
8893
  * clean those up as well
8890
8894
  */
8891
8895
  // TODO(FW-2832): type (using Element triggers other type errors as well)
8892
- const sanitizeElement = (element) => {
8896
+ const sanitizeElement = (element, allowedAttributes, allowedAttributePrefixes = []) => {
8893
8897
  // IE uses childNodes, so ignore nodes that are not elements
8894
8898
  if (element.nodeType && element.nodeType !== 1) {
8895
8899
  return;
@@ -8922,7 +8926,7 @@ const sanitizeElement = (element) => {
8922
8926
  * (`formaction`, `action`, `target`), namespaced attributes like
8923
8927
  * `xlink:href`, and anything else not explicitly known to be safe.
8924
8928
  */
8925
- if (!isAttributeAllowed(lowerName)) {
8929
+ if (!isAttributeAllowed(lowerName, allowedAttributes, allowedAttributePrefixes)) {
8926
8930
  element.removeAttribute(attributeName);
8927
8931
  continue;
8928
8932
  }
@@ -8965,7 +8969,7 @@ const sanitizeElement = (element) => {
8965
8969
  const childElements = getElementChildren(element);
8966
8970
  /* eslint-disable-next-line */
8967
8971
  for (let i = 0; i < childElements.length; i++) {
8968
- sanitizeElement(childElements[i]);
8972
+ sanitizeElement(childElements[i], allowedAttributes, allowedAttributePrefixes);
8969
8973
  }
8970
8974
  };
8971
8975
  /**
@@ -9025,13 +9029,24 @@ const reflectPropertiesToAttributes = (root) => {
9025
9029
  }
9026
9030
  };
9027
9031
  /**
9028
- * Attribute names that are always safe to keep. Covers global HTML
9029
- * attributes, the Ionic component presentational props that cloned rich
9030
- * content (e.g. `ion-select-option` markup) relies on, and the inert SVG
9031
- * presentation attributes used by inline icons.
9032
+ * Attribute allowlist for `sanitizeDOMString`. Intentionally narrow: this
9033
+ * path sanitizes developer HTML strings rendered via `innerHTML` by
9034
+ * `ion-toast`, `ion-loading`, the `ion-alert` message,
9035
+ * `ion-refresher-content`, and `ion-infinite-scroll-content`, so the list
9036
+ * is kept to the minimum those have always needed. Broadening it here would
9037
+ * change sanitization output for all of those consumers, so the wider
9038
+ * rich-content allowlist below is deliberately scoped to `sanitizeDOMTree`
9039
+ * instead.
9040
+ */
9041
+ const domStringAllowedAttributes = ['class', 'id', 'href', 'src', 'name', 'slot'];
9042
+ /**
9043
+ * Attribute allowlist for `sanitizeDOMTree` (the select rich-content path).
9044
+ * Covers global HTML attributes, the Ionic component presentational props
9045
+ * that cloned rich content (e.g. `ion-select-option` markup) relies on, and
9046
+ * the inert SVG presentation attributes used by inline icons.
9032
9047
  *
9033
9048
  * `aria-*` and `data-*` are allowed separately by prefix (refer
9034
- * `allowedAttributePrefixes`) since they are inert and not worth
9049
+ * `richContentAllowedAttributePrefixes`) since they are inert and not worth
9035
9050
  * enumerating. URL-bearing names (`href`, `src`) are allowed here, but
9036
9051
  * their values are still scrubbed for script schemes in `sanitizeElement`.
9037
9052
  *
@@ -9039,7 +9054,7 @@ const reflectPropertiesToAttributes = (root) => {
9039
9054
  * form/navigation-hijack attributes (`formaction`, `action`, `target`),
9040
9055
  * which are therefore stripped.
9041
9056
  */
9042
- const allowedAttributes = [
9057
+ const richContentAllowedAttributes = [
9043
9058
  // Global / structural
9044
9059
  'class',
9045
9060
  'id',
@@ -9103,16 +9118,16 @@ const allowedAttributes = [
9103
9118
  'opacity',
9104
9119
  ];
9105
9120
  /**
9106
- * Attribute-name prefixes that are always safe to keep. `aria-*` and
9107
- * `data-*` attributes cannot execute script or load resources, so they are
9108
- * allowed wholesale rather than enumerated by name.
9121
+ * Attribute-name prefixes that are always safe to keep in the rich-content
9122
+ * path. `aria-*` and `data-*` attributes cannot execute script or load
9123
+ * resources, so they are allowed wholesale rather than enumerated by name.
9109
9124
  */
9110
- const allowedAttributePrefixes = ['aria-', 'data-'];
9125
+ const richContentAllowedAttributePrefixes = ['aria-', 'data-'];
9111
9126
  /**
9112
9127
  * Whether an attribute name (already lowercased) is safe to keep, by exact
9113
9128
  * match or by an allowed prefix.
9114
9129
  */
9115
- const isAttributeAllowed = (lowerName) => {
9130
+ const isAttributeAllowed = (lowerName, allowedAttributes, allowedAttributePrefixes) => {
9116
9131
  if (allowedAttributes.includes(lowerName)) {
9117
9132
  return true;
9118
9133
  }
@@ -9233,6 +9248,14 @@ const cloneToVNode = (node, keyPrefix, index) => {
9233
9248
  const renderClonedContent = (id, content, className, useSpan = false) => {
9234
9249
  const Tag = useSpan ? 'span' : 'div';
9235
9250
  const keyPrefix = `${className}-${id}`;
9251
+ /**
9252
+ * Do not remove. This is the only sanitization pass for callers that pass
9253
+ * an `HTMLElement` straight to `renderOptionLabel` (e.g. vanilla JS)
9254
+ * without going through `getOptionContent`, which sanitizes upstream.
9255
+ * `cloneToVNode` does pure structural conversion and no security
9256
+ * filtering, so dropping this call would reopen an XSS hole on the
9257
+ * direct `HTMLElement` path.
9258
+ */
9236
9259
  sanitizeDOMTree(content);
9237
9260
  return (hAsync(Tag, { class: className, key: keyPrefix }, Array.from(content.childNodes).map((child, i) => cloneToVNode(child, keyPrefix, i))));
9238
9261
  };
@@ -38303,12 +38326,12 @@ class SelectOption {
38303
38326
  registerInstance(this, hostRef);
38304
38327
  this.inputId = `ion-selopt-${selectOptionIds++}`;
38305
38328
  /**
38306
- * If `true`, the user cannot interact with the select option. This property does not apply when `interface="action-sheet"` as `ion-action-sheet` does not allow for disabled buttons.
38329
+ * If `true`, the user cannot interact with the select option.
38307
38330
  */
38308
38331
  this.disabled = false;
38309
38332
  }
38310
38333
  render() {
38311
- return hAsync(Host, { key: '4f284411b91b98eda59aadc401bc4d8e423caae9', role: "option", id: this.inputId, class: getIonMode$1(this) });
38334
+ return hAsync(Host, { key: '8b8bef0f5a55f18048708c34d3ea3ff0ff2f1d47', role: "option", id: this.inputId, class: getIonMode$1(this) });
38312
38335
  }
38313
38336
  get el() { return getElement(this); }
38314
38337
  static get style() { return selectOptionCss(); }
package/hydrate/index.mjs CHANGED
@@ -8763,13 +8763,17 @@ const FOCUS_TRAP_DISABLE_CLASS = 'ion-disable-focus-trap';
8763
8763
  * Sanitize an untrusted HTML string.
8764
8764
  *
8765
8765
  * Parses the string into a detached DOM, removes blocked tags, strips
8766
- * attributes outside the `allowedAttributes` list (refer `sanitizeElement`),
8767
- * and scrubs script-scheme URLs. Returns the sanitized HTML string.
8766
+ * attributes outside the narrow `domStringAllowedAttributes` list (refer
8767
+ * `sanitizeElement`), and scrubs script-scheme URLs. Returns the sanitized
8768
+ * HTML string.
8768
8769
  *
8769
8770
  * Use this when you have an HTML string from an unknown source and need to
8770
8771
  * render it via `innerHTML`. Use `sanitizeDOMTree` instead when you already
8771
8772
  * have a DOM tree and want to sanitize it in place without a string round
8772
- * trip; both apply the same attribute policy.
8773
+ * trip. The two apply the same dangerous-vector scrubbing but different
8774
+ * attribute allowlists: this path stays narrow so existing consumers
8775
+ * (toast, loading, alert message, etc.) are unaffected, while
8776
+ * `sanitizeDOMTree` uses the wider rich-content allowlist.
8773
8777
  *
8774
8778
  * @param untrustedString - The HTML string to sanitize. Pass an
8775
8779
  * `IonicSafeString` to bypass sanitization, or `undefined` to short-circuit.
@@ -8825,7 +8829,7 @@ const sanitizeDOMString = (untrustedString) => {
8825
8829
  const childElements = getElementChildren(element);
8826
8830
  /* eslint-disable-next-line */
8827
8831
  for (let childIndex = 0; childIndex < childElements.length; childIndex++) {
8828
- sanitizeElement(childElements[childIndex]);
8832
+ sanitizeElement(childElements[childIndex], domStringAllowedAttributes);
8829
8833
  }
8830
8834
  }
8831
8835
  });
@@ -8837,7 +8841,7 @@ const sanitizeDOMString = (untrustedString) => {
8837
8841
  const dfChildren = getElementChildren(documentFragment);
8838
8842
  /* eslint-disable-next-line */
8839
8843
  for (let childIndex = 0; childIndex < dfChildren.length; childIndex++) {
8840
- sanitizeElement(dfChildren[childIndex]);
8844
+ sanitizeElement(dfChildren[childIndex], domStringAllowedAttributes);
8841
8845
  }
8842
8846
  // Append document fragment to div
8843
8847
  const fragmentDiv = document.createElement('div');
@@ -8855,8 +8859,8 @@ const sanitizeDOMString = (untrustedString) => {
8855
8859
  * Sanitize an entire trusted DOM tree in place.
8856
8860
  *
8857
8861
  * Removes blocked tags (`script`, `iframe`, etc.) from the subtree and
8858
- * then sanitizes attributes on every remaining element using the same
8859
- * allowlist policy as `sanitizeDOMString` (refer `sanitizeElement`).
8862
+ * then sanitizes attributes on every remaining element using the wider
8863
+ * `richContentAllowedAttributes` allowlist (refer `sanitizeElement`).
8860
8864
  * Component presentational attributes (`size`, `color`, `shape`, inline
8861
8865
  * SVG, `aria-*`, `data-*`) are preserved; `style`, event handlers (`on*`),
8862
8866
  * form/navigation-hijack attributes, script-scheme URLs, and non-image
@@ -8879,7 +8883,7 @@ const sanitizeDOMTree = (root) => {
8879
8883
  matches[i].remove();
8880
8884
  }
8881
8885
  });
8882
- sanitizeElement(root);
8886
+ sanitizeElement(root, richContentAllowedAttributes, richContentAllowedAttributePrefixes);
8883
8887
  };
8884
8888
  /**
8885
8889
  * Clean up current element based on allowed attributes
@@ -8887,7 +8891,7 @@ const sanitizeDOMTree = (root) => {
8887
8891
  * clean those up as well
8888
8892
  */
8889
8893
  // TODO(FW-2832): type (using Element triggers other type errors as well)
8890
- const sanitizeElement = (element) => {
8894
+ const sanitizeElement = (element, allowedAttributes, allowedAttributePrefixes = []) => {
8891
8895
  // IE uses childNodes, so ignore nodes that are not elements
8892
8896
  if (element.nodeType && element.nodeType !== 1) {
8893
8897
  return;
@@ -8920,7 +8924,7 @@ const sanitizeElement = (element) => {
8920
8924
  * (`formaction`, `action`, `target`), namespaced attributes like
8921
8925
  * `xlink:href`, and anything else not explicitly known to be safe.
8922
8926
  */
8923
- if (!isAttributeAllowed(lowerName)) {
8927
+ if (!isAttributeAllowed(lowerName, allowedAttributes, allowedAttributePrefixes)) {
8924
8928
  element.removeAttribute(attributeName);
8925
8929
  continue;
8926
8930
  }
@@ -8963,7 +8967,7 @@ const sanitizeElement = (element) => {
8963
8967
  const childElements = getElementChildren(element);
8964
8968
  /* eslint-disable-next-line */
8965
8969
  for (let i = 0; i < childElements.length; i++) {
8966
- sanitizeElement(childElements[i]);
8970
+ sanitizeElement(childElements[i], allowedAttributes, allowedAttributePrefixes);
8967
8971
  }
8968
8972
  };
8969
8973
  /**
@@ -9023,13 +9027,24 @@ const reflectPropertiesToAttributes = (root) => {
9023
9027
  }
9024
9028
  };
9025
9029
  /**
9026
- * Attribute names that are always safe to keep. Covers global HTML
9027
- * attributes, the Ionic component presentational props that cloned rich
9028
- * content (e.g. `ion-select-option` markup) relies on, and the inert SVG
9029
- * presentation attributes used by inline icons.
9030
+ * Attribute allowlist for `sanitizeDOMString`. Intentionally narrow: this
9031
+ * path sanitizes developer HTML strings rendered via `innerHTML` by
9032
+ * `ion-toast`, `ion-loading`, the `ion-alert` message,
9033
+ * `ion-refresher-content`, and `ion-infinite-scroll-content`, so the list
9034
+ * is kept to the minimum those have always needed. Broadening it here would
9035
+ * change sanitization output for all of those consumers, so the wider
9036
+ * rich-content allowlist below is deliberately scoped to `sanitizeDOMTree`
9037
+ * instead.
9038
+ */
9039
+ const domStringAllowedAttributes = ['class', 'id', 'href', 'src', 'name', 'slot'];
9040
+ /**
9041
+ * Attribute allowlist for `sanitizeDOMTree` (the select rich-content path).
9042
+ * Covers global HTML attributes, the Ionic component presentational props
9043
+ * that cloned rich content (e.g. `ion-select-option` markup) relies on, and
9044
+ * the inert SVG presentation attributes used by inline icons.
9030
9045
  *
9031
9046
  * `aria-*` and `data-*` are allowed separately by prefix (refer
9032
- * `allowedAttributePrefixes`) since they are inert and not worth
9047
+ * `richContentAllowedAttributePrefixes`) since they are inert and not worth
9033
9048
  * enumerating. URL-bearing names (`href`, `src`) are allowed here, but
9034
9049
  * their values are still scrubbed for script schemes in `sanitizeElement`.
9035
9050
  *
@@ -9037,7 +9052,7 @@ const reflectPropertiesToAttributes = (root) => {
9037
9052
  * form/navigation-hijack attributes (`formaction`, `action`, `target`),
9038
9053
  * which are therefore stripped.
9039
9054
  */
9040
- const allowedAttributes = [
9055
+ const richContentAllowedAttributes = [
9041
9056
  // Global / structural
9042
9057
  'class',
9043
9058
  'id',
@@ -9101,16 +9116,16 @@ const allowedAttributes = [
9101
9116
  'opacity',
9102
9117
  ];
9103
9118
  /**
9104
- * Attribute-name prefixes that are always safe to keep. `aria-*` and
9105
- * `data-*` attributes cannot execute script or load resources, so they are
9106
- * allowed wholesale rather than enumerated by name.
9119
+ * Attribute-name prefixes that are always safe to keep in the rich-content
9120
+ * path. `aria-*` and `data-*` attributes cannot execute script or load
9121
+ * resources, so they are allowed wholesale rather than enumerated by name.
9107
9122
  */
9108
- const allowedAttributePrefixes = ['aria-', 'data-'];
9123
+ const richContentAllowedAttributePrefixes = ['aria-', 'data-'];
9109
9124
  /**
9110
9125
  * Whether an attribute name (already lowercased) is safe to keep, by exact
9111
9126
  * match or by an allowed prefix.
9112
9127
  */
9113
- const isAttributeAllowed = (lowerName) => {
9128
+ const isAttributeAllowed = (lowerName, allowedAttributes, allowedAttributePrefixes) => {
9114
9129
  if (allowedAttributes.includes(lowerName)) {
9115
9130
  return true;
9116
9131
  }
@@ -9231,6 +9246,14 @@ const cloneToVNode = (node, keyPrefix, index) => {
9231
9246
  const renderClonedContent = (id, content, className, useSpan = false) => {
9232
9247
  const Tag = useSpan ? 'span' : 'div';
9233
9248
  const keyPrefix = `${className}-${id}`;
9249
+ /**
9250
+ * Do not remove. This is the only sanitization pass for callers that pass
9251
+ * an `HTMLElement` straight to `renderOptionLabel` (e.g. vanilla JS)
9252
+ * without going through `getOptionContent`, which sanitizes upstream.
9253
+ * `cloneToVNode` does pure structural conversion and no security
9254
+ * filtering, so dropping this call would reopen an XSS hole on the
9255
+ * direct `HTMLElement` path.
9256
+ */
9234
9257
  sanitizeDOMTree(content);
9235
9258
  return (hAsync(Tag, { class: className, key: keyPrefix }, Array.from(content.childNodes).map((child, i) => cloneToVNode(child, keyPrefix, i))));
9236
9259
  };
@@ -38301,12 +38324,12 @@ class SelectOption {
38301
38324
  registerInstance(this, hostRef);
38302
38325
  this.inputId = `ion-selopt-${selectOptionIds++}`;
38303
38326
  /**
38304
- * If `true`, the user cannot interact with the select option. This property does not apply when `interface="action-sheet"` as `ion-action-sheet` does not allow for disabled buttons.
38327
+ * If `true`, the user cannot interact with the select option.
38305
38328
  */
38306
38329
  this.disabled = false;
38307
38330
  }
38308
38331
  render() {
38309
- return hAsync(Host, { key: '4f284411b91b98eda59aadc401bc4d8e423caae9', role: "option", id: this.inputId, class: getIonMode$1(this) });
38332
+ return hAsync(Host, { key: '8b8bef0f5a55f18048708c34d3ea3ff0ff2f1d47', role: "option", id: this.inputId, class: getIonMode$1(this) });
38310
38333
  }
38311
38334
  get el() { return getElement(this); }
38312
38335
  static get style() { return selectOptionCss(); }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ionic/core",
3
- "version": "8.8.12-dev.11782342444.186b6e9c",
3
+ "version": "8.8.12-dev.11782931922.18ba507c",
4
4
  "description": "Base components for Ionic",
5
5
  "engines": {
6
6
  "node": ">= 16"
@@ -1,4 +0,0 @@
1
- /*!
2
- * (C) Ionic http://ionicframework.com - MIT License
3
- */
4
- import{j as t}from"./p-CHqRYvYm.js";const o=o=>{try{if(o instanceof y)return o.value;if(!r()||"string"!=typeof o||""===o)return o;if(o.includes("onload="))return"";const t=document.createDocumentFragment(),e=document.createElement("div");t.appendChild(e),e.innerHTML=o,p.forEach((o=>{const e=t.querySelectorAll(o);for(let o=e.length-1;o>=0;o--){const r=e[o];r.parentNode?r.parentNode.removeChild(r):t.removeChild(r);const s=i(r);for(let t=0;t<s.length;t++)n(s[t])}}));const s=i(t);for(let t=0;t<s.length;t++)n(s[t]);const a=document.createElement("div");a.appendChild(t);const c=a.querySelector("div");return null!==c?c.innerHTML:a.innerHTML}catch(o){return t("sanitizeDOMString",o),""}},e=t=>{r()&&(p.forEach((o=>{const e=t.querySelectorAll(o);for(let t=e.length-1;t>=0;t--)e[t].remove()})),n(t))},n=t=>{if(t.nodeType&&1!==t.nodeType)return;if("undefined"!=typeof NamedNodeMap&&!(t.attributes instanceof NamedNodeMap))return void t.remove();t.removeAttribute("style");for(let o=t.attributes.length-1;o>=0;o--){const e=t.attributes.item(o),n=e.name,i=n.toLowerCase();if(!l(i)){t.removeAttribute(n);continue}const r=e.value;if(null==r)continue;const s=r.replace(f,"").toLowerCase();(s.includes("javascript:")||s.includes("vbscript:")||d.includes(i)&&s.startsWith("data:")&&!u.test(s))&&t.removeAttribute(n)}const o=i(t);for(let t=0;t<o.length;t++)n(o[t])},i=t=>null!=t.children?t.children:t.childNodes,r=()=>{var t;const o=window,e=null===(t=null==o?void 0:o.Ionic)||void 0===t?void 0:t.config;return!e||(e.get?e.get("sanitizerEnabled",!0):!0===e.sanitizerEnabled||void 0===e.sanitizerEnabled)},s=t=>{const o=[];t.tagName in m&&o.push(t);for(const e of Object.keys(m))o.push(...Array.from(t.querySelectorAll(e.toLowerCase())));for(const t of o){if(!(t.tagName in m))continue;const o=m[t.tagName];for(const e of o){const o=t[e];"string"==typeof o&&o.length>0&&!t.hasAttribute(e)&&t.setAttribute(e,o)}}},a=["class","id","slot","name","title","alt","lang","dir","role","type","value","disabled","width","height","href","src","color","size","shape","fill","expand","mode","theme","icon","label","label-placement","justify","inset","lines","ios","md","xmlns","viewbox","preserveaspectratio","stroke","stroke-width","stroke-linecap","stroke-linejoin","stroke-opacity","stroke-dasharray","fill-rule","fill-opacity","clip-rule","d","points","cx","cy","r","rx","ry","x","y","x1","y1","x2","y2","transform","opacity"],c=["aria-","data-"],l=t=>!!a.includes(t)||c.some((o=>t.startsWith(o))),f=/[\u0000-\u0020\u007f-\u00a0]/g,d=["href","src"],u=/^data:image\/(?:png|jpe?g|gif|webp|bmp|avif|x-icon|vnd\.microsoft\.icon)[;,]/,p=["script","style","iframe","meta","link","object","embed","base"],m={"ION-ICON":["icon","name","src","ios","md"]};class y{constructor(t){this.value=t}}export{y as I,o as a,s as r,e as s}
@@ -1,4 +0,0 @@
1
- /*!
2
- * (C) Ionic http://ionicframework.com - MIT License
3
- */
4
- import{j as t}from"./p-tcQvqkiX.js";const o=o=>{try{if(o instanceof y)return o.value;if(!r()||"string"!=typeof o||""===o)return o;if(o.includes("onload="))return"";const t=document.createDocumentFragment(),e=document.createElement("div");t.appendChild(e),e.innerHTML=o,p.forEach((o=>{const e=t.querySelectorAll(o);for(let o=e.length-1;o>=0;o--){const r=e[o];r.parentNode?r.parentNode.removeChild(r):t.removeChild(r);const s=i(r);for(let t=0;t<s.length;t++)n(s[t])}}));const s=i(t);for(let t=0;t<s.length;t++)n(s[t]);const a=document.createElement("div");a.appendChild(t);const c=a.querySelector("div");return null!==c?c.innerHTML:a.innerHTML}catch(o){return t("sanitizeDOMString",o),""}},e=t=>{r()&&(p.forEach((o=>{const e=t.querySelectorAll(o);for(let t=e.length-1;t>=0;t--)e[t].remove()})),n(t))},n=t=>{if(t.nodeType&&1!==t.nodeType)return;if("undefined"!=typeof NamedNodeMap&&!(t.attributes instanceof NamedNodeMap))return void t.remove();t.removeAttribute("style");for(let o=t.attributes.length-1;o>=0;o--){const e=t.attributes.item(o),n=e.name,i=n.toLowerCase();if(!l(i)){t.removeAttribute(n);continue}const r=e.value;if(null==r)continue;const s=r.replace(f,"").toLowerCase();(s.includes("javascript:")||s.includes("vbscript:")||d.includes(i)&&s.startsWith("data:")&&!u.test(s))&&t.removeAttribute(n)}const o=i(t);for(let t=0;t<o.length;t++)n(o[t])},i=t=>null!=t.children?t.children:t.childNodes,r=()=>{var t;const o=window,e=null===(t=null==o?void 0:o.Ionic)||void 0===t?void 0:t.config;return!e||(e.get?e.get("sanitizerEnabled",!0):!0===e.sanitizerEnabled||void 0===e.sanitizerEnabled)},s=t=>{const o=[];t.tagName in m&&o.push(t);for(const e of Object.keys(m))o.push(...Array.from(t.querySelectorAll(e.toLowerCase())));for(const t of o){if(!(t.tagName in m))continue;const o=m[t.tagName];for(const e of o){const o=t[e];"string"==typeof o&&o.length>0&&!t.hasAttribute(e)&&t.setAttribute(e,o)}}},a=["class","id","slot","name","title","alt","lang","dir","role","type","value","disabled","width","height","href","src","color","size","shape","fill","expand","mode","theme","icon","label","label-placement","justify","inset","lines","ios","md","xmlns","viewbox","preserveaspectratio","stroke","stroke-width","stroke-linecap","stroke-linejoin","stroke-opacity","stroke-dasharray","fill-rule","fill-opacity","clip-rule","d","points","cx","cy","r","rx","ry","x","y","x1","y1","x2","y2","transform","opacity"],c=["aria-","data-"],l=t=>!!a.includes(t)||c.some((o=>t.startsWith(o))),f=/[\u0000-\u0020\u007f-\u00a0]/g,d=["href","src"],u=/^data:image\/(?:png|jpe?g|gif|webp|bmp|avif|x-icon|vnd\.microsoft\.icon)[;,]/,p=["script","style","iframe","meta","link","object","embed","base"],m={"ION-ICON":["icon","name","src","ios","md"]};class y{constructor(t){this.value=t}}export{y as I,e as a,s as r,o as s}