@oat-sa/tao-core-ui 3.24.1 → 3.24.3

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 (140) hide show
  1. package/dist/animable/pulsable/pulsable.js +0 -1
  2. package/dist/autocomplete/css/autocomplete.css +1 -1
  3. package/dist/autocomplete/css/autocomplete.css.map +1 -1
  4. package/dist/badge/css/badge.css +6 -6
  5. package/dist/badge/css/badge.css.map +1 -1
  6. package/dist/breadcrumbs/css/breadcrumbs.css +2 -2
  7. package/dist/breadcrumbs/css/breadcrumbs.css.map +1 -1
  8. package/dist/calculator/css/calculator.css +8 -6
  9. package/dist/calculator/css/calculator.css.map +1 -1
  10. package/dist/class/css/selector.css +4 -4
  11. package/dist/class/css/selector.css.map +1 -1
  12. package/dist/component/css/components.css +5 -5
  13. package/dist/component/css/components.css.map +1 -1
  14. package/dist/component/css/windowComponent.css +1 -1
  15. package/dist/component/css/windowComponent.css.map +1 -1
  16. package/dist/component/draggable.js +0 -1
  17. package/dist/component/resizable.js +0 -1
  18. package/dist/contextualPopup/css/contextualPopup.css +1 -1
  19. package/dist/contextualPopup/css/contextualPopup.css.map +1 -1
  20. package/dist/datatable/css/datatable.css +3 -3
  21. package/dist/datatable/css/datatable.css.map +1 -1
  22. package/dist/datatable.js +1 -2
  23. package/dist/datetime/css/picker.css +13 -13
  24. package/dist/datetime/css/picker.css.map +1 -1
  25. package/dist/documentViewer/css/documentViewer.css +10 -10
  26. package/dist/documentViewer/css/documentViewer.css.map +1 -1
  27. package/dist/documentViewer/providers/pdfViewer/pdfjs/searchEngine.js +0 -1
  28. package/dist/dynamicComponent/css/dynamicComponent.css +1 -1
  29. package/dist/dynamicComponent/css/dynamicComponent.css.map +1 -1
  30. package/dist/dynamicComponent.js +1 -4
  31. package/dist/figure/FigureStateActive.js +20 -23
  32. package/dist/form/css/dropdownForm.css +1 -1
  33. package/dist/form/css/dropdownForm.css.map +1 -1
  34. package/dist/form/widget/widget.js +1 -4
  35. package/dist/highlighter.js +0 -2
  36. package/dist/image/ImgStateActive.js +13 -15
  37. package/dist/interactUtils.js +7 -8
  38. package/dist/itemButtonList/css/item-button-list.css +9 -3
  39. package/dist/itemButtonList/css/item-button-list.css.map +1 -1
  40. package/dist/itemButtonList.js +1 -2
  41. package/dist/keyNavigation/navigableDomElement.js +3 -4
  42. package/dist/keyNavigation/navigator.js +1 -2
  43. package/dist/listbox/css/listbox.css +1 -1
  44. package/dist/listbox/css/listbox.css.map +1 -1
  45. package/dist/maths/calculator/core/board.js +58 -127
  46. package/dist/maths/calculator/core/labels.js +1 -6
  47. package/dist/maths/calculator/css/calculator.css +18 -18
  48. package/dist/maths/calculator/css/calculator.css.map +1 -1
  49. package/dist/maths/calculator/plugins/screen/simpleScreen/simpleScreen.js +1 -6
  50. package/dist/mediaplayer/css/player.css +7 -7
  51. package/dist/mediaplayer/css/player.css.map +1 -1
  52. package/dist/mediaplayer/players/html5.js +3 -14
  53. package/dist/mediaplayer/players/youtube.js +3 -12
  54. package/dist/mediaplayer/utils/crossOrigin.js +1 -1
  55. package/dist/mediaplayer/utils/timeObserver.js +1 -2
  56. package/dist/mediaplayer/youtubeManager.js +1 -2
  57. package/dist/mediaplayer.js +2 -8
  58. package/dist/mediasizer.js +0 -1
  59. package/dist/resizeObserver.js +1 -3
  60. package/dist/resource/css/selector.css +31 -23
  61. package/dist/resource/css/selector.css.map +1 -1
  62. package/dist/resource/list.js +239 -203
  63. package/dist/resource/selector.js +0 -1
  64. package/dist/resource/tree.js +239 -203
  65. package/dist/resourcemgr/assetSearch.js +20 -18
  66. package/dist/resourcemgr/assetSearchContract.js +67 -12
  67. package/dist/resourcemgr/css/resourcemgr.css +17 -18
  68. package/dist/resourcemgr/css/resourcemgr.css.map +1 -1
  69. package/dist/resourcemgr/fileBrowser.js +3 -5
  70. package/dist/resourcemgr/fileSelector.js +3 -0
  71. package/dist/searchModal/advancedSearch.js +3 -4
  72. package/dist/searchModal/css/searchModal.css +14 -14
  73. package/dist/searchModal/css/searchModal.css.map +1 -1
  74. package/dist/searchModal.js +42 -53
  75. package/dist/switch/css/switch.css +2 -2
  76. package/dist/switch/css/switch.css.map +1 -1
  77. package/dist/tabs/css/tabs.css +2 -2
  78. package/dist/tabs/css/tabs.css.map +1 -1
  79. package/dist/taskQueue/css/taskQueue.css +4 -4
  80. package/dist/taskQueue/css/taskQueue.css.map +1 -1
  81. package/dist/taskQueue/taskQueueModel.js +1 -2
  82. package/dist/taskQueueButton/taskable.js +1 -2
  83. package/dist/validator/validators.js +0 -1
  84. package/dist/waitingDialog/css/waitingDialog.css +2 -2
  85. package/dist/waitingDialog/css/waitingDialog.css.map +1 -1
  86. package/package.json +1 -1
  87. package/src/autocomplete/css/autocomplete.css +1 -1
  88. package/src/autocomplete/css/autocomplete.css.map +1 -1
  89. package/src/badge/css/badge.css +6 -6
  90. package/src/badge/css/badge.css.map +1 -1
  91. package/src/breadcrumbs/css/breadcrumbs.css +2 -2
  92. package/src/breadcrumbs/css/breadcrumbs.css.map +1 -1
  93. package/src/calculator/css/calculator.css +8 -6
  94. package/src/calculator/css/calculator.css.map +1 -1
  95. package/src/class/css/selector.css +4 -4
  96. package/src/class/css/selector.css.map +1 -1
  97. package/src/component/css/components.css +5 -5
  98. package/src/component/css/components.css.map +1 -1
  99. package/src/component/css/windowComponent.css +1 -1
  100. package/src/component/css/windowComponent.css.map +1 -1
  101. package/src/contextualPopup/css/contextualPopup.css +1 -1
  102. package/src/contextualPopup/css/contextualPopup.css.map +1 -1
  103. package/src/css/basic.css +123 -113
  104. package/src/css/basic.css.map +1 -1
  105. package/src/datatable/css/datatable.css +3 -3
  106. package/src/datatable/css/datatable.css.map +1 -1
  107. package/src/datetime/css/picker.css +13 -13
  108. package/src/datetime/css/picker.css.map +1 -1
  109. package/src/documentViewer/css/documentViewer.css +10 -10
  110. package/src/documentViewer/css/documentViewer.css.map +1 -1
  111. package/src/dynamicComponent/css/dynamicComponent.css +1 -1
  112. package/src/dynamicComponent/css/dynamicComponent.css.map +1 -1
  113. package/src/form/css/dropdownForm.css +1 -1
  114. package/src/form/css/dropdownForm.css.map +1 -1
  115. package/src/itemButtonList/css/item-button-list.css +9 -3
  116. package/src/itemButtonList/css/item-button-list.css.map +1 -1
  117. package/src/listbox/css/listbox.css +1 -1
  118. package/src/listbox/css/listbox.css.map +1 -1
  119. package/src/maths/calculator/css/calculator.css +18 -18
  120. package/src/maths/calculator/css/calculator.css.map +1 -1
  121. package/src/mediaplayer/css/player.css +7 -7
  122. package/src/mediaplayer/css/player.css.map +1 -1
  123. package/src/resource/css/selector.css +31 -23
  124. package/src/resource/css/selector.css.map +1 -1
  125. package/src/resourcemgr/assetSearch.js +27 -19
  126. package/src/resourcemgr/assetSearchContract.js +67 -18
  127. package/src/resourcemgr/css/resourcemgr.css +17 -18
  128. package/src/resourcemgr/css/resourcemgr.css.map +1 -1
  129. package/src/resourcemgr/fileBrowser.js +9 -9
  130. package/src/resourcemgr/fileSelector.js +4 -0
  131. package/src/searchModal/css/searchModal.css +14 -14
  132. package/src/searchModal/css/searchModal.css.map +1 -1
  133. package/src/switch/css/switch.css +2 -2
  134. package/src/switch/css/switch.css.map +1 -1
  135. package/src/tabs/css/tabs.css +2 -2
  136. package/src/tabs/css/tabs.css.map +1 -1
  137. package/src/taskQueue/css/taskQueue.css +4 -4
  138. package/src/taskQueue/css/taskQueue.css.map +1 -1
  139. package/src/waitingDialog/css/waitingDialog.css +2 -2
  140. package/src/waitingDialog/css/waitingDialog.css.map +1 -1
