@carbon/ibmdotcom-utilities 2.23.0 → 2.25.0
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.
|
@@ -4,9 +4,27 @@
|
|
|
4
4
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.IBMDotcomUtilities = {}));
|
|
5
5
|
})(this, (function (exports) { 'use strict';
|
|
6
6
|
|
|
7
|
+
function _arrayLikeToArray(r, a) {
|
|
8
|
+
(null == a || a > r.length) && (a = r.length);
|
|
9
|
+
for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
|
|
10
|
+
return n;
|
|
11
|
+
}
|
|
12
|
+
function _arrayWithHoles(r) {
|
|
13
|
+
if (Array.isArray(r)) return r;
|
|
14
|
+
}
|
|
15
|
+
function _arrayWithoutHoles(r) {
|
|
16
|
+
if (Array.isArray(r)) return _arrayLikeToArray(r);
|
|
17
|
+
}
|
|
7
18
|
function _classCallCheck(a, n) {
|
|
8
19
|
if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function");
|
|
9
20
|
}
|
|
21
|
+
function _construct(t, e, r) {
|
|
22
|
+
if (_isNativeReflectConstruct()) return Reflect.construct.apply(null, arguments);
|
|
23
|
+
var o = [null];
|
|
24
|
+
o.push.apply(o, e);
|
|
25
|
+
var p = new (t.bind.apply(t, o))();
|
|
26
|
+
return r && _setPrototypeOf(p, r.prototype), p;
|
|
27
|
+
}
|
|
10
28
|
function _defineProperties(e, r) {
|
|
11
29
|
for (var t = 0; t < r.length; t++) {
|
|
12
30
|
var o = r[t];
|
|
@@ -18,6 +36,109 @@
|
|
|
18
36
|
writable: !1
|
|
19
37
|
}), e;
|
|
20
38
|
}
|
|
39
|
+
function _createForOfIteratorHelper(r, e) {
|
|
40
|
+
var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
|
|
41
|
+
if (!t) {
|
|
42
|
+
if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) {
|
|
43
|
+
t && (r = t);
|
|
44
|
+
var n = 0,
|
|
45
|
+
F = function () {};
|
|
46
|
+
return {
|
|
47
|
+
s: F,
|
|
48
|
+
n: function () {
|
|
49
|
+
return n >= r.length ? {
|
|
50
|
+
done: !0
|
|
51
|
+
} : {
|
|
52
|
+
done: !1,
|
|
53
|
+
value: r[n++]
|
|
54
|
+
};
|
|
55
|
+
},
|
|
56
|
+
e: function (r) {
|
|
57
|
+
throw r;
|
|
58
|
+
},
|
|
59
|
+
f: F
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
63
|
+
}
|
|
64
|
+
var o,
|
|
65
|
+
a = !0,
|
|
66
|
+
u = !1;
|
|
67
|
+
return {
|
|
68
|
+
s: function () {
|
|
69
|
+
t = t.call(r);
|
|
70
|
+
},
|
|
71
|
+
n: function () {
|
|
72
|
+
var r = t.next();
|
|
73
|
+
return a = r.done, r;
|
|
74
|
+
},
|
|
75
|
+
e: function (r) {
|
|
76
|
+
u = !0, o = r;
|
|
77
|
+
},
|
|
78
|
+
f: function () {
|
|
79
|
+
try {
|
|
80
|
+
a || null == t.return || t.return();
|
|
81
|
+
} finally {
|
|
82
|
+
if (u) throw o;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function _isNativeReflectConstruct() {
|
|
88
|
+
try {
|
|
89
|
+
var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
|
|
90
|
+
} catch (t) {}
|
|
91
|
+
return (_isNativeReflectConstruct = function () {
|
|
92
|
+
return !!t;
|
|
93
|
+
})();
|
|
94
|
+
}
|
|
95
|
+
function _iterableToArray(r) {
|
|
96
|
+
if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r);
|
|
97
|
+
}
|
|
98
|
+
function _iterableToArrayLimit(r, l) {
|
|
99
|
+
var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
|
|
100
|
+
if (null != t) {
|
|
101
|
+
var e,
|
|
102
|
+
n,
|
|
103
|
+
i,
|
|
104
|
+
u,
|
|
105
|
+
a = [],
|
|
106
|
+
f = !0,
|
|
107
|
+
o = !1;
|
|
108
|
+
try {
|
|
109
|
+
if (i = (t = t.call(r)).next, 0 === l) {
|
|
110
|
+
if (Object(t) !== t) return;
|
|
111
|
+
f = !1;
|
|
112
|
+
} else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
|
|
113
|
+
} catch (r) {
|
|
114
|
+
o = !0, n = r;
|
|
115
|
+
} finally {
|
|
116
|
+
try {
|
|
117
|
+
if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
|
|
118
|
+
} finally {
|
|
119
|
+
if (o) throw n;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return a;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
function _nonIterableRest() {
|
|
126
|
+
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
127
|
+
}
|
|
128
|
+
function _nonIterableSpread() {
|
|
129
|
+
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
130
|
+
}
|
|
131
|
+
function _setPrototypeOf(t, e) {
|
|
132
|
+
return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) {
|
|
133
|
+
return t.__proto__ = e, t;
|
|
134
|
+
}, _setPrototypeOf(t, e);
|
|
135
|
+
}
|
|
136
|
+
function _slicedToArray(r, e) {
|
|
137
|
+
return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
|
|
138
|
+
}
|
|
139
|
+
function _toConsumableArray(r) {
|
|
140
|
+
return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread();
|
|
141
|
+
}
|
|
21
142
|
function _toPrimitive(t, r) {
|
|
22
143
|
if ("object" != typeof t || !t) return t;
|
|
23
144
|
var e = t[Symbol.toPrimitive];
|
|
@@ -41,6 +162,13 @@
|
|
|
41
162
|
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
|
|
42
163
|
}, _typeof(o);
|
|
43
164
|
}
|
|
165
|
+
function _unsupportedIterableToArray(r, a) {
|
|
166
|
+
if (r) {
|
|
167
|
+
if ("string" == typeof r) return _arrayLikeToArray(r, a);
|
|
168
|
+
var t = {}.toString.call(r).slice(8, -1);
|
|
169
|
+
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
44
172
|
|
|
45
173
|
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
46
174
|
|
|
@@ -582,80 +710,12 @@
|
|
|
582
710
|
|
|
583
711
|
var purify = {exports: {}};
|
|
584
712
|
|
|
585
|
-
/*! @license DOMPurify 2.5.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.5.6/LICENSE */
|
|
586
713
|
(function (module, exports) {
|
|
587
714
|
(function (global, factory) {
|
|
588
715
|
module.exports = factory() ;
|
|
589
716
|
})(commonjsGlobal, function () {
|
|
590
717
|
|
|
591
|
-
|
|
592
|
-
"@babel/helpers - typeof";
|
|
593
|
-
|
|
594
|
-
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) {
|
|
595
|
-
return typeof obj;
|
|
596
|
-
} : function (obj) {
|
|
597
|
-
return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
|
|
598
|
-
}, _typeof(obj);
|
|
599
|
-
}
|
|
600
|
-
function _setPrototypeOf(o, p) {
|
|
601
|
-
_setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
|
|
602
|
-
o.__proto__ = p;
|
|
603
|
-
return o;
|
|
604
|
-
};
|
|
605
|
-
return _setPrototypeOf(o, p);
|
|
606
|
-
}
|
|
607
|
-
function _isNativeReflectConstruct() {
|
|
608
|
-
if (typeof Reflect === "undefined" || !Reflect.construct) return false;
|
|
609
|
-
if (Reflect.construct.sham) return false;
|
|
610
|
-
if (typeof Proxy === "function") return true;
|
|
611
|
-
try {
|
|
612
|
-
Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
|
|
613
|
-
return true;
|
|
614
|
-
} catch (e) {
|
|
615
|
-
return false;
|
|
616
|
-
}
|
|
617
|
-
}
|
|
618
|
-
function _construct(Parent, args, Class) {
|
|
619
|
-
if (_isNativeReflectConstruct()) {
|
|
620
|
-
_construct = Reflect.construct;
|
|
621
|
-
} else {
|
|
622
|
-
_construct = function _construct(Parent, args, Class) {
|
|
623
|
-
var a = [null];
|
|
624
|
-
a.push.apply(a, args);
|
|
625
|
-
var Constructor = Function.bind.apply(Parent, a);
|
|
626
|
-
var instance = new Constructor();
|
|
627
|
-
if (Class) _setPrototypeOf(instance, Class.prototype);
|
|
628
|
-
return instance;
|
|
629
|
-
};
|
|
630
|
-
}
|
|
631
|
-
return _construct.apply(null, arguments);
|
|
632
|
-
}
|
|
633
|
-
function _toConsumableArray(arr) {
|
|
634
|
-
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
|
|
635
|
-
}
|
|
636
|
-
function _arrayWithoutHoles(arr) {
|
|
637
|
-
if (Array.isArray(arr)) return _arrayLikeToArray(arr);
|
|
638
|
-
}
|
|
639
|
-
function _iterableToArray(iter) {
|
|
640
|
-
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
641
|
-
}
|
|
642
|
-
function _unsupportedIterableToArray(o, minLen) {
|
|
643
|
-
if (!o) return;
|
|
644
|
-
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
|
|
645
|
-
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
646
|
-
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
647
|
-
if (n === "Map" || n === "Set") return Array.from(o);
|
|
648
|
-
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
|
|
649
|
-
}
|
|
650
|
-
function _arrayLikeToArray(arr, len) {
|
|
651
|
-
if (len == null || len > arr.length) len = arr.length;
|
|
652
|
-
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
|
|
653
|
-
return arr2;
|
|
654
|
-
}
|
|
655
|
-
function _nonIterableSpread() {
|
|
656
|
-
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
657
|
-
}
|
|
658
|
-
var hasOwnProperty = Object.hasOwnProperty,
|
|
718
|
+
var entries = Object.entries,
|
|
659
719
|
setPrototypeOf = Object.setPrototypeOf,
|
|
660
720
|
isFrozen = Object.isFrozen,
|
|
661
721
|
getPrototypeOf = Object.getPrototypeOf,
|
|
@@ -666,11 +726,6 @@
|
|
|
666
726
|
var _ref = typeof Reflect !== 'undefined' && Reflect,
|
|
667
727
|
apply = _ref.apply,
|
|
668
728
|
construct = _ref.construct;
|
|
669
|
-
if (!apply) {
|
|
670
|
-
apply = function apply(fun, thisValue, args) {
|
|
671
|
-
return fun.apply(thisValue, args);
|
|
672
|
-
};
|
|
673
|
-
}
|
|
674
729
|
if (!freeze) {
|
|
675
730
|
freeze = function freeze(x) {
|
|
676
731
|
return x;
|
|
@@ -681,30 +736,53 @@
|
|
|
681
736
|
return x;
|
|
682
737
|
};
|
|
683
738
|
}
|
|
739
|
+
if (!apply) {
|
|
740
|
+
apply = function apply(fun, thisValue, args) {
|
|
741
|
+
return fun.apply(thisValue, args);
|
|
742
|
+
};
|
|
743
|
+
}
|
|
684
744
|
if (!construct) {
|
|
685
745
|
construct = function construct(Func, args) {
|
|
686
746
|
return _construct(Func, _toConsumableArray(args));
|
|
687
747
|
};
|
|
688
748
|
}
|
|
689
749
|
var arrayForEach = unapply(Array.prototype.forEach);
|
|
750
|
+
var arrayLastIndexOf = unapply(Array.prototype.lastIndexOf);
|
|
690
751
|
var arrayPop = unapply(Array.prototype.pop);
|
|
691
752
|
var arrayPush = unapply(Array.prototype.push);
|
|
753
|
+
var arraySplice = unapply(Array.prototype.splice);
|
|
692
754
|
var stringToLowerCase = unapply(String.prototype.toLowerCase);
|
|
693
755
|
var stringToString = unapply(String.prototype.toString);
|
|
694
756
|
var stringMatch = unapply(String.prototype.match);
|
|
695
757
|
var stringReplace = unapply(String.prototype.replace);
|
|
696
758
|
var stringIndexOf = unapply(String.prototype.indexOf);
|
|
697
759
|
var stringTrim = unapply(String.prototype.trim);
|
|
760
|
+
var objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty);
|
|
698
761
|
var regExpTest = unapply(RegExp.prototype.test);
|
|
699
762
|
var typeErrorCreate = unconstruct(TypeError);
|
|
763
|
+
/**
|
|
764
|
+
* Creates a new function that calls the given function with a specified thisArg and arguments.
|
|
765
|
+
*
|
|
766
|
+
* @param func - The function to be wrapped and called.
|
|
767
|
+
* @returns A new function that calls the given function with a specified thisArg and arguments.
|
|
768
|
+
*/
|
|
700
769
|
function unapply(func) {
|
|
701
770
|
return function (thisArg) {
|
|
771
|
+
if (thisArg instanceof RegExp) {
|
|
772
|
+
thisArg.lastIndex = 0;
|
|
773
|
+
}
|
|
702
774
|
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
703
775
|
args[_key - 1] = arguments[_key];
|
|
704
776
|
}
|
|
705
777
|
return apply(func, thisArg, args);
|
|
706
778
|
};
|
|
707
779
|
}
|
|
780
|
+
/**
|
|
781
|
+
* Creates a new function that constructs an instance of the given constructor function with the provided arguments.
|
|
782
|
+
*
|
|
783
|
+
* @param func - The constructor function to be wrapped and called.
|
|
784
|
+
* @returns A new function that constructs an instance of the given constructor function with the provided arguments.
|
|
785
|
+
*/
|
|
708
786
|
function unconstruct(func) {
|
|
709
787
|
return function () {
|
|
710
788
|
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
@@ -713,11 +791,16 @@
|
|
|
713
791
|
return construct(func, args);
|
|
714
792
|
};
|
|
715
793
|
}
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
794
|
+
/**
|
|
795
|
+
* Add properties to a lookup table
|
|
796
|
+
*
|
|
797
|
+
* @param set - The set to which elements will be added.
|
|
798
|
+
* @param array - The array containing elements to be added to the set.
|
|
799
|
+
* @param transformCaseFunc - An optional function to transform the case of each element before adding to the set.
|
|
800
|
+
* @returns The modified set with added elements.
|
|
801
|
+
*/
|
|
802
|
+
function addToSet(set, array) {
|
|
803
|
+
var transformCaseFunc = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : stringToLowerCase;
|
|
721
804
|
if (setPrototypeOf) {
|
|
722
805
|
// Make 'in' and truthy checks like Boolean(set.constructor)
|
|
723
806
|
// independent of any properties defined on Object.prototype.
|
|
@@ -741,23 +824,61 @@
|
|
|
741
824
|
}
|
|
742
825
|
return set;
|
|
743
826
|
}
|
|
744
|
-
|
|
745
|
-
|
|
827
|
+
/**
|
|
828
|
+
* Clean up an array to harden against CSPP
|
|
829
|
+
*
|
|
830
|
+
* @param array - The array to be cleaned.
|
|
831
|
+
* @returns The cleaned version of the array
|
|
832
|
+
*/
|
|
833
|
+
function cleanArray(array) {
|
|
834
|
+
for (var index = 0; index < array.length; index++) {
|
|
835
|
+
var isPropertyExist = objectHasOwnProperty(array, index);
|
|
836
|
+
if (!isPropertyExist) {
|
|
837
|
+
array[index] = null;
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
return array;
|
|
841
|
+
}
|
|
842
|
+
/**
|
|
843
|
+
* Shallow clone an object
|
|
844
|
+
*
|
|
845
|
+
* @param object - The object to be cloned.
|
|
846
|
+
* @returns A new object that copies the original.
|
|
847
|
+
*/
|
|
746
848
|
function clone(object) {
|
|
747
849
|
var newObject = create(null);
|
|
748
|
-
var
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
850
|
+
var _iterator = _createForOfIteratorHelper(entries(object)),
|
|
851
|
+
_step;
|
|
852
|
+
try {
|
|
853
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
854
|
+
var _step$value = _slicedToArray(_step.value, 2),
|
|
855
|
+
property = _step$value[0],
|
|
856
|
+
value = _step$value[1];
|
|
857
|
+
var isPropertyExist = objectHasOwnProperty(object, property);
|
|
858
|
+
if (isPropertyExist) {
|
|
859
|
+
if (Array.isArray(value)) {
|
|
860
|
+
newObject[property] = cleanArray(value);
|
|
861
|
+
} else if (value && _typeof(value) === 'object' && value.constructor === Object) {
|
|
862
|
+
newObject[property] = clone(value);
|
|
863
|
+
} else {
|
|
864
|
+
newObject[property] = value;
|
|
865
|
+
}
|
|
866
|
+
}
|
|
752
867
|
}
|
|
868
|
+
} catch (err) {
|
|
869
|
+
_iterator.e(err);
|
|
870
|
+
} finally {
|
|
871
|
+
_iterator.f();
|
|
753
872
|
}
|
|
754
873
|
return newObject;
|
|
755
874
|
}
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
*
|
|
759
|
-
*
|
|
760
|
-
*
|
|
875
|
+
/**
|
|
876
|
+
* This method automatically checks if the prop is function or getter and behaves accordingly.
|
|
877
|
+
*
|
|
878
|
+
* @param object - The object to look up the getter function in its prototype chain.
|
|
879
|
+
* @param prop - The property name for which to find the getter function.
|
|
880
|
+
* @returns The getter function found in the prototype chain or a fallback function.
|
|
881
|
+
*/
|
|
761
882
|
function lookupGetter(object, prop) {
|
|
762
883
|
while (object !== null) {
|
|
763
884
|
var desc = getOwnPropertyDescriptor(object, prop);
|
|
@@ -771,71 +892,96 @@
|
|
|
771
892
|
}
|
|
772
893
|
object = getPrototypeOf(object);
|
|
773
894
|
}
|
|
774
|
-
function fallbackValue(
|
|
775
|
-
console.warn('fallback value for', element);
|
|
895
|
+
function fallbackValue() {
|
|
776
896
|
return null;
|
|
777
897
|
}
|
|
778
898
|
return fallbackValue;
|
|
779
899
|
}
|
|
780
900
|
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']);
|
|
781
|
-
|
|
782
|
-
// SVG
|
|
783
901
|
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']);
|
|
784
|
-
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']);
|
|
785
|
-
|
|
902
|
+
var svgFilters = freeze(['feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight', 'feDropShadow', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence']);
|
|
786
903
|
// List of SVG elements that are disallowed by default.
|
|
787
904
|
// We still need to know them so that we can do namespace
|
|
788
905
|
// checks properly in case one wants to add them to
|
|
789
906
|
// allow-list.
|
|
790
|
-
var svgDisallowed = freeze(['animate', 'color-profile', 'cursor', 'discard', '
|
|
791
|
-
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']);
|
|
792
|
-
|
|
907
|
+
var svgDisallowed = freeze(['animate', 'color-profile', 'cursor', 'discard', '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']);
|
|
908
|
+
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', 'mprescripts']);
|
|
793
909
|
// Similarly to SVG, we want to know all MathML elements,
|
|
794
910
|
// even those that we disallow by default.
|
|
795
911
|
var mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']);
|
|
796
912
|
var text = freeze(['#text']);
|
|
797
|
-
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']);
|
|
798
|
-
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']);
|
|
913
|
+
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', 'popover', 'popovertarget', 'popovertargetaction', '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', 'wrap', 'xmlns', 'slot']);
|
|
914
|
+
var svg = freeze(['accent-height', 'accumulate', 'additive', 'alignment-baseline', 'amplitude', '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', 'exponent', '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', 'intercept', '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', 'slope', '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', 'tablevalues', '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']);
|
|
799
915
|
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']);
|
|
800
916
|
var xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']);
|
|
801
917
|
|
|
802
918
|
// eslint-disable-next-line unicorn/better-regex
|
|
803
919
|
var MUSTACHE_EXPR = seal(/\{\{[\w\W]*|[\w\W]*\}\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode
|
|
804
920
|
var ERB_EXPR = seal(/<%[\w\W]*|[\w\W]*%>/gm);
|
|
805
|
-
var TMPLIT_EXPR = seal(
|
|
806
|
-
var DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]
|
|
921
|
+
var TMPLIT_EXPR = seal(/\$\{[\w\W]*/gm); // eslint-disable-line unicorn/better-regex
|
|
922
|
+
var DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]+$/); // eslint-disable-line no-useless-escape
|
|
807
923
|
var ARIA_ATTR = seal(/^aria-[\-\w]+$/); // eslint-disable-line no-useless-escape
|
|
808
|
-
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
|
|
924
|
+
var IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i // eslint-disable-line no-useless-escape
|
|
809
925
|
);
|
|
810
926
|
var IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i);
|
|
811
927
|
var ATTR_WHITESPACE = seal(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g // eslint-disable-line no-control-regex
|
|
812
928
|
);
|
|
813
929
|
var DOCTYPE_NAME = seal(/^html$/i);
|
|
814
930
|
var CUSTOM_ELEMENT = seal(/^[a-z][.\w]*(-[.\w]+)+$/i);
|
|
931
|
+
var EXPRESSIONS = /*#__PURE__*/Object.freeze({
|
|
932
|
+
__proto__: null,
|
|
933
|
+
ARIA_ATTR: ARIA_ATTR,
|
|
934
|
+
ATTR_WHITESPACE: ATTR_WHITESPACE,
|
|
935
|
+
CUSTOM_ELEMENT: CUSTOM_ELEMENT,
|
|
936
|
+
DATA_ATTR: DATA_ATTR,
|
|
937
|
+
DOCTYPE_NAME: DOCTYPE_NAME,
|
|
938
|
+
ERB_EXPR: ERB_EXPR,
|
|
939
|
+
IS_ALLOWED_URI: IS_ALLOWED_URI,
|
|
940
|
+
IS_SCRIPT_OR_DATA: IS_SCRIPT_OR_DATA,
|
|
941
|
+
MUSTACHE_EXPR: MUSTACHE_EXPR,
|
|
942
|
+
TMPLIT_EXPR: TMPLIT_EXPR
|
|
943
|
+
});
|
|
944
|
+
|
|
945
|
+
/* eslint-disable @typescript-eslint/indent */
|
|
946
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType
|
|
947
|
+
var NODE_TYPE = {
|
|
948
|
+
element: 1,
|
|
949
|
+
attribute: 2,
|
|
950
|
+
text: 3,
|
|
951
|
+
cdataSection: 4,
|
|
952
|
+
entityReference: 5,
|
|
953
|
+
// Deprecated
|
|
954
|
+
entityNode: 6,
|
|
955
|
+
// Deprecated
|
|
956
|
+
progressingInstruction: 7,
|
|
957
|
+
comment: 8,
|
|
958
|
+
document: 9,
|
|
959
|
+
documentType: 10,
|
|
960
|
+
documentFragment: 11,
|
|
961
|
+
notation: 12 // Deprecated
|
|
962
|
+
};
|
|
815
963
|
var getGlobal = function getGlobal() {
|
|
816
964
|
return typeof window === 'undefined' ? null : window;
|
|
817
965
|
};
|
|
818
|
-
|
|
819
966
|
/**
|
|
820
967
|
* Creates a no-op policy for internal use only.
|
|
821
968
|
* Don't export this function outside this module!
|
|
822
|
-
* @param
|
|
823
|
-
* @param
|
|
824
|
-
* @return
|
|
825
|
-
* are not supported).
|
|
969
|
+
* @param trustedTypes The policy factory.
|
|
970
|
+
* @param purifyHostElement The Script element used to load DOMPurify (to determine policy name suffix).
|
|
971
|
+
* @return The policy created (or null, if Trusted Types
|
|
972
|
+
* are not supported or creating the policy failed).
|
|
826
973
|
*/
|
|
827
|
-
var _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes,
|
|
974
|
+
var _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes, purifyHostElement) {
|
|
828
975
|
if (_typeof(trustedTypes) !== 'object' || typeof trustedTypes.createPolicy !== 'function') {
|
|
829
976
|
return null;
|
|
830
977
|
}
|
|
831
|
-
|
|
832
978
|
// Allow the callers to control the unique policy name
|
|
833
979
|
// by adding a data-tt-policy-suffix to the script element with the DOMPurify.
|
|
834
980
|
// Policy creation with duplicate names throws in Trusted Types.
|
|
835
981
|
var suffix = null;
|
|
836
982
|
var ATTR_NAME = 'data-tt-policy-suffix';
|
|
837
|
-
if (
|
|
838
|
-
suffix =
|
|
983
|
+
if (purifyHostElement && purifyHostElement.hasAttribute(ATTR_NAME)) {
|
|
984
|
+
suffix = purifyHostElement.getAttribute(ATTR_NAME);
|
|
839
985
|
}
|
|
840
986
|
var policyName = 'dompurify' + (suffix ? '#' + suffix : '');
|
|
841
987
|
try {
|
|
@@ -855,31 +1001,35 @@
|
|
|
855
1001
|
return null;
|
|
856
1002
|
}
|
|
857
1003
|
};
|
|
1004
|
+
var _createHooksMap = function _createHooksMap() {
|
|
1005
|
+
return {
|
|
1006
|
+
afterSanitizeAttributes: [],
|
|
1007
|
+
afterSanitizeElements: [],
|
|
1008
|
+
afterSanitizeShadowDOM: [],
|
|
1009
|
+
beforeSanitizeAttributes: [],
|
|
1010
|
+
beforeSanitizeElements: [],
|
|
1011
|
+
beforeSanitizeShadowDOM: [],
|
|
1012
|
+
uponSanitizeAttribute: [],
|
|
1013
|
+
uponSanitizeElement: [],
|
|
1014
|
+
uponSanitizeShadowNode: []
|
|
1015
|
+
};
|
|
1016
|
+
};
|
|
858
1017
|
function createDOMPurify() {
|
|
859
1018
|
var window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal();
|
|
860
1019
|
var DOMPurify = function DOMPurify(root) {
|
|
861
1020
|
return createDOMPurify(root);
|
|
862
1021
|
};
|
|
863
|
-
|
|
864
|
-
/**
|
|
865
|
-
* Version label, exposed for easier checks
|
|
866
|
-
* if DOMPurify is up to date or not
|
|
867
|
-
*/
|
|
868
|
-
DOMPurify.version = '2.5.6';
|
|
869
|
-
|
|
870
|
-
/**
|
|
871
|
-
* Array of elements that DOMPurify removed during sanitation.
|
|
872
|
-
* Empty if nothing was removed.
|
|
873
|
-
*/
|
|
1022
|
+
DOMPurify.version = '3.2.5';
|
|
874
1023
|
DOMPurify.removed = [];
|
|
875
|
-
if (!window || !window.document || window.document.nodeType !==
|
|
1024
|
+
if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document || !window.Element) {
|
|
876
1025
|
// Not running in a browser, provide a factory function
|
|
877
1026
|
// so that you can pass your own Window
|
|
878
1027
|
DOMPurify.isSupported = false;
|
|
879
1028
|
return DOMPurify;
|
|
880
1029
|
}
|
|
881
|
-
var originalDocument = window.document;
|
|
882
1030
|
var document = window.document;
|
|
1031
|
+
var originalDocument = document;
|
|
1032
|
+
var currentScript = originalDocument.currentScript;
|
|
883
1033
|
var DocumentFragment = window.DocumentFragment,
|
|
884
1034
|
HTMLTemplateElement = window.HTMLTemplateElement,
|
|
885
1035
|
Node = window.Node,
|
|
@@ -892,10 +1042,10 @@
|
|
|
892
1042
|
trustedTypes = window.trustedTypes;
|
|
893
1043
|
var ElementPrototype = Element.prototype;
|
|
894
1044
|
var cloneNode = lookupGetter(ElementPrototype, 'cloneNode');
|
|
1045
|
+
var remove = lookupGetter(ElementPrototype, 'remove');
|
|
895
1046
|
var getNextSibling = lookupGetter(ElementPrototype, 'nextSibling');
|
|
896
1047
|
var getChildNodes = lookupGetter(ElementPrototype, 'childNodes');
|
|
897
1048
|
var getParentNode = lookupGetter(ElementPrototype, 'parentNode');
|
|
898
|
-
|
|
899
1049
|
// As per issue #47, the web-components registry is inherited by a
|
|
900
1050
|
// new document created via createHTMLDocument. As per the spec
|
|
901
1051
|
// (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries)
|
|
@@ -908,54 +1058,45 @@
|
|
|
908
1058
|
document = template.content.ownerDocument;
|
|
909
1059
|
}
|
|
910
1060
|
}
|
|
911
|
-
var trustedTypesPolicy
|
|
912
|
-
var emptyHTML =
|
|
1061
|
+
var trustedTypesPolicy;
|
|
1062
|
+
var emptyHTML = '';
|
|
913
1063
|
var _document = document,
|
|
914
1064
|
implementation = _document.implementation,
|
|
915
1065
|
createNodeIterator = _document.createNodeIterator,
|
|
916
1066
|
createDocumentFragment = _document.createDocumentFragment,
|
|
917
1067
|
getElementsByTagName = _document.getElementsByTagName;
|
|
918
1068
|
var importNode = originalDocument.importNode;
|
|
919
|
-
var
|
|
920
|
-
try {
|
|
921
|
-
documentMode = clone(document).documentMode ? document.documentMode : {};
|
|
922
|
-
} catch (_) {}
|
|
923
|
-
var hooks = {};
|
|
924
|
-
|
|
1069
|
+
var hooks = _createHooksMap();
|
|
925
1070
|
/**
|
|
926
1071
|
* Expose whether this browser supports running the full DOMPurify.
|
|
927
1072
|
*/
|
|
928
|
-
DOMPurify.isSupported = typeof getParentNode === 'function' && implementation && implementation.createHTMLDocument !== undefined
|
|
929
|
-
var MUSTACHE_EXPR
|
|
930
|
-
ERB_EXPR
|
|
931
|
-
TMPLIT_EXPR
|
|
932
|
-
DATA_ATTR
|
|
933
|
-
ARIA_ATTR
|
|
934
|
-
IS_SCRIPT_OR_DATA
|
|
935
|
-
ATTR_WHITESPACE
|
|
936
|
-
CUSTOM_ELEMENT
|
|
937
|
-
var IS_ALLOWED_URI$1 = IS_ALLOWED_URI;
|
|
938
|
-
|
|
1073
|
+
DOMPurify.isSupported = typeof entries === 'function' && typeof getParentNode === 'function' && implementation && implementation.createHTMLDocument !== undefined;
|
|
1074
|
+
var MUSTACHE_EXPR = EXPRESSIONS.MUSTACHE_EXPR,
|
|
1075
|
+
ERB_EXPR = EXPRESSIONS.ERB_EXPR,
|
|
1076
|
+
TMPLIT_EXPR = EXPRESSIONS.TMPLIT_EXPR,
|
|
1077
|
+
DATA_ATTR = EXPRESSIONS.DATA_ATTR,
|
|
1078
|
+
ARIA_ATTR = EXPRESSIONS.ARIA_ATTR,
|
|
1079
|
+
IS_SCRIPT_OR_DATA = EXPRESSIONS.IS_SCRIPT_OR_DATA,
|
|
1080
|
+
ATTR_WHITESPACE = EXPRESSIONS.ATTR_WHITESPACE,
|
|
1081
|
+
CUSTOM_ELEMENT = EXPRESSIONS.CUSTOM_ELEMENT;
|
|
1082
|
+
var IS_ALLOWED_URI$1 = EXPRESSIONS.IS_ALLOWED_URI;
|
|
939
1083
|
/**
|
|
940
1084
|
* We consider the elements and attributes below to be safe. Ideally
|
|
941
1085
|
* don't add any new ones but feel free to remove unwanted ones.
|
|
942
1086
|
*/
|
|
943
|
-
|
|
944
1087
|
/* allowed element names */
|
|
945
1088
|
var ALLOWED_TAGS = null;
|
|
946
1089
|
var DEFAULT_ALLOWED_TAGS = addToSet({}, [].concat(_toConsumableArray(html$1), _toConsumableArray(svg$1), _toConsumableArray(svgFilters), _toConsumableArray(mathMl$1), _toConsumableArray(text)));
|
|
947
|
-
|
|
948
1090
|
/* Allowed attribute names */
|
|
949
1091
|
var ALLOWED_ATTR = null;
|
|
950
1092
|
var DEFAULT_ALLOWED_ATTR = addToSet({}, [].concat(_toConsumableArray(html), _toConsumableArray(svg), _toConsumableArray(mathMl), _toConsumableArray(xml)));
|
|
951
|
-
|
|
952
1093
|
/*
|
|
953
|
-
* Configure how
|
|
1094
|
+
* Configure how DOMPurify should handle custom elements and their attributes as well as customized built-in elements.
|
|
954
1095
|
* @property {RegExp|Function|null} tagNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any custom elements)
|
|
955
1096
|
* @property {RegExp|Function|null} attributeNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any attributes not on the allow list)
|
|
956
1097
|
* @property {boolean} allowCustomizedBuiltInElements allow custom elements derived from built-ins if they pass CUSTOM_ELEMENT_HANDLING.tagNameCheck. Default: `false`.
|
|
957
1098
|
*/
|
|
958
|
-
var CUSTOM_ELEMENT_HANDLING = Object.seal(
|
|
1099
|
+
var CUSTOM_ELEMENT_HANDLING = Object.seal(create(null, {
|
|
959
1100
|
tagNameCheck: {
|
|
960
1101
|
writable: true,
|
|
961
1102
|
configurable: false,
|
|
@@ -975,65 +1116,49 @@
|
|
|
975
1116
|
value: false
|
|
976
1117
|
}
|
|
977
1118
|
}));
|
|
978
|
-
|
|
979
1119
|
/* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */
|
|
980
1120
|
var FORBID_TAGS = null;
|
|
981
|
-
|
|
982
1121
|
/* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */
|
|
983
1122
|
var FORBID_ATTR = null;
|
|
984
|
-
|
|
985
1123
|
/* Decide if ARIA attributes are okay */
|
|
986
1124
|
var ALLOW_ARIA_ATTR = true;
|
|
987
|
-
|
|
988
1125
|
/* Decide if custom data attributes are okay */
|
|
989
1126
|
var ALLOW_DATA_ATTR = true;
|
|
990
|
-
|
|
991
1127
|
/* Decide if unknown protocols are okay */
|
|
992
1128
|
var ALLOW_UNKNOWN_PROTOCOLS = false;
|
|
993
|
-
|
|
994
1129
|
/* Decide if self-closing tags in attributes are allowed.
|
|
995
1130
|
* Usually removed due to a mXSS issue in jQuery 3.0 */
|
|
996
1131
|
var ALLOW_SELF_CLOSE_IN_ATTR = true;
|
|
997
|
-
|
|
998
1132
|
/* Output should be safe for common template engines.
|
|
999
1133
|
* This means, DOMPurify removes data attributes, mustaches and ERB
|
|
1000
1134
|
*/
|
|
1001
1135
|
var SAFE_FOR_TEMPLATES = false;
|
|
1002
|
-
|
|
1003
1136
|
/* Output should be safe even for XML used within HTML and alike.
|
|
1004
1137
|
* This means, DOMPurify removes comments when containing risky content.
|
|
1005
1138
|
*/
|
|
1006
1139
|
var SAFE_FOR_XML = true;
|
|
1007
|
-
|
|
1008
1140
|
/* Decide if document with <html>... should be returned */
|
|
1009
1141
|
var WHOLE_DOCUMENT = false;
|
|
1010
|
-
|
|
1011
1142
|
/* Track whether config is already set on this instance of DOMPurify. */
|
|
1012
1143
|
var SET_CONFIG = false;
|
|
1013
|
-
|
|
1014
1144
|
/* Decide if all elements (e.g. style, script) must be children of
|
|
1015
1145
|
* document.body. By default, browsers might move them to document.head */
|
|
1016
1146
|
var FORCE_BODY = false;
|
|
1017
|
-
|
|
1018
1147
|
/* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html
|
|
1019
1148
|
* string (or a TrustedHTML object if Trusted Types are supported).
|
|
1020
1149
|
* If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead
|
|
1021
1150
|
*/
|
|
1022
1151
|
var RETURN_DOM = false;
|
|
1023
|
-
|
|
1024
1152
|
/* Decide if a DOM `DocumentFragment` should be returned, instead of a html
|
|
1025
1153
|
* string (or a TrustedHTML object if Trusted Types are supported) */
|
|
1026
1154
|
var RETURN_DOM_FRAGMENT = false;
|
|
1027
|
-
|
|
1028
1155
|
/* Try to return a Trusted Type object instead of a string, return a string in
|
|
1029
1156
|
* case Trusted Types are not supported */
|
|
1030
1157
|
var RETURN_TRUSTED_TYPE = false;
|
|
1031
|
-
|
|
1032
1158
|
/* Output should be free from DOM clobbering attacks?
|
|
1033
1159
|
* This sanitizes markups named with colliding, clobberable built-in DOM APIs.
|
|
1034
1160
|
*/
|
|
1035
1161
|
var SANITIZE_DOM = true;
|
|
1036
|
-
|
|
1037
1162
|
/* Achieve full DOM Clobbering protection by isolating the namespace of named
|
|
1038
1163
|
* properties and JS variables, mitigating attacks that abuse the HTML/DOM spec rules.
|
|
1039
1164
|
*
|
|
@@ -1049,25 +1174,19 @@
|
|
|
1049
1174
|
*/
|
|
1050
1175
|
var SANITIZE_NAMED_PROPS = false;
|
|
1051
1176
|
var SANITIZE_NAMED_PROPS_PREFIX = 'user-content-';
|
|
1052
|
-
|
|
1053
1177
|
/* Keep element content when removing element? */
|
|
1054
1178
|
var KEEP_CONTENT = true;
|
|
1055
|
-
|
|
1056
1179
|
/* If a `Node` is passed to sanitize(), then performs sanitization in-place instead
|
|
1057
1180
|
* of importing it into a new Document and returning a sanitized copy */
|
|
1058
1181
|
var IN_PLACE = false;
|
|
1059
|
-
|
|
1060
1182
|
/* Allow usage of profiles like html, svg and mathMl */
|
|
1061
1183
|
var USE_PROFILES = {};
|
|
1062
|
-
|
|
1063
1184
|
/* Tags to ignore content of when KEEP_CONTENT is true */
|
|
1064
1185
|
var FORBID_CONTENTS = null;
|
|
1065
1186
|
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']);
|
|
1066
|
-
|
|
1067
1187
|
/* Tags that are safe for data: URIs */
|
|
1068
1188
|
var DATA_URI_TAGS = null;
|
|
1069
1189
|
var DEFAULT_DATA_URI_TAGS = addToSet({}, ['audio', 'video', 'img', 'source', 'image', 'track']);
|
|
1070
|
-
|
|
1071
1190
|
/* Attributes safe for values like "javascript:" */
|
|
1072
1191
|
var URI_SAFE_ATTRIBUTES = null;
|
|
1073
1192
|
var DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ['alt', 'class', 'for', 'id', 'label', 'name', 'pattern', 'placeholder', 'role', 'summary', 'title', 'value', 'style', 'xmlns']);
|
|
@@ -1077,75 +1196,61 @@
|
|
|
1077
1196
|
/* Document namespace */
|
|
1078
1197
|
var NAMESPACE = HTML_NAMESPACE;
|
|
1079
1198
|
var IS_EMPTY_INPUT = false;
|
|
1080
|
-
|
|
1081
1199
|
/* Allowed XHTML+XML namespaces */
|
|
1082
1200
|
var ALLOWED_NAMESPACES = null;
|
|
1083
1201
|
var DEFAULT_ALLOWED_NAMESPACES = addToSet({}, [MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE], stringToString);
|
|
1084
|
-
|
|
1202
|
+
var MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ['mi', 'mo', 'mn', 'ms', 'mtext']);
|
|
1203
|
+
var HTML_INTEGRATION_POINTS = addToSet({}, ['annotation-xml']);
|
|
1204
|
+
// Certain elements are allowed in both SVG and HTML
|
|
1205
|
+
// namespace. We need to specify them explicitly
|
|
1206
|
+
// so that they don't get erroneously deleted from
|
|
1207
|
+
// HTML namespace.
|
|
1208
|
+
var COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, ['title', 'style', 'font', 'a', 'script']);
|
|
1085
1209
|
/* Parsing of strict XHTML documents */
|
|
1086
|
-
var PARSER_MEDIA_TYPE;
|
|
1210
|
+
var PARSER_MEDIA_TYPE = null;
|
|
1087
1211
|
var SUPPORTED_PARSER_MEDIA_TYPES = ['application/xhtml+xml', 'text/html'];
|
|
1088
1212
|
var DEFAULT_PARSER_MEDIA_TYPE = 'text/html';
|
|
1089
|
-
var transformCaseFunc;
|
|
1090
|
-
|
|
1213
|
+
var transformCaseFunc = null;
|
|
1091
1214
|
/* Keep a reference to config to pass to hooks */
|
|
1092
1215
|
var CONFIG = null;
|
|
1093
|
-
|
|
1094
1216
|
/* Ideally, do not touch anything below this line */
|
|
1095
1217
|
/* ______________________________________________ */
|
|
1096
|
-
|
|
1097
1218
|
var formElement = document.createElement('form');
|
|
1098
1219
|
var isRegexOrFunction = function isRegexOrFunction(testValue) {
|
|
1099
1220
|
return testValue instanceof RegExp || testValue instanceof Function;
|
|
1100
1221
|
};
|
|
1101
|
-
|
|
1102
1222
|
/**
|
|
1103
1223
|
* _parseConfig
|
|
1104
1224
|
*
|
|
1105
|
-
* @param
|
|
1225
|
+
* @param cfg optional config literal
|
|
1106
1226
|
*/
|
|
1107
1227
|
// eslint-disable-next-line complexity
|
|
1108
|
-
var _parseConfig = function _parseConfig(
|
|
1228
|
+
var _parseConfig = function _parseConfig() {
|
|
1229
|
+
var cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
1109
1230
|
if (CONFIG && CONFIG === cfg) {
|
|
1110
1231
|
return;
|
|
1111
1232
|
}
|
|
1112
|
-
|
|
1113
1233
|
/* Shield configuration object from tampering */
|
|
1114
1234
|
if (!cfg || _typeof(cfg) !== 'object') {
|
|
1115
1235
|
cfg = {};
|
|
1116
1236
|
}
|
|
1117
|
-
|
|
1118
1237
|
/* Shield configuration object from prototype pollution */
|
|
1119
1238
|
cfg = clone(cfg);
|
|
1120
1239
|
PARSER_MEDIA_TYPE =
|
|
1121
1240
|
// eslint-disable-next-line unicorn/prefer-includes
|
|
1122
|
-
SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ?
|
|
1123
|
-
|
|
1241
|
+
SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? DEFAULT_PARSER_MEDIA_TYPE : cfg.PARSER_MEDIA_TYPE;
|
|
1124
1242
|
// HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is.
|
|
1125
1243
|
transformCaseFunc = PARSER_MEDIA_TYPE === 'application/xhtml+xml' ? stringToString : stringToLowerCase;
|
|
1126
|
-
|
|
1127
1244
|
/* Set configuration parameters */
|
|
1128
|
-
ALLOWED_TAGS = 'ALLOWED_TAGS'
|
|
1129
|
-
ALLOWED_ATTR = 'ALLOWED_ATTR'
|
|
1130
|
-
ALLOWED_NAMESPACES = 'ALLOWED_NAMESPACES'
|
|
1131
|
-
URI_SAFE_ATTRIBUTES = 'ADD_URI_SAFE_ATTR'
|
|
1132
|
-
|
|
1133
|
-
cfg.
|
|
1134
|
-
|
|
1135
|
-
transformCaseFunc
|
|
1136
|
-
)
|
|
1137
|
-
: DEFAULT_URI_SAFE_ATTRIBUTES;
|
|
1138
|
-
DATA_URI_TAGS = 'ADD_DATA_URI_TAGS' in cfg ? addToSet(clone(DEFAULT_DATA_URI_TAGS),
|
|
1139
|
-
// eslint-disable-line indent
|
|
1140
|
-
cfg.ADD_DATA_URI_TAGS,
|
|
1141
|
-
// eslint-disable-line indent
|
|
1142
|
-
transformCaseFunc // eslint-disable-line indent
|
|
1143
|
-
) // eslint-disable-line indent
|
|
1144
|
-
: DEFAULT_DATA_URI_TAGS;
|
|
1145
|
-
FORBID_CONTENTS = 'FORBID_CONTENTS' in cfg ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc) : DEFAULT_FORBID_CONTENTS;
|
|
1146
|
-
FORBID_TAGS = 'FORBID_TAGS' in cfg ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : {};
|
|
1147
|
-
FORBID_ATTR = 'FORBID_ATTR' in cfg ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : {};
|
|
1148
|
-
USE_PROFILES = 'USE_PROFILES' in cfg ? cfg.USE_PROFILES : false;
|
|
1245
|
+
ALLOWED_TAGS = objectHasOwnProperty(cfg, 'ALLOWED_TAGS') ? addToSet({}, cfg.ALLOWED_TAGS, transformCaseFunc) : DEFAULT_ALLOWED_TAGS;
|
|
1246
|
+
ALLOWED_ATTR = objectHasOwnProperty(cfg, 'ALLOWED_ATTR') ? addToSet({}, cfg.ALLOWED_ATTR, transformCaseFunc) : DEFAULT_ALLOWED_ATTR;
|
|
1247
|
+
ALLOWED_NAMESPACES = objectHasOwnProperty(cfg, 'ALLOWED_NAMESPACES') ? addToSet({}, cfg.ALLOWED_NAMESPACES, stringToString) : DEFAULT_ALLOWED_NAMESPACES;
|
|
1248
|
+
URI_SAFE_ATTRIBUTES = objectHasOwnProperty(cfg, 'ADD_URI_SAFE_ATTR') ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR, transformCaseFunc) : DEFAULT_URI_SAFE_ATTRIBUTES;
|
|
1249
|
+
DATA_URI_TAGS = objectHasOwnProperty(cfg, 'ADD_DATA_URI_TAGS') ? addToSet(clone(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS, transformCaseFunc) : DEFAULT_DATA_URI_TAGS;
|
|
1250
|
+
FORBID_CONTENTS = objectHasOwnProperty(cfg, 'FORBID_CONTENTS') ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc) : DEFAULT_FORBID_CONTENTS;
|
|
1251
|
+
FORBID_TAGS = objectHasOwnProperty(cfg, 'FORBID_TAGS') ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : {};
|
|
1252
|
+
FORBID_ATTR = objectHasOwnProperty(cfg, 'FORBID_ATTR') ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : {};
|
|
1253
|
+
USE_PROFILES = objectHasOwnProperty(cfg, 'USE_PROFILES') ? cfg.USE_PROFILES : false;
|
|
1149
1254
|
ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true
|
|
1150
1255
|
ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true
|
|
1151
1256
|
ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false
|
|
@@ -1161,8 +1266,10 @@
|
|
|
1161
1266
|
SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false; // Default false
|
|
1162
1267
|
KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true
|
|
1163
1268
|
IN_PLACE = cfg.IN_PLACE || false; // Default false
|
|
1164
|
-
IS_ALLOWED_URI$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI
|
|
1269
|
+
IS_ALLOWED_URI$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI;
|
|
1165
1270
|
NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE;
|
|
1271
|
+
MATHML_TEXT_INTEGRATION_POINTS = cfg.MATHML_TEXT_INTEGRATION_POINTS || MATHML_TEXT_INTEGRATION_POINTS;
|
|
1272
|
+
HTML_INTEGRATION_POINTS = cfg.HTML_INTEGRATION_POINTS || HTML_INTEGRATION_POINTS;
|
|
1166
1273
|
CUSTOM_ELEMENT_HANDLING = cfg.CUSTOM_ELEMENT_HANDLING || {};
|
|
1167
1274
|
if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck)) {
|
|
1168
1275
|
CUSTOM_ELEMENT_HANDLING.tagNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck;
|
|
@@ -1179,10 +1286,9 @@
|
|
|
1179
1286
|
if (RETURN_DOM_FRAGMENT) {
|
|
1180
1287
|
RETURN_DOM = true;
|
|
1181
1288
|
}
|
|
1182
|
-
|
|
1183
1289
|
/* Parse profile info */
|
|
1184
1290
|
if (USE_PROFILES) {
|
|
1185
|
-
ALLOWED_TAGS = addToSet({},
|
|
1291
|
+
ALLOWED_TAGS = addToSet({}, text);
|
|
1186
1292
|
ALLOWED_ATTR = [];
|
|
1187
1293
|
if (USE_PROFILES.html === true) {
|
|
1188
1294
|
addToSet(ALLOWED_TAGS, html$1);
|
|
@@ -1204,7 +1310,6 @@
|
|
|
1204
1310
|
addToSet(ALLOWED_ATTR, xml);
|
|
1205
1311
|
}
|
|
1206
1312
|
}
|
|
1207
|
-
|
|
1208
1313
|
/* Merge configuration parameters */
|
|
1209
1314
|
if (cfg.ADD_TAGS) {
|
|
1210
1315
|
if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {
|
|
@@ -1227,23 +1332,40 @@
|
|
|
1227
1332
|
}
|
|
1228
1333
|
addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc);
|
|
1229
1334
|
}
|
|
1230
|
-
|
|
1231
1335
|
/* Add #text in case KEEP_CONTENT is set to true */
|
|
1232
1336
|
if (KEEP_CONTENT) {
|
|
1233
1337
|
ALLOWED_TAGS['#text'] = true;
|
|
1234
1338
|
}
|
|
1235
|
-
|
|
1236
1339
|
/* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */
|
|
1237
1340
|
if (WHOLE_DOCUMENT) {
|
|
1238
1341
|
addToSet(ALLOWED_TAGS, ['html', 'head', 'body']);
|
|
1239
1342
|
}
|
|
1240
|
-
|
|
1241
1343
|
/* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */
|
|
1242
1344
|
if (ALLOWED_TAGS.table) {
|
|
1243
1345
|
addToSet(ALLOWED_TAGS, ['tbody']);
|
|
1244
1346
|
delete FORBID_TAGS.tbody;
|
|
1245
1347
|
}
|
|
1246
|
-
|
|
1348
|
+
if (cfg.TRUSTED_TYPES_POLICY) {
|
|
1349
|
+
if (typeof cfg.TRUSTED_TYPES_POLICY.createHTML !== 'function') {
|
|
1350
|
+
throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');
|
|
1351
|
+
}
|
|
1352
|
+
if (typeof cfg.TRUSTED_TYPES_POLICY.createScriptURL !== 'function') {
|
|
1353
|
+
throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');
|
|
1354
|
+
}
|
|
1355
|
+
// Overwrite existing TrustedTypes policy.
|
|
1356
|
+
trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY;
|
|
1357
|
+
// Sign local variables required by `sanitize`.
|
|
1358
|
+
emptyHTML = trustedTypesPolicy.createHTML('');
|
|
1359
|
+
} else {
|
|
1360
|
+
// Uninitialized policy, attempt to initialize the internal dompurify policy.
|
|
1361
|
+
if (trustedTypesPolicy === undefined) {
|
|
1362
|
+
trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, currentScript);
|
|
1363
|
+
}
|
|
1364
|
+
// If creating the internal policy succeeded sign internal variables.
|
|
1365
|
+
if (trustedTypesPolicy !== null && typeof emptyHTML === 'string') {
|
|
1366
|
+
emptyHTML = trustedTypesPolicy.createHTML('');
|
|
1367
|
+
}
|
|
1368
|
+
}
|
|
1247
1369
|
// Prevent further manipulation of configuration.
|
|
1248
1370
|
// Not available in IE8, Safari 5, etc.
|
|
1249
1371
|
if (freeze) {
|
|
@@ -1251,35 +1373,19 @@
|
|
|
1251
1373
|
}
|
|
1252
1374
|
CONFIG = cfg;
|
|
1253
1375
|
};
|
|
1254
|
-
var MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ['mi', 'mo', 'mn', 'ms', 'mtext']);
|
|
1255
|
-
var HTML_INTEGRATION_POINTS = addToSet({}, ['foreignobject', 'annotation-xml']);
|
|
1256
|
-
|
|
1257
|
-
// Certain elements are allowed in both SVG and HTML
|
|
1258
|
-
// namespace. We need to specify them explicitly
|
|
1259
|
-
// so that they don't get erroneously deleted from
|
|
1260
|
-
// HTML namespace.
|
|
1261
|
-
var COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, ['title', 'style', 'font', 'a', 'script']);
|
|
1262
|
-
|
|
1263
1376
|
/* Keep track of all possible SVG and MathML tags
|
|
1264
1377
|
* so that we can perform the namespace checks
|
|
1265
1378
|
* correctly. */
|
|
1266
|
-
var ALL_SVG_TAGS = addToSet({}, svg$1);
|
|
1267
|
-
addToSet(
|
|
1268
|
-
addToSet(ALL_SVG_TAGS, svgDisallowed);
|
|
1269
|
-
var ALL_MATHML_TAGS = addToSet({}, mathMl$1);
|
|
1270
|
-
addToSet(ALL_MATHML_TAGS, mathMlDisallowed);
|
|
1271
|
-
|
|
1379
|
+
var ALL_SVG_TAGS = addToSet({}, [].concat(_toConsumableArray(svg$1), _toConsumableArray(svgFilters), _toConsumableArray(svgDisallowed)));
|
|
1380
|
+
var ALL_MATHML_TAGS = addToSet({}, [].concat(_toConsumableArray(mathMl$1), _toConsumableArray(mathMlDisallowed)));
|
|
1272
1381
|
/**
|
|
1273
|
-
*
|
|
1274
|
-
*
|
|
1275
|
-
* @param {Element} element a DOM element whose namespace is being checked
|
|
1276
|
-
* @returns {boolean} Return false if the element has a
|
|
1382
|
+
* @param element a DOM element whose namespace is being checked
|
|
1383
|
+
* @returns Return false if the element has a
|
|
1277
1384
|
* namespace that a spec-compliant parser would never
|
|
1278
1385
|
* return. Return true otherwise.
|
|
1279
1386
|
*/
|
|
1280
1387
|
var _checkValidNamespace = function _checkValidNamespace(element) {
|
|
1281
1388
|
var parent = getParentNode(element);
|
|
1282
|
-
|
|
1283
1389
|
// In JSDOM, if we're inside shadow DOM, then parentNode
|
|
1284
1390
|
// can be null. We just simulate parent in this case.
|
|
1285
1391
|
if (!parent || !parent.tagName) {
|
|
@@ -1300,14 +1406,12 @@
|
|
|
1300
1406
|
if (parent.namespaceURI === HTML_NAMESPACE) {
|
|
1301
1407
|
return tagName === 'svg';
|
|
1302
1408
|
}
|
|
1303
|
-
|
|
1304
1409
|
// The only way to switch from MathML to SVG is via`
|
|
1305
1410
|
// svg if parent is either <annotation-xml> or MathML
|
|
1306
1411
|
// text integration points.
|
|
1307
1412
|
if (parent.namespaceURI === MATHML_NAMESPACE) {
|
|
1308
1413
|
return tagName === 'svg' && (parentTagName === 'annotation-xml' || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]);
|
|
1309
1414
|
}
|
|
1310
|
-
|
|
1311
1415
|
// We only allow elements that are defined in SVG
|
|
1312
1416
|
// spec. All others are disallowed in SVG namespace.
|
|
1313
1417
|
return Boolean(ALL_SVG_TAGS[tagName]);
|
|
@@ -1319,13 +1423,11 @@
|
|
|
1319
1423
|
if (parent.namespaceURI === HTML_NAMESPACE) {
|
|
1320
1424
|
return tagName === 'math';
|
|
1321
1425
|
}
|
|
1322
|
-
|
|
1323
1426
|
// The only way to switch from SVG to MathML is via
|
|
1324
1427
|
// <math> and HTML integration points
|
|
1325
1428
|
if (parent.namespaceURI === SVG_NAMESPACE) {
|
|
1326
1429
|
return tagName === 'math' && HTML_INTEGRATION_POINTS[parentTagName];
|
|
1327
1430
|
}
|
|
1328
|
-
|
|
1329
1431
|
// We only allow elements that are defined in MathML
|
|
1330
1432
|
// spec. All others are disallowed in MathML namespace.
|
|
1331
1433
|
return Boolean(ALL_MATHML_TAGS[tagName]);
|
|
@@ -1340,28 +1442,24 @@
|
|
|
1340
1442
|
if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) {
|
|
1341
1443
|
return false;
|
|
1342
1444
|
}
|
|
1343
|
-
|
|
1344
1445
|
// We disallow tags that are specific for MathML
|
|
1345
1446
|
// or SVG and should never appear in HTML namespace
|
|
1346
1447
|
return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]);
|
|
1347
1448
|
}
|
|
1348
|
-
|
|
1349
1449
|
// For XHTML and XML documents that support custom namespaces
|
|
1350
1450
|
if (PARSER_MEDIA_TYPE === 'application/xhtml+xml' && ALLOWED_NAMESPACES[element.namespaceURI]) {
|
|
1351
1451
|
return true;
|
|
1352
1452
|
}
|
|
1353
|
-
|
|
1354
1453
|
// The code should never reach this place (this means
|
|
1355
1454
|
// that the element somehow got namespace that is not
|
|
1356
1455
|
// HTML, SVG, MathML or allowed via ALLOWED_NAMESPACES).
|
|
1357
1456
|
// Return false just in case.
|
|
1358
1457
|
return false;
|
|
1359
1458
|
};
|
|
1360
|
-
|
|
1361
1459
|
/**
|
|
1362
1460
|
* _forceRemove
|
|
1363
1461
|
*
|
|
1364
|
-
* @param
|
|
1462
|
+
* @param node a DOM node
|
|
1365
1463
|
*/
|
|
1366
1464
|
var _forceRemove = function _forceRemove(node) {
|
|
1367
1465
|
arrayPush(DOMPurify.removed, {
|
|
@@ -1369,60 +1467,53 @@
|
|
|
1369
1467
|
});
|
|
1370
1468
|
try {
|
|
1371
1469
|
// eslint-disable-next-line unicorn/prefer-dom-node-remove
|
|
1372
|
-
node.
|
|
1470
|
+
getParentNode(node).removeChild(node);
|
|
1373
1471
|
} catch (_) {
|
|
1374
|
-
|
|
1375
|
-
node.outerHTML = emptyHTML;
|
|
1376
|
-
} catch (_) {
|
|
1377
|
-
node.remove();
|
|
1378
|
-
}
|
|
1472
|
+
remove(node);
|
|
1379
1473
|
}
|
|
1380
1474
|
};
|
|
1381
|
-
|
|
1382
1475
|
/**
|
|
1383
1476
|
* _removeAttribute
|
|
1384
1477
|
*
|
|
1385
|
-
* @param
|
|
1386
|
-
* @param
|
|
1478
|
+
* @param name an Attribute name
|
|
1479
|
+
* @param element a DOM node
|
|
1387
1480
|
*/
|
|
1388
|
-
var _removeAttribute = function _removeAttribute(name,
|
|
1481
|
+
var _removeAttribute = function _removeAttribute(name, element) {
|
|
1389
1482
|
try {
|
|
1390
1483
|
arrayPush(DOMPurify.removed, {
|
|
1391
|
-
attribute:
|
|
1392
|
-
from:
|
|
1484
|
+
attribute: element.getAttributeNode(name),
|
|
1485
|
+
from: element
|
|
1393
1486
|
});
|
|
1394
1487
|
} catch (_) {
|
|
1395
1488
|
arrayPush(DOMPurify.removed, {
|
|
1396
1489
|
attribute: null,
|
|
1397
|
-
from:
|
|
1490
|
+
from: element
|
|
1398
1491
|
});
|
|
1399
1492
|
}
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
if (name === 'is' && !ALLOWED_ATTR[name]) {
|
|
1493
|
+
element.removeAttribute(name);
|
|
1494
|
+
// We void attribute values for unremovable "is" attributes
|
|
1495
|
+
if (name === 'is') {
|
|
1404
1496
|
if (RETURN_DOM || RETURN_DOM_FRAGMENT) {
|
|
1405
1497
|
try {
|
|
1406
|
-
_forceRemove(
|
|
1498
|
+
_forceRemove(element);
|
|
1407
1499
|
} catch (_) {}
|
|
1408
1500
|
} else {
|
|
1409
1501
|
try {
|
|
1410
|
-
|
|
1502
|
+
element.setAttribute(name, '');
|
|
1411
1503
|
} catch (_) {}
|
|
1412
1504
|
}
|
|
1413
1505
|
}
|
|
1414
1506
|
};
|
|
1415
|
-
|
|
1416
1507
|
/**
|
|
1417
1508
|
* _initDocument
|
|
1418
1509
|
*
|
|
1419
|
-
* @param
|
|
1420
|
-
* @return
|
|
1510
|
+
* @param dirty - a string of dirty markup
|
|
1511
|
+
* @return a DOM, filled with the dirty markup
|
|
1421
1512
|
*/
|
|
1422
1513
|
var _initDocument = function _initDocument(dirty) {
|
|
1423
1514
|
/* Create a HTML document */
|
|
1424
|
-
var doc;
|
|
1425
|
-
var leadingWhitespace;
|
|
1515
|
+
var doc = null;
|
|
1516
|
+
var leadingWhitespace = null;
|
|
1426
1517
|
if (FORCE_BODY) {
|
|
1427
1518
|
dirty = '<remove></remove>' + dirty;
|
|
1428
1519
|
} else {
|
|
@@ -1444,7 +1535,6 @@
|
|
|
1444
1535
|
doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE);
|
|
1445
1536
|
} catch (_) {}
|
|
1446
1537
|
}
|
|
1447
|
-
|
|
1448
1538
|
/* Use createHTMLDocument in case DOMParser is not available */
|
|
1449
1539
|
if (!doc || !doc.documentElement) {
|
|
1450
1540
|
doc = implementation.createDocument(NAMESPACE, 'template', null);
|
|
@@ -1458,132 +1548,97 @@
|
|
|
1458
1548
|
if (dirty && leadingWhitespace) {
|
|
1459
1549
|
body.insertBefore(document.createTextNode(leadingWhitespace), body.childNodes[0] || null);
|
|
1460
1550
|
}
|
|
1461
|
-
|
|
1462
1551
|
/* Work on whole document or just its body */
|
|
1463
1552
|
if (NAMESPACE === HTML_NAMESPACE) {
|
|
1464
1553
|
return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0];
|
|
1465
1554
|
}
|
|
1466
1555
|
return WHOLE_DOCUMENT ? doc.documentElement : body;
|
|
1467
1556
|
};
|
|
1468
|
-
|
|
1469
1557
|
/**
|
|
1470
|
-
*
|
|
1558
|
+
* Creates a NodeIterator object that you can use to traverse filtered lists of nodes or elements in a document.
|
|
1471
1559
|
*
|
|
1472
|
-
* @param
|
|
1473
|
-
* @return
|
|
1560
|
+
* @param root The root element or node to start traversing on.
|
|
1561
|
+
* @return The created NodeIterator
|
|
1474
1562
|
*/
|
|
1475
|
-
var
|
|
1563
|
+
var _createNodeIterator = function _createNodeIterator(root) {
|
|
1476
1564
|
return createNodeIterator.call(root.ownerDocument || root, root,
|
|
1477
1565
|
// eslint-disable-next-line no-bitwise
|
|
1478
|
-
NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT | NodeFilter.SHOW_PROCESSING_INSTRUCTION | NodeFilter.SHOW_CDATA_SECTION, null
|
|
1566
|
+
NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT | NodeFilter.SHOW_PROCESSING_INSTRUCTION | NodeFilter.SHOW_CDATA_SECTION, null);
|
|
1479
1567
|
};
|
|
1480
|
-
|
|
1481
1568
|
/**
|
|
1482
1569
|
* _isClobbered
|
|
1483
1570
|
*
|
|
1484
|
-
* @param
|
|
1485
|
-
* @return
|
|
1571
|
+
* @param element element to check for clobbering attacks
|
|
1572
|
+
* @return true if clobbered, false if safe
|
|
1486
1573
|
*/
|
|
1487
|
-
var _isClobbered = function _isClobbered(
|
|
1488
|
-
return
|
|
1574
|
+
var _isClobbered = function _isClobbered(element) {
|
|
1575
|
+
return element instanceof HTMLFormElement && (typeof element.nodeName !== 'string' || typeof element.textContent !== 'string' || typeof element.removeChild !== 'function' || !(element.attributes instanceof NamedNodeMap) || typeof element.removeAttribute !== 'function' || typeof element.setAttribute !== 'function' || typeof element.namespaceURI !== 'string' || typeof element.insertBefore !== 'function' || typeof element.hasChildNodes !== 'function');
|
|
1489
1576
|
};
|
|
1490
|
-
|
|
1491
1577
|
/**
|
|
1492
|
-
*
|
|
1578
|
+
* Checks whether the given object is a DOM node.
|
|
1493
1579
|
*
|
|
1494
|
-
* @param
|
|
1495
|
-
* @return
|
|
1580
|
+
* @param value object to check whether it's a DOM node
|
|
1581
|
+
* @return true is object is a DOM node
|
|
1496
1582
|
*/
|
|
1497
|
-
var _isNode = function _isNode(
|
|
1498
|
-
return
|
|
1583
|
+
var _isNode = function _isNode(value) {
|
|
1584
|
+
return typeof Node === 'function' && value instanceof Node;
|
|
1499
1585
|
};
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
* _executeHook
|
|
1503
|
-
* Execute user configurable hooks
|
|
1504
|
-
*
|
|
1505
|
-
* @param {String} entryPoint Name of the hook's entry point
|
|
1506
|
-
* @param {Node} currentNode node to work on with the hook
|
|
1507
|
-
* @param {Object} data additional hook parameters
|
|
1508
|
-
*/
|
|
1509
|
-
var _executeHook = function _executeHook(entryPoint, currentNode, data) {
|
|
1510
|
-
if (!hooks[entryPoint]) {
|
|
1511
|
-
return;
|
|
1512
|
-
}
|
|
1513
|
-
arrayForEach(hooks[entryPoint], function (hook) {
|
|
1586
|
+
function _executeHooks(hooks, currentNode, data) {
|
|
1587
|
+
arrayForEach(hooks, function (hook) {
|
|
1514
1588
|
hook.call(DOMPurify, currentNode, data, CONFIG);
|
|
1515
1589
|
});
|
|
1516
|
-
}
|
|
1517
|
-
|
|
1590
|
+
}
|
|
1518
1591
|
/**
|
|
1519
1592
|
* _sanitizeElements
|
|
1520
1593
|
*
|
|
1521
1594
|
* @protect nodeName
|
|
1522
1595
|
* @protect textContent
|
|
1523
1596
|
* @protect removeChild
|
|
1524
|
-
*
|
|
1525
|
-
* @
|
|
1526
|
-
* @return {Boolean} true if node was killed, false if left alive
|
|
1597
|
+
* @param currentNode to check for permission to exist
|
|
1598
|
+
* @return true if node was killed, false if left alive
|
|
1527
1599
|
*/
|
|
1528
1600
|
var _sanitizeElements = function _sanitizeElements(currentNode) {
|
|
1529
|
-
var content;
|
|
1530
|
-
|
|
1601
|
+
var content = null;
|
|
1531
1602
|
/* Execute a hook if present */
|
|
1532
|
-
|
|
1533
|
-
|
|
1603
|
+
_executeHooks(hooks.beforeSanitizeElements, currentNode, null);
|
|
1534
1604
|
/* Check if element is clobbered or can clobber */
|
|
1535
1605
|
if (_isClobbered(currentNode)) {
|
|
1536
1606
|
_forceRemove(currentNode);
|
|
1537
1607
|
return true;
|
|
1538
1608
|
}
|
|
1539
|
-
|
|
1540
|
-
/* Check if tagname contains Unicode */
|
|
1541
|
-
if (regExpTest(/[\u0080-\uFFFF]/, currentNode.nodeName)) {
|
|
1542
|
-
_forceRemove(currentNode);
|
|
1543
|
-
return true;
|
|
1544
|
-
}
|
|
1545
|
-
|
|
1546
1609
|
/* Now let's check the element's type and name */
|
|
1547
1610
|
var tagName = transformCaseFunc(currentNode.nodeName);
|
|
1548
|
-
|
|
1549
1611
|
/* Execute a hook if present */
|
|
1550
|
-
|
|
1612
|
+
_executeHooks(hooks.uponSanitizeElement, currentNode, {
|
|
1551
1613
|
tagName: tagName,
|
|
1552
1614
|
allowedTags: ALLOWED_TAGS
|
|
1553
1615
|
});
|
|
1554
|
-
|
|
1555
1616
|
/* Detect mXSS attempts abusing namespace confusion */
|
|
1556
|
-
if (currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) &&
|
|
1617
|
+
if (currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(/<[/\w!]/g, currentNode.innerHTML) && regExpTest(/<[/\w!]/g, currentNode.textContent)) {
|
|
1557
1618
|
_forceRemove(currentNode);
|
|
1558
1619
|
return true;
|
|
1559
1620
|
}
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
if (tagName === 'select' && regExpTest(/<template/i, currentNode.innerHTML)) {
|
|
1621
|
+
/* Remove any occurrence of processing instructions */
|
|
1622
|
+
if (currentNode.nodeType === NODE_TYPE.progressingInstruction) {
|
|
1563
1623
|
_forceRemove(currentNode);
|
|
1564
1624
|
return true;
|
|
1565
1625
|
}
|
|
1566
|
-
|
|
1567
|
-
/* Remove any ocurrence of processing instructions */
|
|
1568
|
-
if (currentNode.nodeType === 7) {
|
|
1569
|
-
_forceRemove(currentNode);
|
|
1570
|
-
return true;
|
|
1571
|
-
}
|
|
1572
|
-
|
|
1573
1626
|
/* Remove any kind of possibly harmful comments */
|
|
1574
|
-
if (SAFE_FOR_XML && currentNode.nodeType ===
|
|
1627
|
+
if (SAFE_FOR_XML && currentNode.nodeType === NODE_TYPE.comment && regExpTest(/<[/\w]/g, currentNode.data)) {
|
|
1575
1628
|
_forceRemove(currentNode);
|
|
1576
1629
|
return true;
|
|
1577
1630
|
}
|
|
1578
|
-
|
|
1579
1631
|
/* Remove element if anything forbids its presence */
|
|
1580
1632
|
if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
|
|
1581
1633
|
/* Check if we have a custom element to handle */
|
|
1582
|
-
if (!FORBID_TAGS[tagName] &&
|
|
1583
|
-
if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName))
|
|
1584
|
-
|
|
1634
|
+
if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {
|
|
1635
|
+
if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) {
|
|
1636
|
+
return false;
|
|
1637
|
+
}
|
|
1638
|
+
if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) {
|
|
1639
|
+
return false;
|
|
1640
|
+
}
|
|
1585
1641
|
}
|
|
1586
|
-
|
|
1587
1642
|
/* Keep content except for bad-listed elements */
|
|
1588
1643
|
if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {
|
|
1589
1644
|
var parentNode = getParentNode(currentNode) || currentNode.parentNode;
|
|
@@ -1600,26 +1655,23 @@
|
|
|
1600
1655
|
_forceRemove(currentNode);
|
|
1601
1656
|
return true;
|
|
1602
1657
|
}
|
|
1603
|
-
|
|
1604
1658
|
/* Check whether element has a valid namespace */
|
|
1605
1659
|
if (currentNode instanceof Element && !_checkValidNamespace(currentNode)) {
|
|
1606
1660
|
_forceRemove(currentNode);
|
|
1607
1661
|
return true;
|
|
1608
1662
|
}
|
|
1609
|
-
|
|
1610
1663
|
/* Make sure that older browsers don't get fallback-tag mXSS */
|
|
1611
1664
|
if ((tagName === 'noscript' || tagName === 'noembed' || tagName === 'noframes') && regExpTest(/<\/no(script|embed|frames)/i, currentNode.innerHTML)) {
|
|
1612
1665
|
_forceRemove(currentNode);
|
|
1613
1666
|
return true;
|
|
1614
1667
|
}
|
|
1615
|
-
|
|
1616
1668
|
/* Sanitize element content to be template-safe */
|
|
1617
|
-
if (SAFE_FOR_TEMPLATES && currentNode.nodeType ===
|
|
1669
|
+
if (SAFE_FOR_TEMPLATES && currentNode.nodeType === NODE_TYPE.text) {
|
|
1618
1670
|
/* Get the element's text content */
|
|
1619
1671
|
content = currentNode.textContent;
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1672
|
+
arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], function (expr) {
|
|
1673
|
+
content = stringReplace(content, expr, ' ');
|
|
1674
|
+
});
|
|
1623
1675
|
if (currentNode.textContent !== content) {
|
|
1624
1676
|
arrayPush(DOMPurify.removed, {
|
|
1625
1677
|
element: currentNode.cloneNode()
|
|
@@ -1627,19 +1679,17 @@
|
|
|
1627
1679
|
currentNode.textContent = content;
|
|
1628
1680
|
}
|
|
1629
1681
|
}
|
|
1630
|
-
|
|
1631
1682
|
/* Execute a hook if present */
|
|
1632
|
-
|
|
1683
|
+
_executeHooks(hooks.afterSanitizeElements, currentNode, null);
|
|
1633
1684
|
return false;
|
|
1634
1685
|
};
|
|
1635
|
-
|
|
1636
1686
|
/**
|
|
1637
1687
|
* _isValidAttribute
|
|
1638
1688
|
*
|
|
1639
|
-
* @param
|
|
1640
|
-
* @param
|
|
1641
|
-
* @param
|
|
1642
|
-
* @return
|
|
1689
|
+
* @param lcTag Lowercase tag name of containing element.
|
|
1690
|
+
* @param lcName Lowercase attribute name.
|
|
1691
|
+
* @param value Attribute value.
|
|
1692
|
+
* @return Returns true if `value` is valid, otherwise false.
|
|
1643
1693
|
*/
|
|
1644
1694
|
// eslint-disable-next-line complexity
|
|
1645
1695
|
var _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) {
|
|
@@ -1647,39 +1697,38 @@
|
|
|
1647
1697
|
if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) {
|
|
1648
1698
|
return false;
|
|
1649
1699
|
}
|
|
1650
|
-
|
|
1651
1700
|
/* Allow valid data-* attributes: At least one character after "-"
|
|
1652
1701
|
(https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)
|
|
1653
1702
|
XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)
|
|
1654
1703
|
We don't need to check the value; it's always URI safe. */
|
|
1655
|
-
if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR
|
|
1704
|
+
if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR, lcName)) ;else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR, lcName)) ;else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) {
|
|
1656
1705
|
if (
|
|
1657
1706
|
// First condition does a very basic check if a) it's basically a valid custom element tagname AND
|
|
1658
1707
|
// b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
|
|
1659
1708
|
// and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck
|
|
1660
|
-
|
|
1709
|
+
_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)) ||
|
|
1661
1710
|
// Alternative, second condition checks if it's an `is`-attribute, AND
|
|
1662
1711
|
// the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
|
|
1663
1712
|
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 {
|
|
1664
1713
|
return false;
|
|
1665
1714
|
}
|
|
1666
1715
|
/* Check value is safe. First, is attr inert? If so, is safe */
|
|
1667
|
-
} else if (URI_SAFE_ATTRIBUTES[lcName]) ;else if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE
|
|
1716
|
+
} else if (URI_SAFE_ATTRIBUTES[lcName]) ;else if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE, ''))) ;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, stringReplace(value, ATTR_WHITESPACE, ''))) ;else if (value) {
|
|
1668
1717
|
return false;
|
|
1669
1718
|
} else ;
|
|
1670
1719
|
return true;
|
|
1671
1720
|
};
|
|
1672
|
-
|
|
1673
1721
|
/**
|
|
1674
|
-
*
|
|
1722
|
+
* _isBasicCustomElement
|
|
1675
1723
|
* checks if at least one dash is included in tagName, and it's not the first char
|
|
1676
1724
|
* for more sophisticated checking see https://github.com/sindresorhus/validate-element-name
|
|
1677
|
-
*
|
|
1725
|
+
*
|
|
1726
|
+
* @param tagName name of the tag of the node to sanitize
|
|
1727
|
+
* @returns Returns true if the tag name meets the basic criteria for a custom element, otherwise false.
|
|
1678
1728
|
*/
|
|
1679
|
-
var
|
|
1680
|
-
return tagName !== 'annotation-xml' && stringMatch(tagName, CUSTOM_ELEMENT
|
|
1729
|
+
var _isBasicCustomElement = function _isBasicCustomElement(tagName) {
|
|
1730
|
+
return tagName !== 'annotation-xml' && stringMatch(tagName, CUSTOM_ELEMENT);
|
|
1681
1731
|
};
|
|
1682
|
-
|
|
1683
1732
|
/**
|
|
1684
1733
|
* _sanitizeAttributes
|
|
1685
1734
|
*
|
|
@@ -1688,181 +1737,151 @@
|
|
|
1688
1737
|
* @protect removeAttribute
|
|
1689
1738
|
* @protect setAttribute
|
|
1690
1739
|
*
|
|
1691
|
-
* @param
|
|
1740
|
+
* @param currentNode to sanitize
|
|
1692
1741
|
*/
|
|
1693
1742
|
var _sanitizeAttributes = function _sanitizeAttributes(currentNode) {
|
|
1694
|
-
var attr;
|
|
1695
|
-
var value;
|
|
1696
|
-
var lcName;
|
|
1697
|
-
var l;
|
|
1698
1743
|
/* Execute a hook if present */
|
|
1699
|
-
|
|
1744
|
+
_executeHooks(hooks.beforeSanitizeAttributes, currentNode, null);
|
|
1700
1745
|
var attributes = currentNode.attributes;
|
|
1701
|
-
|
|
1702
1746
|
/* Check if we have attributes; if not we might have a text node */
|
|
1703
|
-
if (!attributes) {
|
|
1747
|
+
if (!attributes || _isClobbered(currentNode)) {
|
|
1704
1748
|
return;
|
|
1705
1749
|
}
|
|
1706
1750
|
var hookEvent = {
|
|
1707
1751
|
attrName: '',
|
|
1708
1752
|
attrValue: '',
|
|
1709
1753
|
keepAttr: true,
|
|
1710
|
-
allowedAttributes: ALLOWED_ATTR
|
|
1754
|
+
allowedAttributes: ALLOWED_ATTR,
|
|
1755
|
+
forceKeepAttr: undefined
|
|
1711
1756
|
};
|
|
1712
|
-
l = attributes.length;
|
|
1713
|
-
|
|
1757
|
+
var l = attributes.length;
|
|
1714
1758
|
/* Go backwards over all attributes; safely remove bad ones */
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
}
|
|
1749
|
-
|
|
1750
|
-
/* Work around a security issue in jQuery 3.0 */
|
|
1751
|
-
if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(/\/>/i, value)) {
|
|
1752
|
-
_removeAttribute(name, currentNode);
|
|
1753
|
-
continue;
|
|
1754
|
-
}
|
|
1755
|
-
|
|
1756
|
-
/* Sanitize attribute content to be template-safe */
|
|
1757
|
-
if (SAFE_FOR_TEMPLATES) {
|
|
1758
|
-
value = stringReplace(value, MUSTACHE_EXPR$1, ' ');
|
|
1759
|
-
value = stringReplace(value, ERB_EXPR$1, ' ');
|
|
1760
|
-
value = stringReplace(value, TMPLIT_EXPR$1, ' ');
|
|
1761
|
-
}
|
|
1762
|
-
|
|
1763
|
-
/* Is `value` valid for this attribute? */
|
|
1764
|
-
var lcTag = transformCaseFunc(currentNode.nodeName);
|
|
1765
|
-
if (!_isValidAttribute(lcTag, lcName, value)) {
|
|
1766
|
-
continue;
|
|
1767
|
-
}
|
|
1768
|
-
|
|
1769
|
-
/* Full DOM Clobbering protection via namespace isolation,
|
|
1770
|
-
* Prefix id and name attributes with `user-content-`
|
|
1771
|
-
*/
|
|
1772
|
-
if (SANITIZE_NAMED_PROPS && (lcName === 'id' || lcName === 'name')) {
|
|
1773
|
-
// Remove the attribute with this value
|
|
1759
|
+
var _loop = function _loop() {
|
|
1760
|
+
var attr = attributes[l];
|
|
1761
|
+
var name = attr.name,
|
|
1762
|
+
namespaceURI = attr.namespaceURI,
|
|
1763
|
+
attrValue = attr.value;
|
|
1764
|
+
var lcName = transformCaseFunc(name);
|
|
1765
|
+
var value = name === 'value' ? attrValue : stringTrim(attrValue);
|
|
1766
|
+
/* Execute a hook if present */
|
|
1767
|
+
hookEvent.attrName = lcName;
|
|
1768
|
+
hookEvent.attrValue = value;
|
|
1769
|
+
hookEvent.keepAttr = true;
|
|
1770
|
+
hookEvent.forceKeepAttr = undefined; // Allows developers to see this is a property they can set
|
|
1771
|
+
_executeHooks(hooks.uponSanitizeAttribute, currentNode, hookEvent);
|
|
1772
|
+
value = hookEvent.attrValue;
|
|
1773
|
+
/* Full DOM Clobbering protection via namespace isolation,
|
|
1774
|
+
* Prefix id and name attributes with `user-content-`
|
|
1775
|
+
*/
|
|
1776
|
+
if (SANITIZE_NAMED_PROPS && (lcName === 'id' || lcName === 'name')) {
|
|
1777
|
+
// Remove the attribute with this value
|
|
1778
|
+
_removeAttribute(name, currentNode);
|
|
1779
|
+
// Prefix the value and later re-create the attribute with the sanitized value
|
|
1780
|
+
value = SANITIZE_NAMED_PROPS_PREFIX + value;
|
|
1781
|
+
}
|
|
1782
|
+
/* Work around a security issue with comments inside attributes */
|
|
1783
|
+
if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|title)/i, value)) {
|
|
1784
|
+
_removeAttribute(name, currentNode);
|
|
1785
|
+
return 0; // continue
|
|
1786
|
+
}
|
|
1787
|
+
/* Did the hooks approve of the attribute? */
|
|
1788
|
+
if (hookEvent.forceKeepAttr) {
|
|
1789
|
+
return 0; // continue
|
|
1790
|
+
}
|
|
1791
|
+
/* Remove attribute */
|
|
1774
1792
|
_removeAttribute(name, currentNode);
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
}
|
|
1779
|
-
|
|
1780
|
-
/* Handle attributes that require Trusted Types */
|
|
1781
|
-
if (trustedTypesPolicy && _typeof(trustedTypes) === 'object' && typeof trustedTypes.getAttributeType === 'function') {
|
|
1782
|
-
if (namespaceURI) ;else {
|
|
1783
|
-
switch (trustedTypes.getAttributeType(lcTag, lcName)) {
|
|
1784
|
-
case 'TrustedHTML':
|
|
1785
|
-
{
|
|
1786
|
-
value = trustedTypesPolicy.createHTML(value);
|
|
1787
|
-
break;
|
|
1788
|
-
}
|
|
1789
|
-
case 'TrustedScriptURL':
|
|
1790
|
-
{
|
|
1791
|
-
value = trustedTypesPolicy.createScriptURL(value);
|
|
1792
|
-
break;
|
|
1793
|
-
}
|
|
1794
|
-
}
|
|
1793
|
+
/* Did the hooks approve of the attribute? */
|
|
1794
|
+
if (!hookEvent.keepAttr) {
|
|
1795
|
+
return 0; // continue
|
|
1795
1796
|
}
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
if (namespaceURI) {
|
|
1801
|
-
currentNode.setAttributeNS(namespaceURI, name, value);
|
|
1802
|
-
} else {
|
|
1803
|
-
/* Fallback to setAttribute() for browser-unrecognized namespaces e.g. "x-schema". */
|
|
1804
|
-
currentNode.setAttribute(name, value);
|
|
1797
|
+
/* Work around a security issue in jQuery 3.0 */
|
|
1798
|
+
if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(/\/>/i, value)) {
|
|
1799
|
+
_removeAttribute(name, currentNode);
|
|
1800
|
+
return 0; // continue
|
|
1805
1801
|
}
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1802
|
+
/* Sanitize attribute content to be template-safe */
|
|
1803
|
+
if (SAFE_FOR_TEMPLATES) {
|
|
1804
|
+
arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], function (expr) {
|
|
1805
|
+
value = stringReplace(value, expr, ' ');
|
|
1806
|
+
});
|
|
1810
1807
|
}
|
|
1811
|
-
|
|
1808
|
+
/* Is `value` valid for this attribute? */
|
|
1809
|
+
var lcTag = transformCaseFunc(currentNode.nodeName);
|
|
1810
|
+
if (!_isValidAttribute(lcTag, lcName, value)) {
|
|
1811
|
+
return 0; // continue
|
|
1812
|
+
}
|
|
1813
|
+
/* Handle attributes that require Trusted Types */
|
|
1814
|
+
if (trustedTypesPolicy && _typeof(trustedTypes) === 'object' && typeof trustedTypes.getAttributeType === 'function') {
|
|
1815
|
+
if (namespaceURI) ;else {
|
|
1816
|
+
switch (trustedTypes.getAttributeType(lcTag, lcName)) {
|
|
1817
|
+
case 'TrustedHTML':
|
|
1818
|
+
{
|
|
1819
|
+
value = trustedTypesPolicy.createHTML(value);
|
|
1820
|
+
break;
|
|
1821
|
+
}
|
|
1822
|
+
case 'TrustedScriptURL':
|
|
1823
|
+
{
|
|
1824
|
+
value = trustedTypesPolicy.createScriptURL(value);
|
|
1825
|
+
break;
|
|
1826
|
+
}
|
|
1827
|
+
}
|
|
1828
|
+
}
|
|
1829
|
+
}
|
|
1830
|
+
/* Handle invalid data-* attribute set by try-catching it */
|
|
1831
|
+
try {
|
|
1832
|
+
if (namespaceURI) {
|
|
1833
|
+
currentNode.setAttributeNS(namespaceURI, name, value);
|
|
1834
|
+
} else {
|
|
1835
|
+
/* Fallback to setAttribute() for browser-unrecognized namespaces e.g. "x-schema". */
|
|
1836
|
+
currentNode.setAttribute(name, value);
|
|
1837
|
+
}
|
|
1838
|
+
if (_isClobbered(currentNode)) {
|
|
1839
|
+
_forceRemove(currentNode);
|
|
1840
|
+
} else {
|
|
1841
|
+
arrayPop(DOMPurify.removed);
|
|
1842
|
+
}
|
|
1843
|
+
} catch (_) {}
|
|
1844
|
+
},
|
|
1845
|
+
_ret;
|
|
1846
|
+
while (l--) {
|
|
1847
|
+
_ret = _loop();
|
|
1848
|
+
if (_ret === 0) continue;
|
|
1812
1849
|
}
|
|
1813
|
-
|
|
1814
1850
|
/* Execute a hook if present */
|
|
1815
|
-
|
|
1851
|
+
_executeHooks(hooks.afterSanitizeAttributes, currentNode, null);
|
|
1816
1852
|
};
|
|
1817
|
-
|
|
1818
1853
|
/**
|
|
1819
1854
|
* _sanitizeShadowDOM
|
|
1820
1855
|
*
|
|
1821
|
-
* @param
|
|
1856
|
+
* @param fragment to iterate over recursively
|
|
1822
1857
|
*/
|
|
1823
1858
|
var _sanitizeShadowDOM = function _sanitizeShadowDOM(fragment) {
|
|
1824
|
-
var shadowNode;
|
|
1825
|
-
var shadowIterator =
|
|
1826
|
-
|
|
1859
|
+
var shadowNode = null;
|
|
1860
|
+
var shadowIterator = _createNodeIterator(fragment);
|
|
1827
1861
|
/* Execute a hook if present */
|
|
1828
|
-
|
|
1862
|
+
_executeHooks(hooks.beforeSanitizeShadowDOM, fragment, null);
|
|
1829
1863
|
while (shadowNode = shadowIterator.nextNode()) {
|
|
1830
1864
|
/* Execute a hook if present */
|
|
1831
|
-
|
|
1832
|
-
|
|
1865
|
+
_executeHooks(hooks.uponSanitizeShadowNode, shadowNode, null);
|
|
1833
1866
|
/* Sanitize tags and elements */
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1867
|
+
_sanitizeElements(shadowNode);
|
|
1868
|
+
/* Check attributes next */
|
|
1869
|
+
_sanitizeAttributes(shadowNode);
|
|
1838
1870
|
/* Deep shadow DOM detected */
|
|
1839
1871
|
if (shadowNode.content instanceof DocumentFragment) {
|
|
1840
1872
|
_sanitizeShadowDOM(shadowNode.content);
|
|
1841
1873
|
}
|
|
1842
|
-
|
|
1843
|
-
/* Check attributes, sanitize if necessary */
|
|
1844
|
-
_sanitizeAttributes(shadowNode);
|
|
1845
1874
|
}
|
|
1846
|
-
|
|
1847
1875
|
/* Execute a hook if present */
|
|
1848
|
-
|
|
1876
|
+
_executeHooks(hooks.afterSanitizeShadowDOM, fragment, null);
|
|
1849
1877
|
};
|
|
1850
|
-
|
|
1851
|
-
/**
|
|
1852
|
-
* Sanitize
|
|
1853
|
-
* Public method providing core sanitation functionality
|
|
1854
|
-
*
|
|
1855
|
-
* @param {String|Node} dirty string or DOM node
|
|
1856
|
-
* @param {Object} configuration object
|
|
1857
|
-
*/
|
|
1858
1878
|
// eslint-disable-next-line complexity
|
|
1859
1879
|
DOMPurify.sanitize = function (dirty) {
|
|
1860
1880
|
var cfg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
1861
|
-
var body;
|
|
1862
|
-
var importedNode;
|
|
1863
|
-
var currentNode;
|
|
1864
|
-
var
|
|
1865
|
-
var returnNode;
|
|
1881
|
+
var body = null;
|
|
1882
|
+
var importedNode = null;
|
|
1883
|
+
var currentNode = null;
|
|
1884
|
+
var returnNode = null;
|
|
1866
1885
|
/* Make sure we have a string to sanitize.
|
|
1867
1886
|
DO NOT return early, as this will return the wrong type if
|
|
1868
1887
|
the user has requested a DOM object rather than a string */
|
|
@@ -1870,7 +1889,6 @@
|
|
|
1870
1889
|
if (IS_EMPTY_INPUT) {
|
|
1871
1890
|
dirty = '<!-->';
|
|
1872
1891
|
}
|
|
1873
|
-
|
|
1874
1892
|
/* Stringify, in case dirty is an object */
|
|
1875
1893
|
if (typeof dirty !== 'string' && !_isNode(dirty)) {
|
|
1876
1894
|
if (typeof dirty.toString === 'function') {
|
|
@@ -1882,28 +1900,16 @@
|
|
|
1882
1900
|
throw typeErrorCreate('toString is not a function');
|
|
1883
1901
|
}
|
|
1884
1902
|
}
|
|
1885
|
-
|
|
1886
|
-
/* Check we can run. Otherwise fall back or ignore */
|
|
1903
|
+
/* Return dirty HTML if DOMPurify cannot run */
|
|
1887
1904
|
if (!DOMPurify.isSupported) {
|
|
1888
|
-
if (_typeof(window.toStaticHTML) === 'object' || typeof window.toStaticHTML === 'function') {
|
|
1889
|
-
if (typeof dirty === 'string') {
|
|
1890
|
-
return window.toStaticHTML(dirty);
|
|
1891
|
-
}
|
|
1892
|
-
if (_isNode(dirty)) {
|
|
1893
|
-
return window.toStaticHTML(dirty.outerHTML);
|
|
1894
|
-
}
|
|
1895
|
-
}
|
|
1896
1905
|
return dirty;
|
|
1897
1906
|
}
|
|
1898
|
-
|
|
1899
1907
|
/* Assign config vars */
|
|
1900
1908
|
if (!SET_CONFIG) {
|
|
1901
1909
|
_parseConfig(cfg);
|
|
1902
1910
|
}
|
|
1903
|
-
|
|
1904
1911
|
/* Clean up removed elements */
|
|
1905
1912
|
DOMPurify.removed = [];
|
|
1906
|
-
|
|
1907
1913
|
/* Check if dirty is correctly typed for IN_PLACE */
|
|
1908
1914
|
if (typeof dirty === 'string') {
|
|
1909
1915
|
IN_PLACE = false;
|
|
@@ -1921,7 +1927,7 @@
|
|
|
1921
1927
|
elements being stripped by the parser */
|
|
1922
1928
|
body = _initDocument('<!---->');
|
|
1923
1929
|
importedNode = body.ownerDocument.importNode(dirty, true);
|
|
1924
|
-
if (importedNode.nodeType ===
|
|
1930
|
+
if (importedNode.nodeType === NODE_TYPE.element && importedNode.nodeName === 'BODY') {
|
|
1925
1931
|
/* Node is already a body, use as is */
|
|
1926
1932
|
body = importedNode;
|
|
1927
1933
|
} else if (importedNode.nodeName === 'HTML') {
|
|
@@ -1937,52 +1943,34 @@
|
|
|
1937
1943
|
dirty.indexOf('<') === -1) {
|
|
1938
1944
|
return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(dirty) : dirty;
|
|
1939
1945
|
}
|
|
1940
|
-
|
|
1941
1946
|
/* Initialize the document to work on */
|
|
1942
1947
|
body = _initDocument(dirty);
|
|
1943
|
-
|
|
1944
1948
|
/* Check we have a DOM node from the data */
|
|
1945
1949
|
if (!body) {
|
|
1946
1950
|
return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : '';
|
|
1947
1951
|
}
|
|
1948
1952
|
}
|
|
1949
|
-
|
|
1950
1953
|
/* Remove first element node (ours) if FORCE_BODY is set */
|
|
1951
1954
|
if (body && FORCE_BODY) {
|
|
1952
1955
|
_forceRemove(body.firstChild);
|
|
1953
1956
|
}
|
|
1954
|
-
|
|
1955
1957
|
/* Get node iterator */
|
|
1956
|
-
var nodeIterator =
|
|
1957
|
-
|
|
1958
|
+
var nodeIterator = _createNodeIterator(IN_PLACE ? dirty : body);
|
|
1958
1959
|
/* Now start iterating over the created document */
|
|
1959
1960
|
while (currentNode = nodeIterator.nextNode()) {
|
|
1960
|
-
/* Fix IE's strange behavior with manipulated textNodes #89 */
|
|
1961
|
-
if (currentNode.nodeType === 3 && currentNode === oldNode) {
|
|
1962
|
-
continue;
|
|
1963
|
-
}
|
|
1964
|
-
|
|
1965
1961
|
/* Sanitize tags and elements */
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1962
|
+
_sanitizeElements(currentNode);
|
|
1963
|
+
/* Check attributes next */
|
|
1964
|
+
_sanitizeAttributes(currentNode);
|
|
1970
1965
|
/* Shadow DOM detected, sanitize it */
|
|
1971
1966
|
if (currentNode.content instanceof DocumentFragment) {
|
|
1972
1967
|
_sanitizeShadowDOM(currentNode.content);
|
|
1973
1968
|
}
|
|
1974
|
-
|
|
1975
|
-
/* Check attributes, sanitize if necessary */
|
|
1976
|
-
_sanitizeAttributes(currentNode);
|
|
1977
|
-
oldNode = currentNode;
|
|
1978
1969
|
}
|
|
1979
|
-
oldNode = null;
|
|
1980
|
-
|
|
1981
1970
|
/* If we sanitized `dirty` in-place, return it. */
|
|
1982
1971
|
if (IN_PLACE) {
|
|
1983
1972
|
return dirty;
|
|
1984
1973
|
}
|
|
1985
|
-
|
|
1986
1974
|
/* Return sanitized string or DOM */
|
|
1987
1975
|
if (RETURN_DOM) {
|
|
1988
1976
|
if (RETURN_DOM_FRAGMENT) {
|
|
@@ -1994,7 +1982,7 @@
|
|
|
1994
1982
|
} else {
|
|
1995
1983
|
returnNode = body;
|
|
1996
1984
|
}
|
|
1997
|
-
if (ALLOWED_ATTR.shadowroot || ALLOWED_ATTR.
|
|
1985
|
+
if (ALLOWED_ATTR.shadowroot || ALLOWED_ATTR.shadowrootmode) {
|
|
1998
1986
|
/*
|
|
1999
1987
|
AdoptNode() is not used because internal state is not reset
|
|
2000
1988
|
(e.g. the past names map of a HTMLFormElement), this is safe
|
|
@@ -2007,52 +1995,27 @@
|
|
|
2007
1995
|
return returnNode;
|
|
2008
1996
|
}
|
|
2009
1997
|
var serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML;
|
|
2010
|
-
|
|
2011
1998
|
/* Serialize doctype if allowed */
|
|
2012
1999
|
if (WHOLE_DOCUMENT && ALLOWED_TAGS['!doctype'] && body.ownerDocument && body.ownerDocument.doctype && body.ownerDocument.doctype.name && regExpTest(DOCTYPE_NAME, body.ownerDocument.doctype.name)) {
|
|
2013
2000
|
serializedHTML = '<!DOCTYPE ' + body.ownerDocument.doctype.name + '>\n' + serializedHTML;
|
|
2014
2001
|
}
|
|
2015
|
-
|
|
2016
2002
|
/* Sanitize final string template-safe */
|
|
2017
2003
|
if (SAFE_FOR_TEMPLATES) {
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2004
|
+
arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], function (expr) {
|
|
2005
|
+
serializedHTML = stringReplace(serializedHTML, expr, ' ');
|
|
2006
|
+
});
|
|
2021
2007
|
}
|
|
2022
2008
|
return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(serializedHTML) : serializedHTML;
|
|
2023
2009
|
};
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
* Public method to set the configuration once
|
|
2027
|
-
* setConfig
|
|
2028
|
-
*
|
|
2029
|
-
* @param {Object} cfg configuration object
|
|
2030
|
-
*/
|
|
2031
|
-
DOMPurify.setConfig = function (cfg) {
|
|
2010
|
+
DOMPurify.setConfig = function () {
|
|
2011
|
+
var cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
2032
2012
|
_parseConfig(cfg);
|
|
2033
2013
|
SET_CONFIG = true;
|
|
2034
2014
|
};
|
|
2035
|
-
|
|
2036
|
-
/**
|
|
2037
|
-
* Public method to remove the configuration
|
|
2038
|
-
* clearConfig
|
|
2039
|
-
*
|
|
2040
|
-
*/
|
|
2041
2015
|
DOMPurify.clearConfig = function () {
|
|
2042
2016
|
CONFIG = null;
|
|
2043
2017
|
SET_CONFIG = false;
|
|
2044
2018
|
};
|
|
2045
|
-
|
|
2046
|
-
/**
|
|
2047
|
-
* Public method to check if an attribute value is valid.
|
|
2048
|
-
* Uses last set config, if any. Otherwise, uses config defaults.
|
|
2049
|
-
* isValidAttribute
|
|
2050
|
-
*
|
|
2051
|
-
* @param {string} tag Tag name of containing element.
|
|
2052
|
-
* @param {string} attr Attribute name.
|
|
2053
|
-
* @param {string} value Attribute value.
|
|
2054
|
-
* @return {Boolean} Returns true if `value` is valid. Otherwise, returns false.
|
|
2055
|
-
*/
|
|
2056
2019
|
DOMPurify.isValidAttribute = function (tag, attr, value) {
|
|
2057
2020
|
/* Initialize shared config vars if necessary. */
|
|
2058
2021
|
if (!CONFIG) {
|
|
@@ -2062,55 +2025,24 @@
|
|
|
2062
2025
|
var lcName = transformCaseFunc(attr);
|
|
2063
2026
|
return _isValidAttribute(lcTag, lcName, value);
|
|
2064
2027
|
};
|
|
2065
|
-
|
|
2066
|
-
/**
|
|
2067
|
-
* AddHook
|
|
2068
|
-
* Public method to add DOMPurify hooks
|
|
2069
|
-
*
|
|
2070
|
-
* @param {String} entryPoint entry point for the hook to add
|
|
2071
|
-
* @param {Function} hookFunction function to execute
|
|
2072
|
-
*/
|
|
2073
2028
|
DOMPurify.addHook = function (entryPoint, hookFunction) {
|
|
2074
2029
|
if (typeof hookFunction !== 'function') {
|
|
2075
2030
|
return;
|
|
2076
2031
|
}
|
|
2077
|
-
hooks[entryPoint] = hooks[entryPoint] || [];
|
|
2078
2032
|
arrayPush(hooks[entryPoint], hookFunction);
|
|
2079
2033
|
};
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
* (pops it from the stack of hooks if more are present)
|
|
2085
|
-
*
|
|
2086
|
-
* @param {String} entryPoint entry point for the hook to remove
|
|
2087
|
-
* @return {Function} removed(popped) hook
|
|
2088
|
-
*/
|
|
2089
|
-
DOMPurify.removeHook = function (entryPoint) {
|
|
2090
|
-
if (hooks[entryPoint]) {
|
|
2091
|
-
return arrayPop(hooks[entryPoint]);
|
|
2034
|
+
DOMPurify.removeHook = function (entryPoint, hookFunction) {
|
|
2035
|
+
if (hookFunction !== undefined) {
|
|
2036
|
+
var index = arrayLastIndexOf(hooks[entryPoint], hookFunction);
|
|
2037
|
+
return index === -1 ? undefined : arraySplice(hooks[entryPoint], index, 1)[0];
|
|
2092
2038
|
}
|
|
2039
|
+
return arrayPop(hooks[entryPoint]);
|
|
2093
2040
|
};
|
|
2094
|
-
|
|
2095
|
-
/**
|
|
2096
|
-
* RemoveHooks
|
|
2097
|
-
* Public method to remove all DOMPurify hooks at a given entryPoint
|
|
2098
|
-
*
|
|
2099
|
-
* @param {String} entryPoint entry point for the hooks to remove
|
|
2100
|
-
*/
|
|
2101
2041
|
DOMPurify.removeHooks = function (entryPoint) {
|
|
2102
|
-
|
|
2103
|
-
hooks[entryPoint] = [];
|
|
2104
|
-
}
|
|
2042
|
+
hooks[entryPoint] = [];
|
|
2105
2043
|
};
|
|
2106
|
-
|
|
2107
|
-
/**
|
|
2108
|
-
* RemoveAllHooks
|
|
2109
|
-
* Public method to remove all DOMPurify hooks
|
|
2110
|
-
*
|
|
2111
|
-
*/
|
|
2112
2044
|
DOMPurify.removeAllHooks = function () {
|
|
2113
|
-
hooks =
|
|
2045
|
+
hooks = _createHooksMap();
|
|
2114
2046
|
};
|
|
2115
2047
|
return DOMPurify;
|
|
2116
2048
|
}
|
|
@@ -4940,10 +4872,10 @@
|
|
|
4940
4872
|
* @type {object} Settings object
|
|
4941
4873
|
* @property {string} [stablePrefix=c4d] stable prefix
|
|
4942
4874
|
* @property {string} [prefix=cds] core Carbon prefix
|
|
4943
|
-
* Carbon for IBM.com v2.
|
|
4875
|
+
* Carbon for IBM.com v2.25.0',
|
|
4944
4876
|
*/
|
|
4945
4877
|
var settings = {
|
|
4946
|
-
version: 'Carbon for IBM.com v2.
|
|
4878
|
+
version: 'Carbon for IBM.com v2.25.0',
|
|
4947
4879
|
stablePrefix: 'c4d',
|
|
4948
4880
|
prefix: 'cds'
|
|
4949
4881
|
};
|