suneditor 2.43.2 → 2.43.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "suneditor",
3
- "version": "2.43.2",
3
+ "version": "2.43.5",
4
4
  "description": "Pure JavaScript based WYSIWYG web editor",
5
5
  "author": "JiHong.Lee",
6
6
  "license": "MIT",
@@ -398,6 +398,9 @@ export default {
398
398
  _initOptions: function (element, options) {
399
399
  /** Values */
400
400
  options.lang = options.lang || _defaultLang;
401
+ options.value = typeof options.value === 'string' ? options.value : null;
402
+ options.historyStackDelayTime = typeof options.historyStackDelayTime === 'number' ? options.historyStackDelayTime : 400;
403
+ // tag style
401
404
  options.defaultTag = typeof options.defaultTag === 'string' && options.defaultTag.length > 0 ? options.defaultTag : 'p';
402
405
  const textTags = options.textTags = [{bold: 'STRONG', underline: 'U', italic: 'EM', strike: 'DEL', sub: 'SUB', sup: 'SUP'}, (options.textTags || {})].reduce(function (_default, _new) {
403
406
  for (let key in _new) {
@@ -418,8 +421,14 @@ export default {
418
421
  'sub': textTags.sub.toLowerCase(),
419
422
  'sup': textTags.sup.toLowerCase()
420
423
  };
421
- options.value = typeof options.value === 'string' ? options.value : null;
422
- options.historyStackDelayTime = typeof options.historyStackDelayTime === 'number' ? options.historyStackDelayTime : 400;
424
+ options._defaultCommand = {
425
+ bold: options.textTags.bold,
426
+ underline: options.textTags.underline,
427
+ italic: options.textTags.italic,
428
+ strike: options.textTags.strike,
429
+ subscript: options.textTags.sub,
430
+ superscript: options.textTags.sup
431
+ };
423
432
  /** Whitelist, Blacklist */
424
433
  const whitelist = 'br|p|div|pre|blockquote|h1|h2|h3|h4|h5|h6|ol|ul|li|hr|figure|figcaption|img|iframe|audio|video|source|table|thead|tbody|tr|th|td|a|b|strong|var|i|em|u|ins|s|span|strike|del|sub|sup|code|svg|path|details|summary';
425
434
  // tags
@@ -574,9 +583,6 @@ export default {
574
583
  ['fullScreen', 'showBlocks', 'codeView'],
575
584
  ['preview', 'print']
576
585
  ];
577
- /** Private options */
578
- options.__listCommonStyle = options.__listCommonStyle || ['fontSize', 'color', 'fontFamily'];
579
- // options.__defaultFontSize;
580
586
 
581
587
  /** RTL - buttons */
582
588
  if (options.rtl) {
@@ -599,6 +605,10 @@ export default {
599
605
  return _default;
600
606
  }, {});
601
607
 
608
+ /** Private options */
609
+ // options.__defaultFontSize;
610
+ options.__listCommonStyle = options.__listCommonStyle || ['fontSize', 'color', 'fontFamily', 'fontWeight', 'fontStyle'];
611
+
602
612
  /** _init options */
603
613
  options._editorStyles = util._setDefaultOptionStyle(options, options.defaultStyle);
604
614
  },
package/src/lib/core.d.ts CHANGED
@@ -199,16 +199,6 @@ interface Core {
199
199
  */
200
200
  allCommandButtons: Record<string, Element>;
201
201
 
202
- /**
203
- * @description Save the current buttons states to "allCommandButtons" object
204
- */
205
- saveButtonStates(): void;
206
-
207
- /**
208
- * @description Recover the current buttons states from "allCommandButtons" object
209
- */
210
- recoverButtonStates(): void;
211
-
212
202
  /**
213
203
  * @description If the plugin is not added, add the plugin and call the 'add' function.
214
204
  * If the plugin is added call callBack function.
package/src/lib/core.js CHANGED
@@ -475,19 +475,6 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
475
475
  */
476
476
  _styleCommandMap: null,
477
477
 
478
- /**
479
- * @description Map of default command
480
- * @private
481
- */
482
- _defaultCommand: {
483
- bold: options.textTags.bold,
484
- underline: options.textTags.underline,
485
- italic: options.textTags.italic,
486
- strike: options.textTags.strike,
487
- subscript: options.textTags.sub,
488
- superscript: options.textTags.sup
489
- },
490
-
491
478
  /**
492
479
  * @description Variables used internally in editor operation
493
480
  * @property {Boolean} isCodeView State of code view
@@ -523,40 +510,6 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
523
510
  _lineBreakDir: ''
524
511
  },
525
512
 
526
- /**
527
- * @description Save the current buttons states to "allCommandButtons" object
528
- */
529
- saveButtonStates: function () {
530
- if (!this.allCommandButtons) this.allCommandButtons = {};
531
-
532
- const currentButtons = this.context.element._buttonTray.querySelectorAll('.se-menu-list button[data-display]');
533
- for (let i = 0, element, command; i < currentButtons.length; i++) {
534
- element = currentButtons[i];
535
- command = element.getAttribute('data-command');
536
-
537
- this.allCommandButtons[command] = element;
538
- }
539
- },
540
-
541
- /**
542
- * @description Recover the current buttons states from "allCommandButtons" object
543
- */
544
- recoverButtonStates: function () {
545
- if (this.allCommandButtons) {
546
- const currentButtons = this.context.element._buttonTray.querySelectorAll('.se-menu-list button[data-display]');
547
- for (let i = 0, button, command, oldButton; i < currentButtons.length; i++) {
548
- button = currentButtons[i];
549
- command = button.getAttribute('data-command');
550
-
551
- oldButton = this.allCommandButtons[command];
552
- if (oldButton) {
553
- button.parentElement.replaceChild(oldButton, button);
554
- if (this.context.tool[command]) this.context.tool[command] = oldButton;
555
- }
556
- }
557
- }
558
- },
559
-
560
513
  /**
561
514
  * @description If the plugin is not added, add the plugin and call the 'add' function.
562
515
  * If the plugin is added call callBack function.
@@ -1692,7 +1645,9 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
1692
1645
  return null;
1693
1646
  }
1694
1647
 
1695
- const freeFormat = util.getFreeFormatElement(this.getSelectionNode(), null);
1648
+ const line = util.getFormatElement(this.getSelectionNode(), null);
1649
+ const listCell = util.isListCell(line);
1650
+ const freeFormat = util.isFreeFormatElement(line);
1696
1651
  const isFormats = (!freeFormat && (util.isFormatElement(oNode) || util.isRangeFormatElement(oNode))) || util.isComponent(oNode);
1697
1652
 
1698
1653
  if (!afterNode && (isFormats || util.isComponent(oNode) || util.isMedia(oNode))) {
@@ -1837,7 +1792,18 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
1837
1792
  oNode = fNode;
1838
1793
  }
1839
1794
 
1840
- parentNode.insertBefore(oNode, parentNode === afterNode ? parentNode.lastChild : afterNode);
1795
+ // insert--
1796
+ let emptyListCell = false;
1797
+ if (listCell && util.isListCell(oNode)) {
1798
+ afterNode = line.nextElementSibling;
1799
+ parentNode = line.parentNode;
1800
+ emptyListCell = util.onlyZeroWidthSpace(line.textContent);
1801
+ } else {
1802
+ afterNode = parentNode === afterNode ? parentNode.lastChild : afterNode;
1803
+ }
1804
+
1805
+ parentNode.insertBefore(oNode, afterNode);
1806
+ if (emptyListCell) util.removeItem(line);
1841
1807
  } catch (e) {
1842
1808
  parentNode.appendChild(oNode);
1843
1809
  } finally {
@@ -2810,20 +2776,26 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
2810
2776
 
2811
2777
  // one line
2812
2778
  if (oneLine) {
2813
- this._resetCommonListCell(lineNodes[0], styleArray);
2779
+ if (this._resetCommonListCell(lineNodes[0], styleArray)) range = this.setRange(startCon, startOff, endCon, endOff);
2780
+
2814
2781
  const newRange = this._nodeChange_oneLine(lineNodes[0], newNode, validation, startCon, startOff, endCon, endOff, isRemoveFormat, isRemoveNode, range.collapsed, _removeCheck, _getMaintainedNode, _isMaintainedNode);
2815
2782
  start.container = newRange.startContainer;
2816
2783
  start.offset = newRange.startOffset;
2817
2784
  end.container = newRange.endContainer;
2818
2785
  end.offset = newRange.endOffset;
2786
+
2819
2787
  if (start.container === end.container && util.onlyZeroWidthSpace(start.container)) {
2820
2788
  start.offset = end.offset = 1;
2821
2789
  }
2822
2790
  this._setCommonListStyle(newRange.ancestor, null);
2823
2791
  } else { // multi line
2792
+ let appliedCommonList = false;
2793
+ if (endLength > 0 && this._resetCommonListCell(lineNodes[endLength], styleArray)) appliedCommonList = true;
2794
+ if (this._resetCommonListCell(lineNodes[0], styleArray)) appliedCommonList = true;
2795
+ if (appliedCommonList) this.setRange(startCon, startOff, endCon, endOff);
2796
+
2824
2797
  // end
2825
2798
  if (endLength > 0) {
2826
- this._resetCommonListCell(lineNodes[endLength], styleArray);
2827
2799
  newNode = appendNode.cloneNode(false);
2828
2800
  end = this._nodeChange_endLine(lineNodes[endLength], newNode, validation, endCon, endOff, isRemoveFormat, isRemoveNode, _removeCheck, _getMaintainedNode, _isMaintainedNode);
2829
2801
  }
@@ -2841,7 +2813,6 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
2841
2813
  }
2842
2814
 
2843
2815
  // start
2844
- this._resetCommonListCell(lineNodes[0], styleArray);
2845
2816
  newNode = appendNode.cloneNode(false);
2846
2817
  start = this._nodeChange_startLine(lineNodes[0], newNode, validation, startCon, startOff, isRemoveFormat, isRemoveNode, _removeCheck, _getMaintainedNode, _isMaintainedNode, end.container);
2847
2818
 
@@ -2901,9 +2872,11 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
2901
2872
  }
2902
2873
 
2903
2874
  let sel = refer.cloneNode(false);
2904
- let r = null;
2875
+ let r = null, appliedEl = false;
2905
2876
  for (let i = 0, len = children.length, c, s; i < len; i++) {
2906
2877
  c = children[i];
2878
+ if (options._textTagsMap[c.nodeName.toLowerCase()]) continue;
2879
+
2907
2880
  s = util.getValues(c.style);
2908
2881
  if (s.length === 0 || (ec.some(function (k) {return s.indexOf(k) === -1;}) && s.some(function(k) {ec.indexOf(k) > -1;}))) {
2909
2882
  r = c.nextSibling;
@@ -2912,11 +2885,19 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
2912
2885
  el.insertBefore(sel, r);
2913
2886
  sel = refer.cloneNode(false);
2914
2887
  r = null;
2888
+ appliedEl = true;
2915
2889
  }
2916
2890
  }
2917
2891
 
2918
- if (sel.childNodes.length > 0) el.insertBefore(sel, r);
2919
- if (!elStyles.length) el.removeAttribute('style');
2892
+ if (sel.childNodes.length > 0) {
2893
+ el.insertBefore(sel, r);
2894
+ appliedEl = true;
2895
+ }
2896
+ if (!elStyles.length) {
2897
+ el.removeAttribute('style');
2898
+ }
2899
+
2900
+ return appliedEl;
2920
2901
  },
2921
2902
 
2922
2903
  /**
@@ -2934,40 +2915,39 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
2934
2915
  if (!child || children.length > 1 || child.nodeType !== 1) return;
2935
2916
 
2936
2917
  // set cell style---
2937
- const commonStyleElements = [];
2938
2918
  const childStyle = child.style;
2939
2919
  const elStyle = el.style;
2920
+ const nodeName = child.nodeName.toLowerCase();
2921
+ let appliedEl = false;
2940
2922
 
2941
2923
  // bold, italic
2942
- if (options._textTagsMap[child.nodeName.toLowerCase()] === this._defaultCommand.bold.toLowerCase()) elStyle.fontWeight = 'bold'; // bold
2943
- else if (childStyle.fontWeight) elStyle.fontWeight = childStyle.fontWeight;
2944
- if (options._textTagsMap[child.nodeName.toLowerCase()] === this._defaultCommand.italic.toLowerCase()) elStyle.fontStyle = 'italic'; // italic
2945
- else if (childStyle.fontStyle) elStyle.fontStyle = childStyle.fontStyle;
2924
+ if (options._textTagsMap[nodeName] === options._defaultCommand.bold.toLowerCase()) elStyle.fontWeight = 'bold';
2925
+ if (options._textTagsMap[nodeName] === options._defaultCommand.italic.toLowerCase()) elStyle.fontStyle = 'italic';
2946
2926
 
2947
2927
  // styles
2948
2928
  const cKeys = util.getValues(childStyle);
2949
- for (let i = 0, len = this._listCamel.length; i < len; i++) {
2950
- if (cKeys.indexOf(this._listKebab[i]) > -1) {
2951
- elStyle[this._listCamel[i]] = childStyle[this._listCamel[i]];
2952
- childStyle.removeProperty(this._listKebab[i]);
2929
+ if (cKeys.length > 0) {
2930
+ for (let i = 0, len = this._listCamel.length; i < len; i++) {
2931
+ if (cKeys.indexOf(this._listKebab[i]) > -1) {
2932
+ elStyle[this._listCamel[i]] = childStyle[this._listCamel[i]];
2933
+ childStyle.removeProperty(this._listKebab[i]);
2934
+ appliedEl = true;
2935
+ }
2953
2936
  }
2954
2937
  }
2955
-
2956
- // remove child
2957
- if (!childStyle.length) commonStyleElements.push(child);
2958
2938
 
2959
2939
  this._setCommonListStyle(el, child);
2940
+ if (!appliedEl) return;
2960
2941
 
2961
2942
  // common style
2962
- for (let i = 0, len = commonStyleElements.length, n, ch, p; i < len; i++) {
2963
- n = commonStyleElements[i];
2964
- ch = n.childNodes;
2965
- p = n.parentNode;
2966
- n = n.nextSibling;
2943
+ if (!childStyle.length) {
2944
+ const ch = child.childNodes;
2945
+ const p = child.parentNode;
2946
+ const n = child.nextSibling;
2967
2947
  while (ch.length > 0) {
2968
2948
  p.insertBefore(ch[0], n);
2969
2949
  }
2970
- util.removeItem(commonStyleElements[i]);
2950
+ util.removeItem(child);
2971
2951
  }
2972
2952
  },
2973
2953
 
@@ -4284,7 +4264,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
4284
4264
  wysiwyg.appendChild(format);
4285
4265
  last = br;
4286
4266
  }
4287
- this.setRange(first, 0, last, last.textContent.length);
4267
+ event._showToolbarBalloon(this.setRange(first, 0, last, last.textContent.length));
4288
4268
  break;
4289
4269
  case 'codeView':
4290
4270
  this.toggleCodeView();
@@ -4337,7 +4317,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
4337
4317
  if (context.tool.save) context.tool.save.setAttribute('disabled', true);
4338
4318
  break;
4339
4319
  default : // 'STRONG', 'U', 'EM', 'DEL', 'SUB', 'SUP'..
4340
- command = this._defaultCommand[command.toLowerCase()] || command;
4320
+ command = options._defaultCommand[command.toLowerCase()] || command;
4341
4321
  if (!this.commandMap[command]) this.commandMap[command] = target;
4342
4322
 
4343
4323
  const nodesMap = this._variable.currentNodesMap;
@@ -5152,7 +5132,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
5152
5132
  for (let i = 0, t; i < domTree.length; i++) {
5153
5133
  t = domTree[i];
5154
5134
 
5155
- if (!util.isFormatElement(t) && !util.isComponent(t) && !util.isMedia(t)) {
5135
+ if (!util.isFormatElement(t) && !util.isRangeFormatElement(t) && !util.isComponent(t) && !util.isMedia(t)) {
5156
5136
  if (!p) p = util.createElement(options.defaultTag);
5157
5137
  p.appendChild(t);
5158
5138
  i--;
@@ -5626,12 +5606,8 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
5626
5606
  this.codeViewDisabledButtons = context.element._buttonTray.querySelectorAll('.se-menu-list button[data-display]:not([class~="se-code-view-enabled"]):not([data-display="MORE"])');
5627
5607
  this.resizingDisabledButtons = context.element._buttonTray.querySelectorAll('.se-menu-list button[data-display]:not([class~="se-resizing-enabled"]):not([data-display="MORE"])');
5628
5608
 
5629
- this.saveButtonStates();
5630
-
5631
5609
  const tool = context.tool;
5632
5610
  this.commandMap = {
5633
- SUB: tool.subscript,
5634
- SUP: tool.superscript,
5635
5611
  OUTDENT: tool.outdent,
5636
5612
  INDENT: tool.indent
5637
5613
  };
@@ -5639,6 +5615,8 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
5639
5615
  this.commandMap[options.textTags.underline.toUpperCase()] = tool.underline;
5640
5616
  this.commandMap[options.textTags.italic.toUpperCase()] = tool.italic;
5641
5617
  this.commandMap[options.textTags.strike.toUpperCase()] = tool.strike;
5618
+ this.commandMap[options.textTags.sub.toUpperCase()] = tool.subscript;
5619
+ this.commandMap[options.textTags.sup.toUpperCase()] = tool.superscript;
5642
5620
 
5643
5621
  this._styleCommandMap = {
5644
5622
  fullScreen: tool.fullScreen,
@@ -5978,7 +5956,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
5978
5956
 
5979
5957
  const marginDir = options.rtl ? 'marginRight' : 'marginLeft';
5980
5958
  const commandMap = core.commandMap;
5981
- const classOnCheck = this._onButtonsCheck;
5959
+ const classOnCheck = event._onButtonsCheck;
5982
5960
  const commandMapNodes = [];
5983
5961
  const currentNodes = [];
5984
5962
 
@@ -7233,6 +7211,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
7233
7211
  onBlur_wysiwyg: function (e) {
7234
7212
  if (core._antiBlur || core._variable.isCodeView) return;
7235
7213
  core.hasFocus = false;
7214
+ core.effectNode = null;
7236
7215
  core.controllersOff();
7237
7216
  if (core._isInline || core._isBalloon) event._hideToolbar();
7238
7217
 
@@ -7605,7 +7584,9 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
7605
7584
  for (let i = 0, len = domTree.length, node; i < len; i++) {
7606
7585
  node = domTree[i];
7607
7586
  if (node.nodeType === 1) {
7608
- if (util.isFormatElement(node)) {
7587
+ if (util.isListCell(node)) {
7588
+ html += node.outerHTML;
7589
+ } else if (util.isFormatElement(node)) {
7609
7590
  html += '<li>' +(node.innerHTML.trim() || '<br>') + '</li>';
7610
7591
  } else if (util.isRangeFormatElement(node) && !util.isTable(node)) {
7611
7592
  html += event._convertListCell(node);
@@ -8117,11 +8098,10 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
8117
8098
  context.tool = newContext.tool;
8118
8099
  if (options.iframe) context.element.wysiwyg = core._wd.body;
8119
8100
 
8120
- core.recoverButtonStates();
8121
-
8122
8101
  core._cachingButtons();
8123
8102
  core.history._resetCachingButton();
8124
8103
 
8104
+ core.effectNode = null;
8125
8105
  if (core.hasFocus) event._applyTagEffects();
8126
8106
  if (core.isReadOnly) util.setDisabledButtons(true, core.resizingDisabledButtons);
8127
8107
  if (typeof functions.onSetToolbarButtons === 'function') functions.onSetToolbarButtons(newToolbar._buttonTray.querySelectorAll('button'), core);
@@ -8668,4 +8648,4 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
8668
8648
  }
8669
8649
 
8670
8650
  return functions;
8671
- }
8651
+ }
@@ -23,8 +23,7 @@ export default {
23
23
  context.math.focusElement = math_dialog.querySelector('.se-math-exp');
24
24
  context.math.previewElement = math_dialog.querySelector('.se-math-preview');
25
25
  context.math.fontSizeElement = math_dialog.querySelector('.se-math-size');
26
- context.math.focusElement.addEventListener('keyup', this._renderMathExp.bind(core, context.math), false);
27
- context.math.focusElement.addEventListener('change', this._renderMathExp.bind(core, context.math), false);
26
+ context.math.focusElement.addEventListener(core.util.isIE ? 'textinput' : 'input', this._renderMathExp.bind(core, context.math), false);
28
27
  context.math.fontSizeElement.addEventListener('change', function (e) { this.fontSize = e.target.value; }.bind(context.math.previewElement.style), false);
29
28
 
30
29
  /** math controller */
@@ -140,7 +139,7 @@ export default {
140
139
 
141
140
  _renderer: function (exp) {
142
141
  const katex = this.options.katex;
143
- return katex.src.renderToString(exp, katex.options);
142
+ return katex.src.renderToString(exp, {throwOnError: true, displayMode: true});
144
143
  },
145
144
 
146
145
  _renderMathExp: function (contextMath, e) {
@@ -817,7 +817,7 @@ export default {
817
817
 
818
818
  if (!onlyH) w = this.util.getNumber(w, 0);
819
819
  if (!onlyW) h = this.util.isNumber(h) ? h + contextVideo.sizeUnit : !h ? '' : h;
820
- w ? w + contextVideo.sizeUnit : '';
820
+ w = w ? w + contextVideo.sizeUnit : '';
821
821
 
822
822
  if (!onlyH) contextVideo._element.style.width = w;
823
823
  if (!onlyW) contextVideo._cover.style.paddingBottom = contextVideo._cover.style.height = h;