dompurify 3.0.5 → 3.0.6

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,4 +1,4 @@
1
- /*! @license DOMPurify 3.0.5 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.0.5/LICENSE */
1
+ /*! @license DOMPurify 3.0.6 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.0.6/LICENSE */
2
2
 
3
3
  'use strict';
4
4
 
@@ -20,12 +20,6 @@ let {
20
20
  construct
21
21
  } = typeof Reflect !== 'undefined' && Reflect;
22
22
 
23
- if (!apply) {
24
- apply = function apply(fun, thisValue, args) {
25
- return fun.apply(thisValue, args);
26
- };
27
- }
28
-
29
23
  if (!freeze) {
30
24
  freeze = function freeze(x) {
31
25
  return x;
@@ -38,6 +32,12 @@ if (!seal) {
38
32
  };
39
33
  }
40
34
 
35
+ if (!apply) {
36
+ apply = function apply(fun, thisValue, args) {
37
+ return fun.apply(thisValue, args);
38
+ };
39
+ }
40
+
41
41
  if (!construct) {
42
42
  construct = function construct(Func, args) {
43
43
  return new Func(...args);
@@ -55,6 +55,13 @@ const stringIndexOf = unapply(String.prototype.indexOf);
55
55
  const stringTrim = unapply(String.prototype.trim);
56
56
  const regExpTest = unapply(RegExp.prototype.test);
57
57
  const typeErrorCreate = unconstruct(TypeError);
58
+ /**
59
+ * Creates a new function that calls the given function with a specified thisArg and arguments.
60
+ *
61
+ * @param {Function} func - The function to be wrapped and called.
62
+ * @returns {Function} A new function that calls the given function with a specified thisArg and arguments.
63
+ */
64
+
58
65
  function unapply(func) {
59
66
  return function (thisArg) {
60
67
  for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
@@ -64,6 +71,14 @@ function unapply(func) {
64
71
  return apply(func, thisArg, args);
65
72
  };
66
73
  }
74
+ /**
75
+ * Creates a new function that constructs an instance of the given constructor function with the provided arguments.
76
+ *
77
+ * @param {Function} func - The constructor function to be wrapped and called.
78
+ * @returns {Function} A new function that constructs an instance of the given constructor function with the provided arguments.
79
+ */
80
+
81
+
67
82
  function unconstruct(func) {
68
83
  return function () {
69
84
  for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
@@ -73,12 +88,18 @@ function unconstruct(func) {
73
88
  return construct(func, args);
74
89
  };
75
90
  }
76
- /* Add properties to a lookup table */
91
+ /**
92
+ * Add properties to a lookup table
93
+ *
94
+ * @param {Object} set - The set to which elements will be added.
95
+ * @param {Array} array - The array containing elements to be added to the set.
96
+ * @param {Function} transformCaseFunc - An optional function to transform the case of each element before adding to the set.
97
+ * @returns {Object} The modified set with added elements.
98
+ */
77
99
 
78
- function addToSet(set, array, transformCaseFunc) {
79
- var _transformCaseFunc;
80
100
 
81
- transformCaseFunc = (_transformCaseFunc = transformCaseFunc) !== null && _transformCaseFunc !== void 0 ? _transformCaseFunc : stringToLowerCase;
101
+ function addToSet(set, array) {
102
+ let transformCaseFunc = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : stringToLowerCase;
82
103
 
83
104
  if (setPrototypeOf) {
84
105
  // Make 'in' and truthy checks like Boolean(set.constructor)
@@ -110,19 +131,32 @@ function addToSet(set, array, transformCaseFunc) {
110
131
 
111
132
  return set;
112
133
  }
113
- /* Shallow clone an object */
134
+ /**
135
+ * Shallow clone an object
136
+ *
137
+ * @param {Object} object - The object to be cloned.
138
+ * @returns {Object} A new object that copies the original.
139
+ */
140
+
114
141
 
115
142
  function clone(object) {
116
143
  const newObject = create(null);
117
144
 
118
145
  for (const [property, value] of entries(object)) {
119
- newObject[property] = value;
146
+ if (getOwnPropertyDescriptor(object, property) !== undefined) {
147
+ newObject[property] = value;
148
+ }
120
149
  }
121
150
 
122
151
  return newObject;
123
152
  }
124
- /* This method automatically checks if the prop is function
125
- * or getter and behaves accordingly. */
153
+ /**
154
+ * This method automatically checks if the prop is function or getter and behaves accordingly.
155
+ *
156
+ * @param {Object} object - The object to look up the getter function in its prototype chain.
157
+ * @param {String} prop - The property name for which to find the getter function.
158
+ * @returns {Function} The getter function found in the prototype chain or a fallback function.
159
+ */
126
160
 
127
161
  function lookupGetter(object, prop) {
128
162
  while (object !== null) {
@@ -197,7 +231,9 @@ var EXPRESSIONS = /*#__PURE__*/Object.freeze({
197
231
  DOCTYPE_NAME: DOCTYPE_NAME
198
232
  });
199
233
 
200
- const getGlobal = () => typeof window === 'undefined' ? null : window;
234
+ const getGlobal = function getGlobal() {
235
+ return typeof window === 'undefined' ? null : window;
236
+ };
201
237
  /**
202
238
  * Creates a no-op policy for internal use only.
203
239
  * Don't export this function outside this module!
@@ -255,7 +291,7 @@ function createDOMPurify() {
255
291
  */
256
292
 
257
293
 
258
- DOMPurify.version = '3.0.5';
294
+ DOMPurify.version = '3.0.6';
259
295
  /**
260
296
  * Array of elements that DOMPurify removed during sanitation.
261
297
  * Empty if nothing was removed.
@@ -270,11 +306,11 @@ function createDOMPurify() {
270
306
  return DOMPurify;
271
307
  }
272
308
 
273
- const originalDocument = window.document;
274
- const currentScript = originalDocument.currentScript;
275
309
  let {
276
310
  document
277
311
  } = window;
312
+ const originalDocument = document;
313
+ const currentScript = originalDocument.currentScript;
278
314
  const {
279
315
  DocumentFragment,
280
316
  HTMLTemplateElement,
@@ -354,7 +390,7 @@ function createDOMPurify() {
354
390
  * @property {boolean} allowCustomizedBuiltInElements allow custom elements derived from built-ins if they pass CUSTOM_ELEMENT_HANDLING.tagNameCheck. Default: `false`.
355
391
  */
356
392
 
357
- let CUSTOM_ELEMENT_HANDLING = Object.seal(Object.create(null, {
393
+ let CUSTOM_ELEMENT_HANDLING = Object.seal(create(null, {
358
394
  tagNameCheck: {
359
395
  writable: true,
360
396
  configurable: false,
@@ -478,10 +514,10 @@ function createDOMPurify() {
478
514
  const DEFAULT_ALLOWED_NAMESPACES = addToSet({}, [MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE], stringToString);
479
515
  /* Parsing of strict XHTML documents */
480
516
 
481
- let PARSER_MEDIA_TYPE;
517
+ let PARSER_MEDIA_TYPE = null;
482
518
  const SUPPORTED_PARSER_MEDIA_TYPES = ['application/xhtml+xml', 'text/html'];
483
519
  const DEFAULT_PARSER_MEDIA_TYPE = 'text/html';
484
- let transformCaseFunc;
520
+ let transformCaseFunc = null;
485
521
  /* Keep a reference to config to pass to hooks */
486
522
 
487
523
  let CONFIG = null;
@@ -502,7 +538,9 @@ function createDOMPurify() {
502
538
  // eslint-disable-next-line complexity
503
539
 
504
540
 
505
- const _parseConfig = function _parseConfig(cfg) {
541
+ const _parseConfig = function _parseConfig() {
542
+ let cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
543
+
506
544
  if (CONFIG && CONFIG === cfg) {
507
545
  return;
508
546
  }
@@ -721,8 +759,6 @@ function createDOMPurify() {
721
759
  const ALL_MATHML_TAGS = addToSet({}, mathMl$1);
722
760
  addToSet(ALL_MATHML_TAGS, mathMlDisallowed);
723
761
  /**
724
- *
725
- *
726
762
  * @param {Element} element a DOM element whose namespace is being checked
727
763
  * @returns {boolean} Return false if the element has a
728
764
  * namespace that a spec-compliant parser would never
@@ -878,8 +914,8 @@ function createDOMPurify() {
878
914
 
879
915
  const _initDocument = function _initDocument(dirty) {
880
916
  /* Create a HTML document */
881
- let doc;
882
- let leadingWhitespace;
917
+ let doc = null;
918
+ let leadingWhitespace = null;
883
919
 
884
920
  if (FORCE_BODY) {
885
921
  dirty = '<remove></remove>' + dirty;
@@ -932,16 +968,16 @@ function createDOMPurify() {
932
968
  return WHOLE_DOCUMENT ? doc.documentElement : body;
933
969
  };
934
970
  /**
935
- * _createIterator
971
+ * Creates a NodeIterator object that you can use to traverse filtered lists of nodes or elements in a document.
936
972
  *
937
- * @param {Document} root document/fragment to create iterator for
938
- * @return {Iterator} iterator instance
973
+ * @param {Node} root The root element or node to start traversing on.
974
+ * @return {NodeIterator} The created NodeIterator
939
975
  */
940
976
 
941
977
 
942
- const _createIterator = function _createIterator(root) {
978
+ const _createNodeIterator = function _createNodeIterator(root) {
943
979
  return createNodeIterator.call(root.ownerDocument || root, root, // eslint-disable-next-line no-bitwise
944
- NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT, null, false);
980
+ NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT, null);
945
981
  };
946
982
  /**
947
983
  * _isClobbered
@@ -955,15 +991,15 @@ function createDOMPurify() {
955
991
  return elm instanceof HTMLFormElement && (typeof elm.nodeName !== 'string' || typeof elm.textContent !== 'string' || typeof elm.removeChild !== 'function' || !(elm.attributes instanceof NamedNodeMap) || typeof elm.removeAttribute !== 'function' || typeof elm.setAttribute !== 'function' || typeof elm.namespaceURI !== 'string' || typeof elm.insertBefore !== 'function' || typeof elm.hasChildNodes !== 'function');
956
992
  };
957
993
  /**
958
- * _isNode
994
+ * Checks whether the given object is a DOM node.
959
995
  *
960
- * @param {Node} obj object to check whether it's a DOM node
996
+ * @param {Node} object object to check whether it's a DOM node
961
997
  * @return {Boolean} true is object is a DOM node
962
998
  */
963
999
 
964
1000
 
965
1001
  const _isNode = function _isNode(object) {
966
- return typeof Node === 'object' ? object instanceof Node : object && typeof object === 'object' && typeof object.nodeType === 'number' && typeof object.nodeName === 'string';
1002
+ return typeof Node === 'function' && object instanceof Node;
967
1003
  };
968
1004
  /**
969
1005
  * _executeHook
@@ -997,7 +1033,7 @@ function createDOMPurify() {
997
1033
 
998
1034
 
999
1035
  const _sanitizeElements = function _sanitizeElements(currentNode) {
1000
- let content;
1036
+ let content = null;
1001
1037
  /* Execute a hook if present */
1002
1038
 
1003
1039
  _executeHook('beforeSanitizeElements', currentNode, null);
@@ -1022,7 +1058,7 @@ function createDOMPurify() {
1022
1058
  /* Detect mXSS attempts abusing namespace confusion */
1023
1059
 
1024
1060
 
1025
- if (currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && (!_isNode(currentNode.content) || !_isNode(currentNode.content.firstElementChild)) && regExpTest(/<[/\w]/g, currentNode.innerHTML) && regExpTest(/<[/\w]/g, currentNode.textContent)) {
1061
+ if (currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(/<[/\w]/g, currentNode.innerHTML) && regExpTest(/<[/\w]/g, currentNode.textContent)) {
1026
1062
  _forceRemove(currentNode);
1027
1063
 
1028
1064
  return true;
@@ -1032,9 +1068,14 @@ function createDOMPurify() {
1032
1068
 
1033
1069
  if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
1034
1070
  /* Check if we have a custom element to handle */
1035
- if (!FORBID_TAGS[tagName] && _basicCustomElementTest(tagName)) {
1036
- if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) return false;
1037
- if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) return false;
1071
+ if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {
1072
+ if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) {
1073
+ return false;
1074
+ }
1075
+
1076
+ if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) {
1077
+ return false;
1078
+ }
1038
1079
  }
1039
1080
  /* Keep content except for bad-listed elements */
1040
1081
 
@@ -1078,9 +1119,9 @@ function createDOMPurify() {
1078
1119
  if (SAFE_FOR_TEMPLATES && currentNode.nodeType === 3) {
1079
1120
  /* Get the element's text content */
1080
1121
  content = currentNode.textContent;
1081
- content = stringReplace(content, MUSTACHE_EXPR, ' ');
1082
- content = stringReplace(content, ERB_EXPR, ' ');
1083
- content = stringReplace(content, TMPLIT_EXPR, ' ');
1122
+ arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
1123
+ content = stringReplace(content, expr, ' ');
1124
+ });
1084
1125
 
1085
1126
  if (currentNode.textContent !== content) {
1086
1127
  arrayPush(DOMPurify.removed, {
@@ -1122,7 +1163,7 @@ function createDOMPurify() {
1122
1163
  if ( // First condition does a very basic check if a) it's basically a valid custom element tagname AND
1123
1164
  // b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
1124
1165
  // and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck
1125
- _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
1166
+ _isBasicCustomElement(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
1126
1167
  // the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
1127
1168
  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 {
1128
1169
  return false;
@@ -1136,14 +1177,16 @@ function createDOMPurify() {
1136
1177
  return true;
1137
1178
  };
1138
1179
  /**
1139
- * _basicCustomElementCheck
1180
+ * _isBasicCustomElement
1140
1181
  * checks if at least one dash is included in tagName, and it's not the first char
1141
1182
  * for more sophisticated checking see https://github.com/sindresorhus/validate-element-name
1183
+ *
1142
1184
  * @param {string} tagName name of the tag of the node to sanitize
1185
+ * @returns {boolean} Returns true if the tag name meets the basic criteria for a custom element, otherwise false.
1143
1186
  */
1144
1187
 
1145
1188
 
1146
- const _basicCustomElementTest = function _basicCustomElementTest(tagName) {
1189
+ const _isBasicCustomElement = function _isBasicCustomElement(tagName) {
1147
1190
  return tagName.indexOf('-') > 0;
1148
1191
  };
1149
1192
  /**
@@ -1159,12 +1202,7 @@ function createDOMPurify() {
1159
1202
 
1160
1203
 
1161
1204
  const _sanitizeAttributes = function _sanitizeAttributes(currentNode) {
1162
- let attr;
1163
- let value;
1164
- let lcName;
1165
- let l;
1166
1205
  /* Execute a hook if present */
1167
-
1168
1206
  _executeHook('beforeSanitizeAttributes', currentNode, null);
1169
1207
 
1170
1208
  const {
@@ -1182,17 +1220,18 @@ function createDOMPurify() {
1182
1220
  keepAttr: true,
1183
1221
  allowedAttributes: ALLOWED_ATTR
1184
1222
  };
1185
- l = attributes.length;
1223
+ let l = attributes.length;
1186
1224
  /* Go backwards over all attributes; safely remove bad ones */
1187
1225
 
1188
1226
  while (l--) {
1189
- attr = attributes[l];
1227
+ const attr = attributes[l];
1190
1228
  const {
1191
1229
  name,
1192
- namespaceURI
1230
+ namespaceURI,
1231
+ value: attrValue
1193
1232
  } = attr;
1194
- value = name === 'value' ? attr.value : stringTrim(attr.value);
1195
- lcName = transformCaseFunc(name);
1233
+ const lcName = transformCaseFunc(name);
1234
+ let value = name === 'value' ? attrValue : stringTrim(attrValue);
1196
1235
  /* Execute a hook if present */
1197
1236
 
1198
1237
  hookEvent.attrName = lcName;
@@ -1230,9 +1269,9 @@ function createDOMPurify() {
1230
1269
 
1231
1270
 
1232
1271
  if (SAFE_FOR_TEMPLATES) {
1233
- value = stringReplace(value, MUSTACHE_EXPR, ' ');
1234
- value = stringReplace(value, ERB_EXPR, ' ');
1235
- value = stringReplace(value, TMPLIT_EXPR, ' ');
1272
+ arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
1273
+ value = stringReplace(value, expr, ' ');
1274
+ });
1236
1275
  }
1237
1276
  /* Is `value` valid for this attribute? */
1238
1277
 
@@ -1301,9 +1340,9 @@ function createDOMPurify() {
1301
1340
 
1302
1341
 
1303
1342
  const _sanitizeShadowDOM = function _sanitizeShadowDOM(fragment) {
1304
- let shadowNode;
1343
+ let shadowNode = null;
1305
1344
 
1306
- const shadowIterator = _createIterator(fragment);
1345
+ const shadowIterator = _createNodeIterator(fragment);
1307
1346
  /* Execute a hook if present */
1308
1347
 
1309
1348
 
@@ -1339,17 +1378,17 @@ function createDOMPurify() {
1339
1378
  * Public method providing core sanitation functionality
1340
1379
  *
1341
1380
  * @param {String|Node} dirty string or DOM node
1342
- * @param {Object} configuration object
1381
+ * @param {Object} cfg object
1343
1382
  */
1344
1383
  // eslint-disable-next-line complexity
1345
1384
 
1346
1385
 
1347
1386
  DOMPurify.sanitize = function (dirty) {
1348
1387
  let cfg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1349
- let body;
1350
- let importedNode;
1351
- let currentNode;
1352
- let returnNode;
1388
+ let body = null;
1389
+ let importedNode = null;
1390
+ let currentNode = null;
1391
+ let returnNode = null;
1353
1392
  /* Make sure we have a string to sanitize.
1354
1393
  DO NOT return early, as this will return the wrong type if
1355
1394
  the user has requested a DOM object rather than a string */
@@ -1444,7 +1483,7 @@ function createDOMPurify() {
1444
1483
  /* Get node iterator */
1445
1484
 
1446
1485
 
1447
- const nodeIterator = _createIterator(IN_PLACE ? dirty : body);
1486
+ const nodeIterator = _createNodeIterator(IN_PLACE ? dirty : body);
1448
1487
  /* Now start iterating over the created document */
1449
1488
 
1450
1489
 
@@ -1509,9 +1548,9 @@ function createDOMPurify() {
1509
1548
 
1510
1549
 
1511
1550
  if (SAFE_FOR_TEMPLATES) {
1512
- serializedHTML = stringReplace(serializedHTML, MUSTACHE_EXPR, ' ');
1513
- serializedHTML = stringReplace(serializedHTML, ERB_EXPR, ' ');
1514
- serializedHTML = stringReplace(serializedHTML, TMPLIT_EXPR, ' ');
1551
+ arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
1552
+ serializedHTML = stringReplace(serializedHTML, expr, ' ');
1553
+ });
1515
1554
  }
1516
1555
 
1517
1556
  return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(serializedHTML) : serializedHTML;
@@ -1524,7 +1563,9 @@ function createDOMPurify() {
1524
1563
  */
1525
1564
 
1526
1565
 
1527
- DOMPurify.setConfig = function (cfg) {
1566
+ DOMPurify.setConfig = function () {
1567
+ let cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1568
+
1528
1569
  _parseConfig(cfg);
1529
1570
 
1530
1571
  SET_CONFIG = true;
@@ -1545,9 +1586,9 @@ function createDOMPurify() {
1545
1586
  * Uses last set config, if any. Otherwise, uses config defaults.
1546
1587
  * isValidAttribute
1547
1588
  *
1548
- * @param {string} tag Tag name of containing element.
1549
- * @param {string} attr Attribute name.
1550
- * @param {string} value Attribute value.
1589
+ * @param {String} tag Tag name of containing element.
1590
+ * @param {String} attr Attribute name.
1591
+ * @param {String} value Attribute value.
1551
1592
  * @return {Boolean} Returns true if `value` is valid. Otherwise, returns false.
1552
1593
  */
1553
1594
 
@@ -1610,7 +1651,6 @@ function createDOMPurify() {
1610
1651
  /**
1611
1652
  * RemoveAllHooks
1612
1653
  * Public method to remove all DOMPurify hooks
1613
- *
1614
1654
  */
1615
1655
 
1616
1656