@@ -154,7 +154,7 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
154
154
  return (asString || true) ? html : $(html);
155
155
  }
156
156
 
157
- /*! @license DOMPurify 2.4.1 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/2.4.1/LICENSE */
157
+ /*! @license DOMPurify 2.5.9 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/2.5.9/LICENSE */
158
158
 
159
159
  function _typeof(obj) {
160
160
  "@babel/helpers - typeof";
@@ -231,7 +231,6 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
231
231
  var freeze = Object.freeze,
232
232
  seal = Object.seal,
233
233
  create = Object.create; // eslint-disable-line import/no-mutable-exports
234
-
235
234
  var _ref = typeof Reflect !== 'undefined' && Reflect,
236
235
  apply = _ref.apply,
237
236
  construct = _ref.construct;
@@ -282,10 +281,11 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
282
281
  return construct(func, args);
283
282
  };
284
283
  }
285
- /* Add properties to a lookup table */
286
284
 
285
+ /* Add properties to a lookup table */
287
286
  function addToSet(set, array, transformCaseFunc) {
288
- transformCaseFunc = transformCaseFunc ? transformCaseFunc : stringToLowerCase;
287
+ var _transformCaseFunc;
288
+ transformCaseFunc = (_transformCaseFunc = transformCaseFunc) !== null && _transformCaseFunc !== void 0 ? _transformCaseFunc : stringToLowerCase;
289
289
  if (setPrototypeOf) {
290
290
  // Make 'in' and truthy checks like Boolean(set.constructor)
291
291
  // independent of any properties defined on Object.prototype.
@@ -309,23 +309,23 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
309
309
  }
310
310
  return set;
311
311
  }
312
- /* Shallow clone an object */
313
312
 
313
+ /* Shallow clone an object */
314
314
  function clone(object) {
315
315
  var newObject = create(null);
316
316
  var property;
317
317
  for (property in object) {
318
- if (apply(hasOwnProperty, object, [property])) {
318
+ if (apply(hasOwnProperty, object, [property]) === true) {
319
319
  newObject[property] = object[property];
320
320
  }
321
321
  }
322
322
  return newObject;
323
323
  }
324
+
324
325
  /* IE10 doesn't support __lookupGetter__ so lets'
325
326
  * simulate it. It also automatically checks
326
327
  * if the prop is function or getter and behaves
327
328
  * accordingly. */
328
-
329
329
  function lookupGetter(object, prop) {
330
330
  while (object !== null) {
331
331
  var desc = getOwnPropertyDescriptor(object, prop);
@@ -345,43 +345,45 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
345
345
  }
346
346
  return fallbackValue;
347
347
  }
348
- var 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', 'section', 'select', 'shadow', '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']); // SVG
348
+ var 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', 'section', 'select', 'shadow', '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']);
349
349
 
350
+ // SVG
350
351
  var svg$1 = freeze(['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'circle', 'clippath', 'defs', 'desc', 'ellipse', 'filter', 'font', 'g', 'glyph', 'glyphref', 'hkern', 'image', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'mpath', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', 'stop', 'style', 'switch', 'symbol', 'text', 'textpath', 'title', 'tref', 'tspan', 'view', 'vkern']);
351
- var svgFilters = freeze(['feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence']); // List of SVG elements that are disallowed by default.
352
+ var svgFilters = freeze(['feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence']);
353
+
354
+ // List of SVG elements that are disallowed by default.
352
355
  // We still need to know them so that we can do namespace
353
356
  // checks properly in case one wants to add them to
354
357
  // allow-list.
355
-
356
358
  var svgDisallowed = freeze(['animate', 'color-profile', 'cursor', 'discard', 'fedropshadow', 'font-face', 'font-face-format', 'font-face-name', 'font-face-src', 'font-face-uri', 'foreignobject', 'hatch', 'hatchpath', 'mesh', 'meshgradient', 'meshpatch', 'meshrow', 'missing-glyph', 'script', 'set', 'solidcolor', 'unknown', 'use']);
357
- var mathMl$1 = freeze(['math', 'menclose', 'merror', 'mfenced', 'mfrac', 'mglyph', 'mi', 'mlabeledtr', 'mmultiscripts', 'mn', 'mo', 'mover', 'mpadded', 'mphantom', 'mroot', 'mrow', 'ms', 'mspace', 'msqrt', 'mstyle', 'msub', 'msup', 'msubsup', 'mtable', 'mtd', 'mtext', 'mtr', 'munder', 'munderover']); // Similarly to SVG, we want to know all MathML elements,
358
- // even those that we disallow by default.
359
+ var mathMl$1 = freeze(['math', 'menclose', 'merror', 'mfenced', 'mfrac', 'mglyph', 'mi', 'mlabeledtr', 'mmultiscripts', 'mn', 'mo', 'mover', 'mpadded', 'mphantom', 'mroot', 'mrow', 'ms', 'mspace', 'msqrt', 'mstyle', 'msub', 'msup', 'msubsup', 'mtable', 'mtd', 'mtext', 'mtr', 'munder', 'munderover']);
359
360
 
361
+ // Similarly to SVG, we want to know all MathML elements,
362
+ // even those that we disallow by default.
360
363
  var mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']);
361
364
  var text = freeze(['#text']);
362
365
  var 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', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', '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', 'pattern', 'placeholder', 'playsinline', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'translate', 'type', 'usemap', 'valign', 'value', 'width', 'xmlns', 'slot']);
363
366
  var svg = freeze(['accent-height', 'accumulate', 'additive', 'alignment-baseline', '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', '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', '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', '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', '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', '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']);
364
367
  var 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']);
365
368
  var xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']);
366
- var MUSTACHE_EXPR = seal(/\{\{[\w\W]*|[\w\W]*\}\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode
367
369
 
370
+ // eslint-disable-next-line unicorn/better-regex
371
+ var MUSTACHE_EXPR = seal(/\{\{[\w\W]*|[\w\W]*\}\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode
368
372
  var ERB_EXPR = seal(/<%[\w\W]*|[\w\W]*%>/gm);
369
373
  var TMPLIT_EXPR = seal(/\${[\w\W]*}/gm);
370
- var DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]/); // eslint-disable-line no-useless-escape
371
-
374
+ var DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]+$/); // eslint-disable-line no-useless-escape
372
375
  var ARIA_ATTR = seal(/^aria-[\-\w]+$/); // eslint-disable-line no-useless-escape
373
-
374
376
  var IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i // eslint-disable-line no-useless-escape
375
377
  );
376
-
377
378
  var IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i);
378
379
  var ATTR_WHITESPACE = seal(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g // eslint-disable-line no-control-regex
379
380
  );
380
-
381
381
  var DOCTYPE_NAME = seal(/^html$/i);
382
+ var CUSTOM_ELEMENT = seal(/^[a-z][.\w]*(-[.\w]+)+$/i);
382
383
  var getGlobal = function getGlobal() {
383
384
  return typeof window === 'undefined' ? null : window;
384
385
  };
386
+
385
387
  /**
386
388
  * Creates a no-op policy for internal use only.
387
389
  * Don't export this function outside this module!
@@ -390,14 +392,14 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
390
392
  * @return {?TrustedTypePolicy} The policy created (or null, if Trusted Types
391
393
  * are not supported).
392
394
  */
393
-
394
395
  var _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes, document) {
395
396
  if (_typeof(trustedTypes) !== 'object' || typeof trustedTypes.createPolicy !== 'function') {
396
397
  return null;
397
- } // Allow the callers to control the unique policy name
398
+ }
399
+
400
+ // Allow the callers to control the unique policy name
398
401
  // by adding a data-tt-policy-suffix to the script element with the DOMPurify.
399
402
  // Policy creation with duplicate names throws in Trusted Types.
400
-
401
403
  var suffix = null;
402
404
  var ATTR_NAME = 'data-tt-policy-suffix';
