@toast-ui/editor 3.0.3 → 3.1.3

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 (60) hide show
  1. package/README.md +4 -4
  2. package/dist/esm/i18n/ar.js +1 -1
  3. package/dist/esm/i18n/cs-cz.js +1 -1
  4. package/dist/esm/i18n/de-de.js +1 -1
  5. package/dist/esm/i18n/en-us.js +1 -1
  6. package/dist/esm/i18n/es-es.js +1 -1
  7. package/dist/esm/i18n/fi-fi.js +1 -1
  8. package/dist/esm/i18n/fr-fr.js +1 -1
  9. package/dist/esm/i18n/gl-es.js +1 -1
  10. package/dist/esm/i18n/hr-hr.js +1 -1
  11. package/dist/esm/i18n/i18n.js +10 -7
  12. package/dist/esm/i18n/it-it.js +1 -1
  13. package/dist/esm/i18n/ja-jp.js +1 -1
  14. package/dist/esm/i18n/ko-kr.js +1 -1
  15. package/dist/esm/i18n/nb-no.js +1 -1
  16. package/dist/esm/i18n/nl-nl.js +1 -1
  17. package/dist/esm/i18n/pl-pl.js +1 -1
  18. package/dist/esm/i18n/pt-br.js +1 -1
  19. package/dist/esm/i18n/ru-ru.js +1 -1
  20. package/dist/esm/i18n/sv-se.js +1 -1
  21. package/dist/esm/i18n/tr-tr.js +1 -1
  22. package/dist/esm/i18n/uk-ua.js +1 -1
  23. package/dist/esm/i18n/zh-cn.js +1 -1
  24. package/dist/esm/i18n/zh-tw.js +1 -1
  25. package/dist/esm/index.js +2587 -887
  26. package/dist/esm/indexViewer.js +1674 -306
  27. package/dist/i18n/ar.js +5 -5
  28. package/dist/i18n/cs-cz.js +5 -5
  29. package/dist/i18n/de-de.js +5 -5
  30. package/dist/i18n/es-es.js +5 -5
  31. package/dist/i18n/fi-fi.js +5 -5
  32. package/dist/i18n/fr-fr.js +5 -5
  33. package/dist/i18n/gl-es.js +5 -5
  34. package/dist/i18n/hr-hr.js +5 -5
  35. package/dist/i18n/it-it.js +5 -5
  36. package/dist/i18n/ja-jp.js +5 -5
  37. package/dist/i18n/ko-kr.js +5 -5
  38. package/dist/i18n/nb-no.js +5 -5
  39. package/dist/i18n/nl-nl.js +5 -5
  40. package/dist/i18n/pl-pl.js +5 -5
  41. package/dist/i18n/pt-br.js +5 -5
  42. package/dist/i18n/ru-ru.js +5 -5
  43. package/dist/i18n/sv-se.js +5 -5
  44. package/dist/i18n/tr-tr.js +5 -5
  45. package/dist/i18n/uk-ua.js +5 -5
  46. package/dist/i18n/zh-cn.js +5 -5
  47. package/dist/i18n/zh-tw.js +5 -5
  48. package/dist/toastui-editor-only.css +1 -1
  49. package/dist/toastui-editor-viewer.css +6 -6
  50. package/dist/toastui-editor-viewer.js +1855 -395
  51. package/dist/toastui-editor.css +6 -6
  52. package/dist/toastui-editor.js +2486 -704
  53. package/package.json +5 -1
  54. package/types/editor.d.ts +6 -4
  55. package/types/event.d.ts +2 -0
  56. package/types/index.d.ts +4 -3
  57. package/types/spec.d.ts +1 -1
  58. package/types/toastui-editor-viewer.d.ts +39 -0
  59. package/types/ui.d.ts +22 -20
  60. package/types/wysiwyg.d.ts +2 -1
package/dist/esm/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @toast-ui/editor
3
- * @version 3.0.3 | Tue Aug 17 2021
3
+ * @version 3.1.3 | Thu Feb 10 2022
4
4
  * @author NHN FE Development Lab <dl_javascript@nhn.com>
5
5
  * @license MIT
6
6
  */
@@ -56,10 +56,14 @@ var __assign$1 = function() {
56
56
  return __assign$1.apply(this, arguments);
57
57
  };
58
58
 
59
- function __spreadArray$1(to, from) {
60
- for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
61
- to[j] = from[i];
62
- 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));
63
67
  }
64
68
 
