suneditor 2.44.12 → 2.45.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/LICENSE.txt +20 -20
  2. package/README.md +1588 -1585
  3. package/dist/suneditor.min.js +2 -2
  4. package/package.json +71 -71
  5. package/src/assets/css/suneditor-contents.css +561 -561
  6. package/src/assets/css/suneditor.css +0 -0
  7. package/src/assets/defaultIcons.js +103 -103
  8. package/src/lang/Lang.d.ts +143 -143
  9. package/src/lang/ckb.d.ts +4 -4
  10. package/src/lang/ckb.js +187 -187
  11. package/src/lang/da.d.ts +4 -4
  12. package/src/lang/da.js +191 -191
  13. package/src/lang/de.d.ts +4 -4
  14. package/src/lang/de.js +188 -188
  15. package/src/lang/en.d.ts +4 -4
  16. package/src/lang/en.js +187 -187
  17. package/src/lang/es.d.ts +4 -4
  18. package/src/lang/es.js +187 -187
  19. package/src/lang/fr.d.ts +4 -4
  20. package/src/lang/fr.js +188 -188
  21. package/src/lang/he.d.ts +4 -4
  22. package/src/lang/he.js +188 -188
  23. package/src/lang/index.d.ts +22 -22
  24. package/src/lang/index.js +25 -25
  25. package/src/lang/it.d.ts +4 -4
  26. package/src/lang/it.js +188 -188
  27. package/src/lang/ja.d.ts +4 -4
  28. package/src/lang/ja.js +187 -187
  29. package/src/lang/ko.d.ts +4 -4
  30. package/src/lang/ko.js +187 -187
  31. package/src/lang/lv.d.ts +4 -4
  32. package/src/lang/lv.js +187 -187
  33. package/src/lang/nl.d.ts +4 -4
  34. package/src/lang/nl.js +187 -187
  35. package/src/lang/pl.d.ts +4 -4
  36. package/src/lang/pl.js +187 -187
  37. package/src/lang/pt_br.d.ts +4 -4
  38. package/src/lang/pt_br.js +189 -189
  39. package/src/lang/ro.d.ts +4 -4
  40. package/src/lang/ro.js +187 -187
  41. package/src/lang/ru.d.ts +4 -4
  42. package/src/lang/ru.js +187 -187
  43. package/src/lang/se.d.ts +4 -4
  44. package/src/lang/se.js +191 -191
  45. package/src/lang/ua.d.ts +5 -5
  46. package/src/lang/ua.js +188 -188
  47. package/src/lang/ur.d.ts +4 -4
  48. package/src/lang/ur.js +187 -187
  49. package/src/lang/zh_cn.d.ts +4 -4
  50. package/src/lang/zh_cn.js +187 -187
  51. package/src/lib/constructor.js +3 -1
  52. package/src/lib/context.d.ts +42 -42
  53. package/src/lib/context.js +0 -0
  54. package/src/lib/core.d.ts +1101 -1101
  55. package/src/lib/core.js +96 -51
  56. package/src/lib/history.d.ts +48 -48
  57. package/src/lib/history.js +218 -218
  58. package/src/lib/util.d.ts +677 -677
  59. package/src/lib/util.js +39 -11
  60. package/src/options.d.ts +608 -608
  61. package/src/plugins/CommandPlugin.d.ts +7 -7
  62. package/src/plugins/DialogPlugin.d.ts +19 -19
  63. package/src/plugins/FileBrowserPlugin.d.ts +29 -29
  64. package/src/plugins/Module.d.ts +14 -14
  65. package/src/plugins/Plugin.d.ts +41 -41
  66. package/src/plugins/SubmenuPlugin.d.ts +7 -7
  67. package/src/plugins/command/blockquote.d.ts +4 -4
  68. package/src/plugins/command/blockquote.js +46 -46
  69. package/src/plugins/dialog/audio.d.ts +4 -4
  70. package/src/plugins/dialog/audio.js +556 -556
  71. package/src/plugins/dialog/image.d.ts +4 -4
  72. package/src/plugins/dialog/image.js +1115 -1115
  73. package/src/plugins/dialog/link.d.ts +4 -4
  74. package/src/plugins/dialog/link.js +223 -223
  75. package/src/plugins/dialog/math.d.ts +4 -4
  76. package/src/plugins/dialog/math.js +295 -295
  77. package/src/plugins/dialog/mention.d.ts +5 -5
  78. package/src/plugins/dialog/mention.js +242 -242
  79. package/src/plugins/dialog/video.d.ts +4 -4
  80. package/src/plugins/dialog/video.js +977 -977
  81. package/src/plugins/fileBrowser/imageGallery.d.ts +4 -4
  82. package/src/plugins/fileBrowser/imageGallery.js +63 -63
  83. package/src/plugins/index.d.ts +79 -79
  84. package/src/plugins/index.js +32 -32
  85. package/src/plugins/modules/_anchor.js +461 -461
  86. package/src/plugins/modules/_colorPicker.d.ts +59 -59
  87. package/src/plugins/modules/_colorPicker.js +0 -0
  88. package/src/plugins/modules/_notice.d.ts +20 -20
  89. package/src/plugins/modules/_notice.js +72 -72
  90. package/src/plugins/modules/_selectMenu.js +118 -118
  91. package/src/plugins/modules/component.d.ts +24 -24
  92. package/src/plugins/modules/component.js +80 -80
  93. package/src/plugins/modules/dialog.d.ts +27 -27
  94. package/src/plugins/modules/dialog.js +174 -174
  95. package/src/plugins/modules/fileBrowser.d.ts +41 -41
  96. package/src/plugins/modules/fileBrowser.js +373 -373
  97. package/src/plugins/modules/fileManager.d.ts +66 -66
  98. package/src/plugins/modules/fileManager.js +325 -325
  99. package/src/plugins/modules/index.d.ts +10 -10
  100. package/src/plugins/modules/index.js +8 -8
  101. package/src/plugins/modules/resizing.d.ts +153 -153
  102. package/src/plugins/modules/resizing.js +895 -895
  103. package/src/plugins/submenu/align.d.ts +4 -4
  104. package/src/plugins/submenu/align.js +160 -160
  105. package/src/plugins/submenu/font.d.ts +4 -4
  106. package/src/plugins/submenu/font.js +120 -120
  107. package/src/plugins/submenu/fontColor.d.ts +4 -4
  108. package/src/plugins/submenu/fontColor.js +0 -0
  109. package/src/plugins/submenu/fontSize.d.ts +4 -4
  110. package/src/plugins/submenu/fontSize.js +112 -112
  111. package/src/plugins/submenu/formatBlock.d.ts +4 -4
  112. package/src/plugins/submenu/formatBlock.js +273 -273
  113. package/src/plugins/submenu/hiliteColor.d.ts +4 -4
  114. package/src/plugins/submenu/hiliteColor.js +0 -0
  115. package/src/plugins/submenu/horizontalRule.d.ts +4 -4
  116. package/src/plugins/submenu/horizontalRule.js +98 -98
  117. package/src/plugins/submenu/lineHeight.d.ts +4 -4
  118. package/src/plugins/submenu/lineHeight.js +104 -104
  119. package/src/plugins/submenu/list.d.ts +4 -4
  120. package/src/plugins/submenu/list.js +456 -456
  121. package/src/plugins/submenu/paragraphStyle.d.ts +4 -4
  122. package/src/plugins/submenu/paragraphStyle.js +135 -135
  123. package/src/plugins/submenu/table.d.ts +4 -4
  124. package/src/plugins/submenu/template.d.ts +4 -4
  125. package/src/plugins/submenu/template.js +71 -71
  126. package/src/plugins/submenu/textStyle.d.ts +4 -4
  127. package/src/plugins/submenu/textStyle.js +167 -167
  128. package/src/suneditor.d.ts +9 -9
  129. package/src/suneditor.js +75 -75
  130. package/src/suneditor_build.js +17 -17
