tinymce-rails 7.7.0 → 7.8.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.
- checksums.yaml +4 -4
- data/app/assets/source/tinymce/tinymce.js +201 -378
- data/lib/tinymce/rails/version.rb +2 -2
- data/vendor/assets/javascripts/tinymce/icons/default/icons.js +1 -1
- data/vendor/assets/javascripts/tinymce/models/dom/model.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/accordion/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/advlist/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/anchor/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/autolink/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/autoresize/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/autosave/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/charmap/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/code/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/codesample/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/directionality/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/emoticons/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/fullscreen/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/help/plugin.js +2 -2
- data/vendor/assets/javascripts/tinymce/plugins/image/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/importcss/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/insertdatetime/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/link/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/lists/plugin.js +2 -2
- data/vendor/assets/javascripts/tinymce/plugins/media/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/nonbreaking/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/pagebreak/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/preview/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/quickbars/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/save/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/searchreplace/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/table/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/visualblocks/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/visualchars/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/wordcount/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide/content.css +1 -3
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide/content.inline.css +1 -3
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide/content.inline.js +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide/content.inline.min.css +1 -3
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide/content.js +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide/content.min.css +1 -3
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide/skin.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide/skin.js +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide/skin.min.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide-dark/content.css +1 -3
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide-dark/content.inline.css +1 -3
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide-dark/content.inline.js +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide-dark/content.inline.min.css +1 -3
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide-dark/content.js +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide-dark/content.min.css +1 -3
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide-dark/skin.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide-dark/skin.js +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide-dark/skin.min.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/content.css +1 -3
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/content.inline.css +1 -3
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/content.inline.js +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/content.inline.min.css +1 -3
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/content.js +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/content.min.css +1 -3
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/skin.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/skin.js +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/skin.min.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/content.css +1 -3
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/content.inline.css +1 -3
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/content.inline.js +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/content.inline.min.css +1 -3
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/content.js +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/content.min.css +1 -3
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/skin.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/skin.js +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/skin.min.css +1 -1
- data/vendor/assets/javascripts/tinymce/themes/silver/theme.js +136 -190
- data/vendor/assets/javascripts/tinymce/tinymce.d.ts +40 -3
- data/vendor/assets/javascripts/tinymce/tinymce.js +122 -176
- metadata +2 -2
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* TinyMCE version 7.
|
2
|
+
* TinyMCE version 7.8.0 (TBD)
|
3
3
|
*/
|
4
4
|
|
5
5
|
(function () {
|
@@ -7210,6 +7210,8 @@
|
|
7210
7210
|
},
|
7211
7211
|
default: []
|
7212
7212
|
});
|
7213
|
+
registerOption('extended_mathml_attributes', { processor: 'string[]' });
|
7214
|
+
registerOption('extended_mathml_elements', { processor: 'string[]' });
|
7213
7215
|
registerOption('inline_boundaries', {
|
7214
7216
|
processor: 'boolean',
|
7215
7217
|
default: true
|
@@ -7248,6 +7250,11 @@
|
|
7248
7250
|
});
|
7249
7251
|
registerOption('event_root', { processor: 'string' });
|
7250
7252
|
registerOption('service_message', { processor: 'string' });
|
7253
|
+
registerOption('onboarding', {
|
7254
|
+
processor: 'boolean',
|
7255
|
+
default: true
|
7256
|
+
});
|
7257
|
+
registerOption('tiny_cloud_entry_url', { processor: 'string' });
|
7251
7258
|
registerOption('theme', {
|
7252
7259
|
processor: value => value === false || isString(value) || isFunction(value),
|
7253
7260
|
default: 'silver'
|
@@ -8035,7 +8042,7 @@
|
|
8035
8042
|
}
|
8036
8043
|
};
|
8037
8044
|
const startBlink = () => {
|
8038
|
-
cursorInterval = setInterval(() => {
|
8045
|
+
cursorInterval = window.setInterval(() => {
|
8039
8046
|
lastVisualCaret.on(caretState => {
|
8040
8047
|
if (hasFocus()) {
|
8041
8048
|
dom.toggleClass(caretState.caret, 'mce-visual-caret-hidden');
|
@@ -9387,10 +9394,11 @@
|
|
9387
9394
|
'div[data-ephox-embed-iri]',
|
9388
9395
|
'div.tiny-pageembed',
|
9389
9396
|
'div.mce-toc',
|
9390
|
-
'div[data-mce-toc]'
|
9397
|
+
'div[data-mce-toc]',
|
9398
|
+
'div.mce-footnotes'
|
9391
9399
|
];
|
9392
9400
|
const isZeroWidth = elem => isText$c(elem) && get$3(elem) === ZWSP$1;
|
9393
|
-
const context = (editor, elem, wrapName, nodeName) =>
|
9401
|
+
const context = (editor, elem, wrapName, nodeName) => parentElement(elem).fold(() => 'skipping', parent => {
|
9394
9402
|
if (nodeName === 'br' || isZeroWidth(elem)) {
|
9395
9403
|
return 'valid';
|
9396
9404
|
} else if (isAnnotation(elem)) {
|
@@ -9719,13 +9727,13 @@
|
|
9719
9727
|
if (!isNumber(time)) {
|
9720
9728
|
time = 0;
|
9721
9729
|
}
|
9722
|
-
return setTimeout(callback, time);
|
9730
|
+
return window.setTimeout(callback, time);
|
9723
9731
|
};
|
9724
9732
|
const wrappedSetInterval = (callback, time) => {
|
9725
9733
|
if (!isNumber(time)) {
|
9726
9734
|
time = 0;
|
9727
9735
|
}
|
9728
|
-
return setInterval(callback, time);
|
9736
|
+
return window.setInterval(callback, time);
|
9729
9737
|
};
|
9730
9738
|
const Delay = {
|
9731
9739
|
setEditorTimeout: (editor, callback, time) => {
|
@@ -9740,7 +9748,7 @@
|
|
9740
9748
|
if (!editor.removed) {
|
9741
9749
|
callback();
|
9742
9750
|
} else {
|
9743
|
-
clearInterval(timer);
|
9751
|
+
window.clearInterval(timer);
|
9744
9752
|
}
|
9745
9753
|
}, time);
|
9746
9754
|
return timer;
|
@@ -11005,10 +11013,11 @@
|
|
11005
11013
|
};
|
11006
11014
|
const scrollToMarker = (editor, marker, viewHeight, alignToTop, doc) => {
|
11007
11015
|
const pos = marker.pos;
|
11016
|
+
const scrollMargin = 30;
|
11008
11017
|
if (alignToTop) {
|
11009
|
-
to(pos.left, pos.top, doc);
|
11018
|
+
to(pos.left, Math.max(0, pos.top - scrollMargin), doc);
|
11010
11019
|
} else {
|
11011
|
-
const y = pos.top - viewHeight + marker.height;
|
11020
|
+
const y = pos.top - viewHeight + marker.height + scrollMargin;
|
11012
11021
|
to(-editor.getBody().getBoundingClientRect().left, y, doc);
|
11013
11022
|
}
|
11014
11023
|
};
|
@@ -15314,7 +15323,7 @@
|
|
15314
15323
|
}
|
15315
15324
|
};
|
15316
15325
|
|
15317
|
-
/*! @license DOMPurify 3.
|
15326
|
+
/*! @license DOMPurify 3.2.4 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.2.4/LICENSE */
|
15318
15327
|
|
15319
15328
|
const {
|
15320
15329
|
entries,
|
@@ -15353,8 +15362,10 @@
|
|
15353
15362
|
};
|
15354
15363
|
}
|
15355
15364
|
const arrayForEach = unapply(Array.prototype.forEach);
|
15365
|
+
const arrayLastIndexOf = unapply(Array.prototype.lastIndexOf);
|
15356
15366
|
const arrayPop = unapply(Array.prototype.pop);
|
15357
15367
|
const arrayPush = unapply(Array.prototype.push);
|
15368
|
+
const arraySplice = unapply(Array.prototype.splice);
|
15358
15369
|
const stringToLowerCase = unapply(String.prototype.toLowerCase);
|
15359
15370
|
const stringToString = unapply(String.prototype.toString);
|
15360
15371
|
const stringMatch = unapply(String.prototype.match);
|
@@ -15364,12 +15375,11 @@
|
|
15364
15375
|
const objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty);
|
15365
15376
|
const regExpTest = unapply(RegExp.prototype.test);
|
15366
15377
|
const typeErrorCreate = unconstruct(TypeError);
|
15367
|
-
|
15368
15378
|
/**
|
15369
15379
|
* Creates a new function that calls the given function with a specified thisArg and arguments.
|
15370
15380
|
*
|
15371
|
-
* @param
|
15372
|
-
* @returns
|
15381
|
+
* @param func - The function to be wrapped and called.
|
15382
|
+
* @returns A new function that calls the given function with a specified thisArg and arguments.
|
15373
15383
|
*/
|
15374
15384
|
function unapply(func) {
|
15375
15385
|
return function (thisArg) {
|
@@ -15379,12 +15389,11 @@
|
|
15379
15389
|
return apply(func, thisArg, args);
|
15380
15390
|
};
|
15381
15391
|
}
|
15382
|
-
|
15383
15392
|
/**
|
15384
15393
|
* Creates a new function that constructs an instance of the given constructor function with the provided arguments.
|
15385
15394
|
*
|
15386
|
-
* @param
|
15387
|
-
* @returns
|
15395
|
+
* @param func - The constructor function to be wrapped and called.
|
15396
|
+
* @returns A new function that constructs an instance of the given constructor function with the provided arguments.
|
15388
15397
|
*/
|
15389
15398
|
function unconstruct(func) {
|
15390
15399
|
return function () {
|
@@ -15394,14 +15403,13 @@
|
|
15394
15403
|
return construct(func, args);
|
15395
15404
|
};
|
15396
15405
|
}
|
15397
|
-
|
15398
15406
|
/**
|
15399
15407
|
* Add properties to a lookup table
|
15400
15408
|
*
|
15401
|
-
* @param
|
15402
|
-
* @param
|
15403
|
-
* @param
|
15404
|
-
* @returns
|
15409
|
+
* @param set - The set to which elements will be added.
|
15410
|
+
* @param array - The array containing elements to be added to the set.
|
15411
|
+
* @param transformCaseFunc - An optional function to transform the case of each element before adding to the set.
|
15412
|
+
* @returns The modified set with added elements.
|
15405
15413
|
*/
|
15406
15414
|
function addToSet(set, array) {
|
15407
15415
|
let transformCaseFunc = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : stringToLowerCase;
|
@@ -15428,12 +15436,11 @@
|
|
15428
15436
|
}
|
15429
15437
|
return set;
|
15430
15438
|
}
|
15431
|
-
|
15432
15439
|
/**
|
15433
15440
|
* Clean up an array to harden against CSPP
|
15434
15441
|
*
|
15435
|
-
* @param
|
15436
|
-
* @returns
|
15442
|
+
* @param array - The array to be cleaned.
|
15443
|
+
* @returns The cleaned version of the array
|
15437
15444
|
*/
|
15438
15445
|
function cleanArray(array) {
|
15439
15446
|
for (let index = 0; index < array.length; index++) {
|
@@ -15444,12 +15451,11 @@
|
|
15444
15451
|
}
|
15445
15452
|
return array;
|
15446
15453
|
}
|
15447
|
-
|
15448
15454
|
/**
|
15449
15455
|
* Shallow clone an object
|
15450
15456
|
*
|
15451
|
-
* @param
|
15452
|
-
* @returns
|
15457
|
+
* @param object - The object to be cloned.
|
15458
|
+
* @returns A new object that copies the original.
|
15453
15459
|
*/
|
15454
15460
|
function clone(object) {
|
15455
15461
|
const newObject = create$7(null);
|
@@ -15467,13 +15473,12 @@
|
|
15467
15473
|
}
|
15468
15474
|
return newObject;
|
15469
15475
|
}
|
15470
|
-
|
15471
15476
|
/**
|
15472
15477
|
* This method automatically checks if the prop is function or getter and behaves accordingly.
|
15473
15478
|
*
|
15474
|
-
* @param
|
15475
|
-
* @param
|
15476
|
-
* @returns
|
15479
|
+
* @param object - The object to look up the getter function in its prototype chain.
|
15480
|
+
* @param prop - The property name for which to find the getter function.
|
15481
|
+
* @returns The getter function found in the prototype chain or a fallback function.
|
15477
15482
|
*/
|
15478
15483
|
function lookupGetter(object, prop) {
|
15479
15484
|
while (object !== null) {
|
@@ -15495,18 +15500,14 @@
|
|
15495
15500
|
}
|
15496
15501
|
|
15497
15502
|
const 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']);
|
15498
|
-
|
15499
|
-
// SVG
|
15500
15503
|
const 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']);
|
15501
15504
|
const 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']);
|
15502
|
-
|
15503
15505
|
// List of SVG elements that are disallowed by default.
|
15504
15506
|
// We still need to know them so that we can do namespace
|
15505
15507
|
// checks properly in case one wants to add them to
|
15506
15508
|
// allow-list.
|
15507
15509
|
const 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']);
|
15508
15510
|
const 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']);
|
15509
|
-
|
15510
15511
|
// Similarly to SVG, we want to know all MathML elements,
|
15511
15512
|
// even those that we disallow by default.
|
15512
15513
|
const mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']);
|
@@ -15520,8 +15521,8 @@
|
|
15520
15521
|
// eslint-disable-next-line unicorn/better-regex
|
15521
15522
|
const MUSTACHE_EXPR = seal(/\{\{[\w\W]*|[\w\W]*\}\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode
|
15522
15523
|
const ERB_EXPR = seal(/<%[\w\W]*|[\w\W]*%>/gm);
|
15523
|
-
const TMPLIT_EXPR = seal(
|
15524
|
-
const DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]
|
15524
|
+
const TMPLIT_EXPR = seal(/\$\{[\w\W]*/gm); // eslint-disable-line unicorn/better-regex
|
15525
|
+
const DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]+$/); // eslint-disable-line no-useless-escape
|
15525
15526
|
const ARIA_ATTR = seal(/^aria-[\-\w]+$/); // eslint-disable-line no-useless-escape
|
15526
15527
|
const 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
|
15527
15528
|
);
|
@@ -15533,18 +15534,19 @@
|
|
15533
15534
|
|
15534
15535
|
var EXPRESSIONS = /*#__PURE__*/Object.freeze({
|
15535
15536
|
__proto__: null,
|
15536
|
-
MUSTACHE_EXPR: MUSTACHE_EXPR,
|
15537
|
-
ERB_EXPR: ERB_EXPR,
|
15538
|
-
TMPLIT_EXPR: TMPLIT_EXPR,
|
15539
|
-
DATA_ATTR: DATA_ATTR,
|
15540
15537
|
ARIA_ATTR: ARIA_ATTR,
|
15541
|
-
IS_ALLOWED_URI: IS_ALLOWED_URI,
|
15542
|
-
IS_SCRIPT_OR_DATA: IS_SCRIPT_OR_DATA,
|
15543
15538
|
ATTR_WHITESPACE: ATTR_WHITESPACE,
|
15539
|
+
CUSTOM_ELEMENT: CUSTOM_ELEMENT,
|
15540
|
+
DATA_ATTR: DATA_ATTR,
|
15544
15541
|
DOCTYPE_NAME: DOCTYPE_NAME,
|
15545
|
-
|
15542
|
+
ERB_EXPR: ERB_EXPR,
|
15543
|
+
IS_ALLOWED_URI: IS_ALLOWED_URI,
|
15544
|
+
IS_SCRIPT_OR_DATA: IS_SCRIPT_OR_DATA,
|
15545
|
+
MUSTACHE_EXPR: MUSTACHE_EXPR,
|
15546
|
+
TMPLIT_EXPR: TMPLIT_EXPR
|
15546
15547
|
});
|
15547
15548
|
|
15549
|
+
/* eslint-disable @typescript-eslint/indent */
|
15548
15550
|
// https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType
|
15549
15551
|
const NODE_TYPE = {
|
15550
15552
|
element: 1,
|
@@ -15565,20 +15567,18 @@
|
|
15565
15567
|
const getGlobal = function getGlobal() {
|
15566
15568
|
return typeof window === 'undefined' ? null : window;
|
15567
15569
|
};
|
15568
|
-
|
15569
15570
|
/**
|
15570
15571
|
* Creates a no-op policy for internal use only.
|
15571
15572
|
* Don't export this function outside this module!
|
15572
|
-
* @param
|
15573
|
-
* @param
|
15574
|
-
* @return
|
15573
|
+
* @param trustedTypes The policy factory.
|
15574
|
+
* @param purifyHostElement The Script element used to load DOMPurify (to determine policy name suffix).
|
15575
|
+
* @return The policy created (or null, if Trusted Types
|
15575
15576
|
* are not supported or creating the policy failed).
|
15576
15577
|
*/
|
15577
15578
|
const _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes, purifyHostElement) {
|
15578
15579
|
if (typeof trustedTypes !== 'object' || typeof trustedTypes.createPolicy !== 'function') {
|
15579
15580
|
return null;
|
15580
15581
|
}
|
15581
|
-
|
15582
15582
|
// Allow the callers to control the unique policy name
|
15583
15583
|
// by adding a data-tt-policy-suffix to the script element with the DOMPurify.
|
15584
15584
|
// Policy creation with duplicate names throws in Trusted Types.
|
@@ -15605,22 +15605,25 @@
|
|
15605
15605
|
return null;
|
15606
15606
|
}
|
15607
15607
|
};
|
15608
|
+
const _createHooksMap = function _createHooksMap() {
|
15609
|
+
return {
|
15610
|
+
afterSanitizeAttributes: [],
|
15611
|
+
afterSanitizeElements: [],
|
15612
|
+
afterSanitizeShadowDOM: [],
|
15613
|
+
beforeSanitizeAttributes: [],
|
15614
|
+
beforeSanitizeElements: [],
|
15615
|
+
beforeSanitizeShadowDOM: [],
|
15616
|
+
uponSanitizeAttribute: [],
|
15617
|
+
uponSanitizeElement: [],
|
15618
|
+
uponSanitizeShadowNode: []
|
15619
|
+
};
|
15620
|
+
};
|
15608
15621
|
function createDOMPurify() {
|
15609
15622
|
let window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal();
|
15610
15623
|
const DOMPurify = root => createDOMPurify(root);
|
15611
|
-
|
15612
|
-
/**
|
15613
|
-
* Version label, exposed for easier checks
|
15614
|
-
* if DOMPurify is up to date or not
|
15615
|
-
*/
|
15616
|
-
DOMPurify.version = '3.1.7';
|
15617
|
-
|
15618
|
-
/**
|
15619
|
-
* Array of elements that DOMPurify removed during sanitation.
|
15620
|
-
* Empty if nothing was removed.
|
15621
|
-
*/
|
15624
|
+
DOMPurify.version = '3.2.4';
|
15622
15625
|
DOMPurify.removed = [];
|
15623
|
-
if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document) {
|
15626
|
+
if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document || !window.Element) {
|
15624
15627
|
// Not running in a browser, provide a factory function
|
15625
15628
|
// so that you can pass your own Window
|
15626
15629
|
DOMPurify.isSupported = false;
|
@@ -15648,7 +15651,6 @@
|
|
15648
15651
|
const getNextSibling = lookupGetter(ElementPrototype, 'nextSibling');
|
15649
15652
|
const getChildNodes = lookupGetter(ElementPrototype, 'childNodes');
|
15650
15653
|
const getParentNode = lookupGetter(ElementPrototype, 'parentNode');
|
15651
|
-
|
15652
15654
|
// As per issue #47, the web-components registry is inherited by a
|
15653
15655
|
// new document created via createHTMLDocument. As per the spec
|
15654
15656
|
// (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries)
|
@@ -15672,8 +15674,7 @@
|
|
15672
15674
|
const {
|
15673
15675
|
importNode
|
15674
15676
|
} = originalDocument;
|
15675
|
-
let hooks =
|
15676
|
-
|
15677
|
+
let hooks = _createHooksMap();
|
15677
15678
|
/**
|
15678
15679
|
* Expose whether this browser supports running the full DOMPurify.
|
15679
15680
|
*/
|
@@ -15691,22 +15692,18 @@
|
|
15691
15692
|
let {
|
15692
15693
|
IS_ALLOWED_URI: IS_ALLOWED_URI$1
|
15693
15694
|
} = EXPRESSIONS;
|
15694
|
-
|
15695
15695
|
/**
|
15696
15696
|
* We consider the elements and attributes below to be safe. Ideally
|
15697
15697
|
* don't add any new ones but feel free to remove unwanted ones.
|
15698
15698
|
*/
|
15699
|
-
|
15700
15699
|
/* allowed element names */
|
15701
15700
|
let ALLOWED_TAGS = null;
|
15702
15701
|
const DEFAULT_ALLOWED_TAGS = addToSet({}, [...html$1, ...svg$1, ...svgFilters, ...mathMl$1, ...text]);
|
15703
|
-
|
15704
15702
|
/* Allowed attribute names */
|
15705
15703
|
let ALLOWED_ATTR = null;
|
15706
15704
|
const DEFAULT_ALLOWED_ATTR = addToSet({}, [...html, ...svg, ...mathMl, ...xml]);
|
15707
|
-
|
15708
15705
|
/*
|
15709
|
-
* Configure how
|
15706
|
+
* Configure how DOMPurify should handle custom elements and their attributes as well as customized built-in elements.
|
15710
15707
|
* @property {RegExp|Function|null} tagNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any custom elements)
|
15711
15708
|
* @property {RegExp|Function|null} attributeNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any attributes not on the allow list)
|
15712
15709
|
* @property {boolean} allowCustomizedBuiltInElements allow custom elements derived from built-ins if they pass CUSTOM_ELEMENT_HANDLING.tagNameCheck. Default: `false`.
|
@@ -15731,65 +15728,49 @@
|
|
15731
15728
|
value: false
|
15732
15729
|
}
|
15733
15730
|
}));
|
15734
|
-
|
15735
15731
|
/* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */
|
15736
15732
|
let FORBID_TAGS = null;
|
15737
|
-
|
15738
15733
|
/* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */
|
15739
15734
|
let FORBID_ATTR = null;
|
15740
|
-
|
15741
15735
|
/* Decide if ARIA attributes are okay */
|
15742
15736
|
let ALLOW_ARIA_ATTR = true;
|
15743
|
-
|
15744
15737
|
/* Decide if custom data attributes are okay */
|
15745
15738
|
let ALLOW_DATA_ATTR = true;
|
15746
|
-
|
15747
15739
|
/* Decide if unknown protocols are okay */
|
15748
15740
|
let ALLOW_UNKNOWN_PROTOCOLS = false;
|
15749
|
-
|
15750
15741
|
/* Decide if self-closing tags in attributes are allowed.
|
15751
15742
|
* Usually removed due to a mXSS issue in jQuery 3.0 */
|
15752
15743
|
let ALLOW_SELF_CLOSE_IN_ATTR = true;
|
15753
|
-
|
15754
15744
|
/* Output should be safe for common template engines.
|
15755
15745
|
* This means, DOMPurify removes data attributes, mustaches and ERB
|
15756
15746
|
*/
|
15757
15747
|
let SAFE_FOR_TEMPLATES = false;
|
15758
|
-
|
15759
15748
|
/* Output should be safe even for XML used within HTML and alike.
|
15760
15749
|
* This means, DOMPurify removes comments when containing risky content.
|
15761
15750
|
*/
|
15762
15751
|
let SAFE_FOR_XML = true;
|
15763
|
-
|
15764
15752
|
/* Decide if document with <html>... should be returned */
|
15765
15753
|
let WHOLE_DOCUMENT = false;
|
15766
|
-
|
15767
15754
|
/* Track whether config is already set on this instance of DOMPurify. */
|
15768
15755
|
let SET_CONFIG = false;
|
15769
|
-
|
15770
15756
|
/* Decide if all elements (e.g. style, script) must be children of
|
15771
15757
|
* document.body. By default, browsers might move them to document.head */
|
15772
15758
|
let FORCE_BODY = false;
|
15773
|
-
|
15774
15759
|
/* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html
|
15775
15760
|
* string (or a TrustedHTML object if Trusted Types are supported).
|
15776
15761
|
* If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead
|
15777
15762
|
*/
|
15778
15763
|
let RETURN_DOM = false;
|
15779
|
-
|
15780
15764
|
/* Decide if a DOM `DocumentFragment` should be returned, instead of a html
|
15781
15765
|
* string (or a TrustedHTML object if Trusted Types are supported) */
|
15782
15766
|
let RETURN_DOM_FRAGMENT = false;
|
15783
|
-
|
15784
15767
|
/* Try to return a Trusted Type object instead of a string, return a string in
|
15785
15768
|
* case Trusted Types are not supported */
|
15786
15769
|
let RETURN_TRUSTED_TYPE = false;
|
15787
|
-
|
15788
15770
|
/* Output should be free from DOM clobbering attacks?
|
15789
15771
|
* This sanitizes markups named with colliding, clobberable built-in DOM APIs.
|
15790
15772
|
*/
|
15791
15773
|
let SANITIZE_DOM = true;
|
15792
|
-
|
15793
15774
|
/* Achieve full DOM Clobbering protection by isolating the namespace of named
|
15794
15775
|
* properties and JS variables, mitigating attacks that abuse the HTML/DOM spec rules.
|
15795
15776
|
*
|
@@ -15805,25 +15786,19 @@
|
|
15805
15786
|
*/
|
15806
15787
|
let SANITIZE_NAMED_PROPS = false;
|
15807
15788
|
const SANITIZE_NAMED_PROPS_PREFIX = 'user-content-';
|
15808
|
-
|
15809
15789
|
/* Keep element content when removing element? */
|
15810
15790
|
let KEEP_CONTENT = true;
|
15811
|
-
|
15812
15791
|
/* If a `Node` is passed to sanitize(), then performs sanitization in-place instead
|
15813
15792
|
* of importing it into a new Document and returning a sanitized copy */
|
15814
15793
|
let IN_PLACE = false;
|
15815
|
-
|
15816
15794
|
/* Allow usage of profiles like html, svg and mathMl */
|
15817
15795
|
let USE_PROFILES = {};
|
15818
|
-
|
15819
15796
|
/* Tags to ignore content of when KEEP_CONTENT is true */
|
15820
15797
|
let FORBID_CONTENTS = null;
|
15821
15798
|
const 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']);
|
15822
|
-
|
15823
15799
|
/* Tags that are safe for data: URIs */
|
15824
15800
|
let DATA_URI_TAGS = null;
|
15825
15801
|
const DEFAULT_DATA_URI_TAGS = addToSet({}, ['audio', 'video', 'img', 'source', 'image', 'track']);
|
15826
|
-
|
15827
15802
|
/* Attributes safe for values like "javascript:" */
|
15828
15803
|
let URI_SAFE_ATTRIBUTES = null;
|
15829
15804
|
const DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ['alt', 'class', 'for', 'id', 'label', 'name', 'pattern', 'placeholder', 'role', 'summary', 'title', 'value', 'style', 'xmlns']);
|
@@ -15833,32 +15808,33 @@
|
|
15833
15808
|
/* Document namespace */
|
15834
15809
|
let NAMESPACE = HTML_NAMESPACE;
|
15835
15810
|
let IS_EMPTY_INPUT = false;
|
15836
|
-
|
15837
15811
|
/* Allowed XHTML+XML namespaces */
|
15838
15812
|
let ALLOWED_NAMESPACES = null;
|
15839
15813
|
const DEFAULT_ALLOWED_NAMESPACES = addToSet({}, [MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE], stringToString);
|
15840
|
-
|
15814
|
+
let MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ['mi', 'mo', 'mn', 'ms', 'mtext']);
|
15815
|
+
let HTML_INTEGRATION_POINTS = addToSet({}, ['annotation-xml']);
|
15816
|
+
// Certain elements are allowed in both SVG and HTML
|
15817
|
+
// namespace. We need to specify them explicitly
|
15818
|
+
// so that they don't get erroneously deleted from
|
15819
|
+
// HTML namespace.
|
15820
|
+
const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, ['title', 'style', 'font', 'a', 'script']);
|
15841
15821
|
/* Parsing of strict XHTML documents */
|
15842
15822
|
let PARSER_MEDIA_TYPE = null;
|
15843
15823
|
const SUPPORTED_PARSER_MEDIA_TYPES = ['application/xhtml+xml', 'text/html'];
|
15844
15824
|
const DEFAULT_PARSER_MEDIA_TYPE = 'text/html';
|
15845
15825
|
let transformCaseFunc = null;
|
15846
|
-
|
15847
15826
|
/* Keep a reference to config to pass to hooks */
|
15848
15827
|
let CONFIG = null;
|
15849
|
-
|
15850
15828
|
/* Ideally, do not touch anything below this line */
|
15851
15829
|
/* ______________________________________________ */
|
15852
|
-
|
15853
15830
|
const formElement = document.createElement('form');
|
15854
15831
|
const isRegexOrFunction = function isRegexOrFunction(testValue) {
|
15855
15832
|
return testValue instanceof RegExp || testValue instanceof Function;
|
15856
15833
|
};
|
15857
|
-
|
15858
15834
|
/**
|
15859
15835
|
* _parseConfig
|
15860
15836
|
*
|
15861
|
-
* @param
|
15837
|
+
* @param cfg optional config literal
|
15862
15838
|
*/
|
15863
15839
|
// eslint-disable-next-line complexity
|
15864
15840
|
const _parseConfig = function _parseConfig() {
|
@@ -15866,39 +15842,23 @@
|
|
15866
15842
|
if (CONFIG && CONFIG === cfg) {
|
15867
15843
|
return;
|
15868
15844
|
}
|
15869
|
-
|
15870
15845
|
/* Shield configuration object from tampering */
|
15871
15846
|
if (!cfg || typeof cfg !== 'object') {
|
15872
15847
|
cfg = {};
|
15873
15848
|
}
|
15874
|
-
|
15875
15849
|
/* Shield configuration object from prototype pollution */
|
15876
15850
|
cfg = clone(cfg);
|
15877
15851
|
PARSER_MEDIA_TYPE =
|
15878
15852
|
// eslint-disable-next-line unicorn/prefer-includes
|
15879
15853
|
SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? DEFAULT_PARSER_MEDIA_TYPE : cfg.PARSER_MEDIA_TYPE;
|
15880
|
-
|
15881
15854
|
// HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is.
|
15882
15855
|
transformCaseFunc = PARSER_MEDIA_TYPE === 'application/xhtml+xml' ? stringToString : stringToLowerCase;
|
15883
|
-
|
15884
15856
|
/* Set configuration parameters */
|
15885
15857
|
ALLOWED_TAGS = objectHasOwnProperty(cfg, 'ALLOWED_TAGS') ? addToSet({}, cfg.ALLOWED_TAGS, transformCaseFunc) : DEFAULT_ALLOWED_TAGS;
|
15886
15858
|
ALLOWED_ATTR = objectHasOwnProperty(cfg, 'ALLOWED_ATTR') ? addToSet({}, cfg.ALLOWED_ATTR, transformCaseFunc) : DEFAULT_ALLOWED_ATTR;
|
15887
15859
|
ALLOWED_NAMESPACES = objectHasOwnProperty(cfg, 'ALLOWED_NAMESPACES') ? addToSet({}, cfg.ALLOWED_NAMESPACES, stringToString) : DEFAULT_ALLOWED_NAMESPACES;
|
15888
|
-
URI_SAFE_ATTRIBUTES = objectHasOwnProperty(cfg, 'ADD_URI_SAFE_ATTR') ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES),
|
15889
|
-
|
15890
|
-
cfg.ADD_URI_SAFE_ATTR,
|
15891
|
-
// eslint-disable-line indent
|
15892
|
-
transformCaseFunc // eslint-disable-line indent
|
15893
|
-
) // eslint-disable-line indent
|
15894
|
-
: DEFAULT_URI_SAFE_ATTRIBUTES;
|
15895
|
-
DATA_URI_TAGS = objectHasOwnProperty(cfg, 'ADD_DATA_URI_TAGS') ? addToSet(clone(DEFAULT_DATA_URI_TAGS),
|
15896
|
-
// eslint-disable-line indent
|
15897
|
-
cfg.ADD_DATA_URI_TAGS,
|
15898
|
-
// eslint-disable-line indent
|
15899
|
-
transformCaseFunc // eslint-disable-line indent
|
15900
|
-
) // eslint-disable-line indent
|
15901
|
-
: DEFAULT_DATA_URI_TAGS;
|
15860
|
+
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;
|
15861
|
+
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;
|
15902
15862
|
FORBID_CONTENTS = objectHasOwnProperty(cfg, 'FORBID_CONTENTS') ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc) : DEFAULT_FORBID_CONTENTS;
|
15903
15863
|
FORBID_TAGS = objectHasOwnProperty(cfg, 'FORBID_TAGS') ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : {};
|
15904
15864
|
FORBID_ATTR = objectHasOwnProperty(cfg, 'FORBID_ATTR') ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : {};
|
@@ -15920,6 +15880,8 @@
|
|
15920
15880
|
IN_PLACE = cfg.IN_PLACE || false; // Default false
|
15921
15881
|
IS_ALLOWED_URI$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI;
|
15922
15882
|
NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE;
|
15883
|
+
MATHML_TEXT_INTEGRATION_POINTS = cfg.MATHML_TEXT_INTEGRATION_POINTS || MATHML_TEXT_INTEGRATION_POINTS;
|
15884
|
+
HTML_INTEGRATION_POINTS = cfg.HTML_INTEGRATION_POINTS || HTML_INTEGRATION_POINTS;
|
15923
15885
|
CUSTOM_ELEMENT_HANDLING = cfg.CUSTOM_ELEMENT_HANDLING || {};
|
15924
15886
|
if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck)) {
|
15925
15887
|
CUSTOM_ELEMENT_HANDLING.tagNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck;
|
@@ -15936,7 +15898,6 @@
|
|
15936
15898
|
if (RETURN_DOM_FRAGMENT) {
|
15937
15899
|
RETURN_DOM = true;
|
15938
15900
|
}
|
15939
|
-
|
15940
15901
|
/* Parse profile info */
|
15941
15902
|
if (USE_PROFILES) {
|
15942
15903
|
ALLOWED_TAGS = addToSet({}, text);
|
@@ -15961,7 +15922,6 @@
|
|
15961
15922
|
addToSet(ALLOWED_ATTR, xml);
|
15962
15923
|
}
|
15963
15924
|
}
|
15964
|
-
|
15965
15925
|
/* Merge configuration parameters */
|
15966
15926
|
if (cfg.ADD_TAGS) {
|
15967
15927
|
if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {
|
@@ -15984,17 +15944,14 @@
|
|
15984
15944
|
}
|
15985
15945
|
addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc);
|
15986
15946
|
}
|
15987
|
-
|
15988
15947
|
/* Add #text in case KEEP_CONTENT is set to true */
|
15989
15948
|
if (KEEP_CONTENT) {
|
15990
15949
|
ALLOWED_TAGS['#text'] = true;
|
15991
15950
|
}
|
15992
|
-
|
15993
15951
|
/* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */
|
15994
15952
|
if (WHOLE_DOCUMENT) {
|
15995
15953
|
addToSet(ALLOWED_TAGS, ['html', 'head', 'body']);
|
15996
15954
|
}
|
15997
|
-
|
15998
15955
|
/* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */
|
15999
15956
|
if (ALLOWED_TAGS.table) {
|
16000
15957
|
addToSet(ALLOWED_TAGS, ['tbody']);
|
@@ -16007,10 +15964,8 @@
|
|
16007
15964
|
if (typeof cfg.TRUSTED_TYPES_POLICY.createScriptURL !== 'function') {
|
16008
15965
|
throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');
|
16009
15966
|
}
|
16010
|
-
|
16011
15967
|
// Overwrite existing TrustedTypes policy.
|
16012
15968
|
trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY;
|
16013
|
-
|
16014
15969
|
// Sign local variables required by `sanitize`.
|
16015
15970
|
emptyHTML = trustedTypesPolicy.createHTML('');
|
16016
15971
|
} else {
|
@@ -16018,13 +15973,11 @@
|
|
16018
15973
|
if (trustedTypesPolicy === undefined) {
|
16019
15974
|
trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, currentScript);
|
16020
15975
|
}
|
16021
|
-
|
16022
15976
|
// If creating the internal policy succeeded sign internal variables.
|
16023
15977
|
if (trustedTypesPolicy !== null && typeof emptyHTML === 'string') {
|
16024
15978
|
emptyHTML = trustedTypesPolicy.createHTML('');
|
16025
15979
|
}
|
16026
15980
|
}
|
16027
|
-
|
16028
15981
|
// Prevent further manipulation of configuration.
|
16029
15982
|
// Not available in IE8, Safari 5, etc.
|
16030
15983
|
if (freeze) {
|
@@ -16032,30 +15985,19 @@
|
|
16032
15985
|
}
|
16033
15986
|
CONFIG = cfg;
|
16034
15987
|
};
|
16035
|
-
const MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ['mi', 'mo', 'mn', 'ms', 'mtext']);
|
16036
|
-
const HTML_INTEGRATION_POINTS = addToSet({}, ['annotation-xml']);
|
16037
|
-
|
16038
|
-
// Certain elements are allowed in both SVG and HTML
|
16039
|
-
// namespace. We need to specify them explicitly
|
16040
|
-
// so that they don't get erroneously deleted from
|
16041
|
-
// HTML namespace.
|
16042
|
-
const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, ['title', 'style', 'font', 'a', 'script']);
|
16043
|
-
|
16044
15988
|
/* Keep track of all possible SVG and MathML tags
|
16045
15989
|
* so that we can perform the namespace checks
|
16046
15990
|
* correctly. */
|
16047
15991
|
const ALL_SVG_TAGS = addToSet({}, [...svg$1, ...svgFilters, ...svgDisallowed]);
|
16048
15992
|
const ALL_MATHML_TAGS = addToSet({}, [...mathMl$1, ...mathMlDisallowed]);
|
16049
|
-
|
16050
15993
|
/**
|
16051
|
-
* @param
|
16052
|
-
* @returns
|
15994
|
+
* @param element a DOM element whose namespace is being checked
|
15995
|
+
* @returns Return false if the element has a
|
16053
15996
|
* namespace that a spec-compliant parser would never
|
16054
15997
|
* return. Return true otherwise.
|
16055
15998
|
*/
|
16056
15999
|
const _checkValidNamespace = function _checkValidNamespace(element) {
|
16057
16000
|
let parent = getParentNode(element);
|
16058
|
-
|
16059
16001
|
// In JSDOM, if we're inside shadow DOM, then parentNode
|
16060
16002
|
// can be null. We just simulate parent in this case.
|
16061
16003
|
if (!parent || !parent.tagName) {
|
@@ -16076,14 +16018,12 @@
|
|
16076
16018
|
if (parent.namespaceURI === HTML_NAMESPACE) {
|
16077
16019
|
return tagName === 'svg';
|
16078
16020
|
}
|
16079
|
-
|
16080
16021
|
// The only way to switch from MathML to SVG is via`
|
16081
16022
|
// svg if parent is either <annotation-xml> or MathML
|
16082
16023
|
// text integration points.
|
16083
16024
|
if (parent.namespaceURI === MATHML_NAMESPACE) {
|
16084
16025
|
return tagName === 'svg' && (parentTagName === 'annotation-xml' || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]);
|
16085
16026
|
}
|
16086
|
-
|
16087
16027
|
// We only allow elements that are defined in SVG
|
16088
16028
|
// spec. All others are disallowed in SVG namespace.
|
16089
16029
|
return Boolean(ALL_SVG_TAGS[tagName]);
|
@@ -16095,13 +16035,11 @@
|
|
16095
16035
|
if (parent.namespaceURI === HTML_NAMESPACE) {
|
16096
16036
|
return tagName === 'math';
|
16097
16037
|
}
|
16098
|
-
|
16099
16038
|
// The only way to switch from SVG to MathML is via
|
16100
16039
|
// <math> and HTML integration points
|
16101
16040
|
if (parent.namespaceURI === SVG_NAMESPACE) {
|
16102
16041
|
return tagName === 'math' && HTML_INTEGRATION_POINTS[parentTagName];
|
16103
16042
|
}
|
16104
|
-
|
16105
16043
|
// We only allow elements that are defined in MathML
|
16106
16044
|
// spec. All others are disallowed in MathML namespace.
|
16107
16045
|
return Boolean(ALL_MATHML_TAGS[tagName]);
|
@@ -16116,28 +16054,24 @@
|
|
16116
16054
|
if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) {
|
16117
16055
|
return false;
|
16118
16056
|
}
|
16119
|
-
|
16120
16057
|
// We disallow tags that are specific for MathML
|
16121
16058
|
// or SVG and should never appear in HTML namespace
|
16122
16059
|
return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]);
|
16123
16060
|
}
|
16124
|
-
|
16125
16061
|
// For XHTML and XML documents that support custom namespaces
|
16126
16062
|
if (PARSER_MEDIA_TYPE === 'application/xhtml+xml' && ALLOWED_NAMESPACES[element.namespaceURI]) {
|
16127
16063
|
return true;
|
16128
16064
|
}
|
16129
|
-
|
16130
16065
|
// The code should never reach this place (this means
|
16131
16066
|
// that the element somehow got namespace that is not
|
16132
16067
|
// HTML, SVG, MathML or allowed via ALLOWED_NAMESPACES).
|
16133
16068
|
// Return false just in case.
|
16134
16069
|
return false;
|
16135
16070
|
};
|
16136
|
-
|
16137
16071
|
/**
|
16138
16072
|
* _forceRemove
|
16139
16073
|
*
|
16140
|
-
* @param
|
16074
|
+
* @param node a DOM node
|
16141
16075
|
*/
|
16142
16076
|
const _forceRemove = function _forceRemove(node) {
|
16143
16077
|
arrayPush(DOMPurify.removed, {
|
@@ -16150,46 +16084,43 @@
|
|
16150
16084
|
remove(node);
|
16151
16085
|
}
|
16152
16086
|
};
|
16153
|
-
|
16154
16087
|
/**
|
16155
16088
|
* _removeAttribute
|
16156
16089
|
*
|
16157
|
-
* @param
|
16158
|
-
* @param
|
16090
|
+
* @param name an Attribute name
|
16091
|
+
* @param element a DOM node
|
16159
16092
|
*/
|
16160
|
-
const _removeAttribute = function _removeAttribute(name,
|
16093
|
+
const _removeAttribute = function _removeAttribute(name, element) {
|
16161
16094
|
try {
|
16162
16095
|
arrayPush(DOMPurify.removed, {
|
16163
|
-
attribute:
|
16164
|
-
from:
|
16096
|
+
attribute: element.getAttributeNode(name),
|
16097
|
+
from: element
|
16165
16098
|
});
|
16166
16099
|
} catch (_) {
|
16167
16100
|
arrayPush(DOMPurify.removed, {
|
16168
16101
|
attribute: null,
|
16169
|
-
from:
|
16102
|
+
from: element
|
16170
16103
|
});
|
16171
16104
|
}
|
16172
|
-
|
16173
|
-
|
16174
|
-
|
16175
|
-
if (name === 'is' && !ALLOWED_ATTR[name]) {
|
16105
|
+
element.removeAttribute(name);
|
16106
|
+
// We void attribute values for unremovable "is" attributes
|
16107
|
+
if (name === 'is') {
|
16176
16108
|
if (RETURN_DOM || RETURN_DOM_FRAGMENT) {
|
16177
16109
|
try {
|
16178
|
-
_forceRemove(
|
16110
|
+
_forceRemove(element);
|
16179
16111
|
} catch (_) {}
|
16180
16112
|
} else {
|
16181
16113
|
try {
|
16182
|
-
|
16114
|
+
element.setAttribute(name, '');
|
16183
16115
|
} catch (_) {}
|
16184
16116
|
}
|
16185
16117
|
}
|
16186
16118
|
};
|
16187
|
-
|
16188
16119
|
/**
|
16189
16120
|
* _initDocument
|
16190
16121
|
*
|
16191
|
-
* @param
|
16192
|
-
* @return
|
16122
|
+
* @param dirty - a string of dirty markup
|
16123
|
+
* @return a DOM, filled with the dirty markup
|
16193
16124
|
*/
|
16194
16125
|
const _initDocument = function _initDocument(dirty) {
|
16195
16126
|
/* Create a HTML document */
|
@@ -16216,7 +16147,6 @@
|
|
16216
16147
|
doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE);
|
16217
16148
|
} catch (_) {}
|
16218
16149
|
}
|
16219
|
-
|
16220
16150
|
/* Use createHTMLDocument in case DOMParser is not available */
|
16221
16151
|
if (!doc || !doc.documentElement) {
|
16222
16152
|
doc = implementation.createDocument(NAMESPACE, 'template', null);
|
@@ -16230,112 +16160,86 @@
|
|
16230
16160
|
if (dirty && leadingWhitespace) {
|
16231
16161
|
body.insertBefore(document.createTextNode(leadingWhitespace), body.childNodes[0] || null);
|
16232
16162
|
}
|
16233
|
-
|
16234
16163
|
/* Work on whole document or just its body */
|
16235
16164
|
if (NAMESPACE === HTML_NAMESPACE) {
|
16236
16165
|
return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0];
|
16237
16166
|
}
|
16238
16167
|
return WHOLE_DOCUMENT ? doc.documentElement : body;
|
16239
16168
|
};
|
16240
|
-
|
16241
16169
|
/**
|
16242
16170
|
* Creates a NodeIterator object that you can use to traverse filtered lists of nodes or elements in a document.
|
16243
16171
|
*
|
16244
|
-
* @param
|
16245
|
-
* @return
|
16172
|
+
* @param root The root element or node to start traversing on.
|
16173
|
+
* @return The created NodeIterator
|
16246
16174
|
*/
|
16247
16175
|
const _createNodeIterator = function _createNodeIterator(root) {
|
16248
16176
|
return createNodeIterator.call(root.ownerDocument || root, root,
|
16249
16177
|
// eslint-disable-next-line no-bitwise
|
16250
16178
|
NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT | NodeFilter.SHOW_PROCESSING_INSTRUCTION | NodeFilter.SHOW_CDATA_SECTION, null);
|
16251
16179
|
};
|
16252
|
-
|
16253
16180
|
/**
|
16254
16181
|
* _isClobbered
|
16255
16182
|
*
|
16256
|
-
* @param
|
16257
|
-
* @return
|
16183
|
+
* @param element element to check for clobbering attacks
|
16184
|
+
* @return true if clobbered, false if safe
|
16258
16185
|
*/
|
16259
|
-
const _isClobbered = function _isClobbered(
|
16260
|
-
return
|
16186
|
+
const _isClobbered = function _isClobbered(element) {
|
16187
|
+
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');
|
16261
16188
|
};
|
16262
|
-
|
16263
16189
|
/**
|
16264
16190
|
* Checks whether the given object is a DOM node.
|
16265
16191
|
*
|
16266
|
-
* @param
|
16267
|
-
* @return
|
16192
|
+
* @param value object to check whether it's a DOM node
|
16193
|
+
* @return true is object is a DOM node
|
16268
16194
|
*/
|
16269
|
-
const _isNode = function _isNode(
|
16270
|
-
return typeof Node === 'function' &&
|
16195
|
+
const _isNode = function _isNode(value) {
|
16196
|
+
return typeof Node === 'function' && value instanceof Node;
|
16271
16197
|
};
|
16272
|
-
|
16273
|
-
|
16274
|
-
* _executeHook
|
16275
|
-
* Execute user configurable hooks
|
16276
|
-
*
|
16277
|
-
* @param {String} entryPoint Name of the hook's entry point
|
16278
|
-
* @param {Node} currentNode node to work on with the hook
|
16279
|
-
* @param {Object} data additional hook parameters
|
16280
|
-
*/
|
16281
|
-
const _executeHook = function _executeHook(entryPoint, currentNode, data) {
|
16282
|
-
if (!hooks[entryPoint]) {
|
16283
|
-
return;
|
16284
|
-
}
|
16285
|
-
arrayForEach(hooks[entryPoint], hook => {
|
16198
|
+
function _executeHooks(hooks, currentNode, data) {
|
16199
|
+
arrayForEach(hooks, hook => {
|
16286
16200
|
hook.call(DOMPurify, currentNode, data, CONFIG);
|
16287
16201
|
});
|
16288
|
-
}
|
16289
|
-
|
16202
|
+
}
|
16290
16203
|
/**
|
16291
16204
|
* _sanitizeElements
|
16292
16205
|
*
|
16293
16206
|
* @protect nodeName
|
16294
16207
|
* @protect textContent
|
16295
16208
|
* @protect removeChild
|
16296
|
-
*
|
16297
|
-
* @
|
16298
|
-
* @return {Boolean} true if node was killed, false if left alive
|
16209
|
+
* @param currentNode to check for permission to exist
|
16210
|
+
* @return true if node was killed, false if left alive
|
16299
16211
|
*/
|
16300
16212
|
const _sanitizeElements = function _sanitizeElements(currentNode) {
|
16301
16213
|
let content = null;
|
16302
|
-
|
16303
16214
|
/* Execute a hook if present */
|
16304
|
-
|
16305
|
-
|
16215
|
+
_executeHooks(hooks.beforeSanitizeElements, currentNode, null);
|
16306
16216
|
/* Check if element is clobbered or can clobber */
|
16307
16217
|
if (_isClobbered(currentNode)) {
|
16308
16218
|
_forceRemove(currentNode);
|
16309
16219
|
return true;
|
16310
16220
|
}
|
16311
|
-
|
16312
16221
|
/* Now let's check the element's type and name */
|
16313
16222
|
const tagName = transformCaseFunc(currentNode.nodeName);
|
16314
|
-
|
16315
16223
|
/* Execute a hook if present */
|
16316
|
-
|
16224
|
+
_executeHooks(hooks.uponSanitizeElement, currentNode, {
|
16317
16225
|
tagName,
|
16318
16226
|
allowedTags: ALLOWED_TAGS
|
16319
16227
|
});
|
16320
|
-
|
16321
16228
|
/* Detect mXSS attempts abusing namespace confusion */
|
16322
16229
|
if (currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(/<[/\w]/g, currentNode.innerHTML) && regExpTest(/<[/\w]/g, currentNode.textContent)) {
|
16323
16230
|
_forceRemove(currentNode);
|
16324
16231
|
return true;
|
16325
16232
|
}
|
16326
|
-
|
16327
16233
|
/* Remove any occurrence of processing instructions */
|
16328
16234
|
if (currentNode.nodeType === NODE_TYPE.progressingInstruction) {
|
16329
16235
|
_forceRemove(currentNode);
|
16330
16236
|
return true;
|
16331
16237
|
}
|
16332
|
-
|
16333
16238
|
/* Remove any kind of possibly harmful comments */
|
16334
16239
|
if (SAFE_FOR_XML && currentNode.nodeType === NODE_TYPE.comment && regExpTest(/<[/\w]/g, currentNode.data)) {
|
16335
16240
|
_forceRemove(currentNode);
|
16336
16241
|
return true;
|
16337
16242
|
}
|
16338
|
-
|
16339
16243
|
/* Remove element if anything forbids its presence */
|
16340
16244
|
if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
|
16341
16245
|
/* Check if we have a custom element to handle */
|
@@ -16347,7 +16251,6 @@
|
|
16347
16251
|
return false;
|
16348
16252
|
}
|
16349
16253
|
}
|
16350
|
-
|
16351
16254
|
/* Keep content except for bad-listed elements */
|
16352
16255
|
if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {
|
16353
16256
|
const parentNode = getParentNode(currentNode) || currentNode.parentNode;
|
@@ -16364,19 +16267,16 @@
|
|
16364
16267
|
_forceRemove(currentNode);
|
16365
16268
|
return true;
|
16366
16269
|
}
|
16367
|
-
|
16368
16270
|
/* Check whether element has a valid namespace */
|
16369
16271
|
if (currentNode instanceof Element && !_checkValidNamespace(currentNode)) {
|
16370
16272
|
_forceRemove(currentNode);
|
16371
16273
|
return true;
|
16372
16274
|
}
|
16373
|
-
|
16374
16275
|
/* Make sure that older browsers don't get fallback-tag mXSS */
|
16375
16276
|
if ((tagName === 'noscript' || tagName === 'noembed' || tagName === 'noframes') && regExpTest(/<\/no(script|embed|frames)/i, currentNode.innerHTML)) {
|
16376
16277
|
_forceRemove(currentNode);
|
16377
16278
|
return true;
|
16378
16279
|
}
|
16379
|
-
|
16380
16280
|
/* Sanitize element content to be template-safe */
|
16381
16281
|
if (SAFE_FOR_TEMPLATES && currentNode.nodeType === NODE_TYPE.text) {
|
16382
16282
|
/* Get the element's text content */
|
@@ -16391,19 +16291,17 @@
|
|
16391
16291
|
currentNode.textContent = content;
|
16392
16292
|
}
|
16393
16293
|
}
|
16394
|
-
|
16395
16294
|
/* Execute a hook if present */
|
16396
|
-
|
16295
|
+
_executeHooks(hooks.afterSanitizeElements, currentNode, null);
|
16397
16296
|
return false;
|
16398
16297
|
};
|
16399
|
-
|
16400
16298
|
/**
|
16401
16299
|
* _isValidAttribute
|
16402
16300
|
*
|
16403
|
-
* @param
|
16404
|
-
* @param
|
16405
|
-
* @param
|
16406
|
-
* @return
|
16301
|
+
* @param lcTag Lowercase tag name of containing element.
|
16302
|
+
* @param lcName Lowercase attribute name.
|
16303
|
+
* @param value Attribute value.
|
16304
|
+
* @return Returns true if `value` is valid, otherwise false.
|
16407
16305
|
*/
|
16408
16306
|
// eslint-disable-next-line complexity
|
16409
16307
|
const _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) {
|
@@ -16411,7 +16309,6 @@
|
|
16411
16309
|
if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) {
|
16412
16310
|
return false;
|
16413
16311
|
}
|
16414
|
-
|
16415
16312
|
/* Allow valid data-* attributes: At least one character after "-"
|
16416
16313
|
(https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)
|
16417
16314
|
XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)
|
@@ -16433,19 +16330,17 @@
|
|
16433
16330
|
} else ;
|
16434
16331
|
return true;
|
16435
16332
|
};
|
16436
|
-
|
16437
16333
|
/**
|
16438
16334
|
* _isBasicCustomElement
|
16439
16335
|
* checks if at least one dash is included in tagName, and it's not the first char
|
16440
16336
|
* for more sophisticated checking see https://github.com/sindresorhus/validate-element-name
|
16441
16337
|
*
|
16442
|
-
* @param
|
16443
|
-
* @returns
|
16338
|
+
* @param tagName name of the tag of the node to sanitize
|
16339
|
+
* @returns Returns true if the tag name meets the basic criteria for a custom element, otherwise false.
|
16444
16340
|
*/
|
16445
16341
|
const _isBasicCustomElement = function _isBasicCustomElement(tagName) {
|
16446
16342
|
return tagName !== 'annotation-xml' && stringMatch(tagName, CUSTOM_ELEMENT);
|
16447
16343
|
};
|
16448
|
-
|
16449
16344
|
/**
|
16450
16345
|
* _sanitizeAttributes
|
16451
16346
|
*
|
@@ -16454,27 +16349,26 @@
|
|
16454
16349
|
* @protect removeAttribute
|
16455
16350
|
* @protect setAttribute
|
16456
16351
|
*
|
16457
|
-
* @param
|
16352
|
+
* @param currentNode to sanitize
|
16458
16353
|
*/
|
16459
16354
|
const _sanitizeAttributes = function _sanitizeAttributes(currentNode) {
|
16460
16355
|
/* Execute a hook if present */
|
16461
|
-
|
16356
|
+
_executeHooks(hooks.beforeSanitizeAttributes, currentNode, null);
|
16462
16357
|
const {
|
16463
16358
|
attributes
|
16464
16359
|
} = currentNode;
|
16465
|
-
|
16466
16360
|
/* Check if we have attributes; if not we might have a text node */
|
16467
|
-
if (!attributes) {
|
16361
|
+
if (!attributes || _isClobbered(currentNode)) {
|
16468
16362
|
return;
|
16469
16363
|
}
|
16470
16364
|
const hookEvent = {
|
16471
16365
|
attrName: '',
|
16472
16366
|
attrValue: '',
|
16473
16367
|
keepAttr: true,
|
16474
|
-
allowedAttributes: ALLOWED_ATTR
|
16368
|
+
allowedAttributes: ALLOWED_ATTR,
|
16369
|
+
forceKeepAttr: undefined
|
16475
16370
|
};
|
16476
16371
|
let l = attributes.length;
|
16477
|
-
|
16478
16372
|
/* Go backwards over all attributes; safely remove bad ones */
|
16479
16373
|
while (l--) {
|
16480
16374
|
const attr = attributes[l];
|
@@ -16486,65 +16380,54 @@
|
|
16486
16380
|
const lcName = transformCaseFunc(name);
|
16487
16381
|
let value = name === 'value' ? attrValue : stringTrim(attrValue);
|
16488
16382
|
const initValue = value;
|
16489
|
-
|
16490
16383
|
/* Execute a hook if present */
|
16491
16384
|
hookEvent.attrName = lcName;
|
16492
16385
|
hookEvent.attrValue = value;
|
16493
16386
|
hookEvent.keepAttr = true;
|
16494
16387
|
hookEvent.forceKeepAttr = undefined; // Allows developers to see this is a property they can set
|
16495
|
-
|
16388
|
+
_executeHooks(hooks.uponSanitizeAttribute, currentNode, hookEvent);
|
16496
16389
|
value = hookEvent.attrValue;
|
16497
|
-
|
16390
|
+
/* Full DOM Clobbering protection via namespace isolation,
|
16391
|
+
* Prefix id and name attributes with `user-content-`
|
16392
|
+
*/
|
16393
|
+
if (SANITIZE_NAMED_PROPS && (lcName === 'id' || lcName === 'name')) {
|
16394
|
+
// Remove the attribute with this value
|
16395
|
+
_removeAttribute(name, currentNode);
|
16396
|
+
// Prefix the value and later re-create the attribute with the sanitized value
|
16397
|
+
value = SANITIZE_NAMED_PROPS_PREFIX + value;
|
16398
|
+
}
|
16399
|
+
/* Work around a security issue with comments inside attributes */
|
16400
|
+
if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|title)/i, value)) {
|
16401
|
+
_removeAttribute(name, currentNode);
|
16402
|
+
continue;
|
16403
|
+
}
|
16498
16404
|
/* Did the hooks approve of the attribute? */
|
16499
16405
|
if (hookEvent.forceKeepAttr) {
|
16500
16406
|
continue;
|
16501
16407
|
}
|
16502
|
-
|
16503
16408
|
/* Remove attribute */
|
16504
|
-
|
16505
16409
|
/* Did the hooks approve of the attribute? */
|
16506
16410
|
if (!hookEvent.keepAttr) {
|
16507
16411
|
_removeAttribute(name, currentNode);
|
16508
16412
|
continue;
|
16509
16413
|
}
|
16510
|
-
|
16511
16414
|
/* Work around a security issue in jQuery 3.0 */
|
16512
16415
|
if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(/\/>/i, value)) {
|
16513
16416
|
_removeAttribute(name, currentNode);
|
16514
16417
|
continue;
|
16515
16418
|
}
|
16516
|
-
|
16517
16419
|
/* Sanitize attribute content to be template-safe */
|
16518
16420
|
if (SAFE_FOR_TEMPLATES) {
|
16519
16421
|
arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
|
16520
16422
|
value = stringReplace(value, expr, ' ');
|
16521
16423
|
});
|
16522
16424
|
}
|
16523
|
-
|
16524
16425
|
/* Is `value` valid for this attribute? */
|
16525
16426
|
const lcTag = transformCaseFunc(currentNode.nodeName);
|
16526
16427
|
if (!_isValidAttribute(lcTag, lcName, value)) {
|
16527
16428
|
_removeAttribute(name, currentNode);
|
16528
16429
|
continue;
|
16529
16430
|
}
|
16530
|
-
|
16531
|
-
/* Full DOM Clobbering protection via namespace isolation,
|
16532
|
-
* Prefix id and name attributes with `user-content-`
|
16533
|
-
*/
|
16534
|
-
if (SANITIZE_NAMED_PROPS && (lcName === 'id' || lcName === 'name')) {
|
16535
|
-
// Remove the attribute with this value
|
16536
|
-
_removeAttribute(name, currentNode);
|
16537
|
-
|
16538
|
-
// Prefix the value and later re-create the attribute with the sanitized value
|
16539
|
-
value = SANITIZE_NAMED_PROPS_PREFIX + value;
|
16540
|
-
}
|
16541
|
-
|
16542
|
-
/* Work around a security issue with comments inside attributes */
|
16543
|
-
if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|title)/i, value)) {
|
16544
|
-
_removeAttribute(name, currentNode);
|
16545
|
-
continue;
|
16546
|
-
}
|
16547
|
-
|
16548
16431
|
/* Handle attributes that require Trusted Types */
|
16549
16432
|
if (trustedTypesPolicy && typeof trustedTypes === 'object' && typeof trustedTypes.getAttributeType === 'function') {
|
16550
16433
|
if (namespaceURI) ; else {
|
@@ -16562,7 +16445,6 @@
|
|
16562
16445
|
}
|
16563
16446
|
}
|
16564
16447
|
}
|
16565
|
-
|
16566
16448
|
/* Handle invalid data-* attribute set by try-catching it */
|
16567
16449
|
if (value !== initValue) {
|
16568
16450
|
try {
|
@@ -16580,51 +16462,34 @@
|
|
16580
16462
|
} catch (_) {}
|
16581
16463
|
}
|
16582
16464
|
}
|
16583
|
-
|
16584
16465
|
/* Execute a hook if present */
|
16585
|
-
|
16466
|
+
_executeHooks(hooks.afterSanitizeAttributes, currentNode, null);
|
16586
16467
|
};
|
16587
|
-
|
16588
16468
|
/**
|
16589
16469
|
* _sanitizeShadowDOM
|
16590
16470
|
*
|
16591
|
-
* @param
|
16471
|
+
* @param fragment to iterate over recursively
|
16592
16472
|
*/
|
16593
16473
|
const _sanitizeShadowDOM = function _sanitizeShadowDOM(fragment) {
|
16594
16474
|
let shadowNode = null;
|
16595
16475
|
const shadowIterator = _createNodeIterator(fragment);
|
16596
|
-
|
16597
16476
|
/* Execute a hook if present */
|
16598
|
-
|
16477
|
+
_executeHooks(hooks.beforeSanitizeShadowDOM, fragment, null);
|
16599
16478
|
while (shadowNode = shadowIterator.nextNode()) {
|
16600
16479
|
/* Execute a hook if present */
|
16601
|
-
|
16602
|
-
|
16480
|
+
_executeHooks(hooks.uponSanitizeShadowNode, shadowNode, null);
|
16603
16481
|
/* Sanitize tags and elements */
|
16604
|
-
|
16605
|
-
|
16606
|
-
|
16607
|
-
|
16482
|
+
_sanitizeElements(shadowNode);
|
16483
|
+
/* Check attributes next */
|
16484
|
+
_sanitizeAttributes(shadowNode);
|
16608
16485
|
/* Deep shadow DOM detected */
|
16609
16486
|
if (shadowNode.content instanceof DocumentFragment) {
|
16610
16487
|
_sanitizeShadowDOM(shadowNode.content);
|
16611
16488
|
}
|
16612
|
-
|
16613
|
-
/* Check attributes, sanitize if necessary */
|
16614
|
-
_sanitizeAttributes(shadowNode);
|
16615
16489
|
}
|
16616
|
-
|
16617
16490
|
/* Execute a hook if present */
|
16618
|
-
|
16491
|
+
_executeHooks(hooks.afterSanitizeShadowDOM, fragment, null);
|
16619
16492
|
};
|
16620
|
-
|
16621
|
-
/**
|
16622
|
-
* Sanitize
|
16623
|
-
* Public method providing core sanitation functionality
|
16624
|
-
*
|
16625
|
-
* @param {String|Node} dirty string or DOM node
|
16626
|
-
* @param {Object} cfg object
|
16627
|
-
*/
|
16628
16493
|
// eslint-disable-next-line complexity
|
16629
16494
|
DOMPurify.sanitize = function (dirty) {
|
16630
16495
|
let cfg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
@@ -16639,7 +16504,6 @@
|
|
16639
16504
|
if (IS_EMPTY_INPUT) {
|
16640
16505
|
dirty = '<!-->';
|
16641
16506
|
}
|
16642
|
-
|
16643
16507
|
/* Stringify, in case dirty is an object */
|
16644
16508
|
if (typeof dirty !== 'string' && !_isNode(dirty)) {
|
16645
16509
|
if (typeof dirty.toString === 'function') {
|
@@ -16651,20 +16515,16 @@
|
|
16651
16515
|
throw typeErrorCreate('toString is not a function');
|
16652
16516
|
}
|
16653
16517
|
}
|
16654
|
-
|
16655
16518
|
/* Return dirty HTML if DOMPurify cannot run */
|
16656
16519
|
if (!DOMPurify.isSupported) {
|
16657
16520
|
return dirty;
|
16658
16521
|
}
|
16659
|
-
|
16660
16522
|
/* Assign config vars */
|
16661
16523
|
if (!SET_CONFIG) {
|
16662
16524
|
_parseConfig(cfg);
|
16663
16525
|
}
|
16664
|
-
|
16665
16526
|
/* Clean up removed elements */
|
16666
16527
|
DOMPurify.removed = [];
|
16667
|
-
|
16668
16528
|
/* Check if dirty is correctly typed for IN_PLACE */
|
16669
16529
|
if (typeof dirty === 'string') {
|
16670
16530
|
IN_PLACE = false;
|
@@ -16698,45 +16558,34 @@
|
|
16698
16558
|
dirty.indexOf('<') === -1) {
|
16699
16559
|
return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(dirty) : dirty;
|
16700
16560
|
}
|
16701
|
-
|
16702
16561
|
/* Initialize the document to work on */
|
16703
16562
|
body = _initDocument(dirty);
|
16704
|
-
|
16705
16563
|
/* Check we have a DOM node from the data */
|
16706
16564
|
if (!body) {
|
16707
16565
|
return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : '';
|
16708
16566
|
}
|
16709
16567
|
}
|
16710
|
-
|
16711
16568
|
/* Remove first element node (ours) if FORCE_BODY is set */
|
16712
16569
|
if (body && FORCE_BODY) {
|
16713
16570
|
_forceRemove(body.firstChild);
|
16714
16571
|
}
|
16715
|
-
|
16716
16572
|
/* Get node iterator */
|
16717
16573
|
const nodeIterator = _createNodeIterator(IN_PLACE ? dirty : body);
|
16718
|
-
|
16719
16574
|
/* Now start iterating over the created document */
|
16720
16575
|
while (currentNode = nodeIterator.nextNode()) {
|
16721
16576
|
/* Sanitize tags and elements */
|
16722
|
-
|
16723
|
-
|
16724
|
-
|
16725
|
-
|
16577
|
+
_sanitizeElements(currentNode);
|
16578
|
+
/* Check attributes next */
|
16579
|
+
_sanitizeAttributes(currentNode);
|
16726
16580
|
/* Shadow DOM detected, sanitize it */
|
16727
16581
|
if (currentNode.content instanceof DocumentFragment) {
|
16728
16582
|
_sanitizeShadowDOM(currentNode.content);
|
16729
16583
|
}
|
16730
|
-
|
16731
|
-
/* Check attributes, sanitize if necessary */
|
16732
|
-
_sanitizeAttributes(currentNode);
|
16733
16584
|
}
|
16734
|
-
|
16735
16585
|
/* If we sanitized `dirty` in-place, return it. */
|
16736
16586
|
if (IN_PLACE) {
|
16737
16587
|
return dirty;
|
16738
16588
|
}
|
16739
|
-
|
16740
16589
|
/* Return sanitized string or DOM */
|
16741
16590
|
if (RETURN_DOM) {
|
16742
16591
|
if (RETURN_DOM_FRAGMENT) {
|
@@ -16761,12 +16610,10 @@
|
|
16761
16610
|
return returnNode;
|
16762
16611
|
}
|
16763
16612
|
let serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML;
|
16764
|
-
|
16765
16613
|
/* Serialize doctype if allowed */
|
16766
16614
|
if (WHOLE_DOCUMENT && ALLOWED_TAGS['!doctype'] && body.ownerDocument && body.ownerDocument.doctype && body.ownerDocument.doctype.name && regExpTest(DOCTYPE_NAME, body.ownerDocument.doctype.name)) {
|
16767
16615
|
serializedHTML = '<!DOCTYPE ' + body.ownerDocument.doctype.name + '>\n' + serializedHTML;
|
16768
16616
|
}
|
16769
|
-
|
16770
16617
|
/* Sanitize final string template-safe */
|
16771
16618
|
if (SAFE_FOR_TEMPLATES) {
|
16772
16619
|
arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
|
@@ -16775,39 +16622,15 @@
|
|
16775
16622
|
}
|
16776
16623
|
return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(serializedHTML) : serializedHTML;
|
16777
16624
|
};
|
16778
|
-
|
16779
|
-
/**
|
16780
|
-
* Public method to set the configuration once
|
16781
|
-
* setConfig
|
16782
|
-
*
|
16783
|
-
* @param {Object} cfg configuration object
|
16784
|
-
*/
|
16785
16625
|
DOMPurify.setConfig = function () {
|
16786
16626
|
let cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
16787
16627
|
_parseConfig(cfg);
|
16788
16628
|
SET_CONFIG = true;
|
16789
16629
|
};
|
16790
|
-
|
16791
|
-
/**
|
16792
|
-
* Public method to remove the configuration
|
16793
|
-
* clearConfig
|
16794
|
-
*
|
16795
|
-
*/
|
16796
16630
|
DOMPurify.clearConfig = function () {
|
16797
16631
|
CONFIG = null;
|
16798
16632
|
SET_CONFIG = false;
|
16799
16633
|
};
|
16800
|
-
|
16801
|
-
/**
|
16802
|
-
* Public method to check if an attribute value is valid.
|
16803
|
-
* Uses last set config, if any. Otherwise, uses config defaults.
|
16804
|
-
* isValidAttribute
|
16805
|
-
*
|
16806
|
-
* @param {String} tag Tag name of containing element.
|
16807
|
-
* @param {String} attr Attribute name.
|
16808
|
-
* @param {String} value Attribute value.
|
16809
|
-
* @return {Boolean} Returns true if `value` is valid. Otherwise, returns false.
|
16810
|
-
*/
|
16811
16634
|
DOMPurify.isValidAttribute = function (tag, attr, value) {
|
16812
16635
|
/* Initialize shared config vars if necessary. */
|
16813
16636
|
if (!CONFIG) {
|
@@ -16817,54 +16640,24 @@
|
|
16817
16640
|
const lcName = transformCaseFunc(attr);
|
16818
16641
|
return _isValidAttribute(lcTag, lcName, value);
|
16819
16642
|
};
|
16820
|
-
|
16821
|
-
/**
|
16822
|
-
* AddHook
|
16823
|
-
* Public method to add DOMPurify hooks
|
16824
|
-
*
|
16825
|
-
* @param {String} entryPoint entry point for the hook to add
|
16826
|
-
* @param {Function} hookFunction function to execute
|
16827
|
-
*/
|
16828
16643
|
DOMPurify.addHook = function (entryPoint, hookFunction) {
|
16829
16644
|
if (typeof hookFunction !== 'function') {
|
16830
16645
|
return;
|
16831
16646
|
}
|
16832
|
-
hooks[entryPoint] = hooks[entryPoint] || [];
|
16833
16647
|
arrayPush(hooks[entryPoint], hookFunction);
|
16834
16648
|
};
|
16835
|
-
|
16836
|
-
|
16837
|
-
|
16838
|
-
|
16839
|
-
* (pops it from the stack of hooks if more are present)
|
16840
|
-
*
|
16841
|
-
* @param {String} entryPoint entry point for the hook to remove
|
16842
|
-
* @return {Function} removed(popped) hook
|
16843
|
-
*/
|
16844
|
-
DOMPurify.removeHook = function (entryPoint) {
|
16845
|
-
if (hooks[entryPoint]) {
|
16846
|
-
return arrayPop(hooks[entryPoint]);
|
16649
|
+
DOMPurify.removeHook = function (entryPoint, hookFunction) {
|
16650
|
+
if (hookFunction !== undefined) {
|
16651
|
+
const index = arrayLastIndexOf(hooks[entryPoint], hookFunction);
|
16652
|
+
return index === -1 ? undefined : arraySplice(hooks[entryPoint], index, 1)[0];
|
16847
16653
|
}
|
16654
|
+
return arrayPop(hooks[entryPoint]);
|
16848
16655
|
};
|
16849
|
-
|
16850
|
-
/**
|
16851
|
-
* RemoveHooks
|
16852
|
-
* Public method to remove all DOMPurify hooks at a given entryPoint
|
16853
|
-
*
|
16854
|
-
* @param {String} entryPoint entry point for the hooks to remove
|
16855
|
-
*/
|
16856
16656
|
DOMPurify.removeHooks = function (entryPoint) {
|
16857
|
-
|
16858
|
-
hooks[entryPoint] = [];
|
16859
|
-
}
|
16657
|
+
hooks[entryPoint] = [];
|
16860
16658
|
};
|
16861
|
-
|
16862
|
-
/**
|
16863
|
-
* RemoveAllHooks
|
16864
|
-
* Public method to remove all DOMPurify hooks
|
16865
|
-
*/
|
16866
16659
|
DOMPurify.removeAllHooks = function () {
|
16867
|
-
hooks =
|
16660
|
+
hooks = _createHooksMap();
|
16868
16661
|
};
|
16869
16662
|
return DOMPurify;
|
16870
16663
|
}
|
@@ -17346,17 +17139,39 @@
|
|
17346
17139
|
const encoding = el.getAttribute('encoding');
|
17347
17140
|
return hasAllowedEncodings && isString(encoding) && contains$2(allowedEncodings, encoding);
|
17348
17141
|
};
|
17142
|
+
const isValidElementOpt = (node, lcTagName) => {
|
17143
|
+
if (hasAllowedEncodings && lcTagName === 'semantics') {
|
17144
|
+
return Optional.some(true);
|
17145
|
+
} else if (lcTagName === 'annotation') {
|
17146
|
+
return Optional.some(isElement$6(node) && hasValidEncoding(node));
|
17147
|
+
} else if (isArray$1(settings.extended_mathml_elements)) {
|
17148
|
+
if (settings.extended_mathml_elements.includes(lcTagName)) {
|
17149
|
+
return Optional.from(true);
|
17150
|
+
} else {
|
17151
|
+
return Optional.none();
|
17152
|
+
}
|
17153
|
+
} else {
|
17154
|
+
return Optional.none();
|
17155
|
+
}
|
17156
|
+
};
|
17349
17157
|
purify$1.addHook('uponSanitizeElement', (node, evt) => {
|
17350
17158
|
var _a;
|
17351
17159
|
const lcTagName = (_a = evt.tagName) !== null && _a !== void 0 ? _a : node.nodeName.toLowerCase();
|
17352
|
-
|
17353
|
-
|
17354
|
-
}
|
17355
|
-
if (lcTagName === 'annotation') {
|
17356
|
-
const keepElement = hasValidEncoding(node);
|
17160
|
+
const keepElementOpt = isValidElementOpt(node, lcTagName);
|
17161
|
+
keepElementOpt.each(keepElement => {
|
17357
17162
|
evt.allowedTags[lcTagName] = keepElement;
|
17358
|
-
if (!keepElement) {
|
17359
|
-
node
|
17163
|
+
if (!keepElement && settings.sanitize) {
|
17164
|
+
if (isElement$6(node)) {
|
17165
|
+
node.remove();
|
17166
|
+
}
|
17167
|
+
}
|
17168
|
+
});
|
17169
|
+
});
|
17170
|
+
purify$1.addHook('uponSanitizeAttribute', (_node, event) => {
|
17171
|
+
if (isArray$1(settings.extended_mathml_attributes)) {
|
17172
|
+
const keepAttribute = settings.extended_mathml_attributes.includes(event.attrName);
|
17173
|
+
if (keepAttribute) {
|
17174
|
+
event.forceKeepAttr = true;
|
17360
17175
|
}
|
17361
17176
|
}
|
17362
17177
|
});
|
@@ -23679,15 +23494,18 @@
|
|
23679
23494
|
return getCellFirstCursorPosition(cell);
|
23680
23495
|
});
|
23681
23496
|
}, current => {
|
23682
|
-
if (editor.mode.isReadOnly()) {
|
23497
|
+
if (editor.mode.isReadOnly() || !isCellInEditableTable(current)) {
|
23683
23498
|
return Optional.none();
|
23684
23499
|
}
|
23685
23500
|
editor.execCommand('mceTableInsertRowAfter');
|
23686
23501
|
return tabForward(editor, isRoot, current);
|
23687
23502
|
});
|
23688
23503
|
};
|
23689
|
-
const
|
23690
|
-
const
|
23504
|
+
const isCellInEditableTable = cell => closest$4(cell, isTag('table')).exists(isEditable$2);
|
23505
|
+
const tabForward = (editor, isRoot, cell) => tabGo(editor, isRoot, next(cell, isCellEditable));
|
23506
|
+
const tabBackward = (editor, isRoot, cell) => tabGo(editor, isRoot, prev(cell, isCellEditable));
|
23507
|
+
const isCellEditable = cell => isEditable$2(cell) || descendant(cell, isEditableHTMLElement);
|
23508
|
+
const isEditableHTMLElement = node => isHTMLElement$1(node) && isEditable$2(node);
|
23691
23509
|
const handleTab = (editor, forward) => {
|
23692
23510
|
const rootElements = [
|
23693
23511
|
'table',
|
@@ -24345,6 +24163,7 @@
|
|
24345
24163
|
const optionOf = (key, schema) => field(key, key, asOption(), schema);
|
24346
24164
|
const optionString = key => optionOf(key, string);
|
24347
24165
|
const optionFunction = key => optionOf(key, functionProcessor);
|
24166
|
+
const optionObjOf = (key, objSchema) => optionOf(key, objOf(objSchema));
|
24348
24167
|
const defaulted = (key, fallback) => field(key, key, defaulted$1(fallback), anyValue());
|
24349
24168
|
const defaultedOf = (key, fallback, schema) => field(key, key, defaulted$1(fallback), schema);
|
24350
24169
|
const defaultedNumber = (key, fallback) => defaultedOf(key, fallback, number);
|
@@ -24419,7 +24238,7 @@
|
|
24419
24238
|
onAction,
|
24420
24239
|
customField('original', identity)
|
24421
24240
|
]);
|
24422
|
-
const launchButtonFields = baseToolbarButtonFields.concat([defaultedType('contextformbutton')]);
|
24241
|
+
const launchButtonFields$1 = baseToolbarButtonFields.concat([defaultedType('contextformbutton')]);
|
24423
24242
|
const launchToggleButtonFields = baseToolbarToggleButtonFields.concat([defaultedType('contextformtogglebutton')]);
|
24424
24243
|
const toggleOrNormal = choose('type', {
|
24425
24244
|
contextformbutton: contextButtonFields,
|
@@ -24429,7 +24248,7 @@
|
|
24429
24248
|
optionalLabel,
|
24430
24249
|
requiredArrayOf('commands', toggleOrNormal),
|
24431
24250
|
optionOf('launch', choose('type', {
|
24432
|
-
contextformbutton: launchButtonFields,
|
24251
|
+
contextformbutton: launchButtonFields$1,
|
24433
24252
|
contextformtogglebutton: launchToggleButtonFields
|
24434
24253
|
})),
|
24435
24254
|
defaultedFunction('onInput', noop),
|
@@ -24465,8 +24284,10 @@
|
|
24465
24284
|
contextsizeinputform: contextSizeInputFormFields
|
24466
24285
|
});
|
24467
24286
|
|
24287
|
+
const launchButtonFields = baseToolbarButtonFields.concat([defaultedType('contexttoolbarbutton')]);
|
24468
24288
|
objOf([
|
24469
24289
|
defaultedType('contexttoolbar'),
|
24290
|
+
optionObjOf('launch', launchButtonFields),
|
24470
24291
|
requiredOf('items', oneOf([
|
24471
24292
|
string,
|
24472
24293
|
arrOfObj([
|
@@ -29172,6 +28993,8 @@
|
|
29172
28993
|
allow_unsafe_link_target: getOption('allow_unsafe_link_target'),
|
29173
28994
|
convert_unsafe_embeds: getOption('convert_unsafe_embeds'),
|
29174
28995
|
convert_fonts_to_spans: getOption('convert_fonts_to_spans'),
|
28996
|
+
extended_mathml_attributes: getOption('extended_mathml_attributes'),
|
28997
|
+
extended_mathml_elements: getOption('extended_mathml_elements'),
|
29175
28998
|
fix_list_elements: getOption('fix_list_elements'),
|
29176
28999
|
font_size_legacy_values: getOption('font_size_legacy_values'),
|
29177
29000
|
forced_root_block: getOption('forced_root_block'),
|
@@ -31853,7 +31676,7 @@
|
|
31853
31676
|
documentBaseURL: null,
|
31854
31677
|
suffix: null,
|
31855
31678
|
majorVersion: '7',
|
31856
|
-
minorVersion: '
|
31679
|
+
minorVersion: '8.0',
|
31857
31680
|
releaseDate: 'TBD',
|
31858
31681
|
i18n: I18n,
|
31859
31682
|
activeEditor: null,
|
@@ -32273,7 +32096,7 @@
|
|
32273
32096
|
if (!done) {
|
32274
32097
|
done = true;
|
32275
32098
|
if (timer !== null) {
|
32276
|
-
clearTimeout(timer);
|
32099
|
+
window.clearTimeout(timer);
|
32277
32100
|
timer = null;
|
32278
32101
|
}
|
32279
32102
|
completer.apply(null, args);
|
@@ -32283,7 +32106,7 @@
|
|
32283
32106
|
const reject = complete(rejectCb);
|
32284
32107
|
const start = (...args) => {
|
32285
32108
|
if (!done && timer === null) {
|
32286
|
-
timer = setTimeout(() => reject.apply(null, args), timeout);
|
32109
|
+
timer = window.setTimeout(() => reject.apply(null, args), timeout);
|
32287
32110
|
}
|
32288
32111
|
};
|
32289
32112
|
return {
|