dompurify 2.3.6 → 2.3.9

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/purify.es.js CHANGED
@@ -1,6 +1,86 @@
1
- /*! @license DOMPurify 2.3.6 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/2.3.6/LICENSE */
1
+ /*! @license DOMPurify 2.3.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.3.9/LICENSE */
2
2
 
3
- function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
3
+ function _typeof(obj) {
4
+ "@babel/helpers - typeof";
5
+
6
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) {
7
+ return typeof obj;
8
+ } : function (obj) {
9
+ return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
10
+ }, _typeof(obj);
11
+ }
12
+
13
+ function _setPrototypeOf(o, p) {
14
+ _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
15
+ o.__proto__ = p;
16
+ return o;
17
+ };
18
+
19
+ return _setPrototypeOf(o, p);
20
+ }
21
+
22
+ function _isNativeReflectConstruct() {
23
+ if (typeof Reflect === "undefined" || !Reflect.construct) return false;
24
+ if (Reflect.construct.sham) return false;
25
+ if (typeof Proxy === "function") return true;
26
+
27
+ try {
28
+ Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
29
+ return true;
30
+ } catch (e) {
31
+ return false;
32
+ }
33
+ }
34
+
35
+ function _construct(Parent, args, Class) {
36
+ if (_isNativeReflectConstruct()) {
37
+ _construct = Reflect.construct;
38
+ } else {
39
+ _construct = function _construct(Parent, args, Class) {
40
+ var a = [null];
41
+ a.push.apply(a, args);
42
+ var Constructor = Function.bind.apply(Parent, a);
43
+ var instance = new Constructor();
44
+ if (Class) _setPrototypeOf(instance, Class.prototype);
45
+ return instance;
46
+ };
47
+ }
48
+
49
+ return _construct.apply(null, arguments);
50
+ }
51
+
52
+ function _toConsumableArray(arr) {
53
+ return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
54
+ }
55
+
56
+ function _arrayWithoutHoles(arr) {
57
+ if (Array.isArray(arr)) return _arrayLikeToArray(arr);
58
+ }
59
+
60
+ function _iterableToArray(iter) {
61
+ if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
62
+ }
63
+
64
+ function _unsupportedIterableToArray(o, minLen) {
65
+ if (!o) return;
66
+ if (typeof o === "string") return _arrayLikeToArray(o, minLen);
67
+ var n = Object.prototype.toString.call(o).slice(8, -1);
68
+ if (n === "Object" && o.constructor) n = o.constructor.name;
69
+ if (n === "Map" || n === "Set") return Array.from(o);
70
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
71
+ }
72
+
73
+ function _arrayLikeToArray(arr, len) {
74
+ if (len == null || len > arr.length) len = arr.length;
75
+
76
+ for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
77
+
78
+ return arr2;
79
+ }
80
+
81
+ function _nonIterableSpread() {
82
+ throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
83
+ }
4
84
 
5
85
  var hasOwnProperty = Object.hasOwnProperty,
6
86
  setPrototypeOf = Object.setPrototypeOf,
@@ -35,46 +115,43 @@ if (!seal) {
35
115
 
36
116
  if (!construct) {
37
117
  construct = function construct(Func, args) {
38
- return new (Function.prototype.bind.apply(Func, [null].concat(_toConsumableArray(args))))();
118
+ return _construct(Func, _toConsumableArray(args));
39
119
  };
40
120
  }
41
121
 
42
122
  var arrayForEach = unapply(Array.prototype.forEach);
43
123
  var arrayPop = unapply(Array.prototype.pop);
44
124
  var arrayPush = unapply(Array.prototype.push);
45
-
46
125
  var stringToLowerCase = unapply(String.prototype.toLowerCase);
47
126
  var stringMatch = unapply(String.prototype.match);
48
127
  var stringReplace = unapply(String.prototype.replace);
49
128
  var stringIndexOf = unapply(String.prototype.indexOf);
50
129
  var stringTrim = unapply(String.prototype.trim);
51
-
52
130
  var regExpTest = unapply(RegExp.prototype.test);
53
-
54
131
  var typeErrorCreate = unconstruct(TypeError);
55
-
56
132
  function unapply(func) {
57
133
  return function (thisArg) {
58
- for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
134
+ for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
59
135
  args[_key - 1] = arguments[_key];
60
136
  }
61
137
 
62
138
  return apply(func, thisArg, args);
63
139
  };
64
140
  }
65
-
66
141
  function unconstruct(func) {
67
142
  return function () {
68
- for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
143
+ for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
69
144
  args[_key2] = arguments[_key2];
70
145
  }
71
146
 
72
147
  return construct(func, args);
73
148
  };
74
149
  }
75
-
76
150
  /* Add properties to a lookup table */
