@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.
- package/dist/animable/pulsable/pulsable.js +0 -1
- package/dist/autocomplete/css/autocomplete.css +1 -1
- package/dist/autocomplete/css/autocomplete.css.map +1 -1
- package/dist/badge/css/badge.css +6 -6
- package/dist/badge/css/badge.css.map +1 -1
- package/dist/breadcrumbs/css/breadcrumbs.css +2 -2
- package/dist/breadcrumbs/css/breadcrumbs.css.map +1 -1
- package/dist/calculator/css/calculator.css +8 -6
- package/dist/calculator/css/calculator.css.map +1 -1
- package/dist/class/css/selector.css +4 -4
- package/dist/class/css/selector.css.map +1 -1
- package/dist/component/css/components.css +5 -5
- package/dist/component/css/components.css.map +1 -1
- package/dist/component/css/windowComponent.css +1 -1
- package/dist/component/css/windowComponent.css.map +1 -1
- package/dist/component/draggable.js +0 -1
- package/dist/component/resizable.js +0 -1
- package/dist/contextualPopup/css/contextualPopup.css +1 -1
- package/dist/contextualPopup/css/contextualPopup.css.map +1 -1
- package/dist/datatable/css/datatable.css +3 -3
- package/dist/datatable/css/datatable.css.map +1 -1
- package/dist/datatable.js +1 -2
- package/dist/datetime/css/picker.css +13 -13
- package/dist/datetime/css/picker.css.map +1 -1
- package/dist/documentViewer/css/documentViewer.css +10 -10
- package/dist/documentViewer/css/documentViewer.css.map +1 -1
- package/dist/documentViewer/providers/pdfViewer/pdfjs/searchEngine.js +0 -1
- package/dist/dynamicComponent/css/dynamicComponent.css +1 -1
- package/dist/dynamicComponent/css/dynamicComponent.css.map +1 -1
- package/dist/dynamicComponent.js +1 -4
- package/dist/figure/FigureStateActive.js +20 -23
- package/dist/form/css/dropdownForm.css +1 -1
- package/dist/form/css/dropdownForm.css.map +1 -1
- package/dist/form/widget/widget.js +1 -4
- package/dist/highlighter.js +0 -2
- package/dist/image/ImgStateActive.js +13 -15
- package/dist/interactUtils.js +7 -8
- package/dist/itemButtonList/css/item-button-list.css +9 -3
- package/dist/itemButtonList/css/item-button-list.css.map +1 -1
- package/dist/itemButtonList.js +1 -2
- package/dist/keyNavigation/navigableDomElement.js +3 -4
- package/dist/keyNavigation/navigator.js +1 -2
- package/dist/listbox/css/listbox.css +1 -1
- package/dist/listbox/css/listbox.css.map +1 -1
- package/dist/maths/calculator/core/board.js +58 -127
- package/dist/maths/calculator/core/labels.js +1 -6
- package/dist/maths/calculator/css/calculator.css +18 -18
- package/dist/maths/calculator/css/calculator.css.map +1 -1
- package/dist/maths/calculator/plugins/screen/simpleScreen/simpleScreen.js +1 -6
- package/dist/mediaplayer/css/player.css +7 -7
- package/dist/mediaplayer/css/player.css.map +1 -1
- package/dist/mediaplayer/players/html5.js +3 -14
- package/dist/mediaplayer/players/youtube.js +3 -12
- package/dist/mediaplayer/utils/crossOrigin.js +1 -1
- package/dist/mediaplayer/utils/timeObserver.js +1 -2
- package/dist/mediaplayer/youtubeManager.js +1 -2
- package/dist/mediaplayer.js +2 -8
- package/dist/mediasizer.js +0 -1
- package/dist/resizeObserver.js +1 -3
- package/dist/resource/css/selector.css +31 -23
- package/dist/resource/css/selector.css.map +1 -1
- package/dist/resource/list.js +239 -203
- package/dist/resource/selector.js +0 -1
- package/dist/resource/tree.js +239 -203
- package/dist/resourcemgr/assetSearch.js +20 -18
- package/dist/resourcemgr/assetSearchContract.js +67 -12
- package/dist/resourcemgr/css/resourcemgr.css +17 -18
- package/dist/resourcemgr/css/resourcemgr.css.map +1 -1
- package/dist/resourcemgr/fileBrowser.js +3 -5
- package/dist/resourcemgr/fileSelector.js +3 -0
- package/dist/searchModal/advancedSearch.js +3 -4
- package/dist/searchModal/css/searchModal.css +14 -14
- package/dist/searchModal/css/searchModal.css.map +1 -1
- package/dist/searchModal.js +42 -53
- package/dist/switch/css/switch.css +2 -2
- package/dist/switch/css/switch.css.map +1 -1
- package/dist/tabs/css/tabs.css +2 -2
- package/dist/tabs/css/tabs.css.map +1 -1
- package/dist/taskQueue/css/taskQueue.css +4 -4
- package/dist/taskQueue/css/taskQueue.css.map +1 -1
- package/dist/taskQueue/taskQueueModel.js +1 -2
- package/dist/taskQueueButton/taskable.js +1 -2
- package/dist/validator/validators.js +0 -1
- package/dist/waitingDialog/css/waitingDialog.css +2 -2
- package/dist/waitingDialog/css/waitingDialog.css.map +1 -1
- package/package.json +1 -1
- package/src/autocomplete/css/autocomplete.css +1 -1
- package/src/autocomplete/css/autocomplete.css.map +1 -1
- package/src/badge/css/badge.css +6 -6
- package/src/badge/css/badge.css.map +1 -1
- package/src/breadcrumbs/css/breadcrumbs.css +2 -2
- package/src/breadcrumbs/css/breadcrumbs.css.map +1 -1
- package/src/calculator/css/calculator.css +8 -6
- package/src/calculator/css/calculator.css.map +1 -1
- package/src/class/css/selector.css +4 -4
- package/src/class/css/selector.css.map +1 -1
- package/src/component/css/components.css +5 -5
- package/src/component/css/components.css.map +1 -1
- package/src/component/css/windowComponent.css +1 -1
- package/src/component/css/windowComponent.css.map +1 -1
- package/src/contextualPopup/css/contextualPopup.css +1 -1
- package/src/contextualPopup/css/contextualPopup.css.map +1 -1
- package/src/css/basic.css +123 -113
- package/src/css/basic.css.map +1 -1
- package/src/datatable/css/datatable.css +3 -3
- package/src/datatable/css/datatable.css.map +1 -1
- package/src/datetime/css/picker.css +13 -13
- package/src/datetime/css/picker.css.map +1 -1
- package/src/documentViewer/css/documentViewer.css +10 -10
- package/src/documentViewer/css/documentViewer.css.map +1 -1
- package/src/dynamicComponent/css/dynamicComponent.css +1 -1
- package/src/dynamicComponent/css/dynamicComponent.css.map +1 -1
- package/src/form/css/dropdownForm.css +1 -1
- package/src/form/css/dropdownForm.css.map +1 -1
- package/src/itemButtonList/css/item-button-list.css +9 -3
- package/src/itemButtonList/css/item-button-list.css.map +1 -1
- package/src/listbox/css/listbox.css +1 -1
- package/src/listbox/css/listbox.css.map +1 -1
- package/src/maths/calculator/css/calculator.css +18 -18
- package/src/maths/calculator/css/calculator.css.map +1 -1
- package/src/mediaplayer/css/player.css +7 -7
- package/src/mediaplayer/css/player.css.map +1 -1
- package/src/resource/css/selector.css +31 -23
- package/src/resource/css/selector.css.map +1 -1
- package/src/resourcemgr/assetSearch.js +27 -19
- package/src/resourcemgr/assetSearchContract.js +67 -18
- package/src/resourcemgr/css/resourcemgr.css +17 -18
- package/src/resourcemgr/css/resourcemgr.css.map +1 -1
- package/src/resourcemgr/fileBrowser.js +9 -9
- package/src/resourcemgr/fileSelector.js +4 -0
- package/src/searchModal/css/searchModal.css +14 -14
- package/src/searchModal/css/searchModal.css.map +1 -1
- package/src/switch/css/switch.css +2 -2
- package/src/switch/css/switch.css.map +1 -1
- package/src/tabs/css/tabs.css +2 -2
- package/src/tabs/css/tabs.css.map +1 -1
- package/src/taskQueue/css/taskQueue.css +4 -4
- package/src/taskQueue/css/taskQueue.css.map +1 -1
- package/src/waitingDialog/css/waitingDialog.css +2 -2
- package/src/waitingDialog/css/waitingDialog.css.map +1 -1
package/dist/resource/tree.js
CHANGED
|
@@ -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.
|
|
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
|
-
|
|
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']);
|
|
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']);
|
|
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']);
|
|
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]
|
|
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
|
-
}
|
|
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');
|
|
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;
|
|
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
|
-
}
|
|
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({}, ['
|
|
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);
|
|
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
|
-
}
|
|
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
|
-
}
|
|
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
|
-
}
|
|
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
|
-
}
|
|
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
|
-
}
|
|
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
|
-
}
|
|
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
|
-
}
|
|
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);
|
|
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 ?
|
|
1008
|
-
} catch (_) {
|
|
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
|
-
|
|
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
|
-
|
|
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 (
|
|
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
|
|
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
|
|
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
|
-
|
|
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);
|
|
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
|
-
|
|
1319
|
-
|
|
1353
|
+
{
|
|
1354
|
+
value = trustedTypesPolicy.createHTML(value);
|
|
1355
|
+
break;
|
|
1356
|
+
}
|
|
1320
1357
|
case 'TrustedScriptURL':
|
|
1321
|
-
|
|
1322
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1360
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1494
|
-
|
|
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
|
};
|