@touchvue/chat 1.0.0-beta.51 → 1.0.0-beta.52

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 (132) hide show
  1. package/README.md +70 -70
  2. package/es/node_modules/.pnpm/{dompurify@3.4.3 → dompurify@3.3.0}/node_modules/dompurify/dist/purify.es.mjs +143 -299
  3. package/es/node_modules/.pnpm/dompurify@3.3.0/node_modules/dompurify/dist/purify.es.mjs.map +1 -0
  4. package/es/package.json.css +1 -1
  5. package/es/package.json.mjs +1 -1
  6. package/es/packages/components/resolver.mjs.map +1 -1
  7. package/es/packages/components/touchchat/component/AiRobot/HelloChat.vue2.mjs.map +1 -1
  8. package/es/packages/components/touchchat/component/AiRobot/letter.vue.mjs +1 -1
  9. package/es/packages/components/touchchat/component/AiRobot/letter.vue2.mjs +9 -9
  10. package/es/packages/components/touchchat/component/AiRobot/letter.vue2.mjs.map +1 -1
  11. package/es/packages/components/touchchat/component/FileContent.vue2.mjs +3 -3
  12. package/es/packages/components/touchchat/component/FileContent.vue2.mjs.map +1 -1
  13. package/es/packages/components/touchchat/component/FileView.vue2.mjs +2 -2
  14. package/es/packages/components/touchchat/component/FileView.vue2.mjs.map +1 -1
  15. package/es/packages/components/touchchat/component/HelloChat.vue2.mjs.map +1 -1
  16. package/es/packages/components/touchchat/component/ImageFile.vue2.mjs +6 -6
  17. package/es/packages/components/touchchat/component/ImageFile.vue2.mjs.map +1 -1
  18. package/es/packages/components/touchchat/component/ImageView.vue2.mjs +1 -1
  19. package/es/packages/components/touchchat/component/ImageView.vue2.mjs.map +1 -1
  20. package/es/packages/components/touchchat/component/LinkView.vue2.mjs +4 -4
  21. package/es/packages/components/touchchat/component/LinkView.vue2.mjs.map +1 -1
  22. package/es/packages/components/touchchat/component/MarkLayer.vue2.mjs +1 -1
  23. package/es/packages/components/touchchat/component/MarkLayer.vue2.mjs.map +1 -1
  24. package/es/packages/components/touchchat/component/ModuleSelect.vue2.mjs +2 -2
  25. package/es/packages/components/touchchat/component/ModuleSelect.vue2.mjs.map +1 -1
  26. package/es/packages/components/touchchat/component/PDFFile.vue2.mjs +10 -10
  27. package/es/packages/components/touchchat/component/PDFFile.vue2.mjs.map +1 -1
  28. package/es/packages/components/touchchat/component/QuoteContent.vue2.mjs.map +1 -1
  29. package/es/packages/components/touchchat/component/RealtimeVoice.vue2.mjs +1 -1
  30. package/es/packages/components/touchchat/component/RealtimeVoice.vue2.mjs.map +1 -1
  31. package/es/packages/components/touchchat/component/UploadView.vue2.mjs.map +1 -1
  32. package/es/packages/components/touchchat/component/VideoFile.vue.mjs +1 -1
  33. package/es/packages/components/touchchat/component/VideoFile.vue2.mjs.map +1 -1
  34. package/es/packages/components/touchchat/src/AiChat/AgentsView.vue2.mjs +1 -1
  35. package/es/packages/components/touchchat/src/AiChat/AgentsView.vue2.mjs.map +1 -1
  36. package/es/packages/components/touchchat/src/AiChat/AiMessage.vue2.mjs +30 -30
  37. package/es/packages/components/touchchat/src/AiChat/AiMessage.vue2.mjs.map +1 -1
  38. package/es/packages/components/touchchat/src/AiChat/Chat/scriptMatcher.mjs.map +1 -1
  39. package/es/packages/components/touchchat/src/AiChat/Chat/types.mjs.map +1 -1
  40. package/es/packages/components/touchchat/src/AiChat/Chat/useChat.mjs +6 -0
  41. package/es/packages/components/touchchat/src/AiChat/Chat/useChat.mjs.map +1 -1
  42. package/es/packages/components/touchchat/src/AiChat/Chat/useCopy.mjs.map +1 -1
  43. package/es/packages/components/touchchat/src/AiChat/Chat/useMessageRender.mjs +1 -1
  44. package/es/packages/components/touchchat/src/AiChat/Chat/useMessageRender.mjs.map +1 -1
  45. package/es/packages/components/touchchat/src/AiChat/Chat/useSSE.mjs +93 -4
  46. package/es/packages/components/touchchat/src/AiChat/Chat/useSSE.mjs.map +1 -1
  47. package/es/packages/components/touchchat/src/AiChat/ChatInput.vue2.mjs +5 -5
  48. package/es/packages/components/touchchat/src/AiChat/ChatInput.vue2.mjs.map +1 -1
  49. package/es/packages/components/touchchat/src/AiChat/HistoryList.vue2.mjs +1 -1
  50. package/es/packages/components/touchchat/src/AiChat/HistoryList.vue2.mjs.map +1 -1
  51. package/es/packages/components/touchchat/src/AiChat/HistorySidebar.vue2.mjs +3 -3
  52. package/es/packages/components/touchchat/src/AiChat/HistorySidebar.vue2.mjs.map +1 -1
  53. package/es/packages/components/touchchat/src/AiChat/MessageActions.vue2.mjs +11 -11
  54. package/es/packages/components/touchchat/src/AiChat/MessageActions.vue2.mjs.map +1 -1
  55. package/es/packages/components/touchchat/src/AiChat/SiderBarView.vue2.mjs +3 -3
  56. package/es/packages/components/touchchat/src/AiChat/SiderBarView.vue2.mjs.map +1 -1
  57. package/es/packages/components/touchchat/src/AiChat/TouchAgent.vue2.mjs +1 -1
  58. package/es/packages/components/touchchat/src/AiChat/TouchChat.vue2.mjs.map +1 -1
  59. package/es/packages/components/touchchat/src/AiChat/TouchHistory.vue2.mjs.map +1 -1
  60. package/es/packages/components/touchchat/src/AiChat/UserMessage.vue2.mjs +16 -16
  61. package/es/packages/components/touchchat/src/AiChat/UserMessage.vue2.mjs.map +1 -1
  62. package/es/packages/components/touchchat/src/index.vue2.mjs.map +1 -1
  63. package/es/packages/components/touchchat/utils/a2aService.mjs.map +1 -1
  64. package/es/packages/components/touchchat/utils/fetchStream.mjs.map +1 -1
  65. package/es/packages/components/touchchat/utils/markdown.mjs +1 -1
  66. package/lib/node_modules/.pnpm/{dompurify@3.4.3 → dompurify@3.3.0}/node_modules/dompurify/dist/purify.es.js +143 -299
  67. package/lib/node_modules/.pnpm/dompurify@3.3.0/node_modules/dompurify/dist/purify.es.js.map +1 -0
  68. package/lib/package.json.css +1 -1
  69. package/lib/package.json.js +1 -1
  70. package/lib/packages/components/resolver.js.map +1 -1
  71. package/lib/packages/components/touchchat/component/AiRobot/HelloChat.vue2.js.map +1 -1
  72. package/lib/packages/components/touchchat/component/AiRobot/letter.vue.js +1 -1
  73. package/lib/packages/components/touchchat/component/AiRobot/letter.vue2.js +9 -9
  74. package/lib/packages/components/touchchat/component/AiRobot/letter.vue2.js.map +1 -1
  75. package/lib/packages/components/touchchat/component/FileContent.vue2.js +3 -3
  76. package/lib/packages/components/touchchat/component/FileContent.vue2.js.map +1 -1
  77. package/lib/packages/components/touchchat/component/FileView.vue2.js +2 -2
  78. package/lib/packages/components/touchchat/component/FileView.vue2.js.map +1 -1
  79. package/lib/packages/components/touchchat/component/HelloChat.vue2.js.map +1 -1
  80. package/lib/packages/components/touchchat/component/ImageFile.vue2.js +6 -6
  81. package/lib/packages/components/touchchat/component/ImageFile.vue2.js.map +1 -1
  82. package/lib/packages/components/touchchat/component/ImageView.vue2.js +1 -1
  83. package/lib/packages/components/touchchat/component/ImageView.vue2.js.map +1 -1
  84. package/lib/packages/components/touchchat/component/LinkView.vue2.js +4 -4
  85. package/lib/packages/components/touchchat/component/LinkView.vue2.js.map +1 -1
  86. package/lib/packages/components/touchchat/component/MarkLayer.vue2.js +1 -1
  87. package/lib/packages/components/touchchat/component/MarkLayer.vue2.js.map +1 -1
  88. package/lib/packages/components/touchchat/component/ModuleSelect.vue2.js +2 -2
  89. package/lib/packages/components/touchchat/component/ModuleSelect.vue2.js.map +1 -1
  90. package/lib/packages/components/touchchat/component/PDFFile.vue2.js +10 -10
  91. package/lib/packages/components/touchchat/component/PDFFile.vue2.js.map +1 -1
  92. package/lib/packages/components/touchchat/component/QuoteContent.vue2.js.map +1 -1
  93. package/lib/packages/components/touchchat/component/RealtimeVoice.vue2.js +1 -1
  94. package/lib/packages/components/touchchat/component/RealtimeVoice.vue2.js.map +1 -1
  95. package/lib/packages/components/touchchat/component/UploadView.vue2.js.map +1 -1
  96. package/lib/packages/components/touchchat/component/VideoFile.vue.js +1 -1
  97. package/lib/packages/components/touchchat/component/VideoFile.vue2.js.map +1 -1
  98. package/lib/packages/components/touchchat/src/AiChat/AgentsView.vue2.js +1 -1
  99. package/lib/packages/components/touchchat/src/AiChat/AgentsView.vue2.js.map +1 -1
  100. package/lib/packages/components/touchchat/src/AiChat/AiMessage.vue2.js +30 -30
  101. package/lib/packages/components/touchchat/src/AiChat/AiMessage.vue2.js.map +1 -1
  102. package/lib/packages/components/touchchat/src/AiChat/Chat/scriptMatcher.js.map +1 -1
  103. package/lib/packages/components/touchchat/src/AiChat/Chat/types.js.map +1 -1
  104. package/lib/packages/components/touchchat/src/AiChat/Chat/useChat.js +6 -0
  105. package/lib/packages/components/touchchat/src/AiChat/Chat/useChat.js.map +1 -1
  106. package/lib/packages/components/touchchat/src/AiChat/Chat/useCopy.js.map +1 -1
  107. package/lib/packages/components/touchchat/src/AiChat/Chat/useMessageRender.js +1 -1
  108. package/lib/packages/components/touchchat/src/AiChat/Chat/useMessageRender.js.map +1 -1
  109. package/lib/packages/components/touchchat/src/AiChat/Chat/useSSE.js +93 -4
  110. package/lib/packages/components/touchchat/src/AiChat/Chat/useSSE.js.map +1 -1
  111. package/lib/packages/components/touchchat/src/AiChat/ChatInput.vue2.js +5 -5
  112. package/lib/packages/components/touchchat/src/AiChat/ChatInput.vue2.js.map +1 -1
  113. package/lib/packages/components/touchchat/src/AiChat/HistoryList.vue2.js +1 -1
  114. package/lib/packages/components/touchchat/src/AiChat/HistoryList.vue2.js.map +1 -1
  115. package/lib/packages/components/touchchat/src/AiChat/HistorySidebar.vue2.js +3 -3
  116. package/lib/packages/components/touchchat/src/AiChat/HistorySidebar.vue2.js.map +1 -1
  117. package/lib/packages/components/touchchat/src/AiChat/MessageActions.vue2.js +11 -11
  118. package/lib/packages/components/touchchat/src/AiChat/MessageActions.vue2.js.map +1 -1
  119. package/lib/packages/components/touchchat/src/AiChat/SiderBarView.vue2.js +3 -3
  120. package/lib/packages/components/touchchat/src/AiChat/SiderBarView.vue2.js.map +1 -1
  121. package/lib/packages/components/touchchat/src/AiChat/TouchAgent.vue2.js +1 -1
  122. package/lib/packages/components/touchchat/src/AiChat/TouchChat.vue2.js.map +1 -1
  123. package/lib/packages/components/touchchat/src/AiChat/TouchHistory.vue2.js.map +1 -1
  124. package/lib/packages/components/touchchat/src/AiChat/UserMessage.vue2.js +16 -16
  125. package/lib/packages/components/touchchat/src/AiChat/UserMessage.vue2.js.map +1 -1
  126. package/lib/packages/components/touchchat/src/index.vue2.js.map +1 -1
  127. package/lib/packages/components/touchchat/utils/a2aService.js.map +1 -1
  128. package/lib/packages/components/touchchat/utils/fetchStream.js.map +1 -1
  129. package/lib/packages/components/touchchat/utils/markdown.js +1 -1
  130. package/package.json +83 -83
  131. package/es/node_modules/.pnpm/dompurify@3.4.3/node_modules/dompurify/dist/purify.es.mjs.map +0 -1
  132. package/lib/node_modules/.pnpm/dompurify@3.4.3/node_modules/dompurify/dist/purify.es.js.map +0 -1
