@toast-ui/editor 3.0.2 → 3.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/dist/esm/i18n/ar.js +7 -0
- package/dist/esm/i18n/cs-cz.js +7 -0
- package/dist/esm/i18n/de-de.js +7 -0
- package/dist/esm/i18n/en-us.js +7 -0
- package/dist/esm/i18n/es-es.js +7 -0
- package/dist/esm/i18n/fi-fi.js +7 -0
- package/dist/esm/i18n/fr-fr.js +7 -0
- package/dist/esm/i18n/gl-es.js +7 -0
- package/dist/esm/i18n/hr-hr.js +7 -0
- package/dist/esm/i18n/i18n.js +15 -4
- package/dist/esm/i18n/it-it.js +7 -0
- package/dist/esm/i18n/ja-jp.js +7 -0
- package/dist/esm/i18n/ko-kr.js +7 -0
- package/dist/esm/i18n/nb-no.js +7 -0
- package/dist/esm/i18n/nl-nl.js +7 -0
- package/dist/esm/i18n/pl-pl.js +7 -0
- package/dist/esm/i18n/pt-br.js +7 -0
- package/dist/esm/i18n/ru-ru.js +7 -0
- package/dist/esm/i18n/sv-se.js +7 -0
- package/dist/esm/i18n/tr-tr.js +7 -0
- package/dist/esm/i18n/uk-ua.js +7 -0
- package/dist/esm/i18n/zh-cn.js +7 -0
- package/dist/esm/i18n/zh-tw.js +7 -0
- package/dist/esm/index.js +2885 -426
- package/dist/esm/indexViewer.js +1672 -297
- package/dist/i18n/ar.js +1 -1
- package/dist/i18n/cs-cz.js +1 -1
- package/dist/i18n/de-de.js +1 -1
- package/dist/i18n/es-es.js +1 -1
- package/dist/i18n/fi-fi.js +1 -1
- package/dist/i18n/fr-fr.js +1 -1
- package/dist/i18n/gl-es.js +1 -1
- package/dist/i18n/hr-hr.js +1 -1
- package/dist/i18n/it-it.js +1 -1
- package/dist/i18n/ja-jp.js +1 -1
- package/dist/i18n/ko-kr.js +1 -1
- package/dist/i18n/nb-no.js +1 -1
- package/dist/i18n/nl-nl.js +1 -1
- package/dist/i18n/pl-pl.js +1 -1
- package/dist/i18n/pt-br.js +1 -1
- package/dist/i18n/ru-ru.js +1 -1
- package/dist/i18n/sv-se.js +1 -1
- package/dist/i18n/tr-tr.js +1 -1
- package/dist/i18n/uk-ua.js +1 -1
- package/dist/i18n/zh-cn.js +1 -1
- package/dist/i18n/zh-tw.js +1 -1
- package/dist/toastui-editor-only.css +22 -16
- package/dist/toastui-editor-viewer.css +10 -2
- package/dist/toastui-editor-viewer.js +1823 -370
- package/dist/toastui-editor.css +31 -17
- package/dist/toastui-editor.js +2853 -318
- package/package.json +5 -1
- package/types/editor.d.ts +6 -4
- package/types/event.d.ts +1 -0
- package/types/index.d.ts +4 -3
- package/types/toastui-editor-viewer.d.ts +39 -0
package/dist/esm/index.js
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @toast-ui/editor
|
|
3
|
+
* @version 3.1.2 | Mon Dec 27 2021
|
|
4
|
+
* @author NHN FE Development Lab <dl_javascript@nhn.com>
|
|
5
|
+
* @license MIT
|
|
6
|
+
*/
|
|
7
|
+
|
|
1
8
|
import { Fragment, Schema, Slice, NodeRange, Mark as Mark$1, DOMParser, Node as Node$3 } from 'prosemirror-model';
|
|
2
9
|
import { DecorationSet, Decoration, EditorView } from 'prosemirror-view';
|
|
3
10
|
import { ReplaceAroundStep, liftTarget, canSplit, StepMap } from 'prosemirror-transform';
|
|
@@ -49,10 +56,14 @@ var __assign$1 = function() {
|
|
|
49
56
|
return __assign$1.apply(this, arguments);
|
|
50
57
|
};
|
|
51
58
|
|
|
52
|
-
function __spreadArray$1(to, from) {
|
|
53
|
-
for (var i = 0,
|
|
54
|
-
|
|
55
|
-
|
|
59
|
+
function __spreadArray$1(to, from, pack) {
|
|
60
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
61
|
+
if (ar || !(i in from)) {
|
|
62
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
63
|
+
ar[i] = from[i];
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
56
67
|
}
|
|
57
68
|
|
|
58
69
|
function __makeTemplateObject(cooked, raw) {
|
|
@@ -77,12 +88,16 @@ function __makeTemplateObject(cooked, raw) {
|
|
|
77
88
|
* @param {Object} [context] Context(this) of callback function
|
|
78
89
|
* @memberof module:collection
|
|
79
90
|
* @example
|
|
80
|
-
*
|
|
91
|
+
* // ES6
|
|
92
|
+
* import forEachOwnProperties from 'tui-code-snippet/collection/forEachOwnProperties';
|
|
93
|
+
*
|
|
94
|
+
* // CommonJS
|
|
95
|
+
* const forEachOwnProperties = require('tui-code-snippet/collection/forEachOwnProperties');
|
|
81
96
|
*
|
|
82
|
-
*
|
|
97
|
+
* let sum = 0;
|
|
83
98
|
*
|
|
84
99
|
* forEachOwnProperties({a:1,b:2,c:3}, function(value){
|
|
85
|
-
*
|
|
100
|
+
* sum += value;
|
|
86
101
|
* });
|
|
87
102
|
* alert(sum); // 6
|
|
88
103
|
*/
|
|
@@ -190,12 +205,16 @@ var isArray_1 = isArray$3;
|
|
|
190
205
|
* @param {Object} [context] Context(this) of callback function
|
|
191
206
|
* @memberof module:collection
|
|
192
207
|
* @example
|
|
193
|
-
*
|
|
208
|
+
* // ES6
|
|
209
|
+
* import forEachArray from 'tui-code-snippet/collection/forEachArray';
|
|
210
|
+
*
|
|
211
|
+
* // CommonJS
|
|
212
|
+
* const forEachArray = require('tui-code-snippet/collection/forEachArray');
|
|
194
213
|
*
|
|
195
|
-
*
|
|
214
|
+
* let sum = 0;
|
|
196
215
|
*
|
|
197
216
|
* forEachArray([1,2,3], function(value){
|
|
198
|
-
*
|
|
217
|
+
* sum += value;
|
|
199
218
|
* });
|
|
200
219
|
* alert(sum); // 6
|
|
201
220
|
*/
|
|
@@ -240,19 +259,23 @@ var forEachOwnProperties$1 = forEachOwnProperties_1;
|
|
|
240
259
|
* @param {Object} [context] Context(this) of callback function
|
|
241
260
|
* @memberof module:collection
|
|
242
261
|
* @example
|
|
243
|
-
*
|
|
262
|
+
* // ES6
|
|
263
|
+
* import forEach from 'tui-code-snippet/collection/forEach';
|
|
264
|
+
*
|
|
265
|
+
* // CommonJS
|
|
266
|
+
* const forEach = require('tui-code-snippet/collection/forEach');
|
|
244
267
|
*
|
|
245
|
-
*
|
|
268
|
+
* let sum = 0;
|
|
246
269
|
*
|
|
247
270
|
* forEach([1,2,3], function(value){
|
|
248
|
-
*
|
|
271
|
+
* sum += value;
|
|
249
272
|
* });
|
|
250
273
|
* alert(sum); // 6
|
|
251
274
|
*
|
|
252
275
|
* // In case of Array-like object
|
|
253
|
-
*
|
|
276
|
+
* const array = Array.prototype.slice.call(arrayLike); // change to array
|
|
254
277
|
* forEach(array, function(value){
|
|
255
|
-
*
|
|
278
|
+
* sum += value;
|
|
256
279
|
* });
|
|
257
280
|
*/
|
|
258
281
|
function forEach$4(obj, iteratee, context) {
|
|
@@ -315,11 +338,15 @@ var isArray$1 = isArray_1;
|
|
|
315
338
|
* @returns {number} the First index at which a given element, or -1 if it is not present
|
|
316
339
|
* @memberof module:array
|
|
317
340
|
* @example
|
|
318
|
-
*
|
|
341
|
+
* // ES6
|
|
342
|
+
* import inArray from 'tui-code-snippet/array/inArray';
|
|
343
|
+
*
|
|
344
|
+
* // CommonJS
|
|
345
|
+
* const inArray = require('tui-code-snippet/array/inArray');
|
|
319
346
|
*
|
|
320
|
-
*
|
|
321
|
-
*
|
|
322
|
-
*
|
|
347
|
+
* const arr = ['one', 'two', 'three', 'four'];
|
|
348
|
+
* const idx1 = inArray('one', arr, 3); // -1
|
|
349
|
+
* const idx2 = inArray('one', arr); // 0
|
|
323
350
|
*/
|
|
324
351
|
function inArray$4(searchElement, array, startIndex) {
|
|
325
352
|
var i;
|
|
@@ -569,15 +596,19 @@ var forEachOwnProperties = forEachOwnProperties_1;
|
|
|
569
596
|
* @returns {HTMLElement}
|
|
570
597
|
* @memberof module:request
|
|
571
598
|
* @example
|
|
572
|
-
*
|
|
599
|
+
* // ES6
|
|
600
|
+
* import imagePing from 'tui-code-snippet/request/imagePing';
|
|
601
|
+
*
|
|
602
|
+
* // CommonJS
|
|
603
|
+
* const imagePing = require('tui-code-snippet/request/imagePing');
|
|
573
604
|
*
|
|
574
605
|
* imagePing('https://www.google-analytics.com/collect', {
|
|
575
|
-
*
|
|
576
|
-
*
|
|
577
|
-
*
|
|
578
|
-
*
|
|
579
|
-
*
|
|
580
|
-
*
|
|
606
|
+
* v: 1,
|
|
607
|
+
* t: 'event',
|
|
608
|
+
* tid: 'trackingid',
|
|
609
|
+
* cid: 'cid',
|
|
610
|
+
* dp: 'dp',
|
|
611
|
+
* dh: 'dh'
|
|
581
612
|
* });
|
|
582
613
|
*/
|
|
583
614
|
function imagePing$1(url, trackingInfo) {
|
|
@@ -672,6 +703,28 @@ var reEscapeChars$1 = /[>(){}[\]+-.!#|]/g;
|
|
|
672
703
|
var reEscapeHTML = /<([a-zA-Z_][a-zA-Z0-9\-._]*)(\s|[^\\/>])*\/?>|<(\/)([a-zA-Z_][a-zA-Z0-9\-._]*)\s*\/?>|<!--[^-]+-->|<([a-zA-Z_][a-zA-Z0-9\-.:/]*)>/g;
|
|
673
704
|
var reEscapeBackSlash = /\\[!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~\\]/g;
|
|
674
705
|
var reEscapePairedChars = /[*_~`]/g;
|
|
706
|
+
var XMLSPECIAL$1 = '[&<>"]';
|
|
707
|
+
var reXmlSpecial$1 = new RegExp(XMLSPECIAL$1, 'g');
|
|
708
|
+
function replaceUnsafeChar$1(char) {
|
|
709
|
+
switch (char) {
|
|
710
|
+
case '&':
|
|
711
|
+
return '&';
|
|
712
|
+
case '<':
|
|
713
|
+
return '<';
|
|
714
|
+
case '>':
|
|
715
|
+
return '>';
|
|
716
|
+
case '"':
|
|
717
|
+
return '"';
|
|
718
|
+
default:
|
|
719
|
+
return char;
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
function escapeXml$1(text) {
|
|
723
|
+
if (reXmlSpecial$1.test(text)) {
|
|
724
|
+
return text.replace(reXmlSpecial$1, replaceUnsafeChar$1);
|
|
725
|
+
}
|
|
726
|
+
return text;
|
|
727
|
+
}
|
|
675
728
|
function sendHostName() {
|
|
676
729
|
sendHostname_1('editor', 'UA-129966929-1');
|
|
677
730
|
}
|
|
@@ -1234,16 +1287,20 @@ var forEachArray = forEachArray_1;
|
|
|
1234
1287
|
* @returns {Array} Array
|
|
1235
1288
|
* @memberof module:collection
|
|
1236
1289
|
* @example
|
|
1237
|
-
*
|
|
1290
|
+
* // ES6
|
|
1291
|
+
* import toArray from 'tui-code-snippet/collection/toArray';
|
|
1292
|
+
*
|
|
1293
|
+
* // CommonJS
|
|
1294
|
+
* const toArray = require('tui-code-snippet/collection/toArray');
|
|
1238
1295
|
*
|
|
1239
|
-
*
|
|
1240
|
-
*
|
|
1241
|
-
*
|
|
1242
|
-
*
|
|
1243
|
-
*
|
|
1244
|
-
*
|
|
1296
|
+
* const arrayLike = {
|
|
1297
|
+
* 0: 'one',
|
|
1298
|
+
* 1: 'two',
|
|
1299
|
+
* 2: 'three',
|
|
1300
|
+
* 3: 'four',
|
|
1301
|
+
* length: 4
|
|
1245
1302
|
* };
|
|
1246
|
-
*
|
|
1303
|
+
* const result = toArray(arrayLike);
|
|
1247
1304
|
*
|
|
1248
1305
|
* alert(result instanceof Array); // true
|
|
1249
1306
|
* alert(result); // one,two,three,four
|
|
@@ -1422,7 +1479,7 @@ var EditorBase = /** @class */ (function () {
|
|
|
1422
1479
|
var _a = getDefaultCommands(), undo = _a.undo, redo = _a.redo;
|
|
1423
1480
|
var rules = this.createInputRules();
|
|
1424
1481
|
var plugins = __spreadArray$1(__spreadArray$1([], this.keymaps), [
|
|
1425
|
-
keymap(__assign$1({ 'Mod-z': undo(), 'Shift-Mod-z': redo() }, baseKeymap)),
|
|
1482
|
+
keymap(__assign$1({ 'Mod-z': undo(), 'Shift-Mod-z': redo(), 'Shift-Enter': baseKeymap.Enter }, baseKeymap)),
|
|
1426
1483
|
history(),
|
|
1427
1484
|
placeholder(this.placeholder),
|
|
1428
1485
|
addWidget(this.eventEmitter),
|
|
@@ -1493,15 +1550,19 @@ var EditorBase = /** @class */ (function () {
|
|
|
1493
1550
|
delete _this[prop];
|
|
1494
1551
|
});
|
|
1495
1552
|
};
|
|
1496
|
-
EditorBase.prototype.moveCursorToStart = function () {
|
|
1553
|
+
EditorBase.prototype.moveCursorToStart = function (focus) {
|
|
1497
1554
|
var tr = this.view.state.tr;
|
|
1498
1555
|
this.view.dispatch(tr.setSelection(createTextSelection(tr, 1)).scrollIntoView());
|
|
1499
|
-
|
|
1556
|
+
if (focus) {
|
|
1557
|
+
this.focus();
|
|
1558
|
+
}
|
|
1500
1559
|
};
|
|
1501
|
-
EditorBase.prototype.moveCursorToEnd = function () {
|
|
1560
|
+
EditorBase.prototype.moveCursorToEnd = function (focus) {
|
|
1502
1561
|
var tr = this.view.state.tr;
|
|
1503
1562
|
this.view.dispatch(tr.setSelection(createTextSelection(tr, tr.doc.content.size - 1)).scrollIntoView());
|
|
1504
|
-
|
|
1563
|
+
if (focus) {
|
|
1564
|
+
this.focus();
|
|
1565
|
+
}
|
|
1505
1566
|
};
|
|
1506
1567
|
EditorBase.prototype.setScrollTop = function (top) {
|
|
1507
1568
|
this.view.dom.scrollTop = top;
|
|
@@ -1692,6 +1753,8 @@ var OPEN_TAG = "<(" + TAG_NAME + ")(" + ATTRIBUTE$1 + ")*\\s*/?>";
|
|
|
1692
1753
|
var CLOSE_TAG = "</(" + TAG_NAME + ")\\s*[>]";
|
|
1693
1754
|
var HTML_TAG = "(?:" + OPEN_TAG + "|" + CLOSE_TAG + ")";
|
|
1694
1755
|
var reHTMLTag = new RegExp("^" + HTML_TAG, 'i');
|
|
1756
|
+
var reBR = /<br\s*\/*>/i;
|
|
1757
|
+
var ALTERNATIVE_TAG_FOR_BR = '</p><p>';
|
|
1695
1758
|
|
|
1696
1759
|
function isPositionInBox(style, offsetX, offsetY) {
|
|
1697
1760
|
var left = parseInt(style.left, 10);
|
|
@@ -1824,51 +1887,36 @@ function getTotalOffset(el, root) {
|
|
|
1824
1887
|
}
|
|
1825
1888
|
return { offsetTop: offsetTop, offsetLeft: offsetLeft };
|
|
1826
1889
|
}
|
|
1827
|
-
function finalizeHtml(html, needHtmlText) {
|
|
1828
|
-
var result;
|
|
1829
|
-
if (needHtmlText) {
|
|
1830
|
-
result = html.innerHTML;
|
|
1831
|
-
}
|
|
1832
|
-
else {
|
|
1833
|
-
var frag = document.createDocumentFragment();
|
|
1834
|
-
var childNodes = toArray_1(html.childNodes);
|
|
1835
|
-
var length_1 = childNodes.length;
|
|
1836
|
-
for (var i = 0; i < length_1; i += 1) {
|
|
1837
|
-
frag.appendChild(childNodes[i]);
|
|
1838
|
-
}
|
|
1839
|
-
result = frag;
|
|
1840
|
-
}
|
|
1841
|
-
return result;
|
|
1842
|
-
}
|
|
1843
1890
|
function setAttributes(attributes, element) {
|
|
1844
1891
|
Object.keys(attributes).forEach(function (attrName) {
|
|
1845
|
-
if (attributes[attrName]) {
|
|
1846
|
-
element.
|
|
1892
|
+
if (isNil(attributes[attrName])) {
|
|
1893
|
+
element.removeAttribute(attrName);
|
|
1847
1894
|
}
|
|
1848
1895
|
else {
|
|
1849
|
-
element.
|
|
1896
|
+
element.setAttribute(attrName, attributes[attrName]);
|
|
1850
1897
|
}
|
|
1851
1898
|
});
|
|
1852
1899
|
}
|
|
1853
1900
|
function replaceBRWithEmptyBlock(html) {
|
|
1854
|
-
|
|
1901
|
+
// remove br in paragraph to compatible with markdown
|
|
1902
|
+
var replacedHTML = html.replace(/<p><br\s*\/*><\/p>/gi, '<p></p>');
|
|
1855
1903
|
var reHTMLTag = new RegExp(HTML_TAG, 'ig');
|
|
1856
|
-
var htmlTagMatched =
|
|
1904
|
+
var htmlTagMatched = replacedHTML.match(reHTMLTag);
|
|
1857
1905
|
htmlTagMatched === null || htmlTagMatched === void 0 ? void 0 : htmlTagMatched.forEach(function (htmlTag, index) {
|
|
1858
|
-
if (
|
|
1859
|
-
var alternativeTag =
|
|
1906
|
+
if (reBR.test(htmlTag)) {
|
|
1907
|
+
var alternativeTag = ALTERNATIVE_TAG_FOR_BR;
|
|
1860
1908
|
if (index) {
|
|
1861
1909
|
var prevTag = htmlTagMatched[index - 1];
|
|
1862
1910
|
var openTagMatched = prevTag.match(OPEN_TAG);
|
|
1863
|
-
if (openTagMatched) {
|
|
1911
|
+
if (openTagMatched && !/br/i.test(openTagMatched[1])) {
|
|
1864
1912
|
var tagName = openTagMatched[1];
|
|
1865
1913
|
alternativeTag = "</" + tagName + "><" + tagName + ">";
|
|
1866
1914
|
}
|
|
1867
1915
|
}
|
|
1868
|
-
|
|
1916
|
+
replacedHTML = replacedHTML.replace(reBR, alternativeTag);
|
|
1869
1917
|
}
|
|
1870
1918
|
});
|
|
1871
|
-
return
|
|
1919
|
+
return replacedHTML;
|
|
1872
1920
|
}
|
|
1873
1921
|
|
|
1874
1922
|
function resolveSelectionPos(selection) {
|
|
@@ -2096,7 +2144,7 @@ function customBlock$2(node, start, end) {
|
|
|
2096
2144
|
var marks = [markInfo(setOffsetPos(start, 1), end, CUSTOM_BLOCK)];
|
|
2097
2145
|
marks.push(markInfo(start, addOffsetPos(start, syntaxEnd), DELIM));
|
|
2098
2146
|
if (info) {
|
|
2099
|
-
marks.push(markInfo(addOffsetPos(start,
|
|
2147
|
+
marks.push(markInfo(addOffsetPos(start, syntaxEnd), addOffsetPos(start, syntaxLength + info.length), META));
|
|
2100
2148
|
}
|
|
2101
2149
|
marks.push(markInfo(setOffsetPos(end, 1), end, DELIM));
|
|
2102
2150
|
var lineBackgroundMarkInfo = lineBackground(parent, start, end, 'custom-block');
|
|
@@ -3320,9 +3368,11 @@ var ThematicBreak$1 = /** @class */ (function (_super) {
|
|
|
3320
3368
|
return ThematicBreak;
|
|
3321
3369
|
}(Mark));
|
|
3322
3370
|
|
|
3323
|
-
function cannotBeListNode(_a) {
|
|
3324
|
-
var type = _a.type;
|
|
3325
|
-
|
|
3371
|
+
function cannotBeListNode(_a, line) {
|
|
3372
|
+
var type = _a.type, sourcepos = _a.sourcepos;
|
|
3373
|
+
// eslint-disable-next-line prefer-destructuring
|
|
3374
|
+
var startLine = sourcepos[0][0];
|
|
3375
|
+
return line <= startLine && (type === 'codeBlock' || type === 'heading' || type.match('table'));
|
|
3326
3376
|
}
|
|
3327
3377
|
var ListItem$1 = /** @class */ (function (_super) {
|
|
3328
3378
|
__extends$1(ListItem, _super);
|
|
@@ -3425,7 +3475,7 @@ var ListItem$1 = /** @class */ (function (_super) {
|
|
|
3425
3475
|
var skipLines = [];
|
|
3426
3476
|
for (var line = startLine; line <= endLine; line += 1) {
|
|
3427
3477
|
var mdNode = toastMark.findFirstNodeAtLine(line);
|
|
3428
|
-
if (mdNode && cannotBeListNode(mdNode)) {
|
|
3478
|
+
if (mdNode && cannotBeListNode(mdNode, line)) {
|
|
3429
3479
|
break;
|
|
3430
3480
|
}
|
|
3431
3481
|
// to skip unnecessary processing
|
|
@@ -4073,15 +4123,20 @@ var MdEditor = /** @class */ (function (_super) {
|
|
|
4073
4123
|
_this.commands = _this.createCommands();
|
|
4074
4124
|
_this.specs.setContext(__assign$1(__assign$1({}, _this.context), { view: _this.view }));
|
|
4075
4125
|
_this.createClipboard();
|
|
4076
|
-
|
|
4126
|
+
// To prevent unnecessary focus setting during initial rendering
|
|
4127
|
+
_this.eventEmitter.listen('changePreviewTabWrite', function (isMarkdownTabMounted) {
|
|
4128
|
+
return _this.toggleActive(true, isMarkdownTabMounted);
|
|
4129
|
+
});
|
|
4077
4130
|
_this.eventEmitter.listen('changePreviewTabPreview', function () { return _this.toggleActive(false); });
|
|
4078
4131
|
_this.initEvent();
|
|
4079
4132
|
return _this;
|
|
4080
4133
|
}
|
|
4081
|
-
MdEditor.prototype.toggleActive = function (active) {
|
|
4134
|
+
MdEditor.prototype.toggleActive = function (active, isMarkdownTabMounted) {
|
|
4082
4135
|
toggleClass(this.el, 'active', active);
|
|
4083
4136
|
if (active) {
|
|
4084
|
-
|
|
4137
|
+
if (!isMarkdownTabMounted) {
|
|
4138
|
+
this.focus();
|
|
4139
|
+
}
|
|
4085
4140
|
}
|
|
4086
4141
|
else {
|
|
4087
4142
|
this.blur();
|
|
@@ -4298,7 +4353,7 @@ var MdEditor = /** @class */ (function (_super) {
|
|
|
4298
4353
|
});
|
|
4299
4354
|
this.view.dispatch(tr.replaceWith(0, doc.content.size, nodes));
|
|
4300
4355
|
if (cursorToEnd) {
|
|
4301
|
-
this.moveCursorToEnd();
|
|
4356
|
+
this.moveCursorToEnd(true);
|
|
4302
4357
|
}
|
|
4303
4358
|
};
|
|
4304
4359
|
MdEditor.prototype.addWidget = function (node, style, mdPos) {
|
|
@@ -4485,7 +4540,7 @@ var safeEvent = _safeEvent;
|
|
|
4485
4540
|
* @param {object} [context] context - context for handler method.
|
|
4486
4541
|
* @memberof module:domEvent
|
|
4487
4542
|
* @example
|
|
4488
|
-
*
|
|
4543
|
+
* const div = document.querySelector('div');
|
|
4489
4544
|
*
|
|
4490
4545
|
* // Bind one event to an element.
|
|
4491
4546
|
* on(div, 'click', toggle);
|
|
@@ -4502,10 +4557,10 @@ var safeEvent = _safeEvent;
|
|
|
4502
4557
|
* });
|
|
4503
4558
|
*
|
|
4504
4559
|
* // Set a context for handler method.
|
|
4505
|
-
*
|
|
4506
|
-
*
|
|
4560
|
+
* const name = 'global';
|
|
4561
|
+
* const repository = {name: 'CodeSnippet'};
|
|
4507
4562
|
* on(div, 'drag', function() {
|
|
4508
|
-
*
|
|
4563
|
+
* console.log(this.name);
|
|
4509
4564
|
* }, repository);
|
|
4510
4565
|
* // Result when you drag a div: "CodeSnippet"
|
|
4511
4566
|
*/
|
|
@@ -4622,10 +4677,14 @@ var __assign = function() {
|
|
|
4622
4677
|
return __assign.apply(this, arguments);
|
|
4623
4678
|
};
|
|
4624
4679
|
|
|
4625
|
-
function __spreadArray(to, from) {
|
|
4626
|
-
for (var i = 0,
|
|
4627
|
-
|
|
4628
|
-
|
|
4680
|
+
function __spreadArray(to, from, pack) {
|
|
4681
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
4682
|
+
if (ar || !(i in from)) {
|
|
4683
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
4684
|
+
ar[i] = from[i];
|
|
4685
|
+
}
|
|
4686
|
+
}
|
|
4687
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
4629
4688
|
}
|
|
4630
4689
|
|
|
4631
4690
|
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
@@ -9958,7 +10017,7 @@ function isCustomBlock(node) {
|
|
|
9958
10017
|
function isCustomInline(node) {
|
|
9959
10018
|
return node.type === 'customInline';
|
|
9960
10019
|
}
|
|
9961
|
-
function text(s, sourcepos) {
|
|
10020
|
+
function text$1(s, sourcepos) {
|
|
9962
10021
|
var node = createNode$1('text', sourcepos);
|
|
9963
10022
|
node.literal = s;
|
|
9964
10023
|
return node;
|
|
@@ -10134,17 +10193,17 @@ function convertExtAutoLinks(walker, autolinkParser) {
|
|
|
10134
10193
|
for (var _i = 0, linkInfos_1 = linkInfos; _i < linkInfos_1.length; _i++) {
|
|
10135
10194
|
var _b = linkInfos_1[_i], range = _b.range, url = _b.url, linkText = _b.text;
|
|
10136
10195
|
if (range[0] > lastIdx) {
|
|
10137
|
-
newNodes.push(text(literal.substring(lastIdx, range[0]), sourcepos(lastIdx, range[0] - 1)));
|
|
10196
|
+
newNodes.push(text$1(literal.substring(lastIdx, range[0]), sourcepos(lastIdx, range[0] - 1)));
|
|
10138
10197
|
}
|
|
10139
10198
|
var linkNode = createNode$1('link', sourcepos.apply(void 0, range));
|
|
10140
|
-
linkNode.appendChild(text(linkText, sourcepos.apply(void 0, range)));
|
|
10199
|
+
linkNode.appendChild(text$1(linkText, sourcepos.apply(void 0, range)));
|
|
10141
10200
|
linkNode.destination = url;
|
|
10142
10201
|
linkNode.extendedAutolink = true;
|
|
10143
10202
|
newNodes.push(linkNode);
|
|
10144
10203
|
lastIdx = range[1] + 1;
|
|
10145
10204
|
}
|
|
10146
10205
|
if (lastIdx < literal.length) {
|
|
10147
|
-
newNodes.push(text(literal.substring(lastIdx), sourcepos(lastIdx, literal.length - 1)));
|
|
10206
|
+
newNodes.push(text$1(literal.substring(lastIdx), sourcepos(lastIdx, literal.length - 1)));
|
|
10148
10207
|
}
|
|
10149
10208
|
for (var _c = 0, newNodes_1 = newNodes; _c < newNodes_1.length; _c++) {
|
|
10150
10209
|
var newNode = newNodes_1[_c];
|
|
@@ -10335,7 +10394,7 @@ var InlineParser = /** @class */ (function () {
|
|
|
10335
10394
|
}
|
|
10336
10395
|
// If we got here, we didn't match a closing backtick sequence.
|
|
10337
10396
|
this.pos = afterOpenTicks;
|
|
10338
|
-
block.appendChild(text(ticks, this.sourcepos(startpos, this.pos - 1)));
|
|
10397
|
+
block.appendChild(text$1(ticks, this.sourcepos(startpos, this.pos - 1)));
|
|
10339
10398
|
return true;
|
|
10340
10399
|
};
|
|
10341
10400
|
// Parse a backslash-escaped special character, adding either the escaped
|
|
@@ -10354,11 +10413,11 @@ var InlineParser = /** @class */ (function () {
|
|
|
10354
10413
|
this.nextLine();
|
|
10355
10414
|
}
|
|
10356
10415
|
else if (reEscapable.test(subj.charAt(this.pos))) {
|
|
10357
|
-
block.appendChild(text(subj.charAt(this.pos), this.sourcepos(startpos, this.pos)));
|
|
10416
|
+
block.appendChild(text$1(subj.charAt(this.pos), this.sourcepos(startpos, this.pos)));
|
|
10358
10417
|
this.pos += 1;
|
|
10359
10418
|
}
|
|
10360
10419
|
else {
|
|
10361
|
-
block.appendChild(text('\\', this.sourcepos(startpos, startpos)));
|
|
10420
|
+
block.appendChild(text$1('\\', this.sourcepos(startpos, startpos)));
|
|
10362
10421
|
}
|
|
10363
10422
|
return true;
|
|
10364
10423
|
};
|
|
@@ -10373,7 +10432,7 @@ var InlineParser = /** @class */ (function () {
|
|
|
10373
10432
|
node = createNode$1('link', this.sourcepos(startpos, this.pos));
|
|
10374
10433
|
node.destination = normalizeURI("mailto:" + dest);
|
|
10375
10434
|
node.title = '';
|
|
10376
|
-
node.appendChild(text(dest, this.sourcepos(startpos + 1, this.pos - 1)));
|
|
10435
|
+
node.appendChild(text$1(dest, this.sourcepos(startpos + 1, this.pos - 1)));
|
|
10377
10436
|
block.appendChild(node);
|
|
10378
10437
|
return true;
|
|
10379
10438
|
}
|
|
@@ -10382,7 +10441,7 @@ var InlineParser = /** @class */ (function () {
|
|
|
10382
10441
|
node = createNode$1('link', this.sourcepos(startpos, this.pos));
|
|
10383
10442
|
node.destination = normalizeURI(dest);
|
|
10384
10443
|
node.title = '';
|
|
10385
|
-
node.appendChild(text(dest, this.sourcepos(startpos + 1, this.pos - 1)));
|
|
10444
|
+
node.appendChild(text$1(dest, this.sourcepos(startpos + 1, this.pos - 1)));
|
|
10386
10445
|
block.appendChild(node);
|
|
10387
10446
|
return true;
|
|
10388
10447
|
}
|
|
@@ -10476,7 +10535,7 @@ var InlineParser = /** @class */ (function () {
|
|
|
10476
10535
|
else {
|
|
10477
10536
|
contents = this.subject.slice(startpos - 1, this.pos);
|
|
10478
10537
|
}
|
|
10479
|
-
var node = text(contents, this.sourcepos(startpos, this.pos));
|
|
10538
|
+
var node = text$1(contents, this.sourcepos(startpos, this.pos));
|
|
10480
10539
|
block.appendChild(node);
|
|
10481
10540
|
// Add entry to stack for this opener
|
|
10482
10541
|
if ((res.canOpen || res.canClose) &&
|
|
@@ -10747,7 +10806,7 @@ var InlineParser = /** @class */ (function () {
|
|
|
10747
10806
|
InlineParser.prototype.parseOpenBracket = function (block) {
|
|
10748
10807
|
var startpos = this.pos;
|
|
10749
10808
|
this.pos += 1;
|
|
10750
|
-
var node = text('[', this.sourcepos(this.pos, this.pos));
|
|
10809
|
+
var node = text$1('[', this.sourcepos(this.pos, this.pos));
|
|
10751
10810
|
block.appendChild(node);
|
|
10752
10811
|
// Add entry to stack for this opener
|
|
10753
10812
|
this.addBracket(node, startpos, false);
|
|
@@ -10760,13 +10819,13 @@ var InlineParser = /** @class */ (function () {
|
|
|
10760
10819
|
this.pos += 1;
|
|
10761
10820
|
if (this.peek() === C_OPEN_BRACKET$1) {
|
|
10762
10821
|
this.pos += 1;
|
|
10763
|
-
var node = text('![', this.sourcepos(this.pos - 1, this.pos));
|
|
10822
|
+
var node = text$1('![', this.sourcepos(this.pos - 1, this.pos));
|
|
10764
10823
|
block.appendChild(node);
|
|
10765
10824
|
// Add entry to stack for this opener
|
|
10766
10825
|
this.addBracket(node, startpos + 1, true);
|
|
10767
10826
|
}
|
|
10768
10827
|
else {
|
|
10769
|
-
var node = text('!', this.sourcepos(this.pos, this.pos));
|
|
10828
|
+
var node = text$1('!', this.sourcepos(this.pos, this.pos));
|
|
10770
10829
|
block.appendChild(node);
|
|
10771
10830
|
}
|
|
10772
10831
|
return true;
|
|
@@ -10785,12 +10844,12 @@ var InlineParser = /** @class */ (function () {
|
|
|
10785
10844
|
var opener = this.brackets;
|
|
10786
10845
|
if (opener === null) {
|
|
10787
10846
|
// no matched opener, just return a literal
|
|
10788
|
-
block.appendChild(text(']', this.sourcepos(startpos, startpos)));
|
|
10847
|
+
block.appendChild(text$1(']', this.sourcepos(startpos, startpos)));
|
|
10789
10848
|
return true;
|
|
10790
10849
|
}
|
|
10791
10850
|
if (!opener.active) {
|
|
10792
10851
|
// no matched opener, just return a literal
|
|
10793
|
-
block.appendChild(text(']', this.sourcepos(startpos, startpos)));
|
|
10852
|
+
block.appendChild(text$1(']', this.sourcepos(startpos, startpos)));
|
|
10794
10853
|
// take opener off brackets stack
|
|
10795
10854
|
this.removeBracket();
|
|
10796
10855
|
return true;
|
|
@@ -10882,7 +10941,7 @@ var InlineParser = /** @class */ (function () {
|
|
|
10882
10941
|
} // no match
|
|
10883
10942
|
this.removeBracket(); // remove this opener from stack
|
|
10884
10943
|
this.pos = startpos;
|
|
10885
|
-
block.appendChild(text(']', this.sourcepos(startpos, startpos)));
|
|
10944
|
+
block.appendChild(text$1(']', this.sourcepos(startpos, startpos)));
|
|
10886
10945
|
if (this.options.referenceDefinition) {
|
|
10887
10946
|
this.refLinkCandidateMap[block.id] = { node: block, refLabel: refLabel };
|
|
10888
10947
|
}
|
|
@@ -10912,7 +10971,7 @@ var InlineParser = /** @class */ (function () {
|
|
|
10912
10971
|
var m;
|
|
10913
10972
|
var startpos = this.pos + 1;
|
|
10914
10973
|
if ((m = this.match(reEntityHere))) {
|
|
10915
|
-
block.appendChild(text(lib.decodeHTML(m), this.sourcepos(startpos, this.pos)));
|
|
10974
|
+
block.appendChild(text$1(lib.decodeHTML(m), this.sourcepos(startpos, this.pos)));
|
|
10916
10975
|
return true;
|
|
10917
10976
|
}
|
|
10918
10977
|
return false;
|
|
@@ -10947,10 +11006,10 @@ var InlineParser = /** @class */ (function () {
|
|
|
10947
11006
|
}
|
|
10948
11007
|
return repeat('\u2014', emCount) + repeat('\u2013', enCount);
|
|
10949
11008
|
});
|
|
10950
|
-
block.appendChild(text(lit, this.sourcepos(startpos, this.pos)));
|
|
11009
|
+
block.appendChild(text$1(lit, this.sourcepos(startpos, this.pos)));
|
|
10951
11010
|
}
|
|
10952
11011
|
else {
|
|
10953
|
-
var node = text(m, this.sourcepos(startpos, this.pos));
|
|
11012
|
+
var node = text$1(m, this.sourcepos(startpos, this.pos));
|
|
10954
11013
|
block.appendChild(node);
|
|
10955
11014
|
}
|
|
10956
11015
|
return true;
|
|
@@ -11173,7 +11232,7 @@ var InlineParser = /** @class */ (function () {
|
|
|
11173
11232
|
}
|
|
11174
11233
|
if (!res) {
|
|
11175
11234
|
this.pos += 1;
|
|
11176
|
-
block.appendChild(text(fromCodePoint$1(c), this.sourcepos(this.pos, this.pos + 1)));
|
|
11235
|
+
block.appendChild(text$1(fromCodePoint$1(c), this.sourcepos(this.pos, this.pos + 1)));
|
|
11177
11236
|
}
|
|
11178
11237
|
return true;
|
|
11179
11238
|
};
|
|
@@ -13059,6 +13118,7 @@ function filterDisallowedTags(str) {
|
|
|
13059
13118
|
return str;
|
|
13060
13119
|
}
|
|
13061
13120
|
|
|
13121
|
+
var CUSTOM_SYNTAX_LENGTH = 4;
|
|
13062
13122
|
var baseConvertors$1 = {
|
|
13063
13123
|
heading: function (node, _a) {
|
|
13064
13124
|
var entering = _a.entering;
|
|
@@ -13226,7 +13286,7 @@ var baseConvertors$1 = {
|
|
|
13226
13286
|
return customConvertor(node, context);
|
|
13227
13287
|
}
|
|
13228
13288
|
catch (e) {
|
|
13229
|
-
console.warn(e);
|
|
13289
|
+
console.warn("[@toast-ui/editor] - The error occurred when " + info + " block node was parsed in markdown renderer: " + e);
|
|
13230
13290
|
}
|
|
13231
13291
|
}
|
|
13232
13292
|
return [
|
|
@@ -13249,15 +13309,30 @@ var baseConvertors$1 = {
|
|
|
13249
13309
|
];
|
|
13250
13310
|
},
|
|
13251
13311
|
customInline: function (node, context, convertors) {
|
|
13252
|
-
var
|
|
13253
|
-
var
|
|
13312
|
+
var _a = node, sourcepos = _a.sourcepos, info = _a.info;
|
|
13313
|
+
var nomalizedInfo = info.trim().toLowerCase();
|
|
13314
|
+
var customConvertor = convertors[nomalizedInfo];
|
|
13315
|
+
var entering = context.entering;
|
|
13254
13316
|
if (customConvertor) {
|
|
13255
|
-
|
|
13256
|
-
|
|
13257
|
-
|
|
13258
|
-
|
|
13259
|
-
|
|
13260
|
-
|
|
13317
|
+
try {
|
|
13318
|
+
return customConvertor(node, context);
|
|
13319
|
+
}
|
|
13320
|
+
catch (e) {
|
|
13321
|
+
console.warn("[@toast-ui/editor] - The error occurred when " + nomalizedInfo + " inline node was parsed in markdown renderer: " + e);
|
|
13322
|
+
}
|
|
13323
|
+
}
|
|
13324
|
+
var text = sourcepos[1][1] - sourcepos[0][1] + 1 === info.length + CUSTOM_SYNTAX_LENGTH
|
|
13325
|
+
? ''
|
|
13326
|
+
: info + " ";
|
|
13327
|
+
return entering
|
|
13328
|
+
? [
|
|
13329
|
+
{ type: 'openTag', tagName: 'span' },
|
|
13330
|
+
{ type: 'text', content: "$$" + text },
|
|
13331
|
+
]
|
|
13332
|
+
: [
|
|
13333
|
+
{ type: 'text', content: '$$' },
|
|
13334
|
+
{ type: 'closeTag', tagName: 'span' },
|
|
13335
|
+
];
|
|
13261
13336
|
},
|
|
13262
13337
|
};
|
|
13263
13338
|
|
|
@@ -13422,8 +13497,8 @@ var Renderer = /** @class */ (function () {
|
|
|
13422
13497
|
? nodeType.toLowerCase()
|
|
13423
13498
|
: nodeType;
|
|
13424
13499
|
if (orgConvertor) {
|
|
13425
|
-
convertors[convertorType] = function (node, context) {
|
|
13426
|
-
context.origin = function () { return orgConvertor(node, context); };
|
|
13500
|
+
convertors[convertorType] = function (node, context, convertors) {
|
|
13501
|
+
context.origin = function () { return orgConvertor(node, context, convertors); };
|
|
13427
13502
|
return convertor(node, context);
|
|
13428
13503
|
};
|
|
13429
13504
|
}
|
|
@@ -13568,216 +13643,1527 @@ var Renderer = /** @class */ (function () {
|
|
|
13568
13643
|
return Renderer;
|
|
13569
13644
|
}());
|
|
13570
13645
|
|
|
13571
|
-
|
|
13572
|
-
|
|
13573
|
-
|
|
13574
|
-
|
|
13575
|
-
|
|
13576
|
-
|
|
13577
|
-
|
|
13578
|
-
|
|
13579
|
-
|
|
13580
|
-
|
|
13581
|
-
|
|
13582
|
-
|
|
13583
|
-
|
|
13584
|
-
|
|
13585
|
-
|
|
13586
|
-
|
|
13587
|
-
|
|
13588
|
-
|
|
13589
|
-
|
|
13590
|
-
|
|
13591
|
-
|
|
13592
|
-
var reXSSAttr = /href|src|background/i;
|
|
13593
|
-
var reXSSAttrValue = /((java|vb|live)script|x):/i;
|
|
13594
|
-
var reOnEvent = /^on\S+/i;
|
|
13595
|
-
var reXSSOnload = new RegExp("(<" + TAG_NAME + "[^>]*)(onload\\s*=)", 'ig');
|
|
13596
|
-
var reComment = /<!--[\s\S]*?-->/g;
|
|
13597
|
-
var reWhitespace = /[ \t\r\n]/g;
|
|
13598
|
-
var DEFAULT_TAG_BLACK_LIST = [
|
|
13599
|
-
'script',
|
|
13600
|
-
'iframe',
|
|
13601
|
-
'textarea',
|
|
13602
|
-
'form',
|
|
13603
|
-
'button',
|
|
13604
|
-
'select',
|
|
13605
|
-
'input',
|
|
13606
|
-
'meta',
|
|
13607
|
-
'style',
|
|
13608
|
-
'link',
|
|
13609
|
-
'title',
|
|
13610
|
-
'embed',
|
|
13611
|
-
'object',
|
|
13612
|
-
'details',
|
|
13613
|
-
'summary',
|
|
13614
|
-
'base',
|
|
13615
|
-
];
|
|
13616
|
-
var CAN_BE_TAG_WHITE_LIST = ['iframe', 'embed', 'details', 'summary'];
|
|
13617
|
-
var tagBlacklist = __spreadArray$1([], DEFAULT_TAG_BLACK_LIST);
|
|
13618
|
-
function registerTagWhitelistIfPossible(tagName) {
|
|
13619
|
-
if (includes(CAN_BE_TAG_WHITE_LIST, tagName)) {
|
|
13620
|
-
var index = tagBlacklist.indexOf(tagName);
|
|
13621
|
-
if (index > -1) {
|
|
13622
|
-
tagBlacklist.splice(index, 1);
|
|
13623
|
-
}
|
|
13624
|
-
}
|
|
13625
|
-
}
|
|
13626
|
-
function sanitizeHTML(html) {
|
|
13627
|
-
var root = document.createElement('div');
|
|
13628
|
-
if (isString_1(html)) {
|
|
13629
|
-
html = html.replace(reComment, '').replace(reXSSOnload, '$1');
|
|
13630
|
-
root.innerHTML = html;
|
|
13631
|
-
}
|
|
13632
|
-
removeUnnecessaryTags(root);
|
|
13633
|
-
leaveOnlyWhitelistAttribute(root);
|
|
13634
|
-
return finalizeHtml(root, true);
|
|
13635
|
-
}
|
|
13636
|
-
function removeUnnecessaryTags(html) {
|
|
13637
|
-
var removedTags = findNodes(html, tagBlacklist.join(','));
|
|
13638
|
-
removedTags.forEach(function (node) {
|
|
13639
|
-
removeNode$1(node);
|
|
13640
|
-
});
|
|
13646
|
+
/*! @license DOMPurify 2.3.3 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/2.3.3/LICENSE */
|
|
13647
|
+
|
|
13648
|
+
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
|
|
13649
|
+
|
|
13650
|
+
var hasOwnProperty = Object.hasOwnProperty,
|
|
13651
|
+
setPrototypeOf = Object.setPrototypeOf,
|
|
13652
|
+
isFrozen = Object.isFrozen,
|
|
13653
|
+
getPrototypeOf = Object.getPrototypeOf,
|
|
13654
|
+
getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
|
|
13655
|
+
var freeze = Object.freeze,
|
|
13656
|
+
seal = Object.seal,
|
|
13657
|
+
create = Object.create; // eslint-disable-line import/no-mutable-exports
|
|
13658
|
+
|
|
13659
|
+
var _ref = typeof Reflect !== 'undefined' && Reflect,
|
|
13660
|
+
apply = _ref.apply,
|
|
13661
|
+
construct = _ref.construct;
|
|
13662
|
+
|
|
13663
|
+
if (!apply) {
|
|
13664
|
+
apply = function apply(fun, thisValue, args) {
|
|
13665
|
+
return fun.apply(thisValue, args);
|
|
13666
|
+
};
|
|
13641
13667
|
}
|
|
13642
|
-
|
|
13643
|
-
|
|
13668
|
+
|
|
13669
|
+
if (!freeze) {
|
|
13670
|
+
freeze = function freeze(x) {
|
|
13671
|
+
return x;
|
|
13672
|
+
};
|
|
13644
13673
|
}
|
|
13645
|
-
|
|
13646
|
-
|
|
13647
|
-
|
|
13648
|
-
|
|
13649
|
-
|
|
13650
|
-
}
|
|
13651
|
-
node.removeAttribute(name);
|
|
13652
|
-
});
|
|
13674
|
+
|
|
13675
|
+
if (!seal) {
|
|
13676
|
+
seal = function seal(x) {
|
|
13677
|
+
return x;
|
|
13678
|
+
};
|
|
13653
13679
|
}
|
|
13654
|
-
|
|
13655
|
-
|
|
13656
|
-
|
|
13657
|
-
|
|
13658
|
-
|
|
13659
|
-
var htmlAttr = name.match(reHTMLAttr);
|
|
13660
|
-
var svgAttr = name.match(reSvgAttr);
|
|
13661
|
-
var xssAttr = htmlAttr && isXSSAttribute(name, value);
|
|
13662
|
-
return (!htmlAttr && !svgAttr) || xssAttr;
|
|
13663
|
-
});
|
|
13664
|
-
removeBlacklistAttributes(node, blacklist);
|
|
13665
|
-
});
|
|
13680
|
+
|
|
13681
|
+
if (!construct) {
|
|
13682
|
+
construct = function construct(Func, args) {
|
|
13683
|
+
return new (Function.prototype.bind.apply(Func, [null].concat(_toConsumableArray(args))))();
|
|
13684
|
+
};
|
|
13666
13685
|
}
|
|
13667
|
-
|
|
13668
|
-
|
|
13669
|
-
|
|
13686
|
+
|
|
13687
|
+
var arrayForEach = unapply(Array.prototype.forEach);
|
|
13688
|
+
var arrayPop = unapply(Array.prototype.pop);
|
|
13689
|
+
var arrayPush = unapply(Array.prototype.push);
|
|
13690
|
+
|
|
13691
|
+
var stringToLowerCase = unapply(String.prototype.toLowerCase);
|
|
13692
|
+
var stringMatch = unapply(String.prototype.match);
|
|
13693
|
+
var stringReplace = unapply(String.prototype.replace);
|
|
13694
|
+
var stringIndexOf = unapply(String.prototype.indexOf);
|
|
13695
|
+
var stringTrim = unapply(String.prototype.trim);
|
|
13696
|
+
|
|
13697
|
+
var regExpTest = unapply(RegExp.prototype.test);
|
|
13698
|
+
|
|
13699
|
+
var typeErrorCreate = unconstruct(TypeError);
|
|
13700
|
+
|
|
13701
|
+
function unapply(func) {
|
|
13702
|
+
return function (thisArg) {
|
|
13703
|
+
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
13704
|
+
args[_key - 1] = arguments[_key];
|
|
13705
|
+
}
|
|
13706
|
+
|
|
13707
|
+
return apply(func, thisArg, args);
|
|
13708
|
+
};
|
|
13670
13709
|
}
|
|
13671
13710
|
|
|
13672
|
-
function
|
|
13673
|
-
|
|
13674
|
-
|
|
13675
|
-
|
|
13711
|
+
function unconstruct(func) {
|
|
13712
|
+
return function () {
|
|
13713
|
+
for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
13714
|
+
args[_key2] = arguments[_key2];
|
|
13715
|
+
}
|
|
13716
|
+
|
|
13717
|
+
return construct(func, args);
|
|
13718
|
+
};
|
|
13676
13719
|
}
|
|
13677
|
-
|
|
13678
|
-
|
|
13679
|
-
|
|
13680
|
-
|
|
13681
|
-
|
|
13682
|
-
|
|
13683
|
-
|
|
13684
|
-
|
|
13685
|
-
|
|
13686
|
-
|
|
13687
|
-
|
|
13688
|
-
|
|
13720
|
+
|
|
13721
|
+
/* Add properties to a lookup table */
|
|
13722
|
+
function addToSet(set, array) {
|
|
13723
|
+
if (setPrototypeOf) {
|
|
13724
|
+
// Make 'in' and truthy checks like Boolean(set.constructor)
|
|
13725
|
+
// independent of any properties defined on Object.prototype.
|
|
13726
|
+
// Prevent prototype setters from intercepting set as a this value.
|
|
13727
|
+
setPrototypeOf(set, null);
|
|
13728
|
+
}
|
|
13729
|
+
|
|
13730
|
+
var l = array.length;
|
|
13731
|
+
while (l--) {
|
|
13732
|
+
var element = array[l];
|
|
13733
|
+
if (typeof element === 'string') {
|
|
13734
|
+
var lcElement = stringToLowerCase(element);
|
|
13735
|
+
if (lcElement !== element) {
|
|
13736
|
+
// Config presets (e.g. tags.js, attrs.js) are immutable.
|
|
13737
|
+
if (!isFrozen(array)) {
|
|
13738
|
+
array[l] = lcElement;
|
|
13739
|
+
}
|
|
13740
|
+
|
|
13741
|
+
element = lcElement;
|
|
13742
|
+
}
|
|
13743
|
+
}
|
|
13744
|
+
|
|
13745
|
+
set[element] = true;
|
|
13746
|
+
}
|
|
13747
|
+
|
|
13748
|
+
return set;
|
|
13689
13749
|
}
|
|
13690
|
-
|
|
13691
|
-
|
|
13692
|
-
|
|
13693
|
-
|
|
13694
|
-
|
|
13750
|
+
|
|
13751
|
+
/* Shallow clone an object */
|
|
13752
|
+
function clone(object) {
|
|
13753
|
+
var newObject = create(null);
|
|
13754
|
+
|
|
13755
|
+
var property = void 0;
|
|
13756
|
+
for (property in object) {
|
|
13757
|
+
if (apply(hasOwnProperty, object, [property])) {
|
|
13758
|
+
newObject[property] = object[property];
|
|
13759
|
+
}
|
|
13760
|
+
}
|
|
13761
|
+
|
|
13762
|
+
return newObject;
|
|
13695
13763
|
}
|
|
13696
|
-
|
|
13697
|
-
|
|
13698
|
-
|
|
13699
|
-
|
|
13700
|
-
|
|
13701
|
-
|
|
13702
|
-
|
|
13703
|
-
|
|
13764
|
+
|
|
13765
|
+
/* IE10 doesn't support __lookupGetter__ so lets'
|
|
13766
|
+
* simulate it. It also automatically checks
|
|
13767
|
+
* if the prop is function or getter and behaves
|
|
13768
|
+
* accordingly. */
|
|
13769
|
+
function lookupGetter(object, prop) {
|
|
13770
|
+
while (object !== null) {
|
|
13771
|
+
var desc = getOwnPropertyDescriptor(object, prop);
|
|
13772
|
+
if (desc) {
|
|
13773
|
+
if (desc.get) {
|
|
13774
|
+
return unapply(desc.get);
|
|
13775
|
+
}
|
|
13776
|
+
|
|
13777
|
+
if (typeof desc.value === 'function') {
|
|
13778
|
+
return unapply(desc.value);
|
|
13779
|
+
}
|
|
13780
|
+
}
|
|
13781
|
+
|
|
13782
|
+
object = getPrototypeOf(object);
|
|
13783
|
+
}
|
|
13784
|
+
|
|
13785
|
+
function fallbackValue(element) {
|
|
13786
|
+
console.warn('fallback value for', element);
|
|
13787
|
+
return null;
|
|
13788
|
+
}
|
|
13789
|
+
|
|
13790
|
+
return fallbackValue;
|
|
13704
13791
|
}
|
|
13705
|
-
|
|
13706
|
-
|
|
13707
|
-
|
|
13708
|
-
|
|
13709
|
-
|
|
13710
|
-
|
|
13711
|
-
|
|
13712
|
-
|
|
13713
|
-
|
|
13714
|
-
|
|
13715
|
-
|
|
13716
|
-
|
|
13717
|
-
|
|
13718
|
-
|
|
13719
|
-
|
|
13720
|
-
|
|
13721
|
-
|
|
13722
|
-
|
|
13723
|
-
|
|
13724
|
-
|
|
13725
|
-
|
|
13726
|
-
|
|
13727
|
-
|
|
13728
|
-
|
|
13729
|
-
|
|
13730
|
-
|
|
13731
|
-
|
|
13732
|
-
|
|
13733
|
-
|
|
13734
|
-
|
|
13735
|
-
|
|
13736
|
-
|
|
13737
|
-
|
|
13738
|
-
|
|
13739
|
-
|
|
13740
|
-
|
|
13741
|
-
|
|
13742
|
-
|
|
13743
|
-
|
|
13744
|
-
|
|
13745
|
-
|
|
13746
|
-
|
|
13747
|
-
|
|
13748
|
-
|
|
13749
|
-
|
|
13750
|
-
|
|
13751
|
-
|
|
13752
|
-
return [typeName, htmlAttrs, 0];
|
|
13753
|
-
},
|
|
13754
|
-
};
|
|
13755
|
-
},
|
|
13792
|
+
|
|
13793
|
+
var html$2 = 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']);
|
|
13794
|
+
|
|
13795
|
+
// SVG
|
|
13796
|
+
var svg = freeze(['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'circle', 'clippath', 'defs', 'desc', 'ellipse', 'filter', 'font', 'g', 'glyph', 'glyphref', 'hkern', 'image', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'mpath', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', 'stop', 'style', 'switch', 'symbol', 'text', 'textpath', 'title', 'tref', 'tspan', 'view', 'vkern']);
|
|
13797
|
+
|
|
13798
|
+
var svgFilters = freeze(['feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence']);
|
|
13799
|
+
|
|
13800
|
+
// List of SVG elements that are disallowed by default.
|
|
13801
|
+
// We still need to know them so that we can do namespace
|
|
13802
|
+
// checks properly in case one wants to add them to
|
|
13803
|
+
// allow-list.
|
|
13804
|
+
var svgDisallowed = freeze(['animate', 'color-profile', 'cursor', 'discard', 'fedropshadow', 'feimage', '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']);
|
|
13805
|
+
|
|
13806
|
+
var mathMl = freeze(['math', 'menclose', 'merror', 'mfenced', 'mfrac', 'mglyph', 'mi', 'mlabeledtr', 'mmultiscripts', 'mn', 'mo', 'mover', 'mpadded', 'mphantom', 'mroot', 'mrow', 'ms', 'mspace', 'msqrt', 'mstyle', 'msub', 'msup', 'msubsup', 'mtable', 'mtd', 'mtext', 'mtr', 'munder', 'munderover']);
|
|
13807
|
+
|
|
13808
|
+
// Similarly to SVG, we want to know all MathML elements,
|
|
13809
|
+
// even those that we disallow by default.
|
|
13810
|
+
var mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']);
|
|
13811
|
+
|
|
13812
|
+
var text = freeze(['#text']);
|
|
13813
|
+
|
|
13814
|
+
var html$1$1 = freeze(['accept', 'action', 'align', 'alt', 'autocapitalize', 'autocomplete', 'autopictureinpicture', 'autoplay', 'background', 'bgcolor', 'border', 'capture', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'controls', 'controlslist', 'coords', 'crossorigin', 'datetime', 'decoding', 'default', 'dir', 'disabled', 'disablepictureinpicture', 'disableremoteplayback', 'download', 'draggable', 'enctype', 'enterkeyhint', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'inputmode', 'integrity', 'ismap', 'kind', 'label', 'lang', 'list', 'loading', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'muted', 'name', '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']);
|
|
13815
|
+
|
|
13816
|
+
var svg$1 = freeze(['accent-height', 'accumulate', 'additive', 'alignment-baseline', 'ascent', 'attributename', 'attributetype', 'azimuth', 'basefrequency', 'baseline-shift', 'begin', 'bias', 'by', 'class', 'clip', 'clippathunits', 'clip-path', 'clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cx', 'cy', 'd', 'dx', 'dy', 'diffuseconstant', 'direction', 'display', 'divisor', 'dur', 'edgemode', 'elevation', 'end', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'filterunits', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'fx', 'fy', 'g1', 'g2', 'glyph-name', 'glyphref', 'gradientunits', 'gradienttransform', 'height', 'href', 'id', 'image-rendering', 'in', 'in2', 'k', 'k1', 'k2', 'k3', 'k4', 'kerning', 'keypoints', 'keysplines', 'keytimes', 'lang', 'lengthadjust', 'letter-spacing', 'kernelmatrix', 'kernelunitlength', 'lighting-color', 'local', 'marker-end', 'marker-mid', 'marker-start', 'markerheight', 'markerunits', 'markerwidth', 'maskcontentunits', 'maskunits', 'max', 'mask', 'media', 'method', 'mode', 'min', 'name', 'numoctaves', 'offset', 'operator', 'opacity', 'order', 'orient', 'orientation', 'origin', 'overflow', 'paint-order', 'path', 'pathlength', 'patterncontentunits', 'patterntransform', 'patternunits', 'points', 'preservealpha', 'preserveaspectratio', 'primitiveunits', 'r', 'rx', 'ry', 'radius', 'refx', 'refy', 'repeatcount', 'repeatdur', 'restart', 'result', 'rotate', 'scale', 'seed', 'shape-rendering', 'specularconstant', 'specularexponent', 'spreadmethod', 'startoffset', 'stddeviation', 'stitchtiles', 'stop-color', 'stop-opacity', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke', 'stroke-width', 'style', 'surfacescale', 'systemlanguage', 'tabindex', 'targetx', 'targety', 'transform', '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']);
|
|
13817
|
+
|
|
13818
|
+
var mathMl$1 = freeze(['accent', 'accentunder', 'align', 'bevelled', 'close', 'columnsalign', 'columnlines', 'columnspan', 'denomalign', 'depth', 'dir', 'display', 'displaystyle', 'encoding', 'fence', 'frame', 'height', 'href', 'id', 'largeop', 'length', 'linethickness', 'lspace', 'lquote', 'mathbackground', 'mathcolor', 'mathsize', 'mathvariant', 'maxsize', 'minsize', 'movablelimits', 'notation', 'numalign', 'open', 'rowalign', 'rowlines', 'rowspacing', 'rowspan', 'rspace', 'rquote', 'scriptlevel', 'scriptminsize', 'scriptsizemultiplier', 'selection', 'separator', 'separators', 'stretchy', 'subscriptshift', 'supscriptshift', 'symmetric', 'voffset', 'width', 'xmlns']);
|
|
13819
|
+
|
|
13820
|
+
var xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']);
|
|
13821
|
+
|
|
13822
|
+
// eslint-disable-next-line unicorn/better-regex
|
|
13823
|
+
var MUSTACHE_EXPR = seal(/\{\{[\s\S]*|[\s\S]*\}\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode
|
|
13824
|
+
var ERB_EXPR = seal(/<%[\s\S]*|[\s\S]*%>/gm);
|
|
13825
|
+
var DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]/); // eslint-disable-line no-useless-escape
|
|
13826
|
+
var ARIA_ATTR = seal(/^aria-[\-\w]+$/); // eslint-disable-line no-useless-escape
|
|
13827
|
+
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
|
|
13828
|
+
);
|
|
13829
|
+
var IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i);
|
|
13830
|
+
var ATTR_WHITESPACE = seal(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g // eslint-disable-line no-control-regex
|
|
13831
|
+
);
|
|
13832
|
+
|
|
13833
|
+
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
|
13834
|
+
|
|
13835
|
+
function _toConsumableArray$1(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
|
|
13836
|
+
|
|
13837
|
+
var getGlobal = function getGlobal() {
|
|
13838
|
+
return typeof window === 'undefined' ? null : window;
|
|
13756
13839
|
};
|
|
13757
|
-
|
|
13758
|
-
|
|
13759
|
-
|
|
13760
|
-
|
|
13761
|
-
|
|
13762
|
-
|
|
13763
|
-
|
|
13764
|
-
|
|
13765
|
-
|
|
13766
|
-
|
|
13767
|
-
|
|
13840
|
+
|
|
13841
|
+
/**
|
|
13842
|
+
* Creates a no-op policy for internal use only.
|
|
13843
|
+
* Don't export this function outside this module!
|
|
13844
|
+
* @param {?TrustedTypePolicyFactory} trustedTypes The policy factory.
|
|
13845
|
+
* @param {Document} document The document object (to determine policy name suffix)
|
|
13846
|
+
* @return {?TrustedTypePolicy} The policy created (or null, if Trusted Types
|
|
13847
|
+
* are not supported).
|
|
13848
|
+
*/
|
|
13849
|
+
var _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes, document) {
|
|
13850
|
+
if ((typeof trustedTypes === 'undefined' ? 'undefined' : _typeof(trustedTypes)) !== 'object' || typeof trustedTypes.createPolicy !== 'function') {
|
|
13851
|
+
return null;
|
|
13852
|
+
}
|
|
13853
|
+
|
|
13854
|
+
// Allow the callers to control the unique policy name
|
|
13855
|
+
// by adding a data-tt-policy-suffix to the script element with the DOMPurify.
|
|
13856
|
+
// Policy creation with duplicate names throws in Trusted Types.
|
|
13857
|
+
var suffix = null;
|
|
13858
|
+
var ATTR_NAME = 'data-tt-policy-suffix';
|
|
13859
|
+
if (document.currentScript && document.currentScript.hasAttribute(ATTR_NAME)) {
|
|
13860
|
+
suffix = document.currentScript.getAttribute(ATTR_NAME);
|
|
13861
|
+
}
|
|
13862
|
+
|
|
13863
|
+
var policyName = 'dompurify' + (suffix ? '#' + suffix : '');
|
|
13864
|
+
|
|
13865
|
+
try {
|
|
13866
|
+
return trustedTypes.createPolicy(policyName, {
|
|
13867
|
+
createHTML: function createHTML(html$$1) {
|
|
13868
|
+
return html$$1;
|
|
13869
|
+
}
|
|
13768
13870
|
});
|
|
13769
|
-
|
|
13770
|
-
|
|
13871
|
+
} catch (_) {
|
|
13872
|
+
// Policy creation failed (most likely another DOMPurify script has
|
|
13873
|
+
// already run). Skip creating the policy, as this will only cause errors
|
|
13874
|
+
// if TT are enforced.
|
|
13875
|
+
console.warn('TrustedTypes policy ' + policyName + ' could not be created.');
|
|
13876
|
+
return null;
|
|
13877
|
+
}
|
|
13878
|
+
};
|
|
13771
13879
|
|
|
13772
|
-
|
|
13773
|
-
var
|
|
13774
|
-
|
|
13775
|
-
|
|
13776
|
-
|
|
13777
|
-
|
|
13778
|
-
|
|
13779
|
-
|
|
13780
|
-
|
|
13880
|
+
function createDOMPurify() {
|
|
13881
|
+
var window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal();
|
|
13882
|
+
|
|
13883
|
+
var DOMPurify = function DOMPurify(root) {
|
|
13884
|
+
return createDOMPurify(root);
|
|
13885
|
+
};
|
|
13886
|
+
|
|
13887
|
+
/**
|
|
13888
|
+
* Version label, exposed for easier checks
|
|
13889
|
+
* if DOMPurify is up to date or not
|
|
13890
|
+
*/
|
|
13891
|
+
DOMPurify.version = '2.3.3';
|
|
13892
|
+
|
|
13893
|
+
/**
|
|
13894
|
+
* Array of elements that DOMPurify removed during sanitation.
|
|
13895
|
+
* Empty if nothing was removed.
|
|
13896
|
+
*/
|
|
13897
|
+
DOMPurify.removed = [];
|
|
13898
|
+
|
|
13899
|
+
if (!window || !window.document || window.document.nodeType !== 9) {
|
|
13900
|
+
// Not running in a browser, provide a factory function
|
|
13901
|
+
// so that you can pass your own Window
|
|
13902
|
+
DOMPurify.isSupported = false;
|
|
13903
|
+
|
|
13904
|
+
return DOMPurify;
|
|
13905
|
+
}
|
|
13906
|
+
|
|
13907
|
+
var originalDocument = window.document;
|
|
13908
|
+
|
|
13909
|
+
var document = window.document;
|
|
13910
|
+
var DocumentFragment = window.DocumentFragment,
|
|
13911
|
+
HTMLTemplateElement = window.HTMLTemplateElement,
|
|
13912
|
+
Node = window.Node,
|
|
13913
|
+
Element = window.Element,
|
|
13914
|
+
NodeFilter = window.NodeFilter,
|
|
13915
|
+
_window$NamedNodeMap = window.NamedNodeMap,
|
|
13916
|
+
NamedNodeMap = _window$NamedNodeMap === undefined ? window.NamedNodeMap || window.MozNamedAttrMap : _window$NamedNodeMap,
|
|
13917
|
+
Text = window.Text,
|
|
13918
|
+
Comment = window.Comment,
|
|
13919
|
+
DOMParser = window.DOMParser,
|
|
13920
|
+
trustedTypes = window.trustedTypes;
|
|
13921
|
+
|
|
13922
|
+
|
|
13923
|
+
var ElementPrototype = Element.prototype;
|
|
13924
|
+
|
|
13925
|
+
var cloneNode = lookupGetter(ElementPrototype, 'cloneNode');
|
|
13926
|
+
var getNextSibling = lookupGetter(ElementPrototype, 'nextSibling');
|
|
13927
|
+
var getChildNodes = lookupGetter(ElementPrototype, 'childNodes');
|
|
13928
|
+
var getParentNode = lookupGetter(ElementPrototype, 'parentNode');
|
|
13929
|
+
|
|
13930
|
+
// As per issue #47, the web-components registry is inherited by a
|
|
13931
|
+
// new document created via createHTMLDocument. As per the spec
|
|
13932
|
+
// (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries)
|
|
13933
|
+
// a new empty registry is used when creating a template contents owner
|
|
13934
|
+
// document, so we use that as our parent document to ensure nothing
|
|
13935
|
+
// is inherited.
|
|
13936
|
+
if (typeof HTMLTemplateElement === 'function') {
|
|
13937
|
+
var template = document.createElement('template');
|
|
13938
|
+
if (template.content && template.content.ownerDocument) {
|
|
13939
|
+
document = template.content.ownerDocument;
|
|
13940
|
+
}
|
|
13941
|
+
}
|
|
13942
|
+
|
|
13943
|
+
var trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, originalDocument);
|
|
13944
|
+
var emptyHTML = trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML('') : '';
|
|
13945
|
+
|
|
13946
|
+
var _document = document,
|
|
13947
|
+
implementation = _document.implementation,
|
|
13948
|
+
createNodeIterator = _document.createNodeIterator,
|
|
13949
|
+
createDocumentFragment = _document.createDocumentFragment,
|
|
13950
|
+
getElementsByTagName = _document.getElementsByTagName;
|
|
13951
|
+
var importNode = originalDocument.importNode;
|
|
13952
|
+
|
|
13953
|
+
|
|
13954
|
+
var documentMode = {};
|
|
13955
|
+
try {
|
|
13956
|
+
documentMode = clone(document).documentMode ? document.documentMode : {};
|
|
13957
|
+
} catch (_) {}
|
|
13958
|
+
|
|
13959
|
+
var hooks = {};
|
|
13960
|
+
|
|
13961
|
+
/**
|
|
13962
|
+
* Expose whether this browser supports running the full DOMPurify.
|
|
13963
|
+
*/
|
|
13964
|
+
DOMPurify.isSupported = typeof getParentNode === 'function' && implementation && typeof implementation.createHTMLDocument !== 'undefined' && documentMode !== 9;
|
|
13965
|
+
|
|
13966
|
+
var MUSTACHE_EXPR$$1 = MUSTACHE_EXPR,
|
|
13967
|
+
ERB_EXPR$$1 = ERB_EXPR,
|
|
13968
|
+
DATA_ATTR$$1 = DATA_ATTR,
|
|
13969
|
+
ARIA_ATTR$$1 = ARIA_ATTR,
|
|
13970
|
+
IS_SCRIPT_OR_DATA$$1 = IS_SCRIPT_OR_DATA,
|
|
13971
|
+
ATTR_WHITESPACE$$1 = ATTR_WHITESPACE;
|
|
13972
|
+
var IS_ALLOWED_URI$$1 = IS_ALLOWED_URI;
|
|
13973
|
+
|
|
13974
|
+
/**
|
|
13975
|
+
* We consider the elements and attributes below to be safe. Ideally
|
|
13976
|
+
* don't add any new ones but feel free to remove unwanted ones.
|
|
13977
|
+
*/
|
|
13978
|
+
|
|
13979
|
+
/* allowed element names */
|
|
13980
|
+
|
|
13981
|
+
var ALLOWED_TAGS = null;
|
|
13982
|
+
var DEFAULT_ALLOWED_TAGS = addToSet({}, [].concat(_toConsumableArray$1(html$2), _toConsumableArray$1(svg), _toConsumableArray$1(svgFilters), _toConsumableArray$1(mathMl), _toConsumableArray$1(text)));
|
|
13983
|
+
|
|
13984
|
+
/* Allowed attribute names */
|
|
13985
|
+
var ALLOWED_ATTR = null;
|
|
13986
|
+
var DEFAULT_ALLOWED_ATTR = addToSet({}, [].concat(_toConsumableArray$1(html$1$1), _toConsumableArray$1(svg$1), _toConsumableArray$1(mathMl$1), _toConsumableArray$1(xml)));
|
|
13987
|
+
|
|
13988
|
+
/* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */
|
|
13989
|
+
var FORBID_TAGS = null;
|
|
13990
|
+
|
|
13991
|
+
/* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */
|
|
13992
|
+
var FORBID_ATTR = null;
|
|
13993
|
+
|
|
13994
|
+
/* Decide if ARIA attributes are okay */
|
|
13995
|
+
var ALLOW_ARIA_ATTR = true;
|
|
13996
|
+
|
|
13997
|
+
/* Decide if custom data attributes are okay */
|
|
13998
|
+
var ALLOW_DATA_ATTR = true;
|
|
13999
|
+
|
|
14000
|
+
/* Decide if unknown protocols are okay */
|
|
14001
|
+
var ALLOW_UNKNOWN_PROTOCOLS = false;
|
|
14002
|
+
|
|
14003
|
+
/* Output should be safe for common template engines.
|
|
14004
|
+
* This means, DOMPurify removes data attributes, mustaches and ERB
|
|
14005
|
+
*/
|
|
14006
|
+
var SAFE_FOR_TEMPLATES = false;
|
|
14007
|
+
|
|
14008
|
+
/* Decide if document with <html>... should be returned */
|
|
14009
|
+
var WHOLE_DOCUMENT = false;
|
|
14010
|
+
|
|
14011
|
+
/* Track whether config is already set on this instance of DOMPurify. */
|
|
14012
|
+
var SET_CONFIG = false;
|
|
14013
|
+
|
|
14014
|
+
/* Decide if all elements (e.g. style, script) must be children of
|
|
14015
|
+
* document.body. By default, browsers might move them to document.head */
|
|
14016
|
+
var FORCE_BODY = false;
|
|
14017
|
+
|
|
14018
|
+
/* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html
|
|
14019
|
+
* string (or a TrustedHTML object if Trusted Types are supported).
|
|
14020
|
+
* If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead
|
|
14021
|
+
*/
|
|
14022
|
+
var RETURN_DOM = false;
|
|
14023
|
+
|
|
14024
|
+
/* Decide if a DOM `DocumentFragment` should be returned, instead of a html
|
|
14025
|
+
* string (or a TrustedHTML object if Trusted Types are supported) */
|
|
14026
|
+
var RETURN_DOM_FRAGMENT = false;
|
|
14027
|
+
|
|
14028
|
+
/* If `RETURN_DOM` or `RETURN_DOM_FRAGMENT` is enabled, decide if the returned DOM
|
|
14029
|
+
* `Node` is imported into the current `Document`. If this flag is not enabled the
|
|
14030
|
+
* `Node` will belong (its ownerDocument) to a fresh `HTMLDocument`, created by
|
|
14031
|
+
* DOMPurify.
|
|
14032
|
+
*
|
|
14033
|
+
* This defaults to `true` starting DOMPurify 2.2.0. Note that setting it to `false`
|
|
14034
|
+
* might cause XSS from attacks hidden in closed shadowroots in case the browser
|
|
14035
|
+
* supports Declarative Shadow: DOM https://web.dev/declarative-shadow-dom/
|
|
14036
|
+
*/
|
|
14037
|
+
var RETURN_DOM_IMPORT = true;
|
|
14038
|
+
|
|
14039
|
+
/* Try to return a Trusted Type object instead of a string, return a string in
|
|
14040
|
+
* case Trusted Types are not supported */
|
|
14041
|
+
var RETURN_TRUSTED_TYPE = false;
|
|
14042
|
+
|
|
14043
|
+
/* Output should be free from DOM clobbering attacks? */
|
|
14044
|
+
var SANITIZE_DOM = true;
|
|
14045
|
+
|
|
14046
|
+
/* Keep element content when removing element? */
|
|
14047
|
+
var KEEP_CONTENT = true;
|
|
14048
|
+
|
|
14049
|
+
/* If a `Node` is passed to sanitize(), then performs sanitization in-place instead
|
|
14050
|
+
* of importing it into a new Document and returning a sanitized copy */
|
|
14051
|
+
var IN_PLACE = false;
|
|
14052
|
+
|
|
14053
|
+
/* Allow usage of profiles like html, svg and mathMl */
|
|
14054
|
+
var USE_PROFILES = {};
|
|
14055
|
+
|
|
14056
|
+
/* Tags to ignore content of when KEEP_CONTENT is true */
|
|
14057
|
+
var FORBID_CONTENTS = null;
|
|
14058
|
+
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']);
|
|
14059
|
+
|
|
14060
|
+
/* Tags that are safe for data: URIs */
|
|
14061
|
+
var DATA_URI_TAGS = null;
|
|
14062
|
+
var DEFAULT_DATA_URI_TAGS = addToSet({}, ['audio', 'video', 'img', 'source', 'image', 'track']);
|
|
14063
|
+
|
|
14064
|
+
/* Attributes safe for values like "javascript:" */
|
|
14065
|
+
var URI_SAFE_ATTRIBUTES = null;
|
|
14066
|
+
var DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ['alt', 'class', 'for', 'id', 'label', 'name', 'pattern', 'placeholder', 'role', 'summary', 'title', 'value', 'style', 'xmlns']);
|
|
14067
|
+
|
|
14068
|
+
var MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
|
|
14069
|
+
var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
|
|
14070
|
+
var HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';
|
|
14071
|
+
/* Document namespace */
|
|
14072
|
+
var NAMESPACE = HTML_NAMESPACE;
|
|
14073
|
+
var IS_EMPTY_INPUT = false;
|
|
14074
|
+
|
|
14075
|
+
/* Parsing of strict XHTML documents */
|
|
14076
|
+
var PARSER_MEDIA_TYPE = void 0;
|
|
14077
|
+
var SUPPORTED_PARSER_MEDIA_TYPES = ['application/xhtml+xml', 'text/html'];
|
|
14078
|
+
var DEFAULT_PARSER_MEDIA_TYPE = 'text/html';
|
|
14079
|
+
var transformCaseFunc = void 0;
|
|
14080
|
+
|
|
14081
|
+
/* Keep a reference to config to pass to hooks */
|
|
14082
|
+
var CONFIG = null;
|
|
14083
|
+
|
|
14084
|
+
/* Ideally, do not touch anything below this line */
|
|
14085
|
+
/* ______________________________________________ */
|
|
14086
|
+
|
|
14087
|
+
var formElement = document.createElement('form');
|
|
14088
|
+
|
|
14089
|
+
/**
|
|
14090
|
+
* _parseConfig
|
|
14091
|
+
*
|
|
14092
|
+
* @param {Object} cfg optional config literal
|
|
14093
|
+
*/
|
|
14094
|
+
// eslint-disable-next-line complexity
|
|
14095
|
+
var _parseConfig = function _parseConfig(cfg) {
|
|
14096
|
+
if (CONFIG && CONFIG === cfg) {
|
|
14097
|
+
return;
|
|
14098
|
+
}
|
|
14099
|
+
|
|
14100
|
+
/* Shield configuration object from tampering */
|
|
14101
|
+
if (!cfg || (typeof cfg === 'undefined' ? 'undefined' : _typeof(cfg)) !== 'object') {
|
|
14102
|
+
cfg = {};
|
|
14103
|
+
}
|
|
14104
|
+
|
|
14105
|
+
/* Shield configuration object from prototype pollution */
|
|
14106
|
+
cfg = clone(cfg);
|
|
14107
|
+
|
|
14108
|
+
/* Set configuration parameters */
|
|
14109
|
+
ALLOWED_TAGS = 'ALLOWED_TAGS' in cfg ? addToSet({}, cfg.ALLOWED_TAGS) : DEFAULT_ALLOWED_TAGS;
|
|
14110
|
+
ALLOWED_ATTR = 'ALLOWED_ATTR' in cfg ? addToSet({}, cfg.ALLOWED_ATTR) : DEFAULT_ALLOWED_ATTR;
|
|
14111
|
+
URI_SAFE_ATTRIBUTES = 'ADD_URI_SAFE_ATTR' in cfg ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR) : DEFAULT_URI_SAFE_ATTRIBUTES;
|
|
14112
|
+
DATA_URI_TAGS = 'ADD_DATA_URI_TAGS' in cfg ? addToSet(clone(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS) : DEFAULT_DATA_URI_TAGS;
|
|
14113
|
+
FORBID_CONTENTS = 'FORBID_CONTENTS' in cfg ? addToSet({}, cfg.FORBID_CONTENTS) : DEFAULT_FORBID_CONTENTS;
|
|
14114
|
+
FORBID_TAGS = 'FORBID_TAGS' in cfg ? addToSet({}, cfg.FORBID_TAGS) : {};
|
|
14115
|
+
FORBID_ATTR = 'FORBID_ATTR' in cfg ? addToSet({}, cfg.FORBID_ATTR) : {};
|
|
14116
|
+
USE_PROFILES = 'USE_PROFILES' in cfg ? cfg.USE_PROFILES : false;
|
|
14117
|
+
ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true
|
|
14118
|
+
ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true
|
|
14119
|
+
ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false
|
|
14120
|
+
SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false
|
|
14121
|
+
WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false
|
|
14122
|
+
RETURN_DOM = cfg.RETURN_DOM || false; // Default false
|
|
14123
|
+
RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false
|
|
14124
|
+
RETURN_DOM_IMPORT = cfg.RETURN_DOM_IMPORT !== false; // Default true
|
|
14125
|
+
RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false
|
|
14126
|
+
FORCE_BODY = cfg.FORCE_BODY || false; // Default false
|
|
14127
|
+
SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true
|
|
14128
|
+
KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true
|
|
14129
|
+
IN_PLACE = cfg.IN_PLACE || false; // Default false
|
|
14130
|
+
IS_ALLOWED_URI$$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI$$1;
|
|
14131
|
+
NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE;
|
|
14132
|
+
|
|
14133
|
+
PARSER_MEDIA_TYPE =
|
|
14134
|
+
// eslint-disable-next-line unicorn/prefer-includes
|
|
14135
|
+
SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? PARSER_MEDIA_TYPE = DEFAULT_PARSER_MEDIA_TYPE : PARSER_MEDIA_TYPE = cfg.PARSER_MEDIA_TYPE;
|
|
14136
|
+
|
|
14137
|
+
// HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is.
|
|
14138
|
+
transformCaseFunc = PARSER_MEDIA_TYPE === 'application/xhtml+xml' ? function (x) {
|
|
14139
|
+
return x;
|
|
14140
|
+
} : stringToLowerCase;
|
|
14141
|
+
|
|
14142
|
+
if (SAFE_FOR_TEMPLATES) {
|
|
14143
|
+
ALLOW_DATA_ATTR = false;
|
|
14144
|
+
}
|
|
14145
|
+
|
|
14146
|
+
if (RETURN_DOM_FRAGMENT) {
|
|
14147
|
+
RETURN_DOM = true;
|
|
14148
|
+
}
|
|
14149
|
+
|
|
14150
|
+
/* Parse profile info */
|
|
14151
|
+
if (USE_PROFILES) {
|
|
14152
|
+
ALLOWED_TAGS = addToSet({}, [].concat(_toConsumableArray$1(text)));
|
|
14153
|
+
ALLOWED_ATTR = [];
|
|
14154
|
+
if (USE_PROFILES.html === true) {
|
|
14155
|
+
addToSet(ALLOWED_TAGS, html$2);
|
|
14156
|
+
addToSet(ALLOWED_ATTR, html$1$1);
|
|
14157
|
+
}
|
|
14158
|
+
|
|
14159
|
+
if (USE_PROFILES.svg === true) {
|
|
14160
|
+
addToSet(ALLOWED_TAGS, svg);
|
|
14161
|
+
addToSet(ALLOWED_ATTR, svg$1);
|
|
14162
|
+
addToSet(ALLOWED_ATTR, xml);
|
|
14163
|
+
}
|
|
14164
|
+
|
|
14165
|
+
if (USE_PROFILES.svgFilters === true) {
|
|
14166
|
+
addToSet(ALLOWED_TAGS, svgFilters);
|
|
14167
|
+
addToSet(ALLOWED_ATTR, svg$1);
|
|
14168
|
+
addToSet(ALLOWED_ATTR, xml);
|
|
14169
|
+
}
|
|
14170
|
+
|
|
14171
|
+
if (USE_PROFILES.mathMl === true) {
|
|
14172
|
+
addToSet(ALLOWED_TAGS, mathMl);
|
|
14173
|
+
addToSet(ALLOWED_ATTR, mathMl$1);
|
|
14174
|
+
addToSet(ALLOWED_ATTR, xml);
|
|
14175
|
+
}
|
|
14176
|
+
}
|
|
14177
|
+
|
|
14178
|
+
/* Merge configuration parameters */
|
|
14179
|
+
if (cfg.ADD_TAGS) {
|
|
14180
|
+
if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {
|
|
14181
|
+
ALLOWED_TAGS = clone(ALLOWED_TAGS);
|
|
14182
|
+
}
|
|
14183
|
+
|
|
14184
|
+
addToSet(ALLOWED_TAGS, cfg.ADD_TAGS);
|
|
14185
|
+
}
|
|
14186
|
+
|
|
14187
|
+
if (cfg.ADD_ATTR) {
|
|
14188
|
+
if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {
|
|
14189
|
+
ALLOWED_ATTR = clone(ALLOWED_ATTR);
|
|
14190
|
+
}
|
|
14191
|
+
|
|
14192
|
+
addToSet(ALLOWED_ATTR, cfg.ADD_ATTR);
|
|
14193
|
+
}
|
|
14194
|
+
|
|
14195
|
+
if (cfg.ADD_URI_SAFE_ATTR) {
|
|
14196
|
+
addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR);
|
|
14197
|
+
}
|
|
14198
|
+
|
|
14199
|
+
if (cfg.FORBID_CONTENTS) {
|
|
14200
|
+
if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {
|
|
14201
|
+
FORBID_CONTENTS = clone(FORBID_CONTENTS);
|
|
14202
|
+
}
|
|
14203
|
+
|
|
14204
|
+
addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS);
|
|
14205
|
+
}
|
|
14206
|
+
|
|
14207
|
+
/* Add #text in case KEEP_CONTENT is set to true */
|
|
14208
|
+
if (KEEP_CONTENT) {
|
|
14209
|
+
ALLOWED_TAGS['#text'] = true;
|
|
14210
|
+
}
|
|
14211
|
+
|
|
14212
|
+
/* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */
|
|
14213
|
+
if (WHOLE_DOCUMENT) {
|
|
14214
|
+
addToSet(ALLOWED_TAGS, ['html', 'head', 'body']);
|
|
14215
|
+
}
|
|
14216
|
+
|
|
14217
|
+
/* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */
|
|
14218
|
+
if (ALLOWED_TAGS.table) {
|
|
14219
|
+
addToSet(ALLOWED_TAGS, ['tbody']);
|
|
14220
|
+
delete FORBID_TAGS.tbody;
|
|
14221
|
+
}
|
|
14222
|
+
|
|
14223
|
+
// Prevent further manipulation of configuration.
|
|
14224
|
+
// Not available in IE8, Safari 5, etc.
|
|
14225
|
+
if (freeze) {
|
|
14226
|
+
freeze(cfg);
|
|
14227
|
+
}
|
|
14228
|
+
|
|
14229
|
+
CONFIG = cfg;
|
|
14230
|
+
};
|
|
14231
|
+
|
|
14232
|
+
var MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ['mi', 'mo', 'mn', 'ms', 'mtext']);
|
|
14233
|
+
|
|
14234
|
+
var HTML_INTEGRATION_POINTS = addToSet({}, ['foreignobject', 'desc', 'title', 'annotation-xml']);
|
|
14235
|
+
|
|
14236
|
+
/* Keep track of all possible SVG and MathML tags
|
|
14237
|
+
* so that we can perform the namespace checks
|
|
14238
|
+
* correctly. */
|
|
14239
|
+
var ALL_SVG_TAGS = addToSet({}, svg);
|
|
14240
|
+
addToSet(ALL_SVG_TAGS, svgFilters);
|
|
14241
|
+
addToSet(ALL_SVG_TAGS, svgDisallowed);
|
|
14242
|
+
|
|
14243
|
+
var ALL_MATHML_TAGS = addToSet({}, mathMl);
|
|
14244
|
+
addToSet(ALL_MATHML_TAGS, mathMlDisallowed);
|
|
14245
|
+
|
|
14246
|
+
/**
|
|
14247
|
+
*
|
|
14248
|
+
*
|
|
14249
|
+
* @param {Element} element a DOM element whose namespace is being checked
|
|
14250
|
+
* @returns {boolean} Return false if the element has a
|
|
14251
|
+
* namespace that a spec-compliant parser would never
|
|
14252
|
+
* return. Return true otherwise.
|
|
14253
|
+
*/
|
|
14254
|
+
var _checkValidNamespace = function _checkValidNamespace(element) {
|
|
14255
|
+
var parent = getParentNode(element);
|
|
14256
|
+
|
|
14257
|
+
// In JSDOM, if we're inside shadow DOM, then parentNode
|
|
14258
|
+
// can be null. We just simulate parent in this case.
|
|
14259
|
+
if (!parent || !parent.tagName) {
|
|
14260
|
+
parent = {
|
|
14261
|
+
namespaceURI: HTML_NAMESPACE,
|
|
14262
|
+
tagName: 'template'
|
|
14263
|
+
};
|
|
14264
|
+
}
|
|
14265
|
+
|
|
14266
|
+
var tagName = stringToLowerCase(element.tagName);
|
|
14267
|
+
var parentTagName = stringToLowerCase(parent.tagName);
|
|
14268
|
+
|
|
14269
|
+
if (element.namespaceURI === SVG_NAMESPACE) {
|
|
14270
|
+
// The only way to switch from HTML namespace to SVG
|
|
14271
|
+
// is via <svg>. If it happens via any other tag, then
|
|
14272
|
+
// it should be killed.
|
|
14273
|
+
if (parent.namespaceURI === HTML_NAMESPACE) {
|
|
14274
|
+
return tagName === 'svg';
|
|
14275
|
+
}
|
|
14276
|
+
|
|
14277
|
+
// The only way to switch from MathML to SVG is via
|
|
14278
|
+
// svg if parent is either <annotation-xml> or MathML
|
|
14279
|
+
// text integration points.
|
|
14280
|
+
if (parent.namespaceURI === MATHML_NAMESPACE) {
|
|
14281
|
+
return tagName === 'svg' && (parentTagName === 'annotation-xml' || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]);
|
|
14282
|
+
}
|
|
14283
|
+
|
|
14284
|
+
// We only allow elements that are defined in SVG
|
|
14285
|
+
// spec. All others are disallowed in SVG namespace.
|
|
14286
|
+
return Boolean(ALL_SVG_TAGS[tagName]);
|
|
14287
|
+
}
|
|
14288
|
+
|
|
14289
|
+
if (element.namespaceURI === MATHML_NAMESPACE) {
|
|
14290
|
+
// The only way to switch from HTML namespace to MathML
|
|
14291
|
+
// is via <math>. If it happens via any other tag, then
|
|
14292
|
+
// it should be killed.
|
|
14293
|
+
if (parent.namespaceURI === HTML_NAMESPACE) {
|
|
14294
|
+
return tagName === 'math';
|
|
14295
|
+
}
|
|
14296
|
+
|
|
14297
|
+
// The only way to switch from SVG to MathML is via
|
|
14298
|
+
// <math> and HTML integration points
|
|
14299
|
+
if (parent.namespaceURI === SVG_NAMESPACE) {
|
|
14300
|
+
return tagName === 'math' && HTML_INTEGRATION_POINTS[parentTagName];
|
|
14301
|
+
}
|
|
14302
|
+
|
|
14303
|
+
// We only allow elements that are defined in MathML
|
|
14304
|
+
// spec. All others are disallowed in MathML namespace.
|
|
14305
|
+
return Boolean(ALL_MATHML_TAGS[tagName]);
|
|
14306
|
+
}
|
|
14307
|
+
|
|
14308
|
+
if (element.namespaceURI === HTML_NAMESPACE) {
|
|
14309
|
+
// The only way to switch from SVG to HTML is via
|
|
14310
|
+
// HTML integration points, and from MathML to HTML
|
|
14311
|
+
// is via MathML text integration points
|
|
14312
|
+
if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) {
|
|
14313
|
+
return false;
|
|
14314
|
+
}
|
|
14315
|
+
|
|
14316
|
+
if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) {
|
|
14317
|
+
return false;
|
|
14318
|
+
}
|
|
14319
|
+
|
|
14320
|
+
// Certain elements are allowed in both SVG and HTML
|
|
14321
|
+
// namespace. We need to specify them explicitly
|
|
14322
|
+
// so that they don't get erronously deleted from
|
|
14323
|
+
// HTML namespace.
|
|
14324
|
+
var commonSvgAndHTMLElements = addToSet({}, ['title', 'style', 'font', 'a', 'script']);
|
|
14325
|
+
|
|
14326
|
+
// We disallow tags that are specific for MathML
|
|
14327
|
+
// or SVG and should never appear in HTML namespace
|
|
14328
|
+
return !ALL_MATHML_TAGS[tagName] && (commonSvgAndHTMLElements[tagName] || !ALL_SVG_TAGS[tagName]);
|
|
14329
|
+
}
|
|
14330
|
+
|
|
14331
|
+
// The code should never reach this place (this means
|
|
14332
|
+
// that the element somehow got namespace that is not
|
|
14333
|
+
// HTML, SVG or MathML). Return false just in case.
|
|
14334
|
+
return false;
|
|
14335
|
+
};
|
|
14336
|
+
|
|
14337
|
+
/**
|
|
14338
|
+
* _forceRemove
|
|
14339
|
+
*
|
|
14340
|
+
* @param {Node} node a DOM node
|
|
14341
|
+
*/
|
|
14342
|
+
var _forceRemove = function _forceRemove(node) {
|
|
14343
|
+
arrayPush(DOMPurify.removed, { element: node });
|
|
14344
|
+
try {
|
|
14345
|
+
// eslint-disable-next-line unicorn/prefer-dom-node-remove
|
|
14346
|
+
node.parentNode.removeChild(node);
|
|
14347
|
+
} catch (_) {
|
|
14348
|
+
try {
|
|
14349
|
+
node.outerHTML = emptyHTML;
|
|
14350
|
+
} catch (_) {
|
|
14351
|
+
node.remove();
|
|
14352
|
+
}
|
|
14353
|
+
}
|
|
14354
|
+
};
|
|
14355
|
+
|
|
14356
|
+
/**
|
|
14357
|
+
* _removeAttribute
|
|
14358
|
+
*
|
|
14359
|
+
* @param {String} name an Attribute name
|
|
14360
|
+
* @param {Node} node a DOM node
|
|
14361
|
+
*/
|
|
14362
|
+
var _removeAttribute = function _removeAttribute(name, node) {
|
|
14363
|
+
try {
|
|
14364
|
+
arrayPush(DOMPurify.removed, {
|
|
14365
|
+
attribute: node.getAttributeNode(name),
|
|
14366
|
+
from: node
|
|
14367
|
+
});
|
|
14368
|
+
} catch (_) {
|
|
14369
|
+
arrayPush(DOMPurify.removed, {
|
|
14370
|
+
attribute: null,
|
|
14371
|
+
from: node
|
|
14372
|
+
});
|
|
14373
|
+
}
|
|
14374
|
+
|
|
14375
|
+
node.removeAttribute(name);
|
|
14376
|
+
|
|
14377
|
+
// We void attribute values for unremovable "is"" attributes
|
|
14378
|
+
if (name === 'is' && !ALLOWED_ATTR[name]) {
|
|
14379
|
+
if (RETURN_DOM || RETURN_DOM_FRAGMENT) {
|
|
14380
|
+
try {
|
|
14381
|
+
_forceRemove(node);
|
|
14382
|
+
} catch (_) {}
|
|
14383
|
+
} else {
|
|
14384
|
+
try {
|
|
14385
|
+
node.setAttribute(name, '');
|
|
14386
|
+
} catch (_) {}
|
|
14387
|
+
}
|
|
14388
|
+
}
|
|
14389
|
+
};
|
|
14390
|
+
|
|
14391
|
+
/**
|
|
14392
|
+
* _initDocument
|
|
14393
|
+
*
|
|
14394
|
+
* @param {String} dirty a string of dirty markup
|
|
14395
|
+
* @return {Document} a DOM, filled with the dirty markup
|
|
14396
|
+
*/
|
|
14397
|
+
var _initDocument = function _initDocument(dirty) {
|
|
14398
|
+
/* Create a HTML document */
|
|
14399
|
+
var doc = void 0;
|
|
14400
|
+
var leadingWhitespace = void 0;
|
|
14401
|
+
|
|
14402
|
+
if (FORCE_BODY) {
|
|
14403
|
+
dirty = '<remove></remove>' + dirty;
|
|
14404
|
+
} else {
|
|
14405
|
+
/* If FORCE_BODY isn't used, leading whitespace needs to be preserved manually */
|
|
14406
|
+
var matches = stringMatch(dirty, /^[\r\n\t ]+/);
|
|
14407
|
+
leadingWhitespace = matches && matches[0];
|
|
14408
|
+
}
|
|
14409
|
+
|
|
14410
|
+
if (PARSER_MEDIA_TYPE === 'application/xhtml+xml') {
|
|
14411
|
+
// Root of XHTML doc must contain xmlns declaration (see https://www.w3.org/TR/xhtml1/normative.html#strict)
|
|
14412
|
+
dirty = '<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>' + dirty + '</body></html>';
|
|
14413
|
+
}
|
|
14414
|
+
|
|
14415
|
+
var dirtyPayload = trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty;
|
|
14416
|
+
/*
|
|
14417
|
+
* Use the DOMParser API by default, fallback later if needs be
|
|
14418
|
+
* DOMParser not work for svg when has multiple root element.
|
|
14419
|
+
*/
|
|
14420
|
+
if (NAMESPACE === HTML_NAMESPACE) {
|
|
14421
|
+
try {
|
|
14422
|
+
doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE);
|
|
14423
|
+
} catch (_) {}
|
|
14424
|
+
}
|
|
14425
|
+
|
|
14426
|
+
/* Use createHTMLDocument in case DOMParser is not available */
|
|
14427
|
+
if (!doc || !doc.documentElement) {
|
|
14428
|
+
doc = implementation.createDocument(NAMESPACE, 'template', null);
|
|
14429
|
+
try {
|
|
14430
|
+
doc.documentElement.innerHTML = IS_EMPTY_INPUT ? '' : dirtyPayload;
|
|
14431
|
+
} catch (_) {
|
|
14432
|
+
// Syntax error if dirtyPayload is invalid xml
|
|
14433
|
+
}
|
|
14434
|
+
}
|
|
14435
|
+
|
|
14436
|
+
var body = doc.body || doc.documentElement;
|
|
14437
|
+
|
|
14438
|
+
if (dirty && leadingWhitespace) {
|
|
14439
|
+
body.insertBefore(document.createTextNode(leadingWhitespace), body.childNodes[0] || null);
|
|
14440
|
+
}
|
|
14441
|
+
|
|
14442
|
+
/* Work on whole document or just its body */
|
|
14443
|
+
if (NAMESPACE === HTML_NAMESPACE) {
|
|
14444
|
+
return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0];
|
|
14445
|
+
}
|
|
14446
|
+
|
|
14447
|
+
return WHOLE_DOCUMENT ? doc.documentElement : body;
|
|
14448
|
+
};
|
|
14449
|
+
|
|
14450
|
+
/**
|
|
14451
|
+
* _createIterator
|
|
14452
|
+
*
|
|
14453
|
+
* @param {Document} root document/fragment to create iterator for
|
|
14454
|
+
* @return {Iterator} iterator instance
|
|
14455
|
+
*/
|
|
14456
|
+
var _createIterator = function _createIterator(root) {
|
|
14457
|
+
return createNodeIterator.call(root.ownerDocument || root, root, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT, null, false);
|
|
14458
|
+
};
|
|
14459
|
+
|
|
14460
|
+
/**
|
|
14461
|
+
* _isClobbered
|
|
14462
|
+
*
|
|
14463
|
+
* @param {Node} elm element to check for clobbering attacks
|
|
14464
|
+
* @return {Boolean} true if clobbered, false if safe
|
|
14465
|
+
*/
|
|
14466
|
+
var _isClobbered = function _isClobbered(elm) {
|
|
14467
|
+
if (elm instanceof Text || elm instanceof Comment) {
|
|
14468
|
+
return false;
|
|
14469
|
+
}
|
|
14470
|
+
|
|
14471
|
+
if (typeof elm.nodeName !== 'string' || typeof elm.textContent !== 'string' || typeof elm.removeChild !== 'function' || !(elm.attributes instanceof NamedNodeMap) || typeof elm.removeAttribute !== 'function' || typeof elm.setAttribute !== 'function' || typeof elm.namespaceURI !== 'string' || typeof elm.insertBefore !== 'function') {
|
|
14472
|
+
return true;
|
|
14473
|
+
}
|
|
14474
|
+
|
|
14475
|
+
return false;
|
|
14476
|
+
};
|
|
14477
|
+
|
|
14478
|
+
/**
|
|
14479
|
+
* _isNode
|
|
14480
|
+
*
|
|
14481
|
+
* @param {Node} obj object to check whether it's a DOM node
|
|
14482
|
+
* @return {Boolean} true is object is a DOM node
|
|
14483
|
+
*/
|
|
14484
|
+
var _isNode = function _isNode(object) {
|
|
14485
|
+
return (typeof Node === 'undefined' ? 'undefined' : _typeof(Node)) === 'object' ? object instanceof Node : object && (typeof object === 'undefined' ? 'undefined' : _typeof(object)) === 'object' && typeof object.nodeType === 'number' && typeof object.nodeName === 'string';
|
|
14486
|
+
};
|
|
14487
|
+
|
|
14488
|
+
/**
|
|
14489
|
+
* _executeHook
|
|
14490
|
+
* Execute user configurable hooks
|
|
14491
|
+
*
|
|
14492
|
+
* @param {String} entryPoint Name of the hook's entry point
|
|
14493
|
+
* @param {Node} currentNode node to work on with the hook
|
|
14494
|
+
* @param {Object} data additional hook parameters
|
|
14495
|
+
*/
|
|
14496
|
+
var _executeHook = function _executeHook(entryPoint, currentNode, data) {
|
|
14497
|
+
if (!hooks[entryPoint]) {
|
|
14498
|
+
return;
|
|
14499
|
+
}
|
|
14500
|
+
|
|
14501
|
+
arrayForEach(hooks[entryPoint], function (hook) {
|
|
14502
|
+
hook.call(DOMPurify, currentNode, data, CONFIG);
|
|
14503
|
+
});
|
|
14504
|
+
};
|
|
14505
|
+
|
|
14506
|
+
/**
|
|
14507
|
+
* _sanitizeElements
|
|
14508
|
+
*
|
|
14509
|
+
* @protect nodeName
|
|
14510
|
+
* @protect textContent
|
|
14511
|
+
* @protect removeChild
|
|
14512
|
+
*
|
|
14513
|
+
* @param {Node} currentNode to check for permission to exist
|
|
14514
|
+
* @return {Boolean} true if node was killed, false if left alive
|
|
14515
|
+
*/
|
|
14516
|
+
var _sanitizeElements = function _sanitizeElements(currentNode) {
|
|
14517
|
+
var content = void 0;
|
|
14518
|
+
|
|
14519
|
+
/* Execute a hook if present */
|
|
14520
|
+
_executeHook('beforeSanitizeElements', currentNode, null);
|
|
14521
|
+
|
|
14522
|
+
/* Check if element is clobbered or can clobber */
|
|
14523
|
+
if (_isClobbered(currentNode)) {
|
|
14524
|
+
_forceRemove(currentNode);
|
|
14525
|
+
return true;
|
|
14526
|
+
}
|
|
14527
|
+
|
|
14528
|
+
/* Check if tagname contains Unicode */
|
|
14529
|
+
if (stringMatch(currentNode.nodeName, /[\u0080-\uFFFF]/)) {
|
|
14530
|
+
_forceRemove(currentNode);
|
|
14531
|
+
return true;
|
|
14532
|
+
}
|
|
14533
|
+
|
|
14534
|
+
/* Now let's check the element's type and name */
|
|
14535
|
+
var tagName = transformCaseFunc(currentNode.nodeName);
|
|
14536
|
+
|
|
14537
|
+
/* Execute a hook if present */
|
|
14538
|
+
_executeHook('uponSanitizeElement', currentNode, {
|
|
14539
|
+
tagName: tagName,
|
|
14540
|
+
allowedTags: ALLOWED_TAGS
|
|
14541
|
+
});
|
|
14542
|
+
|
|
14543
|
+
/* Detect mXSS attempts abusing namespace confusion */
|
|
14544
|
+
if (!_isNode(currentNode.firstElementChild) && (!_isNode(currentNode.content) || !_isNode(currentNode.content.firstElementChild)) && regExpTest(/<[/\w]/g, currentNode.innerHTML) && regExpTest(/<[/\w]/g, currentNode.textContent)) {
|
|
14545
|
+
_forceRemove(currentNode);
|
|
14546
|
+
return true;
|
|
14547
|
+
}
|
|
14548
|
+
|
|
14549
|
+
/* Mitigate a problem with templates inside select */
|
|
14550
|
+
if (tagName === 'select' && regExpTest(/<template/i, currentNode.innerHTML)) {
|
|
14551
|
+
_forceRemove(currentNode);
|
|
14552
|
+
return true;
|
|
14553
|
+
}
|
|
14554
|
+
|
|
14555
|
+
/* Remove element if anything forbids its presence */
|
|
14556
|
+
if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
|
|
14557
|
+
/* Keep content except for bad-listed elements */
|
|
14558
|
+
if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {
|
|
14559
|
+
var parentNode = getParentNode(currentNode) || currentNode.parentNode;
|
|
14560
|
+
var childNodes = getChildNodes(currentNode) || currentNode.childNodes;
|
|
14561
|
+
|
|
14562
|
+
if (childNodes && parentNode) {
|
|
14563
|
+
var childCount = childNodes.length;
|
|
14564
|
+
|
|
14565
|
+
for (var i = childCount - 1; i >= 0; --i) {
|
|
14566
|
+
parentNode.insertBefore(cloneNode(childNodes[i], true), getNextSibling(currentNode));
|
|
14567
|
+
}
|
|
14568
|
+
}
|
|
14569
|
+
}
|
|
14570
|
+
|
|
14571
|
+
_forceRemove(currentNode);
|
|
14572
|
+
return true;
|
|
14573
|
+
}
|
|
14574
|
+
|
|
14575
|
+
/* Check whether element has a valid namespace */
|
|
14576
|
+
if (currentNode instanceof Element && !_checkValidNamespace(currentNode)) {
|
|
14577
|
+
_forceRemove(currentNode);
|
|
14578
|
+
return true;
|
|
14579
|
+
}
|
|
14580
|
+
|
|
14581
|
+
if ((tagName === 'noscript' || tagName === 'noembed') && regExpTest(/<\/no(script|embed)/i, currentNode.innerHTML)) {
|
|
14582
|
+
_forceRemove(currentNode);
|
|
14583
|
+
return true;
|
|
14584
|
+
}
|
|
14585
|
+
|
|
14586
|
+
/* Sanitize element content to be template-safe */
|
|
14587
|
+
if (SAFE_FOR_TEMPLATES && currentNode.nodeType === 3) {
|
|
14588
|
+
/* Get the element's text content */
|
|
14589
|
+
content = currentNode.textContent;
|
|
14590
|
+
content = stringReplace(content, MUSTACHE_EXPR$$1, ' ');
|
|
14591
|
+
content = stringReplace(content, ERB_EXPR$$1, ' ');
|
|
14592
|
+
if (currentNode.textContent !== content) {
|
|
14593
|
+
arrayPush(DOMPurify.removed, { element: currentNode.cloneNode() });
|
|
14594
|
+
currentNode.textContent = content;
|
|
14595
|
+
}
|
|
14596
|
+
}
|
|
14597
|
+
|
|
14598
|
+
/* Execute a hook if present */
|
|
14599
|
+
_executeHook('afterSanitizeElements', currentNode, null);
|
|
14600
|
+
|
|
14601
|
+
return false;
|
|
14602
|
+
};
|
|
14603
|
+
|
|
14604
|
+
/**
|
|
14605
|
+
* _isValidAttribute
|
|
14606
|
+
*
|
|
14607
|
+
* @param {string} lcTag Lowercase tag name of containing element.
|
|
14608
|
+
* @param {string} lcName Lowercase attribute name.
|
|
14609
|
+
* @param {string} value Attribute value.
|
|
14610
|
+
* @return {Boolean} Returns true if `value` is valid, otherwise false.
|
|
14611
|
+
*/
|
|
14612
|
+
// eslint-disable-next-line complexity
|
|
14613
|
+
var _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) {
|
|
14614
|
+
/* Make sure attribute cannot clobber */
|
|
14615
|
+
if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) {
|
|
14616
|
+
return false;
|
|
14617
|
+
}
|
|
14618
|
+
|
|
14619
|
+
/* Allow valid data-* attributes: At least one character after "-"
|
|
14620
|
+
(https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)
|
|
14621
|
+
XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)
|
|
14622
|
+
We don't need to check the value; it's always URI safe. */
|
|
14623
|
+
if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR$$1, lcName)) ; else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR$$1, lcName)) ; else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) {
|
|
14624
|
+
return false;
|
|
14625
|
+
|
|
14626
|
+
/* Check value is safe. First, is attr inert? If so, is safe */
|
|
14627
|
+
} else if (URI_SAFE_ATTRIBUTES[lcName]) ; else if (regExpTest(IS_ALLOWED_URI$$1, stringReplace(value, ATTR_WHITESPACE$$1, ''))) ; else if ((lcName === 'src' || lcName === 'xlink:href' || lcName === 'href') && lcTag !== 'script' && stringIndexOf(value, 'data:') === 0 && DATA_URI_TAGS[lcTag]) ; else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA$$1, stringReplace(value, ATTR_WHITESPACE$$1, ''))) ; else if (!value) ; else {
|
|
14628
|
+
return false;
|
|
14629
|
+
}
|
|
14630
|
+
|
|
14631
|
+
return true;
|
|
14632
|
+
};
|
|
14633
|
+
|
|
14634
|
+
/**
|
|
14635
|
+
* _sanitizeAttributes
|
|
14636
|
+
*
|
|
14637
|
+
* @protect attributes
|
|
14638
|
+
* @protect nodeName
|
|
14639
|
+
* @protect removeAttribute
|
|
14640
|
+
* @protect setAttribute
|
|
14641
|
+
*
|
|
14642
|
+
* @param {Node} currentNode to sanitize
|
|
14643
|
+
*/
|
|
14644
|
+
var _sanitizeAttributes = function _sanitizeAttributes(currentNode) {
|
|
14645
|
+
var attr = void 0;
|
|
14646
|
+
var value = void 0;
|
|
14647
|
+
var lcName = void 0;
|
|
14648
|
+
var l = void 0;
|
|
14649
|
+
/* Execute a hook if present */
|
|
14650
|
+
_executeHook('beforeSanitizeAttributes', currentNode, null);
|
|
14651
|
+
|
|
14652
|
+
var attributes = currentNode.attributes;
|
|
14653
|
+
|
|
14654
|
+
/* Check if we have attributes; if not we might have a text node */
|
|
14655
|
+
|
|
14656
|
+
if (!attributes) {
|
|
14657
|
+
return;
|
|
14658
|
+
}
|
|
14659
|
+
|
|
14660
|
+
var hookEvent = {
|
|
14661
|
+
attrName: '',
|
|
14662
|
+
attrValue: '',
|
|
14663
|
+
keepAttr: true,
|
|
14664
|
+
allowedAttributes: ALLOWED_ATTR
|
|
14665
|
+
};
|
|
14666
|
+
l = attributes.length;
|
|
14667
|
+
|
|
14668
|
+
/* Go backwards over all attributes; safely remove bad ones */
|
|
14669
|
+
while (l--) {
|
|
14670
|
+
attr = attributes[l];
|
|
14671
|
+
var _attr = attr,
|
|
14672
|
+
name = _attr.name,
|
|
14673
|
+
namespaceURI = _attr.namespaceURI;
|
|
14674
|
+
|
|
14675
|
+
value = stringTrim(attr.value);
|
|
14676
|
+
lcName = transformCaseFunc(name);
|
|
14677
|
+
|
|
14678
|
+
/* Execute a hook if present */
|
|
14679
|
+
hookEvent.attrName = lcName;
|
|
14680
|
+
hookEvent.attrValue = value;
|
|
14681
|
+
hookEvent.keepAttr = true;
|
|
14682
|
+
hookEvent.forceKeepAttr = undefined; // Allows developers to see this is a property they can set
|
|
14683
|
+
_executeHook('uponSanitizeAttribute', currentNode, hookEvent);
|
|
14684
|
+
value = hookEvent.attrValue;
|
|
14685
|
+
/* Did the hooks approve of the attribute? */
|
|
14686
|
+
if (hookEvent.forceKeepAttr) {
|
|
14687
|
+
continue;
|
|
14688
|
+
}
|
|
14689
|
+
|
|
14690
|
+
/* Remove attribute */
|
|
14691
|
+
_removeAttribute(name, currentNode);
|
|
14692
|
+
|
|
14693
|
+
/* Did the hooks approve of the attribute? */
|
|
14694
|
+
if (!hookEvent.keepAttr) {
|
|
14695
|
+
continue;
|
|
14696
|
+
}
|
|
14697
|
+
|
|
14698
|
+
/* Work around a security issue in jQuery 3.0 */
|
|
14699
|
+
if (regExpTest(/\/>/i, value)) {
|
|
14700
|
+
_removeAttribute(name, currentNode);
|
|
14701
|
+
continue;
|
|
14702
|
+
}
|
|
14703
|
+
|
|
14704
|
+
/* Sanitize attribute content to be template-safe */
|
|
14705
|
+
if (SAFE_FOR_TEMPLATES) {
|
|
14706
|
+
value = stringReplace(value, MUSTACHE_EXPR$$1, ' ');
|
|
14707
|
+
value = stringReplace(value, ERB_EXPR$$1, ' ');
|
|
14708
|
+
}
|
|
14709
|
+
|
|
14710
|
+
/* Is `value` valid for this attribute? */
|
|
14711
|
+
var lcTag = transformCaseFunc(currentNode.nodeName);
|
|
14712
|
+
if (!_isValidAttribute(lcTag, lcName, value)) {
|
|
14713
|
+
continue;
|
|
14714
|
+
}
|
|
14715
|
+
|
|
14716
|
+
/* Handle invalid data-* attribute set by try-catching it */
|
|
14717
|
+
try {
|
|
14718
|
+
if (namespaceURI) {
|
|
14719
|
+
currentNode.setAttributeNS(namespaceURI, name, value);
|
|
14720
|
+
} else {
|
|
14721
|
+
/* Fallback to setAttribute() for browser-unrecognized namespaces e.g. "x-schema". */
|
|
14722
|
+
currentNode.setAttribute(name, value);
|
|
14723
|
+
}
|
|
14724
|
+
|
|
14725
|
+
arrayPop(DOMPurify.removed);
|
|
14726
|
+
} catch (_) {}
|
|
14727
|
+
}
|
|
14728
|
+
|
|
14729
|
+
/* Execute a hook if present */
|
|
14730
|
+
_executeHook('afterSanitizeAttributes', currentNode, null);
|
|
14731
|
+
};
|
|
14732
|
+
|
|
14733
|
+
/**
|
|
14734
|
+
* _sanitizeShadowDOM
|
|
14735
|
+
*
|
|
14736
|
+
* @param {DocumentFragment} fragment to iterate over recursively
|
|
14737
|
+
*/
|
|
14738
|
+
var _sanitizeShadowDOM = function _sanitizeShadowDOM(fragment) {
|
|
14739
|
+
var shadowNode = void 0;
|
|
14740
|
+
var shadowIterator = _createIterator(fragment);
|
|
14741
|
+
|
|
14742
|
+
/* Execute a hook if present */
|
|
14743
|
+
_executeHook('beforeSanitizeShadowDOM', fragment, null);
|
|
14744
|
+
|
|
14745
|
+
while (shadowNode = shadowIterator.nextNode()) {
|
|
14746
|
+
/* Execute a hook if present */
|
|
14747
|
+
_executeHook('uponSanitizeShadowNode', shadowNode, null);
|
|
14748
|
+
|
|
14749
|
+
/* Sanitize tags and elements */
|
|
14750
|
+
if (_sanitizeElements(shadowNode)) {
|
|
14751
|
+
continue;
|
|
14752
|
+
}
|
|
14753
|
+
|
|
14754
|
+
/* Deep shadow DOM detected */
|
|
14755
|
+
if (shadowNode.content instanceof DocumentFragment) {
|
|
14756
|
+
_sanitizeShadowDOM(shadowNode.content);
|
|
14757
|
+
}
|
|
14758
|
+
|
|
14759
|
+
/* Check attributes, sanitize if necessary */
|
|
14760
|
+
_sanitizeAttributes(shadowNode);
|
|
14761
|
+
}
|
|
14762
|
+
|
|
14763
|
+
/* Execute a hook if present */
|
|
14764
|
+
_executeHook('afterSanitizeShadowDOM', fragment, null);
|
|
14765
|
+
};
|
|
14766
|
+
|
|
14767
|
+
/**
|
|
14768
|
+
* Sanitize
|
|
14769
|
+
* Public method providing core sanitation functionality
|
|
14770
|
+
*
|
|
14771
|
+
* @param {String|Node} dirty string or DOM node
|
|
14772
|
+
* @param {Object} configuration object
|
|
14773
|
+
*/
|
|
14774
|
+
// eslint-disable-next-line complexity
|
|
14775
|
+
DOMPurify.sanitize = function (dirty, cfg) {
|
|
14776
|
+
var body = void 0;
|
|
14777
|
+
var importedNode = void 0;
|
|
14778
|
+
var currentNode = void 0;
|
|
14779
|
+
var oldNode = void 0;
|
|
14780
|
+
var returnNode = void 0;
|
|
14781
|
+
/* Make sure we have a string to sanitize.
|
|
14782
|
+
DO NOT return early, as this will return the wrong type if
|
|
14783
|
+
the user has requested a DOM object rather than a string */
|
|
14784
|
+
IS_EMPTY_INPUT = !dirty;
|
|
14785
|
+
if (IS_EMPTY_INPUT) {
|
|
14786
|
+
dirty = '<!-->';
|
|
14787
|
+
}
|
|
14788
|
+
|
|
14789
|
+
/* Stringify, in case dirty is an object */
|
|
14790
|
+
if (typeof dirty !== 'string' && !_isNode(dirty)) {
|
|
14791
|
+
// eslint-disable-next-line no-negated-condition
|
|
14792
|
+
if (typeof dirty.toString !== 'function') {
|
|
14793
|
+
throw typeErrorCreate('toString is not a function');
|
|
14794
|
+
} else {
|
|
14795
|
+
dirty = dirty.toString();
|
|
14796
|
+
if (typeof dirty !== 'string') {
|
|
14797
|
+
throw typeErrorCreate('dirty is not a string, aborting');
|
|
14798
|
+
}
|
|
14799
|
+
}
|
|
14800
|
+
}
|
|
14801
|
+
|
|
14802
|
+
/* Check we can run. Otherwise fall back or ignore */
|
|
14803
|
+
if (!DOMPurify.isSupported) {
|
|
14804
|
+
if (_typeof(window.toStaticHTML) === 'object' || typeof window.toStaticHTML === 'function') {
|
|
14805
|
+
if (typeof dirty === 'string') {
|
|
14806
|
+
return window.toStaticHTML(dirty);
|
|
14807
|
+
}
|
|
14808
|
+
|
|
14809
|
+
if (_isNode(dirty)) {
|
|
14810
|
+
return window.toStaticHTML(dirty.outerHTML);
|
|
14811
|
+
}
|
|
14812
|
+
}
|
|
14813
|
+
|
|
14814
|
+
return dirty;
|
|
14815
|
+
}
|
|
14816
|
+
|
|
14817
|
+
/* Assign config vars */
|
|
14818
|
+
if (!SET_CONFIG) {
|
|
14819
|
+
_parseConfig(cfg);
|
|
14820
|
+
}
|
|
14821
|
+
|
|
14822
|
+
/* Clean up removed elements */
|
|
14823
|
+
DOMPurify.removed = [];
|
|
14824
|
+
|
|
14825
|
+
/* Check if dirty is correctly typed for IN_PLACE */
|
|
14826
|
+
if (typeof dirty === 'string') {
|
|
14827
|
+
IN_PLACE = false;
|
|
14828
|
+
}
|
|
14829
|
+
|
|
14830
|
+
if (IN_PLACE) ; else if (dirty instanceof Node) {
|
|
14831
|
+
/* If dirty is a DOM element, append to an empty document to avoid
|
|
14832
|
+
elements being stripped by the parser */
|
|
14833
|
+
body = _initDocument('<!---->');
|
|
14834
|
+
importedNode = body.ownerDocument.importNode(dirty, true);
|
|
14835
|
+
if (importedNode.nodeType === 1 && importedNode.nodeName === 'BODY') {
|
|
14836
|
+
/* Node is already a body, use as is */
|
|
14837
|
+
body = importedNode;
|
|
14838
|
+
} else if (importedNode.nodeName === 'HTML') {
|
|
14839
|
+
body = importedNode;
|
|
14840
|
+
} else {
|
|
14841
|
+
// eslint-disable-next-line unicorn/prefer-dom-node-append
|
|
14842
|
+
body.appendChild(importedNode);
|
|
14843
|
+
}
|
|
14844
|
+
} else {
|
|
14845
|
+
/* Exit directly if we have nothing to do */
|
|
14846
|
+
if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT &&
|
|
14847
|
+
// eslint-disable-next-line unicorn/prefer-includes
|
|
14848
|
+
dirty.indexOf('<') === -1) {
|
|
14849
|
+
return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(dirty) : dirty;
|
|
14850
|
+
}
|
|
14851
|
+
|
|
14852
|
+
/* Initialize the document to work on */
|
|
14853
|
+
body = _initDocument(dirty);
|
|
14854
|
+
|
|
14855
|
+
/* Check we have a DOM node from the data */
|
|
14856
|
+
if (!body) {
|
|
14857
|
+
return RETURN_DOM ? null : emptyHTML;
|
|
14858
|
+
}
|
|
14859
|
+
}
|
|
14860
|
+
|
|
14861
|
+
/* Remove first element node (ours) if FORCE_BODY is set */
|
|
14862
|
+
if (body && FORCE_BODY) {
|
|
14863
|
+
_forceRemove(body.firstChild);
|
|
14864
|
+
}
|
|
14865
|
+
|
|
14866
|
+
/* Get node iterator */
|
|
14867
|
+
var nodeIterator = _createIterator(IN_PLACE ? dirty : body);
|
|
14868
|
+
|
|
14869
|
+
/* Now start iterating over the created document */
|
|
14870
|
+
while (currentNode = nodeIterator.nextNode()) {
|
|
14871
|
+
/* Fix IE's strange behavior with manipulated textNodes #89 */
|
|
14872
|
+
if (currentNode.nodeType === 3 && currentNode === oldNode) {
|
|
14873
|
+
continue;
|
|
14874
|
+
}
|
|
14875
|
+
|
|
14876
|
+
/* Sanitize tags and elements */
|
|
14877
|
+
if (_sanitizeElements(currentNode)) {
|
|
14878
|
+
continue;
|
|
14879
|
+
}
|
|
14880
|
+
|
|
14881
|
+
/* Shadow DOM detected, sanitize it */
|
|
14882
|
+
if (currentNode.content instanceof DocumentFragment) {
|
|
14883
|
+
_sanitizeShadowDOM(currentNode.content);
|
|
14884
|
+
}
|
|
14885
|
+
|
|
14886
|
+
/* Check attributes, sanitize if necessary */
|
|
14887
|
+
_sanitizeAttributes(currentNode);
|
|
14888
|
+
|
|
14889
|
+
oldNode = currentNode;
|
|
14890
|
+
}
|
|
14891
|
+
|
|
14892
|
+
oldNode = null;
|
|
14893
|
+
|
|
14894
|
+
/* If we sanitized `dirty` in-place, return it. */
|
|
14895
|
+
if (IN_PLACE) {
|
|
14896
|
+
return dirty;
|
|
14897
|
+
}
|
|
14898
|
+
|
|
14899
|
+
/* Return sanitized string or DOM */
|
|
14900
|
+
if (RETURN_DOM) {
|
|
14901
|
+
if (RETURN_DOM_FRAGMENT) {
|
|
14902
|
+
returnNode = createDocumentFragment.call(body.ownerDocument);
|
|
14903
|
+
|
|
14904
|
+
while (body.firstChild) {
|
|
14905
|
+
// eslint-disable-next-line unicorn/prefer-dom-node-append
|
|
14906
|
+
returnNode.appendChild(body.firstChild);
|
|
14907
|
+
}
|
|
14908
|
+
} else {
|
|
14909
|
+
returnNode = body;
|
|
14910
|
+
}
|
|
14911
|
+
|
|
14912
|
+
if (RETURN_DOM_IMPORT) {
|
|
14913
|
+
/*
|
|
14914
|
+
AdoptNode() is not used because internal state is not reset
|
|
14915
|
+
(e.g. the past names map of a HTMLFormElement), this is safe
|
|
14916
|
+
in theory but we would rather not risk another attack vector.
|
|
14917
|
+
The state that is cloned by importNode() is explicitly defined
|
|
14918
|
+
by the specs.
|
|
14919
|
+
*/
|
|
14920
|
+
returnNode = importNode.call(originalDocument, returnNode, true);
|
|
14921
|
+
}
|
|
14922
|
+
|
|
14923
|
+
return returnNode;
|
|
14924
|
+
}
|
|
14925
|
+
|
|
14926
|
+
var serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML;
|
|
14927
|
+
|
|
14928
|
+
/* Sanitize final string template-safe */
|
|
14929
|
+
if (SAFE_FOR_TEMPLATES) {
|
|
14930
|
+
serializedHTML = stringReplace(serializedHTML, MUSTACHE_EXPR$$1, ' ');
|
|
14931
|
+
serializedHTML = stringReplace(serializedHTML, ERB_EXPR$$1, ' ');
|
|
14932
|
+
}
|
|
14933
|
+
|
|
14934
|
+
return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(serializedHTML) : serializedHTML;
|
|
14935
|
+
};
|
|
14936
|
+
|
|
14937
|
+
/**
|
|
14938
|
+
* Public method to set the configuration once
|
|
14939
|
+
* setConfig
|
|
14940
|
+
*
|
|
14941
|
+
* @param {Object} cfg configuration object
|
|
14942
|
+
*/
|
|
14943
|
+
DOMPurify.setConfig = function (cfg) {
|
|
14944
|
+
_parseConfig(cfg);
|
|
14945
|
+
SET_CONFIG = true;
|
|
14946
|
+
};
|
|
14947
|
+
|
|
14948
|
+
/**
|
|
14949
|
+
* Public method to remove the configuration
|
|
14950
|
+
* clearConfig
|
|
14951
|
+
*
|
|
14952
|
+
*/
|
|
14953
|
+
DOMPurify.clearConfig = function () {
|
|
14954
|
+
CONFIG = null;
|
|
14955
|
+
SET_CONFIG = false;
|
|
14956
|
+
};
|
|
14957
|
+
|
|
14958
|
+
/**
|
|
14959
|
+
* Public method to check if an attribute value is valid.
|
|
14960
|
+
* Uses last set config, if any. Otherwise, uses config defaults.
|
|
14961
|
+
* isValidAttribute
|
|
14962
|
+
*
|
|
14963
|
+
* @param {string} tag Tag name of containing element.
|
|
14964
|
+
* @param {string} attr Attribute name.
|
|
14965
|
+
* @param {string} value Attribute value.
|
|
14966
|
+
* @return {Boolean} Returns true if `value` is valid. Otherwise, returns false.
|
|
14967
|
+
*/
|
|
14968
|
+
DOMPurify.isValidAttribute = function (tag, attr, value) {
|
|
14969
|
+
/* Initialize shared config vars if necessary. */
|
|
14970
|
+
if (!CONFIG) {
|
|
14971
|
+
_parseConfig({});
|
|
14972
|
+
}
|
|
14973
|
+
|
|
14974
|
+
var lcTag = transformCaseFunc(tag);
|
|
14975
|
+
var lcName = transformCaseFunc(attr);
|
|
14976
|
+
return _isValidAttribute(lcTag, lcName, value);
|
|
14977
|
+
};
|
|
14978
|
+
|
|
14979
|
+
/**
|
|
14980
|
+
* AddHook
|
|
14981
|
+
* Public method to add DOMPurify hooks
|
|
14982
|
+
*
|
|
14983
|
+
* @param {String} entryPoint entry point for the hook to add
|
|
14984
|
+
* @param {Function} hookFunction function to execute
|
|
14985
|
+
*/
|
|
14986
|
+
DOMPurify.addHook = function (entryPoint, hookFunction) {
|
|
14987
|
+
if (typeof hookFunction !== 'function') {
|
|
14988
|
+
return;
|
|
14989
|
+
}
|
|
14990
|
+
|
|
14991
|
+
hooks[entryPoint] = hooks[entryPoint] || [];
|
|
14992
|
+
arrayPush(hooks[entryPoint], hookFunction);
|
|
14993
|
+
};
|
|
14994
|
+
|
|
14995
|
+
/**
|
|
14996
|
+
* RemoveHook
|
|
14997
|
+
* Public method to remove a DOMPurify hook at a given entryPoint
|
|
14998
|
+
* (pops it from the stack of hooks if more are present)
|
|
14999
|
+
*
|
|
15000
|
+
* @param {String} entryPoint entry point for the hook to remove
|
|
15001
|
+
*/
|
|
15002
|
+
DOMPurify.removeHook = function (entryPoint) {
|
|
15003
|
+
if (hooks[entryPoint]) {
|
|
15004
|
+
arrayPop(hooks[entryPoint]);
|
|
15005
|
+
}
|
|
15006
|
+
};
|
|
15007
|
+
|
|
15008
|
+
/**
|
|
15009
|
+
* RemoveHooks
|
|
15010
|
+
* Public method to remove all DOMPurify hooks at a given entryPoint
|
|
15011
|
+
*
|
|
15012
|
+
* @param {String} entryPoint entry point for the hooks to remove
|
|
15013
|
+
*/
|
|
15014
|
+
DOMPurify.removeHooks = function (entryPoint) {
|
|
15015
|
+
if (hooks[entryPoint]) {
|
|
15016
|
+
hooks[entryPoint] = [];
|
|
15017
|
+
}
|
|
15018
|
+
};
|
|
15019
|
+
|
|
15020
|
+
/**
|
|
15021
|
+
* RemoveAllHooks
|
|
15022
|
+
* Public method to remove all DOMPurify hooks
|
|
15023
|
+
*
|
|
15024
|
+
*/
|
|
15025
|
+
DOMPurify.removeAllHooks = function () {
|
|
15026
|
+
hooks = {};
|
|
15027
|
+
};
|
|
15028
|
+
|
|
15029
|
+
return DOMPurify;
|
|
15030
|
+
}
|
|
15031
|
+
|
|
15032
|
+
var purify = createDOMPurify();
|
|
15033
|
+
|
|
15034
|
+
var CAN_BE_WHITE_TAG_LIST = ['iframe', 'embed'];
|
|
15035
|
+
var whiteTagList = [];
|
|
15036
|
+
function registerTagWhitelistIfPossible(tagName) {
|
|
15037
|
+
if (includes(CAN_BE_WHITE_TAG_LIST, tagName)) {
|
|
15038
|
+
whiteTagList.push(tagName.toLowerCase());
|
|
15039
|
+
}
|
|
15040
|
+
}
|
|
15041
|
+
function sanitizeHTML(html, options) {
|
|
15042
|
+
return purify.sanitize(html, __assign$1({ ADD_TAGS: whiteTagList, ADD_ATTR: ['rel', 'target', 'hreflang', 'type'], FORBID_TAGS: [
|
|
15043
|
+
'input',
|
|
15044
|
+
'script',
|
|
15045
|
+
'textarea',
|
|
15046
|
+
'form',
|
|
15047
|
+
'button',
|
|
15048
|
+
'select',
|
|
15049
|
+
'meta',
|
|
15050
|
+
'style',
|
|
15051
|
+
'link',
|
|
15052
|
+
'title',
|
|
15053
|
+
'object',
|
|
15054
|
+
'base',
|
|
15055
|
+
] }, options));
|
|
15056
|
+
}
|
|
15057
|
+
|
|
15058
|
+
function getChildrenHTML(node, typeName) {
|
|
15059
|
+
return node
|
|
15060
|
+
.literal.replace(new RegExp("(<\\s*" + typeName + "[^>]+?>)|(</" + typeName + "\\s*[>])", 'ig'), '')
|
|
15061
|
+
.trim();
|
|
15062
|
+
}
|
|
15063
|
+
function getHTMLAttrsByHTMLString(html) {
|
|
15064
|
+
html = html.match(reHTMLTag)[0];
|
|
15065
|
+
var attrs = html.match(new RegExp(ATTRIBUTE$1, 'g'));
|
|
15066
|
+
return attrs
|
|
15067
|
+
? attrs.reduce(function (acc, attr) {
|
|
15068
|
+
var _a = attr.trim().split('='), name = _a[0], values = _a.slice(1);
|
|
15069
|
+
if (values.length) {
|
|
15070
|
+
acc[name] = values.join('=').replace(/'|"/g, '').trim();
|
|
15071
|
+
}
|
|
15072
|
+
return acc;
|
|
15073
|
+
}, {})
|
|
15074
|
+
: {};
|
|
15075
|
+
}
|
|
15076
|
+
function getHTMLAttrs(dom) {
|
|
15077
|
+
return toArray_1(dom.attributes).reduce(function (acc, attr) {
|
|
15078
|
+
acc[attr.nodeName] = attr.nodeValue;
|
|
15079
|
+
return acc;
|
|
15080
|
+
}, {});
|
|
15081
|
+
}
|
|
15082
|
+
function sanitizeDOM(node, typeName, sanitizer, wwToDOMAdaptor) {
|
|
15083
|
+
var dom = wwToDOMAdaptor.getToDOMNode(typeName)(node);
|
|
15084
|
+
var html = sanitizer(dom.outerHTML);
|
|
15085
|
+
var container = document.createElement('div');
|
|
15086
|
+
container.innerHTML = html;
|
|
15087
|
+
dom = container.firstChild;
|
|
15088
|
+
var htmlAttrs = getHTMLAttrs(dom);
|
|
15089
|
+
return { dom: dom, htmlAttrs: htmlAttrs };
|
|
15090
|
+
}
|
|
15091
|
+
var schemaFactory = {
|
|
15092
|
+
htmlBlock: function (typeName, sanitizeHTML, wwToDOMAdaptor) {
|
|
15093
|
+
return {
|
|
15094
|
+
atom: true,
|
|
15095
|
+
content: 'block+',
|
|
15096
|
+
group: 'block',
|
|
15097
|
+
attrs: {
|
|
15098
|
+
htmlAttrs: { default: {} },
|
|
15099
|
+
childrenHTML: { default: '' },
|
|
15100
|
+
htmlBlock: { default: true },
|
|
15101
|
+
},
|
|
15102
|
+
parseDOM: [
|
|
15103
|
+
{
|
|
15104
|
+
tag: typeName,
|
|
15105
|
+
getAttrs: function (dom) {
|
|
15106
|
+
return {
|
|
15107
|
+
htmlAttrs: getHTMLAttrs(dom),
|
|
15108
|
+
childrenHTML: dom.innerHTML,
|
|
15109
|
+
};
|
|
15110
|
+
},
|
|
15111
|
+
},
|
|
15112
|
+
],
|
|
15113
|
+
toDOM: function (node) {
|
|
15114
|
+
var _a = sanitizeDOM(node, typeName, sanitizeHTML, wwToDOMAdaptor), dom = _a.dom, htmlAttrs = _a.htmlAttrs;
|
|
15115
|
+
htmlAttrs.class = htmlAttrs.class ? htmlAttrs.class + " html-block" : 'html-block';
|
|
15116
|
+
return __spreadArray$1([typeName, htmlAttrs], toArray_1(dom.childNodes));
|
|
15117
|
+
},
|
|
15118
|
+
};
|
|
15119
|
+
},
|
|
15120
|
+
htmlInline: function (typeName, sanitizeHTML, wwToDOMAdaptor) {
|
|
15121
|
+
return {
|
|
15122
|
+
attrs: {
|
|
15123
|
+
htmlAttrs: { default: {} },
|
|
15124
|
+
htmlInline: { default: true },
|
|
15125
|
+
},
|
|
15126
|
+
parseDOM: [
|
|
15127
|
+
{
|
|
15128
|
+
tag: typeName,
|
|
15129
|
+
getAttrs: function (dom) {
|
|
15130
|
+
return {
|
|
15131
|
+
htmlAttrs: getHTMLAttrs(dom),
|
|
15132
|
+
};
|
|
15133
|
+
},
|
|
15134
|
+
},
|
|
15135
|
+
],
|
|
15136
|
+
toDOM: function (node) {
|
|
15137
|
+
var htmlAttrs = sanitizeDOM(node, typeName, sanitizeHTML, wwToDOMAdaptor).htmlAttrs;
|
|
15138
|
+
return [typeName, htmlAttrs, 0];
|
|
15139
|
+
},
|
|
15140
|
+
};
|
|
15141
|
+
},
|
|
15142
|
+
};
|
|
15143
|
+
function createHTMLSchemaMap(convertorMap, sanitizeHTML, wwToDOMAdaptor) {
|
|
15144
|
+
var htmlSchemaMap = { nodes: {}, marks: {} };
|
|
15145
|
+
['htmlBlock', 'htmlInline'].forEach(function (htmlType) {
|
|
15146
|
+
if (convertorMap[htmlType]) {
|
|
15147
|
+
Object.keys(convertorMap[htmlType]).forEach(function (type) {
|
|
15148
|
+
var targetType = htmlType === 'htmlBlock' ? 'nodes' : 'marks';
|
|
15149
|
+
// register tag white list for preventing to remove the html in sanitizer
|
|
15150
|
+
registerTagWhitelistIfPossible(type);
|
|
15151
|
+
htmlSchemaMap[targetType][type] = schemaFactory[htmlType](type, sanitizeHTML, wwToDOMAdaptor);
|
|
15152
|
+
});
|
|
15153
|
+
}
|
|
15154
|
+
});
|
|
15155
|
+
return htmlSchemaMap;
|
|
15156
|
+
}
|
|
15157
|
+
|
|
15158
|
+
var reCloseTag = /^\s*<\s*\//;
|
|
15159
|
+
var baseConvertors = {
|
|
15160
|
+
paragraph: function (_, _a) {
|
|
15161
|
+
var entering = _a.entering, origin = _a.origin, options = _a.options;
|
|
15162
|
+
if (options.nodeId) {
|
|
15163
|
+
return {
|
|
15164
|
+
type: entering ? 'openTag' : 'closeTag',
|
|
15165
|
+
outerNewLine: true,
|
|
15166
|
+
tagName: 'p',
|
|
13781
15167
|
};
|
|
13782
15168
|
}
|
|
13783
15169
|
return origin();
|
|
@@ -14080,10 +15466,16 @@ var MarkdownPreview = /** @class */ (function () {
|
|
|
14080
15466
|
this.sanitizer = sanitizer;
|
|
14081
15467
|
this.initEvent(highlight);
|
|
14082
15468
|
this.initContentSection();
|
|
15469
|
+
// To prevent overflowing contents in the viewer
|
|
15470
|
+
if (this.isViewer) {
|
|
15471
|
+
this.previewContent.style.overflowWrap = 'break-word';
|
|
15472
|
+
}
|
|
14083
15473
|
}
|
|
14084
15474
|
MarkdownPreview.prototype.initContentSection = function () {
|
|
14085
15475
|
this.previewContent = createElementWith("<div class=\"" + cls('contents') + "\"></div>");
|
|
14086
|
-
|
|
15476
|
+
if (!this.isViewer) {
|
|
15477
|
+
this.el.appendChild(this.previewContent);
|
|
15478
|
+
}
|
|
14087
15479
|
};
|
|
14088
15480
|
MarkdownPreview.prototype.toggleActive = function (active) {
|
|
14089
15481
|
toggleClass(this.el, 'active', active);
|
|
@@ -14091,6 +15483,9 @@ var MarkdownPreview = /** @class */ (function () {
|
|
|
14091
15483
|
MarkdownPreview.prototype.initEvent = function (highlight) {
|
|
14092
15484
|
var _this = this;
|
|
14093
15485
|
this.eventEmitter.listen('updatePreview', this.update.bind(this));
|
|
15486
|
+
if (this.isViewer) {
|
|
15487
|
+
return;
|
|
15488
|
+
}
|
|
14094
15489
|
if (highlight) {
|
|
14095
15490
|
this.eventEmitter.listen('changeToolbarState', function (_a) {
|
|
14096
15491
|
var mdNode = _a.mdNode, cursorPos = _a.cursorPos;
|
|
@@ -15404,6 +16799,7 @@ var CustomBlockView = /** @class */ (function () {
|
|
|
15404
16799
|
if (_this.innerEditorView) {
|
|
15405
16800
|
throw new Error('The editor is already opened.');
|
|
15406
16801
|
}
|
|
16802
|
+
_this.dom.draggable = false;
|
|
15407
16803
|
_this.wrapper.style.display = 'none';
|
|
15408
16804
|
_this.innerViewContainer.style.display = 'block';
|
|
15409
16805
|
_this.innerEditorView = new EditorView(_this.innerViewContainer, {
|
|
@@ -15918,7 +17314,7 @@ function getContentBetweenFragmentComments(html) {
|
|
|
15918
17314
|
if (startFragmentIndex > -1 && endFragmentIndex > -1) {
|
|
15919
17315
|
html = html.slice(startFragmentIndex + START_FRAGMENT_COMMENT.length, endFragmentIndex);
|
|
15920
17316
|
}
|
|
15921
|
-
return html;
|
|
17317
|
+
return html.replace(/<br[^>]*>/g, ALTERNATIVE_TAG_FOR_BR);
|
|
15922
17318
|
}
|
|
15923
17319
|
function convertMsoTableToCompletedTable(html) {
|
|
15924
17320
|
// wrap with <tr> if html contains dangling <td> tags
|
|
@@ -16006,9 +17402,9 @@ function createTableBody(tableBodyRows, maxColumnCount, schema) {
|
|
|
16006
17402
|
}
|
|
16007
17403
|
return schema.nodes.tableBody.create(null, copiedRows);
|
|
16008
17404
|
}
|
|
16009
|
-
function createTableFromPastingTable(rows, schema, startFromBody) {
|
|
17405
|
+
function createTableFromPastingTable(rows, schema, startFromBody, isInTable) {
|
|
16010
17406
|
var columnCount = getMaxColumnCount(rows);
|
|
16011
|
-
if (startFromBody) {
|
|
17407
|
+
if (startFromBody && isInTable) {
|
|
16012
17408
|
return schema.nodes.table.create(null, [createTableBody(rows, columnCount, schema)]);
|
|
16013
17409
|
}
|
|
16014
17410
|
var tableHeadRow = rows[0];
|
|
@@ -16019,15 +17415,16 @@ function createTableFromPastingTable(rows, schema, startFromBody) {
|
|
|
16019
17415
|
}
|
|
16020
17416
|
return schema.nodes.table.create(null, nodes);
|
|
16021
17417
|
}
|
|
16022
|
-
function changePastedSlice(slice, schema) {
|
|
17418
|
+
function changePastedSlice(slice, schema, isInTable) {
|
|
16023
17419
|
var nodes = [];
|
|
16024
|
-
slice.content.
|
|
17420
|
+
var content = slice.content, openStart = slice.openStart, openEnd = slice.openEnd;
|
|
17421
|
+
content.forEach(function (node) {
|
|
16025
17422
|
if (node.type.name === 'table') {
|
|
16026
17423
|
var tableContent = getTableContentFromSlice(new Slice(Fragment.from(node), 0, 0));
|
|
16027
17424
|
if (tableContent) {
|
|
16028
17425
|
var rows = createRowsFromPastingTable(tableContent);
|
|
16029
17426
|
var startFromBody = tableContent.firstChild.type.name === 'tableBody';
|
|
16030
|
-
var table = createTableFromPastingTable(rows, schema, startFromBody);
|
|
17427
|
+
var table = createTableFromPastingTable(rows, schema, startFromBody, isInTable);
|
|
16031
17428
|
nodes.push(table);
|
|
16032
17429
|
}
|
|
16033
17430
|
}
|
|
@@ -16035,7 +17432,7 @@ function changePastedSlice(slice, schema) {
|
|
|
16035
17432
|
nodes.push(node);
|
|
16036
17433
|
}
|
|
16037
17434
|
});
|
|
16038
|
-
return new Slice(Fragment.from(nodes),
|
|
17435
|
+
return new Slice(Fragment.from(nodes), openStart, openEnd);
|
|
16039
17436
|
}
|
|
16040
17437
|
|
|
16041
17438
|
var DUMMY_CELL_SIZE = 4;
|
|
@@ -16248,7 +17645,7 @@ var Paragraph = /** @class */ (function (_super) {
|
|
|
16248
17645
|
get: function () {
|
|
16249
17646
|
return {
|
|
16250
17647
|
content: 'inline*',
|
|
16251
|
-
group: 'block
|
|
17648
|
+
group: 'block',
|
|
16252
17649
|
attrs: __assign$1({}, getDefaultCustomAttrs()),
|
|
16253
17650
|
parseDOM: [{ tag: 'p' }],
|
|
16254
17651
|
toDOM: function (_a) {
|
|
@@ -16371,7 +17768,8 @@ var Heading = /** @class */ (function (_super) {
|
|
|
16371
17768
|
});
|
|
16372
17769
|
Heading.prototype.commands = function () {
|
|
16373
17770
|
return function (payload) { return function (state, dispatch) {
|
|
16374
|
-
|
|
17771
|
+
var nodeType = state.schema.nodes[payload.level ? 'heading' : 'paragraph'];
|
|
17772
|
+
return setBlockType(nodeType, payload)(state, dispatch);
|
|
16375
17773
|
}; };
|
|
16376
17774
|
};
|
|
16377
17775
|
return Heading;
|
|
@@ -16477,7 +17875,7 @@ var BulletList = /** @class */ (function (_super) {
|
|
|
16477
17875
|
get: function () {
|
|
16478
17876
|
return {
|
|
16479
17877
|
content: 'listItem+',
|
|
16480
|
-
group: 'block
|
|
17878
|
+
group: 'block',
|
|
16481
17879
|
attrs: __assign$1({ rawHTML: { default: null } }, getDefaultCustomAttrs()),
|
|
16482
17880
|
parseDOM: [createDOMInfoParsedRawHTML('ul')],
|
|
16483
17881
|
toDOM: function (_a) {
|
|
@@ -16527,7 +17925,7 @@ var OrderedList = /** @class */ (function (_super) {
|
|
|
16527
17925
|
get: function () {
|
|
16528
17926
|
return {
|
|
16529
17927
|
content: 'listItem+',
|
|
16530
|
-
group: 'block
|
|
17928
|
+
group: 'block',
|
|
16531
17929
|
attrs: __assign$1({ order: { default: 1 }, rawHTML: { default: null } }, getDefaultCustomAttrs()),
|
|
16532
17930
|
parseDOM: [
|
|
16533
17931
|
{
|
|
@@ -16583,7 +17981,8 @@ var ListItem = /** @class */ (function (_super) {
|
|
|
16583
17981
|
Object.defineProperty(ListItem.prototype, "schema", {
|
|
16584
17982
|
get: function () {
|
|
16585
17983
|
return {
|
|
16586
|
-
content: 'paragraph
|
|
17984
|
+
content: 'paragraph block*',
|
|
17985
|
+
selectable: false,
|
|
16587
17986
|
attrs: {
|
|
16588
17987
|
task: { default: false },
|
|
16589
17988
|
checked: { default: false },
|
|
@@ -17431,9 +18830,13 @@ var Image = /** @class */ (function (_super) {
|
|
|
17431
18830
|
{
|
|
17432
18831
|
tag: 'img[src]',
|
|
17433
18832
|
getAttrs: function (dom) {
|
|
17434
|
-
var
|
|
17435
|
-
|
|
17436
|
-
|
|
18833
|
+
var sanitizedDOM = sanitizeHTML(dom, { RETURN_DOM_FRAGMENT: true })
|
|
18834
|
+
.firstChild;
|
|
18835
|
+
var imageUrl = sanitizedDOM.getAttribute('src') || '';
|
|
18836
|
+
var rawHTML = sanitizedDOM.getAttribute('data-raw-html');
|
|
18837
|
+
var altText = sanitizedDOM.getAttribute('alt');
|
|
18838
|
+
return __assign$1({ imageUrl: imageUrl,
|
|
18839
|
+
altText: altText }, (rawHTML && { rawHTML: rawHTML }));
|
|
17437
18840
|
},
|
|
17438
18841
|
},
|
|
17439
18842
|
],
|
|
@@ -17456,7 +18859,7 @@ var Image = /** @class */ (function (_super) {
|
|
|
17456
18859
|
if (!imageUrl) {
|
|
17457
18860
|
return false;
|
|
17458
18861
|
}
|
|
17459
|
-
var node = schema.nodes.image.createAndFill(__assign$1({ imageUrl:
|
|
18862
|
+
var node = schema.nodes.image.createAndFill(__assign$1({ imageUrl: escapeXml$1(imageUrl) }, (altText && { altText: altText })));
|
|
17460
18863
|
dispatch(tr.replaceSelectionWith(node).scrollIntoView());
|
|
17461
18864
|
return true;
|
|
17462
18865
|
}; };
|
|
@@ -17707,9 +19110,11 @@ var Link = /** @class */ (function (_super) {
|
|
|
17707
19110
|
{
|
|
17708
19111
|
tag: 'a[href]',
|
|
17709
19112
|
getAttrs: function (dom) {
|
|
17710
|
-
var
|
|
17711
|
-
|
|
17712
|
-
|
|
19113
|
+
var sanitizedDOM = sanitizeHTML(dom, { RETURN_DOM_FRAGMENT: true })
|
|
19114
|
+
.firstChild;
|
|
19115
|
+
var href = sanitizedDOM.getAttribute('href') || '';
|
|
19116
|
+
var rawHTML = sanitizedDOM.getAttribute('data-raw-html');
|
|
19117
|
+
return __assign$1({ linkUrl: href, linkText: sanitizedDOM.textContent }, (rawHTML && { rawHTML: rawHTML }));
|
|
17713
19118
|
},
|
|
17714
19119
|
},
|
|
17715
19120
|
],
|
|
@@ -17732,7 +19137,7 @@ var Link = /** @class */ (function (_super) {
|
|
|
17732
19137
|
var empty = selection.empty, from = selection.from, to = selection.to;
|
|
17733
19138
|
if (from && to && linkUrl) {
|
|
17734
19139
|
var attrs = {
|
|
17735
|
-
linkUrl:
|
|
19140
|
+
linkUrl: escapeXml$1(linkUrl),
|
|
17736
19141
|
linkText: escapeMarkdownText(linkText),
|
|
17737
19142
|
};
|
|
17738
19143
|
var mark = schema.mark('link', attrs);
|
|
@@ -18013,7 +19418,9 @@ var WysiwygEditor = /** @class */ (function (_super) {
|
|
|
18013
19418
|
_this.eventEmitter.emit('setFocusedNode', state.selection.$from.node(1));
|
|
18014
19419
|
},
|
|
18015
19420
|
transformPastedHTML: changePastedHTML,
|
|
18016
|
-
transformPasted: function (slice) {
|
|
19421
|
+
transformPasted: function (slice) {
|
|
19422
|
+
return changePastedSlice(slice, _this.schema, isInTableNode(_this.view.state.selection.$from));
|
|
19423
|
+
},
|
|
18017
19424
|
handlePaste: function (view, _, slice) { return pasteToTable(view, slice); },
|
|
18018
19425
|
handleKeyDown: function (_, ev) {
|
|
18019
19426
|
_this.eventEmitter.emit('keydown', _this.editorType, ev);
|
|
@@ -18022,8 +19429,8 @@ var WysiwygEditor = /** @class */ (function (_super) {
|
|
|
18022
19429
|
handleDOMEvents: {
|
|
18023
19430
|
paste: function (_, ev) {
|
|
18024
19431
|
var clipboardData = ev.clipboardData || window.clipboardData;
|
|
18025
|
-
var items = clipboardData
|
|
18026
|
-
if (items) {
|
|
19432
|
+
var items = clipboardData === null || clipboardData === void 0 ? void 0 : clipboardData.items;
|
|
19433
|
+
if ((items === null || items === void 0 ? void 0 : items.length) === 1) {
|
|
18027
19434
|
var imageBlob = pasteImageOnly(items);
|
|
18028
19435
|
if (imageBlob) {
|
|
18029
19436
|
ev.preventDefault();
|
|
@@ -18091,7 +19498,7 @@ var WysiwygEditor = /** @class */ (function (_super) {
|
|
|
18091
19498
|
var _a = this.view.state, tr = _a.tr, doc = _a.doc;
|
|
18092
19499
|
this.view.dispatch(tr.replaceWith(0, doc.content.size, newDoc));
|
|
18093
19500
|
if (cursorToEnd) {
|
|
18094
|
-
this.moveCursorToEnd();
|
|
19501
|
+
this.moveCursorToEnd(true);
|
|
18095
19502
|
}
|
|
18096
19503
|
};
|
|
18097
19504
|
WysiwygEditor.prototype.setSelection = function (start, end) {
|
|
@@ -18155,7 +19562,11 @@ var isNull = isNull_1;
|
|
|
18155
19562
|
* @returns {boolean} Is existy?
|
|
18156
19563
|
* @memberof module:type
|
|
18157
19564
|
* @example
|
|
18158
|
-
*
|
|
19565
|
+
* // ES6
|
|
19566
|
+
* import isExisty from 'tui-code-snippet/type/isExisty');
|
|
19567
|
+
*
|
|
19568
|
+
* // CommonJS
|
|
19569
|
+
* const isExisty = require('tui-code-snippet/type/isExisty');
|
|
18159
19570
|
*
|
|
18160
19571
|
* isExisty(''); //true
|
|
18161
19572
|
* isExisty(0); //true
|
|
@@ -18230,6 +19641,7 @@ var eventTypeList = [
|
|
|
18230
19641
|
'mixinTableOffsetMapPrototype',
|
|
18231
19642
|
'setFocusedNode',
|
|
18232
19643
|
'removePopupWidget',
|
|
19644
|
+
'query',
|
|
18233
19645
|
// provide event for user
|
|
18234
19646
|
'openPopup',
|
|
18235
19647
|
'closePopup',
|
|
@@ -18484,6 +19896,9 @@ function isInlineNode(_a) {
|
|
|
18484
19896
|
var type = _a.type;
|
|
18485
19897
|
return includes(['text', 'strong', 'emph', 'strike', 'image', 'link', 'code'], type);
|
|
18486
19898
|
}
|
|
19899
|
+
function isSoftbreak(mdNode) {
|
|
19900
|
+
return (mdNode === null || mdNode === void 0 ? void 0 : mdNode.type) === 'softbreak';
|
|
19901
|
+
}
|
|
18487
19902
|
function isListNode(_a) {
|
|
18488
19903
|
var type = _a.type, literal = _a.literal;
|
|
18489
19904
|
var matched = type === 'htmlInline' && literal.match(reHTMLTag);
|
|
@@ -18502,11 +19917,15 @@ function getListItemAttrs(_a) {
|
|
|
18502
19917
|
var checked = /data-task-checked/.test(literal);
|
|
18503
19918
|
return { task: task, checked: checked };
|
|
18504
19919
|
}
|
|
18505
|
-
function getMatchedAttributeValue(rawHTML
|
|
19920
|
+
function getMatchedAttributeValue(rawHTML) {
|
|
19921
|
+
var attrNames = [];
|
|
19922
|
+
for (var _i = 1; _i < arguments.length; _i++) {
|
|
19923
|
+
attrNames[_i - 1] = arguments[_i];
|
|
19924
|
+
}
|
|
18506
19925
|
var wrapper = document.createElement('div');
|
|
18507
|
-
wrapper.innerHTML = rawHTML;
|
|
19926
|
+
wrapper.innerHTML = sanitizeHTML(rawHTML);
|
|
18508
19927
|
var el = wrapper.firstChild;
|
|
18509
|
-
return el.getAttribute(attrName) || '';
|
|
19928
|
+
return attrNames.map(function (attrName) { return el.getAttribute(attrName) || ''; });
|
|
18510
19929
|
}
|
|
18511
19930
|
function createConvertors(convertors) {
|
|
18512
19931
|
var convertorMap = {};
|
|
@@ -18560,9 +19979,9 @@ var convertors = {
|
|
|
18560
19979
|
var tag = node.literal;
|
|
18561
19980
|
var link = state.schema.marks.link;
|
|
18562
19981
|
if (openTagName) {
|
|
18563
|
-
var linkUrl = getMatchedAttributeValue(tag, 'href');
|
|
19982
|
+
var linkUrl = getMatchedAttributeValue(tag, 'href')[0];
|
|
18564
19983
|
state.openMark(link.create({
|
|
18565
|
-
linkUrl:
|
|
19984
|
+
linkUrl: linkUrl,
|
|
18566
19985
|
rawHTML: openTagName,
|
|
18567
19986
|
}));
|
|
18568
19987
|
}
|
|
@@ -18572,11 +19991,10 @@ var convertors = {
|
|
|
18572
19991
|
},
|
|
18573
19992
|
img: function (state, node, openTagName) {
|
|
18574
19993
|
var tag = node.literal;
|
|
18575
|
-
|
|
18576
|
-
|
|
18577
|
-
var altText = getMatchedAttributeValue(tag, 'alt');
|
|
19994
|
+
if (openTagName) {
|
|
19995
|
+
var _a = getMatchedAttributeValue(tag, 'src', 'alt'), imageUrl = _a[0], altText = _a[1];
|
|
18578
19996
|
var image = state.schema.nodes.image;
|
|
18579
|
-
state.addNode(image, __assign$1({ rawHTML: openTagName, imageUrl:
|
|
19997
|
+
state.addNode(image, __assign$1({ rawHTML: openTagName, imageUrl: imageUrl }, (altText && { altText: altText })));
|
|
18580
19998
|
}
|
|
18581
19999
|
},
|
|
18582
20000
|
hr: function (state, _, openTagName) {
|
|
@@ -18586,11 +20004,22 @@ var convertors = {
|
|
|
18586
20004
|
var paragraph = state.schema.nodes.paragraph;
|
|
18587
20005
|
var parent = node.parent, prev = node.prev, next = node.next;
|
|
18588
20006
|
if ((parent === null || parent === void 0 ? void 0 : parent.type) === 'paragraph') {
|
|
18589
|
-
|
|
20007
|
+
// should open a paragraph node when line text has only <br> tag
|
|
20008
|
+
// ex) first line\n\n<br>\nfourth line
|
|
20009
|
+
if (isSoftbreak(prev)) {
|
|
18590
20010
|
state.openNode(paragraph);
|
|
18591
20011
|
}
|
|
18592
|
-
|
|
20012
|
+
// should close a paragraph node when line text has only <br> tag
|
|
20013
|
+
// ex) first line\n\n<br>\nfourth line
|
|
20014
|
+
if (isSoftbreak(next)) {
|
|
20015
|
+
state.closeNode();
|
|
20016
|
+
// should close a paragraph node and open a paragraph node to separate between blocks
|
|
20017
|
+
// when <br> tag is in the middle of the paragraph
|
|
20018
|
+
// ex) first <br>line\nthird line
|
|
20019
|
+
}
|
|
20020
|
+
else if (next) {
|
|
18593
20021
|
state.closeNode();
|
|
20022
|
+
state.openNode(paragraph);
|
|
18594
20023
|
}
|
|
18595
20024
|
}
|
|
18596
20025
|
else if ((parent === null || parent === void 0 ? void 0 : parent.type) === 'tableCell') {
|
|
@@ -18657,7 +20086,7 @@ var convertors = {
|
|
|
18657
20086
|
var htmlToWwConvertors = createConvertors(convertors);
|
|
18658
20087
|
|
|
18659
20088
|
function isBRTag(node) {
|
|
18660
|
-
return node.type === 'htmlInline' &&
|
|
20089
|
+
return node.type === 'htmlInline' && reBR.test(node.literal);
|
|
18661
20090
|
}
|
|
18662
20091
|
function addRawHTMLAttributeToDOM(parent) {
|
|
18663
20092
|
toArray_1(parent.childNodes).forEach(function (child) {
|
|
@@ -18838,32 +20267,37 @@ var toWwConvertors = {
|
|
|
18838
20267
|
}
|
|
18839
20268
|
},
|
|
18840
20269
|
tableCell: function (state, node, _a) {
|
|
20270
|
+
var _b;
|
|
18841
20271
|
var entering = _a.entering;
|
|
18842
|
-
|
|
18843
|
-
|
|
18844
|
-
|
|
18845
|
-
|
|
18846
|
-
|
|
18847
|
-
|
|
18848
|
-
|
|
18849
|
-
|
|
20272
|
+
var _c = state.schema.nodes, tableHeadCell = _c.tableHeadCell, tableBodyCell = _c.tableBodyCell, paragraph = _c.paragraph;
|
|
20273
|
+
var tablePart = node.parent.parent;
|
|
20274
|
+
var cell = tablePart.type === 'tableHead' ? tableHeadCell : tableBodyCell;
|
|
20275
|
+
var hasParaNode = function (childNode) {
|
|
20276
|
+
return childNode && (isInlineNode(childNode) || isCustomHTMLInlineNode(state, childNode));
|
|
20277
|
+
};
|
|
20278
|
+
if (entering) {
|
|
20279
|
+
var attrs = null;
|
|
20280
|
+
if (!node.ignored) {
|
|
18850
20281
|
var table = tablePart.parent;
|
|
18851
|
-
var
|
|
18852
|
-
|
|
18853
|
-
|
|
18854
|
-
attrs
|
|
18855
|
-
|
|
18856
|
-
|
|
18857
|
-
|
|
18858
|
-
state.openNode(paragraph);
|
|
20282
|
+
var startIdx = node.startIdx;
|
|
20283
|
+
if (table.columns.length > startIdx) {
|
|
20284
|
+
var align = table.columns[startIdx].align;
|
|
20285
|
+
attrs = (_b = node.attrs) !== null && _b !== void 0 ? _b : {};
|
|
20286
|
+
if (align) {
|
|
20287
|
+
attrs.align = align;
|
|
20288
|
+
}
|
|
18859
20289
|
}
|
|
18860
20290
|
}
|
|
18861
|
-
|
|
18862
|
-
|
|
18863
|
-
|
|
18864
|
-
|
|
20291
|
+
state.openNode(cell, attrs);
|
|
20292
|
+
if (hasParaNode(node.firstChild)) {
|
|
20293
|
+
state.openNode(paragraph);
|
|
20294
|
+
}
|
|
20295
|
+
}
|
|
20296
|
+
else {
|
|
20297
|
+
if (hasParaNode(node.lastChild)) {
|
|
18865
20298
|
state.closeNode();
|
|
18866
20299
|
}
|
|
20300
|
+
state.closeNode();
|
|
18867
20301
|
}
|
|
18868
20302
|
},
|
|
18869
20303
|
strike: function (state, _, _a, customAttrs) {
|
|
@@ -18905,10 +20339,11 @@ var toWwConvertors = {
|
|
|
18905
20339
|
var openTagName = matched[1], closeTagName = matched[3];
|
|
18906
20340
|
var typeName = (openTagName || closeTagName).toLowerCase();
|
|
18907
20341
|
var markType = state.schema.marks[typeName];
|
|
20342
|
+
var sanitizedHTML = sanitizeHTML(html);
|
|
18908
20343
|
// for user defined html schema
|
|
18909
20344
|
if (markType === null || markType === void 0 ? void 0 : markType.spec.attrs.htmlInline) {
|
|
18910
20345
|
if (openTagName) {
|
|
18911
|
-
var htmlAttrs = getHTMLAttrsByHTMLString(
|
|
20346
|
+
var htmlAttrs = getHTMLAttrsByHTMLString(sanitizedHTML);
|
|
18912
20347
|
state.openMark(markType.create({ htmlAttrs: htmlAttrs }));
|
|
18913
20348
|
}
|
|
18914
20349
|
else {
|
|
@@ -18929,14 +20364,15 @@ var toWwConvertors = {
|
|
|
18929
20364
|
var openTagName = matched[1], closeTagName = matched[3];
|
|
18930
20365
|
var typeName = (openTagName || closeTagName).toLowerCase();
|
|
18931
20366
|
var nodeType = state.schema.nodes[typeName];
|
|
20367
|
+
var sanitizedHTML = sanitizeHTML(html);
|
|
18932
20368
|
// for user defined html schema
|
|
18933
20369
|
if (nodeType === null || nodeType === void 0 ? void 0 : nodeType.spec.attrs.htmlBlock) {
|
|
18934
|
-
var htmlAttrs = getHTMLAttrsByHTMLString(
|
|
20370
|
+
var htmlAttrs = getHTMLAttrsByHTMLString(sanitizedHTML);
|
|
18935
20371
|
var childrenHTML = getChildrenHTML(node, typeName);
|
|
18936
20372
|
state.addNode(nodeType, { htmlAttrs: htmlAttrs, childrenHTML: childrenHTML });
|
|
18937
20373
|
}
|
|
18938
20374
|
else {
|
|
18939
|
-
container.innerHTML =
|
|
20375
|
+
container.innerHTML = sanitizedHTML;
|
|
18940
20376
|
addRawHTMLAttributeToDOM(container);
|
|
18941
20377
|
state.convertByDOMParser(container);
|
|
18942
20378
|
}
|
|
@@ -19047,6 +20483,27 @@ var ToWwConvertorState = /** @class */ (function () {
|
|
|
19047
20483
|
var doc = DOMParser.fromSchema(this.schema).parse(root);
|
|
19048
20484
|
doc.content.forEach(function (node) { return _this.push(node); });
|
|
19049
20485
|
};
|
|
20486
|
+
ToWwConvertorState.prototype.closeUnmatchedHTMLInline = function (node, entering) {
|
|
20487
|
+
var _a;
|
|
20488
|
+
if (!entering && node.type !== 'htmlInline') {
|
|
20489
|
+
var length_1 = this.stack.length - 1;
|
|
20490
|
+
for (var i = length_1; i >= 0; i -= 1) {
|
|
20491
|
+
var nodeInfo = this.stack[i];
|
|
20492
|
+
if ((_a = nodeInfo.attrs) === null || _a === void 0 ? void 0 : _a.rawHTML) {
|
|
20493
|
+
if (nodeInfo.content.length) {
|
|
20494
|
+
this.closeNode();
|
|
20495
|
+
}
|
|
20496
|
+
else {
|
|
20497
|
+
// just pop useless unmatched html inline node
|
|
20498
|
+
this.stack.pop();
|
|
20499
|
+
}
|
|
20500
|
+
}
|
|
20501
|
+
else {
|
|
20502
|
+
break;
|
|
20503
|
+
}
|
|
20504
|
+
}
|
|
20505
|
+
}
|
|
20506
|
+
};
|
|
19050
20507
|
ToWwConvertorState.prototype.convert = function (mdNode, infoForPosSync) {
|
|
19051
20508
|
var walker = mdNode.walker();
|
|
19052
20509
|
var event = walker.next();
|
|
@@ -19064,6 +20521,7 @@ var ToWwConvertorState = /** @class */ (function () {
|
|
|
19064
20521
|
skipped = true;
|
|
19065
20522
|
},
|
|
19066
20523
|
};
|
|
20524
|
+
this_1.closeUnmatchedHTMLInline(node, entering);
|
|
19067
20525
|
convertor(this_1, node, context);
|
|
19068
20526
|
if ((infoForPosSync === null || infoForPosSync === void 0 ? void 0 : infoForPosSync.node) === node) {
|
|
19069
20527
|
var pos = this_1.stack.reduce(function (nodeSize, stackItem) {
|
|
@@ -19460,7 +20918,7 @@ var toMdConvertors = {
|
|
|
19460
20918
|
var node = _a.node;
|
|
19461
20919
|
var attrs = node.attrs;
|
|
19462
20920
|
var altText = escape$1(attrs.altText || '');
|
|
19463
|
-
var imageUrl =
|
|
20921
|
+
var imageUrl = escapeXml$1(attrs.imageUrl);
|
|
19464
20922
|
var altAttr = altText ? " alt=\"" + altText + "\"" : '';
|
|
19465
20923
|
return {
|
|
19466
20924
|
rawHTML: attrs.rawHTML ? "<" + attrs.rawHTML + " src=\"" + imageUrl + "\"" + altAttr + ">" : null,
|
|
@@ -19528,7 +20986,7 @@ var toMdConvertors = {
|
|
|
19528
20986
|
var node = _a.node;
|
|
19529
20987
|
var entering = _b.entering;
|
|
19530
20988
|
var attrs = node.attrs;
|
|
19531
|
-
var linkUrl =
|
|
20989
|
+
var linkUrl = escapeXml$1(attrs.linkUrl);
|
|
19532
20990
|
var rawHTML = attrs.rawHTML;
|
|
19533
20991
|
if (entering) {
|
|
19534
20992
|
return {
|
|
@@ -19565,7 +21023,8 @@ var toMdConvertors = {
|
|
|
19565
21023
|
var openTag = "<" + tagName;
|
|
19566
21024
|
var closeTag = "</" + tagName + ">";
|
|
19567
21025
|
Object.keys(attrs).forEach(function (attrName) {
|
|
19568
|
-
|
|
21026
|
+
// To prevent broken converting when attributes has double quote string
|
|
21027
|
+
openTag += " " + attrName + "=\"" + attrs[attrName].replace(/"/g, "'") + "\"";
|
|
19569
21028
|
});
|
|
19570
21029
|
openTag += '>';
|
|
19571
21030
|
if (node.attrs.htmlInline) {
|
|
@@ -20029,6 +21488,14 @@ function getPluginInfo(plugins, eventEmitter, usageStatistics) {
|
|
|
20029
21488
|
var TASK_ATTR_NAME = 'data-task';
|
|
20030
21489
|
var DISABLED_TASK_ATTR_NAME = 'data-task-disabled';
|
|
20031
21490
|
var TASK_CHECKED_CLASS_NAME = 'checked';
|
|
21491
|
+
function registerHTMLTagToWhitelist(convertorMap) {
|
|
21492
|
+
['htmlBlock', 'htmlInline'].forEach(function (htmlType) {
|
|
21493
|
+
if (convertorMap[htmlType]) {
|
|
21494
|
+
// register tag white list for preventing to remove the html in sanitizer
|
|
21495
|
+
Object.keys(convertorMap[htmlType]).forEach(function (type) { return registerTagWhitelistIfPossible(type); });
|
|
21496
|
+
}
|
|
21497
|
+
});
|
|
21498
|
+
}
|
|
20032
21499
|
/**
|
|
20033
21500
|
* Class ToastUIEditorViewer
|
|
20034
21501
|
* @param {object} options Option object
|
|
@@ -20074,6 +21541,7 @@ var ToastUIEditorViewer = /** @class */ (function () {
|
|
|
20074
21541
|
frontMatter: frontMatter,
|
|
20075
21542
|
sanitizer: customHTMLSanitizer || sanitizeHTML,
|
|
20076
21543
|
};
|
|
21544
|
+
registerHTMLTagToWhitelist(rendererOptions.customHTMLRenderer);
|
|
20077
21545
|
if (this.options.events) {
|
|
20078
21546
|
forEachOwnProperties_1(this.options.events, function (fn, key) {
|
|
20079
21547
|
_this.on(key, fn);
|
|
@@ -20094,7 +21562,7 @@ var ToastUIEditorViewer = /** @class */ (function () {
|
|
|
20094
21562
|
customParser: markdownParsers,
|
|
20095
21563
|
});
|
|
20096
21564
|
this.preview = new MarkdownPreview(this.eventEmitter, __assign$1(__assign$1({}, rendererOptions), { isViewer: true }));
|
|
20097
|
-
on_1(this.preview.
|
|
21565
|
+
on_1(this.preview.previewContent, 'mousedown', this.toggleTask.bind(this));
|
|
20098
21566
|
if (initialValue) {
|
|
20099
21567
|
this.setMarkdown(initialValue);
|
|
20100
21568
|
}
|
|
@@ -20508,6 +21976,18 @@ var ScrollSync = /** @class */ (function () {
|
|
|
20508
21976
|
return ScrollSync;
|
|
20509
21977
|
}());
|
|
20510
21978
|
|
|
21979
|
+
var queryMap = {
|
|
21980
|
+
getPopupInitialValues: function (editor, payload) {
|
|
21981
|
+
var popupName = payload.popupName;
|
|
21982
|
+
return popupName === 'link' ? { linkText: editor.getSelectedText() } : {};
|
|
21983
|
+
},
|
|
21984
|
+
};
|
|
21985
|
+
function buildQuery(editor) {
|
|
21986
|
+
editor.eventEmitter.listen('query', function (query, payload) {
|
|
21987
|
+
return queryMap[query](editor, payload);
|
|
21988
|
+
});
|
|
21989
|
+
}
|
|
21990
|
+
|
|
20511
21991
|
/**
|
|
20512
21992
|
* ToastUIEditorCore
|
|
20513
21993
|
* @param {Object} options Option object
|
|
@@ -20547,11 +22027,12 @@ var ScrollSync = /** @class */ (function () {
|
|
|
20547
22027
|
* @param {boolean} [options.frontMatter=false] - whether use the front matter
|
|
20548
22028
|
* @param {Array.<object>} [options.widgetRules=[]] - The rules for replacing the text with widget node
|
|
20549
22029
|
* @param {string} [options.theme] - The theme to style the editor with. The default is included in toastui-editor.css.
|
|
22030
|
+
* @param {autofocus} [options.autofocus=true] - automatically focus the editor on creation.
|
|
20550
22031
|
*/
|
|
20551
22032
|
var ToastUIEditorCore = /** @class */ (function () {
|
|
20552
22033
|
function ToastUIEditorCore(options) {
|
|
20553
22034
|
var _this = this;
|
|
20554
|
-
this.
|
|
22035
|
+
this.initialHTML = options.el.innerHTML;
|
|
20555
22036
|
options.el.innerHTML = '';
|
|
20556
22037
|
this.options = extend_1({
|
|
20557
22038
|
previewStyle: 'tab',
|
|
@@ -20580,10 +22061,13 @@ var ToastUIEditorCore = /** @class */ (function () {
|
|
|
20580
22061
|
frontMatter: false,
|
|
20581
22062
|
widgetRules: [],
|
|
20582
22063
|
theme: 'light',
|
|
22064
|
+
autofocus: true,
|
|
20583
22065
|
}, options);
|
|
20584
22066
|
var _a = this.options, customHTMLRenderer = _a.customHTMLRenderer, extendedAutolinks = _a.extendedAutolinks, referenceDefinition = _a.referenceDefinition, frontMatter = _a.frontMatter, customMarkdownRenderer = _a.customMarkdownRenderer, useCommandShortcut = _a.useCommandShortcut, initialEditType = _a.initialEditType, widgetRules = _a.widgetRules, customHTMLSanitizer = _a.customHTMLSanitizer;
|
|
20585
22067
|
this.mode = initialEditType || 'markdown';
|
|
20586
22068
|
this.mdPreviewStyle = this.options.previewStyle;
|
|
22069
|
+
this.i18n = i18n;
|
|
22070
|
+
this.i18n.setCode(this.options.language);
|
|
20587
22071
|
this.eventEmitter = new EventEmitter();
|
|
20588
22072
|
setWidgetRules(widgetRules);
|
|
20589
22073
|
var linkAttributes = sanitizeLinkAttribute(this.options.linkAttributes);
|
|
@@ -20599,8 +22083,6 @@ var ToastUIEditorCore = /** @class */ (function () {
|
|
|
20599
22083
|
};
|
|
20600
22084
|
var wwToDOMAdaptor = new WwToDOMAdaptor(linkAttributes, rendererOptions.customHTMLRenderer);
|
|
20601
22085
|
var htmlSchemaMap = createHTMLSchemaMap(rendererOptions.customHTMLRenderer, rendererOptions.sanitizer, wwToDOMAdaptor);
|
|
20602
|
-
this.i18n = i18n;
|
|
20603
|
-
this.i18n.setCode(this.options.language);
|
|
20604
22086
|
this.toastMark = new ToastMark('', {
|
|
20605
22087
|
disallowedHtmlBlockTags: ['br', 'img'],
|
|
20606
22088
|
extendedAutolinks: extendedAutolinks,
|
|
@@ -20631,7 +22113,7 @@ var ToastUIEditorCore = /** @class */ (function () {
|
|
|
20631
22113
|
this.setPlaceholder(this.options.placeholder);
|
|
20632
22114
|
}
|
|
20633
22115
|
if (!this.options.initialValue) {
|
|
20634
|
-
this.setHTML(this.
|
|
22116
|
+
this.setHTML(this.initialHTML, false);
|
|
20635
22117
|
}
|
|
20636
22118
|
this.commandManager = new CommandManager(this.eventEmitter, this.mdEditor.commands, this.wwEditor.commands, function () { return _this.mode; });
|
|
20637
22119
|
if (this.options.usageStatistics) {
|
|
@@ -20640,6 +22122,7 @@ var ToastUIEditorCore = /** @class */ (function () {
|
|
|
20640
22122
|
this.scrollSync = new ScrollSync(this.mdEditor, this.preview, this.eventEmitter);
|
|
20641
22123
|
this.addInitEvent();
|
|
20642
22124
|
this.addInitCommand(mdCommands, wwCommands);
|
|
22125
|
+
buildQuery(this);
|
|
20643
22126
|
if (this.options.hooks) {
|
|
20644
22127
|
forEachOwnProperties_1(this.options.hooks, function (fn, key) { return _this.addHook(key, fn); });
|
|
20645
22128
|
}
|
|
@@ -20647,7 +22130,7 @@ var ToastUIEditorCore = /** @class */ (function () {
|
|
|
20647
22130
|
forEachOwnProperties_1(this.options.events, function (fn, key) { return _this.on(key, fn); });
|
|
20648
22131
|
}
|
|
20649
22132
|
this.eventEmitter.emit('load', this);
|
|
20650
|
-
this.moveCursorToStart();
|
|
22133
|
+
this.moveCursorToStart(this.options.autofocus);
|
|
20651
22134
|
}
|
|
20652
22135
|
ToastUIEditorCore.prototype.addInitEvent = function () {
|
|
20653
22136
|
this.on('needChangeMode', this.changeMode.bind(this));
|
|
@@ -20763,15 +22246,19 @@ var ToastUIEditorCore = /** @class */ (function () {
|
|
|
20763
22246
|
};
|
|
20764
22247
|
/**
|
|
20765
22248
|
* Set cursor position to end
|
|
22249
|
+
* @param {boolean} [focus] - automatically focus the editor
|
|
20766
22250
|
*/
|
|
20767
|
-
ToastUIEditorCore.prototype.moveCursorToEnd = function () {
|
|
20768
|
-
|
|
22251
|
+
ToastUIEditorCore.prototype.moveCursorToEnd = function (focus) {
|
|
22252
|
+
if (focus === void 0) { focus = true; }
|
|
22253
|
+
this.getCurrentModeEditor().moveCursorToEnd(focus);
|
|
20769
22254
|
};
|
|
20770
22255
|
/**
|
|
20771
22256
|
* Set cursor position to start
|
|
22257
|
+
* @param {boolean} [focus] - automatically focus the editor
|
|
20772
22258
|
*/
|
|
20773
|
-
ToastUIEditorCore.prototype.moveCursorToStart = function () {
|
|
20774
|
-
|
|
22259
|
+
ToastUIEditorCore.prototype.moveCursorToStart = function (focus) {
|
|
22260
|
+
if (focus === void 0) { focus = true; }
|
|
22261
|
+
this.getCurrentModeEditor().moveCursorToStart(focus);
|
|
20775
22262
|
};
|
|
20776
22263
|
/**
|
|
20777
22264
|
* Set markdown syntax text.
|
|
@@ -20824,16 +22311,13 @@ var ToastUIEditorCore = /** @class */ (function () {
|
|
|
20824
22311
|
ToastUIEditorCore.prototype.getHTML = function () {
|
|
20825
22312
|
var _this = this;
|
|
20826
22313
|
this.eventEmitter.holdEventInvoke(function () {
|
|
20827
|
-
if (_this.
|
|
20828
|
-
_this.
|
|
22314
|
+
if (_this.isMarkdownMode()) {
|
|
22315
|
+
var mdNode = _this.toastMark.getRootNode();
|
|
22316
|
+
var wwNode = _this.convertor.toWysiwygModel(mdNode);
|
|
22317
|
+
_this.wwEditor.setModel(wwNode);
|
|
20829
22318
|
}
|
|
20830
22319
|
});
|
|
20831
|
-
|
|
20832
|
-
var mdRenderer = this.preview.getRenderer();
|
|
20833
|
-
return mdRenderer
|
|
20834
|
-
.render(mdNode)
|
|
20835
|
-
.replace(/\sdata-nodeid="\d{1,}"/g, '')
|
|
20836
|
-
.trim();
|
|
22320
|
+
return this.wwEditor.view.dom.innerHTML;
|
|
20837
22321
|
};
|
|
20838
22322
|
/**
|
|
20839
22323
|
* Insert text
|
|
@@ -21640,11 +23124,15 @@ var templateObject_1$h;
|
|
|
21640
23124
|
* @returns {function} debounced function.
|
|
21641
23125
|
* @memberof module:tricks
|
|
21642
23126
|
* @example
|
|
21643
|
-
*
|
|
23127
|
+
* // ES6
|
|
23128
|
+
* import debounce from 'tui-code-snippet/tricks/debounce';
|
|
23129
|
+
*
|
|
23130
|
+
* // CommonJS
|
|
23131
|
+
* const debounce = require('tui-code-snippet/tricks/debounce');
|
|
21644
23132
|
*
|
|
21645
23133
|
* function someMethodToInvokeDebounced() {}
|
|
21646
23134
|
*
|
|
21647
|
-
*
|
|
23135
|
+
* const debounced = debounce(someMethodToInvokeDebounced, 300);
|
|
21648
23136
|
*
|
|
21649
23137
|
* // invoke repeatedly
|
|
21650
23138
|
* debounced();
|
|
@@ -21692,11 +23180,15 @@ var debounce = debounce_1;
|
|
|
21692
23180
|
* @returns {function} throttled function
|
|
21693
23181
|
* @memberof module:tricks
|
|
21694
23182
|
* @example
|
|
21695
|
-
*
|
|
23183
|
+
* // ES6
|
|
23184
|
+
* import throttle from 'tui-code-snippet/tricks/throttle';
|
|
23185
|
+
*
|
|
23186
|
+
* // CommonJS
|
|
23187
|
+
* const throttle = require('tui-code-snippet/tricks/throttle');
|
|
21696
23188
|
*
|
|
21697
23189
|
* function someMethodToInvokeThrottled() {}
|
|
21698
23190
|
*
|
|
21699
|
-
*
|
|
23191
|
+
* const throttled = throttle(someMethodToInvokeThrottled, 300);
|
|
21700
23192
|
*
|
|
21701
23193
|
* // invoke repeatedly
|
|
21702
23194
|
* throttled(); // invoke (leading)
|
|
@@ -21711,7 +23203,7 @@ var debounce = debounce_1;
|
|
|
21711
23203
|
* // if you need reuse throttled method. then invoke reset()
|
|
21712
23204
|
* throttled.reset();
|
|
21713
23205
|
*/
|
|
21714
|
-
function throttle(fn, interval) {
|
|
23206
|
+
function throttle$1(fn, interval) {
|
|
21715
23207
|
var base;
|
|
21716
23208
|
var isLeading = true;
|
|
21717
23209
|
var tick = function(_args) {
|
|
@@ -21761,7 +23253,934 @@ function throttle(fn, interval) {
|
|
|
21761
23253
|
return throttled;
|
|
21762
23254
|
}
|
|
21763
23255
|
|
|
21764
|
-
var throttle_1 = throttle;
|
|
23256
|
+
var throttle_1 = throttle$1;
|
|
23257
|
+
|
|
23258
|
+
/**
|
|
23259
|
+
* A collection of shims that provide minimal functionality of the ES6 collections.
|
|
23260
|
+
*
|
|
23261
|
+
* These implementations are not meant to be used outside of the ResizeObserver
|
|
23262
|
+
* modules as they cover only a limited range of use cases.
|
|
23263
|
+
*/
|
|
23264
|
+
/* eslint-disable require-jsdoc, valid-jsdoc */
|
|
23265
|
+
var MapShim = (function () {
|
|
23266
|
+
if (typeof Map !== 'undefined') {
|
|
23267
|
+
return Map;
|
|
23268
|
+
}
|
|
23269
|
+
/**
|
|
23270
|
+
* Returns index in provided array that matches the specified key.
|
|
23271
|
+
*
|
|
23272
|
+
* @param {Array<Array>} arr
|
|
23273
|
+
* @param {*} key
|
|
23274
|
+
* @returns {number}
|
|
23275
|
+
*/
|
|
23276
|
+
function getIndex(arr, key) {
|
|
23277
|
+
var result = -1;
|
|
23278
|
+
arr.some(function (entry, index) {
|
|
23279
|
+
if (entry[0] === key) {
|
|
23280
|
+
result = index;
|
|
23281
|
+
return true;
|
|
23282
|
+
}
|
|
23283
|
+
return false;
|
|
23284
|
+
});
|
|
23285
|
+
return result;
|
|
23286
|
+
}
|
|
23287
|
+
return /** @class */ (function () {
|
|
23288
|
+
function class_1() {
|
|
23289
|
+
this.__entries__ = [];
|
|
23290
|
+
}
|
|
23291
|
+
Object.defineProperty(class_1.prototype, "size", {
|
|
23292
|
+
/**
|
|
23293
|
+
* @returns {boolean}
|
|
23294
|
+
*/
|
|
23295
|
+
get: function () {
|
|
23296
|
+
return this.__entries__.length;
|
|
23297
|
+
},
|
|
23298
|
+
enumerable: true,
|
|
23299
|
+
configurable: true
|
|
23300
|
+
});
|
|
23301
|
+
/**
|
|
23302
|
+
* @param {*} key
|
|
23303
|
+
* @returns {*}
|
|
23304
|
+
*/
|
|
23305
|
+
class_1.prototype.get = function (key) {
|
|
23306
|
+
var index = getIndex(this.__entries__, key);
|
|
23307
|
+
var entry = this.__entries__[index];
|
|
23308
|
+
return entry && entry[1];
|
|
23309
|
+
};
|
|
23310
|
+
/**
|
|
23311
|
+
* @param {*} key
|
|
23312
|
+
* @param {*} value
|
|
23313
|
+
* @returns {void}
|
|
23314
|
+
*/
|
|
23315
|
+
class_1.prototype.set = function (key, value) {
|
|
23316
|
+
var index = getIndex(this.__entries__, key);
|
|
23317
|
+
if (~index) {
|
|
23318
|
+
this.__entries__[index][1] = value;
|
|
23319
|
+
}
|
|
23320
|
+
else {
|
|
23321
|
+
this.__entries__.push([key, value]);
|
|
23322
|
+
}
|
|
23323
|
+
};
|
|
23324
|
+
/**
|
|
23325
|
+
* @param {*} key
|
|
23326
|
+
* @returns {void}
|
|
23327
|
+
*/
|
|
23328
|
+
class_1.prototype.delete = function (key) {
|
|
23329
|
+
var entries = this.__entries__;
|
|
23330
|
+
var index = getIndex(entries, key);
|
|
23331
|
+
if (~index) {
|
|
23332
|
+
entries.splice(index, 1);
|
|
23333
|
+
}
|
|
23334
|
+
};
|
|
23335
|
+
/**
|
|
23336
|
+
* @param {*} key
|
|
23337
|
+
* @returns {void}
|
|
23338
|
+
*/
|
|
23339
|
+
class_1.prototype.has = function (key) {
|
|
23340
|
+
return !!~getIndex(this.__entries__, key);
|
|
23341
|
+
};
|
|
23342
|
+
/**
|
|
23343
|
+
* @returns {void}
|
|
23344
|
+
*/
|
|
23345
|
+
class_1.prototype.clear = function () {
|
|
23346
|
+
this.__entries__.splice(0);
|
|
23347
|
+
};
|
|
23348
|
+
/**
|
|
23349
|
+
* @param {Function} callback
|
|
23350
|
+
* @param {*} [ctx=null]
|
|
23351
|
+
* @returns {void}
|
|
23352
|
+
*/
|
|
23353
|
+
class_1.prototype.forEach = function (callback, ctx) {
|
|
23354
|
+
if (ctx === void 0) { ctx = null; }
|
|
23355
|
+
for (var _i = 0, _a = this.__entries__; _i < _a.length; _i++) {
|
|
23356
|
+
var entry = _a[_i];
|
|
23357
|
+
callback.call(ctx, entry[1], entry[0]);
|
|
23358
|
+
}
|
|
23359
|
+
};
|
|
23360
|
+
return class_1;
|
|
23361
|
+
}());
|
|
23362
|
+
})();
|
|
23363
|
+
|
|
23364
|
+
/**
|
|
23365
|
+
* Detects whether window and document objects are available in current environment.
|
|
23366
|
+
*/
|
|
23367
|
+
var isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' && window.document === document;
|
|
23368
|
+
|
|
23369
|
+
// Returns global object of a current environment.
|
|
23370
|
+
var global$1 = (function () {
|
|
23371
|
+
if (typeof global !== 'undefined' && global.Math === Math) {
|
|
23372
|
+
return global;
|
|
23373
|
+
}
|
|
23374
|
+
if (typeof self !== 'undefined' && self.Math === Math) {
|
|
23375
|
+
return self;
|
|
23376
|
+
}
|
|
23377
|
+
if (typeof window !== 'undefined' && window.Math === Math) {
|
|
23378
|
+
return window;
|
|
23379
|
+
}
|
|
23380
|
+
// eslint-disable-next-line no-new-func
|
|
23381
|
+
return Function('return this')();
|
|
23382
|
+
})();
|
|
23383
|
+
|
|
23384
|
+
/**
|
|
23385
|
+
* A shim for the requestAnimationFrame which falls back to the setTimeout if
|
|
23386
|
+
* first one is not supported.
|
|
23387
|
+
*
|
|
23388
|
+
* @returns {number} Requests' identifier.
|
|
23389
|
+
*/
|
|
23390
|
+
var requestAnimationFrame$1 = (function () {
|
|
23391
|
+
if (typeof requestAnimationFrame === 'function') {
|
|
23392
|
+
// It's required to use a bounded function because IE sometimes throws
|
|
23393
|
+
// an "Invalid calling object" error if rAF is invoked without the global
|
|
23394
|
+
// object on the left hand side.
|
|
23395
|
+
return requestAnimationFrame.bind(global$1);
|
|
23396
|
+
}
|
|
23397
|
+
return function (callback) { return setTimeout(function () { return callback(Date.now()); }, 1000 / 60); };
|
|
23398
|
+
})();
|
|
23399
|
+
|
|
23400
|
+
// Defines minimum timeout before adding a trailing call.
|
|
23401
|
+
var trailingTimeout = 2;
|
|
23402
|
+
/**
|
|
23403
|
+
* Creates a wrapper function which ensures that provided callback will be
|
|
23404
|
+
* invoked only once during the specified delay period.
|
|
23405
|
+
*
|
|
23406
|
+
* @param {Function} callback - Function to be invoked after the delay period.
|
|
23407
|
+
* @param {number} delay - Delay after which to invoke callback.
|
|
23408
|
+
* @returns {Function}
|
|
23409
|
+
*/
|
|
23410
|
+
function throttle (callback, delay) {
|
|
23411
|
+
var leadingCall = false, trailingCall = false, lastCallTime = 0;
|
|
23412
|
+
/**
|
|
23413
|
+
* Invokes the original callback function and schedules new invocation if
|
|
23414
|
+
* the "proxy" was called during current request.
|
|
23415
|
+
*
|
|
23416
|
+
* @returns {void}
|
|
23417
|
+
*/
|
|
23418
|
+
function resolvePending() {
|
|
23419
|
+
if (leadingCall) {
|
|
23420
|
+
leadingCall = false;
|
|
23421
|
+
callback();
|
|
23422
|
+
}
|
|
23423
|
+
if (trailingCall) {
|
|
23424
|
+
proxy();
|
|
23425
|
+
}
|
|
23426
|
+
}
|
|
23427
|
+
/**
|
|
23428
|
+
* Callback invoked after the specified delay. It will further postpone
|
|
23429
|
+
* invocation of the original function delegating it to the
|
|
23430
|
+
* requestAnimationFrame.
|
|
23431
|
+
*
|
|
23432
|
+
* @returns {void}
|
|
23433
|
+
*/
|
|
23434
|
+
function timeoutCallback() {
|
|
23435
|
+
requestAnimationFrame$1(resolvePending);
|
|
23436
|
+
}
|
|
23437
|
+
/**
|
|
23438
|
+
* Schedules invocation of the original function.
|
|
23439
|
+
*
|
|
23440
|
+
* @returns {void}
|
|
23441
|
+
*/
|
|
23442
|
+
function proxy() {
|
|
23443
|
+
var timeStamp = Date.now();
|
|
23444
|
+
if (leadingCall) {
|
|
23445
|
+
// Reject immediately following calls.
|
|
23446
|
+
if (timeStamp - lastCallTime < trailingTimeout) {
|
|
23447
|
+
return;
|
|
23448
|
+
}
|
|
23449
|
+
// Schedule new call to be in invoked when the pending one is resolved.
|
|
23450
|
+
// This is important for "transitions" which never actually start
|
|
23451
|
+
// immediately so there is a chance that we might miss one if change
|
|
23452
|
+
// happens amids the pending invocation.
|
|
23453
|
+
trailingCall = true;
|
|
23454
|
+
}
|
|
23455
|
+
else {
|
|
23456
|
+
leadingCall = true;
|
|
23457
|
+
trailingCall = false;
|
|
23458
|
+
setTimeout(timeoutCallback, delay);
|
|
23459
|
+
}
|
|
23460
|
+
lastCallTime = timeStamp;
|
|
23461
|
+
}
|
|
23462
|
+
return proxy;
|
|
23463
|
+
}
|
|
23464
|
+
|
|
23465
|
+
// Minimum delay before invoking the update of observers.
|
|
23466
|
+
var REFRESH_DELAY = 20;
|
|
23467
|
+
// A list of substrings of CSS properties used to find transition events that
|
|
23468
|
+
// might affect dimensions of observed elements.
|
|
23469
|
+
var transitionKeys = ['top', 'right', 'bottom', 'left', 'width', 'height', 'size', 'weight'];
|
|
23470
|
+
// Check if MutationObserver is available.
|
|
23471
|
+
var mutationObserverSupported = typeof MutationObserver !== 'undefined';
|
|
23472
|
+
/**
|
|
23473
|
+
* Singleton controller class which handles updates of ResizeObserver instances.
|
|
23474
|
+
*/
|
|
23475
|
+
var ResizeObserverController = /** @class */ (function () {
|
|
23476
|
+
/**
|
|
23477
|
+
* Creates a new instance of ResizeObserverController.
|
|
23478
|
+
*
|
|
23479
|
+
* @private
|
|
23480
|
+
*/
|
|
23481
|
+
function ResizeObserverController() {
|
|
23482
|
+
/**
|
|
23483
|
+
* Indicates whether DOM listeners have been added.
|
|
23484
|
+
*
|
|
23485
|
+
* @private {boolean}
|
|
23486
|
+
*/
|
|
23487
|
+
this.connected_ = false;
|
|
23488
|
+
/**
|
|
23489
|
+
* Tells that controller has subscribed for Mutation Events.
|
|
23490
|
+
*
|
|
23491
|
+
* @private {boolean}
|
|
23492
|
+
*/
|
|
23493
|
+
this.mutationEventsAdded_ = false;
|
|
23494
|
+
/**
|
|
23495
|
+
* Keeps reference to the instance of MutationObserver.
|
|
23496
|
+
*
|
|
23497
|
+
* @private {MutationObserver}
|
|
23498
|
+
*/
|
|
23499
|
+
this.mutationsObserver_ = null;
|
|
23500
|
+
/**
|
|
23501
|
+
* A list of connected observers.
|
|
23502
|
+
*
|
|
23503
|
+
* @private {Array<ResizeObserverSPI>}
|
|
23504
|
+
*/
|
|
23505
|
+
this.observers_ = [];
|
|
23506
|
+
this.onTransitionEnd_ = this.onTransitionEnd_.bind(this);
|
|
23507
|
+
this.refresh = throttle(this.refresh.bind(this), REFRESH_DELAY);
|
|
23508
|
+
}
|
|
23509
|
+
/**
|
|
23510
|
+
* Adds observer to observers list.
|
|
23511
|
+
*
|
|
23512
|
+
* @param {ResizeObserverSPI} observer - Observer to be added.
|
|
23513
|
+
* @returns {void}
|
|
23514
|
+
*/
|
|
23515
|
+
ResizeObserverController.prototype.addObserver = function (observer) {
|
|
23516
|
+
if (!~this.observers_.indexOf(observer)) {
|
|
23517
|
+
this.observers_.push(observer);
|
|
23518
|
+
}
|
|
23519
|
+
// Add listeners if they haven't been added yet.
|
|
23520
|
+
if (!this.connected_) {
|
|
23521
|
+
this.connect_();
|
|
23522
|
+
}
|
|
23523
|
+
};
|
|
23524
|
+
/**
|
|
23525
|
+
* Removes observer from observers list.
|
|
23526
|
+
*
|
|
23527
|
+
* @param {ResizeObserverSPI} observer - Observer to be removed.
|
|
23528
|
+
* @returns {void}
|
|
23529
|
+
*/
|
|
23530
|
+
ResizeObserverController.prototype.removeObserver = function (observer) {
|
|
23531
|
+
var observers = this.observers_;
|
|
23532
|
+
var index = observers.indexOf(observer);
|
|
23533
|
+
// Remove observer if it's present in registry.
|
|
23534
|
+
if (~index) {
|
|
23535
|
+
observers.splice(index, 1);
|
|
23536
|
+
}
|
|
23537
|
+
// Remove listeners if controller has no connected observers.
|
|
23538
|
+
if (!observers.length && this.connected_) {
|
|
23539
|
+
this.disconnect_();
|
|
23540
|
+
}
|
|
23541
|
+
};
|
|
23542
|
+
/**
|
|
23543
|
+
* Invokes the update of observers. It will continue running updates insofar
|
|
23544
|
+
* it detects changes.
|
|
23545
|
+
*
|
|
23546
|
+
* @returns {void}
|
|
23547
|
+
*/
|
|
23548
|
+
ResizeObserverController.prototype.refresh = function () {
|
|
23549
|
+
var changesDetected = this.updateObservers_();
|
|
23550
|
+
// Continue running updates if changes have been detected as there might
|
|
23551
|
+
// be future ones caused by CSS transitions.
|
|
23552
|
+
if (changesDetected) {
|
|
23553
|
+
this.refresh();
|
|
23554
|
+
}
|
|
23555
|
+
};
|
|
23556
|
+
/**
|
|
23557
|
+
* Updates every observer from observers list and notifies them of queued
|
|
23558
|
+
* entries.
|
|
23559
|
+
*
|
|
23560
|
+
* @private
|
|
23561
|
+
* @returns {boolean} Returns "true" if any observer has detected changes in
|
|
23562
|
+
* dimensions of it's elements.
|
|
23563
|
+
*/
|
|
23564
|
+
ResizeObserverController.prototype.updateObservers_ = function () {
|
|
23565
|
+
// Collect observers that have active observations.
|
|
23566
|
+
var activeObservers = this.observers_.filter(function (observer) {
|
|
23567
|
+
return observer.gatherActive(), observer.hasActive();
|
|
23568
|
+
});
|
|
23569
|
+
// Deliver notifications in a separate cycle in order to avoid any
|
|
23570
|
+
// collisions between observers, e.g. when multiple instances of
|
|
23571
|
+
// ResizeObserver are tracking the same element and the callback of one
|
|
23572
|
+
// of them changes content dimensions of the observed target. Sometimes
|
|
23573
|
+
// this may result in notifications being blocked for the rest of observers.
|
|
23574
|
+
activeObservers.forEach(function (observer) { return observer.broadcastActive(); });
|
|
23575
|
+
return activeObservers.length > 0;
|
|
23576
|
+
};
|
|
23577
|
+
/**
|
|
23578
|
+
* Initializes DOM listeners.
|
|
23579
|
+
*
|
|
23580
|
+
* @private
|
|
23581
|
+
* @returns {void}
|
|
23582
|
+
*/
|
|
23583
|
+
ResizeObserverController.prototype.connect_ = function () {
|
|
23584
|
+
// Do nothing if running in a non-browser environment or if listeners
|
|
23585
|
+
// have been already added.
|
|
23586
|
+
if (!isBrowser || this.connected_) {
|
|
23587
|
+
return;
|
|
23588
|
+
}
|
|
23589
|
+
// Subscription to the "Transitionend" event is used as a workaround for
|
|
23590
|
+
// delayed transitions. This way it's possible to capture at least the
|
|
23591
|
+
// final state of an element.
|
|
23592
|
+
document.addEventListener('transitionend', this.onTransitionEnd_);
|
|
23593
|
+
window.addEventListener('resize', this.refresh);
|
|
23594
|
+
if (mutationObserverSupported) {
|
|
23595
|
+
this.mutationsObserver_ = new MutationObserver(this.refresh);
|
|
23596
|
+
this.mutationsObserver_.observe(document, {
|
|
23597
|
+
attributes: true,
|
|
23598
|
+
childList: true,
|
|
23599
|
+
characterData: true,
|
|
23600
|
+
subtree: true
|
|
23601
|
+
});
|
|
23602
|
+
}
|
|
23603
|
+
else {
|
|
23604
|
+
document.addEventListener('DOMSubtreeModified', this.refresh);
|
|
23605
|
+
this.mutationEventsAdded_ = true;
|
|
23606
|
+
}
|
|
23607
|
+
this.connected_ = true;
|
|
23608
|
+
};
|
|
23609
|
+
/**
|
|
23610
|
+
* Removes DOM listeners.
|
|
23611
|
+
*
|
|
23612
|
+
* @private
|
|
23613
|
+
* @returns {void}
|
|
23614
|
+
*/
|
|
23615
|
+
ResizeObserverController.prototype.disconnect_ = function () {
|
|
23616
|
+
// Do nothing if running in a non-browser environment or if listeners
|
|
23617
|
+
// have been already removed.
|
|
23618
|
+
if (!isBrowser || !this.connected_) {
|
|
23619
|
+
return;
|
|
23620
|
+
}
|
|
23621
|
+
document.removeEventListener('transitionend', this.onTransitionEnd_);
|
|
23622
|
+
window.removeEventListener('resize', this.refresh);
|
|
23623
|
+
if (this.mutationsObserver_) {
|
|
23624
|
+
this.mutationsObserver_.disconnect();
|
|
23625
|
+
}
|
|
23626
|
+
if (this.mutationEventsAdded_) {
|
|
23627
|
+
document.removeEventListener('DOMSubtreeModified', this.refresh);
|
|
23628
|
+
}
|
|
23629
|
+
this.mutationsObserver_ = null;
|
|
23630
|
+
this.mutationEventsAdded_ = false;
|
|
23631
|
+
this.connected_ = false;
|
|
23632
|
+
};
|
|
23633
|
+
/**
|
|
23634
|
+
* "Transitionend" event handler.
|
|
23635
|
+
*
|
|
23636
|
+
* @private
|
|
23637
|
+
* @param {TransitionEvent} event
|
|
23638
|
+
* @returns {void}
|
|
23639
|
+
*/
|
|
23640
|
+
ResizeObserverController.prototype.onTransitionEnd_ = function (_a) {
|
|
23641
|
+
var _b = _a.propertyName, propertyName = _b === void 0 ? '' : _b;
|
|
23642
|
+
// Detect whether transition may affect dimensions of an element.
|
|
23643
|
+
var isReflowProperty = transitionKeys.some(function (key) {
|
|
23644
|
+
return !!~propertyName.indexOf(key);
|
|
23645
|
+
});
|
|
23646
|
+
if (isReflowProperty) {
|
|
23647
|
+
this.refresh();
|
|
23648
|
+
}
|
|
23649
|
+
};
|
|
23650
|
+
/**
|
|
23651
|
+
* Returns instance of the ResizeObserverController.
|
|
23652
|
+
*
|
|
23653
|
+
* @returns {ResizeObserverController}
|
|
23654
|
+
*/
|
|
23655
|
+
ResizeObserverController.getInstance = function () {
|
|
23656
|
+
if (!this.instance_) {
|
|
23657
|
+
this.instance_ = new ResizeObserverController();
|
|
23658
|
+
}
|
|
23659
|
+
return this.instance_;
|
|
23660
|
+
};
|
|
23661
|
+
/**
|
|
23662
|
+
* Holds reference to the controller's instance.
|
|
23663
|
+
*
|
|
23664
|
+
* @private {ResizeObserverController}
|
|
23665
|
+
*/
|
|
23666
|
+
ResizeObserverController.instance_ = null;
|
|
23667
|
+
return ResizeObserverController;
|
|
23668
|
+
}());
|
|
23669
|
+
|
|
23670
|
+
/**
|
|
23671
|
+
* Defines non-writable/enumerable properties of the provided target object.
|
|
23672
|
+
*
|
|
23673
|
+
* @param {Object} target - Object for which to define properties.
|
|
23674
|
+
* @param {Object} props - Properties to be defined.
|
|
23675
|
+
* @returns {Object} Target object.
|
|
23676
|
+
*/
|
|
23677
|
+
var defineConfigurable = (function (target, props) {
|
|
23678
|
+
for (var _i = 0, _a = Object.keys(props); _i < _a.length; _i++) {
|
|
23679
|
+
var key = _a[_i];
|
|
23680
|
+
Object.defineProperty(target, key, {
|
|
23681
|
+
value: props[key],
|
|
23682
|
+
enumerable: false,
|
|
23683
|
+
writable: false,
|
|
23684
|
+
configurable: true
|
|
23685
|
+
});
|
|
23686
|
+
}
|
|
23687
|
+
return target;
|
|
23688
|
+
});
|
|
23689
|
+
|
|
23690
|
+
/**
|
|
23691
|
+
* Returns the global object associated with provided element.
|
|
23692
|
+
*
|
|
23693
|
+
* @param {Object} target
|
|
23694
|
+
* @returns {Object}
|
|
23695
|
+
*/
|
|
23696
|
+
var getWindowOf = (function (target) {
|
|
23697
|
+
// Assume that the element is an instance of Node, which means that it
|
|
23698
|
+
// has the "ownerDocument" property from which we can retrieve a
|
|
23699
|
+
// corresponding global object.
|
|
23700
|
+
var ownerGlobal = target && target.ownerDocument && target.ownerDocument.defaultView;
|
|
23701
|
+
// Return the local global object if it's not possible extract one from
|
|
23702
|
+
// provided element.
|
|
23703
|
+
return ownerGlobal || global$1;
|
|
23704
|
+
});
|
|
23705
|
+
|
|
23706
|
+
// Placeholder of an empty content rectangle.
|
|
23707
|
+
var emptyRect = createRectInit(0, 0, 0, 0);
|
|
23708
|
+
/**
|
|
23709
|
+
* Converts provided string to a number.
|
|
23710
|
+
*
|
|
23711
|
+
* @param {number|string} value
|
|
23712
|
+
* @returns {number}
|
|
23713
|
+
*/
|
|
23714
|
+
function toFloat(value) {
|
|
23715
|
+
return parseFloat(value) || 0;
|
|
23716
|
+
}
|
|
23717
|
+
/**
|
|
23718
|
+
* Extracts borders size from provided styles.
|
|
23719
|
+
*
|
|
23720
|
+
* @param {CSSStyleDeclaration} styles
|
|
23721
|
+
* @param {...string} positions - Borders positions (top, right, ...)
|
|
23722
|
+
* @returns {number}
|
|
23723
|
+
*/
|
|
23724
|
+
function getBordersSize(styles) {
|
|
23725
|
+
var positions = [];
|
|
23726
|
+
for (var _i = 1; _i < arguments.length; _i++) {
|
|
23727
|
+
positions[_i - 1] = arguments[_i];
|
|
23728
|
+
}
|
|
23729
|
+
return positions.reduce(function (size, position) {
|
|
23730
|
+
var value = styles['border-' + position + '-width'];
|
|
23731
|
+
return size + toFloat(value);
|
|
23732
|
+
}, 0);
|
|
23733
|
+
}
|
|
23734
|
+
/**
|
|
23735
|
+
* Extracts paddings sizes from provided styles.
|
|
23736
|
+
*
|
|
23737
|
+
* @param {CSSStyleDeclaration} styles
|
|
23738
|
+
* @returns {Object} Paddings box.
|
|
23739
|
+
*/
|
|
23740
|
+
function getPaddings(styles) {
|
|
23741
|
+
var positions = ['top', 'right', 'bottom', 'left'];
|
|
23742
|
+
var paddings = {};
|
|
23743
|
+
for (var _i = 0, positions_1 = positions; _i < positions_1.length; _i++) {
|
|
23744
|
+
var position = positions_1[_i];
|
|
23745
|
+
var value = styles['padding-' + position];
|
|
23746
|
+
paddings[position] = toFloat(value);
|
|
23747
|
+
}
|
|
23748
|
+
return paddings;
|
|
23749
|
+
}
|
|
23750
|
+
/**
|
|
23751
|
+
* Calculates content rectangle of provided SVG element.
|
|
23752
|
+
*
|
|
23753
|
+
* @param {SVGGraphicsElement} target - Element content rectangle of which needs
|
|
23754
|
+
* to be calculated.
|
|
23755
|
+
* @returns {DOMRectInit}
|
|
23756
|
+
*/
|
|
23757
|
+
function getSVGContentRect(target) {
|
|
23758
|
+
var bbox = target.getBBox();
|
|
23759
|
+
return createRectInit(0, 0, bbox.width, bbox.height);
|
|
23760
|
+
}
|
|
23761
|
+
/**
|
|
23762
|
+
* Calculates content rectangle of provided HTMLElement.
|
|
23763
|
+
*
|
|
23764
|
+
* @param {HTMLElement} target - Element for which to calculate the content rectangle.
|
|
23765
|
+
* @returns {DOMRectInit}
|
|
23766
|
+
*/
|
|
23767
|
+
function getHTMLElementContentRect(target) {
|
|
23768
|
+
// Client width & height properties can't be
|
|
23769
|
+
// used exclusively as they provide rounded values.
|
|
23770
|
+
var clientWidth = target.clientWidth, clientHeight = target.clientHeight;
|
|
23771
|
+
// By this condition we can catch all non-replaced inline, hidden and
|
|
23772
|
+
// detached elements. Though elements with width & height properties less
|
|
23773
|
+
// than 0.5 will be discarded as well.
|
|
23774
|
+
//
|
|
23775
|
+
// Without it we would need to implement separate methods for each of
|
|
23776
|
+
// those cases and it's not possible to perform a precise and performance
|
|
23777
|
+
// effective test for hidden elements. E.g. even jQuery's ':visible' filter
|
|
23778
|
+
// gives wrong results for elements with width & height less than 0.5.
|
|
23779
|
+
if (!clientWidth && !clientHeight) {
|
|
23780
|
+
return emptyRect;
|
|
23781
|
+
}
|
|
23782
|
+
var styles = getWindowOf(target).getComputedStyle(target);
|
|
23783
|
+
var paddings = getPaddings(styles);
|
|
23784
|
+
var horizPad = paddings.left + paddings.right;
|
|
23785
|
+
var vertPad = paddings.top + paddings.bottom;
|
|
23786
|
+
// Computed styles of width & height are being used because they are the
|
|
23787
|
+
// only dimensions available to JS that contain non-rounded values. It could
|
|
23788
|
+
// be possible to utilize the getBoundingClientRect if only it's data wasn't
|
|
23789
|
+
// affected by CSS transformations let alone paddings, borders and scroll bars.
|
|
23790
|
+
var width = toFloat(styles.width), height = toFloat(styles.height);
|
|
23791
|
+
// Width & height include paddings and borders when the 'border-box' box
|
|
23792
|
+
// model is applied (except for IE).
|
|
23793
|
+
if (styles.boxSizing === 'border-box') {
|
|
23794
|
+
// Following conditions are required to handle Internet Explorer which
|
|
23795
|
+
// doesn't include paddings and borders to computed CSS dimensions.
|
|
23796
|
+
//
|
|
23797
|
+
// We can say that if CSS dimensions + paddings are equal to the "client"
|
|
23798
|
+
// properties then it's either IE, and thus we don't need to subtract
|
|
23799
|
+
// anything, or an element merely doesn't have paddings/borders styles.
|
|
23800
|
+
if (Math.round(width + horizPad) !== clientWidth) {
|
|
23801
|
+
width -= getBordersSize(styles, 'left', 'right') + horizPad;
|
|
23802
|
+
}
|
|
23803
|
+
if (Math.round(height + vertPad) !== clientHeight) {
|
|
23804
|
+
height -= getBordersSize(styles, 'top', 'bottom') + vertPad;
|
|
23805
|
+
}
|
|
23806
|
+
}
|
|
23807
|
+
// Following steps can't be applied to the document's root element as its
|
|
23808
|
+
// client[Width/Height] properties represent viewport area of the window.
|
|
23809
|
+
// Besides, it's as well not necessary as the <html> itself neither has
|
|
23810
|
+
// rendered scroll bars nor it can be clipped.
|
|
23811
|
+
if (!isDocumentElement(target)) {
|
|
23812
|
+
// In some browsers (only in Firefox, actually) CSS width & height
|
|
23813
|
+
// include scroll bars size which can be removed at this step as scroll
|
|
23814
|
+
// bars are the only difference between rounded dimensions + paddings
|
|
23815
|
+
// and "client" properties, though that is not always true in Chrome.
|
|
23816
|
+
var vertScrollbar = Math.round(width + horizPad) - clientWidth;
|
|
23817
|
+
var horizScrollbar = Math.round(height + vertPad) - clientHeight;
|
|
23818
|
+
// Chrome has a rather weird rounding of "client" properties.
|
|
23819
|
+
// E.g. for an element with content width of 314.2px it sometimes gives
|
|
23820
|
+
// the client width of 315px and for the width of 314.7px it may give
|
|
23821
|
+
// 314px. And it doesn't happen all the time. So just ignore this delta
|
|
23822
|
+
// as a non-relevant.
|
|
23823
|
+
if (Math.abs(vertScrollbar) !== 1) {
|
|
23824
|
+
width -= vertScrollbar;
|
|
23825
|
+
}
|
|
23826
|
+
if (Math.abs(horizScrollbar) !== 1) {
|
|
23827
|
+
height -= horizScrollbar;
|
|
23828
|
+
}
|
|
23829
|
+
}
|
|
23830
|
+
return createRectInit(paddings.left, paddings.top, width, height);
|
|
23831
|
+
}
|
|
23832
|
+
/**
|
|
23833
|
+
* Checks whether provided element is an instance of the SVGGraphicsElement.
|
|
23834
|
+
*
|
|
23835
|
+
* @param {Element} target - Element to be checked.
|
|
23836
|
+
* @returns {boolean}
|
|
23837
|
+
*/
|
|
23838
|
+
var isSVGGraphicsElement = (function () {
|
|
23839
|
+
// Some browsers, namely IE and Edge, don't have the SVGGraphicsElement
|
|
23840
|
+
// interface.
|
|
23841
|
+
if (typeof SVGGraphicsElement !== 'undefined') {
|
|
23842
|
+
return function (target) { return target instanceof getWindowOf(target).SVGGraphicsElement; };
|
|
23843
|
+
}
|
|
23844
|
+
// If it's so, then check that element is at least an instance of the
|
|
23845
|
+
// SVGElement and that it has the "getBBox" method.
|
|
23846
|
+
// eslint-disable-next-line no-extra-parens
|
|
23847
|
+
return function (target) { return (target instanceof getWindowOf(target).SVGElement &&
|
|
23848
|
+
typeof target.getBBox === 'function'); };
|
|
23849
|
+
})();
|
|
23850
|
+
/**
|
|
23851
|
+
* Checks whether provided element is a document element (<html>).
|
|
23852
|
+
*
|
|
23853
|
+
* @param {Element} target - Element to be checked.
|
|
23854
|
+
* @returns {boolean}
|
|
23855
|
+
*/
|
|
23856
|
+
function isDocumentElement(target) {
|
|
23857
|
+
return target === getWindowOf(target).document.documentElement;
|
|
23858
|
+
}
|
|
23859
|
+
/**
|
|
23860
|
+
* Calculates an appropriate content rectangle for provided html or svg element.
|
|
23861
|
+
*
|
|
23862
|
+
* @param {Element} target - Element content rectangle of which needs to be calculated.
|
|
23863
|
+
* @returns {DOMRectInit}
|
|
23864
|
+
*/
|
|
23865
|
+
function getContentRect(target) {
|
|
23866
|
+
if (!isBrowser) {
|
|
23867
|
+
return emptyRect;
|
|
23868
|
+
}
|
|
23869
|
+
if (isSVGGraphicsElement(target)) {
|
|
23870
|
+
return getSVGContentRect(target);
|
|
23871
|
+
}
|
|
23872
|
+
return getHTMLElementContentRect(target);
|
|
23873
|
+
}
|
|
23874
|
+
/**
|
|
23875
|
+
* Creates rectangle with an interface of the DOMRectReadOnly.
|
|
23876
|
+
* Spec: https://drafts.fxtf.org/geometry/#domrectreadonly
|
|
23877
|
+
*
|
|
23878
|
+
* @param {DOMRectInit} rectInit - Object with rectangle's x/y coordinates and dimensions.
|
|
23879
|
+
* @returns {DOMRectReadOnly}
|
|
23880
|
+
*/
|
|
23881
|
+
function createReadOnlyRect(_a) {
|
|
23882
|
+
var x = _a.x, y = _a.y, width = _a.width, height = _a.height;
|
|
23883
|
+
// If DOMRectReadOnly is available use it as a prototype for the rectangle.
|
|
23884
|
+
var Constr = typeof DOMRectReadOnly !== 'undefined' ? DOMRectReadOnly : Object;
|
|
23885
|
+
var rect = Object.create(Constr.prototype);
|
|
23886
|
+
// Rectangle's properties are not writable and non-enumerable.
|
|
23887
|
+
defineConfigurable(rect, {
|
|
23888
|
+
x: x, y: y, width: width, height: height,
|
|
23889
|
+
top: y,
|
|
23890
|
+
right: x + width,
|
|
23891
|
+
bottom: height + y,
|
|
23892
|
+
left: x
|
|
23893
|
+
});
|
|
23894
|
+
return rect;
|
|
23895
|
+
}
|
|
23896
|
+
/**
|
|
23897
|
+
* Creates DOMRectInit object based on the provided dimensions and the x/y coordinates.
|
|
23898
|
+
* Spec: https://drafts.fxtf.org/geometry/#dictdef-domrectinit
|
|
23899
|
+
*
|
|
23900
|
+
* @param {number} x - X coordinate.
|
|
23901
|
+
* @param {number} y - Y coordinate.
|
|
23902
|
+
* @param {number} width - Rectangle's width.
|
|
23903
|
+
* @param {number} height - Rectangle's height.
|
|
23904
|
+
* @returns {DOMRectInit}
|
|
23905
|
+
*/
|
|
23906
|
+
function createRectInit(x, y, width, height) {
|
|
23907
|
+
return { x: x, y: y, width: width, height: height };
|
|
23908
|
+
}
|
|
23909
|
+
|
|
23910
|
+
/**
|
|
23911
|
+
* Class that is responsible for computations of the content rectangle of
|
|
23912
|
+
* provided DOM element and for keeping track of it's changes.
|
|
23913
|
+
*/
|
|
23914
|
+
var ResizeObservation = /** @class */ (function () {
|
|
23915
|
+
/**
|
|
23916
|
+
* Creates an instance of ResizeObservation.
|
|
23917
|
+
*
|
|
23918
|
+
* @param {Element} target - Element to be observed.
|
|
23919
|
+
*/
|
|
23920
|
+
function ResizeObservation(target) {
|
|
23921
|
+
/**
|
|
23922
|
+
* Broadcasted width of content rectangle.
|
|
23923
|
+
*
|
|
23924
|
+
* @type {number}
|
|
23925
|
+
*/
|
|
23926
|
+
this.broadcastWidth = 0;
|
|
23927
|
+
/**
|
|
23928
|
+
* Broadcasted height of content rectangle.
|
|
23929
|
+
*
|
|
23930
|
+
* @type {number}
|
|
23931
|
+
*/
|
|
23932
|
+
this.broadcastHeight = 0;
|
|
23933
|
+
/**
|
|
23934
|
+
* Reference to the last observed content rectangle.
|
|
23935
|
+
*
|
|
23936
|
+
* @private {DOMRectInit}
|
|
23937
|
+
*/
|
|
23938
|
+
this.contentRect_ = createRectInit(0, 0, 0, 0);
|
|
23939
|
+
this.target = target;
|
|
23940
|
+
}
|
|
23941
|
+
/**
|
|
23942
|
+
* Updates content rectangle and tells whether it's width or height properties
|
|
23943
|
+
* have changed since the last broadcast.
|
|
23944
|
+
*
|
|
23945
|
+
* @returns {boolean}
|
|
23946
|
+
*/
|
|
23947
|
+
ResizeObservation.prototype.isActive = function () {
|
|
23948
|
+
var rect = getContentRect(this.target);
|
|
23949
|
+
this.contentRect_ = rect;
|
|
23950
|
+
return (rect.width !== this.broadcastWidth ||
|
|
23951
|
+
rect.height !== this.broadcastHeight);
|
|
23952
|
+
};
|
|
23953
|
+
/**
|
|
23954
|
+
* Updates 'broadcastWidth' and 'broadcastHeight' properties with a data
|
|
23955
|
+
* from the corresponding properties of the last observed content rectangle.
|
|
23956
|
+
*
|
|
23957
|
+
* @returns {DOMRectInit} Last observed content rectangle.
|
|
23958
|
+
*/
|
|
23959
|
+
ResizeObservation.prototype.broadcastRect = function () {
|
|
23960
|
+
var rect = this.contentRect_;
|
|
23961
|
+
this.broadcastWidth = rect.width;
|
|
23962
|
+
this.broadcastHeight = rect.height;
|
|
23963
|
+
return rect;
|
|
23964
|
+
};
|
|
23965
|
+
return ResizeObservation;
|
|
23966
|
+
}());
|
|
23967
|
+
|
|
23968
|
+
var ResizeObserverEntry = /** @class */ (function () {
|
|
23969
|
+
/**
|
|
23970
|
+
* Creates an instance of ResizeObserverEntry.
|
|
23971
|
+
*
|
|
23972
|
+
* @param {Element} target - Element that is being observed.
|
|
23973
|
+
* @param {DOMRectInit} rectInit - Data of the element's content rectangle.
|
|
23974
|
+
*/
|
|
23975
|
+
function ResizeObserverEntry(target, rectInit) {
|
|
23976
|
+
var contentRect = createReadOnlyRect(rectInit);
|
|
23977
|
+
// According to the specification following properties are not writable
|
|
23978
|
+
// and are also not enumerable in the native implementation.
|
|
23979
|
+
//
|
|
23980
|
+
// Property accessors are not being used as they'd require to define a
|
|
23981
|
+
// private WeakMap storage which may cause memory leaks in browsers that
|
|
23982
|
+
// don't support this type of collections.
|
|
23983
|
+
defineConfigurable(this, { target: target, contentRect: contentRect });
|
|
23984
|
+
}
|
|
23985
|
+
return ResizeObserverEntry;
|
|
23986
|
+
}());
|
|
23987
|
+
|
|
23988
|
+
var ResizeObserverSPI = /** @class */ (function () {
|
|
23989
|
+
/**
|
|
23990
|
+
* Creates a new instance of ResizeObserver.
|
|
23991
|
+
*
|
|
23992
|
+
* @param {ResizeObserverCallback} callback - Callback function that is invoked
|
|
23993
|
+
* when one of the observed elements changes it's content dimensions.
|
|
23994
|
+
* @param {ResizeObserverController} controller - Controller instance which
|
|
23995
|
+
* is responsible for the updates of observer.
|
|
23996
|
+
* @param {ResizeObserver} callbackCtx - Reference to the public
|
|
23997
|
+
* ResizeObserver instance which will be passed to callback function.
|
|
23998
|
+
*/
|
|
23999
|
+
function ResizeObserverSPI(callback, controller, callbackCtx) {
|
|
24000
|
+
/**
|
|
24001
|
+
* Collection of resize observations that have detected changes in dimensions
|
|
24002
|
+
* of elements.
|
|
24003
|
+
*
|
|
24004
|
+
* @private {Array<ResizeObservation>}
|
|
24005
|
+
*/
|
|
24006
|
+
this.activeObservations_ = [];
|
|
24007
|
+
/**
|
|
24008
|
+
* Registry of the ResizeObservation instances.
|
|
24009
|
+
*
|
|
24010
|
+
* @private {Map<Element, ResizeObservation>}
|
|
24011
|
+
*/
|
|
24012
|
+
this.observations_ = new MapShim();
|
|
24013
|
+
if (typeof callback !== 'function') {
|
|
24014
|
+
throw new TypeError('The callback provided as parameter 1 is not a function.');
|
|
24015
|
+
}
|
|
24016
|
+
this.callback_ = callback;
|
|
24017
|
+
this.controller_ = controller;
|
|
24018
|
+
this.callbackCtx_ = callbackCtx;
|
|
24019
|
+
}
|
|
24020
|
+
/**
|
|
24021
|
+
* Starts observing provided element.
|
|
24022
|
+
*
|
|
24023
|
+
* @param {Element} target - Element to be observed.
|
|
24024
|
+
* @returns {void}
|
|
24025
|
+
*/
|
|
24026
|
+
ResizeObserverSPI.prototype.observe = function (target) {
|
|
24027
|
+
if (!arguments.length) {
|
|
24028
|
+
throw new TypeError('1 argument required, but only 0 present.');
|
|
24029
|
+
}
|
|
24030
|
+
// Do nothing if current environment doesn't have the Element interface.
|
|
24031
|
+
if (typeof Element === 'undefined' || !(Element instanceof Object)) {
|
|
24032
|
+
return;
|
|
24033
|
+
}
|
|
24034
|
+
if (!(target instanceof getWindowOf(target).Element)) {
|
|
24035
|
+
throw new TypeError('parameter 1 is not of type "Element".');
|
|
24036
|
+
}
|
|
24037
|
+
var observations = this.observations_;
|
|
24038
|
+
// Do nothing if element is already being observed.
|
|
24039
|
+
if (observations.has(target)) {
|
|
24040
|
+
return;
|
|
24041
|
+
}
|
|
24042
|
+
observations.set(target, new ResizeObservation(target));
|
|
24043
|
+
this.controller_.addObserver(this);
|
|
24044
|
+
// Force the update of observations.
|
|
24045
|
+
this.controller_.refresh();
|
|
24046
|
+
};
|
|
24047
|
+
/**
|
|
24048
|
+
* Stops observing provided element.
|
|
24049
|
+
*
|
|
24050
|
+
* @param {Element} target - Element to stop observing.
|
|
24051
|
+
* @returns {void}
|
|
24052
|
+
*/
|
|
24053
|
+
ResizeObserverSPI.prototype.unobserve = function (target) {
|
|
24054
|
+
if (!arguments.length) {
|
|
24055
|
+
throw new TypeError('1 argument required, but only 0 present.');
|
|
24056
|
+
}
|
|
24057
|
+
// Do nothing if current environment doesn't have the Element interface.
|
|
24058
|
+
if (typeof Element === 'undefined' || !(Element instanceof Object)) {
|
|
24059
|
+
return;
|
|
24060
|
+
}
|
|
24061
|
+
if (!(target instanceof getWindowOf(target).Element)) {
|
|
24062
|
+
throw new TypeError('parameter 1 is not of type "Element".');
|
|
24063
|
+
}
|
|
24064
|
+
var observations = this.observations_;
|
|
24065
|
+
// Do nothing if element is not being observed.
|
|
24066
|
+
if (!observations.has(target)) {
|
|
24067
|
+
return;
|
|
24068
|
+
}
|
|
24069
|
+
observations.delete(target);
|
|
24070
|
+
if (!observations.size) {
|
|
24071
|
+
this.controller_.removeObserver(this);
|
|
24072
|
+
}
|
|
24073
|
+
};
|
|
24074
|
+
/**
|
|
24075
|
+
* Stops observing all elements.
|
|
24076
|
+
*
|
|
24077
|
+
* @returns {void}
|
|
24078
|
+
*/
|
|
24079
|
+
ResizeObserverSPI.prototype.disconnect = function () {
|
|
24080
|
+
this.clearActive();
|
|
24081
|
+
this.observations_.clear();
|
|
24082
|
+
this.controller_.removeObserver(this);
|
|
24083
|
+
};
|
|
24084
|
+
/**
|
|
24085
|
+
* Collects observation instances the associated element of which has changed
|
|
24086
|
+
* it's content rectangle.
|
|
24087
|
+
*
|
|
24088
|
+
* @returns {void}
|
|
24089
|
+
*/
|
|
24090
|
+
ResizeObserverSPI.prototype.gatherActive = function () {
|
|
24091
|
+
var _this = this;
|
|
24092
|
+
this.clearActive();
|
|
24093
|
+
this.observations_.forEach(function (observation) {
|
|
24094
|
+
if (observation.isActive()) {
|
|
24095
|
+
_this.activeObservations_.push(observation);
|
|
24096
|
+
}
|
|
24097
|
+
});
|
|
24098
|
+
};
|
|
24099
|
+
/**
|
|
24100
|
+
* Invokes initial callback function with a list of ResizeObserverEntry
|
|
24101
|
+
* instances collected from active resize observations.
|
|
24102
|
+
*
|
|
24103
|
+
* @returns {void}
|
|
24104
|
+
*/
|
|
24105
|
+
ResizeObserverSPI.prototype.broadcastActive = function () {
|
|
24106
|
+
// Do nothing if observer doesn't have active observations.
|
|
24107
|
+
if (!this.hasActive()) {
|
|
24108
|
+
return;
|
|
24109
|
+
}
|
|
24110
|
+
var ctx = this.callbackCtx_;
|
|
24111
|
+
// Create ResizeObserverEntry instance for every active observation.
|
|
24112
|
+
var entries = this.activeObservations_.map(function (observation) {
|
|
24113
|
+
return new ResizeObserverEntry(observation.target, observation.broadcastRect());
|
|
24114
|
+
});
|
|
24115
|
+
this.callback_.call(ctx, entries, ctx);
|
|
24116
|
+
this.clearActive();
|
|
24117
|
+
};
|
|
24118
|
+
/**
|
|
24119
|
+
* Clears the collection of active observations.
|
|
24120
|
+
*
|
|
24121
|
+
* @returns {void}
|
|
24122
|
+
*/
|
|
24123
|
+
ResizeObserverSPI.prototype.clearActive = function () {
|
|
24124
|
+
this.activeObservations_.splice(0);
|
|
24125
|
+
};
|
|
24126
|
+
/**
|
|
24127
|
+
* Tells whether observer has active observations.
|
|
24128
|
+
*
|
|
24129
|
+
* @returns {boolean}
|
|
24130
|
+
*/
|
|
24131
|
+
ResizeObserverSPI.prototype.hasActive = function () {
|
|
24132
|
+
return this.activeObservations_.length > 0;
|
|
24133
|
+
};
|
|
24134
|
+
return ResizeObserverSPI;
|
|
24135
|
+
}());
|
|
24136
|
+
|
|
24137
|
+
// Registry of internal observers. If WeakMap is not available use current shim
|
|
24138
|
+
// for the Map collection as it has all required methods and because WeakMap
|
|
24139
|
+
// can't be fully polyfilled anyway.
|
|
24140
|
+
var observers = typeof WeakMap !== 'undefined' ? new WeakMap() : new MapShim();
|
|
24141
|
+
/**
|
|
24142
|
+
* ResizeObserver API. Encapsulates the ResizeObserver SPI implementation
|
|
24143
|
+
* exposing only those methods and properties that are defined in the spec.
|
|
24144
|
+
*/
|
|
24145
|
+
var ResizeObserver = /** @class */ (function () {
|
|
24146
|
+
/**
|
|
24147
|
+
* Creates a new instance of ResizeObserver.
|
|
24148
|
+
*
|
|
24149
|
+
* @param {ResizeObserverCallback} callback - Callback that is invoked when
|
|
24150
|
+
* dimensions of the observed elements change.
|
|
24151
|
+
*/
|
|
24152
|
+
function ResizeObserver(callback) {
|
|
24153
|
+
if (!(this instanceof ResizeObserver)) {
|
|
24154
|
+
throw new TypeError('Cannot call a class as a function.');
|
|
24155
|
+
}
|
|
24156
|
+
if (!arguments.length) {
|
|
24157
|
+
throw new TypeError('1 argument required, but only 0 present.');
|
|
24158
|
+
}
|
|
24159
|
+
var controller = ResizeObserverController.getInstance();
|
|
24160
|
+
var observer = new ResizeObserverSPI(callback, controller, this);
|
|
24161
|
+
observers.set(this, observer);
|
|
24162
|
+
}
|
|
24163
|
+
return ResizeObserver;
|
|
24164
|
+
}());
|
|
24165
|
+
// Expose public methods of ResizeObserver.
|
|
24166
|
+
[
|
|
24167
|
+
'observe',
|
|
24168
|
+
'unobserve',
|
|
24169
|
+
'disconnect'
|
|
24170
|
+
].forEach(function (method) {
|
|
24171
|
+
ResizeObserver.prototype[method] = function () {
|
|
24172
|
+
var _a;
|
|
24173
|
+
return (_a = observers.get(this))[method].apply(_a, arguments);
|
|
24174
|
+
};
|
|
24175
|
+
});
|
|
24176
|
+
|
|
24177
|
+
var index = (function () {
|
|
24178
|
+
// Export existing implementation if available.
|
|
24179
|
+
if (typeof global$1.ResizeObserver !== 'undefined') {
|
|
24180
|
+
return global$1.ResizeObserver;
|
|
24181
|
+
}
|
|
24182
|
+
return ResizeObserver;
|
|
24183
|
+
})();
|
|
21765
24184
|
|
|
21766
24185
|
var HeadingPopupBody = /** @class */ (function (_super) {
|
|
21767
24186
|
__extends$1(HeadingPopupBody, _super);
|
|
@@ -22022,17 +24441,17 @@ var TablePopupBody = /** @class */ (function (_super) {
|
|
|
22022
24441
|
range.colIdx = Math.min(Math.max(range.colIdx, MIN_COL_SELECTION_INDEX), MAX_COL_INDEX);
|
|
22023
24442
|
return range;
|
|
22024
24443
|
};
|
|
22025
|
-
TablePopupBody.prototype.mounted = function () {
|
|
22026
|
-
var _a = this.refs.tableEl.getBoundingClientRect(), left = _a.left, top = _a.top;
|
|
22027
|
-
this.offsetRect = {
|
|
22028
|
-
left: window.pageXOffset + left,
|
|
22029
|
-
top: window.pageYOffset + top,
|
|
22030
|
-
};
|
|
22031
|
-
};
|
|
22032
24444
|
TablePopupBody.prototype.updated = function () {
|
|
22033
24445
|
if (!this.props.show) {
|
|
22034
24446
|
this.setState({ colIdx: -1, rowIdx: -1 });
|
|
22035
24447
|
}
|
|
24448
|
+
else if (this.state.colIdx === -1 && this.state.rowIdx === -1) {
|
|
24449
|
+
var _a = this.refs.tableEl.getBoundingClientRect(), left = _a.left, top_1 = _a.top;
|
|
24450
|
+
this.offsetRect = {
|
|
24451
|
+
left: window.pageXOffset + left,
|
|
24452
|
+
top: window.pageYOffset + top_1,
|
|
24453
|
+
};
|
|
24454
|
+
}
|
|
22036
24455
|
};
|
|
22037
24456
|
TablePopupBody.prototype.createTableArea = function (tableRange) {
|
|
22038
24457
|
var colIdx = tableRange.colIdx, rowIdx = tableRange.rowIdx;
|
|
@@ -22059,15 +24478,17 @@ var templateObject_1$c, templateObject_2$6, templateObject_3$2, templateObject_4
|
|
|
22059
24478
|
|
|
22060
24479
|
var CustomPopupBody = /** @class */ (function (_super) {
|
|
22061
24480
|
__extends$1(CustomPopupBody, _super);
|
|
22062
|
-
function CustomPopupBody(
|
|
22063
|
-
|
|
22064
|
-
props.eventEmitter.listen('closePopup', _this.props.hidePopup);
|
|
22065
|
-
return _this;
|
|
24481
|
+
function CustomPopupBody() {
|
|
24482
|
+
return _super !== null && _super.apply(this, arguments) || this;
|
|
22066
24483
|
}
|
|
22067
24484
|
CustomPopupBody.prototype.mounted = function () {
|
|
22068
24485
|
// append the custom popup body element
|
|
22069
24486
|
this.refs.el.appendChild(this.props.body);
|
|
22070
24487
|
};
|
|
24488
|
+
CustomPopupBody.prototype.updated = function (prevProps) {
|
|
24489
|
+
// update custom popup element
|
|
24490
|
+
this.refs.el.replaceChild(this.props.body, prevProps.body);
|
|
24491
|
+
};
|
|
22071
24492
|
CustomPopupBody.prototype.render = function () {
|
|
22072
24493
|
var _this = this;
|
|
22073
24494
|
return html(templateObject_1$b || (templateObject_1$b = __makeTemplateObject(["<div ref=", "></div>"], ["<div ref=", "></div>"])), function (el) { return (_this.refs.el = el); });
|
|
@@ -22344,6 +24765,7 @@ var Popup = /** @class */ (function (_super) {
|
|
|
22344
24765
|
}
|
|
22345
24766
|
Popup.prototype.mounted = function () {
|
|
22346
24767
|
document.addEventListener('mousedown', this.handleMousedown);
|
|
24768
|
+
this.props.eventEmitter.listen('closePopup', this.props.hidePopup);
|
|
22347
24769
|
};
|
|
22348
24770
|
Popup.prototype.beforeDestroy = function () {
|
|
22349
24771
|
document.removeEventListener('mousedown', this.handleMousedown);
|
|
@@ -22420,7 +24842,7 @@ function connectHOC(WrappedComponent) {
|
|
|
22420
24842
|
}
|
|
22421
24843
|
var templateObject_1$8;
|
|
22422
24844
|
|
|
22423
|
-
var DEFAULT_WIDTH
|
|
24845
|
+
var DEFAULT_WIDTH = 80;
|
|
22424
24846
|
var ToolbarButtonComp = /** @class */ (function (_super) {
|
|
22425
24847
|
__extends$1(ToolbarButtonComp, _super);
|
|
22426
24848
|
function ToolbarButtonComp() {
|
|
@@ -22429,17 +24851,19 @@ var ToolbarButtonComp = /** @class */ (function (_super) {
|
|
|
22429
24851
|
_this.props.showTooltip(_this.refs.el);
|
|
22430
24852
|
};
|
|
22431
24853
|
_this.execCommand = function () {
|
|
22432
|
-
var _a = _this.props, item = _a.item, execCommand = _a.execCommand, setPopupInfo = _a.setPopupInfo, getBound = _a.getBound;
|
|
24854
|
+
var _a = _this.props, item = _a.item, execCommand = _a.execCommand, setPopupInfo = _a.setPopupInfo, getBound = _a.getBound, eventEmitter = _a.eventEmitter;
|
|
22433
24855
|
var command = item.command, name = item.name, popup = item.popup;
|
|
22434
24856
|
if (command) {
|
|
22435
24857
|
execCommand(command);
|
|
22436
24858
|
}
|
|
22437
24859
|
else {
|
|
22438
24860
|
var popupName = popup ? 'customPopupBody' : name;
|
|
24861
|
+
var initialValues = eventEmitter.emit('query', 'getPopupInitialValues', { popupName: popupName })[0];
|
|
22439
24862
|
var info = createPopupInfo(popupName, {
|
|
22440
24863
|
el: _this.refs.el,
|
|
22441
24864
|
pos: getBound(_this.refs.el),
|
|
22442
24865
|
popup: popup,
|
|
24866
|
+
initialValues: initialValues,
|
|
22443
24867
|
});
|
|
22444
24868
|
if (info) {
|
|
22445
24869
|
setPopupInfo(info);
|
|
@@ -22460,7 +24884,7 @@ var ToolbarButtonComp = /** @class */ (function (_super) {
|
|
|
22460
24884
|
var _a = this.props, setItemWidth = _a.setItemWidth, item = _a.item;
|
|
22461
24885
|
// set width only if it is not a dropdown toolbar
|
|
22462
24886
|
if (setItemWidth) {
|
|
22463
|
-
setItemWidth(item.name, getOuterWidth(this.refs.el) + (item.hidden ? DEFAULT_WIDTH
|
|
24887
|
+
setItemWidth(item.name, getOuterWidth(this.refs.el) + (item.hidden ? DEFAULT_WIDTH : 0));
|
|
22464
24888
|
}
|
|
22465
24889
|
};
|
|
22466
24890
|
ToolbarButtonComp.prototype.render = function () {
|
|
@@ -22601,8 +25025,7 @@ var DropdownToolbarButtonComp = /** @class */ (function (_super) {
|
|
|
22601
25025
|
var DropdownToolbarButton = connectHOC(DropdownToolbarButtonComp);
|
|
22602
25026
|
var templateObject_1$4, templateObject_2$3;
|
|
22603
25027
|
|
|
22604
|
-
var
|
|
22605
|
-
var DEFAULT_WIDTH = 80;
|
|
25028
|
+
var INLINE_PADDING = 50;
|
|
22606
25029
|
var Toolbar = /** @class */ (function (_super) {
|
|
22607
25030
|
__extends$1(Toolbar, _super);
|
|
22608
25031
|
function Toolbar(props) {
|
|
@@ -22660,6 +25083,7 @@ var Toolbar = /** @class */ (function (_super) {
|
|
|
22660
25083
|
activeTab: 'write',
|
|
22661
25084
|
};
|
|
22662
25085
|
_this.tooltipRef = { current: null };
|
|
25086
|
+
_this.resizeObserver = new index(function () { return _this.handleResize(); });
|
|
22663
25087
|
_this.addEvent();
|
|
22664
25088
|
return _this;
|
|
22665
25089
|
}
|
|
@@ -22693,9 +25117,13 @@ var Toolbar = /** @class */ (function (_super) {
|
|
|
22693
25117
|
};
|
|
22694
25118
|
Toolbar.prototype.addEvent = function () {
|
|
22695
25119
|
var _this = this;
|
|
22696
|
-
this.props.eventEmitter
|
|
22697
|
-
this.handleResize = throttle_1(function () {
|
|
22698
|
-
|
|
25120
|
+
var eventEmitter = this.props.eventEmitter;
|
|
25121
|
+
this.handleResize = throttle_1(function () {
|
|
25122
|
+
// reset toolbar items to re-layout toolbar items with each clientWidth
|
|
25123
|
+
_this.setState({ items: _this.initialItems, dropdownItems: [] });
|
|
25124
|
+
_this.setState(_this.classifyToolbarItems());
|
|
25125
|
+
}, 200);
|
|
25126
|
+
eventEmitter.listen('openPopup', this.openPopup);
|
|
22699
25127
|
};
|
|
22700
25128
|
Toolbar.prototype.appendTooltipToRoot = function () {
|
|
22701
25129
|
var tooltip = "<div class=\"" + cls('tooltip') + "\" style=\"display:none\">\n <div class=\"arrow\"></div>\n <span class=\"text\"></span>\n </div>";
|
|
@@ -22704,6 +25132,23 @@ var Toolbar = /** @class */ (function (_super) {
|
|
|
22704
25132
|
Toolbar.prototype.hiddenScrollSync = function () {
|
|
22705
25133
|
return this.props.editorType === 'wysiwyg' || this.props.previewStyle === 'tab';
|
|
22706
25134
|
};
|
|
25135
|
+
Toolbar.prototype.movePrevItemToDropdownToolbar = function (itemIndex, items, group, dropdownGroup) {
|
|
25136
|
+
var moveItem = function (targetGroup) {
|
|
25137
|
+
var item = targetGroup.pop();
|
|
25138
|
+
if (item) {
|
|
25139
|
+
dropdownGroup.push(item);
|
|
25140
|
+
}
|
|
25141
|
+
};
|
|
25142
|
+
if (itemIndex > 1) {
|
|
25143
|
+
moveItem(group);
|
|
25144
|
+
}
|
|
25145
|
+
else {
|
|
25146
|
+
var prevGroup = last$1(items);
|
|
25147
|
+
if (prevGroup) {
|
|
25148
|
+
moveItem(prevGroup);
|
|
25149
|
+
}
|
|
25150
|
+
}
|
|
25151
|
+
};
|
|
22707
25152
|
Toolbar.prototype.classifyToolbarItems = function () {
|
|
22708
25153
|
var _this = this;
|
|
22709
25154
|
var totalWidth = 0;
|
|
@@ -22712,13 +25157,25 @@ var Toolbar = /** @class */ (function (_super) {
|
|
|
22712
25157
|
var dividerWidth = divider ? getOuterWidth(divider) : 0;
|
|
22713
25158
|
var items = [];
|
|
22714
25159
|
var dropdownItems = [];
|
|
22715
|
-
|
|
25160
|
+
var moved = false;
|
|
25161
|
+
this.initialItems.forEach(function (initialGroup, groupIndex) {
|
|
22716
25162
|
var group = [];
|
|
22717
25163
|
var dropdownGroup = [];
|
|
22718
|
-
initialGroup.forEach(function (item) {
|
|
22719
|
-
|
|
22720
|
-
|
|
22721
|
-
|
|
25164
|
+
initialGroup.forEach(function (item, itemIndex) {
|
|
25165
|
+
if (!item.hidden) {
|
|
25166
|
+
totalWidth += _this.itemWidthMap[item.name];
|
|
25167
|
+
if (totalWidth > clientWidth - INLINE_PADDING) {
|
|
25168
|
+
// should move the prev item to dropdown toolbar for placing the more button
|
|
25169
|
+
if (!moved) {
|
|
25170
|
+
_this.movePrevItemToDropdownToolbar(itemIndex, items, group, dropdownGroup);
|
|
25171
|
+
moved = true;
|
|
25172
|
+
}
|
|
25173
|
+
dropdownGroup.push(item);
|
|
25174
|
+
}
|
|
25175
|
+
else {
|
|
25176
|
+
group.push(item);
|
|
25177
|
+
}
|
|
25178
|
+
}
|
|
22722
25179
|
});
|
|
22723
25180
|
if (group.length) {
|
|
22724
25181
|
setGroupState(group);
|
|
@@ -22729,7 +25186,7 @@ var Toolbar = /** @class */ (function (_super) {
|
|
|
22729
25186
|
dropdownItems.push(dropdownGroup);
|
|
22730
25187
|
}
|
|
22731
25188
|
// add divider width
|
|
22732
|
-
if (
|
|
25189
|
+
if (groupIndex < _this.state.items.length - 1) {
|
|
22733
25190
|
totalWidth += dividerWidth;
|
|
22734
25191
|
}
|
|
22735
25192
|
});
|
|
@@ -22737,11 +25194,12 @@ var Toolbar = /** @class */ (function (_super) {
|
|
|
22737
25194
|
};
|
|
22738
25195
|
Toolbar.prototype.mounted = function () {
|
|
22739
25196
|
if (this.props.previewStyle === 'tab') {
|
|
22740
|
-
this.props.eventEmitter.emit('changePreviewTabWrite');
|
|
25197
|
+
this.props.eventEmitter.emit('changePreviewTabWrite', true);
|
|
22741
25198
|
}
|
|
22742
25199
|
// classify toolbar and dropdown toolbar after DOM has been rendered
|
|
22743
25200
|
this.setState(this.classifyToolbarItems());
|
|
22744
25201
|
this.appendTooltipToRoot();
|
|
25202
|
+
this.resizeObserver.observe(this.refs.el);
|
|
22745
25203
|
};
|
|
22746
25204
|
Toolbar.prototype.updated = function (prevProps) {
|
|
22747
25205
|
var _a = this.props, editorType = _a.editorType, previewStyle = _a.previewStyle, eventEmitter = _a.eventEmitter;
|
|
@@ -22760,6 +25218,7 @@ var Toolbar = /** @class */ (function (_super) {
|
|
|
22760
25218
|
};
|
|
22761
25219
|
Toolbar.prototype.beforeDestroy = function () {
|
|
22762
25220
|
window.removeEventListener('resize', this.handleResize);
|
|
25221
|
+
this.resizeObserver.disconnect();
|
|
22763
25222
|
removeNode$1(this.tooltipRef.current);
|
|
22764
25223
|
};
|
|
22765
25224
|
Toolbar.prototype.render = function () {
|
|
@@ -22894,8 +25353,8 @@ var Layout = /** @class */ (function (_super) {
|
|
|
22894
25353
|
var editorTypeClassName = cls(editorType === 'markdown' ? 'md-mode' : 'ww-mode');
|
|
22895
25354
|
var previewClassName = cls('md') + "-" + previewStyle + "-style";
|
|
22896
25355
|
var themeClassName = cls([theme !== 'light', theme + " "]);
|
|
22897
|
-
return html(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n <div\n class=\"", "", "", "\"\n ref=", "\n >\n <", "\n ref=", "\n eventEmitter=", "\n previewStyle=", "\n toolbarItems=", "\n editorType=", "\n />\n <div\n class=\"", " ", "\"\n ref=", "\n >\n <div\n class=\"", " ", "\"\n
|
|
22898
|
-
"\n <", " eventEmitter=", " />\n </div>\n "])), themeClassName, cls('defaultUI'), displayClassName, function (el) { return (_this.refs.el = el); }, Toolbar, function (toolbar) { return (_this.toolbar = toolbar); }, eventEmitter, previewStyle, toolbarItems, editorType, cls('main'), editorTypeClassName, function (el) { return (_this.refs.editorSection = el); }, cls('md-container'), previewClassName, function (el) { return (_this.refs.mdContainer = el); }, cls('md-splitter'), cls('ww-container'), function (el) { return (_this.refs.wwContainer = el); }, !hideModeSwitch && html(templateObject_1$1 || (templateObject_1$1 = __makeTemplateObject(["<", " eventEmitter=", " editorType=", " />"], ["<", " eventEmitter=", " editorType=", " />"])), Switch, eventEmitter, editorType), ContextMenu, eventEmitter);
|
|
25356
|
+
return html(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n <div\n class=\"", "", "", "\"\n ref=", "\n >\n <", "\n ref=", "\n eventEmitter=", "\n previewStyle=", "\n toolbarItems=", "\n editorType=", "\n />\n <div\n class=\"", " ", "\"\n ref=", "\n >\n <div class=\"", "\">\n <div\n class=\"", " ", "\"\n ref=", "\n >\n <div class=\"", "\"></div>\n </div>\n <div\n class=\"", "\"\n ref=", "\n />\n </div>\n </div>\n ", "\n <", " eventEmitter=", " />\n </div>\n "], ["\n <div\n class=\"", "", "", "\"\n ref=", "\n >\n <", "\n ref=", "\n eventEmitter=", "\n previewStyle=", "\n toolbarItems=", "\n editorType=", "\n />\n <div\n class=\"", " ", "\"\n ref=", "\n >\n <div class=\"", "\">\n <div\n class=\"", " ", "\"\n ref=", "\n >\n <div class=\"", "\"></div>\n </div>\n <div\n class=\"", "\"\n ref=", "\n />\n </div>\n </div>\n ",
|
|
25357
|
+
"\n <", " eventEmitter=", " />\n </div>\n "])), themeClassName, cls('defaultUI'), displayClassName, function (el) { return (_this.refs.el = el); }, Toolbar, function (toolbar) { return (_this.toolbar = toolbar); }, eventEmitter, previewStyle, toolbarItems, editorType, cls('main'), editorTypeClassName, function (el) { return (_this.refs.editorSection = el); }, cls('main-container'), cls('md-container'), previewClassName, function (el) { return (_this.refs.mdContainer = el); }, cls('md-splitter'), cls('ww-container'), function (el) { return (_this.refs.wwContainer = el); }, !hideModeSwitch && html(templateObject_1$1 || (templateObject_1$1 = __makeTemplateObject(["<", " eventEmitter=", " editorType=", " />"], ["<", " eventEmitter=", " editorType=", " />"])), Switch, eventEmitter, editorType), ContextMenu, eventEmitter);
|
|
22899
25358
|
};
|
|
22900
25359
|
Layout.prototype.addEvent = function () {
|
|
22901
25360
|
var eventEmitter = this.props.eventEmitter;
|