package/src/lib/core.js CHANGED
@@ -1180,6 +1180,12 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
1180
1180
  * @private
1181
1181
  */
1182
1182
  _editorRange: function () {
1183
+ const activeEl = this._wd.activeElement;
1184
+ if (util.isInputElement(activeEl)) {
1185
+ this._variable._selectionNode = activeEl;
1186
+ return activeEl;
1187
+ }
1188
+
1183
1189
  const selection = this.getSelection();
1184
1190
  if (!selection) return null;
1185
1191
  let range = null;
@@ -1190,10 +1196,6 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
1190
1196
  range = this._createDefaultRange();
1191
1197
  }
1192
1198
 
1193
- if (util.isFormatElement(range.endContainer) && range.endOffset === 0) {
1194
- range = this.setRange(range.startContainer, range.startOffset, range.startContainer, range.startContainer.length);
1195
- }
1196
-
1197
1199
  this._rangeInfo(range, selection);
1198
1200
  },
1199
1201
 
@@ -4755,12 +4757,14 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
4755
4757
 
4756
4758
  if (options.fullPage) {
4757
4759
  const parseDocument = this._parser.parseFromString(code_html, 'text/html');
4758
- const headChildren = parseDocument.head.children;
4759
4760
 
4760
- for (let i = 0, len = headChildren.length; i < len; i++) {
4761
- if (/^script$/i.test(headChildren[i].tagName)) {
4762
- parseDocument.head.removeChild(headChildren[i]);
4763
- i--, len--;
4761
+ if (!this.options.__allowedScriptTag) {
4762
+ const headChildren = parseDocument.head.children;
4763
+ for (let i = 0, len = headChildren.length; i < len; i++) {
4764
+ if (/^script$/i.test(headChildren[i].tagName)) {
4765
+ parseDocument.head.removeChild(headChildren[i]);
4766
+ i--, len--;
4767
+ }
4764
4768
  }
4765
4769
  }
4766
4770
 
@@ -5126,7 +5130,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
5126
5130
  */
5127
5131
  setIframeContents: function (ctx) {
5128
5132
  if (!options.iframe) return false;
5129
- if (ctx.head) this._wd.head.innerHTML = ctx.head.replace(/<script[\s\S]*>[\s\S]*<\/script>/gi, '');
5133
+ if (ctx.head) this._wd.head.innerHTML = this.options.__allowedScriptTag ? ctx.head : ctx.head.replace(this.__scriptTagRegExp, '');
5130
5134
  if (ctx.body) this._wd.body.innerHTML = this.convertContentsForEditor(ctx.body);
5131
5135
  this._resetComponents();
5132
5136
  },
@@ -5178,7 +5182,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
5178
5182
  const defaultTag = options.defaultTag;
5179
5183
  // element
5180
5184
  if (node.nodeType === 1) {
5181
- if (util._disallowedTags(node)) return '';
5185
+ if (this.__disallowedTagNameRegExp.test(node.nodeName)) return '';
5182
5186
  if (/__se__tag/.test(node.className)) return node.outerHTML;
5183
5187
 
5184
5188
  const ch = util.getListChildNodes(node, function(current) { return util.isSpanWithoutAttr(current) && !util.getParentElement(current, util.isNotCheckingNode); }) || [];
@@ -5234,7 +5238,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
5234
5238
  */
5235
5239
  _deleteDisallowedTags: function (html) {
5236
5240
  html = html
5237
- .replace(/<(script|style)[\s\S]*>[\s\S]*<\/(script|style)>/gi, '')
5241
+ .replace(this.__disallowedTagsRegExp, '')
5238
5242
  .replace(/<[a-z0-9]+\:[a-z0-9]+[^>^\/]*>[^>]*<\/[a-z0-9]+\:[a-z0-9]+>/gi, '');
5239
5243
 
5240
5244
  if (!/\bfont\b/i.test(this.options._editorTagsWhitelist)) {
@@ -5377,9 +5381,10 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
5377
5381
  }
5378
5382
 
5379
5383
  if (v) {
5380
- for (let i = 0, len = v.length; i < len; i++) {
5384
+ for (let i = 0, len = v.length, a; i < len; i++) {
5381
5385
  // if (lowLevelCheck && /^class="(?!(__se__|se-|katex))/.test(v[i].trim())) continue;
5382
- t += ' ' + (/^(?:href|src)\s*=\s*('|"|\s)*javascript\s*\:/i.test(v[i].trim()) ? '' : v[i]);
5386
+ a = (/^(?:href|src)\s*=\s*('|"|\s)*javascript\s*\:/i.test(v[i].trim()) ? '' : v[i]);
5387
+ t += (/^\s/.test(a) ? '' : ' ') + a;
5383
5388
  }
5384
5389
  }
5385
5390
 
@@ -5448,7 +5453,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
5448
5453
 
5449
5454
  for (let i = 0, len = domTree.length, t; i < len; i++) {
5450
5455
  t = domTree[i];
5451
- if (t.nodeType === 1 && !util.isTextStyleElement(t) && !util.isBreak(t) && !util._disallowedTags(t)) {
5456
+ if (t.nodeType === 1 && !util.isTextStyleElement(t) && !util.isBreak(t) && !this.__disallowedTagNameRegExp.test(t.nodeName)) {
5452
5457
  requireFormat = true;
5453
5458
  break;
5454
5459
  }
@@ -5467,10 +5472,10 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
5467
5472
  * @returns {String}
5468
5473
  */
5469
5474
  cleanHTML: function (html, whitelist, blacklist) {
5470
- html = this._deleteDisallowedTags(this._parser.parseFromString(html, 'text/html').body.innerHTML).replace(/(<[a-zA-Z0-9\-]+)[^>]*(?=>)/g, this._cleanTags.bind(this, true)).replace(/<br\/?>$/i, '');
5475
+ html = this._deleteDisallowedTags(this._parser.parseFromString(util.htmlCompress(html), 'text/html').body.innerHTML).replace(/(<[a-zA-Z0-9\-]+)[^>]*(?=>)/g, this._cleanTags.bind(this, true)).replace(/<br\/?>$/i, '');
5471
5476
  const dom = _d.createRange().createContextualFragment(html);
5472
5477
  try {
5473
- util._consistencyCheckOfHTML(dom, this._htmlCheckWhitelistRegExp, this._htmlCheckBlacklistRegExp, true);
5478
+ util._consistencyCheckOfHTML(dom, this._htmlCheckWhitelistRegExp, this._htmlCheckBlacklistRegExp, this._classNameFilter);
5474
5479
  } catch (error) {
5475
5480
  console.warn('[SUNEDITOR.cleanHTML.consistencyCheck.fail] ' + error);
5476
5481
  }
@@ -5497,8 +5502,13 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
5497
5502
  domTree = this._editFormat(dom).childNodes;
5498
5503
  }
5499
5504
 
5500
- for (let i = 0, len = domTree.length; i < len; i++) {
5501
- cleanHTML += this._makeLine(domTree[i], requireFormat);
5505
+ for (let i = 0, len = domTree.length, t; i < len; i++) {
5506
+ t = domTree[i];
5507
+ if (this.__allowedScriptRegExp.test(t.nodeName)) {
5508
+ cleanHTML += t.outerHTML;
5509
+ continue;
5510
+ }
5511
+ cleanHTML += this._makeLine(t, requireFormat);
5502
5512
  }
5503
5513
 
5504
5514
  cleanHTML = util.htmlRemoveWhiteSpace(cleanHTML);
@@ -5518,11 +5528,11 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
5518
5528
  * @returns {String}
5519
5529
  */
5520
5530
  convertContentsForEditor: function (contents) {
5521
- contents = this._deleteDisallowedTags(this._parser.parseFromString(contents, 'text/html').body.innerHTML).replace(/(<[a-zA-Z0-9\-]+)[^>]*(?=>)/g, this._cleanTags.bind(this, false));
5531
+ contents = this._deleteDisallowedTags(this._parser.parseFromString(util.htmlCompress(contents), 'text/html').body.innerHTML).replace(/(<[a-zA-Z0-9\-]+)[^>]*(?=>)/g, this._cleanTags.bind(this, true));
5522
5532
  const dom = _d.createRange().createContextualFragment(contents);
5523
5533
 
5524
5534
  try {
5525
- util._consistencyCheckOfHTML(dom, this._htmlCheckWhitelistRegExp, this._htmlCheckBlacklistRegExp, false);
5535
+ util._consistencyCheckOfHTML(dom, this._htmlCheckWhitelistRegExp, this._htmlCheckBlacklistRegExp, this._classNameFilter);
5526
5536
  } catch (error) {
5527
5537
  console.warn('[SUNEDITOR.convertContentsForEditor.consistencyCheck.fail] ' + error);
5528
5538
  }
@@ -5546,6 +5556,11 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
5546
5556
  for (let i = 0, t; i < domTree.length; i++) {
5547
5557
  t = domTree[i];
5548
5558
 
5559
+ if (this.__allowedScriptRegExp.test(t.nodeName)) {
5560
+ cleanHTML += t.outerHTML;
5561
+ continue;
5562
+ }
5563
+
5549
5564
  if (!util.isFormatElement(t) && !util.isRangeFormatElement(t) && !util.isComponent(t) && !util.isMedia(t) && t.nodeType !== 8 && !/__se__tag/.test(t.className)) {
5550
5565
  if (!p) p = util.createElement(options.defaultTag);
5551
5566
  p.appendChild(t);
@@ -5858,6 +5873,15 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
5858
5873
  this.wwComputedStyle = _w.getComputedStyle(context.element.wysiwyg);
5859
5874
  this._editorHeight = context.element.wysiwygFrame.offsetHeight;
5860
5875
  this._editorHeightPadding = util.getNumber(this.wwComputedStyle.getPropertyValue('padding-top')) + util.getNumber(this.wwComputedStyle.getPropertyValue('padding-bottom'));
5876
+ this._classNameFilter = function (v) {
5877
+ return this.test(v) ? v : '';
5878
+ }.bind(options.allowedClassNames);
5879
+
5880
+ const sPrefix = (options.__allowedScriptTag ? '' : 'script|');
5881
+ this.__scriptTagRegExp = new wRegExp('<(script)[^>]*>([\\s\\S]*?)<\\/\\1>|<script[^>]*\\/?>', 'gi');
5882
+ this.__disallowedTagsRegExp = new wRegExp('<(' + sPrefix + 'style)[^>]*>([\\s\\S]*?)<\\/\\1>|<(' + sPrefix + 'style)[^>]*\\/?>', 'gi');
5883
+ this.__disallowedTagNameRegExp = new wRegExp('^(' + sPrefix + 'meta|link|style|[a-z]+\:[a-z]+)$', 'i');
5884
+ this.__allowedScriptRegExp = new wRegExp('^' + (options.__allowedScriptTag ? 'script' : '') + '$', 'i');
5861
5885
 
5862
5886
  if (!options.iframe && typeof _w.ShadowRoot === 'function') {
5863
5887
  let child = context.element.wysiwygFrame;
@@ -6049,7 +6073,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
6049
6073
  * @private
6050
6074
  */
6051
6075
  _initWysiwygArea: function (reload, _initHTML) {
6052
- context.element.wysiwyg.innerHTML = reload ? _initHTML : this.convertContentsForEditor(typeof _initHTML === 'string' ? _initHTML : context.element.originElement.value);
6076
+ context.element.wysiwyg.innerHTML = reload ? _initHTML : this.convertContentsForEditor((typeof _initHTML === 'string' ? _initHTML : /TEXTAREA/i.test(context.element.originElement) ? context.element.originElement.value : context.element.originElement.innerHTML) || '');
6053
6077
  },
6054
6078
 
6055
6079
  /**
@@ -6295,6 +6319,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
6295
6319
  _responsiveCurrentSize: 'default',
6296
6320
  _responsiveButtonSize: null,
6297
6321
  _responsiveButtons: null,
6322
+ _cursorMoveKeyCode: new _w.RegExp('^(8|3[2-9]|40|46)$'),
6298
6323
  _directionKeyCode: new _w.RegExp('^(8|13|3[2-9]|40|46)$'),
6299
6324
  _nonTextKeyCode: new _w.RegExp('^(8|13|1[6-9]|20|27|3[3-9]|40|45|46|11[2-9]|12[0-3]|144|145)$'),
6300
6325
  _historyIgnoreKeyCode: new _w.RegExp('^(1[6-9]|20|27|3[3-9]|40|45|11[2-9]|12[0-3]|144|145)$'),
@@ -6566,6 +6591,14 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
6566
6591
 
6567
6592
  core._editorRange();
6568
6593
 
6594
+ if (e.detail === 3) {
6595
+ let range = core.getRange();
6596
+ if (util.isFormatElement(range.endContainer) && range.endOffset === 0) {
6597
+ range = core.setRange(range.startContainer, range.startOffset, range.startContainer, range.startContainer.length);
6598
+ core._rangeInfo(range, core.getSelection());
6599
+ }
6600
+ }
6601
+
6569
6602
  const selectionNode = core.getSelectionNode();
6570
6603
  const formatEl = util.getFormatElement(selectionNode, null);
6571
6604
  const rangeEl = util.getRangeFormatElement(selectionNode, null);
@@ -6834,13 +6867,16 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
6834
6867
 
6835
6868
  _onShortcutKey: false,
6836
6869
  onKeyDown_wysiwyg: function (e) {
6870
+ let selectionNode = core.getSelectionNode();
6871
+ if (util.isInputElement(selectionNode)) return;
6872
+
6837
6873
  const keyCode = e.keyCode;
6838
6874
  const shift = e.shiftKey;
6839
6875
  const ctrl = e.ctrlKey || e.metaKey || keyCode === 91 || keyCode === 92 || keyCode === 224;
6840
6876
  const alt = e.altKey;
6841
6877
  event._IEisComposing = keyCode === 229;
6842
6878
 
6843
- if (!ctrl && core.isReadOnly && !event._directionKeyCode.test(keyCode)) {
6879
+ if (!ctrl && core.isReadOnly && !event._cursorMoveKeyCode.test(keyCode)) {
6844
6880
  e.preventDefault();
6845
6881
  return false;
6846
6882
  }
@@ -6865,7 +6901,6 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
6865
6901
  }
6866
6902
 
6867
6903
  /** default key action */
6868
- let selectionNode = core.getSelectionNode();
6869
6904
  const range = core.getRange();
6870
6905
  const selectRange = !range.collapsed || range.startContainer !== range.endContainer;
6871
6906
  const fileComponentName = core._fileManager.pluginRegExp.test(core.currentControllerName) ? core.currentControllerName : '';
@@ -6926,27 +6961,27 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
6926
6961
  }
6927
6962
 
6928
6963
  // clean remove tag
6929
- if (formatEl && range.startContainer === range.endContainer && selectionNode.nodeType === 3 && !util.isFormatElement(selectionNode.parentNode)) {
6930
- if (range.collapsed ? selectionNode.textContent.length === 1 : (range.endOffset - range.startOffset) === selectionNode.textContent.length) {
6931
- e.preventDefault();
6932
-
6933
- let offset = null;
6934
- let prev = selectionNode.parentNode.previousSibling;
6935
- const next = selectionNode.parentNode.nextSibling;
6936
- if (!prev) {
6937
- if (!next) {
6938
- prev = util.createElement('BR');
6939
- formatEl.appendChild(prev);
6940
- } else {
6941
- prev = next;
6942
- offset = 0;
6943
- }
6964
+ const startCon = range.startContainer;
6965
+ if (formatEl && !formatEl.previousElementSibling && range.startOffset === 0 && startCon.nodeType === 3 && !util.isFormatElement(startCon.parentNode)) {
6966
+ let prev = startCon.parentNode.previousSibling;
6967
+ const next = startCon.parentNode.nextSibling;
6968
+ if (!prev) {
6969
+ if (!next) {
6970
+ prev = util.createElement('BR');
6971
+ formatEl.appendChild(prev);
6972
+ } else {
6973
+ prev = next;
6944
6974
  }
6975
+ }
6976
+
6977
+ let con = startCon;
6978
+ while(formatEl.contains(con) && !con.previousSibling) {
6979
+ con = con.parentNode;
6980
+ }
6945
6981
 
6946
- selectionNode.textContent = '';
6947
- util.removeItemAllParents(selectionNode, null, formatEl);
6948
- offset = typeof offset === 'number' ? offset : prev.nodeType === 3 ? prev.textContent.length : 1;
6949
- core.setRange(prev, offset, prev, offset);
6982
+ if (!formatEl.contains(con)) {
6983
+ startCon.textContent = '';
6984
+ util.removeItemAllParents(startCon, null, formatEl);
6950
6985
  break;
6951
6986
  }
6952
6987
  }
@@ -7446,11 +7481,20 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
7446
7481
  e.preventDefault();
7447
7482
  const focusBR = util.createElement('BR');
7448
7483
  const newFormat = util.createElement(formatEl.nodeName);
7449
- newFormat.appendChild(focusBR);
7450
-
7451
7484
  util.copyTagAttributes(newFormat, formatEl, options.lineAttrReset);
7452
7485
 
7453
- formatEl.parentNode.insertBefore(newFormat, formatStartEdge ? formatEl : formatEl.nextElementSibling);
7486
+ let child = focusBR;
7487
+ do {
7488
+ if (!util.isBreak(selectionNode) && selectionNode.nodeType === 1) {
7489
+ const f = selectionNode.cloneNode(false);
7490
+ f.appendChild(child);
7491
+ child = f;
7492
+ }
7493
+ selectionNode = selectionNode.parentNode;
7494
+ } while(formatEl !== selectionNode && formatEl.contains(selectionNode));
7495
+
7496
+ newFormat.appendChild(child);
7497
+ formatEl.parentNode.insertBefore(newFormat, formatStartEdge && !formatEndEdge ? formatEl : formatEl.nextElementSibling);
7454
7498
  if (formatEndEdge) {
7455
7499
  core.setRange(focusBR, 1, focusBR, 1);
7456
7500
  }
@@ -7589,6 +7633,11 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
7589
7633
  core.insertNode(zeroWidth, null, false);
7590
7634
  core.setRange(zeroWidth, 1, zeroWidth, 1);
7591
7635
  }
7636
+
7637
+ if (event._directionKeyCode.test(keyCode)) {
7638
+ core._editorRange();
7639
+ event._applyTagEffects();
7640
+ }
7592
7641
  },
7593
7642
 
7594
7643
  onKeyUp_wysiwyg: function (e) {
@@ -7600,7 +7649,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
7600
7649
  const alt = e.altKey;
7601
7650
 
7602
7651
  if (core.isReadOnly) {
7603
- if (!ctrl && event._directionKeyCode.test(keyCode)) event._applyTagEffects();
7652
+ if (!ctrl && event._cursorMoveKeyCode.test(keyCode)) event._applyTagEffects();
7604
7653
  return;
7605
7654
  }
7606
7655
 
@@ -7653,10 +7702,6 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
7653
7702
  selectionNode = core.getSelectionNode();
7654
7703
  }
7655
7704
 
7656
- if (event._directionKeyCode.test(keyCode)) {
7657
- event._applyTagEffects();
7658
- }
7659
-
7660
7705
  const textKey = !ctrl && !alt && !event._nonTextKeyCode.test(keyCode);
7661
7706
  if (textKey && selectionNode.nodeType === 3 && util.zeroWidthRegExp.test(selectionNode.textContent) && !(e.isComposing !== undefined ? e.isComposing : event._IEisComposing)) {
7662
7707
  let so = range.startOffset, eo = range.endOffset;
@@ -1,48 +1,48 @@
1
- import { Core } from "./core";
2
-
3
- export interface History {
4
- /**
5
- * @description History stack
6
- */
7
- stack: any[];
8
- /**
9
- * @description Saving the current status to the history object stack
10
- * If "delay" is true, it will be saved after (options.historyStackDelayTime || 400) miliseconds
11
- * If the function is called again with the "delay" argument true before it is saved, the delay time is renewal
12
- * You can specify the delay time by sending a number.
13
- * @param {Boolean} delay If true, Add stack without delay time.
14
- */
15
- push: (delay: boolean | number) => void;
16
- /**
17
- * @description Undo function
18
- */
19
- undo: () => void;
20
- /**
21
- * @description Redo function
22
- */
23
- redo: () => void;
24
- /**
25
- * @description Go to the history stack for that index.
26
- * If "index" is -1, go to the last stack
27
- * @param {Number} index Stack index
28
- */
29
- go: (index: number) => void;
30
-
31
- /**
32
- * @description Get the current history stack index.
33
- * @returns
34
- */
35
- getCurrentIndex: () => number;
36
-
37
- /**
38
- * @description Reset the history object
39
- */
40
- reset: (ignoreChangeEvent: any) => void;
41
- /**
42
- * @description Remove all stacks and remove the timeout function.
43
- * @private
44
- */
45
- _destroy: () => void;
46
- }
47
-
48
- export default function _default(core: Core, change: any): History;
1
+ import { Core } from "./core";
2
+
3
+ export interface History {
4
+ /**
5
+ * @description History stack
6
+ */
7
+ stack: any[];
8
+ /**
9
+ * @description Saving the current status to the history object stack
10
+ * If "delay" is true, it will be saved after (options.historyStackDelayTime || 400) miliseconds
11
+ * If the function is called again with the "delay" argument true before it is saved, the delay time is renewal
12
+ * You can specify the delay time by sending a number.
13
+ * @param {Boolean} delay If true, Add stack without delay time.
14
+ */
15
+ push: (delay: boolean | number) => void;
16
+ /**
17
+ * @description Undo function
18
+ */
19
+ undo: () => void;
20
+ /**
21
+ * @description Redo function
22
+ */
23
+ redo: () => void;
24
+ /**
25
+ * @description Go to the history stack for that index.
26
+ * If "index" is -1, go to the last stack
27
+ * @param {Number} index Stack index
28
+ */
29
+ go: (index: number) => void;
30
+
31
+ /**
32
+ * @description Get the current history stack index.
33
+ * @returns
34
+ */
35
+ getCurrentIndex: () => number;
36
+
37
+ /**
38
+ * @description Reset the history object
39
+ */
40
+ reset: (ignoreChangeEvent: any) => void;
41
+ /**
42
+ * @description Remove all stacks and remove the timeout function.
43
+ * @private
44
+ */
45
+ _destroy: () => void;
46
+ }
47
+
48
+ export default function _default(core: Core, change: any): History;