403
405
  if (document.currentScript && document.currentScript.hasAttribute(ATTR_NAME)) {
@@ -426,17 +428,17 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
426
428
  var DOMPurify = function DOMPurify(root) {
427
429
  return createDOMPurify(root);
428
430
  };
431
+
429
432
  /**
430
433
  * Version label, exposed for easier checks
431
434
  * if DOMPurify is up to date or not
432
435
  */
436
+ DOMPurify.version = '2.5.9';
433
437
 
434
- DOMPurify.version = '2.4.1';
435
438
  /**
436
439
  * Array of elements that DOMPurify removed during sanitation.
437
440
  * Empty if nothing was removed.
438
441
  */
439
-
440
442
  DOMPurify.removed = [];
441
443
  if (!window || !window.document || window.document.nodeType !== 9) {
442
444
  // Not running in a browser, provide a factory function
@@ -460,13 +462,14 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
460
462
  var cloneNode = lookupGetter(ElementPrototype, 'cloneNode');
461
463
  var getNextSibling = lookupGetter(ElementPrototype, 'nextSibling');
462
464
  var getChildNodes = lookupGetter(ElementPrototype, 'childNodes');
463
- var getParentNode = lookupGetter(ElementPrototype, 'parentNode'); // As per issue #47, the web-components registry is inherited by a
465
+ var getParentNode = lookupGetter(ElementPrototype, 'parentNode');
466
+
467
+ // As per issue #47, the web-components registry is inherited by a
464
468
  // new document created via createHTMLDocument. As per the spec
465
469
  // (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries)
466
470
  // a new empty registry is used when creating a template contents owner
467
471
  // document, so we use that as our parent document to ensure nothing
468
472
  // is inherited.
469
-
470
473
  if (typeof HTMLTemplateElement === 'function') {
471
474
  var template = document.createElement('template');
472
475
  if (template.content && template.content.ownerDocument) {
@@ -486,39 +489,40 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
486
489
  documentMode = clone(document).documentMode ? document.documentMode : {};
487
490
  } catch (_) {}
488
491
  var hooks = {};
492
+
489
493
  /**
490
494
  * Expose whether this browser supports running the full DOMPurify.
491
495
  */
492
-
493
- DOMPurify.isSupported = typeof getParentNode === 'function' && implementation && typeof implementation.createHTMLDocument !== 'undefined' && documentMode !== 9;
496
+ DOMPurify.isSupported = typeof getParentNode === 'function' && implementation && implementation.createHTMLDocument !== undefined && documentMode !== 9;
494
497
  var MUSTACHE_EXPR$1 = MUSTACHE_EXPR,
495
498
  ERB_EXPR$1 = ERB_EXPR,
496
499
  TMPLIT_EXPR$1 = TMPLIT_EXPR,
497
500
  DATA_ATTR$1 = DATA_ATTR,
498
501
  ARIA_ATTR$1 = ARIA_ATTR,
499
502
  IS_SCRIPT_OR_DATA$1 = IS_SCRIPT_OR_DATA,
500
- ATTR_WHITESPACE$1 = ATTR_WHITESPACE;
503
+ ATTR_WHITESPACE$1 = ATTR_WHITESPACE,
504
+ CUSTOM_ELEMENT$1 = CUSTOM_ELEMENT;
501
505
  var IS_ALLOWED_URI$1 = IS_ALLOWED_URI;
506
+
502
507
  /**
503
508
  * We consider the elements and attributes below to be safe. Ideally
504
509
  * don't add any new ones but feel free to remove unwanted ones.
505
510
  */
506
511
 
507
512
  /* allowed element names */
508
-
509
513
  var ALLOWED_TAGS = null;
510
514
  var DEFAULT_ALLOWED_TAGS = addToSet({}, [].concat(_toConsumableArray(html$1), _toConsumableArray(svg$1), _toConsumableArray(svgFilters), _toConsumableArray(mathMl$1), _toConsumableArray(text)));
511
- /* Allowed attribute names */
512
515
 
516
+ /* Allowed attribute names */
513
517
  var ALLOWED_ATTR = null;
514
518
  var DEFAULT_ALLOWED_ATTR = addToSet({}, [].concat(_toConsumableArray(html), _toConsumableArray(svg), _toConsumableArray(mathMl), _toConsumableArray(xml)));
519
+
515
520
  /*
516
521
  * Configure how DOMPUrify should handle custom elements and their attributes as well as customized built-in elements.
517
522
  * @property {RegExp|Function|null} tagNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any custom elements)
518
523
  * @property {RegExp|Function|null} attributeNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any attributes not on the allow list)
519
524
  * @property {boolean} allowCustomizedBuiltInElements allow custom elements derived from built-ins if they pass CUSTOM_ELEMENT_HANDLING.tagNameCheck. Default: `false`.
520
525
  */
521
-
522
526
  var CUSTOM_ELEMENT_HANDLING = Object.seal(Object.create(null, {
523
527
  tagNameCheck: {
524
528
  writable: true,
@@ -539,55 +543,65 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
539
543
  value: false
540
544
  }
541
545
  }));
542
- /* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */
543
546
 
547
+ /* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */
544
548
  var FORBID_TAGS = null;
545
- /* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */
546
549
 
550
+ /* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */
547
551
  var FORBID_ATTR = null;
548
- /* Decide if ARIA attributes are okay */
549
552
 
553
+ /* Decide if ARIA attributes are okay */
550
554
  var ALLOW_ARIA_ATTR = true;
551
- /* Decide if custom data attributes are okay */
552
555
 
556
+ /* Decide if custom data attributes are okay */
553
557
  var ALLOW_DATA_ATTR = true;
554
- /* Decide if unknown protocols are okay */
555
558
 
559
+ /* Decide if unknown protocols are okay */
556
560
  var ALLOW_UNKNOWN_PROTOCOLS = false;
561
+
562
+ /* Decide if self-closing tags in attributes are allowed.
563
+ * Usually removed due to a mXSS issue in jQuery 3.0 */
564
+ var ALLOW_SELF_CLOSE_IN_ATTR = true;
565
+
557
566
  /* Output should be safe for common template engines.
558
567
  * This means, DOMPurify removes data attributes, mustaches and ERB
559
568
  */
560
-
561
569
  var SAFE_FOR_TEMPLATES = false;
562
- /* Decide if document with <html>... should be returned */
563
570
 
571
+ /* Output should be safe even for XML used within HTML and alike.
572
+ * This means, DOMPurify removes comments when containing risky content.
573
+ */
574
+ var SAFE_FOR_XML = true;
575
+
576
+ /* Decide if document with <html>... should be returned */
564
577
  var WHOLE_DOCUMENT = false;
565
- /* Track whether config is already set on this instance of DOMPurify. */
566
578
 
579
+ /* Track whether config is already set on this instance of DOMPurify. */
567
580
  var SET_CONFIG = false;
581
+
568
582
  /* Decide if all elements (e.g. style, script) must be children of
569
583
  * document.body. By default, browsers might move them to document.head */
570
-
571
584
  var FORCE_BODY = false;
585
+
572
586
  /* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html
573
587
  * string (or a TrustedHTML object if Trusted Types are supported).
574
588
  * If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead
575
589
  */
576
-
577
590
  var RETURN_DOM = false;
591
+
578
592
  /* Decide if a DOM `DocumentFragment` should be returned, instead of a html
579
593
  * string (or a TrustedHTML object if Trusted Types are supported) */
580
-
581
594
  var RETURN_DOM_FRAGMENT = false;
595
+
582
596
  /* Try to return a Trusted Type object instead of a string, return a string in
583
597
  * case Trusted Types are not supported */
584
-
585
598
  var RETURN_TRUSTED_TYPE = false;
599
+
586
600
  /* Output should be free from DOM clobbering attacks?
587
601
  * This sanitizes markups named with colliding, clobberable built-in DOM APIs.
588
602
  */
589
-
590
603
  var SANITIZE_DOM = true;
604
+
591
605
  /* Achieve full DOM Clobbering protection by isolating the namespace of named
592
606
  * properties and JS variables, mitigating attacks that abuse the HTML/DOM spec rules.
593
607
  *
@@ -601,85 +615,84 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
601
615
  * Namespace isolation is implemented by prefixing `id` and `name` attributes
602
616
  * with a constant string, i.e., `user-content-`
603
617
  */
604
-
605
618
  var SANITIZE_NAMED_PROPS = false;
606
619
  var SANITIZE_NAMED_PROPS_PREFIX = 'user-content-';
607
- /* Keep element content when removing element? */
608
620
 
621
+ /* Keep element content when removing element? */
609
622
  var KEEP_CONTENT = true;
623
+
610
624
  /* If a `Node` is passed to sanitize(), then performs sanitization in-place instead
611
625
  * of importing it into a new Document and returning a sanitized copy */
612
-
613
626
  var IN_PLACE = false;
614
- /* Allow usage of profiles like html, svg and mathMl */
615
627
 
628
+ /* Allow usage of profiles like html, svg and mathMl */
616
629
  var USE_PROFILES = {};
617
- /* Tags to ignore content of when KEEP_CONTENT is true */
618
630
 
631
+ /* Tags to ignore content of when KEEP_CONTENT is true */
619
632
  var FORBID_CONTENTS = null;
620
633
  var DEFAULT_FORBID_CONTENTS = addToSet({}, ['annotation-xml', 'audio', 'colgroup', 'desc', 'foreignobject', 'head', 'iframe', 'math', 'mi', 'mn', 'mo', 'ms', 'mtext', 'noembed', 'noframes', 'noscript', 'plaintext', 'script', 'style', 'svg', 'template', 'thead', 'title', 'video', 'xmp']);
621
- /* Tags that are safe for data: URIs */
622
634
 
635
+ /* Tags that are safe for data: URIs */
623
636
  var DATA_URI_TAGS = null;
624
637
  var DEFAULT_DATA_URI_TAGS = addToSet({}, ['audio', 'video', 'img', 'source', 'image', 'track']);
625
- /* Attributes safe for values like "javascript:" */
626
638
 
639
+ /* Attributes safe for values like "javascript:" */
627
640
  var URI_SAFE_ATTRIBUTES = null;
628
641
  var DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ['alt', 'class', 'for', 'id', 'label', 'name', 'pattern', 'placeholder', 'role', 'summary', 'title', 'value', 'style', 'xmlns']);
629
642
  var MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
630
643
  var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
631
644
  var HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';
632
645
  /* Document namespace */
633
-
634
646
  var NAMESPACE = HTML_NAMESPACE;
635
647
  var IS_EMPTY_INPUT = false;
636
- /* Allowed XHTML+XML namespaces */
637
648
 
649
+ /* Allowed XHTML+XML namespaces */
638
650
  var ALLOWED_NAMESPACES = null;
639
651
  var DEFAULT_ALLOWED_NAMESPACES = addToSet({}, [MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE], stringToString);
640
- /* Parsing of strict XHTML documents */
641
652
 
653
+ /* Parsing of strict XHTML documents */
642
654
  var PARSER_MEDIA_TYPE;
643
655
  var SUPPORTED_PARSER_MEDIA_TYPES = ['application/xhtml+xml', 'text/html'];
644
656
  var DEFAULT_PARSER_MEDIA_TYPE = 'text/html';
645
657
  var transformCaseFunc;
646
- /* Keep a reference to config to pass to hooks */
647
658
 
659
+ /* Keep a reference to config to pass to hooks */
648
660
  var CONFIG = null;
649
- /* Ideally, do not touch anything below this line */
650
661
 
662
+ /* Ideally, do not touch anything below this line */
651
663
  /* ______________________________________________ */
652
664
 
653
665
  var formElement = document.createElement('form');
654
666
  var isRegexOrFunction = function isRegexOrFunction(testValue) {
655
667
  return testValue instanceof RegExp || testValue instanceof Function;
656
668
  };
669
+
657
670
  /**
658
671
  * _parseConfig
659
672
  *
660
673
  * @param {Object} cfg optional config literal
661
674
  */
662
675
  // eslint-disable-next-line complexity
663
-
664
676
  var _parseConfig = function _parseConfig(cfg) {
665
677
  if (CONFIG && CONFIG === cfg) {
666
678
  return;
667
679
  }
668
- /* Shield configuration object from tampering */
669
680
 
681
+ /* Shield configuration object from tampering */
670
682
  if (!cfg || _typeof(cfg) !== 'object') {
671
683
  cfg = {};
672
684
  }
673
- /* Shield configuration object from prototype pollution */
674
685
 
686
+ /* Shield configuration object from prototype pollution */
675
687
  cfg = clone(cfg);
676
688
  PARSER_MEDIA_TYPE =
677
689
  // eslint-disable-next-line unicorn/prefer-includes
678
- SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? PARSER_MEDIA_TYPE = DEFAULT_PARSER_MEDIA_TYPE : PARSER_MEDIA_TYPE = cfg.PARSER_MEDIA_TYPE; // HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is.
690
+ SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? PARSER_MEDIA_TYPE = DEFAULT_PARSER_MEDIA_TYPE : PARSER_MEDIA_TYPE = cfg.PARSER_MEDIA_TYPE;
679
691
 
692
+ // HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is.
680
693
  transformCaseFunc = PARSER_MEDIA_TYPE === 'application/xhtml+xml' ? stringToString : stringToLowerCase;
681
- /* Set configuration parameters */
682
694
 
695
+ /* Set configuration parameters */
683
696
  ALLOWED_TAGS = 'ALLOWED_TAGS' in cfg ? addToSet({}, cfg.ALLOWED_TAGS, transformCaseFunc) : DEFAULT_ALLOWED_TAGS;
684
697
  ALLOWED_ATTR = 'ALLOWED_ATTR' in cfg ? addToSet({}, cfg.ALLOWED_ATTR, transformCaseFunc) : DEFAULT_ALLOWED_ATTR;
685
698
  ALLOWED_NAMESPACES = 'ALLOWED_NAMESPACES' in cfg ? addToSet({}, cfg.ALLOWED_NAMESPACES, stringToString) : DEFAULT_ALLOWED_NAMESPACES;
@@ -702,33 +715,23 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
702
715
  FORBID_ATTR = 'FORBID_ATTR' in cfg ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : {};
703
716
  USE_PROFILES = 'USE_PROFILES' in cfg ? cfg.USE_PROFILES : false;
704
717
  ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true
705
-
706
718
  ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true
707
-
708
719
  ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false
709
-
720
+ ALLOW_SELF_CLOSE_IN_ATTR = cfg.ALLOW_SELF_CLOSE_IN_ATTR !== false; // Default true
710
721
  SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false
711
-
722
+ SAFE_FOR_XML = cfg.SAFE_FOR_XML !== false; // Default true
712
723
  WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false
713
-
714
724
  RETURN_DOM = cfg.RETURN_DOM || false; // Default false
715
-
716
725
  RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false
717
-
718
726
  RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false
719
-
720
727
  FORCE_BODY = cfg.FORCE_BODY || false; // Default false
721
-
722
728
  SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true
723
-
724
729
  SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false; // Default false
725
-
726
730
  KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true
727
-
728
731
  IN_PLACE = cfg.IN_PLACE || false; // Default false
729
-
730
732
  IS_ALLOWED_URI$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI$1;
731
733
  NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE;
734
+ CUSTOM_ELEMENT_HANDLING = cfg.CUSTOM_ELEMENT_HANDLING || {};
732
735
  if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck)) {
733
736
  CUSTOM_ELEMENT_HANDLING.tagNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck;
734
737
  }
@@ -744,8 +747,8 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
744
747
  if (RETURN_DOM_FRAGMENT) {
745
748
  RETURN_DOM = true;
746
749
  }
747
- /* Parse profile info */
748
750
 
751
+ /* Parse profile info */
749
752
  if (USE_PROFILES) {
750
753
  ALLOWED_TAGS = addToSet({}, _toConsumableArray(text));
751
754
  ALLOWED_ATTR = [];
@@ -769,8 +772,8 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
769
772
  addToSet(ALLOWED_ATTR, xml);
770
773
  }
771
774
  }