@@ -2,65 +2,24 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- /*! @license DOMPurify 3.4.3 | (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.3/LICENSE */
5
+ /*! @license DOMPurify 3.3.0 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.3.0/LICENSE */
6
6
 
7
- function _arrayLikeToArray(r, a) {
8
- (null == a || a > r.length) && (a = r.length);
9
- for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
10
- return n;
11
- }
12
- function _arrayWithHoles(r) {
13
- if (Array.isArray(r)) return r;
14
- }
15
- function _iterableToArrayLimit(r, l) {
16
- var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
17
- if (null != t) {
18
- var e,
19
- n,
20
- i,
21
- u,
22
- a = [],
23
- f = true,
24
- o = false;
25
- try {
26
- if (i = (t = t.call(r)).next, 0 === l) ; else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
27
- } catch (r) {
28
- o = true, n = r;
29
- } finally {
30
- try {
31
- if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
32
- } finally {
33
- if (o) throw n;
34
- }
35
- }
36
- return a;
37
- }
38
- }
39
- function _nonIterableRest() {
40
- throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
41
- }
42
- function _slicedToArray(r, e) {
43
- return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
44
- }
45
- function _unsupportedIterableToArray(r, a) {
46
- if (r) {
47
- if ("string" == typeof r) return _arrayLikeToArray(r, a);
48
- var t = {}.toString.call(r).slice(8, -1);
49
- return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
50
- }
51
- }
52
-
53
- const entries = Object.entries,
54
- setPrototypeOf = Object.setPrototypeOf,
55
- isFrozen = Object.isFrozen,
56
- getPrototypeOf = Object.getPrototypeOf,
57
- getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
58
- let freeze = Object.freeze,
59
- seal = Object.seal,
60
- create = Object.create; // eslint-disable-line import/no-mutable-exports
61
- let _ref = typeof Reflect !== 'undefined' && Reflect,
62
- apply = _ref.apply,
63
- construct = _ref.construct;
7
+ const {
8
+ entries,
9
+ setPrototypeOf,
10
+ isFrozen,
11
+ getPrototypeOf,
12
+ getOwnPropertyDescriptor
13
+ } = Object;
14
+ let {
15
+ freeze,
16
+ seal,
17
+ create
18
+ } = Object; // eslint-disable-line import/no-mutable-exports
19
+ let {
20
+ apply,
21
+ construct
22
+ } = typeof Reflect !== 'undefined' && Reflect;
64
23
  if (!freeze) {
65
24
  freeze = function freeze(x) {
66
25
  return x;
@@ -92,19 +51,13 @@ const arrayLastIndexOf = unapply(Array.prototype.lastIndexOf);
92
51
  const arrayPop = unapply(Array.prototype.pop);
93
52
  const arrayPush = unapply(Array.prototype.push);
94
53
  const arraySplice = unapply(Array.prototype.splice);
95
- const arrayIsArray = Array.isArray;
96
54
  const stringToLowerCase = unapply(String.prototype.toLowerCase);
97
55
  const stringToString = unapply(String.prototype.toString);
98
56
  const stringMatch = unapply(String.prototype.match);
99
57
  const stringReplace = unapply(String.prototype.replace);
100
58
  const stringIndexOf = unapply(String.prototype.indexOf);
101
59
  const stringTrim = unapply(String.prototype.trim);
102
- const numberToString = unapply(Number.prototype.toString);
103
- const booleanToString = unapply(Boolean.prototype.toString);
104
- const bigintToString = typeof BigInt === 'undefined' ? null : unapply(BigInt.prototype.toString);
105
- const symbolToString = typeof Symbol === 'undefined' ? null : unapply(Symbol.prototype.toString);
106
60
  const objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty);
107
- const objectToString = unapply(Object.prototype.toString);
108
61
  const regExpTest = unapply(RegExp.prototype.test);
109
62
  const typeErrorCreate = unconstruct(TypeError);
110
63
  /**
@@ -154,9 +107,6 @@ function addToSet(set, array) {
154
107
  // Prevent prototype setters from intercepting set as a this value.
155
108
  setPrototypeOf(set, null);
156
109
  }
157
- if (!arrayIsArray(array)) {
158
- return set;
159
- }
160
110
  let l = array.length;
161
111
  while (l--) {
162
112
  let element = array[l];
@@ -197,13 +147,10 @@ function cleanArray(array) {
197
147
  */
198
148
  function clone(object) {
199
149
  const newObject = create(null);
200
- for (const _ref2 of entries(object)) {
201
- var _ref3 = _slicedToArray(_ref2, 2);
202
- const property = _ref3[0];
203
- const value = _ref3[1];
150
+ for (const [property, value] of entries(object)) {
204
151
  const isPropertyExist = objectHasOwnProperty(object, property);
205
152
  if (isPropertyExist) {
206
- if (arrayIsArray(value)) {
153
+ if (Array.isArray(value)) {
207
154
  newObject[property] = cleanArray(value);
208
155
  } else if (value && typeof value === 'object' && value.constructor === Object) {
209
156
  newObject[property] = clone(value);
@@ -214,58 +161,6 @@ function clone(object) {
214
161
  }
215
162
  return newObject;
216
163
  }
217
- /**
218
- * Convert non-node values into strings without depending on direct property access.
219
- *
220
- * @param value - The value to stringify.
221
- * @returns A string representation of the provided value.
222
- */
223
- function stringifyValue(value) {
224
- switch (typeof value) {
225
- case 'string':
226
- {
227
- return value;
228
- }
229
- case 'number':
230
- {
231
- return numberToString(value);
232
- }
233
- case 'boolean':
234
- {
235
- return booleanToString(value);
236
- }
237
- case 'bigint':
238
- {
239
- return bigintToString ? bigintToString(value) : '0';
240
- }
241
- case 'symbol':
242
- {
243
- return symbolToString ? symbolToString(value) : 'Symbol()';
244
- }
245
- case 'undefined':
246
- {
247
- return objectToString(value);
248
- }
249
- case 'function':
250
- case 'object':
251
- {
252
- if (value === null) {
253
- return objectToString(value);
254
- }
255
- const valueAsRecord = value;
256
- const valueToString = lookupGetter(valueAsRecord, 'toString');
257
- if (typeof valueToString === 'function') {
258
- const stringified = valueToString(valueAsRecord);
259
- return typeof stringified === 'string' ? stringified : objectToString(stringified);
260
- }
261
- return objectToString(value);
262
- }
263
- default:
264
- {
265
- return objectToString(value);
266
- }
267
- }
268
- }
269
164
  /**
270
165
  * This method automatically checks if the prop is function or getter and behaves accordingly.
271
166
  *
@@ -291,14 +186,6 @@ function lookupGetter(object, prop) {
291
186
  }
292
187
  return fallbackValue;
293
188
  }
294
- function isRegex(value) {
295
- try {
296
- regExpTest(value, '');
297
- return true;
298
- } catch (_unused) {
299
- return false;
300
- }
301
- }
302
189
 
303
190
  const html$1 = freeze(['a', 'abbr', 'acronym', 'address', 'area', 'article', 'aside', 'audio', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'content', 'data', 'datalist', 'dd', 'decorator', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meter', 'nav', 'nobr', 'ol', 'optgroup', 'option', 'output', 'p', 'picture', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'search', 'section', 'select', 'shadow', 'slot', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr']);
304
191
  const svg$1 = freeze(['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'circle', 'clippath', 'defs', 'desc', 'ellipse', 'enterkeyhint', 'exportparts', 'filter', 'font', 'g', 'glyph', 'glyphref', 'hkern', 'image', 'inputmode', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'mpath', 'part', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', 'stop', 'style', 'switch', 'symbol', 'text', 'textpath', 'title', 'tref', 'tspan', 'view', 'vkern']);
@@ -314,14 +201,15 @@ const mathMl$1 = freeze(['math', 'menclose', 'merror', 'mfenced', 'mfrac', 'mgly
314
201
  const mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']);
315
202
  const text = freeze(['#text']);
316
203
 
317
- const html = freeze(['accept', 'action', 'align', 'alt', 'autocapitalize', 'autocomplete', 'autopictureinpicture', 'autoplay', 'background', 'bgcolor', 'border', 'capture', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'controls', 'controlslist', 'coords', 'crossorigin', 'datetime', 'decoding', 'default', 'dir', 'disabled', 'disablepictureinpicture', 'disableremoteplayback', 'download', 'draggable', 'enctype', 'enterkeyhint', 'exportparts', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'inert', 'inputmode', 'integrity', 'ismap', 'kind', 'label', 'lang', 'list', 'loading', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'muted', 'name', 'nonce', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'part', 'pattern', 'placeholder', 'playsinline', 'popover', 'popovertarget', 'popovertargetaction', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'slot', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'translate', 'type', 'usemap', 'valign', 'value', 'width', 'wrap', 'xmlns']);
204
+ const html = freeze(['accept', 'action', 'align', 'alt', 'autocapitalize', 'autocomplete', 'autopictureinpicture', 'autoplay', 'background', 'bgcolor', 'border', 'capture', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'controls', 'controlslist', 'coords', 'crossorigin', 'datetime', 'decoding', 'default', 'dir', 'disabled', 'disablepictureinpicture', 'disableremoteplayback', 'download', 'draggable', 'enctype', 'enterkeyhint', 'exportparts', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'inert', 'inputmode', 'integrity', 'ismap', 'kind', 'label', 'lang', 'list', 'loading', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'muted', 'name', 'nonce', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'part', 'pattern', 'placeholder', 'playsinline', 'popover', 'popovertarget', 'popovertargetaction', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'slot', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'translate', 'type', 'usemap', 'valign', 'value', 'width', 'wrap', 'xmlns', 'slot']);
318
205
  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']);
319
- 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']);
206
+ const mathMl = freeze(['accent', 'accentunder', 'align', 'bevelled', 'close', 'columnsalign', 'columnlines', 'columnspan', 'denomalign', 'depth', 'dir', 'display', 'displaystyle', 'encoding', 'fence', 'frame', 'height', 'href', 'id', 'largeop', 'length', 'linethickness', 'lspace', 'lquote', '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']);
320
207
  const xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']);
321
208
 
322
- const MUSTACHE_EXPR = seal(/{{[\w\W]*|^[\w\W]*}}/g);
323
- const ERB_EXPR = seal(/<%[\w\W]*|^[\w\W]*%>/g);
324
- const TMPLIT_EXPR = seal(/\${[\w\W]*/g);
209
+ // eslint-disable-next-line unicorn/better-regex
210
+ const MUSTACHE_EXPR = seal(/\{\{[\w\W]*|[\w\W]*\}\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode
211
+ const ERB_EXPR = seal(/<%[\w\W]*|[\w\W]*%>/gm);
212
+ const TMPLIT_EXPR = seal(/\$\{[\w\W]*/gm); // eslint-disable-line unicorn/better-regex
325
213
  const DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]+$/); // eslint-disable-line no-useless-escape
326
214
  const ARIA_ATTR = seal(/^aria-[\-\w]+$/); // eslint-disable-line no-useless-escape
327
215
  const IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i // eslint-disable-line no-useless-escape
@@ -332,15 +220,38 @@ const ATTR_WHITESPACE = seal(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205
332
220
  const DOCTYPE_NAME = seal(/^html$/i);
333
221
  const CUSTOM_ELEMENT = seal(/^[a-z][.\w]*(-[.\w]+)+$/i);
334
222
 
223
+ var EXPRESSIONS = /*#__PURE__*/Object.freeze({
224
+ __proto__: null,
225
+ ARIA_ATTR: ARIA_ATTR,
226
+ ATTR_WHITESPACE: ATTR_WHITESPACE,
227
+ CUSTOM_ELEMENT: CUSTOM_ELEMENT,
228
+ DATA_ATTR: DATA_ATTR,
229
+ DOCTYPE_NAME: DOCTYPE_NAME,
230
+ ERB_EXPR: ERB_EXPR,
231
+ IS_ALLOWED_URI: IS_ALLOWED_URI,
232
+ IS_SCRIPT_OR_DATA: IS_SCRIPT_OR_DATA,
233
+ MUSTACHE_EXPR: MUSTACHE_EXPR,
234
+ TMPLIT_EXPR: TMPLIT_EXPR
235
+ });
236
+
335
237
  /* eslint-disable @typescript-eslint/indent */
336
238
  // https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType
337
239
  const NODE_TYPE = {
338
240
  element: 1,
241
+ attribute: 2,
339
242
  text: 3,
243
+ cdataSection: 4,
244
+ entityReference: 5,
245
+ // Deprecated
246
+ entityNode: 6,
340
247
  // Deprecated
341
248
  progressingInstruction: 7,
342
249
  comment: 8,
343
- document: 9};
250
+ document: 9,
251
+ documentType: 10,
252
+ documentFragment: 11,
253
+ notation: 12 // Deprecated
254
+ };
344
255
  const getGlobal = function getGlobal() {
345
256
  return typeof window === 'undefined' ? null : window;
346
257
  };
@@ -398,7 +309,7 @@ const _createHooksMap = function _createHooksMap() {
398
309
  function createDOMPurify() {
399
310
  let window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal();
400
311
  const DOMPurify = root => createDOMPurify(root);
401
- DOMPurify.version = '3.4.3';
312
+ DOMPurify.version = '3.3.0';
402
313
  DOMPurify.removed = [];
403
314
  if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document || !window.Element) {
404
315
  // Not running in a browser, provide a factory function
@@ -406,19 +317,22 @@ function createDOMPurify() {
406
317
  DOMPurify.isSupported = false;
407
318
  return DOMPurify;
408
319
  }
409
- let document = window.document;
320
+ let {
321
+ document
322
+ } = window;
410
323
  const originalDocument = document;
411
324
  const currentScript = originalDocument.currentScript;
412
- const DocumentFragment = window.DocumentFragment,
413
- HTMLTemplateElement = window.HTMLTemplateElement,
414
- Node = window.Node,
415
- Element = window.Element,
416
- NodeFilter = window.NodeFilter,
417
- _window$NamedNodeMap = window.NamedNodeMap,
418
- NamedNodeMap = _window$NamedNodeMap === void 0 ? window.NamedNodeMap || window.MozNamedAttrMap : _window$NamedNodeMap,
419
- HTMLFormElement = window.HTMLFormElement,
420
- DOMParser = window.DOMParser,
421
- trustedTypes = window.trustedTypes;
325
+ const {
326
+ DocumentFragment,
327
+ HTMLTemplateElement,
328
+ Node,
329
+ Element,
330
+ NodeFilter,
331
+ NamedNodeMap = window.NamedNodeMap || window.MozNamedAttrMap,
332
+ HTMLFormElement,
333
+ DOMParser,
334
+ trustedTypes
335
+ } = window;
422
336
  const ElementPrototype = Element.prototype;
423
337
  const cloneNode = lookupGetter(ElementPrototype, 'cloneNode');
424
338
  const remove = lookupGetter(ElementPrototype, 'remove');
@@ -439,26 +353,33 @@ function createDOMPurify() {
439
353
  }
440
354
  let trustedTypesPolicy;
441
355
  let emptyHTML = '';
442
- const _document = document,
443
- implementation = _document.implementation,
444
- createNodeIterator = _document.createNodeIterator,
445
- createDocumentFragment = _document.createDocumentFragment,
446
- getElementsByTagName = _document.getElementsByTagName;
447
- const importNode = originalDocument.importNode;
356
+ const {
357
+ implementation,
358
+ createNodeIterator,
359
+ createDocumentFragment,
360
+ getElementsByTagName
361
+ } = document;
362
+ const {
363
+ importNode
364
+ } = originalDocument;
448
365
  let hooks = _createHooksMap();
449
366
  /**
450
367
  * Expose whether this browser supports running the full DOMPurify.
451
368
  */
452
369
  DOMPurify.isSupported = typeof entries === 'function' && typeof getParentNode === 'function' && implementation && implementation.createHTMLDocument !== undefined;
453
- const MUSTACHE_EXPR$1 = MUSTACHE_EXPR,
454
- ERB_EXPR$1 = ERB_EXPR,
455
- TMPLIT_EXPR$1 = TMPLIT_EXPR,
456
- DATA_ATTR$1 = DATA_ATTR,
457
- ARIA_ATTR$1 = ARIA_ATTR,
458
- IS_SCRIPT_OR_DATA$1 = IS_SCRIPT_OR_DATA,
459
- ATTR_WHITESPACE$1 = ATTR_WHITESPACE,
460
- CUSTOM_ELEMENT$1 = CUSTOM_ELEMENT;
461
- let IS_ALLOWED_URI$1 = IS_ALLOWED_URI;
370
+ const {
371
+ MUSTACHE_EXPR,
372
+ ERB_EXPR,
373
+ TMPLIT_EXPR,
374
+ DATA_ATTR,
375
+ ARIA_ATTR,
376
+ IS_SCRIPT_OR_DATA,
377
+ ATTR_WHITESPACE,
378
+ CUSTOM_ELEMENT
379
+ } = EXPRESSIONS;
380
+ let {
381
+ IS_ALLOWED_URI: IS_ALLOWED_URI$1
382
+ } = EXPRESSIONS;
462
383
  /**
463
384
  * We consider the elements and attributes below to be safe. Ideally
464
385
  * don't add any new ones but feel free to remove unwanted ones.
@@ -636,15 +557,15 @@ function createDOMPurify() {
636
557
  // HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is.
637
558
  transformCaseFunc = PARSER_MEDIA_TYPE === 'application/xhtml+xml' ? stringToString : stringToLowerCase;
638
559
  /* Set configuration parameters */
639
- ALLOWED_TAGS = objectHasOwnProperty(cfg, 'ALLOWED_TAGS') && arrayIsArray(cfg.ALLOWED_TAGS) ? addToSet({}, cfg.ALLOWED_TAGS, transformCaseFunc) : DEFAULT_ALLOWED_TAGS;
640
- ALLOWED_ATTR = objectHasOwnProperty(cfg, 'ALLOWED_ATTR') && arrayIsArray(cfg.ALLOWED_ATTR) ? addToSet({}, cfg.ALLOWED_ATTR, transformCaseFunc) : DEFAULT_ALLOWED_ATTR;
641
- ALLOWED_NAMESPACES = objectHasOwnProperty(cfg, 'ALLOWED_NAMESPACES') && arrayIsArray(cfg.ALLOWED_NAMESPACES) ? addToSet({}, cfg.ALLOWED_NAMESPACES, stringToString) : DEFAULT_ALLOWED_NAMESPACES;
642
- URI_SAFE_ATTRIBUTES = objectHasOwnProperty(cfg, 'ADD_URI_SAFE_ATTR') && arrayIsArray(cfg.ADD_URI_SAFE_ATTR) ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR, transformCaseFunc) : DEFAULT_URI_SAFE_ATTRIBUTES;
643
- DATA_URI_TAGS = objectHasOwnProperty(cfg, 'ADD_DATA_URI_TAGS') && arrayIsArray(cfg.ADD_DATA_URI_TAGS) ? addToSet(clone(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS, transformCaseFunc) : DEFAULT_DATA_URI_TAGS;
644
- FORBID_CONTENTS = objectHasOwnProperty(cfg, 'FORBID_CONTENTS') && arrayIsArray(cfg.FORBID_CONTENTS) ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc) : DEFAULT_FORBID_CONTENTS;
645
- FORBID_TAGS = objectHasOwnProperty(cfg, 'FORBID_TAGS') && arrayIsArray(cfg.FORBID_TAGS) ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : clone({});
646
- FORBID_ATTR = objectHasOwnProperty(cfg, 'FORBID_ATTR') && arrayIsArray(cfg.FORBID_ATTR) ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : clone({});
647
- USE_PROFILES = objectHasOwnProperty(cfg, 'USE_PROFILES') ? cfg.USE_PROFILES && typeof cfg.USE_PROFILES === 'object' ? clone(cfg.USE_PROFILES) : cfg.USE_PROFILES : false;
560
+ ALLOWED_TAGS = objectHasOwnProperty(cfg, 'ALLOWED_TAGS') ? addToSet({}, cfg.ALLOWED_TAGS, transformCaseFunc) : DEFAULT_ALLOWED_TAGS;
561
+ ALLOWED_ATTR = objectHasOwnProperty(cfg, 'ALLOWED_ATTR') ? addToSet({}, cfg.ALLOWED_ATTR, transformCaseFunc) : DEFAULT_ALLOWED_ATTR;
562
+ ALLOWED_NAMESPACES = objectHasOwnProperty(cfg, 'ALLOWED_NAMESPACES') ? addToSet({}, cfg.ALLOWED_NAMESPACES, stringToString) : DEFAULT_ALLOWED_NAMESPACES;
563
+ URI_SAFE_ATTRIBUTES = objectHasOwnProperty(cfg, 'ADD_URI_SAFE_ATTR') ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR, transformCaseFunc) : DEFAULT_URI_SAFE_ATTRIBUTES;
564
+ DATA_URI_TAGS = objectHasOwnProperty(cfg, 'ADD_DATA_URI_TAGS') ? addToSet(clone(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS, transformCaseFunc) : DEFAULT_DATA_URI_TAGS;
565
+ FORBID_CONTENTS = objectHasOwnProperty(cfg, 'FORBID_CONTENTS') ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc) : DEFAULT_FORBID_CONTENTS;
566
+ FORBID_TAGS = objectHasOwnProperty(cfg, 'FORBID_TAGS') ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : clone({});
567
+ FORBID_ATTR = objectHasOwnProperty(cfg, 'FORBID_ATTR') ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : clone({});
568
+ USE_PROFILES = objectHasOwnProperty(cfg, 'USE_PROFILES') ? cfg.USE_PROFILES : false;
648
569
  ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true
649
570
  ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true
650
571
  ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false
@@ -660,20 +581,19 @@ function createDOMPurify() {
660
581
  SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false; // Default false
661
582
  KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true
662
583
  IN_PLACE = cfg.IN_PLACE || false; // Default false
663
- IS_ALLOWED_URI$1 = isRegex(cfg.ALLOWED_URI_REGEXP) ? cfg.ALLOWED_URI_REGEXP : IS_ALLOWED_URI; // Default regexp
664
- NAMESPACE = typeof cfg.NAMESPACE === 'string' ? cfg.NAMESPACE : HTML_NAMESPACE; // Default HTML namespace
665
- MATHML_TEXT_INTEGRATION_POINTS = objectHasOwnProperty(cfg, 'MATHML_TEXT_INTEGRATION_POINTS') && cfg.MATHML_TEXT_INTEGRATION_POINTS && typeof cfg.MATHML_TEXT_INTEGRATION_POINTS === 'object' ? clone(cfg.MATHML_TEXT_INTEGRATION_POINTS) : addToSet({}, ['mi', 'mo', 'mn', 'ms', 'mtext']); // Default built-in map
666
- HTML_INTEGRATION_POINTS = objectHasOwnProperty(cfg, 'HTML_INTEGRATION_POINTS') && cfg.HTML_INTEGRATION_POINTS && typeof cfg.HTML_INTEGRATION_POINTS === 'object' ? clone(cfg.HTML_INTEGRATION_POINTS) : addToSet({}, ['annotation-xml']); // Default built-in map
667
- const customElementHandling = objectHasOwnProperty(cfg, 'CUSTOM_ELEMENT_HANDLING') && cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING === 'object' ? clone(cfg.CUSTOM_ELEMENT_HANDLING) : create(null);
668
- CUSTOM_ELEMENT_HANDLING = create(null);
669
- if (objectHasOwnProperty(customElementHandling, 'tagNameCheck') && isRegexOrFunction(customElementHandling.tagNameCheck)) {
670
- CUSTOM_ELEMENT_HANDLING.tagNameCheck = customElementHandling.tagNameCheck; // Default undefined
584
+ IS_ALLOWED_URI$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI;
585
+ NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE;
586
+ MATHML_TEXT_INTEGRATION_POINTS = cfg.MATHML_TEXT_INTEGRATION_POINTS || MATHML_TEXT_INTEGRATION_POINTS;
587
+ HTML_INTEGRATION_POINTS = cfg.HTML_INTEGRATION_POINTS || HTML_INTEGRATION_POINTS;
588
+ CUSTOM_ELEMENT_HANDLING = cfg.CUSTOM_ELEMENT_HANDLING || {};
589
+ if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck)) {
590
+ CUSTOM_ELEMENT_HANDLING.tagNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck;
671
591
  }
672
- if (objectHasOwnProperty(customElementHandling, 'attributeNameCheck') && isRegexOrFunction(customElementHandling.attributeNameCheck)) {
673
- CUSTOM_ELEMENT_HANDLING.attributeNameCheck = customElementHandling.attributeNameCheck; // Default undefined
592
+ if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)) {
593
+ CUSTOM_ELEMENT_HANDLING.attributeNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck;
674
594
  }
675
- if (objectHasOwnProperty(customElementHandling, 'allowCustomizedBuiltInElements') && typeof customElementHandling.allowCustomizedBuiltInElements === 'boolean') {
676
- CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = customElementHandling.allowCustomizedBuiltInElements; // Default undefined
595
+ if (cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements === 'boolean') {
596
+ CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements;
677
597
  }
678
598
  if (SAFE_FOR_TEMPLATES) {
679
599
  ALLOW_DATA_ATTR = false;
@@ -684,7 +604,7 @@ function createDOMPurify() {
684
604
  /* Parse profile info */
685
605
  if (USE_PROFILES) {
686
606
  ALLOWED_TAGS = addToSet({}, text);
687
- ALLOWED_ATTR = create(null);
607
+ ALLOWED_ATTR = [];
688
608
  if (USE_PROFILES.html === true) {
689
609
  addToSet(ALLOWED_TAGS, html$1);
690
610
  addToSet(ALLOWED_ATTR, html);
@@ -705,46 +625,36 @@ function createDOMPurify() {
705
625
  addToSet(ALLOWED_ATTR, xml);
706
626
  }
707
627
  }
708
- /* Always reset function-based ADD_TAGS / ADD_ATTR checks to prevent
709
- * leaking across calls when switching from function to array config */
710
- EXTRA_ELEMENT_HANDLING.tagCheck = null;
711
- EXTRA_ELEMENT_HANDLING.attributeCheck = null;
712
628
  /* Merge configuration parameters */
713
- if (objectHasOwnProperty(cfg, 'ADD_TAGS')) {
629
+ if (cfg.ADD_TAGS) {
714
630
  if (typeof cfg.ADD_TAGS === 'function') {
715
631
  EXTRA_ELEMENT_HANDLING.tagCheck = cfg.ADD_TAGS;
716
- } else if (arrayIsArray(cfg.ADD_TAGS)) {
632
+ } else {
717
633
  if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {
718
634
  ALLOWED_TAGS = clone(ALLOWED_TAGS);
719
635
  }
720
636
  addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc);
721
637
  }
722
638
  }
723
- if (objectHasOwnProperty(cfg, 'ADD_ATTR')) {
639
+ if (cfg.ADD_ATTR) {
724
640
  if (typeof cfg.ADD_ATTR === 'function') {
725
641
  EXTRA_ELEMENT_HANDLING.attributeCheck = cfg.ADD_ATTR;
726
- } else if (arrayIsArray(cfg.ADD_ATTR)) {
642
+ } else {
727
643
  if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {
728
644
  ALLOWED_ATTR = clone(ALLOWED_ATTR);
729
645
  }
730
646
  addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc);
731
647
  }
732
648
  }
733
- if (objectHasOwnProperty(cfg, 'ADD_URI_SAFE_ATTR') && arrayIsArray(cfg.ADD_URI_SAFE_ATTR)) {
649
+ if (cfg.ADD_URI_SAFE_ATTR) {
734
650
  addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc);
735
651
  }
736
- if (objectHasOwnProperty(cfg, 'FORBID_CONTENTS') && arrayIsArray(cfg.FORBID_CONTENTS)) {
652
+ if (cfg.FORBID_CONTENTS) {
737
653
  if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {
738
654
  FORBID_CONTENTS = clone(FORBID_CONTENTS);
739
655
  }
740
656
  addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc);
741
657
  }
742
- if (objectHasOwnProperty(cfg, 'ADD_FORBID_CONTENTS') && arrayIsArray(cfg.ADD_FORBID_CONTENTS)) {
743
- if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {
744
- FORBID_CONTENTS = clone(FORBID_CONTENTS);
745
- }
746
- addToSet(FORBID_CONTENTS, cfg.ADD_FORBID_CONTENTS, transformCaseFunc);
747
- }
748
658
  /* Add #text in case KEEP_CONTENT is set to true */
749
659
  if (KEEP_CONTENT) {
750
660
  ALLOWED_TAGS['#text'] = true;
@@ -1031,11 +941,6 @@ function createDOMPurify() {
1031
941
  _forceRemove(currentNode);
1032
942
  return true;
1033
943
  }
1034
- /* Remove risky CSS construction leading to mXSS */
1035
- if (SAFE_FOR_XML && currentNode.namespaceURI === HTML_NAMESPACE && tagName === 'style' && _isNode(currentNode.firstElementChild)) {
1036
- _forceRemove(currentNode);
1037
- return true;
1038
- }
1039
944
  /* Remove any occurrence of processing instructions */
1040
945
  if (currentNode.nodeType === NODE_TYPE.progressingInstruction) {
1041
946
  _forceRemove(currentNode);
@@ -1047,7 +952,7 @@ function createDOMPurify() {
1047
952
  return true;
1048
953
  }
1049
954
  /* Remove element if anything forbids its presence */
1050
- if (FORBID_TAGS[tagName] || !(EXTRA_ELEMENT_HANDLING.tagCheck instanceof Function && EXTRA_ELEMENT_HANDLING.tagCheck(tagName)) && !ALLOWED_TAGS[tagName]) {
955
+ if (!(EXTRA_ELEMENT_HANDLING.tagCheck instanceof Function && EXTRA_ELEMENT_HANDLING.tagCheck(tagName)) && (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName])) {
1051
956
  /* Check if we have a custom element to handle */
1052
957
  if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {
1053
958
  if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) {
@@ -1065,6 +970,7 @@ function createDOMPurify() {
1065
970
  const childCount = childNodes.length;
1066
971
  for (let i = childCount - 1; i >= 0; --i) {
1067
972
  const childClone = cloneNode(childNodes[i], true);
973
+ childClone.__removalCount = (currentNode.__removalCount || 0) + 1;
1068
974
  parentNode.insertBefore(childClone, getNextSibling(currentNode));
1069
975
  }
1070
976
  }
@@ -1086,7 +992,7 @@ function createDOMPurify() {
1086
992
  if (SAFE_FOR_TEMPLATES && currentNode.nodeType === NODE_TYPE.text) {
1087
993
  /* Get the element's text content */
1088
994
  content = currentNode.textContent;
1089
- arrayForEach([MUSTACHE_EXPR$1, ERB_EXPR$1, TMPLIT_EXPR$1], expr => {
995
+ arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
1090
996
  content = stringReplace(content, expr, ' ');
1091
997
  });
1092
998
  if (currentNode.textContent !== content) {
@@ -1110,20 +1016,15 @@ function createDOMPurify() {
1110
1016
  */
1111
1017
  // eslint-disable-next-line complexity
1112
1018
  const _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) {
1113
- /* FORBID_ATTR must always win, even if ADD_ATTR predicate would allow it */
1114
- if (FORBID_ATTR[lcName]) {
1115
- return false;
1116
- }
1117
1019
  /* Make sure attribute cannot clobber */
1118
1020
  if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) {
1119
1021
  return false;
1120
1022
  }
1121
- const nameIsPermitted = ALLOWED_ATTR[lcName] || EXTRA_ELEMENT_HANDLING.attributeCheck instanceof Function && EXTRA_ELEMENT_HANDLING.attributeCheck(lcName, lcTag);
1122
1023
  /* Allow valid data-* attributes: At least one character after "-"
1123
1024
  (https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)
1124
1025
  XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)
1125
1026
  We don't need to check the value; it's always URI safe. */
1126
- if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR$1, lcName)) ; else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR$1, lcName)) ; else if (!nameIsPermitted || FORBID_ATTR[lcName]) {
1027
+ if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR, lcName)) ; else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR, lcName)) ; else if (EXTRA_ELEMENT_HANDLING.attributeCheck instanceof Function && EXTRA_ELEMENT_HANDLING.attributeCheck(lcName, lcTag)) ; else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) {
1127
1028
  if (
1128
1029
  // First condition does a very basic check if a) it's basically a valid custom element tagname AND
1129
1030
  // b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
@@ -1135,15 +1036,11 @@ function createDOMPurify() {
1135
1036
  return false;
1136
1037
  }
1137
1038
  /* Check value is safe. First, is attr inert? If so, is safe */
1138
- } else if (URI_SAFE_ATTRIBUTES[lcName]) ; else if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE$1, ''))) ; else if ((lcName === 'src' || lcName === 'xlink:href' || lcName === 'href') && lcTag !== 'script' && stringIndexOf(value, 'data:') === 0 && DATA_URI_TAGS[lcTag]) ; else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA$1, stringReplace(value, ATTR_WHITESPACE$1, ''))) ; else if (value) {
1039
+ } else if (URI_SAFE_ATTRIBUTES[lcName]) ; else if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE, ''))) ; else if ((lcName === 'src' || lcName === 'xlink:href' || lcName === 'href') && lcTag !== 'script' && stringIndexOf(value, 'data:') === 0 && DATA_URI_TAGS[lcTag]) ; else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA, stringReplace(value, ATTR_WHITESPACE, ''))) ; else if (value) {
1139
1040
  return false;
1140
1041
  } else ;