77
- function addToSet(set, array) {
151
+
152
+ function addToSet(set, array, transformCaseFunc) {
153
+ transformCaseFunc = transformCaseFunc ? transformCaseFunc : stringToLowerCase;
154
+
78
155
  if (setPrototypeOf) {
79
156
  // Make 'in' and truthy checks like Boolean(set.constructor)
80
157
  // independent of any properties defined on Object.prototype.
@@ -83,10 +160,13 @@ function addToSet(set, array) {
83
160
  }
84
161
 
85
162
  var l = array.length;
163
+
86
164
  while (l--) {
87
165
  var element = array[l];
166
+
88
167
  if (typeof element === 'string') {
89
- var lcElement = stringToLowerCase(element);
168
+ var lcElement = transformCaseFunc(element);
169
+
90
170
  if (lcElement !== element) {
91
171
  // Config presets (e.g. tags.js, attrs.js) are immutable.
92
172
  if (!isFrozen(array)) {
@@ -102,12 +182,12 @@ function addToSet(set, array) {
102
182
 
103
183
  return set;
104
184
  }
105
-
106
185
  /* Shallow clone an object */
186
+
107
187
  function clone(object) {
108
188
  var newObject = create(null);
189
+ var property;
109
190
 
110
- var property = void 0;
111
191
  for (property in object) {
112
192
  if (apply(hasOwnProperty, object, [property])) {
113
193
  newObject[property] = object[property];
@@ -116,14 +196,15 @@ function clone(object) {
116
196
 
117
197
  return newObject;
118
198
  }
119
-
120
199
  /* IE10 doesn't support __lookupGetter__ so lets'
121
200
  * simulate it. It also automatically checks
122
201
  * if the prop is function or getter and behaves
123
202
  * accordingly. */
203
+
124
204
  function lookupGetter(object, prop) {
125
205
  while (object !== null) {
126
206
  var desc = getOwnPropertyDescriptor(object, prop);
207
+
127
208
  if (desc) {
128
209
  if (desc.get) {
129
210
  return unapply(desc.get);
@@ -145,40 +226,33 @@ function lookupGetter(object, prop) {
145
226
  return fallbackValue;
146
227
  }
147
228
 
148
- var html = 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']);
149
-
150
- // SVG
151
- var svg = 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']);
229
+ 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
152
230
 
153
- 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']);
154
-
155
- // List of SVG elements that are disallowed by default.
231
+ 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']);
232
+ 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.
156
233
  // We still need to know them so that we can do namespace
157
234
  // checks properly in case one wants to add them to
158
235
  // allow-list.
159
- 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']);
160
236
 
161
- var mathMl = 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']);
162
-
163
- // Similarly to SVG, we want to know all MathML elements,
237
+ 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']);
238
+ 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,
164
239
  // even those that we disallow by default.
165
- var mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']);
166
240
 
241
+ var mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']);
167
242
  var text = freeze(['#text']);
168
243
 
169
- var html$1 = 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']);
170
-
171
- var svg$1 = 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']);
172
-
173
- var mathMl$1 = 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']);
174
-
244
+ 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']);
245
+ 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']);
246
+ 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']);
175
247
  var xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']);
176
248
 
177
- // eslint-disable-next-line unicorn/better-regex
178
- var MUSTACHE_EXPR = seal(/\{\{[\s\S]*|[\s\S]*\}\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode
179
- var ERB_EXPR = seal(/<%[\s\S]*|[\s\S]*%>/gm);
249
+ var MUSTACHE_EXPR = seal(/\{\{[\w\W]*|[\w\W]*\}\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode
250
+
251
+ var ERB_EXPR = seal(/<%[\w\W]*|[\w\W]*%>/gm);
180
252
  var DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]/); // eslint-disable-line no-useless-escape
253
+
181
254
  var ARIA_ATTR = seal(/^aria-[\-\w]+$/); // eslint-disable-line no-useless-escape
255
+
182
256
  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
183
257
  );
184
258
  var IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i);
@@ -186,14 +260,9 @@ var ATTR_WHITESPACE = seal(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\
186
260
  );
187
261
  var DOCTYPE_NAME = seal(/^html$/i);
188
262
 
189
- var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
190
-
191
- function _toConsumableArray$1(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
192
-
193
263
  var getGlobal = function getGlobal() {
194
264
  return typeof window === 'undefined' ? null : window;
195
265
  };
196
-
197
266
  /**
198
267
  * Creates a no-op policy for internal use only.
199
268
  * Don't export this function outside this module!
@@ -202,16 +271,19 @@ var getGlobal = function getGlobal() {
202
271
  * @return {?TrustedTypePolicy} The policy created (or null, if Trusted Types
203
272
  * are not supported).
204
273
  */
274
+
275
+
205
276
  var _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes, document) {
206
- if ((typeof trustedTypes === 'undefined' ? 'undefined' : _typeof(trustedTypes)) !== 'object' || typeof trustedTypes.createPolicy !== 'function') {
277
+ if (_typeof(trustedTypes) !== 'object' || typeof trustedTypes.createPolicy !== 'function') {
207
278
  return null;
208
- }
209
-
210
- // Allow the callers to control the unique policy name
279
+ } // Allow the callers to control the unique policy name
211
280
  // by adding a data-tt-policy-suffix to the script element with the DOMPurify.
212
281
  // Policy creation with duplicate names throws in Trusted Types.
282
+
283
+
213
284
  var suffix = null;
214
285
  var ATTR_NAME = 'data-tt-policy-suffix';
286
+
215
287
  if (document.currentScript && document.currentScript.hasAttribute(ATTR_NAME)) {
216
288
  suffix = document.currentScript.getAttribute(ATTR_NAME);
217
289
  }
@@ -220,8 +292,8 @@ var _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes,
220
292
 
221
293
  try {
222
294
  return trustedTypes.createPolicy(policyName, {
223
- createHTML: function createHTML(html$$1) {
224
- return html$$1;
295
+ createHTML: function createHTML(html) {
296
+ return html;
225
297
  }
226
298
  });
227
299
  } catch (_) {
@@ -239,29 +311,28 @@ function createDOMPurify() {
239
311
  var DOMPurify = function DOMPurify(root) {
240
312
  return createDOMPurify(root);
241
313
  };
242
-
243
314
  /**
244
315
  * Version label, exposed for easier checks
245
316
  * if DOMPurify is up to date or not
246
317
  */
247
- DOMPurify.version = '2.3.6';
248
318
 
319
+
320
+ DOMPurify.version = '2.3.9';
249
321
  /**
250
322
  * Array of elements that DOMPurify removed during sanitation.
251
323
  * Empty if nothing was removed.
252
324
  */
325
+
253
326
  DOMPurify.removed = [];
254
327
 
255
328
  if (!window || !window.document || window.document.nodeType !== 9) {
256
329
  // Not running in a browser, provide a factory function
257
330
  // so that you can pass your own Window
258
331
  DOMPurify.isSupported = false;
259
-
260
332
  return DOMPurify;
261
333
  }
262
334
 
263
335
  var originalDocument = window.document;
264
-
265
336
  var document = window.document;
266
337
  var DocumentFragment = window.DocumentFragment,
267
338
  HTMLTemplateElement = window.HTMLTemplateElement,
@@ -269,63 +340,57 @@ function createDOMPurify() {
269
340
  Element = window.Element,
270
341
  NodeFilter = window.NodeFilter,
271
342
  _window$NamedNodeMap = window.NamedNodeMap,
272
- NamedNodeMap = _window$NamedNodeMap === undefined ? window.NamedNodeMap || window.MozNamedAttrMap : _window$NamedNodeMap,
343
+ NamedNodeMap = _window$NamedNodeMap === void 0 ? window.NamedNodeMap || window.MozNamedAttrMap : _window$NamedNodeMap,
273
344
  HTMLFormElement = window.HTMLFormElement,
274
345
  DOMParser = window.DOMParser,
275
346
  trustedTypes = window.trustedTypes;
276
-
277
-
278
347
  var ElementPrototype = Element.prototype;
279
-
280
348
  var cloneNode = lookupGetter(ElementPrototype, 'cloneNode');
281
349
  var getNextSibling = lookupGetter(ElementPrototype, 'nextSibling');
282
350
  var getChildNodes = lookupGetter(ElementPrototype, 'childNodes');
283
- var getParentNode = lookupGetter(ElementPrototype, 'parentNode');
284
-
285
- // As per issue #47, the web-components registry is inherited by a
351
+ var getParentNode = lookupGetter(ElementPrototype, 'parentNode'); // As per issue #47, the web-components registry is inherited by a
286
352
  // new document created via createHTMLDocument. As per the spec
287
353
  // (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries)
288
354
  // a new empty registry is used when creating a template contents owner
289
355
  // document, so we use that as our parent document to ensure nothing
290
356
  // is inherited.
357
+
291
358
  if (typeof HTMLTemplateElement === 'function') {
292
359
  var template = document.createElement('template');
360
+
293
361
  if (template.content && template.content.ownerDocument) {
294
362
  document = template.content.ownerDocument;
295
363
  }
296
364
  }
297
365
 
298
366
  var trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, originalDocument);
299
- var emptyHTML = trustedTypesPolicy ? trustedTypesPolicy.createHTML('') : '';
300
367
 
368
+ var emptyHTML = trustedTypesPolicy ? trustedTypesPolicy.createHTML('') : '';
301
369
  var _document = document,
302
370
  implementation = _document.implementation,
303
371
  createNodeIterator = _document.createNodeIterator,
304
372
  createDocumentFragment = _document.createDocumentFragment,
305
373
  getElementsByTagName = _document.getElementsByTagName;
306
374
  var importNode = originalDocument.importNode;
307
-
308
-
309
375
  var documentMode = {};
376
+
310
377
  try {
311
378
  documentMode = clone(document).documentMode ? document.documentMode : {};
312
379
  } catch (_) {}
313
380
 
314
381
  var hooks = {};
315
-
316
382
  /**
317
383
  * Expose whether this browser supports running the full DOMPurify.
318
384
  */
319
- DOMPurify.isSupported = typeof getParentNode === 'function' && implementation && typeof implementation.createHTMLDocument !== 'undefined' && documentMode !== 9;
320
-
321
- var MUSTACHE_EXPR$$1 = MUSTACHE_EXPR,
322
- ERB_EXPR$$1 = ERB_EXPR,
323
- DATA_ATTR$$1 = DATA_ATTR,
324
- ARIA_ATTR$$1 = ARIA_ATTR,
325
- IS_SCRIPT_OR_DATA$$1 = IS_SCRIPT_OR_DATA,
326
- ATTR_WHITESPACE$$1 = ATTR_WHITESPACE;
327
- var IS_ALLOWED_URI$$1 = IS_ALLOWED_URI;
328
385
 
386
+ DOMPurify.isSupported = typeof getParentNode === 'function' && implementation && typeof implementation.createHTMLDocument !== 'undefined' && documentMode !== 9;
387
+ var MUSTACHE_EXPR$1 = MUSTACHE_EXPR,
388
+ ERB_EXPR$1 = ERB_EXPR,
389
+ DATA_ATTR$1 = DATA_ATTR,
390
+ ARIA_ATTR$1 = ARIA_ATTR,
391
+ IS_SCRIPT_OR_DATA$1 = IS_SCRIPT_OR_DATA,
392
+ ATTR_WHITESPACE$1 = ATTR_WHITESPACE;
393
+ var IS_ALLOWED_URI$1 = IS_ALLOWED_URI;
329
394
  /**
330
395
  * We consider the elements and attributes below to be safe. Ideally
331
396
  * don't add any new ones but feel free to remove unwanted ones.
@@ -334,18 +399,18 @@ function createDOMPurify() {
334
399
  /* allowed element names */
335
400
 
336
401
  var ALLOWED_TAGS = null;
337
- var DEFAULT_ALLOWED_TAGS = addToSet({}, [].concat(_toConsumableArray$1(html), _toConsumableArray$1(svg), _toConsumableArray$1(svgFilters), _toConsumableArray$1(mathMl), _toConsumableArray$1(text)));
338
-
402
+ var DEFAULT_ALLOWED_TAGS = addToSet({}, [].concat(_toConsumableArray(html$1), _toConsumableArray(svg$1), _toConsumableArray(svgFilters), _toConsumableArray(mathMl$1), _toConsumableArray(text)));
339
403
  /* Allowed attribute names */
340
- var ALLOWED_ATTR = null;
341
- var DEFAULT_ALLOWED_ATTR = addToSet({}, [].concat(_toConsumableArray$1(html$1), _toConsumableArray$1(svg$1), _toConsumableArray$1(mathMl$1), _toConsumableArray$1(xml)));
342
404
 
405
+ var ALLOWED_ATTR = null;
406
+ var DEFAULT_ALLOWED_ATTR = addToSet({}, [].concat(_toConsumableArray(html), _toConsumableArray(svg), _toConsumableArray(mathMl), _toConsumableArray(xml)));
343
407
  /*
344
408
  * Configure how DOMPUrify should handle custom elements and their attributes as well as customized built-in elements.
345
409
  * @property {RegExp|Function|null} tagNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any custom elements)
346
410
  * @property {RegExp|Function|null} attributeNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any attributes not on the allow list)
347
411
  * @property {boolean} allowCustomizedBuiltInElements allow custom elements derived from built-ins if they pass CUSTOM_ELEMENT_HANDLING.tagNameCheck. Default: `false`.
348
412
  */
413
+
349
414
  var CUSTOM_ELEMENT_HANDLING = Object.seal(Object.create(null, {
350
415
  tagNameCheck: {
351
416
  writable: true,
@@ -366,93 +431,93 @@ function createDOMPurify() {
366
431
  value: false
367
432
  }
368
433
  }));
369
-
370
434
  /* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */
371
- var FORBID_TAGS = null;
372
435
 
436
+ var FORBID_TAGS = null;
373
437
  /* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */
374
- var FORBID_ATTR = null;
375
438
 
439
+ var FORBID_ATTR = null;
376
440
  /* Decide if ARIA attributes are okay */
377
- var ALLOW_ARIA_ATTR = true;
378
441
 
442
+ var ALLOW_ARIA_ATTR = true;
379
443
  /* Decide if custom data attributes are okay */
380
- var ALLOW_DATA_ATTR = true;
381
444
 
445
+ var ALLOW_DATA_ATTR = true;
382
446
  /* Decide if unknown protocols are okay */
383
- var ALLOW_UNKNOWN_PROTOCOLS = false;
384
447
 
448
+ var ALLOW_UNKNOWN_PROTOCOLS = false;
385
449
  /* Output should be safe for common template engines.
386
450
  * This means, DOMPurify removes data attributes, mustaches and ERB
387
451
  */
388
- var SAFE_FOR_TEMPLATES = false;
389
452
 
453
+ var SAFE_FOR_TEMPLATES = false;
390
454
  /* Decide if document with <html>... should be returned */
391
- var WHOLE_DOCUMENT = false;
392
455
 
456
+ var WHOLE_DOCUMENT = false;
393
457
  /* Track whether config is already set on this instance of DOMPurify. */
394
- var SET_CONFIG = false;
395
458
 
459
+ var SET_CONFIG = false;
396
460
  /* Decide if all elements (e.g. style, script) must be children of
397
461
  * document.body. By default, browsers might move them to document.head */
398
- var FORCE_BODY = false;
399
462
 
463
+ var FORCE_BODY = false;
400
464
  /* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html
401
465
  * string (or a TrustedHTML object if Trusted Types are supported).
402
466
  * If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead
403
467
  */
404
- var RETURN_DOM = false;
405
468
 
469
+ var RETURN_DOM = false;
406
470
  /* Decide if a DOM `DocumentFragment` should be returned, instead of a html
407
471
  * string (or a TrustedHTML object if Trusted Types are supported) */
408
- var RETURN_DOM_FRAGMENT = false;
409
472
 
473
+ var RETURN_DOM_FRAGMENT = false;
410
474
  /* Try to return a Trusted Type object instead of a string, return a string in
411
475
  * case Trusted Types are not supported */
412
- var RETURN_TRUSTED_TYPE = false;
413
476
 
477
+ var RETURN_TRUSTED_TYPE = false;
414
478
  /* Output should be free from DOM clobbering attacks? */
415
- var SANITIZE_DOM = true;
416
479
 
480
+ var SANITIZE_DOM = true;
417
481
  /* Keep element content when removing element? */
418
- var KEEP_CONTENT = true;
419
482
 
483
+ var KEEP_CONTENT = true;
420
484
  /* If a `Node` is passed to sanitize(), then performs sanitization in-place instead
421
485
  * of importing it into a new Document and returning a sanitized copy */
422
- var IN_PLACE = false;
423
486
 
487
+ var IN_PLACE = false;
424
488
  /* Allow usage of profiles like html, svg and mathMl */
425
- var USE_PROFILES = {};
426
489
 
490
+ var USE_PROFILES = {};
427
491
  /* Tags to ignore content of when KEEP_CONTENT is true */
492
+
428
493
  var FORBID_CONTENTS = null;
429
494
  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']);
430
-
431
495
  /* Tags that are safe for data: URIs */
496
+
432
497
  var DATA_URI_TAGS = null;
433
498
  var DEFAULT_DATA_URI_TAGS = addToSet({}, ['audio', 'video', 'img', 'source', 'image', 'track']);
434
-
435
499
  /* Attributes safe for values like "javascript:" */
500
+
436
501
  var URI_SAFE_ATTRIBUTES = null;
437
502
  var DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ['alt', 'class', 'for', 'id', 'label', 'name', 'pattern', 'placeholder', 'role', 'summary', 'title', 'value', 'style', 'xmlns']);
438
-
439
503
  var MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
440
504
  var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
441
505
  var HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';
442
506
  /* Document namespace */
507
+
443
508
  var NAMESPACE = HTML_NAMESPACE;
444
509
  var IS_EMPTY_INPUT = false;
445
-
446
510
  /* Parsing of strict XHTML documents */
447
- var PARSER_MEDIA_TYPE = void 0;
511
+
512
+ var PARSER_MEDIA_TYPE;
448
513
  var SUPPORTED_PARSER_MEDIA_TYPES = ['application/xhtml+xml', 'text/html'];
449
514
  var DEFAULT_PARSER_MEDIA_TYPE = 'text/html';
450
- var transformCaseFunc = void 0;
451
-
515
+ var transformCaseFunc;
452
516
  /* Keep a reference to config to pass to hooks */
453
- var CONFIG = null;
454
517
 
518
+ var CONFIG = null;
455
519
  /* Ideally, do not touch anything below this line */
520
+
456
521
  /* ______________________________________________ */
457
522
 
458
523
  var formElement = document.createElement('form');
@@ -460,49 +525,79 @@ function createDOMPurify() {
460
525
  var isRegexOrFunction = function isRegexOrFunction(testValue) {
461
526
  return testValue instanceof RegExp || testValue instanceof Function;
462
527
  };
463
-
464
528
  /**
465
529
  * _parseConfig
466
530
  *
467
531
  * @param {Object} cfg optional config literal
468
532
  */
469
533
  // eslint-disable-next-line complexity
534
+
535
+
470
536
  var _parseConfig = function _parseConfig(cfg) {
471
537
  if (CONFIG && CONFIG === cfg) {
472
538
  return;
473
539
  }
474
-
475
540
  /* Shield configuration object from tampering */
476
- if (!cfg || (typeof cfg === 'undefined' ? 'undefined' : _typeof(cfg)) !== 'object') {
541
+
542
+
543
+ if (!cfg || _typeof(cfg) !== 'object') {
477
544
  cfg = {};
478
545
  }
479
-
480
546
  /* Shield configuration object from prototype pollution */
547
+
548
+
481
549
  cfg = clone(cfg);
550
+ PARSER_MEDIA_TYPE = // eslint-disable-next-line unicorn/prefer-includes
551
+ 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.
482
552
 
553
+ transformCaseFunc = PARSER_MEDIA_TYPE === 'application/xhtml+xml' ? function (x) {
554
+ return x;
555
+ } : stringToLowerCase;
483
556
  /* Set configuration parameters */
484
- ALLOWED_TAGS = 'ALLOWED_TAGS' in cfg ? addToSet({}, cfg.ALLOWED_TAGS) : DEFAULT_ALLOWED_TAGS;
485
- ALLOWED_ATTR = 'ALLOWED_ATTR' in cfg ? addToSet({}, cfg.ALLOWED_ATTR) : DEFAULT_ALLOWED_ATTR;
486
- URI_SAFE_ATTRIBUTES = 'ADD_URI_SAFE_ATTR' in cfg ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR) : DEFAULT_URI_SAFE_ATTRIBUTES;
487
- DATA_URI_TAGS = 'ADD_DATA_URI_TAGS' in cfg ? addToSet(clone(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS) : DEFAULT_DATA_URI_TAGS;
488
- FORBID_CONTENTS = 'FORBID_CONTENTS' in cfg ? addToSet({}, cfg.FORBID_CONTENTS) : DEFAULT_FORBID_CONTENTS;
489
- FORBID_TAGS = 'FORBID_TAGS' in cfg ? addToSet({}, cfg.FORBID_TAGS) : {};
490
- FORBID_ATTR = 'FORBID_ATTR' in cfg ? addToSet({}, cfg.FORBID_ATTR) : {};
557
+
558
+ ALLOWED_TAGS = 'ALLOWED_TAGS' in cfg ? addToSet({}, cfg.ALLOWED_TAGS, transformCaseFunc) : DEFAULT_ALLOWED_TAGS;
559
+ ALLOWED_ATTR = 'ALLOWED_ATTR' in cfg ? addToSet({}, cfg.ALLOWED_ATTR, transformCaseFunc) : DEFAULT_ALLOWED_ATTR;
560
+ URI_SAFE_ATTRIBUTES = 'ADD_URI_SAFE_ATTR' in cfg ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), // eslint-disable-line indent
561
+ cfg.ADD_URI_SAFE_ATTR, // eslint-disable-line indent
562
+ transformCaseFunc // eslint-disable-line indent
563
+ ) // eslint-disable-line indent
564
+ : DEFAULT_URI_SAFE_ATTRIBUTES;
565
+ DATA_URI_TAGS = 'ADD_DATA_URI_TAGS' in cfg ? addToSet(clone(DEFAULT_DATA_URI_TAGS), // eslint-disable-line indent
566
+ cfg.ADD_DATA_URI_TAGS, // eslint-disable-line indent
567
+ transformCaseFunc // eslint-disable-line indent
568
+ ) // eslint-disable-line indent
569
+ : DEFAULT_DATA_URI_TAGS;
570
+ FORBID_CONTENTS = 'FORBID_CONTENTS' in cfg ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc) : DEFAULT_FORBID_CONTENTS;
571
+ FORBID_TAGS = 'FORBID_TAGS' in cfg ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : {};
572
+ FORBID_ATTR = 'FORBID_ATTR' in cfg ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : {};
491
573
  USE_PROFILES = 'USE_PROFILES' in cfg ? cfg.USE_PROFILES : false;
492
574
  ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true
575
+
493
576
  ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true
577
+
494
578
  ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false
579
+
495
580
  SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false
581
+
496
582
  WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false
583
+
497
584
  RETURN_DOM = cfg.RETURN_DOM || false; // Default false
585
+
498
586
  RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false
587
+
499
588
  RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false
589
+
500
590
  FORCE_BODY = cfg.FORCE_BODY || false; // Default false
591
+
501
592
  SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true
593
+
502
594
  KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true
595
+
503
596
  IN_PLACE = cfg.IN_PLACE || false; // Default false
504
- IS_ALLOWED_URI$$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI$$1;
597
+
598
+ IS_ALLOWED_URI$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI$1;
505
599
  NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE;
600
+
506
601
  if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck)) {
507
602
  CUSTOM_ELEMENT_HANDLING.tagNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck;
508
603
  }
@@ -515,15 +610,6 @@ function createDOMPurify() {
515
610
  CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements;
516
611
  }
517
612
 
518
- PARSER_MEDIA_TYPE =
519
- // eslint-disable-next-line unicorn/prefer-includes
520
- SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? PARSER_MEDIA_TYPE = DEFAULT_PARSER_MEDIA_TYPE : PARSER_MEDIA_TYPE = cfg.PARSER_MEDIA_TYPE;
521
-
522
- // HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is.
523
- transformCaseFunc = PARSER_MEDIA_TYPE === 'application/xhtml+xml' ? function (x) {
524
- return x;
525
- } : stringToLowerCase;
526
-
527
613
  if (SAFE_FOR_TEMPLATES) {
528
614
  ALLOW_DATA_ATTR = false;
529
615
  }
@@ -531,42 +617,45 @@ function createDOMPurify() {
531
617
  if (RETURN_DOM_FRAGMENT) {
532
618
  RETURN_DOM = true;
533
619
  }
534
-
535
620
  /* Parse profile info */
621
+
622
+
536
623
  if (USE_PROFILES) {
537
- ALLOWED_TAGS = addToSet({}, [].concat(_toConsumableArray$1(text)));
624
+ ALLOWED_TAGS = addToSet({}, _toConsumableArray(text));
538
625
  ALLOWED_ATTR = [];
626
+
539
627
  if (USE_PROFILES.html === true) {
540
- addToSet(ALLOWED_TAGS, html);
541
- addToSet(ALLOWED_ATTR, html$1);
628
+ addToSet(ALLOWED_TAGS, html$1);
629
+ addToSet(ALLOWED_ATTR, html);
542
630
  }
543
631
 
544
632
  if (USE_PROFILES.svg === true) {
545
- addToSet(ALLOWED_TAGS, svg);
546
- addToSet(ALLOWED_ATTR, svg$1);
633
+ addToSet(ALLOWED_TAGS, svg$1);
634
+ addToSet(ALLOWED_ATTR, svg);
547
635
  addToSet(ALLOWED_ATTR, xml);
548
636
  }
549
637
 
550
638
  if (USE_PROFILES.svgFilters === true) {
551
639
  addToSet(ALLOWED_TAGS, svgFilters);
552
- addToSet(ALLOWED_ATTR, svg$1);
640
+ addToSet(ALLOWED_ATTR, svg);
553
641
  addToSet(ALLOWED_ATTR, xml);
554
642
  }
555
643
 
556
644
  if (USE_PROFILES.mathMl === true) {
557
- addToSet(ALLOWED_TAGS, mathMl);
558
- addToSet(ALLOWED_ATTR, mathMl$1);
645
+ addToSet(ALLOWED_TAGS, mathMl$1);
646
+ addToSet(ALLOWED_ATTR, mathMl);
559
647
  addToSet(ALLOWED_ATTR, xml);
560
648
  }
561
649
  }
562
-
563
650
  /* Merge configuration parameters */
651
+
652
+
564
653
  if (cfg.ADD_TAGS) {
565
654
  if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {
566
655
  ALLOWED_TAGS = clone(ALLOWED_TAGS);
567
656
  }
568
657
 
569
- addToSet(ALLOWED_TAGS, cfg.ADD_TAGS);
658
+ addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc);
570
659
  }
571
660
 
572
661
  if (cfg.ADD_ATTR) {
@@ -574,11 +663,11 @@ function createDOMPurify() {
574
663
  ALLOWED_ATTR = clone(ALLOWED_ATTR);
575
664
  }
576
665
 
577
- addToSet(ALLOWED_ATTR, cfg.ADD_ATTR);
666
+ addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc);
578
667
  }
579
668
 
580
669
  if (cfg.ADD_URI_SAFE_ATTR) {
581
- addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR);
670
+ addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc);
582
671
  }
583
672
 
584
673
  if (cfg.FORBID_CONTENTS) {
@@ -586,27 +675,30 @@ function createDOMPurify() {
586
675
  FORBID_CONTENTS = clone(FORBID_CONTENTS);
587
676
  }
588
677
 
589
- addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS);
678
+ addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc);
590
679
  }
591
-
592
680
  /* Add #text in case KEEP_CONTENT is set to true */
681
+
682
+
593
683
  if (KEEP_CONTENT) {
594
684
  ALLOWED_TAGS['#text'] = true;
595
685
  }
596
-
597
686
  /* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */
687
+
688
+
598
689
  if (WHOLE_DOCUMENT) {
599
690
  addToSet(ALLOWED_TAGS, ['html', 'head', 'body']);
600
691
  }
601
-
602
692
  /* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */
693
+
694
+
603
695
  if (ALLOWED_TAGS.table) {
604
696
  addToSet(ALLOWED_TAGS, ['tbody']);
605
697
  delete FORBID_TAGS.tbody;
606
- }
607
-
608
- // Prevent further manipulation of configuration.
698
+ } // Prevent further manipulation of configuration.
609
699
  // Not available in IE8, Safari 5, etc.
700
+
701
+
610
702
  if (freeze) {
611
703
  freeze(cfg);
612
704
  }
@@ -615,19 +707,21 @@ function createDOMPurify() {
615
707
  };
616
708
 
617
709
  var MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ['mi', 'mo', 'mn', 'ms', 'mtext']);
710
+ var HTML_INTEGRATION_POINTS = addToSet({}, ['foreignobject', 'desc', 'title', 'annotation-xml']); // Certain elements are allowed in both SVG and HTML
711
+ // namespace. We need to specify them explicitly
712
+ // so that they don't get erroneously deleted from
713
+ // HTML namespace.
618
714
 
619
- var HTML_INTEGRATION_POINTS = addToSet({}, ['foreignobject', 'desc', 'title', 'annotation-xml']);
620
-
715
+ var COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, ['title', 'style', 'font', 'a', 'script']);
621
716
  /* Keep track of all possible SVG and MathML tags
622
717
  * so that we can perform the namespace checks
623
718
  * correctly. */
624
- var ALL_SVG_TAGS = addToSet({}, svg);
719
+
720
+ var ALL_SVG_TAGS = addToSet({}, svg$1);
625
721
  addToSet(ALL_SVG_TAGS, svgFilters);
626
722
  addToSet(ALL_SVG_TAGS, svgDisallowed);
627
-
628
- var ALL_MATHML_TAGS = addToSet({}, mathMl);
723
+ var ALL_MATHML_TAGS = addToSet({}, mathMl$1);
629
724
  addToSet(ALL_MATHML_TAGS, mathMlDisallowed);
630
-
631
725
  /**
632
726
  *
633
727
  *
@@ -636,11 +730,11 @@ function createDOMPurify() {
636
730
  * namespace that a spec-compliant parser would never
637
731
  * return. Return true otherwise.
638
732
  */
639
- var _checkValidNamespace = function _checkValidNamespace(element) {
640
- var parent = getParentNode(element);
641
733
 
642
- // In JSDOM, if we're inside shadow DOM, then parentNode
734
+ var _checkValidNamespace = function _checkValidNamespace(element) {
735
+ var parent = getParentNode(element); // In JSDOM, if we're inside shadow DOM, then parentNode
643
736
  // can be null. We just simulate parent in this case.
737
+
644
738
  if (!parent || !parent.tagName) {
645
739
  parent = {
646
740
  namespaceURI: HTML_NAMESPACE,
@@ -657,17 +751,17 @@ function createDOMPurify() {
657
751
  // it should be killed.
658
752
  if (parent.namespaceURI === HTML_NAMESPACE) {
659
753
  return tagName === 'svg';
660
- }
661
-
662
- // The only way to switch from MathML to SVG is via
754
+ } // The only way to switch from MathML to SVG is via
663
755
  // svg if parent is either <annotation-xml> or MathML
664
756
  // text integration points.
757
+
758
+
665
759
  if (parent.namespaceURI === MATHML_NAMESPACE) {
666
760
  return tagName === 'svg' && (parentTagName === 'annotation-xml' || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]);
667
- }
668
-
669
- // We only allow elements that are defined in SVG
761
+ } // We only allow elements that are defined in SVG
670
762
  // spec. All others are disallowed in SVG namespace.
763
+
764
+
671
765
  return Boolean(ALL_SVG_TAGS[tagName]);
672
766
  }
673
767
 
@@ -677,16 +771,16 @@ function createDOMPurify() {
677
771
  // it should be killed.
678
772
  if (parent.namespaceURI === HTML_NAMESPACE) {
679
773
  return tagName === 'math';
680
- }
681
-
682
- // The only way to switch from SVG to MathML is via
774
+ } // The only way to switch from SVG to MathML is via
683
775
  // <math> and HTML integration points
776
+
777
+
684
778
  if (parent.namespaceURI === SVG_NAMESPACE) {
685
779
  return tagName === 'math' && HTML_INTEGRATION_POINTS[parentTagName];
686
- }
687
-
688
- // We only allow elements that are defined in MathML
780
+ } // We only allow elements that are defined in MathML
689
781
  // spec. All others are disallowed in MathML namespace.
782
+
783
+
690
784
  return Boolean(ALL_MATHML_TAGS[tagName]);
691
785
  }
692
786
 
@@ -700,32 +794,30 @@ function createDOMPurify() {
700
794
 
701
795
  if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) {
702
796
  return false;
703
- }
704
-
705
- // Certain elements are allowed in both SVG and HTML
706
- // namespace. We need to specify them explicitly
707
- // so that they don't get erronously deleted from
708
- // HTML namespace.
709
- var commonSvgAndHTMLElements = addToSet({}, ['title', 'style', 'font', 'a', 'script']);
710
-
711
- // We disallow tags that are specific for MathML
797
+ } // We disallow tags that are specific for MathML
712
798
  // or SVG and should never appear in HTML namespace
713
- return !ALL_MATHML_TAGS[tagName] && (commonSvgAndHTMLElements[tagName] || !ALL_SVG_TAGS[tagName]);
714
- }
715
799
 
716
- // The code should never reach this place (this means
800
+
801
+ return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]);
802
+ } // The code should never reach this place (this means
717
803
  // that the element somehow got namespace that is not
718
804
  // HTML, SVG or MathML). Return false just in case.
805
+
806
+
719
807
  return false;
720
808
  };
721
-
722
809
  /**
723
810
  * _forceRemove
724
811
  *
725
812
  * @param {Node} node a DOM node
726
813
  */
814
+
815
+
727
816
  var _forceRemove = function _forceRemove(node) {
728
- arrayPush(DOMPurify.removed, { element: node });
817
+ arrayPush(DOMPurify.removed, {
818
+ element: node
819
+ });
820
+
729
821
  try {
730
822
  // eslint-disable-next-line unicorn/prefer-dom-node-remove
731
823
  node.parentNode.removeChild(node);
@@ -737,13 +829,14 @@ function createDOMPurify() {
737
829
  }
738
830
  }
739
831
  };
740
-
741
832
  /**
742
833
  * _removeAttribute
743
834
  *
744
835
  * @param {String} name an Attribute name
745
836
  * @param {Node} node a DOM node
746
837
  */
838
+
839
+
747
840
  var _removeAttribute = function _removeAttribute(name, node) {
748
841
  try {
749
842
  arrayPush(DOMPurify.removed, {
@@ -757,9 +850,8 @@ function createDOMPurify() {
757
850
  });
758
851
  }
759
852
 
760
- node.removeAttribute(name);
853
+ node.removeAttribute(name); // We void attribute values for unremovable "is"" attributes
761
854
 
762
- // We void attribute values for unremovable "is"" attributes
763
855
  if (name === 'is' && !ALLOWED_ATTR[name]) {
764
856
  if (RETURN_DOM || RETURN_DOM_FRAGMENT) {
765
857
  try {
@@ -772,17 +864,18 @@ function createDOMPurify() {
772
864
  }
773
865
  }
774
866
  };
775
-
776
867
  /**
777
868
  * _initDocument
778
869
  *
779
870
  * @param {String} dirty a string of dirty markup
780
871
  * @return {Document} a DOM, filled with the dirty markup
781
872
  */
873
+
874
+
782
875
  var _initDocument = function _initDocument(dirty) {
783
876
  /* Create a HTML document */
784
- var doc = void 0;
785
- var leadingWhitespace = void 0;
877
+ var doc;
878
+ var leadingWhitespace;
786
879
 
787
880
  if (FORCE_BODY) {
788
881
  dirty = '<remove></remove>' + dirty;
@@ -802,19 +895,21 @@ function createDOMPurify() {
802
895
  * Use the DOMParser API by default, fallback later if needs be
803
896
  * DOMParser not work for svg when has multiple root element.
804
897
  */
898
+
805
899
  if (NAMESPACE === HTML_NAMESPACE) {
806
900
  try {
807
901
  doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE);
808
902
  } catch (_) {}
809
903
  }
810
-
811
904
  /* Use createHTMLDocument in case DOMParser is not available */
905
+
906
+
812
907
  if (!doc || !doc.documentElement) {
813
908
  doc = implementation.createDocument(NAMESPACE, 'template', null);
909
+
814
910
  try {
815
911
  doc.documentElement.innerHTML = IS_EMPTY_INPUT ? '' : dirtyPayload;
816
- } catch (_) {
817
- // Syntax error if dirtyPayload is invalid xml
912
+ } catch (_) {// Syntax error if dirtyPayload is invalid xml
818
913
  }
819
914
  }
820
915
 
@@ -823,47 +918,49 @@ function createDOMPurify() {
823
918
  if (dirty && leadingWhitespace) {
824
919
  body.insertBefore(document.createTextNode(leadingWhitespace), body.childNodes[0] || null);
825
920
  }
826
-
827
921
  /* Work on whole document or just its body */
922
+
923
+
828
924
  if (NAMESPACE === HTML_NAMESPACE) {
829
925
  return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0];
830
926
  }
831
927
 
832
928
  return WHOLE_DOCUMENT ? doc.documentElement : body;
833
929
  };
834
-
835
930
  /**
836
931
  * _createIterator
837
932
  *
838
933
  * @param {Document} root document/fragment to create iterator for
839
934
  * @return {Iterator} iterator instance
840
935
  */
936
+
937
+
841
938
  var _createIterator = function _createIterator(root) {
842
- return createNodeIterator.call(root.ownerDocument || root, root,
843
- // eslint-disable-next-line no-bitwise
939
+ return createNodeIterator.call(root.ownerDocument || root, root, // eslint-disable-next-line no-bitwise
844
940
  NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT, null, false);
845
941
  };
846
-
847
942
  /**
848
943
  * _isClobbered
849
944
  *
850
945
  * @param {Node} elm element to check for clobbering attacks
851
946
  * @return {Boolean} true if clobbered, false if safe
852
947
  */
948
+
949
+
853
950
  var _isClobbered = function _isClobbered(elm) {
854
951
  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');
855
952
  };
856
-
857
953
  /**
858
954
  * _isNode
859
955
  *
860
956
  * @param {Node} obj object to check whether it's a DOM node
861
957
  * @return {Boolean} true is object is a DOM node
862
958
  */
959
+
960
+
863
961
  var _isNode = function _isNode(object) {
864
- return (typeof Node === 'undefined' ? 'undefined' : _typeof(Node)) === 'object' ? object instanceof Node : object && (typeof object === 'undefined' ? 'undefined' : _typeof(object)) === 'object' && typeof object.nodeType === 'number' && typeof object.nodeName === 'string';
962
+ return _typeof(Node) === 'object' ? object instanceof Node : object && _typeof(object) === 'object' && typeof object.nodeType === 'number' && typeof object.nodeName === 'string';
865
963
  };
866
-
867
964
  /**
868
965
  * _executeHook
869
966
  * Execute user configurable hooks
@@ -872,6 +969,8 @@ function createDOMPurify() {
872
969
  * @param {Node} currentNode node to work on with the hook
873
970
  * @param {Object} data additional hook parameters
874
971
  */
972
+
973
+
875
974
  var _executeHook = function _executeHook(entryPoint, currentNode, data) {
876
975
  if (!hooks[entryPoint]) {
877
976
  return;
@@ -881,7 +980,6 @@ function createDOMPurify() {
881
980
  hook.call(DOMPurify, currentNode, data, CONFIG);
882
981
  });
883
982
  };
884
-
885
983
  /**
886
984
  * _sanitizeElements
887
985
  *
@@ -892,54 +990,67 @@ function createDOMPurify() {
892
990
  * @param {Node} currentNode to check for permission to exist
893
991
  * @return {Boolean} true if node was killed, false if left alive
894
992
  */
895
- var _sanitizeElements = function _sanitizeElements(currentNode) {
896
- var content = void 0;
897
993
 
994
+
995
+ var _sanitizeElements = function _sanitizeElements(currentNode) {
996
+ var content;
898
997
  /* Execute a hook if present */
899
- _executeHook('beforeSanitizeElements', currentNode, null);
900
998
 
999
+ _executeHook('beforeSanitizeElements', currentNode, null);
901
1000
  /* Check if element is clobbered or can clobber */
1001
+
1002
+
902
1003
  if (_isClobbered(currentNode)) {
903
1004
  _forceRemove(currentNode);
1005
+
904
1006
  return true;
905
1007
  }
906
-
907
1008
  /* Check if tagname contains Unicode */
908
- if (stringMatch(currentNode.nodeName, /[\u0080-\uFFFF]/)) {
1009
+
1010
+
1011
+ if (regExpTest(/[\u0080-\uFFFF]/, currentNode.nodeName)) {
909
1012
  _forceRemove(currentNode);
1013
+
910
1014
  return true;
911
1015
  }
912
-
913
1016
  /* Now let's check the element's type and name */
914
- var tagName = transformCaseFunc(currentNode.nodeName);
915
1017
 
1018
+
1019
+ var tagName = transformCaseFunc(currentNode.nodeName);
916
1020
  /* Execute a hook if present */
1021
+
917
1022
  _executeHook('uponSanitizeElement', currentNode, {
918
1023
  tagName: tagName,
919
1024
  allowedTags: ALLOWED_TAGS
920
1025
  });
921
-
922
1026
  /* Detect mXSS attempts abusing namespace confusion */
923
- if (!_isNode(currentNode.firstElementChild) && (!_isNode(currentNode.content) || !_isNode(currentNode.content.firstElementChild)) && regExpTest(/<[/\w]/g, currentNode.innerHTML) && regExpTest(/<[/\w]/g, currentNode.textContent)) {
1027
+
1028
+
1029
+ if (currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && (!_isNode(currentNode.content) || !_isNode(currentNode.content.firstElementChild)) && regExpTest(/<[/\w]/g, currentNode.innerHTML) && regExpTest(/<[/\w]/g, currentNode.textContent)) {
924
1030
  _forceRemove(currentNode);
1031
+
925
1032
  return true;
926
1033
  }
927
-
928
1034
  /* Mitigate a problem with templates inside select */
1035
+
1036
+
929
1037
  if (tagName === 'select' && regExpTest(/<template/i, currentNode.innerHTML)) {
930
1038
  _forceRemove(currentNode);
1039
+
931
1040
  return true;
932
1041
  }
933
-
934
1042
  /* Remove element if anything forbids its presence */
1043
+
1044
+
935
1045
  if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
936
1046
  /* Check if we have a custom element to handle */
937
1047
  if (!FORBID_TAGS[tagName] && _basicCustomElementTest(tagName)) {
938
1048
  if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) return false;
939
1049
  if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) return false;
940
1050
  }
941
-
942
1051
  /* Keep content except for bad-listed elements */
1052
+
1053
+
943
1054
  if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {
944
1055
  var parentNode = getParentNode(currentNode) || currentNode.parentNode;
945
1056
  var childNodes = getChildNodes(currentNode) || currentNode.childNodes;
@@ -954,38 +1065,46 @@ function createDOMPurify() {
954
1065
  }
955
1066
 
956
1067
  _forceRemove(currentNode);
1068
+
957
1069
  return true;
958
1070
  }
959
-
960
1071
  /* Check whether element has a valid namespace */
1072
+
1073
+
961
1074
  if (currentNode instanceof Element && !_checkValidNamespace(currentNode)) {
962
1075
  _forceRemove(currentNode);
1076
+
963
1077
  return true;
964
1078
  }
965
1079
 
966
1080
  if ((tagName === 'noscript' || tagName === 'noembed') && regExpTest(/<\/no(script|embed)/i, currentNode.innerHTML)) {
967
1081
  _forceRemove(currentNode);
1082
+
968
1083
  return true;
969
1084
  }
970
-
971
1085
  /* Sanitize element content to be template-safe */
1086
+
1087
+
972
1088
  if (SAFE_FOR_TEMPLATES && currentNode.nodeType === 3) {
973
1089
  /* Get the element's text content */
974
1090
  content = currentNode.textContent;
975
- content = stringReplace(content, MUSTACHE_EXPR$$1, ' ');
976
- content = stringReplace(content, ERB_EXPR$$1, ' ');
1091
+ content = stringReplace(content, MUSTACHE_EXPR$1, ' ');
1092
+ content = stringReplace(content, ERB_EXPR$1, ' ');
1093
+
977
1094
  if (currentNode.textContent !== content) {
978
- arrayPush(DOMPurify.removed, { element: currentNode.cloneNode() });
1095
+ arrayPush(DOMPurify.removed, {
1096
+ element: currentNode.cloneNode()
1097
+ });
979
1098
  currentNode.textContent = content;
980
1099
  }
981
1100
  }
982
-
983
1101
  /* Execute a hook if present */
1102
+
1103
+
984
1104
  _executeHook('afterSanitizeElements', currentNode, null);
985
1105
 
986
1106
  return false;
987
1107
  };
988
-
989
1108
  /**
990
1109
  * _isValidAttribute
991
1110
  *
@@ -995,45 +1114,47 @@ function createDOMPurify() {
995
1114
  * @return {Boolean} Returns true if `value` is valid, otherwise false.
996
1115
  */
997
1116
  // eslint-disable-next-line complexity
1117
+
1118
+
998
1119
  var _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) {
999
1120
  /* Make sure attribute cannot clobber */
1000
1121
  if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) {
1001
1122
  return false;
1002
1123
  }
1003
-
1004
1124
  /* Allow valid data-* attributes: At least one character after "-"
1005
1125
  (https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)
1006
1126
  XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)
1007
1127
  We don't need to check the value; it's always URI safe. */
1008
- 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]) {
1009
- if (
1010
- // First condition does a very basic check if a) it's basically a valid custom element tagname AND
1128
+
1129
+
1130
+ 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]) {
1131
+ if ( // First condition does a very basic check if a) it's basically a valid custom element tagname AND
1011
1132
  // b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
1012
1133
  // and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck
1013
- _basicCustomElementTest(lcTag) && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag)) && (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName) || CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName)) ||
1014
- // Alternative, second condition checks if it's an `is`-attribute, AND
1134
+ _basicCustomElementTest(lcTag) && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag)) && (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName) || CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName)) || // Alternative, second condition checks if it's an `is`-attribute, AND
1015
1135
  // the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
