@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.
Files changed (57) hide show
  1. package/README.md +4 -4
  2. package/dist/esm/i18n/ar.js +7 -0
  3. package/dist/esm/i18n/cs-cz.js +7 -0
  4. package/dist/esm/i18n/de-de.js +7 -0
  5. package/dist/esm/i18n/en-us.js +7 -0
  6. package/dist/esm/i18n/es-es.js +7 -0
  7. package/dist/esm/i18n/fi-fi.js +7 -0
  8. package/dist/esm/i18n/fr-fr.js +7 -0
  9. package/dist/esm/i18n/gl-es.js +7 -0
  10. package/dist/esm/i18n/hr-hr.js +7 -0
  11. package/dist/esm/i18n/i18n.js +15 -4
  12. package/dist/esm/i18n/it-it.js +7 -0
  13. package/dist/esm/i18n/ja-jp.js +7 -0
  14. package/dist/esm/i18n/ko-kr.js +7 -0
  15. package/dist/esm/i18n/nb-no.js +7 -0
  16. package/dist/esm/i18n/nl-nl.js +7 -0
  17. package/dist/esm/i18n/pl-pl.js +7 -0
  18. package/dist/esm/i18n/pt-br.js +7 -0
  19. package/dist/esm/i18n/ru-ru.js +7 -0
  20. package/dist/esm/i18n/sv-se.js +7 -0
  21. package/dist/esm/i18n/tr-tr.js +7 -0
  22. package/dist/esm/i18n/uk-ua.js +7 -0
  23. package/dist/esm/i18n/zh-cn.js +7 -0
  24. package/dist/esm/i18n/zh-tw.js +7 -0
  25. package/dist/esm/index.js +2885 -426
  26. package/dist/esm/indexViewer.js +1672 -297
  27. package/dist/i18n/ar.js +1 -1
  28. package/dist/i18n/cs-cz.js +1 -1
  29. package/dist/i18n/de-de.js +1 -1
  30. package/dist/i18n/es-es.js +1 -1
  31. package/dist/i18n/fi-fi.js +1 -1
  32. package/dist/i18n/fr-fr.js +1 -1
  33. package/dist/i18n/gl-es.js +1 -1
  34. package/dist/i18n/hr-hr.js +1 -1
  35. package/dist/i18n/it-it.js +1 -1
  36. package/dist/i18n/ja-jp.js +1 -1
  37. package/dist/i18n/ko-kr.js +1 -1
  38. package/dist/i18n/nb-no.js +1 -1
  39. package/dist/i18n/nl-nl.js +1 -1
  40. package/dist/i18n/pl-pl.js +1 -1
  41. package/dist/i18n/pt-br.js +1 -1
  42. package/dist/i18n/ru-ru.js +1 -1
  43. package/dist/i18n/sv-se.js +1 -1
  44. package/dist/i18n/tr-tr.js +1 -1
  45. package/dist/i18n/uk-ua.js +1 -1
  46. package/dist/i18n/zh-cn.js +1 -1
  47. package/dist/i18n/zh-tw.js +1 -1
  48. package/dist/toastui-editor-only.css +22 -16
  49. package/dist/toastui-editor-viewer.css +10 -2
  50. package/dist/toastui-editor-viewer.js +1823 -370
  51. package/dist/toastui-editor.css +31 -17
  52. package/dist/toastui-editor.js +2853 -318
  53. package/package.json +5 -1
  54. package/types/editor.d.ts +6 -4
  55. package/types/event.d.ts +1 -0
  56. package/types/index.d.ts +4 -3
  57. 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, il = from.length, j = to.length; i < il; i++, j++)
54
- to[j] = from[i];
55
- return to;
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
- * var forEachOwnProperties = require('tui-code-snippet/collection/forEachOwnProperties'); // node, commonjs
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
- * var sum = 0;
97
+ * let sum = 0;
83
98
  *