1141
1042
  return true;
1142
1043
  };
1143
- /* Names the HTML spec reserves from valid-custom-element-name; these must
1144
- * never be treated as basic custom elements even when a permissive
1145
- * CUSTOM_ELEMENT_HANDLING.tagNameCheck is configured. */
1146
- const RESERVED_CUSTOM_ELEMENT_NAMES = addToSet({}, ['annotation-xml', 'color-profile', 'font-face', 'font-face-format', 'font-face-name', 'font-face-src', 'font-face-uri', 'missing-glyph']);
1147
1044
  /**
1148
1045
  * _isBasicCustomElement
1149
1046
  * checks if at least one dash is included in tagName, and it's not the first char
@@ -1153,7 +1050,7 @@ function createDOMPurify() {
1153
1050
  * @returns Returns true if the tag name meets the basic criteria for a custom element, otherwise false.
1154
1051
  */
1155
1052
  const _isBasicCustomElement = function _isBasicCustomElement(tagName) {
1156
- return !RESERVED_CUSTOM_ELEMENT_NAMES[stringToLowerCase(tagName)] && regExpTest(CUSTOM_ELEMENT$1, tagName);
1053
+ return tagName !== 'annotation-xml' && stringMatch(tagName, CUSTOM_ELEMENT);
1157
1054
  };