772
- /* Merge configuration parameters */
773
775
 
776
+ /* Merge configuration parameters */
774
777
  if (cfg.ADD_TAGS) {
775
778
  if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {
776
779
  ALLOWED_TAGS = clone(ALLOWED_TAGS);
@@ -792,45 +795,48 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
792
795
  }
793
796
  addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc);
794
797
  }
795
- /* Add #text in case KEEP_CONTENT is set to true */
796
798
 
799
+ /* Add #text in case KEEP_CONTENT is set to true */
797
800
  if (KEEP_CONTENT) {
798
801
  ALLOWED_TAGS['#text'] = true;
799
802
  }
800
- /* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */
801
803
 
804
+ /* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */
802
805
  if (WHOLE_DOCUMENT) {
803
806
  addToSet(ALLOWED_TAGS, ['html', 'head', 'body']);
804
807
  }
805
- /* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */
806
808
 
809
+ /* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */
807
810
  if (ALLOWED_TAGS.table) {
808
811
  addToSet(ALLOWED_TAGS, ['tbody']);
809
812
  delete FORBID_TAGS.tbody;
810
- } // Prevent further manipulation of configuration.
811
- // Not available in IE8, Safari 5, etc.
813
+ }
812
814
 
815
+ // Prevent further manipulation of configuration.
816
+ // Not available in IE8, Safari 5, etc.
813
817
  if (freeze) {
814
818
  freeze(cfg);
815
819
  }
816
820
  CONFIG = cfg;
817
821
  };
818
822
  var MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ['mi', 'mo', 'mn', 'ms', 'mtext']);
819
- var HTML_INTEGRATION_POINTS = addToSet({}, ['foreignobject', 'desc', 'title', 'annotation-xml']); // Certain elements are allowed in both SVG and HTML
823
+ var HTML_INTEGRATION_POINTS = addToSet({}, ['annotation-xml']);
824
+
825
+ // Certain elements are allowed in both SVG and HTML
820
826
  // namespace. We need to specify them explicitly
821
827
  // so that they don't get erroneously deleted from
822
828
  // HTML namespace.
823
-
824
829
  var COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, ['title', 'style', 'font', 'a', 'script']);
830
+
825
831
  /* Keep track of all possible SVG and MathML tags
826
832
  * so that we can perform the namespace checks
827
833
  * correctly. */
828
-
829
834
  var ALL_SVG_TAGS = addToSet({}, svg$1);
830
835
  addToSet(ALL_SVG_TAGS, svgFilters);
831
836
  addToSet(ALL_SVG_TAGS, svgDisallowed);
832
837
  var ALL_MATHML_TAGS = addToSet({}, mathMl$1);
833
838
  addToSet(ALL_MATHML_TAGS, mathMlDisallowed);
839
+
834
840
  /**
835
841
  *
836
842
  *
@@ -839,11 +845,11 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
839
845
  * namespace that a spec-compliant parser would never
840
846
  * return. Return true otherwise.
841
847
  */
