suneditor 2.43.13 → 2.44.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "suneditor",
3
- "version": "2.43.13",
3
+ "version": "2.44.0",
4
4
  "description": "Pure JavaScript based WYSIWYG web editor",
5
5
  "author": "JiHong.Lee",
6
6
  "license": "MIT",
@@ -32,6 +32,10 @@
32
32
  direction: rtl;
33
33
  }
34
34
 
35
+ .sun-editor-editable .se-component > figure {
36
+ direction: initial;
37
+ }
38
+
35
39
  /** controllers on tag */
36
40
  .sun-editor-editable td, .sun-editor-editable th,
37
41
  .sun-editor-editable figure, .sun-editor-editable figcaption, .sun-editor-editable img,
@@ -39,20 +43,6 @@
39
43
  position: relative;
40
44
  }
41
45
 
42
- /* float */
43
- .sun-editor-editable .__se__float-left {
44
- float: left;
45
- }
46
- .sun-editor-editable .__se__float-right {
47
- float: right;
48
- }
49
- .sun-editor-editable .__se__float-center {
50
- float: center;
51
- }
52
- .sun-editor-editable .__se__float-none {
53
- float: none;
54
- }
55
-
56
46
  /** span */
57
47
  .sun-editor-editable span {
58
48
  display: inline;
@@ -364,6 +354,22 @@
364
354
  -webkit-box-shadow:0 0 0 0.2rem #80bdff; box-shadow:0 0 0 0.2rem #3f9dff; transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;
365
355
  }
366
356
 
357
+ /* float */
358
+ .sun-editor-editable .__se__float-left {
359
+ float: left;
360
+ margin-right: 4px;
361
+ }
362
+ .sun-editor-editable .__se__float-right {
363
+ float: right;
364
+ margin-left: 4px;
365
+ }
366
+ .sun-editor-editable .__se__float-center {
367
+ float: center;
368
+ }
369
+ .sun-editor-editable .__se__float-none {
370
+ float: none;
371
+ }
372
+
367
373
  /** image, video .. */