1158
1055
  /**
1159
1056
  * _sanitizeAttributes
@@ -1168,7 +1065,9 @@ function createDOMPurify() {
1168
1065
  const _sanitizeAttributes = function _sanitizeAttributes(currentNode) {
1169
1066
  /* Execute a hook if present */
1170
1067
  _executeHooks(hooks.beforeSanitizeAttributes, currentNode, null);
1171
- const attributes = currentNode.attributes;
1068
+ const {
1069
+ attributes
1070
+ } = currentNode;
1172
1071
  /* Check if we have attributes; if not we might have a text node */
1173
1072
  if (!attributes || _isClobbered(currentNode)) {
1174
1073
  return;
@@ -1184,9 +1083,11 @@ function createDOMPurify() {
1184
1083
  /* Go backwards over all attributes; safely remove bad ones */
1185
1084
  while (l--) {
1186
1085
  const attr = attributes[l];
1187
- const name = attr.name,
1188
- namespaceURI = attr.namespaceURI,
1189
- attrValue = attr.value;
1086
+ const {
1087
+ name,
1088
+ namespaceURI,
1089
+ value: attrValue
1090
+ } = attr;
1190
1091
  const lcName = transformCaseFunc(name);
1191
1092
  const initValue = attrValue;
1192
1093
  let value = name === 'value' ? initValue : stringTrim(initValue);
@@ -1200,16 +1101,14 @@ function createDOMPurify() {
1200
1101
  /* Full DOM Clobbering protection via namespace isolation,
1201
1102
  * Prefix id and name attributes with `user-content-`
1202
1103
  */
1203
- if (SANITIZE_NAMED_PROPS && (lcName === 'id' || lcName === 'name') && stringIndexOf(value, SANITIZE_NAMED_PROPS_PREFIX) !== 0) {
1104
+ if (SANITIZE_NAMED_PROPS && (lcName === 'id' || lcName === 'name')) {
1204
1105
  // Remove the attribute with this value
1205
1106
  _removeAttribute(name, currentNode);
1206
1107
  // Prefix the value and later re-create the attribute with the sanitized value
1207
1108
  value = SANITIZE_NAMED_PROPS_PREFIX + value;
1208
1109
  }
1209
- // Else: already prefixed, leave the attribute alone — the prefix is
1210
- // itself the clobbering protection, and re-applying it is incorrect.
1211
1110
  /* Work around a security issue with comments inside attributes */
1212
- if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|script|title|xmp|textarea|noscript|iframe|noembed|noframes)/i, value)) {
1111
+ if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|title|textarea)/i, value)) {
1213
1112
  _removeAttribute(name, currentNode);
1214
1113
  continue;
1215
1114
  }
