dompurify 2.3.6 → 2.3.7

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