842
-
843
848
  var _checkValidNamespace = function _checkValidNamespace(element) {
844
- var parent = getParentNode(element); // In JSDOM, if we're inside shadow DOM, then parentNode
845
- // can be null. We just simulate parent in this case.
849
+ var parent = getParentNode(element);
846
850
 
851
+ // In JSDOM, if we're inside shadow DOM, then parentNode
852
+ // can be null. We just simulate parent in this case.
847
853
  if (!parent || !parent.tagName) {
848
854
  parent = {
849
855
  namespaceURI: NAMESPACE,
@@ -861,15 +867,17 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
861
867
  // it should be killed.
862
868
  if (parent.namespaceURI === HTML_NAMESPACE) {
863
869
  return tagName === 'svg';
864
- } // The only way to switch from MathML to SVG is via`
870
+ }
871
+
872
+ // The only way to switch from MathML to SVG is via`
865
873
  // svg if parent is either <annotation-xml> or MathML
866
874
  // text integration points.
867
-
868
875
  if (parent.namespaceURI === MATHML_NAMESPACE) {
869
876
  return tagName === 'svg' && (parentTagName === 'annotation-xml' || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]);
870
- } // We only allow elements that are defined in SVG
871
- // spec. All others are disallowed in SVG namespace.
877
+ }
872
878
 
879
+ // We only allow elements that are defined in SVG
880
+ // spec. All others are disallowed in SVG namespace.
873
881
  return Boolean(ALL_SVG_TAGS[tagName]);
874
882
  }
875
883
  if (element.namespaceURI === MATHML_NAMESPACE) {
@@ -878,14 +886,16 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
878
886
  // it should be killed.
879
887
  if (parent.namespaceURI === HTML_NAMESPACE) {
880
888
  return tagName === 'math';
881
- } // The only way to switch from SVG to MathML is via
882
- // <math> and HTML integration points
889
+ }
883
890
 
891
+ // The only way to switch from SVG to MathML is via
892
+ // <math> and HTML integration points
884
893
  if (parent.namespaceURI === SVG_NAMESPACE) {
885
894
  return tagName === 'math' && HTML_INTEGRATION_POINTS[parentTagName];
886
- } // We only allow elements that are defined in MathML
887
- // spec. All others are disallowed in MathML namespace.
895
+ }
888
896
 
897
+ // We only allow elements that are defined in MathML
898
+ // spec. All others are disallowed in MathML namespace.
889
899
  return Boolean(ALL_MATHML_TAGS[tagName]);
890
900
  }
891
901
  if (element.namespaceURI === HTML_NAMESPACE) {
@@ -897,27 +907,30 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
897
907
  }
898
908
  if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) {
899
909
  return false;
900
- } // We disallow tags that are specific for MathML
901
- // or SVG and should never appear in HTML namespace
910
+ }
902
911
 
912
+ // We disallow tags that are specific for MathML
913
+ // or SVG and should never appear in HTML namespace
903
914
  return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]);
904
- } // For XHTML and XML documents that support custom namespaces
915
+ }
905
916
 
917
+ // For XHTML and XML documents that support custom namespaces
906
918
  if (PARSER_MEDIA_TYPE === 'application/xhtml+xml' && ALLOWED_NAMESPACES[element.namespaceURI]) {
907
919
  return true;
908
- } // The code should never reach this place (this means
920
+ }
921
+
922
+ // The code should never reach this place (this means
909
923
  // that the element somehow got namespace that is not
910
924
  // HTML, SVG, MathML or allowed via ALLOWED_NAMESPACES).
911
925
  // Return false just in case.
912
-
913
926
  return false;
914
927
  };
928
+
915
929
  /**
916
930
  * _forceRemove
917
931
  *
918
932
  * @param {Node} node a DOM node
919
933
  */
920
-
921
934
  var _forceRemove = function _forceRemove(node) {
922
935
  arrayPush(DOMPurify.removed, {
923
936
  element: node
@@ -933,13 +946,13 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
933
946
  }
934
947
  }
935
948
  };
949
+
936
950
  /**
937
951
  * _removeAttribute
938
952
  *
939
953
  * @param {String} name an Attribute name
940
954
  * @param {Node} node a DOM node
941
955
  */
942
-
943
956
  var _removeAttribute = function _removeAttribute(name, node) {
944
957
  try {
945
958
  arrayPush(DOMPurify.removed, {
@@ -952,8 +965,9 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
952
965
  from: node
953
966
  });
954
967
  }
955
- node.removeAttribute(name); // We void attribute values for unremovable "is"" attributes
968
+ node.removeAttribute(name);
956
969
 
970
+ // We void attribute values for unremovable "is"" attributes
957
971
  if (name === 'is' && !ALLOWED_ATTR[name]) {
958
972
  if (RETURN_DOM || RETURN_DOM_FRAGMENT) {
959
973
  try {
@@ -966,13 +980,13 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
966
980
  }
967
981
  }
968
982
  };
983
+
969
984
  /**
970
985
  * _initDocument
971
986
  *
972
987
  * @param {String} dirty a string of dirty markup
973
988
  * @return {Document} a DOM, filled with the dirty markup
974
989
  */
975
-
976
990
  var _initDocument = function _initDocument(dirty) {
977
991
  /* Create a HTML document */
978
992
  var doc;
@@ -993,64 +1007,65 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
993
1007
  * Use the DOMParser API by default, fallback later if needs be
994
1008
  * DOMParser not work for svg when has multiple root element.
995
1009
  */
996
-
997
1010
  if (NAMESPACE === HTML_NAMESPACE) {
998
1011
  try {
999
1012
  doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE);
1000
1013
  } catch (_) {}
1001
1014
  }
1002
- /* Use createHTMLDocument in case DOMParser is not available */
1003
1015
 
1016
+ /* Use createHTMLDocument in case DOMParser is not available */
1004
1017
  if (!doc || !doc.documentElement) {
1005
1018
  doc = implementation.createDocument(NAMESPACE, 'template', null);
1006
1019
  try {
1007
- doc.documentElement.innerHTML = IS_EMPTY_INPUT ? '' : dirtyPayload;
1008
- } catch (_) {// Syntax error if dirtyPayload is invalid xml
1020
+ doc.documentElement.innerHTML = IS_EMPTY_INPUT ? emptyHTML : dirtyPayload;
1021
+ } catch (_) {
1022
+ // Syntax error if dirtyPayload is invalid xml
1009
1023
  }
1010
1024
  }
1011
1025
  var body = doc.body || doc.documentElement;
1012
1026
  if (dirty && leadingWhitespace) {
1013
1027
  body.insertBefore(document.createTextNode(leadingWhitespace), body.childNodes[0] || null);
1014
1028
  }
1015
- /* Work on whole document or just its body */
1016
1029
 
1030
+ /* Work on whole document or just its body */
1017
1031
  if (NAMESPACE === HTML_NAMESPACE) {
1018
1032
  return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0];
1019
1033
  }
1020
1034
  return WHOLE_DOCUMENT ? doc.documentElement : body;
1021
1035
  };
1036
+
1022
1037
  /**
1023
1038
  * _createIterator
1024
1039
  *
1025
1040
  * @param {Document} root document/fragment to create iterator for
1026
1041
  * @return {Iterator} iterator instance
1027
1042
  */
1028
-
1029
1043
  var _createIterator = function _createIterator(root) {
1030
1044
  return createNodeIterator.call(root.ownerDocument || root, root,
1031
1045
  // eslint-disable-next-line no-bitwise
1032
- NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT, null, false);
1046
+ NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT | NodeFilter.SHOW_PROCESSING_INSTRUCTION | NodeFilter.SHOW_CDATA_SECTION, null, false);
1033
1047
  };
1048
+
1034
1049
  /**
1035
1050
  * _isClobbered
1036
1051
  *
1037
1052
  * @param {Node} elm element to check for clobbering attacks
1038
1053
  * @return {Boolean} true if clobbered, false if safe
1039
1054
  */
1040
-
1041
1055
  var _isClobbered = function _isClobbered(elm) {
1042
1056
  return elm instanceof HTMLFormElement && (typeof elm.nodeName !== 'string' || typeof elm.textContent !== 'string' || typeof elm.removeChild !== 'function' || !(elm.attributes instanceof NamedNodeMap) || typeof elm.removeAttribute !== 'function' || typeof elm.setAttribute !== 'function' || typeof elm.namespaceURI !== 'string' || typeof elm.insertBefore !== 'function' || typeof elm.hasChildNodes !== 'function');
1043
1057
  };
1058
+
1044
1059
  /**
1045
1060
  * _isNode
1046
1061
  *
1047
1062
  * @param {Node} obj object to check whether it's a DOM node
1048
1063
  * @return {Boolean} true is object is a DOM node
1049
1064
  */
1050
-
1051
1065
  var _isNode = function _isNode(object) {
1052
1066
  return _typeof(Node) === 'object' ? object instanceof Node : object && _typeof(object) === 'object' && typeof object.nodeType === 'number' && typeof object.nodeName === 'string';
1053
1067
  };
1068
+
1054
1069
  /**
1055
1070
  * _executeHook
1056
1071
  * Execute user configurable hooks
@@ -1059,7 +1074,6 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
1059
1074
  * @param {Node} currentNode node to work on with the hook
1060
1075
  * @param {Object} data additional hook parameters
1061
1076
  */
1062
-
1063
1077
  var _executeHook = function _executeHook(entryPoint, currentNode, data) {
1064
1078
  if (!hooks[entryPoint]) {
1065
1079
  return;
@@ -1068,6 +1082,7 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
1068
1082
  hook.call(DOMPurify, currentNode, data, CONFIG);
1069
1083
  });
1070
1084
  };
1085
+
1071
1086
  /**
1072
1087
  * _sanitizeElements
1073
1088
  *
@@ -1078,80 +1093,95 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
1078
1093
  * @param {Node} currentNode to check for permission to exist
1079
1094
  * @return {Boolean} true if node was killed, false if left alive
1080
1095
  */