368
374
  .sun-editor-editable img, .sun-editor-editable iframe, .sun-editor-editable video, .sun-editor-editable audio {
369
375
  display: block;
@@ -2,7 +2,7 @@
2
2
  /* font color #333, background color: #fff */
3
3
  /* grey color #e1e1e1 , #d1d1d1 , #c1c1c1 , #b1b1b1 */
4
4
  /* blue color #c7deff , #80bdff , #3f9dff , #4592ff, #407dd1, #3288ff */
5
- /* red color #b94a48 , #f2dede , #eed3d7 */
5
+ /* red color #b94a48 , #f2dede , #eed3d7, #d9534f */
6
6
 
7
7
  /** --- suneditor main */
8
8
  .sun-editor {width:auto; height:auto; box-sizing:border-box; font-family:Helvetica Neue; border:1px solid #dadada; background-color:#FFF; color:#000; user-select:none; -o-user-select:none; -moz-user-select:none; -khtml-user-select:none; -webkit-user-select:none; -ms-user-select:none;}
@@ -32,6 +32,9 @@
32
32
 
33
33
  /** --- Icons ---------------------------------------------------------- */
34
34
  /* default svg */
35
+ .sun-editor svg {
36
+ fill: currentColor;
37
+ }
35
38
  .sun-editor button > svg, .sun-editor .se-svg {
36
39
  width: 16px;
37
40
  height: 16px;
@@ -340,6 +343,8 @@
340
343
  .sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-math-preview {font-size:13px;}
341
344
  .sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-math-preview > span {display:inline-block; -webkit-box-shadow:0 0 0 0.1rem #c7deff; box-shadow:0 0 0 0.1rem #c7deff;}
342
345
  .sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-math-preview > span * {direction:ltr;}
346
+ .sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-math-preview > .se-math-katex-error {color:#b94a48; -webkit-box-shadow:0 0 0 0.1rem #f2dede; box-shadow:0 0 0 0.1rem #f2dede;}
347
+ .sun-editor .se-dialog .se-dialog-inner .se-dialog-form .se-math-preview > .se-math-katex-error svg {width:auto; height:30px; color:#b94a48;}
343
348
  /* dialog - modal - link preview */
344
349
  .sun-editor .se-dialog .se-dialog-inner .se-link-preview {display:block; height:auto; max-height:18px; font-size:13px; font-weight:normal; font-family:inherit; color:#666; background-color:transparent; overflow:hidden; text-overflow:ellipsis; word-break:break-all; white-space:pre;}
345
350
  /* dialog - modal - anchor module */
@@ -454,8 +459,8 @@
454
459
 
455
460
  /** --- tooltip */
456
461
  .sun-editor .se-tooltip {position:relative; overflow:visible;}
457
- .sun-editor .se-tooltip .se-tooltip-inner {visibility:hidden; position:absolute; display:block; width:auto; top:120%; left:50%; background:transparent; opacity:0; z-index:1; line-height:1.5; transition:opacity 0.5s; margin:0; padding:0; bottom:auto; float:none; pointer-events:none; backface-visibility:hidden; -webkit-backface-visibility:hidden; -moz-backface-visibility:hidden;}
458
- .sun-editor .se-tooltip .se-tooltip-inner .se-tooltip-text {position:relative; display:inline-block; width:auto; left:-50%; font-size:0.9em; margin:0; padding:4px 6px; border-radius:2px; background-color:#333; color:#fff; text-align:center; line-height:unset; white-space:nowrap; cursor:auto;}
462
+ .sun-editor .se-tooltip .se-tooltip-inner {visibility:hidden; position:absolute; display:block; width:auto; height:auto; top:120%; left:50%; background:transparent; opacity:0; z-index:1; line-height:1.5; transition:opacity 0.5s; margin:0; padding:0; bottom:auto; float:none; pointer-events:none; backface-visibility:hidden; -webkit-backface-visibility:hidden; -moz-backface-visibility:hidden;}
463
+ .sun-editor .se-tooltip .se-tooltip-inner .se-tooltip-text {position:relative; display:inline-block; width:auto; height:auto; left:-50%; font-size:0.9em; margin:0; padding:4px 6px; border-radius:2px; background-color:#333; color:#fff; text-align:center; line-height:unset; white-space:nowrap; cursor:auto;}
459
464
  .sun-editor .se-tooltip .se-tooltip-inner .se-tooltip-text::after {content:""; position:absolute; bottom:100%; left:50%; margin-left:-5px; border-width:5px; border-style:solid; border-color:transparent transparent #333 transparent;}
460
465
  .sun-editor .se-tooltip:hover .se-tooltip-inner {visibility:visible; opacity:1;}
461
466
  .sun-editor .se-tooltip .se-tooltip-inner .se-tooltip-text .se-shortcut {display:block !important;}
@@ -496,6 +501,7 @@
496
501
 
497
502
  /* dialog--- */
498
503
  .sun-editor.se-rtl .se-dialog * {direction:rtl;}
504
+ .sun-editor.se-rtl .se-dialog .se-dialog-inner .se-dialog-form .se-video-ratio {margin-left:0; margin-right:4px;}
499
505
  /* dialog - header */
500
506
  .sun-editor.se-rtl .se-dialog .se-dialog-inner .se-dialog-header .se-dialog-close {float:left;}
501
507
  .sun-editor.se-rtl .se-dialog .se-dialog-inner .se-dialog-header .se-modal-title {float:right;}
@@ -530,6 +536,17 @@
530
536
  .sun-editor .se-btn-module-border.module-float-right {float:right;}
531
537
 
532
538
 
539
+ /** --- error ---------------------------------------------------------- */
540
+ .sun-editor .se-error {color:#d9534f;}
541
+ .sun-editor input.se-error:focus, select.se-error:focus, textarea.se-error:focus {
542
+ border: 1px solid #f2dede;
543
+ outline: 0;
544
+ -webkit-box-shadow: 0 0 0 0.2rem #eed3d7;
545
+ box-shadow: 0 0 0 0.2rem #eed3d7;
546
+ transition: border-color .15s ease-in-out,box-shadow .15s ease-in-out;
547
+ }
548
+
549
+
533
550
  /** ---------------------------------------------------------- menu items style ---------------------------------------------------------- */
534
551
  /** hr menu items */
535
552
  .sun-editor hr.__se__solid {
@@ -87,6 +87,8 @@ export default {
87
87
  download: '<svg viewBox="0 0 24 24"><path d="M2 12H4V17H20V12H22V17C22 18.11 21.11 19 20 19H4C2.9 19 2 18.11 2 17V12M12 15L17.55 9.54L16.13 8.13L13 11.25V2H11V11.25L7.88 8.13L6.46 9.55L12 15Z" /></svg>',
88
88
  dir_ltr: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M9 4v4c-1.1 0-2-.9-2-2s.9-2 2-2m8-2H9C6.79 2 5 3.79 5 6s1.79 4 4 4v5h2V4h2v11h2V4h2V2zm0 12v3H5v2h12v3l4-4-4-4z"/></svg>',
89
89
  dir_rtl: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M10 4v4c-1.1 0-2-.9-2-2s.9-2 2-2m8-2h-8C7.79 2 6 3.79 6 6s1.79 4 4 4v5h2V4h2v11h2V4h2V2zM8 14l-4 4 4 4v-3h12v-2H8v-3z"/></svg>',
90
+ // Error
91
+ alert_outline: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M11,15H13V17H11V15M11,7H13V13H11V7M12,2C6.47,2 2,6.5 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M12,20A8,8 0 0,1 4,12A8,8 0 0,1 12,4A8,8 0 0,1 20,12A8,8 0 0,1 12,20Z" /></svg>',
90
92
  // More icons
91
93
  more_text: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="10 10 180 180"><g><path d="M49.711,142.188h49.027c2.328,0.002,4.394,1.492,5.129,3.699l9.742,29.252c0.363,1.092,1.385,1.828,2.537,1.83l15.883,0.01c0.859,0,1.667-0.412,2.17-1.109s0.641-1.594,0.37-2.41l-16.625-50.045L86.503,28.953c-0.36-1.097-1.383-1.839-2.537-1.842H64.532c-1.153-0.001-2.178,0.736-2.542,1.831L13.847,173.457c-0.271,0.816-0.135,1.713,0.369,2.412c0.503,0.697,1.311,1.109,2.171,1.109h15.872c1.151,0,2.173-0.736,2.537-1.828l9.793-29.287C45.325,143.66,47.39,142.18,49.711,142.188L49.711,142.188z M53.493,119.098l15.607-46.9c0.744-2.196,2.806-3.674,5.125-3.674s4.381,1.478,5.125,3.674l15.607,46.904c0.537,1.621,0.263,3.402-0.736,4.789c-1.018,1.408-2.649,2.24-4.386,2.24H58.615c-1.736,0-3.368-0.832-4.386-2.24C53.23,122.504,52.956,120.721,53.493,119.098L53.493,119.098z M190.465,63.32c0-2.919-1.015-5.396-3.059-7.428c-2.029-2.031-4.496-3.047-7.383-3.047c-2.889,0-5.355,1.016-7.388,3.047c-2.029,2.032-3.056,4.498-3.056,7.386c0,2.889,1.026,5.354,3.056,7.385c2.032,2.032,4.499,3.059,7.388,3.059c2.887,0,5.354-1.026,7.383-3.059C189.45,68.633,190.465,66.178,190.465,63.32L190.465,63.32z M190.465,101.994c0-2.858-1.015-5.313-3.059-7.333c-2.029-2.042-4.496-3.047-7.383-3.047c-2.889,0-5.355,1.005-7.388,3.047c-2.029,2.021-3.056,4.486-3.056,7.376c0,2.887,1.026,5.352,3.056,7.395c2.032,2.021,4.499,3.047,7.388,3.047c2.887,0,5.354-1.025,7.383-3.047C189.45,107.389,190.465,104.914,190.465,101.994L190.465,101.994z M190.465,140.76c0-2.918-1.015-5.395-3.059-7.438c-2.029-2.041-4.496-3.047-7.383-3.047c-2.889,0-5.355,1.006-7.388,3.047c-2.029,2.043-3.056,4.52-3.056,7.438c0,2.922,1.026,5.398,3.056,7.439c2.032,2.021,4.499,3.047,7.388,3.047c2.887,0,5.354-1.025,7.383-3.047C189.45,146.158,190.465,143.682,190.465,140.76L190.465,140.76z"/></g></svg>',
92
94
  more_paragraph: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="10 10 180 180"><g><path d="M128.39,28.499H63.493c-25.558,0-46.354,20.796-46.354,46.354c0,25.559,20.796,46.353,46.354,46.353h9.271v55.625h18.542V47.04h9.271V176.83h18.543V47.04h9.271V28.499z M72.764,102.664h-9.271c-15.337,0-27.813-12.475-27.813-27.812c0-15.336,12.476-27.813,27.813-27.813h9.271V102.664z M190.465,63.32c0-2.919-1.015-5.396-3.059-7.428c-2.029-2.031-4.496-3.047-7.383-3.047c-2.889,0-5.355,1.016-7.388,3.047c-2.029,2.032-3.056,4.498-3.056,7.386c0,2.889,1.026,5.354,3.056,7.385c2.032,2.032,4.499,3.059,7.388,3.059c2.887,0,5.354-1.026,7.383-3.059C189.45,68.633,190.465,66.178,190.465,63.32L190.465,63.32z M190.465,101.994c0-2.858-1.015-5.313-3.059-7.333c-2.029-2.042-4.496-3.047-7.383-3.047c-2.889,0-5.355,1.005-7.388,3.047c-2.029,2.021-3.056,4.486-3.056,7.376c0,2.887,1.026,5.352,3.056,7.395c2.032,2.021,4.499,3.047,7.388,3.047c2.887,0,5.354-1.025,7.383-3.047C189.45,107.389,190.465,104.914,190.465,101.994L190.465,101.994z M190.465,140.76c0-2.918-1.015-5.395-3.059-7.438c-2.029-2.041-4.496-3.047-7.383-3.047c-2.889,0-5.355,1.006-7.388,3.047c-2.029,2.043-3.056,4.52-3.056,7.438c0,2.922,1.026,5.398,3.056,7.439c2.032,2.021,4.499,3.047,7.388,3.047c2.887,0,5.354-1.025,7.383-3.047C189.45,146.158,190.465,143.682,190.465,140.76L190.465,140.76z"/></g></svg>',
@@ -410,6 +410,7 @@ export default {
410
410
  options.lang = options.lang || _defaultLang;
411
411
  options.value = typeof options.value === 'string' ? options.value : null;
412
412
  options.historyStackDelayTime = typeof options.historyStackDelayTime === 'number' ? options.historyStackDelayTime : 400;
413
+ options.frameAttrbutes = options.frameAttrbutes || {};
413
414
  // tag style
414
415
  options.defaultTag = typeof options.defaultTag === 'string' && options.defaultTag.length > 0 ? options.defaultTag : 'p';
415
416
  const textTags = options.textTags = [{bold: 'STRONG', underline: 'U', italic: 'EM', strike: 'DEL', sub: 'SUB', sup: 'SUP'}, (options.textTags || {})].reduce(function (_default, _new) {
@@ -511,7 +512,7 @@ export default {
511
512
  options.lineHeights = !options.lineHeights ? null : options.lineHeights;
512
513
  options.paragraphStyles = !options.paragraphStyles ? null : options.paragraphStyles;
513
514
  options.textStyles = !options.textStyles ? null : options.textStyles;
514
- options.fontSizeUnit = typeof options.fontSizeUnit === 'string' ? (options.fontSizeUnit.trim() || 'px') : 'px';
515
+ options.fontSizeUnit = typeof options.fontSizeUnit === 'string' ? (options.fontSizeUnit.trim().toLowerCase() || 'px') : 'px';
515
516
  options.alignItems = typeof options.alignItems === 'object' ? options.alignItems : (options.rtl ? ['right', 'center', 'left', 'justify'] : ['left', 'center', 'right', 'justify']);
516
517
  /** Image */
517
518
  options.imageResizing = options.imageResizing === undefined ? true : options.imageResizing;
package/src/lib/core.js CHANGED
@@ -474,8 +474,9 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
474
474
  * @private
475
475
  */
476
476
  _cleanStyleRegExp: {
477
- span: new _w.RegExp('\s*(font-family|font-size|color|background-color)\s*:[^;]+(?!;)*', 'ig'),
478
- format: new _w.RegExp('\s*(text-align|margin-left|margin-right)\s*:[^;]+(?!;)*', 'ig')
477
+ span: new _w.RegExp('\\s*(font-family|font-size|color|background-color)\\s*:[^;]+(?!;)*', 'ig'),
478
+ format: new _w.RegExp('\\s*(text-align|margin-left|margin-right)\\s*:[^;]+(?!;)*', 'ig'),
479
+ fontSizeUnit: new _w.RegExp('\\d+' + options.fontSizeUnit + '$', 'i'),
479
480
  },
480
481
 
481
482
  /**
@@ -1777,7 +1778,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
1777
1778
  let c = parentNode.childNodes[startOff];
1778
1779
  const focusNode = (c && c.nodeType === 3 && util.onlyZeroWidthSpace(c) && util.isBreak(c.nextSibling)) ? c.nextSibling : c;
1779
1780
  if (focusNode) {
1780
- if (!focusNode.nextSibling) {
1781
+ if (!focusNode.nextSibling && util.isBreak(focusNode)) {
1781
1782
  parentNode.removeChild(focusNode);
1782
1783
  afterNode = null;
1783
1784
  } else {
@@ -1793,7 +1794,6 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
1793
1794
  }
1794
1795
  } else { /** Select range nodes */
1795
1796
  const isSameContainer = startCon === endCon;
1796
-
1797
1797
  if (isSameContainer) {
1798
1798
  if (this.isEdgePoint(endCon, endOff)) afterNode = endCon.nextSibling;
1799
1799
  else afterNode = endCon.splitText(endOff);
@@ -2057,6 +2057,16 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
2057
2057
  startOff = endOff = 0;
2058
2058
  }
2059
2059
 
2060
+ if (startCon === endCon && range.collapsed) {
2061
+ if (startCon.textContent && util.onlyZeroWidthSpace(startCon.textContent.substr(startOff))) {
2062
+ return {
2063
+ container: startCon,
2064
+ offset: offset,
2065
+ prevContainer: startCon && startCon.parentNode ? startCon : null
2066
+ };
2067
+ }
2068
+ }
2069
+
2060
2070
  let beforeNode = null;
2061
2071
  let afterNode = null;
2062
2072
 
@@ -4721,7 +4731,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
4721
4731
  _var._codeOriginCssText = code.style.cssText;
4722
4732
 
4723
4733
  editorArea.style.cssText = toolbar.style.cssText = '';
4724
- wysiwygFrame.style.cssText = (wysiwygFrame.style.cssText.match(/\s?display(\s+)?:(\s+)?[a-zA-Z]+;/) || [''])[0];
4734
+ wysiwygFrame.style.cssText = (wysiwygFrame.style.cssText.match(/\s?display(\s+)?:(\s+)?[a-zA-Z]+;/) || [''])[0] + options.defaultStyle;
4725
4735
  code.style.cssText = (code.style.cssText.match(/\s?display(\s+)?:(\s+)?[a-zA-Z]+;/) || [''])[0];
4726
4736
  toolbar.style.width = wysiwygFrame.style.height = code.style.height = '100%';
4727
4737
  toolbar.style.position = 'relative';
@@ -4889,7 +4899,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
4889
4899
  '<!DOCTYPE html><html>' +
4890
4900
  '<head>' +
4891
4901
  '<meta charset="utf-8" />' +
4892
- '<meta name="viewport" content="width=device-width, initial-scale=1">' +
4902
+ '<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">' +
4893
4903
  '<title>' + lang.toolbar.preview + '</title>' +
4894
4904
  linkHTML +
4895
4905
  '</head>' +
@@ -5102,6 +5112,32 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
5102
5112
  .replace(this.editorTagsBlacklistRegExp, '');
5103
5113
  },
5104
5114
 
5115
+ _convertFontSize: function (to, size) {
5116
+ const value = size.match(/(\d+(?:\.\d+)?)(.+)/);
5117
+ const sizeNum = value[1] * 1;
5118
+ const from = value[2];
5119
+ let pxSize = sizeNum;
5120
+
5121
+ if (/em/.test(from)) {
5122
+ pxSize = this.round(sizeNum / 0.0625);
5123
+ } else if (from === 'pt') {
5124
+ pxSize = this.round(sizeNum * 1.333);
5125
+ } else if (from === '%') {
5126
+ pxSize = sizeNum / 100;
5127
+ }
5128
+
5129
+ switch (to) {
5130
+ case 'em':
5131
+ case 'rem':
5132
+ case '%':
5133
+ return (pxSize * 0.0625).toFixed(2) + to;
5134
+ case 'pt':
5135
+ return this._w.Math.floor(pxSize / 1.333) + to;
5136
+ default: // px
5137
+ return pxSize + to;
5138
+ }
5139
+ },
5140
+
5105
5141
  _cleanStyle: function (m, v, name) {
5106
5142
  const sv = m.match(/style\s*=\s*(?:"|')[^"']*(?:"|')/);
5107
5143
  if (sv) {
@@ -5121,6 +5157,9 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
5121
5157
  break;
5122
5158
  case 'fontSize':
5123
5159
  if (!options.plugins.fontSize) continue;
5160
+ if (!this._cleanStyleRegExp.fontSizeUnit.test(r[0])) {
5161
+ r[0] = r[0].replace(this._w.RegExp('\\d+' + r[0].match(/\d+(.+$)/)[1]), this._convertFontSize.bind(this._w.Math, options.fontSizeUnit));
5162
+ }
5124
5163
  break;
5125
5164
  case 'color':
5126
5165
  if (!options.plugins.fontColor || /rgba\(([0-9]+\s*,\s*){3}0\)|windowtext/i.test(c)) continue;
@@ -5299,7 +5338,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
5299
5338
  * @returns {String}
5300
5339
  */
5301
5340
  cleanHTML: function (html, whitelist, blacklist) {
5302
- html = this._deleteDisallowedTags(this._parser.parseFromString(html, 'text/html').body.innerHTML).replace(/(<[a-zA-Z0-9\-]+)[^>]*(?=>)/g, this._cleanTags.bind(this, true)).replace(/^.+\x3C!--StartFragment--\>|\x3C!--EndFragment-->.+$/g, '');
5341
+ html = this._deleteDisallowedTags(this._parser.parseFromString(html, 'text/html').body.innerHTML).replace(/(<[a-zA-Z0-9\-]+)[^>]*(?=>)/g, this._cleanTags.bind(this, true));
5303
5342
 
5304
5343
  const dom = _d.createRange().createContextualFragment(html);
5305
5344
  try {
@@ -5925,7 +5964,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
5925
5964
  },
5926
5965
 
5927
5966
  __callResizeFunction: function (h, resizeObserverEntry) {
5928
- h = h === -1 ? (resizeObserverEntry.borderBoxSize ? resizeObserverEntry.borderBoxSize[0].blockSize : (resizeObserverEntry.contentRect.height + this._editorHeightPadding)) : h;
5967
+ h = h === -1 ? (resizeObserverEntry.borderBoxSize && resizeObserverEntry.borderBoxSize[0] ? resizeObserverEntry.borderBoxSize[0].blockSize : (resizeObserverEntry.contentRect.height + this._editorHeightPadding)) : h;
5929
5968
  if (this._editorHeight !== h) {
5930
5969
  if (typeof functions.onResizeEditor === 'function') functions.onResizeEditor(h, this._editorHeight, core, resizeObserverEntry);
5931
5970
  this._editorHeight = h;
@@ -6063,18 +6102,24 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
6063
6102
 
6064
6103
  // toolbar visibility
6065
6104
  context.element.toolbar.style.visibility = '';
6105
+ // wisywig attributes
6106
+ const attr = options.frameAttrbutes;
6107
+ for (let k in attr) {
6108
+ context.element.wysiwyg.setAttribute(k, attr[k]);
6109
+ }
6066
6110
 
6067
6111
  this._checkComponents();
6068
6112
  this._componentsInfoInit = false;
6069
6113
  this._componentsInfoReset = false;
6070
6114
 
6071
6115
  this.history.reset(true);
6072
- this._resourcesStateChange();
6073
-
6116
+
6074
6117
  _w.setTimeout(function () {
6075
6118
  // observer
6076
6119
  if (event._resizeObserver) event._resizeObserver.observe(context.element.wysiwygFrame);
6077
6120
  if (event._toolbarObserver) event._toolbarObserver.observe(context.element._toolbarShadow);
6121
+ // resource state
6122
+ core._resourcesStateChange();
6078
6123
  // user event
6079
6124
  if (typeof functions.onload === 'function') functions.onload(core, reload);
6080
6125
  });
@@ -6617,9 +6662,6 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
6617
6662
 
6618
6663
  core._editorRange();
6619
6664
 
6620
- // user event
6621
- if (typeof functions.onInput === 'function' && functions.onInput(e, core) === false) return;
6622
-
6623
6665
  const data = (e.data === null ? '' : e.data === undefined ? ' ' : e.data) || '';
6624
6666
  if (!core._charCount(data)) {
6625
6667
  e.preventDefault();
@@ -6627,6 +6669,9 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
6627
6669
  return false;
6628
6670
  }
6629
6671
 
6672
+ // user event
6673
+ if (typeof functions.onInput === 'function' && functions.onInput(e, core) === false) return;
6674
+
6630
6675
  // history stack
6631
6676
  core.history.push(true);
6632
6677
  },
@@ -7774,6 +7819,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
7774
7819
  const onlyText = !cleanData;
7775
7820
 
7776
7821
  if (!onlyText) {
7822
+ cleanData = cleanData.replace(/^<html>\r\n<body>\r\n\x3C!--StartFragment--\>|\x3C!--EndFragment-->\r\n<\/body\>\r\n<\/html>$/g, '');
7777
7823
  if (MSData) {
7778
7824
  cleanData = cleanData.replace(/\n/g, ' ');
7779
7825
  plainText = plainText.replace(/\n/g, ' ');
@@ -8061,12 +8107,12 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
8061
8107
  */
8062
8108
  onChange: null,
8063
8109
 
8064
- /**
8110
+ /**
8065
8111
  * @description Event functions
8066
8112
  * @param {String} contents Current contents
8067
8113
  * @param {Object} core Core object
8068
8114
  */
8069
- onSave: null,
8115
+ onSave: null,
8070
8116
 
8071
8117
  /**
8072
8118
  * @description Event functions (drop, paste)
@@ -8435,6 +8481,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
8435
8481
 
8436
8482
  /**
8437
8483
  * @description Copying the contents of the editor to the original textarea and execute onSave callback
8484
+ * * not working during enabled codeView mode
8438
8485
  */
8439
8486
  save: function () {
8440
8487
  const contents = core.getContents(false);
@@ -8452,6 +8499,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
8452
8499
 
8453
8500
  /**
8454
8501
  * @description Gets the contents of the suneditor
8502
+ * * not working during enabled codeView mode
8455
8503
  * @param {Boolean} onlyContents - Return only the contents of the body without headers when the "fullPage" option is true
8456
8504
  * @returns {String}
8457
8505
  */
@@ -8461,6 +8509,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
8461
8509
 
8462
8510
  /**
8463
8511
  * @description Gets only the text of the suneditor contents
8512
+ * * not working during enabled codeView mode
8464
8513
  * @returns {String}
8465
8514
  */
8466
8515
  getText: function () {
package/src/lib/util.js CHANGED
@@ -1805,7 +1805,7 @@ const util = {
1805
1805
  // wrong position
1806
1806
  const wrongTags = this.getListChildNodes(documentFragment, function (current) {
1807
1807
  if (current.nodeType !== 1) {
1808
- if (this.isList(current.parentNode)) removeTags.push(current);
1808
+ if (this.isList(current.parentElement)) removeTags.push(current);
1809
1809
  return false;
1810
1810
  }
1811
1811
 
@@ -1947,7 +1947,7 @@ const util = {
1947
1947
  frame.setAttribute('scrolling', 'auto');
1948
1948
  frame.contentDocument.head.innerHTML = '' +
1949
1949
  '<meta charset="utf-8" />' +
1950
- '<meta name="viewport" content="width=device-width, initial-scale=1">' +
1950
+ '<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">' +
1951
1951
  this._setIframeCssTags(options);
1952
1952
  frame.contentDocument.body.className = options._editableClass;
1953
1953
  frame.contentDocument.body.setAttribute('contenteditable', true);
@@ -649,7 +649,7 @@ export default {
649
649
  oImg.src = src;
650
650
  oImg.alt = alt;
651
651
  oImg.setAttribute('data-rotate', '0');
652
- anchor = imagePlugin.onRender_link.call(this, oImg, anchor);
652
+ anchor = imagePlugin.onRender_link.call(this, oImg, anchor ? anchor.cloneNode(false) : null);
653
653
 
654
654
  if (contextImage._resizing) {
655
655
  oImg.setAttribute('data-proportion', contextImage._proportionChecked);
@@ -933,8 +933,8 @@ export default {
933
933
  */
934
934
  setSize: function (w, h, notResetPercentage, direction) {
935
935
  const contextImage = this.context.image;
936
- const onlyW = /^(rw|lw)$/.test(direction);
937
- const onlyH = /^(th|bh)$/.test(direction);
936
+ const onlyW = /^(rw|lw)$/.test(direction) && /\d+/.test(contextImage._element.style.height);
937
+ const onlyH = /^(th|bh)$/.test(direction) && /\d+/.test(contextImage._element.style.width);
938
938
 
939
939
  if (!onlyH) {
940
940
  contextImage._element.style.width = this.util.isNumber(w) ? w + contextImage.sizeUnit : w;
@@ -957,6 +957,7 @@ export default {
957
957
  setAutoSize: function () {
958
958
  const contextImage = this.context.image;
959
959
 
960
+ if (contextImage._caption) contextImage._caption.style.marginTop = '';
960
961
  this.plugins.resizing.resetTransform.call(this, contextImage._element);
961
962
  this.plugins.image.cancelPercentAttr.call(this);
962
963
 
@@ -2,6 +2,8 @@
2
2
 
3
3
  import dialog from '../modules/dialog';
4
4
 
5
+ const KATEX_WEBSITE = "https://katex.org/docs/supported.html";
6
+
5
7
  export default {
6
8
  name: 'math',
7
9
  display: 'dialog',
@@ -63,7 +65,7 @@ export default {
63
65
  '</div>' +
64
66
  '<div class="se-dialog-body">' +
65
67
  '<div class="se-dialog-form">' +
66
- '<label>' + lang.dialogBox.mathBox.inputLabel + ' (<a href="https://katex.org/docs/supported.html" target="_blank">KaTeX</a>)</label>' +
68
+ '<label>' + lang.dialogBox.mathBox.inputLabel + ' (<a href="' + KATEX_WEBSITE + '" target="_blank">KaTeX</a>)</label>' +
67
69
  '<textarea class="se-input-form se-math-exp" type="text"></textarea>' +
68
70
  '</div>' +
69
71
  '<div class="se-dialog-form">' +
@@ -138,8 +140,16 @@ export default {
138
140
  },
139
141
 
140
142
  _renderer: function (exp) {
141
- const katex = this.options.katex;
142
- return katex.src.renderToString(exp, {throwOnError: true, displayMode: true});
143
+ let result = '';
144
+ try {
145
+ this.util.removeClass(this.context.math.focusElement, 'se-error');
146
+ result = this.options.katex.src.renderToString(exp, {throwOnError: true, displayMode: true});
147
+ } catch(error) {
148
+ this.util.addClass(this.context.math.focusElement, 'se-error');
149
+ result = '<span class="se-math-katex-error">Katex syntax error. (Refer <a href="' + KATEX_WEBSITE + '" target="_blank">KaTeX</a>)</span>';
150
+ console.warn('[SUNEDITOR.math.Katex.error] ', error);
151
+ }
152
+ return result;
143
153
  },
144
154
 
145
155
  _renderMathExp: function (contextMath, e) {
@@ -540,7 +540,7 @@ export default {
540
540
  url = 'https://player.vimeo.com/video/' + url.slice(url.lastIndexOf('/') + 1);
541
541
  }
542
542
 
543
- this.plugins.video.create_video.call(this, this.plugins.video[(!/youtu\.?be/.test(url) && !/vimeo\.com/.test(url) ? "createVideoTag" : "createIframeTag")].call(this), url, contextVideo.inputX.value, contextVideo.inputY.value, contextVideo._align, null, this.context.dialog.updateModal);
543
+ this.plugins.video.create_video.call(this, this.plugins.video[(!/embed|iframe|player|\/e\/|\.php|\.html?/.test(url) && !/vimeo\.com/.test(url) ? "createVideoTag" : "createIframeTag")].call(this), url, contextVideo.inputX.value, contextVideo.inputY.value, contextVideo._align, null, this.context.dialog.updateModal);
544
544
  } catch (error) {
545
545
  throw Error('[SUNEDITOR.video.upload.fail] cause : "' + error.message + '"');
546
546
  } finally {