1016
1136
  lcName === 'is' && CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, value) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(value))) ; else {
1017
1137
  return false;
1018
1138
  }
1019
1139
  /* Check value is safe. First, is attr inert? If so, is safe */
1020
- } 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 {
1140
+
1141
+ } 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 {
1021
1142
  return false;
1022
1143
  }
1023
1144
 
1024
1145
  return true;
1025
1146
  };
1026
-
1027
1147
  /**
1028
1148
  * _basicCustomElementCheck
1029
1149
  * checks if at least one dash is included in tagName, and it's not the first char
1030
1150
  * for more sophisticated checking see https://github.com/sindresorhus/validate-element-name
1031
1151
  * @param {string} tagName name of the tag of the node to sanitize
1032
1152
  */
1153
+
1154
+
1033
1155
  var _basicCustomElementTest = function _basicCustomElementTest(tagName) {
1034
1156
  return tagName.indexOf('-') > 0;
1035
1157
  };
1036
-
1037
1158
  /**
1038
1159
  * _sanitizeAttributes
1039
1160
  *
@@ -1044,16 +1165,18 @@ function createDOMPurify() {
1044
1165
  *
1045
1166
  * @param {Node} currentNode to sanitize
1046
1167
  */
1168
+
1169
+
1047
1170
  var _sanitizeAttributes = function _sanitizeAttributes(currentNode) {
1048
- var attr = void 0;
1049
- var value = void 0;
1050
- var lcName = void 0;
1051
- var l = void 0;
1171
+ var attr;
1172
+ var value;
1173
+ var lcName;
1174
+ var l;
1052
1175
  /* Execute a hook if present */
1176
+
1053
1177
  _executeHook('beforeSanitizeAttributes', currentNode, null);
1054
1178
 
1055
1179
  var attributes = currentNode.attributes;
1056
-
1057
1180
  /* Check if we have attributes; if not we might have a text node */
1058
1181
 
1059
1182
  if (!attributes) {
@@ -1067,56 +1190,66 @@ function createDOMPurify() {
1067
1190
  allowedAttributes: ALLOWED_ATTR
1068
1191
  };
1069
1192
  l = attributes.length;
1070
-
1071
1193
  /* Go backwards over all attributes; safely remove bad ones */
1194
+
1072
1195
  while (l--) {
1073
1196
  attr = attributes[l];
1074
1197
  var _attr = attr,
1075
1198
  name = _attr.name,
1076
1199
  namespaceURI = _attr.namespaceURI;
1077
-
1078
- value = stringTrim(attr.value);
1200
+ value = name === 'value' ? attr.value : stringTrim(attr.value);
1079
1201
  lcName = transformCaseFunc(name);
1080
-
1081
1202
  /* Execute a hook if present */
1203
+
1082
1204
  hookEvent.attrName = lcName;
1083
1205
  hookEvent.attrValue = value;
1084
1206
  hookEvent.keepAttr = true;
1085
1207
  hookEvent.forceKeepAttr = undefined; // Allows developers to see this is a property they can set
1208
+
1086
1209
  _executeHook('uponSanitizeAttribute', currentNode, hookEvent);
1210
+
1087
1211
  value = hookEvent.attrValue;
1088
1212
  /* Did the hooks approve of the attribute? */
1213
+
1089
1214
  if (hookEvent.forceKeepAttr) {
1090
1215
  continue;
1091
1216
  }
1092
-
1093
1217
  /* Remove attribute */
1094
- _removeAttribute(name, currentNode);
1095
1218
 
1219
+
1220
+ _removeAttribute(name, currentNode);
1096
1221
  /* Did the hooks approve of the attribute? */
1222
+
1223
+
1097
1224
  if (!hookEvent.keepAttr) {
1098
1225
  continue;
1099
1226
  }
1100
-
1101
1227
  /* Work around a security issue in jQuery 3.0 */
1228
+
1229
+
1102
1230
  if (regExpTest(/\/>/i, value)) {
1103
1231
  _removeAttribute(name, currentNode);
1232
+
1104
1233
  continue;
1105
1234
  }
1106
-
1107
1235
  /* Sanitize attribute content to be template-safe */
1236
+
1237
+
1108
1238
  if (SAFE_FOR_TEMPLATES) {
1109
- value = stringReplace(value, MUSTACHE_EXPR$$1, ' ');
1110
- value = stringReplace(value, ERB_EXPR$$1, ' ');
1239
+ value = stringReplace(value, MUSTACHE_EXPR$1, ' ');
1240
+ value = stringReplace(value, ERB_EXPR$1, ' ');
1111
1241
  }
1112
-
1113
1242
  /* Is `value` valid for this attribute? */
1243
+
1244
+
1114
1245
  var lcTag = transformCaseFunc(currentNode.nodeName);
1246
+
1115
1247
  if (!_isValidAttribute(lcTag, lcName, value)) {
1116
1248
  continue;
1117
1249
  }
1118
-
1119
1250
  /* Handle invalid data-* attribute set by try-catching it */
1251
+
1252
+
1120
1253
  try {
1121
1254
  if (namespaceURI) {
1122
1255
  currentNode.setAttributeNS(namespaceURI, name, value);
@@ -1128,45 +1261,52 @@ function createDOMPurify() {
1128
1261
  arrayPop(DOMPurify.removed);
1129
1262
  } catch (_) {}
1130
1263
  }
1131
-
1132
1264
  /* Execute a hook if present */
1265
+
1266
+
1133
1267
  _executeHook('afterSanitizeAttributes', currentNode, null);
1134
1268
  };
1135
-
1136
1269
  /**
1137
1270
  * _sanitizeShadowDOM
1138
1271
  *
1139
1272
  * @param {DocumentFragment} fragment to iterate over recursively
1140
1273
  */
1274
+
1275
+
1141
1276
  var _sanitizeShadowDOM = function _sanitizeShadowDOM(fragment) {
1142
- var shadowNode = void 0;
1143
- var shadowIterator = _createIterator(fragment);
1277
+ var shadowNode;
1144
1278
 
1279
+ var shadowIterator = _createIterator(fragment);
1145
1280
  /* Execute a hook if present */
1281
+
1282
+
1146
1283
  _executeHook('beforeSanitizeShadowDOM', fragment, null);
1147
1284
 
1148
1285
  while (shadowNode = shadowIterator.nextNode()) {
1149
1286
  /* Execute a hook if present */
1150
1287
  _executeHook('uponSanitizeShadowNode', shadowNode, null);
1151
-
1152
1288
  /* Sanitize tags and elements */
1289
+
1290
+
1153
1291
  if (_sanitizeElements(shadowNode)) {
1154
1292
  continue;
1155
1293
  }
1156
-
1157
1294
  /* Deep shadow DOM detected */
1295
+
1296
+
1158
1297
  if (shadowNode.content instanceof DocumentFragment) {
1159
1298
  _sanitizeShadowDOM(shadowNode.content);
1160
1299
  }
1161
-
1162
1300
  /* Check attributes, sanitize if necessary */
1301
+
1302
+
1163
1303
  _sanitizeAttributes(shadowNode);
1164
1304
  }
1165
-
1166
1305
  /* Execute a hook if present */
1306
+
1307
+
1167
1308
  _executeHook('afterSanitizeShadowDOM', fragment, null);
1168
1309
  };
1169
-
1170
1310
  /**
1171
1311
  * Sanitize
1172
1312
  * Public method providing core sanitation functionality
@@ -1175,34 +1315,41 @@ function createDOMPurify() {
1175
1315
  * @param {Object} configuration object
1176
1316
  */
1177
1317
  // eslint-disable-next-line complexity
1318
+
1319
+
1178
1320
  DOMPurify.sanitize = function (dirty, cfg) {
1179
- var body = void 0;
1180
- var importedNode = void 0;
1181
- var currentNode = void 0;
1182
- var oldNode = void 0;
1183
- var returnNode = void 0;
1321
+ var body;
1322
+ var importedNode;
1323
+ var currentNode;
1324
+ var oldNode;
1325
+ var returnNode;
1184
1326
  /* Make sure we have a string to sanitize.
1185
1327
  DO NOT return early, as this will return the wrong type if
1186
1328
  the user has requested a DOM object rather than a string */
1329
+
1187
1330
  IS_EMPTY_INPUT = !dirty;
1331
+
1188
1332
  if (IS_EMPTY_INPUT) {
1189
1333
  dirty = '<!-->';
1190
1334
  }
1191
-
1192
1335
  /* Stringify, in case dirty is an object */
1336
+
1337
+
1193
1338
  if (typeof dirty !== 'string' && !_isNode(dirty)) {
1194
1339
  // eslint-disable-next-line no-negated-condition
1195
1340
  if (typeof dirty.toString !== 'function') {
1196
1341
  throw typeErrorCreate('toString is not a function');
1197
1342
  } else {
1198
1343
  dirty = dirty.toString();
1344
+
1199
1345
  if (typeof dirty !== 'string') {
1200
1346
  throw typeErrorCreate('dirty is not a string, aborting');
1201
1347
  }
1202
1348
  }
1203
1349
  }
1204
-
1205
1350
  /* Check we can run. Otherwise fall back or ignore */
1351
+
1352
+
1206
1353
  if (!DOMPurify.isSupported) {
1207
1354
  if (_typeof(window.toStaticHTML) === 'object' || typeof window.toStaticHTML === 'function') {
1208
1355
  if (typeof dirty === 'string') {
@@ -1216,16 +1363,18 @@ function createDOMPurify() {
1216
1363
 
1217
1364
  return dirty;
1218
1365
  }
1219
-
1220
1366
  /* Assign config vars */
1367
+
1368
+
1221
1369
  if (!SET_CONFIG) {
1222
1370
  _parseConfig(cfg);
1223
1371
  }
1224
-
1225
1372
  /* Clean up removed elements */
1226
- DOMPurify.removed = [];
1227
1373
 
1374
+
1375
+ DOMPurify.removed = [];
1228
1376
  /* Check if dirty is correctly typed for IN_PLACE */
1377
+
1229
1378
  if (typeof dirty === 'string') {
1230
1379
  IN_PLACE = false;
1231
1380
  }
@@ -1234,6 +1383,7 @@ function createDOMPurify() {
1234
1383
  /* Do some early pre-sanitization to avoid unsafe root nodes */
1235
1384
  if (dirty.nodeName) {
1236
1385
  var tagName = transformCaseFunc(dirty.nodeName);
1386
+
1237
1387
  if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
1238
1388
  throw typeErrorCreate('root node is forbidden and cannot be sanitized in-place');
1239
1389
  }
@@ -1243,6 +1393,7 @@ function createDOMPurify() {
1243
1393
  elements being stripped by the parser */
1244
1394
  body = _initDocument('<!---->');
1245
1395
  importedNode = body.ownerDocument.importNode(dirty, true);
1396
+
1246
1397
  if (importedNode.nodeType === 1 && importedNode.nodeName === 'BODY') {
1247
1398
  /* Node is already a body, use as is */
1248
1399
  body = importedNode;
@@ -1254,60 +1405,67 @@ function createDOMPurify() {
1254
1405
  }
1255
1406
  } else {
1256
1407
  /* Exit directly if we have nothing to do */
1257
- if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT &&
1258
- // eslint-disable-next-line unicorn/prefer-includes
1408
+ if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT && // eslint-disable-next-line unicorn/prefer-includes
1259
1409
  dirty.indexOf('<') === -1) {
1260
1410
  return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(dirty) : dirty;
1261
1411
  }
1262
-
1263
1412
  /* Initialize the document to work on */
1264
- body = _initDocument(dirty);
1265
1413
 
1414
+
1415
+ body = _initDocument(dirty);
1266
1416
  /* Check we have a DOM node from the data */
1417
+
1267
1418
  if (!body) {
1268
1419
  return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : '';
1269
1420
  }
1270
1421
  }
1271
-
1272
1422
  /* Remove first element node (ours) if FORCE_BODY is set */
1423
+
1424
+
1273
1425
  if (body && FORCE_BODY) {
1274
1426
  _forceRemove(body.firstChild);
1275
1427
  }
1276
-
1277
1428
  /* Get node iterator */
1278
- var nodeIterator = _createIterator(IN_PLACE ? dirty : body);
1279
1429
 
1430
+
1431
+ var nodeIterator = _createIterator(IN_PLACE ? dirty : body);
1280
1432
  /* Now start iterating over the created document */
1433
+
1434
+
1281
1435
  while (currentNode = nodeIterator.nextNode()) {
1282
1436
  /* Fix IE's strange behavior with manipulated textNodes #89 */
1283
1437
  if (currentNode.nodeType === 3 && currentNode === oldNode) {
1284
1438
  continue;
1285
1439
  }
1286
-
1287
1440
  /* Sanitize tags and elements */
1441
+
1442
+
1288
1443
  if (_sanitizeElements(currentNode)) {
1289
1444
  continue;
1290
1445
  }
1291
-
1292
1446
  /* Shadow DOM detected, sanitize it */
1447
+
1448
+
1293
1449
  if (currentNode.content instanceof DocumentFragment) {
1294
1450
  _sanitizeShadowDOM(currentNode.content);
1295
1451
  }
1296
-
1297
1452
  /* Check attributes, sanitize if necessary */
1453
+
1454
+
1298
1455
  _sanitizeAttributes(currentNode);
1299
1456
 
1300
1457
  oldNode = currentNode;
1301
1458
  }
1302
1459
 
1303
1460
  oldNode = null;
1304
-
1305
1461
  /* If we sanitized `dirty` in-place, return it. */
1462
+
1306
1463
  if (IN_PLACE) {
1307
1464
  return dirty;
1308
1465
  }
1309
-
1310
1466
  /* Return sanitized string or DOM */
1467
+
1468
+
1311
1469
  if (RETURN_DOM) {
1312
1470
  if (RETURN_DOM_FRAGMENT) {
1313
1471
  returnNode = createDocumentFragment.call(body.ownerDocument);
@@ -1335,42 +1493,45 @@ function createDOMPurify() {
1335
1493
  }
1336
1494
 
1337
1495
  var serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML;
1338
-
1339
1496
  /* Serialize doctype if allowed */
1497
+
1340
1498
  if (WHOLE_DOCUMENT && ALLOWED_TAGS['!doctype'] && body.ownerDocument && body.ownerDocument.doctype && body.ownerDocument.doctype.name && regExpTest(DOCTYPE_NAME, body.ownerDocument.doctype.name)) {
1341
1499
  serializedHTML = '<!DOCTYPE ' + body.ownerDocument.doctype.name + '>\n' + serializedHTML;
1342
1500
  }
1343
-
1344
1501
  /* Sanitize final string template-safe */
1502
+
1503
+
1345
1504
  if (SAFE_FOR_TEMPLATES) {
1346
- serializedHTML = stringReplace(serializedHTML, MUSTACHE_EXPR$$1, ' ');
1347
- serializedHTML = stringReplace(serializedHTML, ERB_EXPR$$1, ' ');
1505
+ serializedHTML = stringReplace(serializedHTML, MUSTACHE_EXPR$1, ' ');
1506
+ serializedHTML = stringReplace(serializedHTML, ERB_EXPR$1, ' ');
1348
1507
  }
1349
1508
 
1350
1509
  return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(serializedHTML) : serializedHTML;
1351
1510
  };
1352
-
1353
1511
  /**
1354
1512
  * Public method to set the configuration once
1355
1513
  * setConfig
1356
1514
  *
1357
1515
  * @param {Object} cfg configuration object
1358
1516
  */
1517
+
1518
+
1359
1519
  DOMPurify.setConfig = function (cfg) {
1360
1520
  _parseConfig(cfg);
1521
+
1361
1522
  SET_CONFIG = true;
1362
1523
  };
1363
-
1364
1524
  /**
1365
1525
  * Public method to remove the configuration
1366
1526
  * clearConfig
1367
1527
  *
1368
1528
  */
1529
+
1530
+
1369
1531
  DOMPurify.clearConfig = function () {
1370
1532
  CONFIG = null;
1371
1533
  SET_CONFIG = false;
1372
1534
  };
1373
-
1374
1535
  /**
1375
1536
  * Public method to check if an attribute value is valid.
1376
1537
  * Uses last set config, if any. Otherwise, uses config defaults.
@@ -1381,6 +1542,8 @@ function createDOMPurify() {
1381
1542
  * @param {string} value Attribute value.
1382
1543
  * @return {Boolean} Returns true if `value` is valid. Otherwise, returns false.
1383
1544
  */
1545
+
1546
+
1384
1547
  DOMPurify.isValidAttribute = function (tag, attr, value) {
1385
1548
  /* Initialize shared config vars if necessary. */
1386
1549
  if (!CONFIG) {
@@ -1391,7 +1554,6 @@ function createDOMPurify() {
1391
1554
  var lcName = transformCaseFunc(attr);
1392
1555
  return _isValidAttribute(lcTag, lcName, value);
1393
1556
  };
1394
-
1395
1557
  /**
1396
1558
  * AddHook
1397
1559
  * Public method to add DOMPurify hooks
@@ -1399,6 +1561,8 @@ function createDOMPurify() {
1399
1561
  * @param {String} entryPoint entry point for the hook to add
1400
1562
  * @param {Function} hookFunction function to execute
1401
1563
  */
1564
+
1565
+
1402
1566
  DOMPurify.addHook = function (entryPoint, hookFunction) {
1403
1567
  if (typeof hookFunction !== 'function') {
1404
1568
  return;
@@ -1407,37 +1571,41 @@ function createDOMPurify() {
1407
1571
  hooks[entryPoint] = hooks[entryPoint] || [];
1408
1572
  arrayPush(hooks[entryPoint], hookFunction);
1409
1573
  };
1410
-
1411
1574
  /**
1412
1575
  * RemoveHook
1413
1576
  * Public method to remove a DOMPurify hook at a given entryPoint
1414
1577
  * (pops it from the stack of hooks if more are present)
1415
1578
  *
1416
1579
  * @param {String} entryPoint entry point for the hook to remove
1580
+ * @return {Function} removed(popped) hook
1417
1581
  */
1582
+
1583
+
1418
1584
  DOMPurify.removeHook = function (entryPoint) {
1419
1585
  if (hooks[entryPoint]) {
1420
- arrayPop(hooks[entryPoint]);
1586
+ return arrayPop(hooks[entryPoint]);
1421
1587
  }
1422
1588
  };
1423
-
1424
1589
  /**
1425
1590
  * RemoveHooks
1426
1591
  * Public method to remove all DOMPurify hooks at a given entryPoint
1427
1592
  *
1428
1593
  * @param {String} entryPoint entry point for the hooks to remove
1429
1594
  */
1595
+
1596
+
1430
1597
  DOMPurify.removeHooks = function (entryPoint) {
1431
1598
  if (hooks[entryPoint]) {
1432
1599
  hooks[entryPoint] = [];
1433
1600
  }
1434
1601
  };
1435
-
1436
1602
  /**
1437
1603
  * RemoveAllHooks
1438
1604
  * Public method to remove all DOMPurify hooks
1439
1605
  *
1440
1606
  */
1607
+
1608
+
1441
1609
  DOMPurify.removeAllHooks = function () {
1442
1610
  hooks = {};
1443
1611
  };
@@ -1447,5 +1615,5 @@ function createDOMPurify() {
1447
1615
 
1448
1616
  var purify = createDOMPurify();
1449
1617
 
1450
- export default purify;
1618
+ export { purify as default };
1451
1619
  //# sourceMappingURL=purify.es.js.map