1081
-
1082
1096
  var _sanitizeElements = function _sanitizeElements(currentNode) {
1083
1097
  var content;
1084
- /* Execute a hook if present */
1085
1098
 
1099
+ /* Execute a hook if present */
1086
1100
  _executeHook('beforeSanitizeElements', currentNode, null);
1087
- /* Check if element is clobbered or can clobber */
1088
1101
 
1102
+ /* Check if element is clobbered or can clobber */
1089
1103
  if (_isClobbered(currentNode)) {
1090
1104
  _forceRemove(currentNode);
1091
1105
  return true;
1092
1106
  }
1093
- /* Check if tagname contains Unicode */
1094
1107
 
1108
+ /* Check if tagname contains Unicode */
1095
1109
  if (regExpTest(/[\u0080-\uFFFF]/, currentNode.nodeName)) {
1096
1110
  _forceRemove(currentNode);
1097
1111
  return true;
1098
1112
  }
1099
- /* Now let's check the element's type and name */
1100
1113
 
1114
+ /* Now let's check the element's type and name */
1101
1115
  var tagName = transformCaseFunc(currentNode.nodeName);
1102
- /* Execute a hook if present */
1103
1116
 
1117
+ /* Execute a hook if present */
1104
1118
  _executeHook('uponSanitizeElement', currentNode, {
1105
1119
  tagName: tagName,
1106
1120
  allowedTags: ALLOWED_TAGS
1107
1121
  });
1108
- /* Detect mXSS attempts abusing namespace confusion */
1109
1122
 
1123
+ /* Detect mXSS attempts abusing namespace confusion */
1110
1124
  if (currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && (!_isNode(currentNode.content) || !_isNode(currentNode.content.firstElementChild)) && regExpTest(/<[/\w]/g, currentNode.innerHTML) && regExpTest(/<[/\w]/g, currentNode.textContent)) {
1111
1125
  _forceRemove(currentNode);
1112
1126
  return true;
1113
1127
  }
1114
- /* Mitigate a problem with templates inside select */
1115
1128
 
1129
+ /* Mitigate a problem with templates inside select */
1116
1130
  if (tagName === 'select' && regExpTest(/<template/i, currentNode.innerHTML)) {
1117
1131
  _forceRemove(currentNode);
1118
1132
  return true;
1119
1133
  }
1120
- /* Remove element if anything forbids its presence */
1121
1134
 
1135
+ /* Remove any ocurrence of processing instructions */
1136
+ if (currentNode.nodeType === 7) {
1137
+ _forceRemove(currentNode);
1138
+ return true;
1139
+ }
1140
+
1141
+ /* Remove any kind of possibly harmful comments */
1142
+ if (SAFE_FOR_XML && currentNode.nodeType === 8 && regExpTest(/<[/\w]/g, currentNode.data)) {
1143
+ _forceRemove(currentNode);
1144
+ return true;
1145
+ }
1146
+
1147
+ /* Remove element if anything forbids its presence */
1122
1148
  if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
1123
1149
  /* Check if we have a custom element to handle */
1124
1150
  if (!FORBID_TAGS[tagName] && _basicCustomElementTest(tagName)) {
1125
1151
  if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) return false;
1126
1152
  if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) return false;
1127
1153
  }
1128
- /* Keep content except for bad-listed elements */
1129
1154
 
1155
+ /* Keep content except for bad-listed elements */
1130
1156
  if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {
1131
1157
  var parentNode = getParentNode(currentNode) || currentNode.parentNode;
1132
1158
  var childNodes = getChildNodes(currentNode) || currentNode.childNodes;
1133
1159
  if (childNodes && parentNode) {
1134
1160
  var childCount = childNodes.length;
1135
1161
  for (var i = childCount - 1; i >= 0; --i) {
1136
- parentNode.insertBefore(cloneNode(childNodes[i], true), getNextSibling(currentNode));
1162
+ var childClone = cloneNode(childNodes[i], true);
1163
+ childClone.__removalCount = (currentNode.__removalCount || 0) + 1;
1164
+ parentNode.insertBefore(childClone, getNextSibling(currentNode));
1137
1165
  }
1138
1166
  }
1139
1167
  }
1140
1168
  _forceRemove(currentNode);
1141
1169
  return true;
1142
1170
  }
1143
- /* Check whether element has a valid namespace */
1144
1171
 
1172
+ /* Check whether element has a valid namespace */
1145
1173
  if (currentNode instanceof Element && !_checkValidNamespace(currentNode)) {
1146
1174
  _forceRemove(currentNode);
1147
1175
  return true;
1148
1176
  }
1149
- if ((tagName === 'noscript' || tagName === 'noembed') && regExpTest(/<\/no(script|embed)/i, currentNode.innerHTML)) {
1177
+
1178
+ /* Make sure that older browsers don't get fallback-tag mXSS */
1179
+ if ((tagName === 'noscript' || tagName === 'noembed' || tagName === 'noframes') && regExpTest(/<\/no(script|embed|frames)/i, currentNode.innerHTML)) {
1150
1180
  _forceRemove(currentNode);
1151
1181
  return true;
1152
1182
  }
1153
- /* Sanitize element content to be template-safe */
1154
1183
 
1184
+ /* Sanitize element content to be template-safe */
1155
1185
  if (SAFE_FOR_TEMPLATES && currentNode.nodeType === 3) {
1156
1186
  /* Get the element's text content */
1157
1187
  content = currentNode.textContent;
@@ -1165,11 +1195,12 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
1165
1195
  currentNode.textContent = content;
1166
1196
  }
1167
1197
  }
1168
- /* Execute a hook if present */
1169
1198
 
1199
+ /* Execute a hook if present */
1170
1200
  _executeHook('afterSanitizeElements', currentNode, null);
1171
1201
  return false;
1172
1202
  };
1203
+
1173
1204
  /**
1174
1205
  * _isValidAttribute
1175
1206
  *
@@ -1179,17 +1210,16 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
1179
1210
  * @return {Boolean} Returns true if `value` is valid, otherwise false.
1180
1211
  */
1181
1212
  // eslint-disable-next-line complexity
1182
-
1183
1213
  var _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) {
1184
1214
  /* Make sure attribute cannot clobber */
1185
1215
  if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) {
1186
1216
  return false;
1187
1217
  }
1218
+
1188
1219
  /* Allow valid data-* attributes: At least one character after "-"
1189
1220
  (https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)
1190
1221
  XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)
1191
1222
  We don't need to check the value; it's always URI safe. */
1192
-
1193
1223
  if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR$1, lcName)) ;else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR$1, lcName)) ;else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) {
1194
1224
  if (
1195
1225
  // First condition does a very basic check if a) it's basically a valid custom element tagname AND
@@ -1202,21 +1232,22 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
1202
1232
  return false;
1203
1233
  }
1204
1234
  /* Check value is safe. First, is attr inert? If so, is safe */
1205
- } 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) ;else {
1235
+ } 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) {
1206
1236
  return false;
1207
1237
  }
1208
1238
  return true;
1209
1239
  };
1240
+
1210
1241
  /**
1211
1242
  * _basicCustomElementCheck
1212
1243
  * checks if at least one dash is included in tagName, and it's not the first char
1213
1244
  * for more sophisticated checking see https://github.com/sindresorhus/validate-element-name
1214
1245
  * @param {string} tagName name of the tag of the node to sanitize
1215
1246
  */
1216
-
1217
1247
  var _basicCustomElementTest = function _basicCustomElementTest(tagName) {
1218
- return tagName.indexOf('-') > 0;
1248
+ return tagName !== 'annotation-xml' && stringMatch(tagName, CUSTOM_ELEMENT$1);
1219
1249
  };
1250
+
1220
1251
  /**
1221
1252
  * _sanitizeAttributes
1222
1253
  *
@@ -1227,19 +1258,17 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
1227
1258
  *
1228
1259
  * @param {Node} currentNode to sanitize
1229
1260
  */
