@oat-sa/tao-core-ui 3.24.0 → 3.24.2

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