84
99
  * forEachOwnProperties({a:1,b:2,c:3}, function(value){
85
- * sum += value;
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
- * var forEachArray = require('tui-code-snippet/collection/forEachArray'); // node, commonjs
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
- * var sum = 0;
214
+ * let sum = 0;
196
215
  *
197
216
  * forEachArray([1,2,3], function(value){
198
- * sum += value;
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
- * var forEach = require('tui-code-snippet/collection/forEach'); // node, commonjs
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
- * var sum = 0;
268
+ * let sum = 0;
246
269
  *
247
270
  * forEach([1,2,3], function(value){
248
- * sum += value;
271
+ * sum += value;
249
272
  * });
250
273
  * alert(sum); // 6
251
274
  *
252
275
  * // In case of Array-like object
253
- * var array = Array.prototype.slice.call(arrayLike); // change to array
276
+ * const array = Array.prototype.slice.call(arrayLike); // change to array
254
277
  * forEach(array, function(value){
255
- * sum += value;
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
- * var inArray = require('tui-code-snippet/array/inArray'); // node, commonjs
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
- * var arr = ['one', 'two', 'three', 'four'];
321
- * var idx1 = inArray('one', arr, 3); // -1
322
- * var idx2 = inArray('one', arr); // 0
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
- * var imagePing = require('tui-code-snippet/request/imagePing'); // node, commonjs
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
- * v: 1,
576
- * t: 'event',
577
- * tid: 'trackingid',
578
- * cid: 'cid',
579
- * dp: 'dp',
580
- * dh: 'dh'
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 '&amp;';
712
+ case '<':
713
+ return '&lt;';
714
+ case '>':
715
+ return '&gt;';
716
+ case '"':
717
+ return '&quot;';
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
- * var toArray = require('tui-code-snippet/collection/toArray'); // node, commonjs
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
- * var arrayLike = {
1240
- * 0: 'one',
1241
- * 1: 'two',
1242
- * 2: 'three',
1243
- * 3: 'four',
1244
- * length: 4
1296
+ * const arrayLike = {
1297
+ * 0: 'one',
1298
+ * 1: 'two',
1299
+ * 2: 'three',
1300
+ * 3: 'four',
1301
+ * length: 4
1245
1302
  * };
1246
- * var result = toArray(arrayLike);
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
- this.focus();
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
- this.focus();
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.setAttribute(attrName, attributes[attrName]);
1892
+ if (isNil(attributes[attrName])) {
1893
+ element.removeAttribute(attrName);
1847
1894
  }
1848
1895
  else {
1849
- element.removeAttribute(attrName);
1896
+ element.setAttribute(attrName, attributes[attrName]);
1850
1897
  }
1851
1898
  });
1852
1899
  }
1853
1900
  function replaceBRWithEmptyBlock(html) {
1854
- var reBr = /<br\s*\/*>/i;
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 = html.match(reHTMLTag);
1904
+ var htmlTagMatched = replacedHTML.match(reHTMLTag);
1857
1905
  htmlTagMatched === null || htmlTagMatched === void 0 ? void 0 : htmlTagMatched.forEach(function (htmlTag, index) {
1858
- if (reBr.test(htmlTag)) {
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
- html = html.replace(reBr, alternativeTag);
1916
+ replacedHTML = replacedHTML.replace(reBR, alternativeTag);
1869
1917
  }
1870
1918
  });
1871
- return html;
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, 2), addOffsetPos(start, syntaxLength + info.length), META));
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
- return type === 'codeBlock' || type === 'heading' || type.indexOf('table') !== -1;
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
- _this.eventEmitter.listen('changePreviewTabWrite', function () { return _this.toggleActive(true); });
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
- this.focus();
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
- * var div = document.querySelector('div');
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
- * var name = 'global';
4506
- * var repository = {name: 'CodeSnippet'};
4560
+ * const name = 'global';
4561
+ * const repository = {name: 'CodeSnippet'};
4507
4562
  * on(div, 'drag', function() {
4508
- * console.log(this.name);
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, il = from.length, j = to.length; i < il; i++, j++)
4627
- to[j] = from[i];
4628
- return to;
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 info = node.info.trim().toLowerCase();
13253
- var customConvertor = convertors[info];
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
- return customConvertor(node, context);
13256
- }
13257
- return {
13258
- type: context.entering ? 'openTag' : 'closeTag',
13259
- tagName: 'span',
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
- var reHTMLAttr = new RegExp('^(abbr|align|alt|axis|bgcolor|border|cellpadding|cellspacing|class|clear|' +
13572
- 'color|cols|compact|coords|dir|face|headers|height|hreflang|hspace|' +
13573
- 'ismap|lang|language|nohref|nowrap|rel|rev|rows|rules|' +
13574
- 'scope|scrolling|shape|size|span|start|summary|tabindex|target|title|type|' +
13575
- 'valign|value|vspace|width|checked|mathvariant|encoding|id|name|' +
13576
- 'background|cite|href|longdesc|src|usemap|xlink:href|data-+|checked|style)', 'g');
13577
- var reSvgAttr = new RegExp('^(accent-height|accumulate|additive|alphabetic|arabic-form|ascent|' +
13578
- 'baseProfile|bbox|begin|by|calcMode|cap-height|class|color|color-rendering|content|' +
13579
- 'cx|cy|d|dx|dy|descent|display|dur|end|fill|fill-rule|font-family|font-size|font-stretch|' +
13580
- 'font-style|font-variant|font-weight|from|fx|fy|g1|g2|glyph-name|gradientUnits|hanging|' +
13581
- 'height|horiz-adv-x|horiz-origin-x|ideographic|k|keyPoints|keySplines|keyTimes|lang|' +
13582
- 'marker-end|marker-mid|marker-start|markerHeight|markerUnits|markerWidth|mathematical|' +
13583
- 'max|min|offset|opacity|orient|origin|overline-position|overline-thickness|panose-1|' +
13584
- 'path|pathLength|points|preserveAspectRatio|r|refX|refY|repeatCount|repeatDur|' +
13585
- 'requiredExtensions|requiredFeatures|restart|rotate|rx|ry|slope|stemh|stemv|stop-color|' +
13586
- 'stop-opacity|strikethrough-position|strikethrough-thickness|stroke|stroke-dasharray|' +
13587
- 'stroke-dashoffset|stroke-linecap|stroke-linejoin|stroke-miterlimit|stroke-opacity|' +
13588
- 'stroke-width|systemLanguage|target|text-anchor|to|transform|type|u1|u2|underline-position|' +
13589
- 'underline-thickness|unicode|unicode-range|units-per-em|values|version|viewBox|visibility|' +
13590
- 'width|widths|x|x-height|x1|x2|xlink:actuate|xlink:arcrole|xlink:role|xlink:show|xlink:title|' +
13591
- 'xlink:type|xml:base|xml:lang|xml:space|xmlns|xmlns:xlink|y|y1|y2|zoomAndPan)', 'g');
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
- function isXSSAttribute(attrName, attrValue) {
13643
- return attrName.match(reXSSAttr) && attrValue.replace(reWhitespace, '').match(reXSSAttrValue);
13668
+
13669
+ if (!freeze) {
13670
+ freeze = function freeze(x) {
13671
+ return x;
13672
+ };
13644
13673
  }
13645
- function removeBlacklistAttributes(node, blacklistAttrs) {
13646
- blacklistAttrs.forEach(function (_a) {
13647
- var name = _a.name;
13648
- if (reOnEvent.test(name)) {
13649
- node[name] = null;
13650
- }
13651
- node.removeAttribute(name);
13652
- });
13674
+
13675
+ if (!seal) {
13676
+ seal = function seal(x) {
13677
+ return x;
13678
+ };
13653
13679
  }
13654
- function leaveOnlyWhitelistAttribute(html) {
13655
- findNodes(html, '*').forEach(function (node) {
13656
- var attributes = node.attributes;
13657
- var blacklist = toArray_1(attributes).filter(function (attr) {
13658
- var name = attr.name, value = attr.value;
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
- function sanitizeXSSAttributeValue(attrValue) {
13668
- attrValue = attrValue.replace(reComment, '');
13669
- return reXSSAttrValue.test(attrValue) ? '' : attrValue;
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 getChildrenHTML(node, typeName) {
13673
- return node
13674
- .literal.replace(new RegExp("(<\\s*" + typeName + "[^>]+?>)|(</" + typeName + "\\s*[>])", 'ig'), '')
13675
- .trim();
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
- function getHTMLAttrsByHTMLString(html) {
13678
- html = html.match(reHTMLTag)[0];
13679
- var attrs = html.match(new RegExp(ATTRIBUTE$1, 'g'));
13680
- return attrs
13681
- ? attrs.reduce(function (acc, attr) {
13682
- var _a = attr.trim().split('='), name = _a[0], values = _a.slice(1);
13683
- if (values.length) {
13684
- acc[name] = values.join('=').replace(/'|"/g, '').trim();
13685
- }
13686
- return acc;
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
- function getHTMLAttrs(dom) {
13691
- return toArray_1(dom.attributes).reduce(function (acc, attr) {
13692
- acc[attr.nodeName] = attr.nodeValue;
13693
- return acc;
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
- function sanitizeDOM(node, typeName, sanitizer, wwToDOMAdaptor) {
13697
- var dom = wwToDOMAdaptor.getToDOMNode(typeName)(node);
13698
- var html = sanitizer(dom.outerHTML);
13699
- var container = document.createElement('div');
13700
- container.innerHTML = html;
13701
- dom = container.firstChild;
13702
- var htmlAttrs = getHTMLAttrs(dom);
13703
- return { dom: dom, htmlAttrs: htmlAttrs };
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
- var schemaFactory = {
13706
- htmlBlock: function (typeName, sanitizeHTML, wwToDOMAdaptor) {
13707
- return {
13708
- atom: true,
13709
- content: 'block+',
13710
- group: 'block',
13711
- attrs: {
13712
- htmlAttrs: { default: {} },
13713
- childrenHTML: { default: '' },
13714
- htmlBlock: { default: true },
13715
- },
13716
- parseDOM: [
13717
- {
13718
- tag: typeName,
13719
- getAttrs: function (dom) {
13720
- return {
13721
- htmlAttrs: getHTMLAttrs(dom),
13722
- childrenHTML: dom.innerHTML,
13723
- };
13724
- },
13725
- },
13726
- ],
13727
- toDOM: function (node) {
13728
- var _a = sanitizeDOM(node, typeName, sanitizeHTML, wwToDOMAdaptor), dom = _a.dom, htmlAttrs = _a.htmlAttrs;
13729
- htmlAttrs.class = htmlAttrs.class ? htmlAttrs.class + " html-block" : 'html-block';
13730
- return __spreadArray$1([typeName, htmlAttrs], toArray_1(dom.childNodes));
13731
- },
13732
- };
13733
- },
13734
- htmlInline: function (typeName, sanitizeHTML, wwToDOMAdaptor) {
13735
- return {
13736
- attrs: {
13737
- htmlAttrs: { default: {} },
13738
- htmlInline: { default: true },
13739
- },
13740
- parseDOM: [
13741
- {
13742
- tag: typeName,
13743
- getAttrs: function (dom) {
13744
- return {
13745
- htmlAttrs: getHTMLAttrs(dom),
13746
- };
13747
- },
13748
- },
13749
- ],
13750
- toDOM: function (node) {
13751
- var htmlAttrs = sanitizeDOM(node, typeName, sanitizeHTML, wwToDOMAdaptor).htmlAttrs;
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
- function createHTMLSchemaMap(convertorMap, sanitizeHTML, wwToDOMAdaptor) {
13758
- var htmlSchemaMap = { nodes: {}, marks: {} };
13759
- ['htmlBlock', 'htmlInline'].forEach(function (htmlType) {
13760
- if (convertorMap[htmlType]) {
13761
- Object.keys(convertorMap[htmlType]).forEach(function (type) {
13762
- var targetType = htmlType === 'htmlBlock' ? 'nodes' : 'marks';
13763
- // register tag white list for preventing to remove the html in sanitizer
13764
- registerTagWhitelistIfPossible(type);
13765
- htmlSchemaMap[targetType][type] = schemaFactory[htmlType](type, sanitizeHTML, wwToDOMAdaptor);
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
- return htmlSchemaMap;
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
- var reCloseTag = /^\s*<\s*\//;
13773
- var baseConvertors = {
13774
- paragraph: function (_, _a) {
13775
- var entering = _a.entering, origin = _a.origin, options = _a.options;
13776
- if (options.nodeId) {
13777
- return {
13778
- type: entering ? 'openTag' : 'closeTag',
13779
- outerNewLine: true,
13780
- tagName: 'p',
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
- this.el.appendChild(this.previewContent);
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.forEach(function (node) {
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), 0, 0);
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 listGroup',
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
- return setBlockType(state.schema.nodes.heading, payload)(state, dispatch);
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 listGroup',
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 listGroup',
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 listGroup*',
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 imageUrl = dom.getAttribute('src') || '';
17435
- var rawHTML = dom.getAttribute('data-raw-html');
17436
- return __assign$1({ imageUrl: sanitizeXSSAttributeValue(imageUrl), altText: dom.getAttribute('alt') }, (rawHTML && { rawHTML: rawHTML }));
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: encodeMarkdownText(imageUrl) }, (altText && { altText: altText })));
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 href = dom.getAttribute('href') || '';
17711
- var rawHTML = dom.getAttribute('data-raw-html');
17712
- return __assign$1({ linkUrl: sanitizeXSSAttributeValue(href), linkText: dom.textContent }, (rawHTML && { rawHTML: rawHTML }));
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: encodeMarkdownText(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) { return changePastedSlice(slice, _this.schema); },
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 && clipboardData.items;
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
- * var isExisty = require('tui-code-snippet/type/isExisty'); // node, commonjs
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, attrName) {
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: sanitizeXSSAttributeValue(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
- var imageUrl = getMatchedAttributeValue(tag, 'src');
18576
- if (imageUrl) {
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: sanitizeXSSAttributeValue(imageUrl) }, (altText && { altText: altText })));
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
- if (prev && !(prev.type === 'htmlInline' && prev.literal.match(CLOSE_TAG))) {
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
- if (next) {
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' && /<br ?\/?>/.test(node.literal);
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
- if (!node.ignored) {
18843
- var hasParaNode = function (childNode) {
18844
- return childNode && (isInlineNode(childNode) || isCustomHTMLInlineNode(state, childNode));
18845
- };
18846
- if (entering) {
18847
- var _b = state.schema.nodes, tableHeadCell = _b.tableHeadCell, tableBodyCell = _b.tableBodyCell, paragraph = _b.paragraph;
18848
- var tablePart = node.parent.parent;
18849
- var cell = tablePart.type === 'tableHead' ? tableHeadCell : tableBodyCell;
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 align = table.columns[node.startIdx].align;
18852
- var attrs = __assign$1({}, node.attrs);
18853
- if (align) {
18854
- attrs.align = align;
18855
- }
18856
- state.openNode(cell, attrs);
18857
- if (hasParaNode(node.firstChild)) {
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
- else {
18862
- if (hasParaNode(node.lastChild)) {
18863
- state.closeNode();
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(html);
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(html);
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 = html;
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 = escape$1(attrs.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 = escape$1(attrs.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
- openTag += " " + attrName + "=\"" + attrs[attrName] + "\"";
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.el, 'mousedown', this.toggleTask.bind(this));
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.initialHtml = options.el.innerHTML;
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.initialHtml, false);
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
- this.getCurrentModeEditor().moveCursorToEnd();
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
- this.getCurrentModeEditor().moveCursorToStart();
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.isWysiwygMode()) {
20828
- _this.mdEditor.setMarkdown(_this.convertor.toMarkdownText(_this.wwEditor.getModel()));
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
- var mdNode = this.toastMark.getRootNode();
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
- * var debounce = require('tui-code-snippet/tricks/debounce'); // node, commonjs
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
- * var debounced = debounce(someMethodToInvokeDebounced, 300);
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
- * var throttle = require('tui-code-snippet/tricks/throttle'); // node, commonjs
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
- * var throttled = throttle(someMethodToInvokeThrottled, 300);
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(props) {
22063
- var _this = _super.call(this, props) || this;
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$1 = 80;
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$1 : 0));
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 DROPDOWN_WIDTH = 120;
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.listen('openPopup', this.openPopup);
22697
- this.handleResize = throttle_1(function () { return _this.setState(_this.classifyToolbarItems()); }, 200);
22698
- window.addEventListener('resize', this.handleResize);
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
- this.initialItems.forEach(function (initialGroup, index) {
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
- totalWidth += _this.itemWidthMap[item.name] || DEFAULT_WIDTH;
22720
- var target = totalWidth >= clientWidth - DROPDOWN_WIDTH ? dropdownGroup : group;
22721
- target.push(item);
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 (index < _this.state.items.length - 1) {
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 ref=", "\n >\n <div class=\"", "\"></div>\n </div>\n <div\n class=\"", "\"\n ref=", "\n />\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\n class=\"", " ", "\"\n ref=", "\n >\n <div class=\"", "\"></div>\n </div>\n <div\n class=\"", "\"\n ref=", "\n />\n </div>\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;