1230
-
1231
1261
  var _sanitizeAttributes = function _sanitizeAttributes(currentNode) {
1232
1262
  var attr;
1233
1263
  var value;
1234
1264
  var lcName;
1235
1265
  var l;
1236
1266
  /* Execute a hook if present */
1237
-
1238
1267
  _executeHook('beforeSanitizeAttributes', currentNode, null);
1239
1268
  var attributes = currentNode.attributes;
1240
- /* Check if we have attributes; if not we might have a text node */
1241
1269
 
1242
- if (!attributes) {
1270
+ /* Check if we have attributes; if not we might have a text node */
1271
+ if (!attributes || _isClobbered(currentNode)) {
1243
1272
  return;
1244
1273
  }
1245
1274
  var hookEvent = {
@@ -1249,8 +1278,8 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
1249
1278
  allowedAttributes: ALLOWED_ATTR
1250
1279
  };
1251
1280
  l = attributes.length;
1252
- /* Go backwards over all attributes; safely remove bad ones */
1253
1281
 
1282
+ /* Go backwards over all attributes; safely remove bad ones */
1254
1283
  while (l--) {
1255
1284
  attr = attributes[l];
1256
1285
  var _attr = attr,
@@ -1258,73 +1287,83 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
1258
1287
  namespaceURI = _attr.namespaceURI;
1259
1288
  value = name === 'value' ? attr.value : stringTrim(attr.value);
1260
1289
  lcName = transformCaseFunc(name);
1261
- /* Execute a hook if present */
1262
1290
 
1291
+ /* Execute a hook if present */
1263
1292
  hookEvent.attrName = lcName;
1264
1293
  hookEvent.attrValue = value;
1265
1294
  hookEvent.keepAttr = true;
1266
1295
  hookEvent.forceKeepAttr = undefined; // Allows developers to see this is a property they can set
1267
-
1268
1296
  _executeHook('uponSanitizeAttribute', currentNode, hookEvent);
1269
1297
  value = hookEvent.attrValue;
1270
- /* Did the hooks approve of the attribute? */
1271
1298
 
1299
+ /* Did the hooks approve of the attribute? */
1272
1300
  if (hookEvent.forceKeepAttr) {
1273
1301
  continue;
1274
1302
  }
1275
- /* Remove attribute */
1276
1303
 
1304
+ /* Remove attribute */
1277
1305
  _removeAttribute(name, currentNode);
1278
- /* Did the hooks approve of the attribute? */
1279
1306
 
1307
+ /* Did the hooks approve of the attribute? */
1280
1308
  if (!hookEvent.keepAttr) {
1281
1309
  continue;
1282
1310
  }
1283
- /* Work around a security issue in jQuery 3.0 */
1284
1311
 
1285
- if (regExpTest(/\/>/i, value)) {
1312
+ /* Work around a security issue in jQuery 3.0 */
1313
+ if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(/\/>/i, value)) {
1286
1314
  _removeAttribute(name, currentNode);
1287
1315
  continue;
1288
1316
  }
1289
- /* Sanitize attribute content to be template-safe */
1290
1317
 
1318
+ /* Sanitize attribute content to be template-safe */
1291
1319
  if (SAFE_FOR_TEMPLATES) {
1292
1320
  value = stringReplace(value, MUSTACHE_EXPR$1, ' ');
1293
1321
  value = stringReplace(value, ERB_EXPR$1, ' ');
1294
1322
  value = stringReplace(value, TMPLIT_EXPR$1, ' ');
1295
1323
  }
1296
- /* Is `value` valid for this attribute? */
1297
1324
 
1325
+ /* Is `value` valid for this attribute? */
1298
1326
  var lcTag = transformCaseFunc(currentNode.nodeName);
1299
1327
  if (!_isValidAttribute(lcTag, lcName, value)) {
1300
1328
  continue;
1301
1329
  }
1330
+
1302
1331
  /* Full DOM Clobbering protection via namespace isolation,
1303
1332
  * Prefix id and name attributes with `user-content-`
1304
1333
  */
1305
-
1306
1334
  if (SANITIZE_NAMED_PROPS && (lcName === 'id' || lcName === 'name')) {
1307
1335
  // Remove the attribute with this value
1308
- _removeAttribute(name, currentNode); // Prefix the value and later re-create the attribute with the sanitized value
1336
+ _removeAttribute(name, currentNode);
1309
1337
 
1338
+ // Prefix the value and later re-create the attribute with the sanitized value
1310
1339
  value = SANITIZE_NAMED_PROPS_PREFIX + value;
1311
1340
  }
1312
- /* Handle attributes that require Trusted Types */
1313
1341
 
1342
+ /* Work around a security issue with comments inside attributes */
1343
+ if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|script|title|xmp|textarea|noscript|iframe|noembed|noframes)/i, value)) {
1344
+ _removeAttribute(name, currentNode);
1345
+ continue;
1346
+ }
1347
+
1348
+ /* Handle attributes that require Trusted Types */
1314
1349
  if (trustedTypesPolicy && _typeof(trustedTypes) === 'object' && typeof trustedTypes.getAttributeType === 'function') {
1315
1350
  if (namespaceURI) ;else {
1316
1351
  switch (trustedTypes.getAttributeType(lcTag, lcName)) {
1317
1352
  case 'TrustedHTML':
1318
- value = trustedTypesPolicy.createHTML(value);
1319
- break;
1353
+ {
1354
+ value = trustedTypesPolicy.createHTML(value);
1355
+ break;
1356
+ }
1320
1357
  case 'TrustedScriptURL':
1321
- value = trustedTypesPolicy.createScriptURL(value);
1322
- break;
1358
+ {
1359
+ value = trustedTypesPolicy.createScriptURL(value);
1360
+ break;
1361
+ }
1323
1362
  }
1324
1363
  }
1325
1364
  }
1326
- /* Handle invalid data-* attribute set by try-catching it */
1327
1365
 
1366
+ /* Handle invalid data-* attribute set by try-catching it */
1328
1367
  try {
1329
1368
  if (namespaceURI) {
1330
1369
  currentNode.setAttributeNS(namespaceURI, name, value);
@@ -1332,46 +1371,48 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
1332
1371
  /* Fallback to setAttribute() for browser-unrecognized namespaces e.g. "x-schema". */
1333
1372
  currentNode.setAttribute(name, value);
1334
1373
  }
1335
- arrayPop(DOMPurify.removed);
1374
+ if (_isClobbered(currentNode)) {
1375
+ _forceRemove(currentNode);
1376
+ } else {
1377
+ arrayPop(DOMPurify.removed);
1378
+ }
1336
1379
  } catch (_) {}
1337
1380
  }
1338
- /* Execute a hook if present */
1339
1381
 
1382
+ /* Execute a hook if present */
1340
1383
  _executeHook('afterSanitizeAttributes', currentNode, null);
1341
1384
  };
1385
+
1342
1386
  /**
1343
1387
  * _sanitizeShadowDOM
1344
1388
  *
1345
1389
  * @param {DocumentFragment} fragment to iterate over recursively
1346
1390
  */
1347
-
1348
1391
  var _sanitizeShadowDOM = function _sanitizeShadowDOM(fragment) {
1349
1392
  var shadowNode;
1350
1393
  var shadowIterator = _createIterator(fragment);
1351
- /* Execute a hook if present */
1352
1394
 
1395
+ /* Execute a hook if present */
1353
1396
  _executeHook('beforeSanitizeShadowDOM', fragment, null);
1354
1397
  while (shadowNode = shadowIterator.nextNode()) {
1355
1398
  /* Execute a hook if present */
1356
1399
  _executeHook('uponSanitizeShadowNode', shadowNode, null);
1357
1400
  /* Sanitize tags and elements */
1401
+ _sanitizeElements(shadowNode);
1358
1402
 
1359
- if (_sanitizeElements(shadowNode)) {
1360
- continue;
1361
- }
1362
- /* Deep shadow DOM detected */
1403
+ /* Check attributes next */
1404
+ _sanitizeAttributes(shadowNode);
1363
1405
 
1406
+ /* Deep shadow DOM detected */
1364
1407
  if (shadowNode.content instanceof DocumentFragment) {
1365
1408
  _sanitizeShadowDOM(shadowNode.content);
1366
1409
  }
1367
- /* Check attributes, sanitize if necessary */
1368
-
1369
- _sanitizeAttributes(shadowNode);
1370
1410
  }
1371
- /* Execute a hook if present */
1372
1411
 
1412
+ /* Execute a hook if present */
1373
1413
  _executeHook('afterSanitizeShadowDOM', fragment, null);
1374
1414
  };
1415
+
1375
1416
  /**
1376
1417
  * Sanitize
1377
1418
  * Public method providing core sanitation functionality
@@ -1380,7 +1421,6 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
1380
1421
  * @param {Object} configuration object
1381
1422
  */
1382
1423
  // eslint-disable-next-line complexity