65
69
  function __makeTemplateObject(cooked, raw) {
@@ -84,12 +88,16 @@ function __makeTemplateObject(cooked, raw) {
84
88
  * @param {Object} [context] Context(this) of callback function
85
89
  * @memberof module:collection
86
90
  * @example
87
- * 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');
88
96
  *
89
- * var sum = 0;
97
+ * let sum = 0;
90
98
  *
91
99
  * forEachOwnProperties({a:1,b:2,c:3}, function(value){
92
- * sum += value;
100
+ * sum += value;
93
101
  * });
94
102
  * alert(sum); // 6
95
103
  */
@@ -197,12 +205,16 @@ var isArray_1 = isArray$3;
197
205
  * @param {Object} [context] Context(this) of callback function
198
206
  * @memberof module:collection
199
207
  * @example
200
- * 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');
201
213
  *
202
- * var sum = 0;
214
+ * let sum = 0;
203
215
  *
204
216
  * forEachArray([1,2,3], function(value){
205
- * sum += value;
217
+ * sum += value;
206
218
  * });
207
219
  * alert(sum); // 6
208
220
  */
@@ -247,19 +259,23 @@ var forEachOwnProperties$1 = forEachOwnProperties_1;
247
259
  * @param {Object} [context] Context(this) of callback function
248
260
  * @memberof module:collection
249
261
  * @example
250
- * 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');
251
267
  *
252
- * var sum = 0;
268
+ * let sum = 0;
253
269
  *
254
270
  * forEach([1,2,3], function(value){
255
- * sum += value;
271
+ * sum += value;
256
272
  * });
257
273
  * alert(sum); // 6
258
274
  *
259
275
  * // In case of Array-like object
260
- * var array = Array.prototype.slice.call(arrayLike); // change to array
276
+ * const array = Array.prototype.slice.call(arrayLike); // change to array
261
277
  * forEach(array, function(value){
262
- * sum += value;
278
+ * sum += value;
263
279
  * });
264
280
  */
265
281
  function forEach$4(obj, iteratee, context) {
@@ -322,11 +338,15 @@ var isArray$1 = isArray_1;
322
338
  * @returns {number} the First index at which a given element, or -1 if it is not present
323
339
  * @memberof module:array
324
340
  * @example
325
- * 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');
326
346
  *
327
- * var arr = ['one', 'two', 'three', 'four'];
328
- * var idx1 = inArray('one', arr, 3); // -1
329
- * 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
330
350
  */
331
351
  function inArray$4(searchElement, array, startIndex) {
332
352
  var i;
@@ -576,15 +596,19 @@ var forEachOwnProperties = forEachOwnProperties_1;
576
596
  * @returns {HTMLElement}
577
597
  * @memberof module:request
578
598
  * @example
579
- * 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');
580
604
  *
581
605
  * imagePing('https://www.google-analytics.com/collect', {
582
- * v: 1,
583
- * t: 'event',
584
- * tid: 'trackingid',
585
- * cid: 'cid',
586
- * dp: 'dp',
587
- * dh: 'dh'
606
+ * v: 1,
607
+ * t: 'event',
608
+ * tid: 'trackingid',
609
+ * cid: 'cid',
610
+ * dp: 'dp',
611
+ * dh: 'dh'
588
612
  * });
589
613
  */
590
614
  function imagePing$1(url, trackingInfo) {
@@ -679,6 +703,30 @@ var reEscapeChars$1 = /[>(){}[\]+-.!#|]/g;
679
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;
680
704
  var reEscapeBackSlash = /\\[!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~\\]/g;
681
705
  var reEscapePairedChars = /[*_~`]/g;
706
+ var reMdImageSyntax = /!\[.*\]\(.*\)/g;
707
+ var reEscapedCharInLinkSyntax = /[[\]]/g; //
708
+ var XMLSPECIAL$1 = '[&<>"]';
709
+ var reXmlSpecial$1 = new RegExp(XMLSPECIAL$1, 'g');
710
+ function replaceUnsafeChar$1(char) {
711
+ switch (char) {
712
+ case '&':
713
+ return '&amp;';
714
+ case '<':
715
+ return '&lt;';
716
+ case '>':
717
+ return '&gt;';
718
+ case '"':
719
+ return '&quot;';
720
+ default:
721
+ return char;
722
+ }
723
+ }
724
+ function escapeXml$1(text) {
725
+ if (reXmlSpecial$1.test(text)) {
726
+ return text.replace(reXmlSpecial$1, replaceUnsafeChar$1);
727
+ }
728
+ return text;
729
+ }
682
730
  function sendHostName() {
683
731
  sendHostname_1('editor', 'UA-129966929-1');
684
732
  }
@@ -728,6 +776,18 @@ function isNeedEscapeText(text) {
728
776
  });
729
777
  return needEscape;
730
778
  }
779
+ function escapeTextForLink(text) {
780
+ var imageSyntaxRanges = [];
781
+ var result = reMdImageSyntax.exec(text);
782
+ while (result) {
783
+ imageSyntaxRanges.push([result.index, result.index + result[0].length]);
784
+ result = reMdImageSyntax.exec(text);
785
+ }
786
+ return text.replace(reEscapedCharInLinkSyntax, function (matched, offset) {
787
+ var isDelimiter = imageSyntaxRanges.some(function (range) { return offset > range[0] && offset < range[1]; });
788
+ return isDelimiter ? matched : "\\" + matched;
789
+ });
790
+ }
731
791
  function escape$1(text) {
732
792
  var replacer = function (matched) { return "\\" + matched; };
733
793
  var escapedText = text.replace(reSpaceMoreThanOne, ' ');
@@ -850,6 +910,54 @@ function getSortedNumPair(valueA, valueB) {
850
910
  return valueA > valueB ? [valueB, valueA] : [valueA, valueB];
851
911
  }
852
912
 
913
+ /**
914
+ * @fileoverview Transform the Array-like object to Array.
915
+ * @author NHN FE Development Lab <dl_javascript@nhn.com>
916
+ */
917
+
918
+ var forEachArray = forEachArray_1;
919
+
920
+ /**
921
+ * Transform the Array-like object to Array.
922
+ * In low IE (below 8), Array.prototype.slice.call is not perfect. So, try-catch statement is used.
923
+ * @param {*} arrayLike Array-like object
924
+ * @returns {Array} Array
925
+ * @memberof module:collection
926
+ * @example
927
+ * // ES6
928
+ * import toArray from 'tui-code-snippet/collection/toArray';
929
+ *
930
+ * // CommonJS
931
+ * const toArray = require('tui-code-snippet/collection/toArray');
932
+ *
933
+ * const arrayLike = {
934
+ * 0: 'one',
935
+ * 1: 'two',
936
+ * 2: 'three',
937
+ * 3: 'four',
938
+ * length: 4
939
+ * };
940
+ * const result = toArray(arrayLike);
941
+ *
942
+ * alert(result instanceof Array); // true
943
+ * alert(result); // one,two,three,four
944
+ */
945
+ function toArray$1(arrayLike) {
946
+ var arr;
947
+ try {
948
+ arr = Array.prototype.slice.call(arrayLike);
949
+ } catch (e) {
950
+ arr = [];
951
+ forEachArray(arrayLike, function(value) {
952
+ arr.push(value);
953
+ });
954
+ }
955
+
956
+ return arr;
957
+ }
958
+
959
+ var toArray_1 = toArray$1;
960
+
853
961
  function createParagraph(schema, content) {
854
962
  var paragraph = schema.nodes.paragraph;
855
963
  if (!content) {
@@ -1173,267 +1281,472 @@ function placeholder(options) {
1173
1281
  });
1174
1282
  }
1175
1283
 
1176
- var pluginKey$1 = new PluginKey('widget');
1177
- var PopupWidget = /** @class */ (function () {
1178
- function PopupWidget(eventEmitter) {
1179
- var _this = this;
1180
- this.popup = null;
1181
- this.removeWidget = function () {
1182
- if (_this.popup) {
1183
- document.body.removeChild(_this.popup);
1184
- _this.popup = null;
1185
- }
1186
- };
1187
- this.eventEmitter = eventEmitter;
1188
- this.eventEmitter.listen('blur', this.removeWidget);
1189
- this.eventEmitter.listen('removePopupWidget', this.removeWidget);
1190
- }
1191
- PopupWidget.prototype.update = function (view) {
1192
- var widget = pluginKey$1.getState(view.state);
1193
- this.removeWidget();
1194
- if (widget) {
1195
- var node = widget.node, style = widget.style;
1196
- var _a = view.coordsAtPos(widget.pos), top_1 = _a.top, left = _a.left, bottom = _a.bottom;
1197
- var height = bottom - top_1;
1198
- css_1(node, { position: 'absolute', left: left + "px", opacity: '0' });
1199
- document.body.appendChild(node);
1200
- css_1(node, {
1201
- top: (style === 'bottom' ? top_1 + height : top_1 - node.clientHeight - height) + "px",
1202
- opacity: '1',
1203
- });
1204
- this.popup = node;
1205
- view.focus();
1206
- }
1207
- };
1208
- PopupWidget.prototype.destroy = function () {
1209
- this.eventEmitter.removeEventHandler('blur', this.removeWidget);
1210
- };
1211
- return PopupWidget;
1212
- }());
1213
- function addWidget(eventEmitter) {
1214
- return new Plugin({
1215
- key: pluginKey$1,
1216
- state: {
1217
- init: function () {
1218
- return null;
1219
- },
1220
- apply: function (tr) {
1221
- return tr.getMeta('widget');
1222
- },
1223
- },
1224
- view: function () {
1225
- return new PopupWidget(eventEmitter);
1226
- },
1227
- });
1228
- }
1229
-
1230
1284
  /**
1231
- * @fileoverview Transform the Array-like object to Array.
1285
+ * @fileoverview Check element has specific css class
1232
1286
  * @author NHN FE Development Lab <dl_javascript@nhn.com>
1233
1287
  */
1234
1288
 
1235
- var forEachArray = forEachArray_1;
1289
+ var inArray$1 = inArray_1;
1290
+ var getClass = getClass_1;
1236
1291
 
1237
1292
  /**
1238
- * Transform the Array-like object to Array.
1239
- * In low IE (below 8), Array.prototype.slice.call is not perfect. So, try-catch statement is used.
1240
- * @param {*} arrayLike Array-like object
1241
- * @returns {Array} Array
1242
- * @memberof module:collection
1243
- * @example
1244
- * var toArray = require('tui-code-snippet/collection/toArray'); // node, commonjs
1245
- *
1246
- * var arrayLike = {
1247
- * 0: 'one',
1248
- * 1: 'two',
1249
- * 2: 'three',
1250
- * 3: 'four',
1251
- * length: 4
1252
- * };
1253
- * var result = toArray(arrayLike);
1254
- *
1255
- * alert(result instanceof Array); // true
1256
- * alert(result); // one,two,three,four
1293
+ * Check element has specific css class
1294
+ * @param {(HTMLElement|SVGElement)} element - target element
1295
+ * @param {string} cssClass - css class
1296
+ * @returns {boolean}
1297
+ * @memberof module:domUtil
1257
1298
  */
1258
- function toArray$1(arrayLike) {
1259
- var arr;
1260
- try {
1261
- arr = Array.prototype.slice.call(arrayLike);
1262
- } catch (e) {
1263
- arr = [];
1264
- forEachArray(arrayLike, function(value) {
1265
- arr.push(value);
1266
- });
1299
+ function hasClass(element, cssClass) {
1300
+ var origin;
1301
+
1302
+ if (element.classList) {
1303
+ return element.classList.contains(cssClass);
1267
1304
  }
1268
1305
 
1269
- return arr;
1306
+ origin = getClass(element).split(/\s+/);
1307
+
1308
+ return inArray$1(cssClass, origin) > -1;
1270
1309
  }
1271
1310
 
1272
- var toArray_1 = toArray$1;
1311
+ var hasClass_1 = hasClass;
1273
1312
 
1274
- function addDefaultImageBlobHook(eventEmitter) {
1275
- eventEmitter.listen('addImageBlobHook', function (blob, callback) {
1276
- var reader = new FileReader();
1277
- reader.onload = function (_a) {
1278
- var target = _a.target;
1279
- return callback(target.result);
1280
- };
1281
- reader.readAsDataURL(blob);
1282
- });
1283
- }
1284
- function emitImageBlobHook(eventEmitter, blob, type) {
1285
- var hook = function (imageUrl, altText) {
1286
- eventEmitter.emit('command', 'addImage', {
1287
- imageUrl: imageUrl,
1288
- altText: altText || blob.name || 'image',
1289
- });
1290
- };
1291
- eventEmitter.emit('addImageBlobHook', blob, hook, type);
1292
- }
1293
- function pasteImageOnly(items) {
1294
- var images = toArray_1(items).filter(function (_a) {
1295
- var type = _a.type;
1296
- return type.indexOf('image') !== -1;
1297
- });
1298
- if (images.length === 1) {
1299
- var item = images[0];
1300
- if (item) {
1301
- return item.getAsFile();
1302
- }
1303
- }
1304
- return null;
1305
- }
1313
+ /**
1314
+ * @fileoverview Check element match selector
1315
+ * @author NHN FE Development Lab <dl_javascript@nhn.com>
1316
+ */
1306
1317
 
1307
- function dropImage(_a) {
1308
- var eventEmitter = _a.eventEmitter;
1309
- return new Plugin({
1310
- props: {
1311
- handleDOMEvents: {
1312
- drop: function (_, ev) {
1313
- var _a;
1314
- var items = (_a = ev.dataTransfer) === null || _a === void 0 ? void 0 : _a.files;
1315
- if (items) {
1316
- forEachArray_1(items, function (item) {
1317
- if (item.type.indexOf('image') !== -1) {
1318
- ev.preventDefault();
1319
- ev.stopPropagation();
1320
- emitImageBlobHook(eventEmitter, item, ev.type);
1321
- return false;
1322
- }
1323
- return true;
1324
- });
1325
- }
1326
- return true;
1327
- },
1328
- },
1329
- },
1330
- });
1331
- }
1318
+ var inArray = inArray_1;
1319
+ var toArray = toArray_1;
1332
1320
 
1333
- var Node$2 = /** @class */ (function () {
1334
- function Node() {
1335
- }
1336
- Object.defineProperty(Node.prototype, "type", {
1337
- get: function () {
1338
- return 'node';
1339
- },
1340
- enumerable: false,
1341
- configurable: true
1342
- });
1343
- Node.prototype.setContext = function (context) {
1344
- this.context = context;
1321
+ var elProto = Element.prototype;
1322
+ var matchSelector = elProto.matches ||
1323
+ elProto.webkitMatchesSelector ||
1324
+ elProto.mozMatchesSelector ||
1325
+ elProto.msMatchesSelector ||
1326
+ function(selector) {
1327
+ var doc = this.document || this.ownerDocument;
1328
+
1329
+ return inArray(this, toArray(doc.querySelectorAll(selector))) > -1;
1345
1330
  };
1346
- return Node;
1347
- }());
1348
1331
 
1349
- function widgetNodeView(pmNode) {
1350
- var dom = document.createElement('span');
1351
- var node = widgetToDOM(pmNode.attrs.info, pmNode.textContent);
1352
- dom.className = 'tui-widget';
1353
- dom.appendChild(node);
1354
- return { dom: dom };
1355
- }
1356
- function isWidgetNode(pmNode) {
1357
- return pmNode.type.name === 'widget';
1332
+ /**
1333
+ * Check element match selector
1334
+ * @param {HTMLElement} element - element to check
1335
+ * @param {string} selector - selector to check
1336
+ * @returns {boolean} is selector matched to element?
1337
+ * @memberof module:domUtil
1338
+ */
1339
+ function matches(element, selector) {
1340
+ return matchSelector.call(element, selector);
1358
1341
  }
1359
- var Widget = /** @class */ (function (_super) {
1360
- __extends$1(Widget, _super);
1361
- function Widget() {
1362
- return _super !== null && _super.apply(this, arguments) || this;
1342
+
1343
+ var matches_1 = matches;
1344
+
1345
+ var TAG_NAME = '[A-Za-z][A-Za-z0-9-]*';
1346
+ var ATTRIBUTE_NAME = '[a-zA-Z_:][a-zA-Z0-9:._-]*';
1347
+ var UNQUOTED_VALUE = '[^"\'=<>`\\x00-\\x20]+';
1348
+ var SINGLE_QUOTED_VALUE = "'[^']*'";
1349
+ var DOUBLE_QUOTED_VALUE = '"[^"]*"';
1350
+ var ATTRIBUTE_VALUE = "(?:" + UNQUOTED_VALUE + "|" + SINGLE_QUOTED_VALUE + "|" + DOUBLE_QUOTED_VALUE + ")";
1351
+ var ATTRIBUTE_VALUE_SPEC = "" + '(?:\\s*=\\s*' + ATTRIBUTE_VALUE + ")";
1352
+ var ATTRIBUTE$1 = "" + '(?:\\s+' + ATTRIBUTE_NAME + ATTRIBUTE_VALUE_SPEC + "?)";
1353
+ var OPEN_TAG = "<(" + TAG_NAME + ")(" + ATTRIBUTE$1 + ")*\\s*/?>";
1354
+ var CLOSE_TAG = "</(" + TAG_NAME + ")\\s*[>]";
1355
+ var HTML_TAG = "(?:" + OPEN_TAG + "|" + CLOSE_TAG + ")";
1356
+ var reHTMLTag = new RegExp("^" + HTML_TAG, 'i');
1357
+ var reBR = /<br\s*\/*>/i;
1358
+ var reHTMLComment = /<! ---->|<!--(?:-?[^>-])(?:-?[^-])*-->/;
1359
+ var ALTERNATIVE_TAG_FOR_BR = '</p><p>';
1360
+
1361
+ function isPositionInBox(style, offsetX, offsetY) {
1362
+ var left = parseInt(style.left, 10);
1363
+ var top = parseInt(style.top, 10);
1364
+ var width = parseInt(style.width, 10) + parseInt(style.paddingLeft, 10) + parseInt(style.paddingRight, 10);
1365
+ var height = parseInt(style.height, 10) + parseInt(style.paddingTop, 10) + parseInt(style.paddingBottom, 10);
1366
+ return offsetX >= left && offsetX <= left + width && offsetY >= top && offsetY <= top + height;
1367
+ }
1368
+ var CLS_PREFIX = 'toastui-editor-';
1369
+ function cls() {
1370
+ var names = [];
1371
+ for (var _i = 0; _i < arguments.length; _i++) {
1372
+ names[_i] = arguments[_i];
1363
1373
  }
1364
- Object.defineProperty(Widget.prototype, "name", {
1365
- get: function () {
1366
- return 'widget';
1367
- },
1368
- enumerable: false,
1369
- configurable: true
1374
+ var result = [];
1375
+ for (var _a = 0, names_1 = names; _a < names_1.length; _a++) {
1376
+ var name_1 = names_1[_a];
1377
+ var className = void 0;
1378
+ if (Array.isArray(name_1)) {
1379
+ className = name_1[0] ? name_1[1] : null;
1380
+ }
1381
+ else {
1382
+ className = name_1;
1383
+ }
1384
+ if (className) {
1385
+ result.push("" + CLS_PREFIX + className);
1386
+ }
1387
+ }
1388
+ return result.join(' ');
1389
+ }
1390
+ function clsWithMdPrefix() {
1391
+ var names = [];
1392
+ for (var _i = 0; _i < arguments.length; _i++) {
1393
+ names[_i] = arguments[_i];
1394
+ }
1395
+ return names.map(function (className) { return CLS_PREFIX + "md-" + className; }).join(' ');
1396
+ }
1397
+ function isTextNode(node) {
1398
+ return (node === null || node === void 0 ? void 0 : node.nodeType) === Node.TEXT_NODE;
1399
+ }
1400
+ function isElemNode(node) {
1401
+ return node && node.nodeType === Node.ELEMENT_NODE;
1402
+ }
1403
+ function findNodes(element, selector) {
1404
+ var nodeList = toArray_1(element.querySelectorAll(selector));
1405
+ if (nodeList.length) {
1406
+ return nodeList;
1407
+ }
1408
+ return [];
1409
+ }
1410
+ function appendNodes(node, nodesToAppend) {
1411
+ nodesToAppend = isArray_1(nodesToAppend) ? toArray_1(nodesToAppend) : [nodesToAppend];
1412
+ nodesToAppend.forEach(function (nodeToAppend) {
1413
+ node.appendChild(nodeToAppend);
1370
1414
  });
1371
- Object.defineProperty(Widget.prototype, "schema", {
1372
- get: function () {
1373
- return {
1374
- attrs: {
1375
- info: { default: null },
1376
- },
1377
- group: 'inline',
1378
- inline: true,
1379
- content: 'text*',
1380
- selectable: false,
1381
- atom: true,
1382
- toDOM: function () {
1383
- return ['span', { class: 'tui-widget' }, 0];
1384
- },
1385
- parseDOM: [
1386
- {
1387
- tag: 'span.tui-widget',
1388
- getAttrs: function (dom) {
1389
- var text = dom.textContent;
1390
- var _a = text.match(/\$\$(widget\d+)/), info = _a[1];
1391
- return { info: info };
1392
- },
1393
- },
1394
- ],
1395
- };
1396
- },
1397
- enumerable: false,
1398
- configurable: true
1415
+ }
1416
+ function insertBeforeNode(insertedNode, node) {
1417
+ if (node.parentNode) {
1418
+ node.parentNode.insertBefore(insertedNode, node);
1419
+ }
1420
+ }
1421
+ function removeNode$1(node) {
1422
+ if (node.parentNode) {
1423
+ node.parentNode.removeChild(node);
1424
+ }
1425
+ }
1426
+ function unwrapNode(node) {
1427
+ var result = [];
1428
+ while (node.firstChild) {
1429
+ result.push(node.firstChild);
1430
+ if (node.parentNode) {
1431
+ node.parentNode.insertBefore(node.firstChild, node);
1432
+ }
1433
+ }
1434
+ removeNode$1(node);
1435
+ return result;
1436
+ }
1437
+ function toggleClass(element, className, state) {
1438
+ if (isUndefined_1(state)) {
1439
+ state = !hasClass_1(element, className);
1440
+ }
1441
+ var toggleFn = state ? addClass_1 : removeClass_1;
1442
+ toggleFn(element, className);
1443
+ }
1444
+ function createElementWith(contents, target) {
1445
+ var container = document.createElement('div');
1446
+ if (isString_1(contents)) {
1447
+ container.innerHTML = contents;
1448
+ }
1449
+ else {
1450
+ container.appendChild(contents);
1451
+ }
1452
+ var firstChild = container.firstChild;
1453
+ if (target) {
1454
+ target.appendChild(firstChild);
1455
+ }
1456
+ return firstChild;
1457
+ }
1458
+ function getOuterWidth(el) {
1459
+ var computed = window.getComputedStyle(el);
1460
+ return (['margin-left', 'margin-right'].reduce(function (acc, type) { return acc + parseInt(computed.getPropertyValue(type), 10); }, 0) + el.offsetWidth);
1461
+ }
1462
+ function closest(node, found) {
1463
+ var condition;
1464
+ if (isString_1(found)) {
1465
+ condition = function (target) { return matches_1(target, found); };
1466
+ }
1467
+ else {
1468
+ condition = function (target) { return target === found; };
1469
+ }
1470
+ while (node && node !== document) {
1471
+ if (isElemNode(node) && condition(node)) {
1472
+ return node;
1473
+ }
1474
+ node = node.parentNode;
1475
+ }
1476
+ return null;
1477
+ }
1478
+ function getTotalOffset(el, root) {
1479
+ var offsetTop = 0;
1480
+ var offsetLeft = 0;
1481
+ while (el && el !== root) {
1482
+ var top_1 = el.offsetTop, left = el.offsetLeft, offsetParent = el.offsetParent;
1483
+ offsetTop += top_1;
1484
+ offsetLeft += left;
1485
+ if (offsetParent === root.offsetParent) {
1486
+ break;
1487
+ }
1488
+ el = el.offsetParent;
1489
+ }
1490
+ return { offsetTop: offsetTop, offsetLeft: offsetLeft };
1491
+ }
1492
+ function setAttributes(attributes, element) {
1493
+ Object.keys(attributes).forEach(function (attrName) {
1494
+ if (isNil(attributes[attrName])) {
1495
+ element.removeAttribute(attrName);
1496
+ }
1497
+ else {
1498
+ element.setAttribute(attrName, attributes[attrName]);
1499
+ }
1399
1500
  });
1400
- return Widget;
1401
- }(Node$2));
1501
+ }
1502
+ function replaceBRWithEmptyBlock(html) {
1503
+ // remove br in paragraph to compatible with markdown
1504
+ var replacedHTML = html.replace(/<p><br\s*\/*><\/p>/gi, '<p></p>');
1505
+ var reHTMLTag = new RegExp(HTML_TAG, 'ig');
1506
+ var htmlTagMatched = replacedHTML.match(reHTMLTag);
1507
+ htmlTagMatched === null || htmlTagMatched === void 0 ? void 0 : htmlTagMatched.forEach(function (htmlTag, index) {
1508
+ if (reBR.test(htmlTag)) {
1509
+ var alternativeTag = ALTERNATIVE_TAG_FOR_BR;
1510
+ if (index) {
1511
+ var prevTag = htmlTagMatched[index - 1];
1512
+ var openTagMatched = prevTag.match(OPEN_TAG);
1513
+ if (openTagMatched && !/br/i.test(openTagMatched[1])) {
1514
+ var tagName = openTagMatched[1];
1515
+ alternativeTag = "</" + tagName + "><" + tagName + ">";
1516
+ }
1517
+ }
1518
+ replacedHTML = replacedHTML.replace(reBR, alternativeTag);
1519
+ }
1520
+ });
1521
+ return replacedHTML;
1522
+ }
1402
1523
 
1403
- var EditorBase = /** @class */ (function () {
1404
- function EditorBase(eventEmitter) {
1405
- this.el = document.createElement('div');
1406
- this.el.className = 'toastui-editor';
1524
+ var pluginKey$1 = new PluginKey('widget');
1525
+ var MARGIN = 5;
1526
+ var PopupWidget = /** @class */ (function () {
1527
+ function PopupWidget(view, eventEmitter) {
1528
+ var _this = this;
1529
+ this.popup = null;
1530
+ this.removeWidget = function () {
1531
+ if (_this.popup) {
1532
+ _this.rootEl.removeChild(_this.popup);
1533
+ _this.popup = null;
1534
+ }
1535
+ };
1536
+ this.rootEl = view.dom.parentElement;
1407
1537
  this.eventEmitter = eventEmitter;
1408
- this.placeholder = { text: '' };
1409
- }
1410
- EditorBase.prototype.createState = function () {
1411
- return EditorState.create({
1412
- schema: this.schema,
1413
- plugins: this.createPlugins(),
1538
+ this.eventEmitter.listen('blur', this.removeWidget);
1539
+ this.eventEmitter.listen('loadUI', function () {
1540
+ _this.rootEl = closest(view.dom.parentElement, "." + cls('defaultUI'));
1414
1541
  });
1415
- };
1416
- EditorBase.prototype.initEvent = function () {
1417
- var _a = this, eventEmitter = _a.eventEmitter, view = _a.view, editorType = _a.editorType;
1418
- view.dom.addEventListener('focus', function () { return eventEmitter.emit('focus', editorType); });
1419
- view.dom.addEventListener('blur', function () { return eventEmitter.emit('blur', editorType); });
1420
- };
1421
- EditorBase.prototype.emitChangeEvent = function (tr) {
1422
- this.eventEmitter.emit('caretChange', this.editorType);
1423
- if (tr.docChanged) {
1424
- this.eventEmitter.emit('change', this.editorType);
1542
+ this.eventEmitter.listen('removePopupWidget', this.removeWidget);
1543
+ }
1544
+ PopupWidget.prototype.update = function (view) {
1545
+ var widget = pluginKey$1.getState(view.state);
1546
+ this.removeWidget();
1547
+ if (widget) {
1548
+ var node = widget.node, style = widget.style;
1549
+ var _a = view.coordsAtPos(widget.pos), top_1 = _a.top, left = _a.left, bottom = _a.bottom;
1550
+ var height = bottom - top_1;
1551
+ var rect = this.rootEl.getBoundingClientRect();
1552
+ var relTopPos = top_1 - rect.top;
1553
+ css_1(node, { opacity: '0' });
1554
+ this.rootEl.appendChild(node);
1555
+ css_1(node, {
1556
+ position: 'absolute',
1557
+ left: left - rect.left + MARGIN + "px",
1558
+ top: (style === 'bottom' ? relTopPos + height - MARGIN : relTopPos - height) + "px",
1559
+ opacity: '1',
1560
+ });
1561
+ this.popup = node;
1562
+ view.focus();
1425
1563
  }
1426
1564
  };
1427
- Object.defineProperty(EditorBase.prototype, "defaultPlugins", {
1428
- get: function () {
1429
- var _a = getDefaultCommands(), undo = _a.undo, redo = _a.redo;
1430
- var rules = this.createInputRules();
1431
- var plugins = __spreadArray$1(__spreadArray$1([], this.keymaps), [
1432
- keymap(__assign$1({ 'Mod-z': undo(), 'Shift-Mod-z': redo() }, baseKeymap)),
1433
- history(),
1434
- placeholder(this.placeholder),
1435
- addWidget(this.eventEmitter),
1436
- dropImage(this.context),
1565
+ PopupWidget.prototype.destroy = function () {
1566
+ this.eventEmitter.removeEventHandler('blur', this.removeWidget);
1567
+ };
1568
+ return PopupWidget;
1569
+ }());
1570
+ function addWidget(eventEmitter) {
1571
+ return new Plugin({
1572
+ key: pluginKey$1,
1573
+ state: {
1574
+ init: function () {
1575
+ return null;
1576
+ },
1577
+ apply: function (tr) {
1578
+ return tr.getMeta('widget');
1579
+ },
1580
+ },
1581
+ view: function (editorView) {
1582
+ return new PopupWidget(editorView, eventEmitter);
1583
+ },
1584
+ });
1585
+ }
1586
+
1587
+ function addDefaultImageBlobHook(eventEmitter) {
1588
+ eventEmitter.listen('addImageBlobHook', function (blob, callback) {
1589
+ var reader = new FileReader();
1590
+ reader.onload = function (_a) {
1591
+ var target = _a.target;
1592
+ return callback(target.result);
1593
+ };
1594
+ reader.readAsDataURL(blob);
1595
+ });
1596
+ }
1597
+ function emitImageBlobHook(eventEmitter, blob, type) {
1598
+ var hook = function (imageUrl, altText) {
1599
+ eventEmitter.emit('command', 'addImage', {
1600
+ imageUrl: imageUrl,
1601
+ altText: altText || blob.name || 'image',
1602
+ });
1603
+ };
1604
+ eventEmitter.emit('addImageBlobHook', blob, hook, type);
1605
+ }
1606
+ function pasteImageOnly(items) {
1607
+ var images = toArray_1(items).filter(function (_a) {
1608
+ var type = _a.type;
1609
+ return type.indexOf('image') !== -1;
1610
+ });
1611
+ if (images.length === 1) {
1612
+ var item = images[0];
1613
+ if (item) {
1614
+ return item.getAsFile();
1615
+ }
1616
+ }
1617
+ return null;
1618
+ }
1619
+
1620
+ function dropImage(_a) {
1621
+ var eventEmitter = _a.eventEmitter;
1622
+ return new Plugin({
1623
+ props: {
1624
+ handleDOMEvents: {
1625
+ drop: function (_, ev) {
1626
+ var _a;
1627
+ var items = (_a = ev.dataTransfer) === null || _a === void 0 ? void 0 : _a.files;
1628
+ if (items) {
1629
+ forEachArray_1(items, function (item) {
1630
+ if (item.type.indexOf('image') !== -1) {
1631
+ ev.preventDefault();
1632
+ ev.stopPropagation();
1633
+ emitImageBlobHook(eventEmitter, item, ev.type);
1634
+ return false;
1635
+ }
1636
+ return true;
1637
+ });
1638
+ }
1639
+ return true;
1640
+ },
1641
+ },
1642
+ },
1643
+ });
1644
+ }
1645
+
1646
+ var Node$2 = /** @class */ (function () {
1647
+ function Node() {
1648
+ }
1649
+ Object.defineProperty(Node.prototype, "type", {
1650
+ get: function () {
1651
+ return 'node';
1652
+ },
1653
+ enumerable: false,
1654
+ configurable: true
1655
+ });
1656
+ Node.prototype.setContext = function (context) {
1657
+ this.context = context;
1658
+ };
1659
+ return Node;
1660
+ }());
1661
+
1662
+ function widgetNodeView(pmNode) {
1663
+ var dom = document.createElement('span');
1664
+ var node = widgetToDOM(pmNode.attrs.info, pmNode.textContent);
1665
+ dom.className = 'tui-widget';
1666
+ dom.appendChild(node);
1667
+ return { dom: dom };
1668
+ }
1669
+ function isWidgetNode(pmNode) {
1670
+ return pmNode.type.name === 'widget';
1671
+ }
1672
+ var Widget = /** @class */ (function (_super) {
1673
+ __extends$1(Widget, _super);
1674
+ function Widget() {
1675
+ return _super !== null && _super.apply(this, arguments) || this;
1676
+ }
1677
+ Object.defineProperty(Widget.prototype, "name", {
1678
+ get: function () {
1679
+ return 'widget';
1680
+ },
1681
+ enumerable: false,
1682
+ configurable: true
1683
+ });
1684
+ Object.defineProperty(Widget.prototype, "schema", {
1685
+ get: function () {
1686
+ return {
1687
+ attrs: {
1688
+ info: { default: null },
1689
+ },
1690
+ group: 'inline',
1691
+ inline: true,
1692
+ content: 'text*',
1693
+ selectable: false,
1694
+ atom: true,
1695
+ toDOM: function () {
1696
+ return ['span', { class: 'tui-widget' }, 0];
1697
+ },
1698
+ parseDOM: [
1699
+ {
1700
+ tag: 'span.tui-widget',
1701
+ getAttrs: function (dom) {
1702
+ var text = dom.textContent;
1703
+ var _a = text.match(/\$\$(widget\d+)/), info = _a[1];
1704
+ return { info: info };
1705
+ },
1706
+ },
1707
+ ],
1708
+ };
1709
+ },
1710
+ enumerable: false,
1711
+ configurable: true
1712
+ });
1713
+ return Widget;
1714
+ }(Node$2));
1715
+
1716
+ var EditorBase = /** @class */ (function () {
1717
+ function EditorBase(eventEmitter) {
1718
+ this.timer = null;
1719
+ this.el = document.createElement('div');
1720
+ this.el.className = 'toastui-editor';
1721
+ this.eventEmitter = eventEmitter;
1722
+ this.placeholder = { text: '' };
1723
+ }
1724
+ EditorBase.prototype.createState = function () {
1725
+ return EditorState.create({
1726
+ schema: this.schema,
1727
+ plugins: this.createPlugins(),
1728
+ });
1729
+ };
1730
+ EditorBase.prototype.initEvent = function () {
1731
+ var _a = this, eventEmitter = _a.eventEmitter, view = _a.view, editorType = _a.editorType;
1732
+ view.dom.addEventListener('focus', function () { return eventEmitter.emit('focus', editorType); });
1733
+ view.dom.addEventListener('blur', function () { return eventEmitter.emit('blur', editorType); });
1734
+ };
1735
+ EditorBase.prototype.emitChangeEvent = function (tr) {
1736
+ this.eventEmitter.emit('caretChange', this.editorType);
1737
+ if (tr.docChanged) {
1738
+ this.eventEmitter.emit('change', this.editorType);
1739
+ }
1740
+ };
1741
+ Object.defineProperty(EditorBase.prototype, "defaultPlugins", {
1742
+ get: function () {
1743
+ var rules = this.createInputRules();
1744
+ var plugins = __spreadArray$1(__spreadArray$1([], this.keymaps), [
1745
+ keymap(__assign$1({ 'Shift-Enter': baseKeymap.Enter }, baseKeymap)),
1746
+ history(),
1747
+ placeholder(this.placeholder),
1748
+ addWidget(this.eventEmitter),
1749
+ dropImage(this.context),
1437
1750
  ]);
1438
1751
  return rules ? plugins.concat(rules) : plugins;
1439
1752
  },
@@ -1466,6 +1779,12 @@ var EditorBase = /** @class */ (function () {
1466
1779
  });
1467
1780
  return rules.length ? inputRules({ rules: rules }) : null;
1468
1781
  };
1782
+ EditorBase.prototype.clearTimer = function () {
1783
+ if (this.timer) {
1784
+ clearTimeout(this.timer);
1785
+ this.timer = null;
1786
+ }
1787
+ };
1469
1788
  EditorBase.prototype.createSchema = function () {
1470
1789
  return new Schema({
1471
1790
  nodes: this.specs.nodes,
@@ -1473,7 +1792,13 @@ var EditorBase = /** @class */ (function () {
1473
1792
  });
1474
1793
  };
1475
1794
  EditorBase.prototype.createKeymaps = function (useCommandShortcut) {
1476
- return useCommandShortcut ? this.specs.keymaps() : [];
1795
+ var _a = getDefaultCommands(), undo = _a.undo, redo = _a.redo;
1796
+ var allKeymaps = this.specs.keymaps(useCommandShortcut);
1797
+ var historyKeymap = {
1798
+ 'Mod-z': undo(),
1799
+ 'Shift-Mod-z': redo(),
1800
+ };
1801
+ return useCommandShortcut ? allKeymaps.concat(keymap(historyKeymap)) : allKeymaps;
1477
1802
  };
1478
1803
  EditorBase.prototype.createCommands = function () {
1479
1804
  return this.specs.commands(this.view);
@@ -1484,8 +1809,9 @@ var EditorBase = /** @class */ (function () {
1484
1809
  };
1485
1810
  EditorBase.prototype.focus = function () {
1486
1811
  var _this = this;
1812
+ this.clearTimer();
1487
1813
  // prevent the error for IE11
1488
- setTimeout(function () {
1814
+ this.timer = setTimeout(function () {
1489
1815
  _this.view.focus();
1490
1816
  _this.view.dispatch(_this.view.state.tr.scrollIntoView());
1491
1817
  });
@@ -1495,20 +1821,25 @@ var EditorBase = /** @class */ (function () {
1495
1821
  };
1496
1822
  EditorBase.prototype.destroy = function () {
1497
1823
  var _this = this;
1824
+ this.clearTimer();
1498
1825
  this.view.destroy();
1499
1826
  Object.keys(this).forEach(function (prop) {
1500
1827
  delete _this[prop];
1501
1828
  });
1502
1829
  };
1503
- EditorBase.prototype.moveCursorToStart = function () {
1830
+ EditorBase.prototype.moveCursorToStart = function (focus) {
1504
1831
  var tr = this.view.state.tr;
1505
1832
  this.view.dispatch(tr.setSelection(createTextSelection(tr, 1)).scrollIntoView());
1506
- this.focus();
1833
+ if (focus) {
1834
+ this.focus();
1835
+ }
1507
1836
  };
1508
- EditorBase.prototype.moveCursorToEnd = function () {
1837
+ EditorBase.prototype.moveCursorToEnd = function (focus) {
1509
1838
  var tr = this.view.state.tr;
1510
1839
  this.view.dispatch(tr.setSelection(createTextSelection(tr, tr.doc.content.size - 1)).scrollIntoView());
1511
- this.focus();
1840
+ if (focus) {
1841
+ this.focus();
1842
+ }
1512
1843
  };
1513
1844
  EditorBase.prototype.setScrollTop = function (top) {
1514
1845
  this.view.dom.scrollTop = top;
@@ -1550,6 +1881,25 @@ function isFunction(obj) {
1550
1881
 
1551
1882
  var isFunction_1 = isFunction;
1552
1883
 
1884
+ var defaultCommandShortcuts = [
1885
+ 'Enter',
1886
+ 'Shift-Enter',
1887
+ 'Mod-Enter',
1888
+ 'Tab',
1889
+ 'Shift-Tab',
1890
+ 'Delete',
1891
+ 'Backspace',
1892
+ 'Mod-Delete',
1893
+ 'Mod-Backspace',
1894
+ 'ArrowUp',
1895
+ 'ArrowDown',
1896
+ 'ArrowLeft',
1897
+ 'ArrowRight',
1898
+ 'Mod-d',
1899
+ 'Mod-D',
1900
+ 'Alt-ArrowUp',
1901
+ 'Alt-ArrowDown',
1902
+ ];
1553
1903
  function execCommand(view, command, payload) {
1554
1904
  view.focus();
1555
1905
  return command(payload)(view.state, view.dispatch, view);
@@ -1614,9 +1964,18 @@ var SpecManager = /** @class */ (function () {
1614
1964
  }
1615
1965
  return specCommands;
1616
1966
  };
1617
- SpecManager.prototype.keymaps = function () {
1967
+ SpecManager.prototype.keymaps = function (useCommandShortcut) {
1618
1968
  var specKeymaps = this.specs.filter(function (spec) { return spec.keymaps; }).map(function (spec) { return spec.keymaps(); });
1619
- return specKeymaps.map(function (keys) { return keymap(keys); });
1969
+ return specKeymaps.map(function (keys) {
1970
+ if (!useCommandShortcut) {
1971
+ Object.keys(keys).forEach(function (key) {
1972
+ if (!includes(defaultCommandShortcuts, key)) {
1973
+ delete keys[key];
1974
+ }
1975
+ });
1976
+ }
1977
+ return keymap(keys);
1978
+ });
1620
1979
  };
1621
1980
  SpecManager.prototype.setContext = function (context) {
1622
1981
  this.specs.forEach(function (spec) {
@@ -1626,264 +1985,12 @@ var SpecManager = /** @class */ (function () {
1626
1985
  return SpecManager;
1627
1986
  }());
1628
1987
 
1629
- /**
1630
- * @fileoverview Check element has specific css class
1631
- * @author NHN FE Development Lab <dl_javascript@nhn.com>
1632
- */
1633
-
1634
- var inArray$1 = inArray_1;
1635
- var getClass = getClass_1;
1636
-
1637
- /**
1638
- * Check element has specific css class
1639
- * @param {(HTMLElement|SVGElement)} element - target element
1640
- * @param {string} cssClass - css class
1641
- * @returns {boolean}
1642
- * @memberof module:domUtil
1643
- */
1644
- function hasClass(element, cssClass) {
1645
- var origin;
1646
-
1647
- if (element.classList) {
1648
- return element.classList.contains(cssClass);
1649
- }
1650
-
1651
- origin = getClass(element).split(/\s+/);
1652
-
1653
- return inArray$1(cssClass, origin) > -1;
1654
- }
1655
-
1656
- var hasClass_1 = hasClass;
1657
-
1658
- /**
1659
- * @fileoverview Check element match selector
1660
- * @author NHN FE Development Lab <dl_javascript@nhn.com>
1661
- */
1662
-
1663
- var inArray = inArray_1;
1664
- var toArray = toArray_1;
1665
-
1666
- var elProto = Element.prototype;
1667
- var matchSelector = elProto.matches ||
1668
- elProto.webkitMatchesSelector ||
1669
- elProto.mozMatchesSelector ||
1670
- elProto.msMatchesSelector ||
1671
- function(selector) {
1672
- var doc = this.document || this.ownerDocument;
1673
-
1674
- return inArray(this, toArray(doc.querySelectorAll(selector))) > -1;
1675
- };
1676
-
1677
- /**
1678
- * Check element match selector
1679
- * @param {HTMLElement} element - element to check
1680
- * @param {string} selector - selector to check
1681
- * @returns {boolean} is selector matched to element?
1682
- * @memberof module:domUtil
1683
- */
1684
- function matches(element, selector) {
1685
- return matchSelector.call(element, selector);
1686
- }
1687
-
1688
- var matches_1 = matches;
1689
-
1690
- var TAG_NAME = '[A-Za-z][A-Za-z0-9-]*';
1691
- var ATTRIBUTE_NAME = '[a-zA-Z_:][a-zA-Z0-9:._-]*';
1692
- var UNQUOTED_VALUE = '[^"\'=<>`\\x00-\\x20]+';
1693
- var SINGLE_QUOTED_VALUE = "'[^']*'";
1694
- var DOUBLE_QUOTED_VALUE = '"[^"]*"';
1695
- var ATTRIBUTE_VALUE = "(?:" + UNQUOTED_VALUE + "|" + SINGLE_QUOTED_VALUE + "|" + DOUBLE_QUOTED_VALUE + ")";
1696
- var ATTRIBUTE_VALUE_SPEC = "" + '(?:\\s*=\\s*' + ATTRIBUTE_VALUE + ")";
1697
- var ATTRIBUTE$1 = "" + '(?:\\s+' + ATTRIBUTE_NAME + ATTRIBUTE_VALUE_SPEC + "?)";
1698
- var OPEN_TAG = "<(" + TAG_NAME + ")(" + ATTRIBUTE$1 + ")*\\s*/?>";
1699
- var CLOSE_TAG = "</(" + TAG_NAME + ")\\s*[>]";
1700
- var HTML_TAG = "(?:" + OPEN_TAG + "|" + CLOSE_TAG + ")";
1701
- var reHTMLTag = new RegExp("^" + HTML_TAG, 'i');
1702
-
1703
- function isPositionInBox(style, offsetX, offsetY) {
1704
- var left = parseInt(style.left, 10);
1705
- var top = parseInt(style.top, 10);
1706
- var width = parseInt(style.width, 10) + parseInt(style.paddingLeft, 10) + parseInt(style.paddingRight, 10);
1707
- var height = parseInt(style.height, 10) + parseInt(style.paddingTop, 10) + parseInt(style.paddingBottom, 10);
1708
- return offsetX >= left && offsetX <= left + width && offsetY >= top && offsetY <= top + height;
1709
- }
1710
- var CLS_PREFIX = 'toastui-editor-';
1711
- function cls() {
1712
- var names = [];
1713
- for (var _i = 0; _i < arguments.length; _i++) {
1714
- names[_i] = arguments[_i];
1715
- }
1716
- var result = [];
1717
- for (var _a = 0, names_1 = names; _a < names_1.length; _a++) {
1718
- var name_1 = names_1[_a];
1719
- var className = void 0;
1720
- if (Array.isArray(name_1)) {
1721
- className = name_1[0] ? name_1[1] : null;
1722
- }
1723
- else {
1724
- className = name_1;
1725
- }
1726
- if (className) {
1727
- result.push("" + CLS_PREFIX + className);
1728
- }
1729
- }
1730
- return result.join(' ');
1731
- }
1732
- function clsWithMdPrefix() {
1733
- var names = [];
1734
- for (var _i = 0; _i < arguments.length; _i++) {
1735
- names[_i] = arguments[_i];
1736
- }
1737
- return names.map(function (className) { return CLS_PREFIX + "md-" + className; }).join(' ');
1738
- }
1739
- function isTextNode(node) {
1740
- return (node === null || node === void 0 ? void 0 : node.nodeType) === Node.TEXT_NODE;
1741
- }
1742
- function isElemNode(node) {
1743
- return node && node.nodeType === Node.ELEMENT_NODE;
1744
- }
1745
- function findNodes(element, selector) {
1746
- var nodeList = toArray_1(element.querySelectorAll(selector));
1747
- if (nodeList.length) {
1748
- return nodeList;
1749
- }
1750
- return [];
1751
- }
1752
- function appendNodes(node, nodesToAppend) {
1753
- nodesToAppend = isArray_1(nodesToAppend) ? toArray_1(nodesToAppend) : [nodesToAppend];
1754
- nodesToAppend.forEach(function (nodeToAppend) {
1755
- node.appendChild(nodeToAppend);
1756
- });
1757
- }
1758
- function insertBeforeNode(insertedNode, node) {
1759
- if (node.parentNode) {
1760
- node.parentNode.insertBefore(insertedNode, node);
1761
- }
1762
- }
1763
- function removeNode$1(node) {
1764
- if (node.parentNode) {
1765
- node.parentNode.removeChild(node);
1766
- }
1767
- }
1768
- function unwrapNode(node) {
1769
- var result = [];
1770
- while (node.firstChild) {
1771
- result.push(node.firstChild);
1772
- if (node.parentNode) {
1773
- node.parentNode.insertBefore(node.firstChild, node);
1774
- }
1775
- }
1776
- removeNode$1(node);
1777
- return result;
1778
- }
1779
- function toggleClass(element, className, state) {
1780
- if (isUndefined_1(state)) {
1781
- state = !hasClass_1(element, className);
1782
- }
1783
- var toggleFn = state ? addClass_1 : removeClass_1;
1784
- toggleFn(element, className);
1785
- }
1786
- function createElementWith(contents, target) {
1787
- var container = document.createElement('div');
1788
- if (isString_1(contents)) {
1789
- container.innerHTML = contents;
1790
- }
1791
- else {
1792
- container.appendChild(contents);
1793
- }
1794
- var firstChild = container.firstChild;
1795
- if (target) {
1796
- target.appendChild(firstChild);
1797
- }
1798
- return firstChild;
1799
- }
1800
- function getOuterWidth(el) {
1801
- var computed = window.getComputedStyle(el);
1802
- return (['margin-left', 'margin-right'].reduce(function (acc, type) { return acc + parseInt(computed.getPropertyValue(type), 10); }, 0) + el.offsetWidth);
1803
- }
1804
- function closest(node, found) {
1805
- var condition;
1806
- if (isString_1(found)) {
1807
- condition = function (target) { return matches_1(target, found); };
1808
- }
1809
- else {
1810
- condition = function (target) { return target === found; };
1811
- }
1812
- while (node && node !== document) {
1813
- if (isElemNode(node) && condition(node)) {
1814
- return node;
1815
- }
1816
- node = node.parentNode;
1817
- }
1818
- return null;
1819
- }
1820
- function getTotalOffset(el, root) {
1821
- var offsetTop = 0;
1822
- var offsetLeft = 0;
1823
- while (el && el !== root) {
1824
- var top_1 = el.offsetTop, left = el.offsetLeft, offsetParent = el.offsetParent;
1825
- offsetTop += top_1;
1826
- offsetLeft += left;
1827
- if (offsetParent === root.offsetParent) {
1828
- break;
1829
- }
1830
- el = el.offsetParent;
1831
- }
1832
- return { offsetTop: offsetTop, offsetLeft: offsetLeft };
1833
- }
1834
- function finalizeHtml(html, needHtmlText) {
1835
- var result;
1836
- if (needHtmlText) {
1837
- result = html.innerHTML;
1838
- }
1839
- else {
1840
- var frag = document.createDocumentFragment();
1841
- var childNodes = toArray_1(html.childNodes);
1842
- var length_1 = childNodes.length;
1843
- for (var i = 0; i < length_1; i += 1) {
1844
- frag.appendChild(childNodes[i]);
1845
- }
1846
- result = frag;
1847
- }
1848
- return result;
1849
- }
1850
- function setAttributes(attributes, element) {
1851
- Object.keys(attributes).forEach(function (attrName) {
1852
- if (attributes[attrName]) {
1853
- element.setAttribute(attrName, attributes[attrName]);
1854
- }
1855
- else {
1856
- element.removeAttribute(attrName);
1857
- }
1858
- });
1859
- }
1860
- function replaceBRWithEmptyBlock(html) {
1861
- var reBr = /<br\s*\/*>/i;
1862
- var reHTMLTag = new RegExp(HTML_TAG, 'ig');
1863
- var htmlTagMatched = html.match(reHTMLTag);
1864
- htmlTagMatched === null || htmlTagMatched === void 0 ? void 0 : htmlTagMatched.forEach(function (htmlTag, index) {
1865
- if (reBr.test(htmlTag)) {
1866
- var alternativeTag = '';
1867
- if (index) {
1868
- var prevTag = htmlTagMatched[index - 1];
1869
- var openTagMatched = prevTag.match(OPEN_TAG);
1870
- if (openTagMatched) {
1871
- var tagName = openTagMatched[1];
1872
- alternativeTag = "</" + tagName + "><" + tagName + ">";
1873
- }
1874
- }
1875
- html = html.replace(reBr, alternativeTag);
1876
- }
1877
- });
1878
- return html;
1879
- }
1880
-
1881
- function resolveSelectionPos(selection) {
1882
- var from = selection.from, to = selection.to;
1883
- if (selection instanceof AllSelection) {
1884
- return [from + 1, to - 1];
1885
- }
1886
- return [from, to];
1988
+ function resolveSelectionPos(selection) {
1989
+ var from = selection.from, to = selection.to;
1990
+ if (selection instanceof AllSelection) {
1991
+ return [from + 1, to - 1];
1992
+ }
1993
+ return [from, to];
1887
1994
  }
1888
1995
  function getMdLine(resolvedPos) {
1889
1996
  return resolvedPos.index(0) + 1;
@@ -2337,34 +2444,60 @@ function getMarkForAdding(node, toastMark) {
2337
2444
  return markInfo !== null && markInfo !== void 0 ? markInfo : [];
2338
2445
  }
2339
2446
 
2447
+ var defaultToolbarStateKeys = [
2448
+ 'taskList',
2449
+ 'orderedList',
2450
+ 'bulletList',
2451
+ 'table',
2452
+ 'strong',
2453
+ 'emph',
2454
+ 'strike',
2455
+ 'heading',
2456
+ 'thematicBreak',
2457
+ 'blockQuote',
2458
+ 'code',
2459
+ 'codeBlock',
2460
+ 'indent',
2461
+ 'outdent',
2462
+ ];
2340
2463
  function getToolbarStateType$1(mdNode) {
2464
+ var type = mdNode.type;
2341
2465
  if (isListNode$1(mdNode)) {
2342
2466
  if (mdNode.listData.task) {
2343
2467
  return 'taskList';
2344
2468
  }
2345
2469
  return mdNode.listData.type === 'ordered' ? 'orderedList' : 'bulletList';
2346
2470
  }
2347
- if (mdNode.type.indexOf('table') !== -1) {
2471
+ if (type.indexOf('table') !== -1) {
2348
2472
  return 'table';
2349
2473
  }
2350
- return mdNode.type;
2474
+ if (!includes(defaultToolbarStateKeys, type)) {
2475
+ return null;
2476
+ }
2477
+ return type;
2351
2478
  }
2352
2479
  function getToolbarState$1(targetNode) {
2353
- var toolbarState = {};
2480
+ var toolbarState = {
2481
+ indent: { active: false, disabled: true },
2482
+ outdent: { active: false, disabled: true },
2483
+ };
2354
2484
  var listEnabled = true;
2355
2485
  traverseParentNodes(targetNode, function (mdNode) {
2356
2486
  var type = getToolbarStateType$1(mdNode);
2357
- if (type === 'customBlock' || type === 'image' || type === 'link') {
2487
+ if (!type) {
2358
2488
  return;
2359
2489
  }
2360
2490
  if (type === 'bulletList' || type === 'orderedList') {
2491
+ // to apply the nearlist list state in the nested list
2361
2492
  if (listEnabled) {
2362
- toolbarState[type] = true;
2493
+ toolbarState[type] = { active: true };
2494
+ toolbarState.indent.disabled = false;
2495
+ toolbarState.outdent.disabled = false;
2363
2496
  listEnabled = false;
2364
2497
  }
2365
2498
  }
2366
2499
  else {
2367
- toolbarState[type] = true;
2500
+ toolbarState[type] = { active: true };
2368
2501
  }
2369
2502
  });
2370
2503
  return toolbarState;
@@ -3327,9 +3460,11 @@ var ThematicBreak$1 = /** @class */ (function (_super) {
3327
3460
  return ThematicBreak;
3328
3461
  }(Mark));
3329
3462
 
3330
- function cannotBeListNode(_a) {
3331
- var type = _a.type;
3332
- return type === 'codeBlock' || type === 'heading' || type.indexOf('table') !== -1;
3463
+ function cannotBeListNode(_a, line) {
3464
+ var type = _a.type, sourcepos = _a.sourcepos;
3465
+ // eslint-disable-next-line prefer-destructuring
3466
+ var startLine = sourcepos[0][0];
3467
+ return line <= startLine && (type === 'codeBlock' || type === 'heading' || type.match('table'));
3333
3468
  }
3334
3469
  var ListItem$1 = /** @class */ (function (_super) {
3335
3470
  __extends$1(ListItem, _super);
@@ -3432,7 +3567,7 @@ var ListItem$1 = /** @class */ (function (_super) {
3432
3567
  var skipLines = [];
3433
3568
  for (var line = startLine; line <= endLine; line += 1) {
3434
3569
  var mdNode = toastMark.findFirstNodeAtLine(line);
3435
- if (mdNode && cannotBeListNode(mdNode)) {
3570
+ if (mdNode && cannotBeListNode(mdNode, line)) {
3436
3571
  break;
3437
3572
  }
3438
3573
  // to skip unnecessary processing
@@ -3723,56 +3858,6 @@ var Code$1 = /** @class */ (function (_super) {
3723
3858
  return Code;
3724
3859
  }(Mark));
3725
3860
 
3726
- var encoderList = [
3727
- {
3728
- regExp: /\(/g,
3729
- encoded: '%28',
3730
- escaped: '\\(',
3731
- },
3732
- {
3733
- regExp: /\)/g,
3734
- encoded: '%29',
3735
- escaped: '\\)',
3736
- },
3737
- {
3738
- regExp: /\[/g,
3739
- encoded: '%5B',
3740
- escaped: '\\[',
3741
- },
3742
- {
3743
- regExp: /\]/g,
3744
- encoded: '%5D',
3745
- escaped: '\\]',
3746
- },
3747
- {
3748
- regExp: /</g,
3749
- encoded: '%3C',
3750
- escaped: '\\<',
3751
- },
3752
- {
3753
- regExp: />/g,
3754
- encoded: '%3E',
3755
- escaped: '\\>',
3756
- },
3757
- {
3758
- regExp: / /g,
3759
- encoded: '%20',
3760
- escaped: ' ',
3761
- },
3762
- ];
3763
- function escapeMarkdownText(text) {
3764
- return encoderList.reduce(function (result, _a) {
3765
- var regExp = _a.regExp, escaped = _a.escaped;
3766
- return result.replace(regExp, escaped);
3767
- }, text);
3768
- }
3769
- function encodeMarkdownText(text) {
3770
- return encoderList.reduce(function (result, _a) {
3771
- var regExp = _a.regExp, encoded = _a.encoded;
3772
- return result.replace(regExp, encoded);
3773
- }, text);
3774
- }
3775
-
3776
3861
  var Link$1 = /** @class */ (function (_super) {
3777
3862
  __extends$1(Link, _super);
3778
3863
  function Link() {
@@ -3822,8 +3907,7 @@ var Link$1 = /** @class */ (function (_super) {
3822
3907
  url = imageUrl;
3823
3908
  syntax = '!';
3824
3909
  }
3825
- text = escapeMarkdownText(text);
3826
- url = encodeMarkdownText(url);
3910
+ text = escapeTextForLink(text);
3827
3911
  syntax += "[" + text + "](" + url + ")";
3828
3912
  dispatch(tr.replaceWith(from, to, createTextNode$1(schema, syntax)));
3829
3913
  return true;
@@ -3990,6 +4074,7 @@ var Html = /** @class */ (function (_super) {
3990
4074
  return Html;
3991
4075
  }(Mark));
3992
4076
 
4077
+ var customBlockSyntax = '$$';
3993
4078
  var CustomBlock$1 = /** @class */ (function (_super) {
3994
4079
  __extends$1(CustomBlock, _super);
3995
4080
  function CustomBlock() {
@@ -4013,6 +4098,22 @@ var CustomBlock$1 = /** @class */ (function (_super) {
4013
4098
  enumerable: false,
4014
4099
  configurable: true
4015
4100
  });
4101
+ CustomBlock.prototype.commands = function () {
4102
+ return function (payload) { return function (state, dispatch) {
4103
+ var selection = state.selection, schema = state.schema, tr = state.tr;
4104
+ var _a = getRangeInfo(selection), startFromOffset = _a.startFromOffset, endToOffset = _a.endToOffset;
4105
+ if (!(payload === null || payload === void 0 ? void 0 : payload.info)) {
4106
+ return false;
4107
+ }
4108
+ var customBlock = "" + customBlockSyntax + payload.info;
4109
+ var startNode = createTextNode$1(schema, customBlock);
4110
+ var endNode = createTextNode$1(schema, customBlockSyntax);
4111
+ tr.insert(startFromOffset, startNode).split(startFromOffset + customBlock.length);
4112
+ tr.split(tr.mapping.map(endToOffset)).insert(tr.mapping.map(endToOffset), endNode);
4113
+ dispatch(tr.setSelection(createTextSelection(tr, tr.mapping.map(endToOffset) - (customBlockSyntax.length + 2))));
4114
+ return true;
4115
+ }; };
4116
+ };
4016
4117
  return CustomBlock;
4017
4118
  }(Mark));
4018
4119
 
@@ -4080,15 +4181,20 @@ var MdEditor = /** @class */ (function (_super) {
4080
4181
  _this.commands = _this.createCommands();
4081
4182
  _this.specs.setContext(__assign$1(__assign$1({}, _this.context), { view: _this.view }));
4082
4183
  _this.createClipboard();
4083
- _this.eventEmitter.listen('changePreviewTabWrite', function () { return _this.toggleActive(true); });
4184
+ // To prevent unnecessary focus setting during initial rendering
4185
+ _this.eventEmitter.listen('changePreviewTabWrite', function (isMarkdownTabMounted) {
4186
+ return _this.toggleActive(true, isMarkdownTabMounted);
4187
+ });
4084
4188
  _this.eventEmitter.listen('changePreviewTabPreview', function () { return _this.toggleActive(false); });
4085
4189
  _this.initEvent();
4086
4190
  return _this;
4087
4191
  }
4088
- MdEditor.prototype.toggleActive = function (active) {
4192
+ MdEditor.prototype.toggleActive = function (active, isMarkdownTabMounted) {
4089
4193
  toggleClass(this.el, 'active', active);
4090
4194
  if (active) {
4091
- this.focus();
4195
+ if (!isMarkdownTabMounted) {
4196
+ this.focus();
4197
+ }
4092
4198
  }
4093
4199
  else {
4094
4200
  this.blur();
@@ -4102,10 +4208,14 @@ var MdEditor = /** @class */ (function (_super) {
4102
4208
  var clipboardData = ev.clipboardData || window.clipboardData;
4103
4209
  var items = clipboardData && clipboardData.items;
4104
4210
  if (items) {
4105
- var imageBlob = pasteImageOnly(items);
4106
- if (imageBlob) {
4107
- ev.preventDefault();
4108
- emitImageBlobHook(_this.eventEmitter, imageBlob, ev.type);
4211
+ var containRtfItem = toArray_1(items).some(function (item) { return item.kind === 'string' && item.type === 'text/rtf'; });
4212
+ // if it contains rtf, it's most likely copy paste from office -> no image
4213
+ if (!containRtfItem) {
4214
+ var imageBlob = pasteImageOnly(items);
4215
+ if (imageBlob) {
4216
+ ev.preventDefault();
4217
+ emitImageBlobHook(_this.eventEmitter, imageBlob, ev.type);
4218
+ }
4109
4219
  }
4110
4220
  }
4111
4221
  });
@@ -4305,7 +4415,7 @@ var MdEditor = /** @class */ (function (_super) {
4305
4415
  });
4306
4416
  this.view.dispatch(tr.replaceWith(0, doc.content.size, nodes));
4307
4417
  if (cursorToEnd) {
4308
- this.moveCursorToEnd();
4418
+ this.moveCursorToEnd(true);
4309
4419
  }
4310
4420
  };
4311
4421
  MdEditor.prototype.addWidget = function (node, style, mdPos) {
@@ -4492,7 +4602,7 @@ var safeEvent = _safeEvent;
4492
4602
  * @param {object} [context] context - context for handler method.
4493
4603
  * @memberof module:domEvent
4494
4604
  * @example
4495
- * var div = document.querySelector('div');
4605
+ * const div = document.querySelector('div');
4496
4606
  *
4497
4607
  * // Bind one event to an element.
4498
4608
  * on(div, 'click', toggle);
@@ -4509,10 +4619,10 @@ var safeEvent = _safeEvent;
4509
4619
  * });
4510
4620
  *
4511
4621
  * // Set a context for handler method.
4512
- * var name = 'global';
4513
- * var repository = {name: 'CodeSnippet'};
4622
+ * const name = 'global';
4623
+ * const repository = {name: 'CodeSnippet'};
4514
4624
  * on(div, 'drag', function() {
4515
- * console.log(this.name);
4625
+ * console.log(this.name);
4516
4626
  * }, repository);
4517
4627
  * // Result when you drag a div: "CodeSnippet"
4518
4628
  */
@@ -4629,10 +4739,14 @@ var __assign = function() {
4629
4739
  return __assign.apply(this, arguments);
4630
4740
  };
4631
4741
 
4632
- function __spreadArray(to, from) {
4633
- for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
4634
- to[j] = from[i];
4635
- return to;
4742
+ function __spreadArray(to, from, pack) {
4743
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
4744
+ if (ar || !(i in from)) {
4745
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
4746
+ ar[i] = from[i];
4747
+ }
4748
+ }
4749
+ return to.concat(ar || Array.prototype.slice.call(from));
4636
4750
  }
4637
4751
 
4638
4752
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
@@ -9965,7 +10079,7 @@ function isCustomBlock(node) {
9965
10079
  function isCustomInline(node) {
9966
10080
  return node.type === 'customInline';
9967
10081
  }
9968
- function text(s, sourcepos) {
10082
+ function text$1(s, sourcepos) {
9969
10083
  var node = createNode$1('text', sourcepos);
9970
10084
  node.literal = s;
9971
10085
  return node;
@@ -10141,17 +10255,17 @@ function convertExtAutoLinks(walker, autolinkParser) {
10141
10255
  for (var _i = 0, linkInfos_1 = linkInfos; _i < linkInfos_1.length; _i++) {
10142
10256
  var _b = linkInfos_1[_i], range = _b.range, url = _b.url, linkText = _b.text;
10143
10257
  if (range[0] > lastIdx) {
10144
- newNodes.push(text(literal.substring(lastIdx, range[0]), sourcepos(lastIdx, range[0] - 1)));
10258
+ newNodes.push(text$1(literal.substring(lastIdx, range[0]), sourcepos(lastIdx, range[0] - 1)));
10145
10259
  }
10146
10260
  var linkNode = createNode$1('link', sourcepos.apply(void 0, range));
10147
- linkNode.appendChild(text(linkText, sourcepos.apply(void 0, range)));
10261
+ linkNode.appendChild(text$1(linkText, sourcepos.apply(void 0, range)));
10148
10262
  linkNode.destination = url;
10149
10263
  linkNode.extendedAutolink = true;
10150
10264
  newNodes.push(linkNode);
10151
10265
  lastIdx = range[1] + 1;
10152
10266
  }
10153
10267
  if (lastIdx < literal.length) {
10154
- newNodes.push(text(literal.substring(lastIdx), sourcepos(lastIdx, literal.length - 1)));
10268
+ newNodes.push(text$1(literal.substring(lastIdx), sourcepos(lastIdx, literal.length - 1)));
10155
10269
  }
10156
10270
  for (var _c = 0, newNodes_1 = newNodes; _c < newNodes_1.length; _c++) {
10157
10271
  var newNode = newNodes_1[_c];
@@ -10342,7 +10456,7 @@ var InlineParser = /** @class */ (function () {
10342
10456
  }
10343
10457
  // If we got here, we didn't match a closing backtick sequence.
10344
10458
  this.pos = afterOpenTicks;
10345
- block.appendChild(text(ticks, this.sourcepos(startpos, this.pos - 1)));
10459
+ block.appendChild(text$1(ticks, this.sourcepos(startpos, this.pos - 1)));
10346
10460
  return true;
10347
10461
  };
10348
10462
  // Parse a backslash-escaped special character, adding either the escaped
@@ -10361,11 +10475,11 @@ var InlineParser = /** @class */ (function () {
10361
10475
  this.nextLine();
10362
10476
  }
10363
10477
  else if (reEscapable.test(subj.charAt(this.pos))) {
10364
- block.appendChild(text(subj.charAt(this.pos), this.sourcepos(startpos, this.pos)));
10478
+ block.appendChild(text$1(subj.charAt(this.pos), this.sourcepos(startpos, this.pos)));
10365
10479
  this.pos += 1;
10366
10480
  }
10367
10481
  else {
10368
- block.appendChild(text('\\', this.sourcepos(startpos, startpos)));
10482
+ block.appendChild(text$1('\\', this.sourcepos(startpos, startpos)));
10369
10483
  }
10370
10484
  return true;
10371
10485
  };
@@ -10380,7 +10494,7 @@ var InlineParser = /** @class */ (function () {
10380
10494
  node = createNode$1('link', this.sourcepos(startpos, this.pos));
10381
10495
  node.destination = normalizeURI("mailto:" + dest);
10382
10496
  node.title = '';
10383
- node.appendChild(text(dest, this.sourcepos(startpos + 1, this.pos - 1)));
10497
+ node.appendChild(text$1(dest, this.sourcepos(startpos + 1, this.pos - 1)));
10384
10498
  block.appendChild(node);
10385
10499
  return true;
10386
10500
  }
@@ -10389,7 +10503,7 @@ var InlineParser = /** @class */ (function () {
10389
10503
  node = createNode$1('link', this.sourcepos(startpos, this.pos));
10390
10504
  node.destination = normalizeURI(dest);
10391
10505
  node.title = '';
10392
- node.appendChild(text(dest, this.sourcepos(startpos + 1, this.pos - 1)));
10506
+ node.appendChild(text$1(dest, this.sourcepos(startpos + 1, this.pos - 1)));
10393
10507
  block.appendChild(node);
10394
10508
  return true;
10395
10509
  }
@@ -10483,7 +10597,7 @@ var InlineParser = /** @class */ (function () {
10483
10597
  else {
10484
10598
  contents = this.subject.slice(startpos - 1, this.pos);
10485
10599
  }
10486
- var node = text(contents, this.sourcepos(startpos, this.pos));
10600
+ var node = text$1(contents, this.sourcepos(startpos, this.pos));
10487
10601
  block.appendChild(node);
10488
10602
  // Add entry to stack for this opener
10489
10603
  if ((res.canOpen || res.canClose) &&
@@ -10622,7 +10736,7 @@ var InlineParser = /** @class */ (function () {
10622
10736
  var literal = textNode.literal || '';
10623
10737
  var info = literal.split(/\s/)[0];
10624
10738
  newNode.info = info;
10625
- if (literal.length === info.length + 1) {
10739
+ if (literal.length <= info.length) {
10626
10740
  textNode.unlink();
10627
10741
  }
10628
10742
  else {
@@ -10754,7 +10868,7 @@ var InlineParser = /** @class */ (function () {
10754
10868
  InlineParser.prototype.parseOpenBracket = function (block) {
10755
10869
  var startpos = this.pos;
10756
10870
  this.pos += 1;
10757
- var node = text('[', this.sourcepos(this.pos, this.pos));
10871
+ var node = text$1('[', this.sourcepos(this.pos, this.pos));
10758
10872
  block.appendChild(node);
10759
10873
  // Add entry to stack for this opener
10760
10874
  this.addBracket(node, startpos, false);
@@ -10767,13 +10881,13 @@ var InlineParser = /** @class */ (function () {
10767
10881
  this.pos += 1;
10768
10882
  if (this.peek() === C_OPEN_BRACKET$1) {
10769
10883
  this.pos += 1;
10770
- var node = text('![', this.sourcepos(this.pos - 1, this.pos));
10884
+ var node = text$1('![', this.sourcepos(this.pos - 1, this.pos));
10771
10885
  block.appendChild(node);
10772
10886
  // Add entry to stack for this opener
10773
10887
  this.addBracket(node, startpos + 1, true);
10774
10888
  }
10775
10889
  else {
10776
- var node = text('!', this.sourcepos(this.pos, this.pos));
10890
+ var node = text$1('!', this.sourcepos(this.pos, this.pos));
10777
10891
  block.appendChild(node);
10778
10892
  }
10779
10893
  return true;
@@ -10792,12 +10906,12 @@ var InlineParser = /** @class */ (function () {
10792
10906
  var opener = this.brackets;
10793
10907
  if (opener === null) {
10794
10908
  // no matched opener, just return a literal
10795
- block.appendChild(text(']', this.sourcepos(startpos, startpos)));
10909
+ block.appendChild(text$1(']', this.sourcepos(startpos, startpos)));
10796
10910
  return true;
10797
10911
  }
10798
10912
  if (!opener.active) {
10799
10913
  // no matched opener, just return a literal
10800
- block.appendChild(text(']', this.sourcepos(startpos, startpos)));
10914
+ block.appendChild(text$1(']', this.sourcepos(startpos, startpos)));
10801
10915
  // take opener off brackets stack
10802
10916
  this.removeBracket();
10803
10917
  return true;
@@ -10889,7 +11003,7 @@ var InlineParser = /** @class */ (function () {
10889
11003
  } // no match
10890
11004
  this.removeBracket(); // remove this opener from stack
10891
11005
  this.pos = startpos;
10892
- block.appendChild(text(']', this.sourcepos(startpos, startpos)));
11006
+ block.appendChild(text$1(']', this.sourcepos(startpos, startpos)));
10893
11007
  if (this.options.referenceDefinition) {
10894
11008
  this.refLinkCandidateMap[block.id] = { node: block, refLabel: refLabel };
10895
11009
  }
@@ -10919,7 +11033,7 @@ var InlineParser = /** @class */ (function () {
10919
11033
  var m;
10920
11034
  var startpos = this.pos + 1;
10921
11035
  if ((m = this.match(reEntityHere))) {
10922
- block.appendChild(text(lib.decodeHTML(m), this.sourcepos(startpos, this.pos)));
11036
+ block.appendChild(text$1(lib.decodeHTML(m), this.sourcepos(startpos, this.pos)));
10923
11037
  return true;
10924
11038
  }
10925
11039
  return false;
@@ -10954,10 +11068,10 @@ var InlineParser = /** @class */ (function () {
10954
11068
  }
10955
11069
  return repeat('\u2014', emCount) + repeat('\u2013', enCount);
10956
11070
  });
10957
- block.appendChild(text(lit, this.sourcepos(startpos, this.pos)));
11071
+ block.appendChild(text$1(lit, this.sourcepos(startpos, this.pos)));
10958
11072
  }
10959
11073
  else {
10960
- var node = text(m, this.sourcepos(startpos, this.pos));
11074
+ var node = text$1(m, this.sourcepos(startpos, this.pos));
10961
11075
  block.appendChild(node);
10962
11076
  }
10963
11077
  return true;
@@ -11180,7 +11294,7 @@ var InlineParser = /** @class */ (function () {
11180
11294
  }
11181
11295
  if (!res) {
11182
11296
  this.pos += 1;
11183
- block.appendChild(text(fromCodePoint$1(c), this.sourcepos(this.pos, this.pos + 1)));
11297
+ block.appendChild(text$1(fromCodePoint$1(c), this.sourcepos(this.pos, this.pos + 1)));
11184
11298
  }
11185
11299
  return true;
11186
11300
  };
@@ -13233,7 +13347,7 @@ var baseConvertors$1 = {
13233
13347
  return customConvertor(node, context);
13234
13348
  }
13235
13349
  catch (e) {
13236
- console.warn(e);
13350
+ console.warn("[@toast-ui/editor] - The error occurred when " + info + " block node was parsed in markdown renderer: " + e);
13237
13351
  }
13238
13352
  }
13239
13353
  return [
@@ -13256,15 +13370,27 @@ var baseConvertors$1 = {
13256
13370
  ];
13257
13371
  },
13258
13372
  customInline: function (node, context, convertors) {
13259
- var info = node.info.trim().toLowerCase();
13260
- var customConvertor = convertors[info];
13373
+ var _a = node, info = _a.info, firstChild = _a.firstChild;
13374
+ var nomalizedInfo = info.trim().toLowerCase();
13375
+ var customConvertor = convertors[nomalizedInfo];
13376
+ var entering = context.entering;
13261
13377
  if (customConvertor) {
13262
- return customConvertor(node, context);
13378
+ try {
13379
+ return customConvertor(node, context);
13380
+ }
13381
+ catch (e) {
13382
+ console.warn("[@toast-ui/editor] - The error occurred when " + nomalizedInfo + " inline node was parsed in markdown renderer: " + e);
13383
+ }
13263
13384
  }
13264
- return {
13265
- type: context.entering ? 'openTag' : 'closeTag',
13266
- tagName: 'span',
13267
- };
13385
+ return entering
13386
+ ? [
13387
+ { type: 'openTag', tagName: 'span' },
13388
+ { type: 'text', content: "$$" + info + (firstChild ? ' ' : '') },
13389
+ ]
13390
+ : [
13391
+ { type: 'text', content: '$$' },
13392
+ { type: 'closeTag', tagName: 'span' },
13393
+ ];
13268
13394
  },
13269
13395
  };
13270
13396
 
@@ -13429,8 +13555,8 @@ var Renderer = /** @class */ (function () {
13429
13555
  ? nodeType.toLowerCase()
13430
13556
  : nodeType;
13431
13557
  if (orgConvertor) {
13432
- convertors[convertorType] = function (node, context) {
13433
- context.origin = function () { return orgConvertor(node, context); };
13558
+ convertors[convertorType] = function (node, context, convertors) {
13559
+ context.origin = function () { return orgConvertor(node, context, convertors); };
13434
13560
  return convertor(node, context);
13435
13561
  };
13436
13562
  }
@@ -13571,114 +13697,1425 @@ var Renderer = /** @class */ (function () {
13571
13697
  this.generateCloseTagString(node);
13572
13698
  this.addOuterNewLine(node);
13573
13699
  }
13574
- };
13575
- return Renderer;
13576
- }());
13700
+ };
13701
+ return Renderer;
13702
+ }());
13703
+
13704
+ /*! @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 */
13705
+
13706
+ 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); } }
13707
+
13708
+ var hasOwnProperty = Object.hasOwnProperty,
13709
+ setPrototypeOf = Object.setPrototypeOf,
13710
+ isFrozen = Object.isFrozen,
13711
+ getPrototypeOf = Object.getPrototypeOf,
13712
+ getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
13713
+ var freeze = Object.freeze,
13714
+ seal = Object.seal,
13715
+ create = Object.create; // eslint-disable-line import/no-mutable-exports
13716
+
13717
+ var _ref = typeof Reflect !== 'undefined' && Reflect,
13718
+ apply = _ref.apply,
13719
+ construct = _ref.construct;
13720
+
13721
+ if (!apply) {
13722
+ apply = function apply(fun, thisValue, args) {
13723
+ return fun.apply(thisValue, args);
13724
+ };
13725
+ }
13726
+
13727
+ if (!freeze) {
13728
+ freeze = function freeze(x) {
13729
+ return x;
13730
+ };
13731
+ }
13732
+
13733
+ if (!seal) {
13734
+ seal = function seal(x) {
13735
+ return x;
13736
+ };
13737
+ }
13738
+
13739
+ if (!construct) {
13740
+ construct = function construct(Func, args) {
13741
+ return new (Function.prototype.bind.apply(Func, [null].concat(_toConsumableArray(args))))();
13742
+ };
13743
+ }
13744
+
13745
+ var arrayForEach = unapply(Array.prototype.forEach);
13746
+ var arrayPop = unapply(Array.prototype.pop);
13747
+ var arrayPush = unapply(Array.prototype.push);
13748
+
13749
+ var stringToLowerCase = unapply(String.prototype.toLowerCase);
13750
+ var stringMatch = unapply(String.prototype.match);
13751
+ var stringReplace = unapply(String.prototype.replace);
13752
+ var stringIndexOf = unapply(String.prototype.indexOf);
13753
+ var stringTrim = unapply(String.prototype.trim);
13754
+
13755
+ var regExpTest = unapply(RegExp.prototype.test);
13756
+
13757
+ var typeErrorCreate = unconstruct(TypeError);
13758
+
13759
+ function unapply(func) {
13760
+ return function (thisArg) {
13761
+ for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
13762
+ args[_key - 1] = arguments[_key];
13763
+ }
13764
+
13765
+ return apply(func, thisArg, args);
13766
+ };
13767
+ }
13768
+
13769
+ function unconstruct(func) {
13770
+ return function () {
13771
+ for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
13772
+ args[_key2] = arguments[_key2];
13773
+ }
13774
+
13775
+ return construct(func, args);
13776
+ };
13777
+ }
13778
+
13779
+ /* Add properties to a lookup table */
13780
+ function addToSet(set, array) {
13781
+ if (setPrototypeOf) {
13782
+ // Make 'in' and truthy checks like Boolean(set.constructor)
13783
+ // independent of any properties defined on Object.prototype.
13784
+ // Prevent prototype setters from intercepting set as a this value.
13785
+ setPrototypeOf(set, null);
13786
+ }
13787
+
13788
+ var l = array.length;
13789
+ while (l--) {
13790
+ var element = array[l];
13791
+ if (typeof element === 'string') {
13792
+ var lcElement = stringToLowerCase(element);
13793
+ if (lcElement !== element) {
13794
+ // Config presets (e.g. tags.js, attrs.js) are immutable.
13795
+ if (!isFrozen(array)) {
13796
+ array[l] = lcElement;
13797
+ }
13798
+
13799
+ element = lcElement;
13800
+ }
13801
+ }
13802
+
13803
+ set[element] = true;
13804
+ }
13805
+
13806
+ return set;
13807
+ }
13808
+
13809
+ /* Shallow clone an object */
13810
+ function clone(object) {
13811
+ var newObject = create(null);
13812
+
13813
+ var property = void 0;
13814
+ for (property in object) {
13815
+ if (apply(hasOwnProperty, object, [property])) {
13816
+ newObject[property] = object[property];
13817
+ }
13818
+ }
13819
+
13820
+ return newObject;
13821
+ }
13822
+
13823
+ /* IE10 doesn't support __lookupGetter__ so lets'
13824
+ * simulate it. It also automatically checks
13825
+ * if the prop is function or getter and behaves
13826
+ * accordingly. */
13827
+ function lookupGetter(object, prop) {
13828
+ while (object !== null) {
13829
+ var desc = getOwnPropertyDescriptor(object, prop);
13830
+ if (desc) {
13831
+ if (desc.get) {
13832
+ return unapply(desc.get);
13833
+ }
13834
+
13835
+ if (typeof desc.value === 'function') {
13836
+ return unapply(desc.value);
13837
+ }
13838
+ }
13839
+
13840
+ object = getPrototypeOf(object);
13841
+ }
13842
+
13843
+ function fallbackValue(element) {
13844
+ console.warn('fallback value for', element);
13845
+ return null;
13846
+ }
13847
+
13848
+ return fallbackValue;
13849
+ }
13850
+
13851
+ 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']);
13852
+
13853
+ // SVG
13854
+ 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']);
13855
+
13856
+ 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']);
13857
+
13858
+ // List of SVG elements that are disallowed by default.
13859
+ // We still need to know them so that we can do namespace
13860
+ // checks properly in case one wants to add them to
13861
+ // allow-list.
13862
+ 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']);
13863
+
13864
+ 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']);
13865
+
13866
+ // Similarly to SVG, we want to know all MathML elements,
13867
+ // even those that we disallow by default.
13868
+ var mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']);
13869
+
13870
+ var text = freeze(['#text']);
13871
+
13872
+ 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']);
13873
+
13874
+ 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']);
13875
+
13876
+ 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']);
13877
+
13878
+ var xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']);
13879
+
13880
+ // eslint-disable-next-line unicorn/better-regex
13881
+ var MUSTACHE_EXPR = seal(/\{\{[\s\S]*|[\s\S]*\}\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode
13882
+ var ERB_EXPR = seal(/<%[\s\S]*|[\s\S]*%>/gm);
13883
+ var DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]/); // eslint-disable-line no-useless-escape
13884
+ var ARIA_ATTR = seal(/^aria-[\-\w]+$/); // eslint-disable-line no-useless-escape
13885
+ 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
13886
+ );
13887
+ var IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i);
13888
+ var ATTR_WHITESPACE = seal(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g // eslint-disable-line no-control-regex
13889
+ );
13890
+
13891
+ 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; };
13892
+
13893
+ 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); } }
13894
+
13895
+ var getGlobal = function getGlobal() {
13896
+ return typeof window === 'undefined' ? null : window;
13897
+ };
13898
+
13899
+ /**
13900
+ * Creates a no-op policy for internal use only.
13901
+ * Don't export this function outside this module!
13902
+ * @param {?TrustedTypePolicyFactory} trustedTypes The policy factory.
13903
+ * @param {Document} document The document object (to determine policy name suffix)
13904
+ * @return {?TrustedTypePolicy} The policy created (or null, if Trusted Types
13905
+ * are not supported).
13906
+ */
13907
+ var _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes, document) {
13908
+ if ((typeof trustedTypes === 'undefined' ? 'undefined' : _typeof(trustedTypes)) !== 'object' || typeof trustedTypes.createPolicy !== 'function') {
13909
+ return null;
13910
+ }
13911
+
13912
+ // Allow the callers to control the unique policy name
13913
+ // by adding a data-tt-policy-suffix to the script element with the DOMPurify.
13914
+ // Policy creation with duplicate names throws in Trusted Types.
13915
+ var suffix = null;
13916
+ var ATTR_NAME = 'data-tt-policy-suffix';
13917
+ if (document.currentScript && document.currentScript.hasAttribute(ATTR_NAME)) {
13918
+ suffix = document.currentScript.getAttribute(ATTR_NAME);
13919
+ }
13920
+
13921
+ var policyName = 'dompurify' + (suffix ? '#' + suffix : '');
13922
+
13923
+ try {
13924
+ return trustedTypes.createPolicy(policyName, {
13925
+ createHTML: function createHTML(html$$1) {
13926
+ return html$$1;
13927
+ }
13928
+ });
13929
+ } catch (_) {
13930
+ // Policy creation failed (most likely another DOMPurify script has
13931
+ // already run). Skip creating the policy, as this will only cause errors
13932
+ // if TT are enforced.
13933
+ console.warn('TrustedTypes policy ' + policyName + ' could not be created.');
13934
+ return null;
13935
+ }
13936
+ };
13937
+
13938
+ function createDOMPurify() {
13939
+ var window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal();
13940
+
13941
+ var DOMPurify = function DOMPurify(root) {
13942
+ return createDOMPurify(root);
13943
+ };
13944
+
13945
+ /**
13946
+ * Version label, exposed for easier checks
13947
+ * if DOMPurify is up to date or not
13948
+ */
13949
+ DOMPurify.version = '2.3.3';
13950
+
13951
+ /**
13952
+ * Array of elements that DOMPurify removed during sanitation.
13953
+ * Empty if nothing was removed.
13954
+ */
13955
+ DOMPurify.removed = [];
13956
+
13957
+ if (!window || !window.document || window.document.nodeType !== 9) {
13958
+ // Not running in a browser, provide a factory function
13959
+ // so that you can pass your own Window
13960
+ DOMPurify.isSupported = false;
13961
+
13962
+ return DOMPurify;
13963
+ }
13964
+
13965
+ var originalDocument = window.document;
13966
+
13967
+ var document = window.document;
13968
+ var DocumentFragment = window.DocumentFragment,
13969
+ HTMLTemplateElement = window.HTMLTemplateElement,
13970
+ Node = window.Node,
13971
+ Element = window.Element,
13972
+ NodeFilter = window.NodeFilter,
13973
+ _window$NamedNodeMap = window.NamedNodeMap,
13974
+ NamedNodeMap = _window$NamedNodeMap === undefined ? window.NamedNodeMap || window.MozNamedAttrMap : _window$NamedNodeMap,
13975
+ Text = window.Text,
13976
+ Comment = window.Comment,
13977
+ DOMParser = window.DOMParser,
13978
+ trustedTypes = window.trustedTypes;
13979
+
13980
+
13981
+ var ElementPrototype = Element.prototype;
13982
+
13983
+ var cloneNode = lookupGetter(ElementPrototype, 'cloneNode');
13984
+ var getNextSibling = lookupGetter(ElementPrototype, 'nextSibling');
13985
+ var getChildNodes = lookupGetter(ElementPrototype, 'childNodes');
13986
+ var getParentNode = lookupGetter(ElementPrototype, 'parentNode');
13987
+
13988
+ // As per issue #47, the web-components registry is inherited by a
13989
+ // new document created via createHTMLDocument. As per the spec
13990
+ // (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries)
13991
+ // a new empty registry is used when creating a template contents owner
13992
+ // document, so we use that as our parent document to ensure nothing
13993
+ // is inherited.
13994
+ if (typeof HTMLTemplateElement === 'function') {
13995
+ var template = document.createElement('template');
13996
+ if (template.content && template.content.ownerDocument) {
13997
+ document = template.content.ownerDocument;
13998
+ }
13999
+ }
14000
+
14001
+ var trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, originalDocument);
14002
+ var emptyHTML = trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML('') : '';
14003
+
14004
+ var _document = document,
14005
+ implementation = _document.implementation,
14006
+ createNodeIterator = _document.createNodeIterator,
14007
+ createDocumentFragment = _document.createDocumentFragment,
14008
+ getElementsByTagName = _document.getElementsByTagName;
14009
+ var importNode = originalDocument.importNode;
14010
+
14011
+
14012
+ var documentMode = {};
14013
+ try {
14014
+ documentMode = clone(document).documentMode ? document.documentMode : {};
14015
+ } catch (_) {}
14016
+
14017
+ var hooks = {};
14018
+
14019
+ /**
14020
+ * Expose whether this browser supports running the full DOMPurify.
14021
+ */
14022
+ DOMPurify.isSupported = typeof getParentNode === 'function' && implementation && typeof implementation.createHTMLDocument !== 'undefined' && documentMode !== 9;
14023
+
14024
+ var MUSTACHE_EXPR$$1 = MUSTACHE_EXPR,
14025
+ ERB_EXPR$$1 = ERB_EXPR,
14026
+ DATA_ATTR$$1 = DATA_ATTR,
14027
+ ARIA_ATTR$$1 = ARIA_ATTR,
14028
+ IS_SCRIPT_OR_DATA$$1 = IS_SCRIPT_OR_DATA,
14029
+ ATTR_WHITESPACE$$1 = ATTR_WHITESPACE;
14030
+ var IS_ALLOWED_URI$$1 = IS_ALLOWED_URI;
14031
+
14032
+ /**
14033
+ * We consider the elements and attributes below to be safe. Ideally
14034
+ * don't add any new ones but feel free to remove unwanted ones.
14035
+ */
14036
+
14037
+ /* allowed element names */
14038
+
14039
+ var ALLOWED_TAGS = null;
14040
+ var DEFAULT_ALLOWED_TAGS = addToSet({}, [].concat(_toConsumableArray$1(html$2), _toConsumableArray$1(svg), _toConsumableArray$1(svgFilters), _toConsumableArray$1(mathMl), _toConsumableArray$1(text)));
14041
+
14042
+ /* Allowed attribute names */
14043
+ var ALLOWED_ATTR = null;
14044
+ var DEFAULT_ALLOWED_ATTR = addToSet({}, [].concat(_toConsumableArray$1(html$1$1), _toConsumableArray$1(svg$1), _toConsumableArray$1(mathMl$1), _toConsumableArray$1(xml)));
14045
+
14046
+ /* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */
14047
+ var FORBID_TAGS = null;
14048
+
14049
+ /* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */
14050
+ var FORBID_ATTR = null;
14051
+
14052
+ /* Decide if ARIA attributes are okay */
14053
+ var ALLOW_ARIA_ATTR = true;
14054
+
14055
+ /* Decide if custom data attributes are okay */
14056
+ var ALLOW_DATA_ATTR = true;
14057
+
14058
+ /* Decide if unknown protocols are okay */
14059
+ var ALLOW_UNKNOWN_PROTOCOLS = false;
14060
+
14061
+ /* Output should be safe for common template engines.
14062
+ * This means, DOMPurify removes data attributes, mustaches and ERB
14063
+ */
14064
+ var SAFE_FOR_TEMPLATES = false;
14065
+
14066
+ /* Decide if document with <html>... should be returned */
14067
+ var WHOLE_DOCUMENT = false;
14068
+
14069
+ /* Track whether config is already set on this instance of DOMPurify. */
14070
+ var SET_CONFIG = false;
14071
+
14072
+ /* Decide if all elements (e.g. style, script) must be children of
14073
+ * document.body. By default, browsers might move them to document.head */
14074
+ var FORCE_BODY = false;
14075
+
14076
+ /* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html
14077
+ * string (or a TrustedHTML object if Trusted Types are supported).
14078
+ * If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead
14079
+ */
14080
+ var RETURN_DOM = false;
14081
+
14082
+ /* Decide if a DOM `DocumentFragment` should be returned, instead of a html
14083
+ * string (or a TrustedHTML object if Trusted Types are supported) */
14084
+ var RETURN_DOM_FRAGMENT = false;
14085
+
14086
+ /* If `RETURN_DOM` or `RETURN_DOM_FRAGMENT` is enabled, decide if the returned DOM
14087
+ * `Node` is imported into the current `Document`. If this flag is not enabled the
14088
+ * `Node` will belong (its ownerDocument) to a fresh `HTMLDocument`, created by
14089
+ * DOMPurify.
14090
+ *
14091
+ * This defaults to `true` starting DOMPurify 2.2.0. Note that setting it to `false`
14092
+ * might cause XSS from attacks hidden in closed shadowroots in case the browser
14093
+ * supports Declarative Shadow: DOM https://web.dev/declarative-shadow-dom/
14094
+ */
14095
+ var RETURN_DOM_IMPORT = true;
14096
+
14097
+ /* Try to return a Trusted Type object instead of a string, return a string in
14098
+ * case Trusted Types are not supported */
14099
+ var RETURN_TRUSTED_TYPE = false;
14100
+
14101
+ /* Output should be free from DOM clobbering attacks? */
14102
+ var SANITIZE_DOM = true;
14103
+
14104
+ /* Keep element content when removing element? */
14105
+ var KEEP_CONTENT = true;
14106
+
14107
+ /* If a `Node` is passed to sanitize(), then performs sanitization in-place instead
14108
+ * of importing it into a new Document and returning a sanitized copy */
14109
+ var IN_PLACE = false;
14110
+
14111
+ /* Allow usage of profiles like html, svg and mathMl */
14112
+ var USE_PROFILES = {};
14113
+
14114
+ /* Tags to ignore content of when KEEP_CONTENT is true */
14115
+ var FORBID_CONTENTS = null;
14116
+ 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']);
14117
+
14118
+ /* Tags that are safe for data: URIs */
14119
+ var DATA_URI_TAGS = null;
14120
+ var DEFAULT_DATA_URI_TAGS = addToSet({}, ['audio', 'video', 'img', 'source', 'image', 'track']);
14121
+
14122
+ /* Attributes safe for values like "javascript:" */
14123
+ var URI_SAFE_ATTRIBUTES = null;
14124
+ var DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ['alt', 'class', 'for', 'id', 'label', 'name', 'pattern', 'placeholder', 'role', 'summary', 'title', 'value', 'style', 'xmlns']);
14125
+
14126
+ var MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
14127
+ var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
14128
+ var HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';
14129
+ /* Document namespace */
14130
+ var NAMESPACE = HTML_NAMESPACE;
14131
+ var IS_EMPTY_INPUT = false;
14132
+
14133
+ /* Parsing of strict XHTML documents */
14134
+ var PARSER_MEDIA_TYPE = void 0;
14135
+ var SUPPORTED_PARSER_MEDIA_TYPES = ['application/xhtml+xml', 'text/html'];
14136
+ var DEFAULT_PARSER_MEDIA_TYPE = 'text/html';
14137
+ var transformCaseFunc = void 0;
14138
+
14139
+ /* Keep a reference to config to pass to hooks */
14140
+ var CONFIG = null;
14141
+
14142
+ /* Ideally, do not touch anything below this line */
14143
+ /* ______________________________________________ */
14144
+
14145
+ var formElement = document.createElement('form');
14146
+
14147
+ /**
14148
+ * _parseConfig
14149
+ *
14150
+ * @param {Object} cfg optional config literal
14151
+ */
14152
+ // eslint-disable-next-line complexity
14153
+ var _parseConfig = function _parseConfig(cfg) {
14154
+ if (CONFIG && CONFIG === cfg) {
14155
+ return;
14156
+ }
14157
+
14158
+ /* Shield configuration object from tampering */
14159
+ if (!cfg || (typeof cfg === 'undefined' ? 'undefined' : _typeof(cfg)) !== 'object') {
14160
+ cfg = {};
14161
+ }
14162
+
14163
+ /* Shield configuration object from prototype pollution */
14164
+ cfg = clone(cfg);
14165
+
14166
+ /* Set configuration parameters */
14167
+ ALLOWED_TAGS = 'ALLOWED_TAGS' in cfg ? addToSet({}, cfg.ALLOWED_TAGS) : DEFAULT_ALLOWED_TAGS;
14168
+ ALLOWED_ATTR = 'ALLOWED_ATTR' in cfg ? addToSet({}, cfg.ALLOWED_ATTR) : DEFAULT_ALLOWED_ATTR;
14169
+ URI_SAFE_ATTRIBUTES = 'ADD_URI_SAFE_ATTR' in cfg ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR) : DEFAULT_URI_SAFE_ATTRIBUTES;
14170
+ DATA_URI_TAGS = 'ADD_DATA_URI_TAGS' in cfg ? addToSet(clone(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS) : DEFAULT_DATA_URI_TAGS;
14171
+ FORBID_CONTENTS = 'FORBID_CONTENTS' in cfg ? addToSet({}, cfg.FORBID_CONTENTS) : DEFAULT_FORBID_CONTENTS;
14172
+ FORBID_TAGS = 'FORBID_TAGS' in cfg ? addToSet({}, cfg.FORBID_TAGS) : {};
14173
+ FORBID_ATTR = 'FORBID_ATTR' in cfg ? addToSet({}, cfg.FORBID_ATTR) : {};
14174
+ USE_PROFILES = 'USE_PROFILES' in cfg ? cfg.USE_PROFILES : false;
14175
+ ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true
14176
+ ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true
14177
+ ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false
14178
+ SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false
14179
+ WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false
14180
+ RETURN_DOM = cfg.RETURN_DOM || false; // Default false
14181
+ RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false
14182
+ RETURN_DOM_IMPORT = cfg.RETURN_DOM_IMPORT !== false; // Default true
14183
+ RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false
14184
+ FORCE_BODY = cfg.FORCE_BODY || false; // Default false
14185
+ SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true
14186
+ KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true
14187
+ IN_PLACE = cfg.IN_PLACE || false; // Default false
14188
+ IS_ALLOWED_URI$$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI$$1;
14189
+ NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE;
14190
+
14191
+ PARSER_MEDIA_TYPE =
14192
+ // eslint-disable-next-line unicorn/prefer-includes
14193
+ SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? PARSER_MEDIA_TYPE = DEFAULT_PARSER_MEDIA_TYPE : PARSER_MEDIA_TYPE = cfg.PARSER_MEDIA_TYPE;
14194
+
14195
+ // HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is.
14196
+ transformCaseFunc = PARSER_MEDIA_TYPE === 'application/xhtml+xml' ? function (x) {
14197
+ return x;
14198
+ } : stringToLowerCase;
14199
+
14200
+ if (SAFE_FOR_TEMPLATES) {
14201
+ ALLOW_DATA_ATTR = false;
14202
+ }
14203
+
14204
+ if (RETURN_DOM_FRAGMENT) {
14205
+ RETURN_DOM = true;
14206
+ }
14207
+
14208
+ /* Parse profile info */
14209
+ if (USE_PROFILES) {
14210
+ ALLOWED_TAGS = addToSet({}, [].concat(_toConsumableArray$1(text)));
14211
+ ALLOWED_ATTR = [];
14212
+ if (USE_PROFILES.html === true) {
14213
+ addToSet(ALLOWED_TAGS, html$2);
14214
+ addToSet(ALLOWED_ATTR, html$1$1);
14215
+ }
14216
+
14217
+ if (USE_PROFILES.svg === true) {
14218
+ addToSet(ALLOWED_TAGS, svg);
14219
+ addToSet(ALLOWED_ATTR, svg$1);
14220
+ addToSet(ALLOWED_ATTR, xml);
14221
+ }
14222
+
14223
+ if (USE_PROFILES.svgFilters === true) {
14224
+ addToSet(ALLOWED_TAGS, svgFilters);
14225
+ addToSet(ALLOWED_ATTR, svg$1);
14226
+ addToSet(ALLOWED_ATTR, xml);
14227
+ }
14228
+
14229
+ if (USE_PROFILES.mathMl === true) {
14230
+ addToSet(ALLOWED_TAGS, mathMl);
14231
+ addToSet(ALLOWED_ATTR, mathMl$1);
14232
+ addToSet(ALLOWED_ATTR, xml);
14233
+ }
14234
+ }
14235
+
14236
+ /* Merge configuration parameters */
14237
+ if (cfg.ADD_TAGS) {
14238
+ if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {
14239
+ ALLOWED_TAGS = clone(ALLOWED_TAGS);
14240
+ }
14241
+
14242
+ addToSet(ALLOWED_TAGS, cfg.ADD_TAGS);
14243
+ }
14244
+
14245
+ if (cfg.ADD_ATTR) {
14246
+ if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {
14247
+ ALLOWED_ATTR = clone(ALLOWED_ATTR);
14248
+ }
14249
+
14250
+ addToSet(ALLOWED_ATTR, cfg.ADD_ATTR);
14251
+ }
14252
+
14253
+ if (cfg.ADD_URI_SAFE_ATTR) {
14254
+ addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR);
14255
+ }
14256
+
14257
+ if (cfg.FORBID_CONTENTS) {
14258
+ if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {
14259
+ FORBID_CONTENTS = clone(FORBID_CONTENTS);
14260
+ }
14261
+
14262
+ addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS);
14263
+ }
14264
+
14265
+ /* Add #text in case KEEP_CONTENT is set to true */
14266
+ if (KEEP_CONTENT) {
14267
+ ALLOWED_TAGS['#text'] = true;
14268
+ }
14269
+
14270
+ /* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */
14271
+ if (WHOLE_DOCUMENT) {
14272
+ addToSet(ALLOWED_TAGS, ['html', 'head', 'body']);
14273
+ }
14274
+
14275
+ /* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */
14276
+ if (ALLOWED_TAGS.table) {
14277
+ addToSet(ALLOWED_TAGS, ['tbody']);
14278
+ delete FORBID_TAGS.tbody;
14279
+ }
14280
+
14281
+ // Prevent further manipulation of configuration.
14282
+ // Not available in IE8, Safari 5, etc.
14283
+ if (freeze) {
14284
+ freeze(cfg);
14285
+ }
14286
+
14287
+ CONFIG = cfg;
14288
+ };
14289
+
14290
+ var MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ['mi', 'mo', 'mn', 'ms', 'mtext']);
14291
+
14292
+ var HTML_INTEGRATION_POINTS = addToSet({}, ['foreignobject', 'desc', 'title', 'annotation-xml']);
14293
+
14294
+ /* Keep track of all possible SVG and MathML tags
14295
+ * so that we can perform the namespace checks
14296
+ * correctly. */
14297
+ var ALL_SVG_TAGS = addToSet({}, svg);
14298
+ addToSet(ALL_SVG_TAGS, svgFilters);
14299
+ addToSet(ALL_SVG_TAGS, svgDisallowed);
14300
+
14301
+ var ALL_MATHML_TAGS = addToSet({}, mathMl);
14302
+ addToSet(ALL_MATHML_TAGS, mathMlDisallowed);
14303
+
14304
+ /**
14305
+ *
14306
+ *
14307
+ * @param {Element} element a DOM element whose namespace is being checked
14308
+ * @returns {boolean} Return false if the element has a
14309
+ * namespace that a spec-compliant parser would never
14310
+ * return. Return true otherwise.
14311
+ */
14312
+ var _checkValidNamespace = function _checkValidNamespace(element) {
14313
+ var parent = getParentNode(element);
14314
+
14315
+ // In JSDOM, if we're inside shadow DOM, then parentNode
14316
+ // can be null. We just simulate parent in this case.
14317
+ if (!parent || !parent.tagName) {
14318
+ parent = {
14319
+ namespaceURI: HTML_NAMESPACE,
14320
+ tagName: 'template'
14321
+ };
14322
+ }
14323
+
14324
+ var tagName = stringToLowerCase(element.tagName);
14325
+ var parentTagName = stringToLowerCase(parent.tagName);
14326
+
14327
+ if (element.namespaceURI === SVG_NAMESPACE) {
14328
+ // The only way to switch from HTML namespace to SVG
14329
+ // is via <svg>. If it happens via any other tag, then
14330
+ // it should be killed.
14331
+ if (parent.namespaceURI === HTML_NAMESPACE) {
14332
+ return tagName === 'svg';
14333
+ }
14334
+
14335
+ // The only way to switch from MathML to SVG is via
14336
+ // svg if parent is either <annotation-xml> or MathML
14337
+ // text integration points.
14338
+ if (parent.namespaceURI === MATHML_NAMESPACE) {
14339
+ return tagName === 'svg' && (parentTagName === 'annotation-xml' || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]);
14340
+ }
14341
+
14342
+ // We only allow elements that are defined in SVG
14343
+ // spec. All others are disallowed in SVG namespace.
14344
+ return Boolean(ALL_SVG_TAGS[tagName]);
14345
+ }
14346
+
14347
+ if (element.namespaceURI === MATHML_NAMESPACE) {
14348
+ // The only way to switch from HTML namespace to MathML
14349
+ // is via <math>. If it happens via any other tag, then
14350
+ // it should be killed.
14351
+ if (parent.namespaceURI === HTML_NAMESPACE) {
14352
+ return tagName === 'math';
14353
+ }
14354
+
14355
+ // The only way to switch from SVG to MathML is via
14356
+ // <math> and HTML integration points
14357
+ if (parent.namespaceURI === SVG_NAMESPACE) {
14358
+ return tagName === 'math' && HTML_INTEGRATION_POINTS[parentTagName];
14359
+ }
14360
+
14361
+ // We only allow elements that are defined in MathML
14362
+ // spec. All others are disallowed in MathML namespace.
14363
+ return Boolean(ALL_MATHML_TAGS[tagName]);
14364
+ }
14365
+
14366
+ if (element.namespaceURI === HTML_NAMESPACE) {
14367
+ // The only way to switch from SVG to HTML is via
14368
+ // HTML integration points, and from MathML to HTML
14369
+ // is via MathML text integration points
14370
+ if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) {
14371
+ return false;
14372
+ }
14373
+
14374
+ if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) {
14375
+ return false;
14376
+ }
14377
+
14378
+ // Certain elements are allowed in both SVG and HTML
14379
+ // namespace. We need to specify them explicitly
14380
+ // so that they don't get erronously deleted from
14381
+ // HTML namespace.
14382
+ var commonSvgAndHTMLElements = addToSet({}, ['title', 'style', 'font', 'a', 'script']);
14383
+
14384
+ // We disallow tags that are specific for MathML
14385
+ // or SVG and should never appear in HTML namespace
14386
+ return !ALL_MATHML_TAGS[tagName] && (commonSvgAndHTMLElements[tagName] || !ALL_SVG_TAGS[tagName]);
14387
+ }
14388
+
14389
+ // The code should never reach this place (this means
14390
+ // that the element somehow got namespace that is not
14391
+ // HTML, SVG or MathML). Return false just in case.
14392
+ return false;
14393
+ };
14394
+
14395
+ /**
14396
+ * _forceRemove
14397
+ *
14398
+ * @param {Node} node a DOM node
14399
+ */
14400
+ var _forceRemove = function _forceRemove(node) {
14401
+ arrayPush(DOMPurify.removed, { element: node });
14402
+ try {
14403
+ // eslint-disable-next-line unicorn/prefer-dom-node-remove
14404
+ node.parentNode.removeChild(node);
14405
+ } catch (_) {
14406
+ try {
14407
+ node.outerHTML = emptyHTML;
14408
+ } catch (_) {
14409
+ node.remove();
14410
+ }
14411
+ }
14412
+ };
14413
+
14414
+ /**
14415
+ * _removeAttribute
14416
+ *
14417
+ * @param {String} name an Attribute name
14418
+ * @param {Node} node a DOM node
14419
+ */
14420
+ var _removeAttribute = function _removeAttribute(name, node) {
14421
+ try {
14422
+ arrayPush(DOMPurify.removed, {
14423
+ attribute: node.getAttributeNode(name),
14424
+ from: node
14425
+ });
14426
+ } catch (_) {
14427
+ arrayPush(DOMPurify.removed, {
14428
+ attribute: null,
14429
+ from: node
14430
+ });
14431
+ }
14432
+
14433
+ node.removeAttribute(name);
14434
+
14435
+ // We void attribute values for unremovable "is"" attributes
14436
+ if (name === 'is' && !ALLOWED_ATTR[name]) {
14437
+ if (RETURN_DOM || RETURN_DOM_FRAGMENT) {
14438
+ try {
14439
+ _forceRemove(node);
14440
+ } catch (_) {}
14441
+ } else {
14442
+ try {
14443
+ node.setAttribute(name, '');
14444
+ } catch (_) {}
14445
+ }
14446
+ }
14447
+ };
14448
+
14449
+ /**
14450
+ * _initDocument
14451
+ *
14452
+ * @param {String} dirty a string of dirty markup
14453
+ * @return {Document} a DOM, filled with the dirty markup
14454
+ */
14455
+ var _initDocument = function _initDocument(dirty) {
14456
+ /* Create a HTML document */
14457
+ var doc = void 0;
14458
+ var leadingWhitespace = void 0;
14459
+
14460
+ if (FORCE_BODY) {
14461
+ dirty = '<remove></remove>' + dirty;
14462
+ } else {
14463
+ /* If FORCE_BODY isn't used, leading whitespace needs to be preserved manually */
14464
+ var matches = stringMatch(dirty, /^[\r\n\t ]+/);
14465
+ leadingWhitespace = matches && matches[0];
14466
+ }
14467
+
14468
+ if (PARSER_MEDIA_TYPE === 'application/xhtml+xml') {
14469
+ // Root of XHTML doc must contain xmlns declaration (see https://www.w3.org/TR/xhtml1/normative.html#strict)
14470
+ dirty = '<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>' + dirty + '</body></html>';
14471
+ }
14472
+
14473
+ var dirtyPayload = trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty;
14474
+ /*
14475
+ * Use the DOMParser API by default, fallback later if needs be
14476
+ * DOMParser not work for svg when has multiple root element.
14477
+ */
14478
+ if (NAMESPACE === HTML_NAMESPACE) {
14479
+ try {
14480
+ doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE);
14481
+ } catch (_) {}
14482
+ }
14483
+
14484
+ /* Use createHTMLDocument in case DOMParser is not available */
14485
+ if (!doc || !doc.documentElement) {
14486
+ doc = implementation.createDocument(NAMESPACE, 'template', null);
14487
+ try {
14488
+ doc.documentElement.innerHTML = IS_EMPTY_INPUT ? '' : dirtyPayload;
14489
+ } catch (_) {
14490
+ // Syntax error if dirtyPayload is invalid xml
14491
+ }
14492
+ }
14493
+
14494
+ var body = doc.body || doc.documentElement;
14495
+
14496
+ if (dirty && leadingWhitespace) {
14497
+ body.insertBefore(document.createTextNode(leadingWhitespace), body.childNodes[0] || null);
14498
+ }
14499
+
14500
+ /* Work on whole document or just its body */
14501
+ if (NAMESPACE === HTML_NAMESPACE) {
14502
+ return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0];
14503
+ }
14504
+
14505
+ return WHOLE_DOCUMENT ? doc.documentElement : body;
14506
+ };
14507
+
14508
+ /**
14509
+ * _createIterator
14510
+ *
14511
+ * @param {Document} root document/fragment to create iterator for
14512
+ * @return {Iterator} iterator instance
14513
+ */
14514
+ var _createIterator = function _createIterator(root) {
14515
+ return createNodeIterator.call(root.ownerDocument || root, root, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT, null, false);
14516
+ };
14517
+
14518
+ /**
14519
+ * _isClobbered
14520
+ *
14521
+ * @param {Node} elm element to check for clobbering attacks
14522
+ * @return {Boolean} true if clobbered, false if safe
14523
+ */
14524
+ var _isClobbered = function _isClobbered(elm) {
14525
+ if (elm instanceof Text || elm instanceof Comment) {
14526
+ return false;
14527
+ }
14528
+
14529
+ 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') {
14530
+ return true;
14531
+ }
14532
+
14533
+ return false;
14534
+ };
14535
+
14536
+ /**
14537
+ * _isNode
14538
+ *
14539
+ * @param {Node} obj object to check whether it's a DOM node
14540
+ * @return {Boolean} true is object is a DOM node
14541
+ */
14542
+ var _isNode = function _isNode(object) {
14543
+ 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';
14544
+ };
14545
+
14546
+ /**
14547
+ * _executeHook
14548
+ * Execute user configurable hooks
14549
+ *
14550
+ * @param {String} entryPoint Name of the hook's entry point
14551
+ * @param {Node} currentNode node to work on with the hook
14552
+ * @param {Object} data additional hook parameters
14553
+ */
14554
+ var _executeHook = function _executeHook(entryPoint, currentNode, data) {
14555
+ if (!hooks[entryPoint]) {
14556
+ return;
14557
+ }
14558
+
14559
+ arrayForEach(hooks[entryPoint], function (hook) {
14560
+ hook.call(DOMPurify, currentNode, data, CONFIG);
14561
+ });
14562
+ };
14563
+
14564
+ /**
14565
+ * _sanitizeElements
14566
+ *
14567
+ * @protect nodeName
14568
+ * @protect textContent
14569
+ * @protect removeChild
14570
+ *
14571
+ * @param {Node} currentNode to check for permission to exist
14572
+ * @return {Boolean} true if node was killed, false if left alive
14573
+ */
14574
+ var _sanitizeElements = function _sanitizeElements(currentNode) {
14575
+ var content = void 0;
14576
+
14577
+ /* Execute a hook if present */
14578
+ _executeHook('beforeSanitizeElements', currentNode, null);
14579
+
14580
+ /* Check if element is clobbered or can clobber */
14581
+ if (_isClobbered(currentNode)) {
14582
+ _forceRemove(currentNode);
14583
+ return true;
14584
+ }
14585
+
14586
+ /* Check if tagname contains Unicode */
14587
+ if (stringMatch(currentNode.nodeName, /[\u0080-\uFFFF]/)) {
14588
+ _forceRemove(currentNode);
14589
+ return true;
14590
+ }
14591
+
14592
+ /* Now let's check the element's type and name */
14593
+ var tagName = transformCaseFunc(currentNode.nodeName);
14594
+
14595
+ /* Execute a hook if present */
14596
+ _executeHook('uponSanitizeElement', currentNode, {
14597
+ tagName: tagName,
14598
+ allowedTags: ALLOWED_TAGS
14599
+ });
14600
+
14601
+ /* Detect mXSS attempts abusing namespace confusion */
14602
+ if (!_isNode(currentNode.firstElementChild) && (!_isNode(currentNode.content) || !_isNode(currentNode.content.firstElementChild)) && regExpTest(/<[/\w]/g, currentNode.innerHTML) && regExpTest(/<[/\w]/g, currentNode.textContent)) {
14603
+ _forceRemove(currentNode);
14604
+ return true;
14605
+ }
14606
+
14607
+ /* Mitigate a problem with templates inside select */
14608
+ if (tagName === 'select' && regExpTest(/<template/i, currentNode.innerHTML)) {
14609
+ _forceRemove(currentNode);
14610
+ return true;
14611
+ }
14612
+
14613
+ /* Remove element if anything forbids its presence */
14614
+ if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
14615
+ /* Keep content except for bad-listed elements */
14616
+ if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {
14617
+ var parentNode = getParentNode(currentNode) || currentNode.parentNode;
14618
+ var childNodes = getChildNodes(currentNode) || currentNode.childNodes;
14619
+
14620
+ if (childNodes && parentNode) {
14621
+ var childCount = childNodes.length;
14622
+
14623
+ for (var i = childCount - 1; i >= 0; --i) {
14624
+ parentNode.insertBefore(cloneNode(childNodes[i], true), getNextSibling(currentNode));
14625
+ }
14626
+ }
14627
+ }
14628
+
14629
+ _forceRemove(currentNode);
14630
+ return true;
14631
+ }
14632
+
14633
+ /* Check whether element has a valid namespace */
14634
+ if (currentNode instanceof Element && !_checkValidNamespace(currentNode)) {
14635
+ _forceRemove(currentNode);
14636
+ return true;
14637
+ }
14638
+
14639
+ if ((tagName === 'noscript' || tagName === 'noembed') && regExpTest(/<\/no(script|embed)/i, currentNode.innerHTML)) {
14640
+ _forceRemove(currentNode);
14641
+ return true;
14642
+ }
14643
+
14644
+ /* Sanitize element content to be template-safe */
14645
+ if (SAFE_FOR_TEMPLATES && currentNode.nodeType === 3) {
14646
+ /* Get the element's text content */
14647
+ content = currentNode.textContent;
14648
+ content = stringReplace(content, MUSTACHE_EXPR$$1, ' ');
14649
+ content = stringReplace(content, ERB_EXPR$$1, ' ');
14650
+ if (currentNode.textContent !== content) {
14651
+ arrayPush(DOMPurify.removed, { element: currentNode.cloneNode() });
14652
+ currentNode.textContent = content;
14653
+ }
14654
+ }
14655
+
14656
+ /* Execute a hook if present */
14657
+ _executeHook('afterSanitizeElements', currentNode, null);
14658
+
14659
+ return false;
14660
+ };
14661
+
14662
+ /**
14663
+ * _isValidAttribute
14664
+ *
14665
+ * @param {string} lcTag Lowercase tag name of containing element.
14666
+ * @param {string} lcName Lowercase attribute name.
14667
+ * @param {string} value Attribute value.
14668
+ * @return {Boolean} Returns true if `value` is valid, otherwise false.
14669
+ */
14670
+ // eslint-disable-next-line complexity
14671
+ var _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) {
14672
+ /* Make sure attribute cannot clobber */
14673
+ if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) {
14674
+ return false;
14675
+ }
14676
+
14677
+ /* Allow valid data-* attributes: At least one character after "-"
14678
+ (https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)
14679
+ XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)
14680
+ We don't need to check the value; it's always URI safe. */
14681
+ 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]) {
14682
+ return false;
14683
+
14684
+ /* Check value is safe. First, is attr inert? If so, is safe */
14685
+ } 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 {
14686
+ return false;
14687
+ }
14688
+
14689
+ return true;
14690
+ };
14691
+
14692
+ /**
14693
+ * _sanitizeAttributes
14694
+ *
14695
+ * @protect attributes
14696
+ * @protect nodeName
14697
+ * @protect removeAttribute
14698
+ * @protect setAttribute
14699
+ *
14700
+ * @param {Node} currentNode to sanitize
14701
+ */
14702
+ var _sanitizeAttributes = function _sanitizeAttributes(currentNode) {
14703
+ var attr = void 0;
14704
+ var value = void 0;
14705
+ var lcName = void 0;
14706
+ var l = void 0;
14707
+ /* Execute a hook if present */
14708
+ _executeHook('beforeSanitizeAttributes', currentNode, null);
14709
+
14710
+ var attributes = currentNode.attributes;
14711
+
14712
+ /* Check if we have attributes; if not we might have a text node */
14713
+
14714
+ if (!attributes) {
14715
+ return;
14716
+ }
14717
+
14718
+ var hookEvent = {
14719
+ attrName: '',
14720
+ attrValue: '',
14721
+ keepAttr: true,
14722
+ allowedAttributes: ALLOWED_ATTR
14723
+ };
14724
+ l = attributes.length;
14725
+
14726
+ /* Go backwards over all attributes; safely remove bad ones */
14727
+ while (l--) {
14728
+ attr = attributes[l];
14729
+ var _attr = attr,
14730
+ name = _attr.name,
14731
+ namespaceURI = _attr.namespaceURI;
14732
+
14733
+ value = stringTrim(attr.value);
14734
+ lcName = transformCaseFunc(name);
14735
+
14736
+ /* Execute a hook if present */
14737
+ hookEvent.attrName = lcName;
14738
+ hookEvent.attrValue = value;
14739
+ hookEvent.keepAttr = true;
14740
+ hookEvent.forceKeepAttr = undefined; // Allows developers to see this is a property they can set
14741
+ _executeHook('uponSanitizeAttribute', currentNode, hookEvent);
14742
+ value = hookEvent.attrValue;
14743
+ /* Did the hooks approve of the attribute? */
14744
+ if (hookEvent.forceKeepAttr) {
14745
+ continue;
14746
+ }
14747
+
14748
+ /* Remove attribute */
14749
+ _removeAttribute(name, currentNode);
14750
+
14751
+ /* Did the hooks approve of the attribute? */
14752
+ if (!hookEvent.keepAttr) {
14753
+ continue;
14754
+ }
14755
+
14756
+ /* Work around a security issue in jQuery 3.0 */
14757
+ if (regExpTest(/\/>/i, value)) {
14758
+ _removeAttribute(name, currentNode);
14759
+ continue;
14760
+ }
14761
+
14762
+ /* Sanitize attribute content to be template-safe */
14763
+ if (SAFE_FOR_TEMPLATES) {
14764
+ value = stringReplace(value, MUSTACHE_EXPR$$1, ' ');
14765
+ value = stringReplace(value, ERB_EXPR$$1, ' ');
14766
+ }
14767
+
14768
+ /* Is `value` valid for this attribute? */
14769
+ var lcTag = transformCaseFunc(currentNode.nodeName);
14770
+ if (!_isValidAttribute(lcTag, lcName, value)) {
14771
+ continue;
14772
+ }
14773
+
14774
+ /* Handle invalid data-* attribute set by try-catching it */
14775
+ try {
14776
+ if (namespaceURI) {
14777
+ currentNode.setAttributeNS(namespaceURI, name, value);
14778
+ } else {
14779
+ /* Fallback to setAttribute() for browser-unrecognized namespaces e.g. "x-schema". */
14780
+ currentNode.setAttribute(name, value);
14781
+ }
14782
+
14783
+ arrayPop(DOMPurify.removed);
14784
+ } catch (_) {}
14785
+ }
14786
+
14787
+ /* Execute a hook if present */
14788
+ _executeHook('afterSanitizeAttributes', currentNode, null);
14789
+ };
14790
+
14791
+ /**
14792
+ * _sanitizeShadowDOM
14793
+ *
14794
+ * @param {DocumentFragment} fragment to iterate over recursively
14795
+ */
14796
+ var _sanitizeShadowDOM = function _sanitizeShadowDOM(fragment) {
14797
+ var shadowNode = void 0;
14798
+ var shadowIterator = _createIterator(fragment);
14799
+
14800
+ /* Execute a hook if present */
14801
+ _executeHook('beforeSanitizeShadowDOM', fragment, null);
14802
+
14803
+ while (shadowNode = shadowIterator.nextNode()) {
14804
+ /* Execute a hook if present */
14805
+ _executeHook('uponSanitizeShadowNode', shadowNode, null);
14806
+
14807
+ /* Sanitize tags and elements */
14808
+ if (_sanitizeElements(shadowNode)) {
14809
+ continue;
14810
+ }
14811
+
14812
+ /* Deep shadow DOM detected */
14813
+ if (shadowNode.content instanceof DocumentFragment) {
14814
+ _sanitizeShadowDOM(shadowNode.content);
14815
+ }
14816
+
14817
+ /* Check attributes, sanitize if necessary */
14818
+ _sanitizeAttributes(shadowNode);
14819
+ }
14820
+
14821
+ /* Execute a hook if present */
14822
+ _executeHook('afterSanitizeShadowDOM', fragment, null);
14823
+ };
14824
+
14825
+ /**
14826
+ * Sanitize
14827
+ * Public method providing core sanitation functionality
14828
+ *
14829
+ * @param {String|Node} dirty string or DOM node
14830
+ * @param {Object} configuration object
14831
+ */
14832
+ // eslint-disable-next-line complexity
14833
+ DOMPurify.sanitize = function (dirty, cfg) {
14834
+ var body = void 0;
14835
+ var importedNode = void 0;
14836
+ var currentNode = void 0;
14837
+ var oldNode = void 0;
14838
+ var returnNode = void 0;
14839
+ /* Make sure we have a string to sanitize.
14840
+ DO NOT return early, as this will return the wrong type if
14841
+ the user has requested a DOM object rather than a string */
14842
+ IS_EMPTY_INPUT = !dirty;
14843
+ if (IS_EMPTY_INPUT) {
14844
+ dirty = '<!-->';
14845
+ }
14846
+
14847
+ /* Stringify, in case dirty is an object */
14848
+ if (typeof dirty !== 'string' && !_isNode(dirty)) {
14849
+ // eslint-disable-next-line no-negated-condition
14850
+ if (typeof dirty.toString !== 'function') {
14851
+ throw typeErrorCreate('toString is not a function');
14852
+ } else {
14853
+ dirty = dirty.toString();
14854
+ if (typeof dirty !== 'string') {
14855
+ throw typeErrorCreate('dirty is not a string, aborting');
14856
+ }
14857
+ }
14858
+ }
14859
+
14860
+ /* Check we can run. Otherwise fall back or ignore */
14861
+ if (!DOMPurify.isSupported) {
14862
+ if (_typeof(window.toStaticHTML) === 'object' || typeof window.toStaticHTML === 'function') {
14863
+ if (typeof dirty === 'string') {
14864
+ return window.toStaticHTML(dirty);
14865
+ }
13577
14866
 
13578
- var reHTMLAttr = new RegExp('^(abbr|align|alt|axis|bgcolor|border|cellpadding|cellspacing|class|clear|' +
13579
- 'color|cols|compact|coords|dir|face|headers|height|hreflang|hspace|' +
13580
- 'ismap|lang|language|nohref|nowrap|rel|rev|rows|rules|' +
13581
- 'scope|scrolling|shape|size|span|start|summary|tabindex|target|title|type|' +
13582
- 'valign|value|vspace|width|checked|mathvariant|encoding|id|name|' +
13583
- 'background|cite|href|longdesc|src|usemap|xlink:href|data-+|checked|style)', 'g');
13584
- var reSvgAttr = new RegExp('^(accent-height|accumulate|additive|alphabetic|arabic-form|ascent|' +
13585
- 'baseProfile|bbox|begin|by|calcMode|cap-height|class|color|color-rendering|content|' +
13586
- 'cx|cy|d|dx|dy|descent|display|dur|end|fill|fill-rule|font-family|font-size|font-stretch|' +
13587
- 'font-style|font-variant|font-weight|from|fx|fy|g1|g2|glyph-name|gradientUnits|hanging|' +
13588
- 'height|horiz-adv-x|horiz-origin-x|ideographic|k|keyPoints|keySplines|keyTimes|lang|' +
13589
- 'marker-end|marker-mid|marker-start|markerHeight|markerUnits|markerWidth|mathematical|' +
13590
- 'max|min|offset|opacity|orient|origin|overline-position|overline-thickness|panose-1|' +
13591
- 'path|pathLength|points|preserveAspectRatio|r|refX|refY|repeatCount|repeatDur|' +
13592
- 'requiredExtensions|requiredFeatures|restart|rotate|rx|ry|slope|stemh|stemv|stop-color|' +
13593
- 'stop-opacity|strikethrough-position|strikethrough-thickness|stroke|stroke-dasharray|' +
13594
- 'stroke-dashoffset|stroke-linecap|stroke-linejoin|stroke-miterlimit|stroke-opacity|' +
13595
- 'stroke-width|systemLanguage|target|text-anchor|to|transform|type|u1|u2|underline-position|' +
13596
- 'underline-thickness|unicode|unicode-range|units-per-em|values|version|viewBox|visibility|' +
13597
- 'width|widths|x|x-height|x1|x2|xlink:actuate|xlink:arcrole|xlink:role|xlink:show|xlink:title|' +
13598
- 'xlink:type|xml:base|xml:lang|xml:space|xmlns|xmlns:xlink|y|y1|y2|zoomAndPan)', 'g');
13599
- var reXSSAttr = /href|src|background/i;
13600
- var reXSSAttrValue = /((java|vb|live)script|x):/i;
13601
- var reOnEvent = /^on\S+/i;
13602
- var reXSSOnload = new RegExp("(<" + TAG_NAME + "[^>]*)(onload\\s*=)", 'ig');
13603
- var reComment = /<!--[\s\S]*?-->/g;
13604
- var reWhitespace = /[ \t\r\n]/g;
13605
- var DEFAULT_TAG_BLACK_LIST = [
13606
- 'script',
13607
- 'iframe',
13608
- 'textarea',
13609
- 'form',
13610
- 'button',
13611
- 'select',
13612
- 'input',
13613
- 'meta',
13614
- 'style',
13615
- 'link',
13616
- 'title',
13617
- 'embed',
13618
- 'object',
13619
- 'details',
13620
- 'summary',
13621
- 'base',
13622
- ];
13623
- var CAN_BE_TAG_WHITE_LIST = ['iframe', 'embed', 'details', 'summary'];
13624
- var tagBlacklist = __spreadArray$1([], DEFAULT_TAG_BLACK_LIST);
13625
- function registerTagWhitelistIfPossible(tagName) {
13626
- if (includes(CAN_BE_TAG_WHITE_LIST, tagName)) {
13627
- var index = tagBlacklist.indexOf(tagName);
13628
- if (index > -1) {
13629
- tagBlacklist.splice(index, 1);
14867
+ if (_isNode(dirty)) {
14868
+ return window.toStaticHTML(dirty.outerHTML);
13630
14869
  }
14870
+ }
14871
+
14872
+ return dirty;
13631
14873
  }
13632
- }
13633
- function sanitizeHTML(html) {
13634
- var root = document.createElement('div');
13635
- if (isString_1(html)) {
13636
- html = html.replace(reComment, '').replace(reXSSOnload, '$1');
13637
- root.innerHTML = html;
14874
+
14875
+ /* Assign config vars */
14876
+ if (!SET_CONFIG) {
14877
+ _parseConfig(cfg);
13638
14878
  }
13639
- removeUnnecessaryTags(root);
13640
- leaveOnlyWhitelistAttribute(root);
13641
- return finalizeHtml(root, true);
13642
- }
13643
- function removeUnnecessaryTags(html) {
13644
- var removedTags = findNodes(html, tagBlacklist.join(','));
13645
- removedTags.forEach(function (node) {
13646
- removeNode$1(node);
13647
- });
13648
- }
13649
- function isXSSAttribute(attrName, attrValue) {
13650
- return attrName.match(reXSSAttr) && attrValue.replace(reWhitespace, '').match(reXSSAttrValue);
13651
- }
13652
- function removeBlacklistAttributes(node, blacklistAttrs) {
13653
- blacklistAttrs.forEach(function (_a) {
13654
- var name = _a.name;
13655
- if (reOnEvent.test(name)) {
13656
- node[name] = null;
14879
+
14880
+ /* Clean up removed elements */
14881
+ DOMPurify.removed = [];
14882
+
14883
+ /* Check if dirty is correctly typed for IN_PLACE */
14884
+ if (typeof dirty === 'string') {
14885
+ IN_PLACE = false;
14886
+ }
14887
+
14888
+ if (IN_PLACE) ; else if (dirty instanceof Node) {
14889
+ /* If dirty is a DOM element, append to an empty document to avoid
14890
+ elements being stripped by the parser */
14891
+ body = _initDocument('<!---->');
14892
+ importedNode = body.ownerDocument.importNode(dirty, true);
14893
+ if (importedNode.nodeType === 1 && importedNode.nodeName === 'BODY') {
14894
+ /* Node is already a body, use as is */
14895
+ body = importedNode;
14896
+ } else if (importedNode.nodeName === 'HTML') {
14897
+ body = importedNode;
14898
+ } else {
14899
+ // eslint-disable-next-line unicorn/prefer-dom-node-append
14900
+ body.appendChild(importedNode);
14901
+ }
14902
+ } else {
14903
+ /* Exit directly if we have nothing to do */
14904
+ if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT &&
14905
+ // eslint-disable-next-line unicorn/prefer-includes
14906
+ dirty.indexOf('<') === -1) {
14907
+ return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(dirty) : dirty;
14908
+ }
14909
+
14910
+ /* Initialize the document to work on */
14911
+ body = _initDocument(dirty);
14912
+
14913
+ /* Check we have a DOM node from the data */
14914
+ if (!body) {
14915
+ return RETURN_DOM ? null : emptyHTML;
14916
+ }
14917
+ }
14918
+
14919
+ /* Remove first element node (ours) if FORCE_BODY is set */
14920
+ if (body && FORCE_BODY) {
14921
+ _forceRemove(body.firstChild);
14922
+ }
14923
+
14924
+ /* Get node iterator */
14925
+ var nodeIterator = _createIterator(IN_PLACE ? dirty : body);
14926
+
14927
+ /* Now start iterating over the created document */
14928
+ while (currentNode = nodeIterator.nextNode()) {
14929
+ /* Fix IE's strange behavior with manipulated textNodes #89 */
14930
+ if (currentNode.nodeType === 3 && currentNode === oldNode) {
14931
+ continue;
14932
+ }
14933
+
14934
+ /* Sanitize tags and elements */
14935
+ if (_sanitizeElements(currentNode)) {
14936
+ continue;
14937
+ }
14938
+
14939
+ /* Shadow DOM detected, sanitize it */
14940
+ if (currentNode.content instanceof DocumentFragment) {
14941
+ _sanitizeShadowDOM(currentNode.content);
14942
+ }
14943
+
14944
+ /* Check attributes, sanitize if necessary */
14945
+ _sanitizeAttributes(currentNode);
14946
+
14947
+ oldNode = currentNode;
14948
+ }
14949
+
14950
+ oldNode = null;
14951
+
14952
+ /* If we sanitized `dirty` in-place, return it. */
14953
+ if (IN_PLACE) {
14954
+ return dirty;
14955
+ }
14956
+
14957
+ /* Return sanitized string or DOM */
14958
+ if (RETURN_DOM) {
14959
+ if (RETURN_DOM_FRAGMENT) {
14960
+ returnNode = createDocumentFragment.call(body.ownerDocument);
14961
+
14962
+ while (body.firstChild) {
14963
+ // eslint-disable-next-line unicorn/prefer-dom-node-append
14964
+ returnNode.appendChild(body.firstChild);
13657
14965
  }
13658
- node.removeAttribute(name);
13659
- });
13660
- }
13661
- function leaveOnlyWhitelistAttribute(html) {
13662
- findNodes(html, '*').forEach(function (node) {
13663
- var attributes = node.attributes;
13664
- var blacklist = toArray_1(attributes).filter(function (attr) {
13665
- var name = attr.name, value = attr.value;
13666
- var htmlAttr = name.match(reHTMLAttr);
13667
- var svgAttr = name.match(reSvgAttr);
13668
- var xssAttr = htmlAttr && isXSSAttribute(name, value);
13669
- return (!htmlAttr && !svgAttr) || xssAttr;
13670
- });
13671
- removeBlacklistAttributes(node, blacklist);
13672
- });
14966
+ } else {
14967
+ returnNode = body;
14968
+ }
14969
+
14970
+ if (RETURN_DOM_IMPORT) {
14971
+ /*
14972
+ AdoptNode() is not used because internal state is not reset
14973
+ (e.g. the past names map of a HTMLFormElement), this is safe
14974
+ in theory but we would rather not risk another attack vector.
14975
+ The state that is cloned by importNode() is explicitly defined
14976
+ by the specs.
14977
+ */
14978
+ returnNode = importNode.call(originalDocument, returnNode, true);
14979
+ }
14980
+
14981
+ return returnNode;
14982
+ }
14983
+
14984
+ var serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML;
14985
+
14986
+ /* Sanitize final string template-safe */
14987
+ if (SAFE_FOR_TEMPLATES) {
14988
+ serializedHTML = stringReplace(serializedHTML, MUSTACHE_EXPR$$1, ' ');
14989
+ serializedHTML = stringReplace(serializedHTML, ERB_EXPR$$1, ' ');
14990
+ }
14991
+
14992
+ return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(serializedHTML) : serializedHTML;
14993
+ };
14994
+
14995
+ /**
14996
+ * Public method to set the configuration once
14997
+ * setConfig
14998
+ *
14999
+ * @param {Object} cfg configuration object
15000
+ */
15001
+ DOMPurify.setConfig = function (cfg) {
15002
+ _parseConfig(cfg);
15003
+ SET_CONFIG = true;
15004
+ };
15005
+
15006
+ /**
15007
+ * Public method to remove the configuration
15008
+ * clearConfig
15009
+ *
15010
+ */
15011
+ DOMPurify.clearConfig = function () {
15012
+ CONFIG = null;
15013
+ SET_CONFIG = false;
15014
+ };
15015
+
15016
+ /**
15017
+ * Public method to check if an attribute value is valid.
15018
+ * Uses last set config, if any. Otherwise, uses config defaults.
15019
+ * isValidAttribute
15020
+ *
15021
+ * @param {string} tag Tag name of containing element.
15022
+ * @param {string} attr Attribute name.
15023
+ * @param {string} value Attribute value.
15024
+ * @return {Boolean} Returns true if `value` is valid. Otherwise, returns false.
15025
+ */
15026
+ DOMPurify.isValidAttribute = function (tag, attr, value) {
15027
+ /* Initialize shared config vars if necessary. */
15028
+ if (!CONFIG) {
15029
+ _parseConfig({});
15030
+ }
15031
+
15032
+ var lcTag = transformCaseFunc(tag);
15033
+ var lcName = transformCaseFunc(attr);
15034
+ return _isValidAttribute(lcTag, lcName, value);
15035
+ };
15036
+
15037
+ /**
15038
+ * AddHook
15039
+ * Public method to add DOMPurify hooks
15040
+ *
15041
+ * @param {String} entryPoint entry point for the hook to add
15042
+ * @param {Function} hookFunction function to execute
15043
+ */
15044
+ DOMPurify.addHook = function (entryPoint, hookFunction) {
15045
+ if (typeof hookFunction !== 'function') {
15046
+ return;
15047
+ }
15048
+
15049
+ hooks[entryPoint] = hooks[entryPoint] || [];
15050
+ arrayPush(hooks[entryPoint], hookFunction);
15051
+ };
15052
+
15053
+ /**
15054
+ * RemoveHook
15055
+ * Public method to remove a DOMPurify hook at a given entryPoint
15056
+ * (pops it from the stack of hooks if more are present)
15057
+ *
15058
+ * @param {String} entryPoint entry point for the hook to remove
15059
+ */
15060
+ DOMPurify.removeHook = function (entryPoint) {
15061
+ if (hooks[entryPoint]) {
15062
+ arrayPop(hooks[entryPoint]);
15063
+ }
15064
+ };
15065
+
15066
+ /**
15067
+ * RemoveHooks
15068
+ * Public method to remove all DOMPurify hooks at a given entryPoint
15069
+ *
15070
+ * @param {String} entryPoint entry point for the hooks to remove
15071
+ */
15072
+ DOMPurify.removeHooks = function (entryPoint) {
15073
+ if (hooks[entryPoint]) {
15074
+ hooks[entryPoint] = [];
15075
+ }
15076
+ };
15077
+
15078
+ /**
15079
+ * RemoveAllHooks
15080
+ * Public method to remove all DOMPurify hooks
15081
+ *
15082
+ */
15083
+ DOMPurify.removeAllHooks = function () {
15084
+ hooks = {};
15085
+ };
15086
+
15087
+ return DOMPurify;
13673
15088
  }
13674
- function sanitizeXSSAttributeValue(attrValue) {
13675
- attrValue = attrValue.replace(reComment, '');
13676
- return reXSSAttrValue.test(attrValue) ? '' : attrValue;
15089
+
15090
+ var purify = createDOMPurify();
15091
+
15092
+ var CAN_BE_WHITE_TAG_LIST = ['iframe', 'embed'];
15093
+ var whiteTagList = [];
15094
+ function registerTagWhitelistIfPossible(tagName) {
15095
+ if (includes(CAN_BE_WHITE_TAG_LIST, tagName)) {
15096
+ whiteTagList.push(tagName.toLowerCase());
15097
+ }
15098
+ }
15099
+ function sanitizeHTML(html, options) {
15100
+ return purify.sanitize(html, __assign$1({ ADD_TAGS: whiteTagList, ADD_ATTR: ['rel', 'target', 'hreflang', 'type'], FORBID_TAGS: [
15101
+ 'input',
15102
+ 'script',
15103
+ 'textarea',
15104
+ 'form',
15105
+ 'button',
15106
+ 'select',
15107
+ 'meta',
15108
+ 'style',
15109
+ 'link',
15110
+ 'title',
15111
+ 'object',
15112
+ 'base',
15113
+ ] }, options));
13677
15114
  }
13678
15115
 
13679
15116
  function getChildrenHTML(node, typeName) {
13680
15117
  return node
13681
- .literal.replace(new RegExp("(<\\s*" + typeName + "[^>]+?>)|(</" + typeName + "\\s*[>])", 'ig'), '')
15118
+ .literal.replace(new RegExp("(<\\s*" + typeName + "[^>]*>)|(</" + typeName + "\\s*[>])", 'ig'), '')
13682
15119
  .trim();
13683
15120
  }
13684
15121
  function getHTMLAttrsByHTMLString(html) {
@@ -13993,11 +15430,11 @@ function getAdditionalPos(scrollTop, offsetTop, height, targetNodeHeight) {
13993
15430
  var ratio = Math.min((scrollTop - offsetTop) / height, 1);
13994
15431
  return ratio * targetNodeHeight;
13995
15432
  }
13996
- function getParentNodeObj(mdNode) {
13997
- var el = document.querySelector("[data-nodeid=\"" + mdNode.id + "\"]");
15433
+ function getParentNodeObj(previewContent, mdNode) {
15434
+ var el = previewContent.querySelector("[data-nodeid=\"" + mdNode.id + "\"]");
13998
15435
  while (!el || isStyledInlineNode(mdNode)) {
13999
15436
  mdNode = mdNode.parent;
14000
- el = document.querySelector("[data-nodeid=\"" + mdNode.id + "\"]");
15437
+ el = previewContent.querySelector("[data-nodeid=\"" + mdNode.id + "\"]");
14001
15438
  }
14002
15439
  return getNonNestableNodeObj({ mdNode: mdNode, el: el });
14003
15440
  }
@@ -14087,10 +15524,16 @@ var MarkdownPreview = /** @class */ (function () {
14087
15524
  this.sanitizer = sanitizer;
14088
15525
  this.initEvent(highlight);
14089
15526
  this.initContentSection();
15527
+ // To prevent overflowing contents in the viewer
15528
+ if (this.isViewer) {
15529
+ this.previewContent.style.overflowWrap = 'break-word';
15530
+ }
14090
15531
  }
14091
15532
  MarkdownPreview.prototype.initContentSection = function () {
14092
15533
  this.previewContent = createElementWith("<div class=\"" + cls('contents') + "\"></div>");
14093
- this.el.appendChild(this.previewContent);
15534
+ if (!this.isViewer) {
15535
+ this.el.appendChild(this.previewContent);
15536
+ }
14094
15537
  };
14095
15538
  MarkdownPreview.prototype.toggleActive = function (active) {
14096
15539
  toggleClass(this.el, 'active', active);
@@ -14098,6 +15541,9 @@ var MarkdownPreview = /** @class */ (function () {
14098
15541
  MarkdownPreview.prototype.initEvent = function (highlight) {
14099
15542
  var _this = this;
14100
15543
  this.eventEmitter.listen('updatePreview', this.update.bind(this));
15544
+ if (this.isViewer) {
15545
+ return;
15546
+ }
14101
15547
  if (highlight) {
14102
15548
  this.eventEmitter.listen('changeToolbarState', function (_a) {
14103
15549
  var mdNode = _a.mdNode, cursorPos = _a.cursorPos;
@@ -14688,7 +16134,10 @@ var TableOffsetMap = /** @class */ (function () {
14688
16134
  };
14689
16135
  TableOffsetMap.prototype.getNodeAndPos = function (rowIdx, colIdx) {
14690
16136
  var cellInfo = this.rowInfo[rowIdx][colIdx];
14691
- return { node: this.table.nodeAt(cellInfo.offset - 1), pos: cellInfo.offset };
16137
+ return {
16138
+ node: this.table.nodeAt(cellInfo.offset - this.tableStartOffset),
16139
+ pos: cellInfo.offset,
16140
+ };
14692
16141
  };
14693
16142
  TableOffsetMap.prototype.extendedRowspan = function (rowIdx, colIdx) {
14694
16143
  return false;
@@ -15349,47 +16798,49 @@ function getToolbarStateType(node, parentNode) {
15349
16798
  return type;
15350
16799
  }
15351
16800
  function setListNodeToolbarState(type, nodeTypeState) {
15352
- nodeTypeState[type] = true;
16801
+ nodeTypeState[type] = { active: true };
15353
16802
  LIST_TYPES.filter(function (listName) { return listName !== type; }).forEach(function (listType) {
15354
16803
  if (nodeTypeState[listType]) {
15355
16804
  delete nodeTypeState[listType];
15356
16805
  }
15357
16806
  });
15358
16807
  }
15359
- function getMarkTypeStates(from, to, schema) {
15360
- var markTypeState = {};
16808
+ function setMarkTypeStates(from, to, schema, toolbarState) {
15361
16809
  MARK_TYPES.forEach(function (type) {
15362
16810
  var mark = schema.marks[type];
15363
16811
  var marksAtPos = from.marksAcross(to) || [];
15364
16812
  var foundMark = !!mark.isInSet(marksAtPos);
15365
16813
  if (foundMark) {
15366
- markTypeState[type] = true;
16814
+ toolbarState[type] = { active: true };
15367
16815
  }
15368
16816
  });
15369
- return markTypeState;
15370
16817
  }
15371
16818
  function getToolbarState(selection, doc, schema) {
15372
16819
  var $from = selection.$from, $to = selection.$to, from = selection.from, to = selection.to;
15373
- var nodeTypeState = {};
15374
- var markTypeState = {};
16820
+ var toolbarState = {
16821
+ indent: { active: false, disabled: true },
16822
+ outdent: { active: false, disabled: true },
16823
+ };
15375
16824
  doc.nodesBetween(from, to, function (node, _, parentNode) {
15376
16825
  var type = getToolbarStateType(node, parentNode);
15377
16826
  if (includes(EXCEPT_TYPES, type)) {
15378
16827
  return;
15379
16828
  }
15380
16829
  if (includes(LIST_TYPES, type)) {
15381
- setListNodeToolbarState(type, nodeTypeState);
16830
+ setListNodeToolbarState(type, toolbarState);
16831
+ toolbarState.indent.disabled = false;
16832
+ toolbarState.outdent.disabled = false;
15382
16833
  }
15383
16834
  else if (type === 'paragraph' || type === 'text') {
15384
- markTypeState = getMarkTypeStates($from, $to, schema);
16835
+ setMarkTypeStates($from, $to, schema, toolbarState);
15385
16836
  }
15386
16837
  else {
15387
- nodeTypeState[type] = true;
16838
+ toolbarState[type] = { active: true };
15388
16839
  }
15389
16840
  });
15390
- return __assign$1(__assign$1({}, nodeTypeState), markTypeState);
16841
+ return toolbarState;
15391
16842
  }
15392
- function toolbarState(eventEmitter) {
16843
+ function toolbarStateHighlight(eventEmitter) {
15393
16844
  return new Plugin({
15394
16845
  view: function () {
15395
16846
  return {
@@ -15411,6 +16862,7 @@ var CustomBlockView = /** @class */ (function () {
15411
16862
  if (_this.innerEditorView) {
15412
16863
  throw new Error('The editor is already opened.');
15413
16864
  }
16865
+ _this.dom.draggable = false;
15414
16866
  _this.wrapper.style.display = 'none';
15415
16867
  _this.innerViewContainer.style.display = 'block';
15416
16868
  _this.innerEditorView = new EditorView(_this.innerViewContainer, {
@@ -15652,6 +17104,7 @@ var CodeBlockView = /** @class */ (function () {
15652
17104
  this.dom = null;
15653
17105
  this.contentDOM = null;
15654
17106
  this.input = null;
17107
+ this.timer = null;
15655
17108
  this.handleMousedown = function (ev) {
15656
17109
  var target = ev.target;
15657
17110
  var style = getComputedStyle(target, ':after');
@@ -15707,7 +17160,7 @@ var CodeBlockView = /** @class */ (function () {
15707
17160
  input.type = 'text';
15708
17161
  input.value = this.node.attrs.language;
15709
17162
  wrapper.appendChild(input);
15710
- document.querySelector('.toastui-editor.ww-mode').appendChild(wrapper);
17163
+ this.view.dom.parentElement.appendChild(wrapper);
15711
17164
  var wrpperWidth = wrapper.clientWidth;
15712
17165
  css_1(wrapper, {
15713
17166
  top: top + 10 + "px",
@@ -15717,7 +17170,10 @@ var CodeBlockView = /** @class */ (function () {
15717
17170
  this.input = input;
15718
17171
  this.input.addEventListener('blur', function () { return _this.changeLanguage(); });
15719
17172
  this.input.addEventListener('keydown', this.handleKeydown);
15720
- setTimeout(function () { return _this.input.focus(); });
17173
+ this.clearTimer();
17174
+ this.timer = setTimeout(function () {
17175
+ _this.input.focus();
17176
+ });
15721
17177
  };
15722
17178
  CodeBlockView.prototype.bindDOMEvent = function () {
15723
17179
  if (this.dom) {
@@ -15750,6 +17206,12 @@ var CodeBlockView = /** @class */ (function () {
15750
17206
  removeNode$1(parent_1);
15751
17207
  }
15752
17208
  };
17209
+ CodeBlockView.prototype.clearTimer = function () {
17210
+ if (this.timer) {
17211
+ clearTimeout(this.timer);
17212
+ this.timer = null;
17213
+ }
17214
+ };
15753
17215
  CodeBlockView.prototype.stopEvent = function () {
15754
17216
  return true;
15755
17217
  };
@@ -15762,6 +17224,7 @@ var CodeBlockView = /** @class */ (function () {
15762
17224
  };
15763
17225
  CodeBlockView.prototype.destroy = function () {
15764
17226
  this.reset();
17227
+ this.clearTimer();
15765
17228
  if (this.dom) {
15766
17229
  this.dom.removeEventListener('click', this.handleMousedown);
15767
17230
  }
@@ -15925,7 +17388,7 @@ function getContentBetweenFragmentComments(html) {
15925
17388
  if (startFragmentIndex > -1 && endFragmentIndex > -1) {
15926
17389
  html = html.slice(startFragmentIndex + START_FRAGMENT_COMMENT.length, endFragmentIndex);
15927
17390
  }
15928
- return html;
17391
+ return html.replace(/<br[^>]*>/g, ALTERNATIVE_TAG_FOR_BR);
15929
17392
  }
15930
17393
  function convertMsoTableToCompletedTable(html) {
15931
17394
  // wrap with <tr> if html contains dangling <td> tags
@@ -16013,9 +17476,9 @@ function createTableBody(tableBodyRows, maxColumnCount, schema) {
16013
17476
  }
16014
17477
  return schema.nodes.tableBody.create(null, copiedRows);
16015
17478
  }
16016
- function createTableFromPastingTable(rows, schema, startFromBody) {
17479
+ function createTableFromPastingTable(rows, schema, startFromBody, isInTable) {
16017
17480
  var columnCount = getMaxColumnCount(rows);
16018
- if (startFromBody) {
17481
+ if (startFromBody && isInTable) {
16019
17482
  return schema.nodes.table.create(null, [createTableBody(rows, columnCount, schema)]);
16020
17483
  }
16021
17484
  var tableHeadRow = rows[0];
@@ -16026,15 +17489,16 @@ function createTableFromPastingTable(rows, schema, startFromBody) {
16026
17489
  }
16027
17490
  return schema.nodes.table.create(null, nodes);
16028
17491
  }
16029
- function changePastedSlice(slice, schema) {
17492
+ function changePastedSlice(slice, schema, isInTable) {
16030
17493
  var nodes = [];
16031
- slice.content.forEach(function (node) {
17494
+ var content = slice.content, openStart = slice.openStart, openEnd = slice.openEnd;
17495
+ content.forEach(function (node) {
16032
17496
  if (node.type.name === 'table') {
16033
17497
  var tableContent = getTableContentFromSlice(new Slice(Fragment.from(node), 0, 0));
16034
17498
  if (tableContent) {
16035
17499
  var rows = createRowsFromPastingTable(tableContent);
16036
17500
  var startFromBody = tableContent.firstChild.type.name === 'tableBody';
16037
- var table = createTableFromPastingTable(rows, schema, startFromBody);
17501
+ var table = createTableFromPastingTable(rows, schema, startFromBody, isInTable);
16038
17502
  nodes.push(table);
16039
17503
  }
16040
17504
  }
@@ -16042,7 +17506,7 @@ function changePastedSlice(slice, schema) {
16042
17506
  nodes.push(node);
16043
17507
  }
16044
17508
  });
16045
- return new Slice(Fragment.from(nodes), 0, 0);
17509
+ return new Slice(Fragment.from(nodes), openStart, openEnd);
16046
17510
  }
16047
17511
 
16048
17512
  var DUMMY_CELL_SIZE = 4;
@@ -16255,7 +17719,7 @@ var Paragraph = /** @class */ (function (_super) {
16255
17719
  get: function () {
16256
17720
  return {
16257
17721
  content: 'inline*',
16258
- group: 'block listGroup',
17722
+ group: 'block',
16259
17723
  attrs: __assign$1({}, getDefaultCustomAttrs()),
16260
17724
  parseDOM: [{ tag: 'p' }],
16261
17725
  toDOM: function (_a) {
@@ -16378,7 +17842,8 @@ var Heading = /** @class */ (function (_super) {
16378
17842
  });
16379
17843
  Heading.prototype.commands = function () {
16380
17844
  return function (payload) { return function (state, dispatch) {
16381
- return setBlockType(state.schema.nodes.heading, payload)(state, dispatch);
17845
+ var nodeType = state.schema.nodes[payload.level ? 'heading' : 'paragraph'];
17846
+ return setBlockType(nodeType, payload)(state, dispatch);
16382
17847
  }; };
16383
17848
  };
16384
17849
  return Heading;
@@ -16484,7 +17949,7 @@ var BulletList = /** @class */ (function (_super) {
16484
17949
  get: function () {
16485
17950
  return {
16486
17951
  content: 'listItem+',
16487
- group: 'block listGroup',
17952
+ group: 'block',
16488
17953
  attrs: __assign$1({ rawHTML: { default: null } }, getDefaultCustomAttrs()),
16489
17954
  parseDOM: [createDOMInfoParsedRawHTML('ul')],
16490
17955
  toDOM: function (_a) {
@@ -16534,7 +17999,7 @@ var OrderedList = /** @class */ (function (_super) {
16534
17999
  get: function () {
16535
18000
  return {
16536
18001
  content: 'listItem+',
16537
- group: 'block listGroup',
18002
+ group: 'block',
16538
18003
  attrs: __assign$1({ order: { default: 1 }, rawHTML: { default: null } }, getDefaultCustomAttrs()),
16539
18004
  parseDOM: [
16540
18005
  {
@@ -16590,7 +18055,8 @@ var ListItem = /** @class */ (function (_super) {
16590
18055
  Object.defineProperty(ListItem.prototype, "schema", {
16591
18056
  get: function () {
16592
18057
  return {
16593
- content: 'paragraph listGroup*',
18058
+ content: 'paragraph block*',
18059
+ selectable: false,
16594
18060
  attrs: {
16595
18061
  task: { default: false },
16596
18062
  checked: { default: false },
@@ -16791,9 +18257,10 @@ function addParagraphBeforeTable(tr, map, schema) {
16791
18257
  }
16792
18258
  return tr.setSelection(Selection.near(tableStartPos, -1));
16793
18259
  }
16794
- function addParagraphAfterTable(tr, map, schema) {
18260
+ function addParagraphAfterTable(tr, map, schema, forcedAddtion) {
18261
+ if (forcedAddtion === void 0) { forcedAddtion = false; }
16795
18262
  var tableEndPos = tr.doc.resolve(map.tableEndOffset);
16796
- if (!tableEndPos.nodeAfter) {
18263
+ if (forcedAddtion || !tableEndPos.nodeAfter) {
16797
18264
  return addParagraph(tr, tableEndPos, schema);
16798
18265
  }
16799
18266
  return tr.setSelection(Selection.near(tableEndPos, 1));
@@ -17198,6 +18665,29 @@ var Table = /** @class */ (function (_super) {
17198
18665
  return false;
17199
18666
  };
17200
18667
  };
18668
+ Table.prototype.exitTable = function () {
18669
+ return function (state, dispatch) {
18670
+ var selection = state.selection, tr = state.tr, schema = state.schema;
18671
+ var $from = selection.$from;
18672
+ var cell = findNodeBy($from, function (_a) {
18673
+ var type = _a.type;
18674
+ return type.name === 'tableHeadCell' || type.name === 'tableBodyCell';
18675
+ });
18676
+ if (cell) {
18677
+ var para = findNodeBy($from, function (_a) {
18678
+ var type = _a.type;
18679
+ return type.name === 'paragraph';
18680
+ });
18681
+ if (para) {
18682
+ var anchor = getResolvedSelection(selection).anchor;
18683
+ var map = TableOffsetMap.create(anchor);
18684
+ dispatch(addParagraphAfterTable(tr, map, schema, true));
18685
+ return true;
18686
+ }
18687
+ }
18688
+ return false;
18689
+ };
18690
+ };
17201
18691
  Table.prototype.commands = function () {
17202
18692
  return {
17203
18693
  addTable: this.addTable(),
@@ -17224,6 +18714,7 @@ var Table = /** @class */ (function (_super) {
17224
18714
  'Mod-Backspace': deleteCellContent,
17225
18715
  Delete: deleteCellContent,
17226
18716
  'Mod-Delete': deleteCellContent,
18717
+ 'Mod-Enter': this.exitTable(),
17227
18718
  };
17228
18719
  };
17229
18720
  return Table;
@@ -17438,9 +18929,13 @@ var Image = /** @class */ (function (_super) {
17438
18929
  {
17439
18930
  tag: 'img[src]',
17440
18931
  getAttrs: function (dom) {
17441
- var imageUrl = dom.getAttribute('src') || '';
17442
- var rawHTML = dom.getAttribute('data-raw-html');
17443
- return __assign$1({ imageUrl: sanitizeXSSAttributeValue(imageUrl), altText: dom.getAttribute('alt') }, (rawHTML && { rawHTML: rawHTML }));
18932
+ var sanitizedDOM = sanitizeHTML(dom, { RETURN_DOM_FRAGMENT: true })
18933
+ .firstChild;
18934
+ var imageUrl = sanitizedDOM.getAttribute('src') || '';
18935
+ var rawHTML = sanitizedDOM.getAttribute('data-raw-html');
18936
+ var altText = sanitizedDOM.getAttribute('alt');
18937
+ return __assign$1({ imageUrl: imageUrl,
18938
+ altText: altText }, (rawHTML && { rawHTML: rawHTML }));
17444
18939
  },
17445
18940
  },
17446
18941
  ],
@@ -17448,7 +18943,7 @@ var Image = /** @class */ (function (_super) {
17448
18943
  var attrs = _a.attrs;
17449
18944
  return [
17450
18945
  attrs.rawHTML || 'img',
17451
- __assign$1(__assign$1({ src: attrs.imageUrl }, (attrs.altText && { alt: attrs.altText })), getCustomAttrs(attrs)),
18946
+ __assign$1(__assign$1({ src: escapeXml$1(attrs.imageUrl) }, (attrs.altText && { alt: attrs.altText })), getCustomAttrs(attrs)),
17452
18947
  ];
17453
18948
  },
17454
18949
  };
@@ -17463,7 +18958,7 @@ var Image = /** @class */ (function (_super) {
17463
18958
  if (!imageUrl) {
17464
18959
  return false;
17465
18960
  }
17466
- var node = schema.nodes.image.createAndFill(__assign$1({ imageUrl: encodeMarkdownText(imageUrl) }, (altText && { altText: altText })));
18961
+ var node = schema.nodes.image.createAndFill(__assign$1({ imageUrl: imageUrl }, (altText && { altText: altText })));
17467
18962
  dispatch(tr.replaceSelectionWith(node).scrollIntoView());
17468
18963
  return true;
17469
18964
  }; };
@@ -17708,15 +19203,18 @@ var Link = /** @class */ (function (_super) {
17708
19203
  get: function () {
17709
19204
  var _this = this;
17710
19205
  return {
17711
- attrs: __assign$1({ linkUrl: { default: '' }, linkText: { default: null }, rawHTML: { default: null } }, getDefaultCustomAttrs()),
19206
+ attrs: __assign$1({ linkUrl: { default: '' }, title: { default: null }, rawHTML: { default: null } }, getDefaultCustomAttrs()),
17712
19207
  inclusive: false,
17713
19208
  parseDOM: [
17714
19209
  {
17715
19210
  tag: 'a[href]',
17716
19211
  getAttrs: function (dom) {
17717
- var href = dom.getAttribute('href') || '';
17718
- var rawHTML = dom.getAttribute('data-raw-html');
17719
- return __assign$1({ linkUrl: sanitizeXSSAttributeValue(href), linkText: dom.textContent }, (rawHTML && { rawHTML: rawHTML }));
19212
+ var sanitizedDOM = sanitizeHTML(dom, { RETURN_DOM_FRAGMENT: true })
19213
+ .firstChild;
19214
+ var href = sanitizedDOM.getAttribute('href') || '';
19215
+ var title = sanitizedDOM.getAttribute('title') || '';
19216
+ var rawHTML = sanitizedDOM.getAttribute('data-raw-html');
19217
+ return __assign$1({ linkUrl: href, title: title }, (rawHTML && { rawHTML: rawHTML }));
17720
19218
  },
17721
19219
  },
17722
19220
  ],
@@ -17724,7 +19222,7 @@ var Link = /** @class */ (function (_super) {
17724
19222
  var attrs = _a.attrs;
17725
19223
  return [
17726
19224
  attrs.rawHTML || 'a',
17727
- __assign$1(__assign$1({ href: attrs.linkUrl }, _this.linkAttributes), getCustomAttrs(attrs)),
19225
+ __assign$1(__assign$1({ href: escapeXml$1(attrs.linkUrl) }, _this.linkAttributes), getCustomAttrs(attrs)),
17728
19226
  ];
17729
19227
  },
17730
19228
  };
@@ -17738,10 +19236,7 @@ var Link = /** @class */ (function (_super) {
17738
19236
  var schema = state.schema, tr = state.tr, selection = state.selection;
17739
19237
  var empty = selection.empty, from = selection.from, to = selection.to;
17740
19238
  if (from && to && linkUrl) {
17741
- var attrs = {
17742
- linkUrl: encodeMarkdownText(linkUrl),
17743
- linkText: escapeMarkdownText(linkText),
17744
- };
19239
+ var attrs = { linkUrl: linkUrl };
17745
19240
  var mark = schema.mark('link', attrs);
17746
19241
  if (empty && linkText) {
17747
19242
  var node = createTextNode$1(schema, linkText, mark);
@@ -17858,6 +19353,13 @@ var CustomBlock = /** @class */ (function (_super) {
17858
19353
  enumerable: false,
17859
19354
  configurable: true
17860
19355
  });
19356
+ CustomBlock.prototype.commands = function () {
19357
+ return function (payload) { return function (state, dispatch) {
19358
+ return (payload === null || payload === void 0 ? void 0 : payload.info)
19359
+ ? setBlockType(state.schema.nodes.customBlock, payload)(state, dispatch)
19360
+ : false;
19361
+ }; };
19362
+ };
17861
19363
  return CustomBlock;
17862
19364
  }(Node$2));
17863
19365
 
@@ -17879,8 +19381,10 @@ var FrontMatter = /** @class */ (function (_super) {
17879
19381
  content: 'text*',
17880
19382
  group: 'block',
17881
19383
  code: true,
19384
+ defining: true,
17882
19385
  parseDOM: [
17883
19386
  {
19387
+ preserveWhitespace: 'full',
17884
19388
  tag: 'div[data-front-matter]',
17885
19389
  },
17886
19390
  ],
@@ -17909,6 +19413,51 @@ var FrontMatter = /** @class */ (function (_super) {
17909
19413
  return FrontMatter;
17910
19414
  }(Node$2));
17911
19415
 
19416
+ var HTMLComment = /** @class */ (function (_super) {
19417
+ __extends$1(HTMLComment, _super);
19418
+ function HTMLComment() {
19419
+ return _super !== null && _super.apply(this, arguments) || this;
19420
+ }
19421
+ Object.defineProperty(HTMLComment.prototype, "name", {
19422
+ get: function () {
19423
+ return 'htmlComment';
19424
+ },
19425
+ enumerable: false,
19426
+ configurable: true
19427
+ });
19428
+ Object.defineProperty(HTMLComment.prototype, "schema", {
19429
+ get: function () {
19430
+ return {
19431
+ content: 'text*',
19432
+ group: 'block',
19433
+ code: true,
19434
+ defining: true,
19435
+ parseDOM: [{ preserveWhitespace: 'full', tag: 'div[data-html-comment]' }],
19436
+ toDOM: function () {
19437
+ return ['div', { 'data-html-comment': 'true' }, 0];
19438
+ },
19439
+ };
19440
+ },
19441
+ enumerable: false,
19442
+ configurable: true
19443
+ });
19444
+ HTMLComment.prototype.commands = function () {
19445
+ return function () { return function (state, dispatch, view) {
19446
+ var $from = state.selection.$from;
19447
+ if (view.endOfTextblock('down') && $from.node().type.name === 'htmlComment') {
19448
+ return exitCode(state, dispatch);
19449
+ }
19450
+ return false;
19451
+ }; };
19452
+ };
19453
+ HTMLComment.prototype.keymaps = function () {
19454
+ return {
19455
+ Enter: this.commands()(),
19456
+ };
19457
+ };
19458
+ return HTMLComment;
19459
+ }(Node$2));
19460
+
17912
19461
  function createSpecs(linkAttributes) {
17913
19462
  return new SpecManager([
17914
19463
  new Doc(),
@@ -17936,6 +19485,7 @@ function createSpecs(linkAttributes) {
17936
19485
  new CustomBlock(),
17937
19486
  new FrontMatter(),
17938
19487
  new Widget(),
19488
+ new HTMLComment(),
17939
19489
  ]);
17940
19490
  }
17941
19491
 
@@ -17981,7 +19531,7 @@ var WysiwygEditor = /** @class */ (function (_super) {
17981
19531
  tableSelection(),
17982
19532
  tableContextMenu(this.eventEmitter),
17983
19533
  task(),
17984
- toolbarState(this.eventEmitter)
19534
+ toolbarStateHighlight(this.eventEmitter)
17985
19535
  ], this.createPluginProps()));
17986
19536
  };
17987
19537
  WysiwygEditor.prototype.createPluginNodeViews = function () {
@@ -18020,7 +19570,9 @@ var WysiwygEditor = /** @class */ (function (_super) {
18020
19570
  _this.eventEmitter.emit('setFocusedNode', state.selection.$from.node(1));
18021
19571
  },
18022
19572
  transformPastedHTML: changePastedHTML,
18023
- transformPasted: function (slice) { return changePastedSlice(slice, _this.schema); },
19573
+ transformPasted: function (slice) {
19574
+ return changePastedSlice(slice, _this.schema, isInTableNode(_this.view.state.selection.$from));
19575
+ },
18024
19576
  handlePaste: function (view, _, slice) { return pasteToTable(view, slice); },
18025
19577
  handleKeyDown: function (_, ev) {
18026
19578
  _this.eventEmitter.emit('keydown', _this.editorType, ev);
@@ -18029,12 +19581,16 @@ var WysiwygEditor = /** @class */ (function (_super) {
18029
19581
  handleDOMEvents: {
18030
19582
  paste: function (_, ev) {
18031
19583
  var clipboardData = ev.clipboardData || window.clipboardData;
18032
- var items = clipboardData && clipboardData.items;
19584
+ var items = clipboardData === null || clipboardData === void 0 ? void 0 : clipboardData.items;
18033
19585
  if (items) {
18034
- var imageBlob = pasteImageOnly(items);
18035
- if (imageBlob) {
18036
- ev.preventDefault();
18037
- emitImageBlobHook(_this.eventEmitter, imageBlob, ev.type);
19586
+ var containRtfItem = toArray_1(items).some(function (item) { return item.kind === 'string' && item.type === 'text/rtf'; });
19587
+ // if it contains rtf, it's most likely copy paste from office -> no image
19588
+ if (!containRtfItem) {
19589
+ var imageBlob = pasteImageOnly(items);
19590
+ if (imageBlob) {
19591
+ ev.preventDefault();
19592
+ emitImageBlobHook(_this.eventEmitter, imageBlob, ev.type);
19593
+ }
18038
19594
  }
18039
19595
  }
18040
19596
  return false;
@@ -18098,7 +19654,7 @@ var WysiwygEditor = /** @class */ (function (_super) {
18098
19654
  var _a = this.view.state, tr = _a.tr, doc = _a.doc;
18099
19655
  this.view.dispatch(tr.replaceWith(0, doc.content.size, newDoc));
18100
19656
  if (cursorToEnd) {
18101
- this.moveCursorToEnd();
19657
+ this.moveCursorToEnd(true);
18102
19658
  }
18103
19659
  };
18104
19660
  WysiwygEditor.prototype.setSelection = function (start, end) {
@@ -18162,7 +19718,11 @@ var isNull = isNull_1;
18162
19718
  * @returns {boolean} Is existy?
18163
19719
  * @memberof module:type
18164
19720
  * @example
18165
- * var isExisty = require('tui-code-snippet/type/isExisty'); // node, commonjs
19721
+ * // ES6
19722
+ * import isExisty from 'tui-code-snippet/type/isExisty');
19723
+ *
19724
+ * // CommonJS
19725
+ * const isExisty = require('tui-code-snippet/type/isExisty');
18166
19726
  *
18167
19727
  * isExisty(''); //true
18168
19728
  * isExisty(0); //true
@@ -18237,6 +19797,7 @@ var eventTypeList = [
18237
19797
  'mixinTableOffsetMapPrototype',
18238
19798
  'setFocusedNode',
18239
19799
  'removePopupWidget',
19800
+ 'query',
18240
19801
  // provide event for user
18241
19802
  'openPopup',
18242
19803
  'closePopup',
@@ -18244,6 +19805,7 @@ var eventTypeList = [
18244
19805
  'beforePreviewRender',
18245
19806
  'beforeConvertWysiwygToMarkdown',
18246
19807
  'load',
19808
+ 'loadUI',
18247
19809
  'change',
18248
19810
  'caretChange',
18249
19811
  'destroy',
@@ -18491,6 +20053,9 @@ function isInlineNode(_a) {
18491
20053
  var type = _a.type;
18492
20054
  return includes(['text', 'strong', 'emph', 'strike', 'image', 'link', 'code'], type);
18493
20055
  }
20056
+ function isSoftbreak(mdNode) {
20057
+ return (mdNode === null || mdNode === void 0 ? void 0 : mdNode.type) === 'softbreak';
20058
+ }
18494
20059
  function isListNode(_a) {
18495
20060
  var type = _a.type, literal = _a.literal;
18496
20061
  var matched = type === 'htmlInline' && literal.match(reHTMLTag);
@@ -18509,11 +20074,15 @@ function getListItemAttrs(_a) {
18509
20074
  var checked = /data-task-checked/.test(literal);
18510
20075
  return { task: task, checked: checked };
18511
20076
  }
18512
- function getMatchedAttributeValue(rawHTML, attrName) {
20077
+ function getMatchedAttributeValue(rawHTML) {
20078
+ var attrNames = [];
20079
+ for (var _i = 1; _i < arguments.length; _i++) {
20080
+ attrNames[_i - 1] = arguments[_i];
20081
+ }
18513
20082
  var wrapper = document.createElement('div');
18514
- wrapper.innerHTML = rawHTML;
20083
+ wrapper.innerHTML = sanitizeHTML(rawHTML);
18515
20084
  var el = wrapper.firstChild;
18516
- return el.getAttribute(attrName) || '';
20085
+ return attrNames.map(function (attrName) { return el.getAttribute(attrName) || ''; });
18517
20086
  }
18518
20087
  function createConvertors(convertors) {
18519
20088
  var convertorMap = {};
@@ -18567,9 +20136,9 @@ var convertors = {
18567
20136
  var tag = node.literal;
18568
20137
  var link = state.schema.marks.link;
18569
20138
  if (openTagName) {
18570
- var linkUrl = getMatchedAttributeValue(tag, 'href');
20139
+ var linkUrl = getMatchedAttributeValue(tag, 'href')[0];
18571
20140
  state.openMark(link.create({
18572
- linkUrl: sanitizeXSSAttributeValue(linkUrl),
20141
+ linkUrl: linkUrl,
18573
20142
  rawHTML: openTagName,
18574
20143
  }));
18575
20144
  }
@@ -18579,11 +20148,10 @@ var convertors = {
18579
20148
  },
18580
20149
  img: function (state, node, openTagName) {
18581
20150
  var tag = node.literal;
18582
- var imageUrl = getMatchedAttributeValue(tag, 'src');
18583
- if (imageUrl) {
18584
- var altText = getMatchedAttributeValue(tag, 'alt');
20151
+ if (openTagName) {
20152
+ var _a = getMatchedAttributeValue(tag, 'src', 'alt'), imageUrl = _a[0], altText = _a[1];
18585
20153
  var image = state.schema.nodes.image;
18586
- state.addNode(image, __assign$1({ rawHTML: openTagName, imageUrl: sanitizeXSSAttributeValue(imageUrl) }, (altText && { altText: altText })));
20154
+ state.addNode(image, __assign$1({ rawHTML: openTagName, imageUrl: imageUrl }, (altText && { altText: altText })));
18587
20155
  }
18588
20156
  },
18589
20157
  hr: function (state, _, openTagName) {
@@ -18593,11 +20161,22 @@ var convertors = {
18593
20161
  var paragraph = state.schema.nodes.paragraph;
18594
20162
  var parent = node.parent, prev = node.prev, next = node.next;
18595
20163
  if ((parent === null || parent === void 0 ? void 0 : parent.type) === 'paragraph') {
18596
- if (prev && !(prev.type === 'htmlInline' && prev.literal.match(CLOSE_TAG))) {
20164
+ // should open a paragraph node when line text has only <br> tag
20165
+ // ex) first line\n\n<br>\nfourth line
20166
+ if (isSoftbreak(prev)) {
18597
20167
  state.openNode(paragraph);
18598
20168
  }
18599
- if (next) {
20169
+ // should close a paragraph node when line text has only <br> tag
20170
+ // ex) first line\n\n<br>\nfourth line
20171
+ if (isSoftbreak(next)) {
20172
+ state.closeNode();
20173
+ // should close a paragraph node and open a paragraph node to separate between blocks
20174
+ // when <br> tag is in the middle of the paragraph
20175
+ // ex) first <br>line\nthird line
20176
+ }
20177
+ else if (next) {
18600
20178
  state.closeNode();
20179
+ state.openNode(paragraph);
18601
20180
  }
18602
20181
  }
18603
20182
  else if ((parent === null || parent === void 0 ? void 0 : parent.type) === 'tableCell') {
@@ -18664,7 +20243,7 @@ var convertors = {
18664
20243
  var htmlToWwConvertors = createConvertors(convertors);
18665
20244
 
18666
20245
  function isBRTag(node) {
18667
- return node.type === 'htmlInline' && /<br ?\/?>/.test(node.literal);
20246
+ return node.type === 'htmlInline' && reBR.test(node.literal);
18668
20247
  }
18669
20248
  function addRawHTMLAttributeToDOM(parent) {
18670
20249
  toArray_1(parent.childNodes).forEach(function (child) {
@@ -18789,7 +20368,7 @@ var toWwConvertors = {
18789
20368
  var link = state.schema.marks.link;
18790
20369
  var _b = node, destination = _b.destination, title = _b.title;
18791
20370
  if (entering) {
18792
- var attrs = __assign$1(__assign$1({ linkUrl: destination }, (title && { linkText: title })), customAttrs);
20371
+ var attrs = __assign$1({ linkUrl: destination, title: title }, customAttrs);
18793
20372
  state.openMark(link.create(attrs));
18794
20373
  }
18795
20374
  else {
@@ -18855,7 +20434,7 @@ var toWwConvertors = {
18855
20434
  var tablePart = node.parent.parent;
18856
20435
  var cell = tablePart.type === 'tableHead' ? tableHeadCell : tableBodyCell;
18857
20436
  var table = tablePart.parent;
18858
- var align = table.columns[node.startIdx].align;
20437
+ var align = (table.columns[node.startIdx] || {}).align;
18859
20438
  var attrs = __assign$1({}, node.attrs);
18860
20439
  if (align) {
18861
20440
  attrs.align = align;
@@ -18912,10 +20491,11 @@ var toWwConvertors = {
18912
20491
  var openTagName = matched[1], closeTagName = matched[3];
18913
20492
  var typeName = (openTagName || closeTagName).toLowerCase();
18914
20493
  var markType = state.schema.marks[typeName];
20494
+ var sanitizedHTML = sanitizeHTML(html);
18915
20495
  // for user defined html schema
18916
20496
  if (markType === null || markType === void 0 ? void 0 : markType.spec.attrs.htmlInline) {
18917
20497
  if (openTagName) {
18918
- var htmlAttrs = getHTMLAttrsByHTMLString(html);
20498
+ var htmlAttrs = getHTMLAttrsByHTMLString(sanitizedHTML);
18919
20499
  state.openMark(markType.create({ htmlAttrs: htmlAttrs }));
18920
20500
  }
18921
20501
  else {
@@ -18932,25 +20512,34 @@ var toWwConvertors = {
18932
20512
  htmlBlock: function (state, node) {
18933
20513
  var html = node.literal;
18934
20514
  var container = document.createElement('div');
18935
- var matched = html.match(reHTMLTag);
18936
- var openTagName = matched[1], closeTagName = matched[3];
18937
- var typeName = (openTagName || closeTagName).toLowerCase();
18938
- var nodeType = state.schema.nodes[typeName];
18939
- // for user defined html schema
18940
- if (nodeType === null || nodeType === void 0 ? void 0 : nodeType.spec.attrs.htmlBlock) {
18941
- var htmlAttrs = getHTMLAttrsByHTMLString(html);
18942
- var childrenHTML = getChildrenHTML(node, typeName);
18943
- state.addNode(nodeType, { htmlAttrs: htmlAttrs, childrenHTML: childrenHTML });
20515
+ var isHTMLComment = reHTMLComment.test(html);
20516
+ if (isHTMLComment) {
20517
+ state.openNode(state.schema.nodes.htmlComment);
20518
+ state.addText(node.literal);
20519
+ state.closeNode();
18944
20520
  }
18945
20521
  else {
18946
- container.innerHTML = html;
18947
- addRawHTMLAttributeToDOM(container);
18948
- state.convertByDOMParser(container);
20522
+ var matched = html.match(reHTMLTag);
20523
+ var openTagName = matched[1], closeTagName = matched[3];
20524
+ var typeName = (openTagName || closeTagName).toLowerCase();
20525
+ var nodeType = state.schema.nodes[typeName];
20526
+ var sanitizedHTML = sanitizeHTML(html);
20527
+ // for user defined html schema
20528
+ if (nodeType === null || nodeType === void 0 ? void 0 : nodeType.spec.attrs.htmlBlock) {
20529
+ var htmlAttrs = getHTMLAttrsByHTMLString(sanitizedHTML);
20530
+ var childrenHTML = getChildrenHTML(node, typeName);
20531
+ state.addNode(nodeType, { htmlAttrs: htmlAttrs, childrenHTML: childrenHTML });
20532
+ }
20533
+ else {
20534
+ container.innerHTML = sanitizedHTML;
20535
+ addRawHTMLAttributeToDOM(container);
20536
+ state.convertByDOMParser(container);
20537
+ }
18949
20538
  }
18950
20539
  },
18951
20540
  customInline: function (state, node, _a) {
18952
20541
  var entering = _a.entering, skipChildren = _a.skipChildren;
18953
- var info = node.info;
20542
+ var _b = node, info = _b.info, firstChild = _b.firstChild;
18954
20543
  var schema = state.schema;
18955
20544
  if (info.indexOf('widget') !== -1 && entering) {
18956
20545
  var content = getWidgetContent(node);
@@ -18959,6 +20548,13 @@ var toWwConvertors = {
18959
20548
  schema.text(createWidgetContent(info, content)),
18960
20549
  ]);
18961
20550
  }
20551
+ else {
20552
+ var text = '$$';
20553
+ if (entering) {
20554
+ text += firstChild ? info + " " : info;
20555
+ }
20556
+ state.addText(text);
20557
+ }
18962
20558
  },
18963
20559
  };
18964
20560
  function createWwConvertors(customConvertors) {
@@ -18974,7 +20570,7 @@ function createWwConvertors(customConvertors) {
18974
20570
  var wwConvertor = toWwConvertors[type];
18975
20571
  if (wwConvertor && !includes(['htmlBlock', 'htmlInline'], type)) {
18976
20572
  convertors[type] = function (state, node, context) {
18977
- context.origin = function () { return orgConvertors[type](node, context); };
20573
+ context.origin = function () { return orgConvertors[type](node, context, orgConvertors); };
18978
20574
  var tokens = customConvertors[type](node, context);
18979
20575
  var attrs;
18980
20576
  if (tokens) {
@@ -19054,6 +20650,27 @@ var ToWwConvertorState = /** @class */ (function () {
19054
20650
  var doc = DOMParser.fromSchema(this.schema).parse(root);
19055
20651
  doc.content.forEach(function (node) { return _this.push(node); });
19056
20652
  };
20653
+ ToWwConvertorState.prototype.closeUnmatchedHTMLInline = function (node, entering) {
20654
+ var _a;
20655
+ if (!entering && node.type !== 'htmlInline') {
20656
+ var length_1 = this.stack.length - 1;
20657
+ for (var i = length_1; i >= 0; i -= 1) {
20658
+ var nodeInfo = this.stack[i];
20659
+ if ((_a = nodeInfo.attrs) === null || _a === void 0 ? void 0 : _a.rawHTML) {
20660
+ if (nodeInfo.content.length) {
20661
+ this.closeNode();
20662
+ }
20663
+ else {
20664
+ // just pop useless unmatched html inline node
20665
+ this.stack.pop();
20666
+ }
20667
+ }
20668
+ else {
20669
+ break;
20670
+ }
20671
+ }
20672
+ }
20673
+ };
19057
20674
  ToWwConvertorState.prototype.convert = function (mdNode, infoForPosSync) {
19058
20675
  var walker = mdNode.walker();
19059
20676
  var event = walker.next();
@@ -19071,6 +20688,7 @@ var ToWwConvertorState = /** @class */ (function () {
19071
20688
  skipped = true;
19072
20689
  },
19073
20690
  };
20691
+ this_1.closeUnmatchedHTMLInline(node, entering);
19074
20692
  convertor(this_1, node, context);
19075
20693
  if ((infoForPosSync === null || infoForPosSync === void 0 ? void 0 : infoForPosSync.node) === node) {
19076
20694
  var pos = this_1.stack.reduce(function (nodeSize, stackItem) {
@@ -19142,7 +20760,13 @@ var nodeTypeWriters = {
19142
20760
  text: function (state, _a) {
19143
20761
  var _b;
19144
20762
  var node = _a.node;
19145
- state.text((_b = node.text) !== null && _b !== void 0 ? _b : '');
20763
+ var text = (_b = node.text) !== null && _b !== void 0 ? _b : '';
20764
+ if ((node.marks || []).some(function (mark) { return mark.type.name === 'link'; })) {
20765
+ state.text(escapeTextForLink(text), false);
20766
+ }
20767
+ else {
20768
+ state.text(text);
20769
+ }
19146
20770
  },
19147
20771
  paragraph: function (state, _a) {
19148
20772
  var node = _a.node, parent = _a.parent, _b = _a.index, index = _b === void 0 ? 0 : _b;
@@ -19307,9 +20931,19 @@ var nodeTypeWriters = {
19307
20931
  var text = _a.text;
19308
20932
  state.write(text);
19309
20933
  },
19310
- html: function (state, _, _a) {
19311
- var text = _a.text;
20934
+ html: function (state, _a, _b) {
20935
+ var node = _a.node;
20936
+ var text = _b.text;
20937
+ state.write(text);
20938
+ if (node.attrs.htmlBlock) {
20939
+ state.closeBlock(node);
20940
+ }
20941
+ },
20942
+ htmlComment: function (state, _a, _b) {
20943
+ var node = _a.node;
20944
+ var text = _b.text;
19312
20945
  state.write(text);
20946
+ state.closeBlock(node);
19313
20947
  },
19314
20948
  };
19315
20949
  function write(type, _a) {
@@ -19466,13 +21100,13 @@ var toMdConvertors = {
19466
21100
  image: function (_a) {
19467
21101
  var node = _a.node;
19468
21102
  var attrs = node.attrs;
19469
- var altText = escape$1(attrs.altText || '');
19470
- var imageUrl = escape$1(attrs.imageUrl);
19471
- var altAttr = altText ? " alt=\"" + altText + "\"" : '';
21103
+ var rawHTML = attrs.rawHTML, altText = attrs.altText;
21104
+ var imageUrl = attrs.imageUrl.replace(/&amp;/g, '&');
21105
+ var altAttr = altText ? " alt=\"" + escapeXml$1(altText) + "\"" : '';
19472
21106
  return {
19473
- rawHTML: attrs.rawHTML ? "<" + attrs.rawHTML + " src=\"" + imageUrl + "\"" + altAttr + ">" : null,
21107
+ rawHTML: rawHTML ? "<" + rawHTML + " src=\"" + escapeXml$1(imageUrl) + "\"" + altAttr + ">" : null,
19474
21108
  attrs: {
19475
- altText: altText,
21109
+ altText: escapeTextForLink(altText || ''),
19476
21110
  imageUrl: imageUrl,
19477
21111
  },
19478
21112
  };
@@ -19535,17 +21169,17 @@ var toMdConvertors = {
19535
21169
  var node = _a.node;
19536
21170
  var entering = _b.entering;
19537
21171
  var attrs = node.attrs;
19538
- var linkUrl = escape$1(attrs.linkUrl);
19539
- var rawHTML = attrs.rawHTML;
21172
+ var title = attrs.title, rawHTML = attrs.rawHTML;
21173
+ var linkUrl = attrs.linkUrl.replace(/&amp;/g, '&');
21174
+ var titleAttr = title ? " title=\"" + escapeXml$1(title) + "\"" : '';
19540
21175
  if (entering) {
19541
21176
  return {
19542
21177
  delim: '[',
19543
- rawHTML: rawHTML ? "<" + rawHTML + " href=\"" + linkUrl + "\">" : null,
21178
+ rawHTML: rawHTML ? "<" + rawHTML + " href=\"" + escapeXml$1(linkUrl) + "\"" + titleAttr + ">" : null,
19544
21179
  };
19545
21180
  }
19546
- var linkText = attrs.title ? " " + quote(attrs.linkText) : '';
19547
21181
  return {
19548
- delim: "](" + linkText + linkUrl + ")",
21182
+ delim: "](" + linkUrl + (title ? " " + quote(escapeTextForLink(title)) : '') + ")",
19549
21183
  rawHTML: getCloseRawHTML(rawHTML),
19550
21184
  };
19551
21185
  },
@@ -19563,6 +21197,12 @@ var toMdConvertors = {
19563
21197
  rawHTML: rawHTML,
19564
21198
  };
19565
21199
  },
21200
+ htmlComment: function (_a) {
21201
+ var node = _a.node;
21202
+ return {
21203
+ text: node.textContent,
21204
+ };
21205
+ },
19566
21206
  // html inline node, html block node
19567
21207
  html: function (_a, _b) {
19568
21208
  var node = _a.node;
@@ -19572,7 +21212,8 @@ var toMdConvertors = {
19572
21212
  var openTag = "<" + tagName;
19573
21213
  var closeTag = "</" + tagName + ">";
19574
21214
  Object.keys(attrs).forEach(function (attrName) {
19575
- openTag += " " + attrName + "=\"" + attrs[attrName] + "\"";
21215
+ // To prevent broken converting when attributes has double quote string
21216
+ openTag += " " + attrName + "=\"" + attrs[attrName].replace(/"/g, "'") + "\"";
19576
21217
  });
19577
21218
  openTag += '>';
19578
21219
  if (node.attrs.htmlInline) {
@@ -20036,6 +21677,14 @@ function getPluginInfo(plugins, eventEmitter, usageStatistics) {
20036
21677
  var TASK_ATTR_NAME = 'data-task';
20037
21678
  var DISABLED_TASK_ATTR_NAME = 'data-task-disabled';
20038
21679
  var TASK_CHECKED_CLASS_NAME = 'checked';
21680
+ function registerHTMLTagToWhitelist(convertorMap) {
21681
+ ['htmlBlock', 'htmlInline'].forEach(function (htmlType) {
21682
+ if (convertorMap[htmlType]) {
21683
+ // register tag white list for preventing to remove the html in sanitizer
21684
+ Object.keys(convertorMap[htmlType]).forEach(function (type) { return registerTagWhitelistIfPossible(type); });
21685
+ }
21686
+ });
21687
+ }
20039
21688
  /**
20040
21689
  * Class ToastUIEditorViewer
20041
21690
  * @param {object} options Option object
@@ -20081,6 +21730,7 @@ var ToastUIEditorViewer = /** @class */ (function () {
20081
21730
  frontMatter: frontMatter,
20082
21731
  sanitizer: customHTMLSanitizer || sanitizeHTML,
20083
21732
  };
21733
+ registerHTMLTagToWhitelist(rendererOptions.customHTMLRenderer);
20084
21734
  if (this.options.events) {
20085
21735
  forEachOwnProperties_1(this.options.events, function (fn, key) {
20086
21736
  _this.on(key, fn);
@@ -20101,7 +21751,7 @@ var ToastUIEditorViewer = /** @class */ (function () {
20101
21751
  customParser: markdownParsers,
20102
21752
  });
20103
21753
  this.preview = new MarkdownPreview(this.eventEmitter, __assign$1(__assign$1({}, rendererOptions), { isViewer: true }));
20104
- on_1(this.preview.el, 'mousedown', this.toggleTask.bind(this));
21754
+ on_1(this.preview.previewContent, 'mousedown', this.toggleTask.bind(this));
20105
21755
  if (initialValue) {
20106
21756
  this.setMarkdown(initialValue);
20107
21757
  }
@@ -20229,7 +21879,7 @@ function createMdLikeNode(node) {
20229
21879
  };
20230
21880
  var nodeTypeMap = {
20231
21881
  heading: { level: attrs.level },
20232
- link: { destination: attrs.linkUrl, title: attrs.linkText },
21882
+ link: { destination: attrs.linkUrl, title: attrs.title },
20233
21883
  image: { destination: attrs.imageUrl },
20234
21884
  codeBlock: { info: attrs.language },
20235
21885
  bulletList: { type: 'list', listData: { type: 'bullet' } },
@@ -20367,6 +22017,7 @@ var ScrollSync = /** @class */ (function () {
20367
22017
  this.latestPreviewScrollTop = null;
20368
22018
  this.blockedScroll = null;
20369
22019
  this.active = true;
22020
+ this.timer = null;
20370
22021
  var previewRoot = preview.previewContent, previewEl = preview.el;
20371
22022
  this.previewRoot = previewRoot;
20372
22023
  this.previewEl = previewEl;
@@ -20379,10 +22030,11 @@ var ScrollSync = /** @class */ (function () {
20379
22030
  ScrollSync.prototype.addScrollSyncEvent = function () {
20380
22031
  var _this = this;
20381
22032
  this.eventEmitter.listen('afterPreviewRender', function () {
22033
+ _this.clearTimer();
20382
22034
  // Immediately after the 'afterPreviewRender' event has occurred,
20383
22035
  // browser rendering is not yet complete.
20384
22036
  // So the size of elements can not be accurately measured.
20385
- setTimeout(function () {
22037
+ _this.timer = setTimeout(function () {
20386
22038
  _this.syncPreviewScrollTop(true);
20387
22039
  }, 200);
20388
22040
  });
@@ -20409,7 +22061,7 @@ var ScrollSync = /** @class */ (function () {
20409
22061
  var pos = this.mdEditor.getSelection();
20410
22062
  var firstMdNode = this.toastMark.findFirstNodeAtLine(pos[0][0]);
20411
22063
  var previewHeight = this.previewEl.clientHeight;
20412
- var el = getParentNodeObj(firstMdNode).el;
22064
+ var el = getParentNodeObj(this.previewRoot, firstMdNode).el;
20413
22065
  var totalOffsetTop = getTotalOffsetTop(el, this.previewRoot) || el.offsetTop;
20414
22066
  var nodeHeight = el.clientHeight;
20415
22067
  // multiply 0.5 for calculating the position in the middle of preview area
@@ -20441,7 +22093,7 @@ var ScrollSync = /** @class */ (function () {
20441
22093
  targetScrollTop = scrollTopByEditing;
20442
22094
  }
20443
22095
  else {
20444
- var _d = getParentNodeObj(firstMdNode), el = _d.el, mdNode = _d.mdNode;
22096
+ var _d = getParentNodeObj(this.previewRoot, firstMdNode), el = _d.el, mdNode = _d.mdNode;
20445
22097
  var _e = getEditorRangeHeightInfo(doc, mdNode, children), height = _e.height, rect = _e.rect;
20446
22098
  var totalOffsetTop = getTotalOffsetTop(el, previewRoot) || el.offsetTop;
20447
22099
  var nodeHeight = el.clientHeight;
@@ -20469,7 +22121,7 @@ var ScrollSync = /** @class */ (function () {
20469
22121
  }
20470
22122
  var children = dom.children;
20471
22123
  var mdNodeId = Number(targetNode.getAttribute('data-nodeid'));
20472
- var _b = getParentNodeObj(toastMark.findNodeById(mdNodeId)), mdNode = _b.mdNode, el = _b.el;
22124
+ var _b = getParentNodeObj(this.previewRoot, toastMark.findNodeById(mdNodeId)), mdNode = _b.mdNode, el = _b.el;
20473
22125
  var mdNodeStartLine = getMdStartLine(mdNode);
20474
22126
  targetScrollTop = children[mdNodeStartLine - 1].offsetTop;
20475
22127
  var height = getEditorRangeHeightInfo(state.doc, mdNode, children).height;
@@ -20508,13 +22160,32 @@ var ScrollSync = /** @class */ (function () {
20508
22160
  };
20509
22161
  animate(curScrollTop, targetScrollTop, syncCallbacks);
20510
22162
  };
22163
+ ScrollSync.prototype.clearTimer = function () {
22164
+ if (this.timer) {
22165
+ clearTimeout(this.timer);
22166
+ this.timer = null;
22167
+ }
22168
+ };
20511
22169
  ScrollSync.prototype.destroy = function () {
22170
+ this.clearTimer();
20512
22171
  this.eventEmitter.removeEventHandler('scroll');
20513
22172
  this.eventEmitter.removeEventHandler('afterPreviewRender');
20514
22173
  };
20515
22174
  return ScrollSync;
20516
22175
  }());
20517
22176
 
22177
+ var queryMap = {
22178
+ getPopupInitialValues: function (editor, payload) {
22179
+ var popupName = payload.popupName;
22180
+ return popupName === 'link' ? { linkText: editor.getSelectedText() } : {};
22181
+ },
22182
+ };
22183
+ function buildQuery(editor) {
22184
+ editor.eventEmitter.listen('query', function (query, payload) {
22185
+ return queryMap[query](editor, payload);
22186
+ });
22187
+ }
22188
+
20518
22189
  /**
20519
22190
  * ToastUIEditorCore
20520
22191
  * @param {Object} options Option object
@@ -20554,11 +22225,12 @@ var ScrollSync = /** @class */ (function () {
20554
22225
  * @param {boolean} [options.frontMatter=false] - whether use the front matter
20555
22226
  * @param {Array.<object>} [options.widgetRules=[]] - The rules for replacing the text with widget node
20556
22227
  * @param {string} [options.theme] - The theme to style the editor with. The default is included in toastui-editor.css.
22228
+ * @param {autofocus} [options.autofocus=true] - automatically focus the editor on creation.
20557
22229
  */
20558
22230
  var ToastUIEditorCore = /** @class */ (function () {
20559
22231
  function ToastUIEditorCore(options) {
20560
22232
  var _this = this;
20561
- this.initialHtml = options.el.innerHTML;
22233
+ this.initialHTML = options.el.innerHTML;
20562
22234
  options.el.innerHTML = '';
20563
22235
  this.options = extend_1({
20564
22236
  previewStyle: 'tab',
@@ -20587,10 +22259,13 @@ var ToastUIEditorCore = /** @class */ (function () {
20587
22259
  frontMatter: false,
20588
22260
  widgetRules: [],
20589
22261
  theme: 'light',
22262
+ autofocus: true,
20590
22263
  }, options);
20591
22264
  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;
20592
22265
  this.mode = initialEditType || 'markdown';
20593
22266
  this.mdPreviewStyle = this.options.previewStyle;
22267
+ this.i18n = i18n;
22268
+ this.i18n.setCode(this.options.language);
20594
22269
  this.eventEmitter = new EventEmitter();
20595
22270
  setWidgetRules(widgetRules);
20596
22271
  var linkAttributes = sanitizeLinkAttribute(this.options.linkAttributes);
@@ -20606,8 +22281,6 @@ var ToastUIEditorCore = /** @class */ (function () {
20606
22281
  };
20607
22282
  var wwToDOMAdaptor = new WwToDOMAdaptor(linkAttributes, rendererOptions.customHTMLRenderer);
20608
22283
  var htmlSchemaMap = createHTMLSchemaMap(rendererOptions.customHTMLRenderer, rendererOptions.sanitizer, wwToDOMAdaptor);
20609
- this.i18n = i18n;
20610
- this.i18n.setCode(this.options.language);
20611
22284
  this.toastMark = new ToastMark('', {
20612
22285
  disallowedHtmlBlockTags: ['br', 'img'],
20613
22286
  extendedAutolinks: extendedAutolinks,
@@ -20638,7 +22311,7 @@ var ToastUIEditorCore = /** @class */ (function () {
20638
22311
  this.setPlaceholder(this.options.placeholder);
20639
22312
  }
20640
22313
  if (!this.options.initialValue) {
20641
- this.setHTML(this.initialHtml, false);
22314
+ this.setHTML(this.initialHTML, false);
20642
22315
  }
20643
22316
  this.commandManager = new CommandManager(this.eventEmitter, this.mdEditor.commands, this.wwEditor.commands, function () { return _this.mode; });
20644
22317
  if (this.options.usageStatistics) {
@@ -20647,6 +22320,7 @@ var ToastUIEditorCore = /** @class */ (function () {
20647
22320
  this.scrollSync = new ScrollSync(this.mdEditor, this.preview, this.eventEmitter);
20648
22321
  this.addInitEvent();
20649
22322
  this.addInitCommand(mdCommands, wwCommands);
22323
+ buildQuery(this);
20650
22324
  if (this.options.hooks) {
20651
22325
  forEachOwnProperties_1(this.options.hooks, function (fn, key) { return _this.addHook(key, fn); });
20652
22326
  }
@@ -20654,10 +22328,18 @@ var ToastUIEditorCore = /** @class */ (function () {
20654
22328
  forEachOwnProperties_1(this.options.events, function (fn, key) { return _this.on(key, fn); });
20655
22329
  }
20656
22330
  this.eventEmitter.emit('load', this);
20657
- this.moveCursorToStart();
22331
+ this.moveCursorToStart(this.options.autofocus);
20658
22332
  }
20659
22333
  ToastUIEditorCore.prototype.addInitEvent = function () {
22334
+ var _this = this;
20660
22335
  this.on('needChangeMode', this.changeMode.bind(this));
22336
+ this.on('loadUI', function () {
22337
+ if (_this.height !== 'auto') {
22338
+ // 75px equals default editor ui height - the editing area height
22339
+ var minHeight = Math.min(parseInt(_this.minHeight, 10), parseInt(_this.height, 10) - 75) + "px";
22340
+ _this.setMinHeight(minHeight);
22341
+ }
22342
+ });
20661
22343
  addDefaultImageBlobHook(this.eventEmitter);
20662
22344
  };
20663
22345
  ToastUIEditorCore.prototype.addInitCommand = function (mdCommands, wwCommands) {
@@ -20770,15 +22452,19 @@ var ToastUIEditorCore = /** @class */ (function () {
20770
22452
  };
20771
22453
  /**
20772
22454
  * Set cursor position to end
22455
+ * @param {boolean} [focus] - automatically focus the editor
20773
22456
  */
20774
- ToastUIEditorCore.prototype.moveCursorToEnd = function () {
20775
- this.getCurrentModeEditor().moveCursorToEnd();
22457
+ ToastUIEditorCore.prototype.moveCursorToEnd = function (focus) {
22458
+ if (focus === void 0) { focus = true; }
22459
+ this.getCurrentModeEditor().moveCursorToEnd(focus);
20776
22460
  };
20777
22461
  /**
20778
22462
  * Set cursor position to start
22463
+ * @param {boolean} [focus] - automatically focus the editor
20779
22464
  */
20780
- ToastUIEditorCore.prototype.moveCursorToStart = function () {
20781
- this.getCurrentModeEditor().moveCursorToStart();
22465
+ ToastUIEditorCore.prototype.moveCursorToStart = function (focus) {
22466
+ if (focus === void 0) { focus = true; }
22467
+ this.getCurrentModeEditor().moveCursorToStart(focus);
20782
22468
  };
20783
22469
  /**
20784
22470
  * Set markdown syntax text.
@@ -20831,16 +22517,13 @@ var ToastUIEditorCore = /** @class */ (function () {
20831
22517
  ToastUIEditorCore.prototype.getHTML = function () {
20832
22518
  var _this = this;
20833
22519
  this.eventEmitter.holdEventInvoke(function () {
20834
- if (_this.isWysiwygMode()) {
20835
- _this.mdEditor.setMarkdown(_this.convertor.toMarkdownText(_this.wwEditor.getModel()));
22520
+ if (_this.isMarkdownMode()) {
22521
+ var mdNode = _this.toastMark.getRootNode();
22522
+ var wwNode = _this.convertor.toWysiwygModel(mdNode);
22523
+ _this.wwEditor.setModel(wwNode);
20836
22524
  }
20837
22525
  });
20838
- var mdNode = this.toastMark.getRootNode();
20839
- var mdRenderer = this.preview.getRenderer();
20840
- return mdRenderer
20841
- .render(mdNode)
20842
- .replace(/\sdata-nodeid="\d{1,}"/g, '')
20843
- .trim();
22526
+ return this.wwEditor.view.dom.innerHTML;
20844
22527
  };
20845
22528
  /**
20846
22529
  * Insert text
@@ -20928,12 +22611,11 @@ var ToastUIEditorCore = /** @class */ (function () {
20928
22611
  if (isString_1(height)) {
20929
22612
  if (height === 'auto') {
20930
22613
  addClass_1(el, 'auto-height');
20931
- this.setMinHeight(this.getMinHeight());
20932
22614
  }
20933
22615
  else {
20934
22616
  removeClass_1(el, 'auto-height');
20935
- this.setMinHeight(height);
20936
22617
  }
22618
+ this.setMinHeight(this.getMinHeight());
20937
22619
  }
20938
22620
  css_1(el, { height: height });
20939
22621
  this.height = height;
@@ -20950,16 +22632,18 @@ var ToastUIEditorCore = /** @class */ (function () {
20950
22632
  * @param {string} minHeight - min content height in pixel
20951
22633
  */
20952
22634
  ToastUIEditorCore.prototype.setMinHeight = function (minHeight) {
20953
- var _a;
20954
- this.minHeight = minHeight;
20955
- var editorHeight = this.options.el.clientHeight;
20956
- var editorSectionHeight = ((_a = document.querySelector("." + cls('main'))) === null || _a === void 0 ? void 0 : _a.clientHeight) || 0;
20957
- var diffHeight = editorHeight - editorSectionHeight;
20958
- var minHeightNum = parseInt(minHeight, 10);
20959
- minHeightNum = Math.max(minHeightNum - diffHeight, 0);
20960
- this.wwEditor.setMinHeight(minHeightNum);
20961
- this.mdEditor.setMinHeight(minHeightNum);
20962
- this.preview.setMinHeight(minHeightNum);
22635
+ if (minHeight !== this.minHeight) {
22636
+ var height = this.height || this.options.height;
22637
+ if (height !== 'auto' && this.options.el.querySelector("." + cls('main'))) {
22638
+ // 75px equals default editor ui height - the editing area height
22639
+ minHeight = Math.min(parseInt(minHeight, 10), parseInt(height, 10) - 75) + "px";
22640
+ }
22641
+ var minHeightNum = parseInt(minHeight, 10);
22642
+ this.minHeight = minHeight;
22643
+ this.wwEditor.setMinHeight(minHeightNum);
22644
+ this.mdEditor.setMinHeight(minHeightNum);
22645
+ this.preview.setMinHeight(minHeightNum);
22646
+ }
20963
22647
  };
20964
22648
  /**
20965
22649
  * Get minimum height of editor content
@@ -21647,11 +23331,15 @@ var templateObject_1$h;
21647
23331
  * @returns {function} debounced function.
21648
23332
  * @memberof module:tricks
21649
23333
  * @example
21650
- * var debounce = require('tui-code-snippet/tricks/debounce'); // node, commonjs
23334
+ * // ES6
23335
+ * import debounce from 'tui-code-snippet/tricks/debounce';
23336
+ *
23337
+ * // CommonJS
23338
+ * const debounce = require('tui-code-snippet/tricks/debounce');
21651
23339
  *
21652
23340
  * function someMethodToInvokeDebounced() {}
21653
23341
  *
21654
- * var debounced = debounce(someMethodToInvokeDebounced, 300);
23342
+ * const debounced = debounce(someMethodToInvokeDebounced, 300);
21655
23343
  *
21656
23344
  * // invoke repeatedly
21657
23345
  * debounced();
@@ -21699,11 +23387,15 @@ var debounce = debounce_1;
21699
23387
  * @returns {function} throttled function
21700
23388
  * @memberof module:tricks
21701
23389
  * @example
21702
- * var throttle = require('tui-code-snippet/tricks/throttle'); // node, commonjs
23390
+ * // ES6
23391
+ * import throttle from 'tui-code-snippet/tricks/throttle';
23392
+ *
23393
+ * // CommonJS
23394
+ * const throttle = require('tui-code-snippet/tricks/throttle');
21703
23395
  *
21704
23396
  * function someMethodToInvokeThrottled() {}
21705
23397
  *
21706
- * var throttled = throttle(someMethodToInvokeThrottled, 300);
23398
+ * const throttled = throttle(someMethodToInvokeThrottled, 300);
21707
23399
  *
21708
23400
  * // invoke repeatedly
21709
23401
  * throttled(); // invoke (leading)
@@ -22993,15 +24685,17 @@ var templateObject_1$c, templateObject_2$6, templateObject_3$2, templateObject_4
22993
24685
 
22994
24686
  var CustomPopupBody = /** @class */ (function (_super) {
22995
24687
  __extends$1(CustomPopupBody, _super);
22996
- function CustomPopupBody(props) {
22997
- var _this = _super.call(this, props) || this;
22998
- props.eventEmitter.listen('closePopup', _this.props.hidePopup);
22999
- return _this;
24688
+ function CustomPopupBody() {
24689
+ return _super !== null && _super.apply(this, arguments) || this;
23000
24690
  }
23001
24691
  CustomPopupBody.prototype.mounted = function () {
23002
24692
  // append the custom popup body element
23003
24693
  this.refs.el.appendChild(this.props.body);
23004
24694
  };
24695
+ CustomPopupBody.prototype.updated = function (prevProps) {
24696
+ // update custom popup element
24697
+ this.refs.el.replaceChild(this.props.body, prevProps.body);
24698
+ };
23005
24699
  CustomPopupBody.prototype.render = function () {
23006
24700
  var _this = this;
23007
24701
  return html(templateObject_1$b || (templateObject_1$b = __makeTemplateObject(["<div ref=", "></div>"], ["<div ref=", "></div>"])), function (el) { return (_this.refs.el = el); });
@@ -23170,6 +24864,7 @@ function createDefaultToolbarItemInfo(type) {
23170
24864
  className: 'indent',
23171
24865
  command: 'indent',
23172
24866
  tooltip: i18n.get('Indent'),
24867
+ state: 'indent',
23173
24868
  };
23174
24869
  break;
23175
24870
  case 'outdent':
@@ -23178,6 +24873,7 @@ function createDefaultToolbarItemInfo(type) {
23178
24873
  className: 'outdent',
23179
24874
  command: 'outdent',
23180
24875
  tooltip: i18n.get('Outdent'),
24876
+ state: 'outdent',
23181
24877
  };
23182
24878
  break;
23183
24879
  case 'scrollSync':
@@ -23278,6 +24974,7 @@ var Popup = /** @class */ (function (_super) {
23278
24974
  }
23279
24975
  Popup.prototype.mounted = function () {
23280
24976
  document.addEventListener('mousedown', this.handleMousedown);
24977
+ this.props.eventEmitter.listen('closePopup', this.props.hidePopup);
23281
24978
  };
23282
24979
  Popup.prototype.beforeDestroy = function () {
23283
24980
  document.removeEventListener('mousedown', this.handleMousedown);
@@ -23327,7 +25024,7 @@ function connectHOC(WrappedComponent) {
23327
25024
  _this.hideTooltip = function () {
23328
25025
  css_1(_this.props.tooltipRef.current, 'display', 'none');
23329
25026
  };
23330
- _this.state = { active: false };
25027
+ _this.state = { active: false, disabled: props.disabled };
23331
25028
  _this.addEvent();
23332
25029
  return _this;
23333
25030
  }
@@ -23336,9 +25033,10 @@ function connectHOC(WrappedComponent) {
23336
25033
  var _a = this.props, item = _a.item, eventEmitter = _a.eventEmitter;
23337
25034
  if (item.state) {
23338
25035
  eventEmitter.listen('changeToolbarState', function (_a) {
25036
+ var _b;
23339
25037
  var toolbarState = _a.toolbarState;
23340
- var active = !!toolbarState[item.state];
23341
- _this.setState({ active: active });
25038
+ var _c = (_b = toolbarState[item.state]) !== null && _b !== void 0 ? _b : {}, active = _c.active, disabled = _c.disabled;
25039
+ _this.setState({ active: !!active, disabled: disabled !== null && disabled !== void 0 ? disabled : _this.props.disabled });
23342
25040
  });
23343
25041
  }
23344
25042
  };
@@ -23347,7 +25045,7 @@ function connectHOC(WrappedComponent) {
23347
25045
  return { left: offsetLeft, top: el.offsetHeight + offsetTop };
23348
25046
  };
23349
25047
  ButtonHOC.prototype.render = function () {
23350
- return html(templateObject_1$8 || (templateObject_1$8 = __makeTemplateObject(["\n <", "\n ...", "\n active=", "\n showTooltip=", "\n hideTooltip=", "\n getBound=", "\n />\n "], ["\n <", "\n ...", "\n active=", "\n showTooltip=", "\n hideTooltip=", "\n getBound=", "\n />\n "])), WrappedComponent, this.props, this.state.active, this.showTooltip, this.hideTooltip, this.getBound);
25048
+ return html(templateObject_1$8 || (templateObject_1$8 = __makeTemplateObject(["\n <", "\n ...", "\n active=", "\n showTooltip=", "\n hideTooltip=", "\n getBound=", "\n disabled=", "\n />\n "], ["\n <", "\n ...", "\n active=", "\n showTooltip=", "\n hideTooltip=", "\n getBound=", "\n disabled=", "\n />\n "])), WrappedComponent, this.props, this.state.active, this.showTooltip, this.hideTooltip, this.getBound, this.state.disabled || this.props.disabled);
23351
25049
  };
23352
25050
  return ButtonHOC;
23353
25051
  }(Component));
@@ -23363,17 +25061,19 @@ var ToolbarButtonComp = /** @class */ (function (_super) {
23363
25061
  _this.props.showTooltip(_this.refs.el);
23364
25062
  };
23365
25063
  _this.execCommand = function () {
23366
- var _a = _this.props, item = _a.item, execCommand = _a.execCommand, setPopupInfo = _a.setPopupInfo, getBound = _a.getBound;
25064
+ var _a = _this.props, item = _a.item, execCommand = _a.execCommand, setPopupInfo = _a.setPopupInfo, getBound = _a.getBound, eventEmitter = _a.eventEmitter;
23367
25065
  var command = item.command, name = item.name, popup = item.popup;
23368
25066
  if (command) {
23369
25067
  execCommand(command);
23370
25068
  }
23371
25069
  else {
23372
25070
  var popupName = popup ? 'customPopupBody' : name;
25071
+ var initialValues = eventEmitter.emit('query', 'getPopupInitialValues', { popupName: popupName })[0];
23373
25072
  var info = createPopupInfo(popupName, {
23374
25073
  el: _this.refs.el,
23375
25074
  pos: getBound(_this.refs.el),
23376
25075
  popup: popup,
25076
+ initialValues: initialValues,
23377
25077
  });
23378
25078
  if (info) {
23379
25079
  setPopupInfo(info);
@@ -23556,7 +25256,7 @@ var Toolbar = /** @class */ (function (_super) {
23556
25256
  };
23557
25257
  _this.openPopup = function (popupName, initialValues) {
23558
25258
  if (initialValues === void 0) { initialValues = {}; }
23559
- var el = document.querySelector("." + cls('toolbar-group') + " ." + popupName);
25259
+ var el = _this.refs.el.querySelector("." + cls('toolbar-group') + " ." + popupName);
23560
25260
  if (el) {
23561
25261
  var _a = getTotalOffset(el, closest(el, "." + cls('toolbar'))), offsetLeft = _a.offsetLeft, offsetTop = _a.offsetTop;
23562
25262
  var info = createPopupInfo(popupName, {
@@ -23704,7 +25404,7 @@ var Toolbar = /** @class */ (function (_super) {
23704
25404
  };
23705
25405
  Toolbar.prototype.mounted = function () {
23706
25406
  if (this.props.previewStyle === 'tab') {
23707
- this.props.eventEmitter.emit('changePreviewTabWrite');
25407
+ this.props.eventEmitter.emit('changePreviewTabWrite', true);
23708
25408
  }
23709
25409
  // classify toolbar and dropdown toolbar after DOM has been rendered
23710
25410
  this.setState(this.classifyToolbarItems());
@@ -23899,6 +25599,7 @@ var ToastUIEditor = /** @class */ (function (_super) {
23899
25599
  var groupIndex = toolbarItem.groupIndex, itemIndex = toolbarItem.itemIndex, item = toolbarItem.item;
23900
25600
  _this.defaultUI.insertToolbarItem({ groupIndex: groupIndex, itemIndex: itemIndex }, item);
23901
25601
  });
25602
+ _this.eventEmitter.emit('loadUI', _this);
23902
25603
  return _this;
23903
25604
  }
23904
25605
  /**
@@ -23990,5 +25691,4 @@ ToastUIEditorCore.setLanguage(['en', 'en-US'], {
23990
25691
  'Choose language': 'Choose language',
23991
25692
  });
23992
25693
 
23993
- export default ToastUIEditor;
23994
- export { ToastUIEditor as Editor, ToastUIEditorCore as EditorCore };
25694
+ export { ToastUIEditor as Editor, ToastUIEditorCore as EditorCore, ToastUIEditor as default };