@@ -1234,7 +1133,7 @@ function createDOMPurify() {
1234
1133
  }
1235
1134
  /* Sanitize attribute content to be template-safe */
1236
1135
  if (SAFE_FOR_TEMPLATES) {
1237
- arrayForEach([MUSTACHE_EXPR$1, ERB_EXPR$1, TMPLIT_EXPR$1], expr => {
1136
+ arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
1238
1137
  value = stringReplace(value, expr, ' ');
1239
1138
  });
1240
1139
  }
@@ -1288,7 +1187,7 @@ function createDOMPurify() {
1288
1187
  *
1289
1188
  * @param fragment to iterate over recursively
1290
1189
  */
1291
- const _sanitizeShadowDOM2 = function _sanitizeShadowDOM(fragment) {
1190
+ const _sanitizeShadowDOM = function _sanitizeShadowDOM(fragment) {
1292
1191
  let shadowNode = null;
1293
1192
  const shadowIterator = _createNodeIterator(fragment);
1294
1193
  /* Execute a hook if present */
@@ -1302,55 +1201,12 @@ function createDOMPurify() {
1302
1201
  _sanitizeAttributes(shadowNode);
1303
1202
  /* Deep shadow DOM detected */
1304
1203
  if (shadowNode.content instanceof DocumentFragment) {
1305
- _sanitizeShadowDOM2(shadowNode.content);
1204
+ _sanitizeShadowDOM(shadowNode.content);
1306
1205
  }
1307
1206
  }
1308
1207
  /* Execute a hook if present */
1309
1208
  _executeHooks(hooks.afterSanitizeShadowDOM, fragment, null);
1310
1209
  };
1311
- /**
1312
- * _sanitizeAttachedShadowRoots
1313
- *
1314
- * Walks `root` and feeds every attached shadow root we encounter into
1315
- * the existing _sanitizeShadowDOM pipeline. The default node iterator
1316
- * does not descend into shadow trees, so nodes inside an attached
1317
- * shadow root would otherwise be skipped entirely.
1318
- *
1319
- * Two real input paths put attached shadow roots in front of us:
1320
- * 1. IN_PLACE on a DOM node that already has shadow roots attached.
1321
- * 2. DOM-node input where importNode(dirty, true) deep-clones the
1322
- * shadow root because it was created with `clonable: true`.
1323
- *
1324
- * This pass runs once, up front, so the main iteration loop (and the
1325
- * existing _sanitizeShadowDOM template-content recursion) stay
1326
- * untouched — string-input paths are not affected.
1327
- *
1328
- * @param root the subtree root to walk for attached shadow roots
1329
- */
1330
- const _sanitizeAttachedShadowRoots2 = function _sanitizeAttachedShadowRoots(root) {
1331
- if (root.nodeType === NODE_TYPE.element && root.shadowRoot instanceof DocumentFragment) {
1332
- const sr = root.shadowRoot;
1333
- // Recurse first so that nested shadow roots are reached even if
1334
- // _sanitizeShadowDOM removes hosts at this level.
1335
- _sanitizeAttachedShadowRoots2(sr);
1336
- _sanitizeShadowDOM2(sr);
1337
- }
1338
- // Snapshot children before recursing. Sanitization of one subtree
1339
- // (e.g. via an uponSanitizeShadowNode hook) may detach siblings,
1340
- // and naive nextSibling traversal would silently skip the rest of
1341
- // the list once a node is detached.
1342
- const childNodes = root.childNodes;
1343
- if (!childNodes) {
1344
- return;
1345
- }
1346
- const snapshot = [];
1347
- arrayForEach(childNodes, child => {
1348
- arrayPush(snapshot, child);
1349
- });
1350
- for (const child of snapshot) {
1351
- _sanitizeAttachedShadowRoots2(child);
1352
- }
1353
- };
1354
1210
  // eslint-disable-next-line complexity
1355
1211
  DOMPurify.sanitize = function (dirty) {
1356
1212
  let cfg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
@@ -1367,9 +1223,13 @@ function createDOMPurify() {
1367
1223
  }
1368
1224
  /* Stringify, in case dirty is an object */
1369
1225
  if (typeof dirty !== 'string' && !_isNode(dirty)) {
1370
- dirty = stringifyValue(dirty);
1371
- if (typeof dirty !== 'string') {
1372
- throw typeErrorCreate('dirty is not a string, aborting');
1226
+ if (typeof dirty.toString === 'function') {
1227
+ dirty = dirty.toString();
1228
+ if (typeof dirty !== 'string') {
1229
+ throw typeErrorCreate('dirty is not a string, aborting');
1230
+ }
1231
+ } else {
1232
+ throw typeErrorCreate('toString is not a function');
1373
1233
  }
1374
1234
  }
1375
1235
  /* Return dirty HTML if DOMPurify cannot run */
@@ -1388,16 +1248,12 @@ function createDOMPurify() {
1388
1248
  }
1389
1249
  if (IN_PLACE) {
1390
1250
  /* Do some early pre-sanitization to avoid unsafe root nodes */
1391
- const nn = dirty.nodeName;
1392
- if (typeof nn === 'string') {
1393
- const tagName = transformCaseFunc(nn);
1251
+ if (dirty.nodeName) {
1252
+ const tagName = transformCaseFunc(dirty.nodeName);
1394
1253
  if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
1395
1254
  throw typeErrorCreate('root node is forbidden and cannot be sanitized in-place');
1396
1255
  }
1397
1256
  }
1398
- /* Sanitize attached shadow roots before the main iterator runs.
1399
- The iterator does not descend into shadow trees. */
1400
- _sanitizeAttachedShadowRoots2(dirty);
1401
1257
  } else if (dirty instanceof Node) {
1402
1258
  /* If dirty is a DOM element, append to an empty document to avoid
1403
1259
  elements being stripped by the parser */
@@ -1412,10 +1268,6 @@ function createDOMPurify() {
1412
1268
  // eslint-disable-next-line unicorn/prefer-dom-node-append
1413
1269
  body.appendChild(importedNode);
1414
1270
  }
1415
- /* Clonable shadow roots are deep-cloned by importNode(); sanitize
1416
- them before the main iterator runs, since the iterator does not
1417
- descend into shadow trees. */
1418
- _sanitizeAttachedShadowRoots2(importedNode);
1419
1271
  } else {
1420
1272
  /* Exit directly if we have nothing to do */
1421
1273
  if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT &&
@@ -1444,7 +1296,7 @@ function createDOMPurify() {
1444
1296
  _sanitizeAttributes(currentNode);
1445
1297
  /* Shadow DOM detected, sanitize it */
1446
1298
  if (currentNode.content instanceof DocumentFragment) {
1447
- _sanitizeShadowDOM2(currentNode.content);
1299
+ _sanitizeShadowDOM(currentNode.content);
1448
1300
  }
1449
1301
  }
1450
1302
  /* If we sanitized `dirty` in-place, return it. */
@@ -1453,14 +1305,6 @@ function createDOMPurify() {
1453
1305
  }
1454
1306
  /* Return sanitized string or DOM */
1455
1307
  if (RETURN_DOM) {
1456
- if (SAFE_FOR_TEMPLATES) {
1457
- body.normalize();
1458
- let html = body.innerHTML;
1459
- arrayForEach([MUSTACHE_EXPR$1, ERB_EXPR$1, TMPLIT_EXPR$1], expr => {
1460
- html = stringReplace(html, expr, ' ');
1461
- });
1462
- body.innerHTML = html;
1463
- }
1464
1308
  if (RETURN_DOM_FRAGMENT) {
1465
1309
  returnNode = createDocumentFragment.call(body.ownerDocument);
1466
1310
  while (body.firstChild) {
@@ -1489,7 +1333,7 @@ function createDOMPurify() {
1489
1333
  }
1490
1334
  /* Sanitize final string template-safe */
1491
1335
  if (SAFE_FOR_TEMPLATES) {
1492
- arrayForEach([MUSTACHE_EXPR$1, ERB_EXPR$1, TMPLIT_EXPR$1], expr => {
1336
+ arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
1493
1337
  serializedHTML = stringReplace(serializedHTML, expr, ' ');
1494
1338
  });
1495
1339
  }