1383
-
1384
1424
  DOMPurify.sanitize = function (dirty) {
1385
1425
  var cfg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1386
1426
  var body;
@@ -1391,26 +1431,24 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
1391
1431
  /* Make sure we have a string to sanitize.
1392
1432
  DO NOT return early, as this will return the wrong type if
1393
1433
  the user has requested a DOM object rather than a string */
1394
-
1395
1434
  IS_EMPTY_INPUT = !dirty;
1396
1435
  if (IS_EMPTY_INPUT) {
1397
1436
  dirty = '<!-->';
1398
1437
  }
1399
- /* Stringify, in case dirty is an object */
1400
1438
 
1439
+ /* Stringify, in case dirty is an object */
1401
1440
  if (typeof dirty !== 'string' && !_isNode(dirty)) {
1402
- // eslint-disable-next-line no-negated-condition
1403
- if (typeof dirty.toString !== 'function') {
1404
- throw typeErrorCreate('toString is not a function');
1405
- } else {
1441
+ if (typeof dirty.toString === 'function') {
1406
1442
  dirty = dirty.toString();
1407
1443
  if (typeof dirty !== 'string') {
1408
1444
  throw typeErrorCreate('dirty is not a string, aborting');
1409
1445
  }
1446
+ } else {
1447
+ throw typeErrorCreate('toString is not a function');
1410
1448
  }
1411
1449
  }
1412
- /* Check we can run. Otherwise fall back or ignore */
1413
1450
 
1451
+ /* Check we can run. Otherwise fall back or ignore */
1414
1452
  if (!DOMPurify.isSupported) {
1415
1453
  if (_typeof(window.toStaticHTML) === 'object' || typeof window.toStaticHTML === 'function') {
1416
1454
  if (typeof dirty === 'string') {
@@ -1422,16 +1460,16 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
1422
1460
  }
1423
1461
  return dirty;
1424
1462
  }
1425
- /* Assign config vars */
1426
1463
 
1464
+ /* Assign config vars */
1427
1465
  if (!SET_CONFIG) {
1428
1466
  _parseConfig(cfg);
1429
1467
  }
1430
- /* Clean up removed elements */
1431
1468
 
1469
+ /* Clean up removed elements */
1432
1470
  DOMPurify.removed = [];
1433
- /* Check if dirty is correctly typed for IN_PLACE */
1434
1471
 
1472
+ /* Check if dirty is correctly typed for IN_PLACE */
1435
1473
  if (typeof dirty === 'string') {
1436
1474
  IN_PLACE = false;
1437
1475
  }
@@ -1464,53 +1502,51 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
1464
1502
  dirty.indexOf('<') === -1) {
1465
1503
  return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(dirty) : dirty;
1466
1504
  }
1467
- /* Initialize the document to work on */
1468
1505
 
1506
+ /* Initialize the document to work on */
1469
1507
  body = _initDocument(dirty);
1470
- /* Check we have a DOM node from the data */
1471
1508
 
1509
+ /* Check we have a DOM node from the data */
1472
1510
  if (!body) {
1473
1511
  return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : '';
1474
1512
  }
1475
1513
  }
1476
- /* Remove first element node (ours) if FORCE_BODY is set */
1477
1514
 
1515
+ /* Remove first element node (ours) if FORCE_BODY is set */
1478
1516
  if (body && FORCE_BODY) {
1479
1517
  _forceRemove(body.firstChild);
1480
1518
  }
1481
- /* Get node iterator */
1482
1519
 
1520
+ /* Get node iterator */
1483
1521
  var nodeIterator = _createIterator(IN_PLACE ? dirty : body);
1484
- /* Now start iterating over the created document */
1485
1522
 
1523
+ /* Now start iterating over the created document */
1486
1524
  while (currentNode = nodeIterator.nextNode()) {
1487
1525
  /* Fix IE's strange behavior with manipulated textNodes #89 */
1488
1526
  if (currentNode.nodeType === 3 && currentNode === oldNode) {
1489
1527
  continue;
1490
1528
  }
1529
+
1491
1530
  /* Sanitize tags and elements */
1531
+ _sanitizeElements(currentNode);
1492
1532
 
1493
- if (_sanitizeElements(currentNode)) {
1494
- continue;
1495
- }
1496
- /* Shadow DOM detected, sanitize it */
1533
+ /* Check attributes next */
1534
+ _sanitizeAttributes(currentNode);
1497
1535
 
1536
+ /* Shadow DOM detected, sanitize it */
1498
1537
  if (currentNode.content instanceof DocumentFragment) {
1499
1538
  _sanitizeShadowDOM(currentNode.content);
1500
1539
  }
1501
- /* Check attributes, sanitize if necessary */
1502
-
1503
- _sanitizeAttributes(currentNode);
1504
1540
  oldNode = currentNode;
1505
1541
  }
1506
1542
  oldNode = null;
1507
- /* If we sanitized `dirty` in-place, return it. */
1508
1543
 
1544
+ /* If we sanitized `dirty` in-place, return it. */
1509
1545
  if (IN_PLACE) {
1510
1546
  return dirty;
1511
1547
  }
1512
- /* Return sanitized string or DOM */
1513
1548
 
1549
+ /* Return sanitized string or DOM */
1514
1550
  if (RETURN_DOM) {
1515
1551
  if (RETURN_DOM_FRAGMENT) {
1516
1552
  returnNode = createDocumentFragment.call(body.ownerDocument);
@@ -1521,7 +1557,7 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
1521
1557
  } else {
1522
1558
  returnNode = body;
1523
1559
  }
1524
- if (ALLOWED_ATTR.shadowroot) {
1560
+ if (ALLOWED_ATTR.shadowroot || ALLOWED_ATTR.shadowrootmod) {
1525
1561
  /*
1526
1562
  AdoptNode() is not used because internal state is not reset
1527
1563
  (e.g. the past names map of a HTMLFormElement), this is safe
@@ -1534,13 +1570,13 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
1534
1570
  return returnNode;
1535
1571
  }
1536
1572
  var serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML;
1537
- /* Serialize doctype if allowed */
1538
1573
 
1574
+ /* Serialize doctype if allowed */
1539
1575
  if (WHOLE_DOCUMENT && ALLOWED_TAGS['!doctype'] && body.ownerDocument && body.ownerDocument.doctype && body.ownerDocument.doctype.name && regExpTest(DOCTYPE_NAME, body.ownerDocument.doctype.name)) {
1540
1576
  serializedHTML = '<!DOCTYPE ' + body.ownerDocument.doctype.name + '>\n' + serializedHTML;
1541
1577
  }
1542
- /* Sanitize final string template-safe */
1543
1578
 
1579
+ /* Sanitize final string template-safe */
1544
1580
  if (SAFE_FOR_TEMPLATES) {
1545
1581
  serializedHTML = stringReplace(serializedHTML, MUSTACHE_EXPR$1, ' ');
1546
1582
  serializedHTML = stringReplace(serializedHTML, ERB_EXPR$1, ' ');
@@ -1548,27 +1584,28 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
1548
1584
  }
1549
1585
  return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(serializedHTML) : serializedHTML;
1550
1586
  };
1587
+
1551
1588
  /**
1552
1589
  * Public method to set the configuration once
1553
1590
  * setConfig
1554
1591
  *
1555
1592
  * @param {Object} cfg configuration object
1556
1593
  */
1557
-
1558
1594
  DOMPurify.setConfig = function (cfg) {
1559
1595
  _parseConfig(cfg);
1560
1596
  SET_CONFIG = true;
1561
1597
  };
1598
+
1562
1599
  /**
1563
1600
  * Public method to remove the configuration
1564
1601
  * clearConfig
1565
1602
  *
1566
1603
  */
1567
-
1568
1604
  DOMPurify.clearConfig = function () {
1569
1605
  CONFIG = null;
1570
1606
  SET_CONFIG = false;
1571
1607
  };
1608
+
1572
1609
  /**
1573
1610
  * Public method to check if an attribute value is valid.
1574
1611
  * Uses last set config, if any. Otherwise, uses config defaults.
@@ -1579,7 +1616,6 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
1579
1616
  * @param {string} value Attribute value.
1580
1617
  * @return {Boolean} Returns true if `value` is valid. Otherwise, returns false.
1581
1618
  */
1582
-
1583
1619
  DOMPurify.isValidAttribute = function (tag, attr, value) {
1584
1620
  /* Initialize shared config vars if necessary. */
1585
1621
  if (!CONFIG) {
@@ -1589,6 +1625,7 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
1589
1625
  var lcName = transformCaseFunc(attr);
1590
1626
  return _isValidAttribute(lcTag, lcName, value);
1591
1627
  };
1628
+
1592
1629
  /**
1593
1630
  * AddHook
1594
1631
  * Public method to add DOMPurify hooks
@@ -1596,7 +1633,6 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
1596
1633
  * @param {String} entryPoint entry point for the hook to add
1597
1634
  * @param {Function} hookFunction function to execute
1598
1635
  */
1599
-
1600
1636
  DOMPurify.addHook = function (entryPoint, hookFunction) {
1601
1637
  if (typeof hookFunction !== 'function') {
1602
1638
  return;
@@ -1604,6 +1640,7 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
1604
1640
  hooks[entryPoint] = hooks[entryPoint] || [];
1605
1641
  arrayPush(hooks[entryPoint], hookFunction);
1606
1642
  };
1643
+
1607
1644
  /**
1608
1645
  * RemoveHook
1609
1646
  * Public method to remove a DOMPurify hook at a given entryPoint
@@ -1612,30 +1649,29 @@ define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider'
1612
1649
  * @param {String} entryPoint entry point for the hook to remove
1613
1650
  * @return {Function} removed(popped) hook
1614
1651
  */
1615
-
1616
1652
  DOMPurify.removeHook = function (entryPoint) {
1617
1653
  if (hooks[entryPoint]) {
1618
1654
  return arrayPop(hooks[entryPoint]);
1619
1655
  }
1620
1656
  };
1657
+
1621
1658
  /**
1622
1659
  * RemoveHooks
1623
1660
  * Public method to remove all DOMPurify hooks at a given entryPoint
1624
1661
  *
1625
1662
  * @param {String} entryPoint entry point for the hooks to remove
1626
1663
  */
1627
-
1628
1664
  DOMPurify.removeHooks = function (entryPoint) {
1629
1665
  if (hooks[entryPoint]) {
1630
1666
  hooks[entryPoint] = [];
1631
1667
  }
1632
1668
  };
1669
+
1633
1670
  /**
1634
1671
  * RemoveAllHooks
1635
1672
  * Public method to remove all DOMPurify hooks
1636
1673
  *
1637
1674
  */
1638
-
1639
1675
  DOMPurify.removeAllHooks = function () {
1640
1676
  hooks = {};
1641
1677
  };