suneditor 2.46.3 → 2.47.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.46.3",
3
+ "version": "2.47.0",
4
4
  "description": "Vanilla javascript based WYSIWYG web editor, with no dependencies",
5
5
  "author": "JiHong.Lee",
6
6
  "license": "MIT",
@@ -97,7 +97,7 @@
97
97
  .sun-editor .se-toolbar .se-arrow.se-arrow-down::after {border-top-color:#fafafa;}
98
98
 
99
99
  /** --- container */
100
- .sun-editor .se-container {position:relative; width:100%; height:100%;}
100
+ .sun-editor .se-container {position:relative; width:auto; height:auto;}
101
101
 
102
102
  /** button */
103
103
  .sun-editor button {color:#000;}
@@ -563,4 +563,4 @@
563
563
 
564
564
  /** animation */
565
565
  @keyframes blinker { 50% {opacity:0;} }
566
- @keyframes spinner { to {transform:rotate(361deg);} }
566
+ @keyframes spinner { to {transform:rotate(361deg);} }
@@ -87,7 +87,7 @@ export default {
87
87
  /// focus temp
88
88
  const focusTemp = doc.createElement('INPUT');
89
89
  focusTemp.tabIndex = -1;
90
- focusTemp.style.cssText = 'position: absolute !important; top: -10000px !important; display: block !important; width: 0 !important; height: 0 !important; margin: 0 !important; padding: 0 !important;';
90
+ focusTemp.style.cssText = 'position: fixed !important; top: -10000px !important; display: block !important; width: 0 !important; height: 0 !important; margin: 0 !important; padding: 0 !important;';
91
91
 
92
92
  // toolbar container
93
93
  const toolbarContainer = options.toolbarContainer;
@@ -557,6 +557,7 @@ export default {
557
557
  options.videoRatio = (util.getNumber(options.videoRatio, 4) || 0.5625);
558
558
  options.videoRatioList = !options.videoRatioList ? null : options.videoRatioList;
559
559
  options.youtubeQuery = (options.youtubeQuery || '').replace('?', '');
560
+ options.vimeoQuery = (options.vimeoQuery || '').replace('?', '');
560
561
  options.videoFileInput = !!options.videoFileInput;
561
562
  options.videoUrlInput = (options.videoUrlInput === undefined || !options.videoFileInput) ? true : options.videoUrlInput;
562
563
  options.videoUploadHeader = options.videoUploadHeader || null;
package/src/lib/core.d.ts CHANGED
@@ -693,6 +693,7 @@ export default class SunEditor {
693
693
  onPaste: (e: Event, cleanData: string, maxCharCount: number, core: Core) => boolean | string;
694
694
  onCopy: (e: Event, clipboardData: any, core: Core) => boolean;
695
695
  onCut: (e: Event, clipboardData: any, core: Core) => boolean;
696
+ onPasteMath: (e: Event, core: Core) => void;
696
697
 
697
698
  /**
698
699
  * @description Called just after the save was executed.
package/src/lib/core.js CHANGED
@@ -1756,6 +1756,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
1756
1756
  return null;
1757
1757
  }
1758
1758
 
1759
+ let fNode = null;
1759
1760
  let range = this.getRange();
1760
1761
  let line = util.isListCell(range.commonAncestorContainer) ? range.commonAncestorContainer : util.getFormatElement(this.getSelectionNode(), null);
1761
1762
  let insertListCell = util.isListCell(line) && (util.isListCell(oNode) || util.isList(oNode));
@@ -1958,9 +1959,10 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
1958
1959
  }
1959
1960
 
1960
1961
  if (util.isWysiwygDiv(parentNode) && (oNode.nodeType === 3 || util.isBreak(oNode))) {
1961
- const fNode = util.createElement(options.defaultTag);
1962
- fNode.appendChild(oNode);
1963
- oNode = fNode;
1962
+ const fomatNode = util.createElement(options.defaultTag);
1963
+ fomatNode.appendChild(oNode);
1964
+ fNode = oNode;
1965
+ oNode = fomatNode;
1964
1966
  }
1965
1967
  }
1966
1968
 
@@ -2018,6 +2020,8 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
2018
2020
  parentNode.appendChild(oNode);
2019
2021
  console.warn('[SUNEDITOR.insertNode.warn] ' + error);
2020
2022
  } finally {
2023
+ if (fNode) oNode = fNode;
2024
+
2021
2025
  const dupleNodes = parentNode.querySelectorAll('[data-se-duple]');
2022
2026
  if (dupleNodes.length > 0) {
2023
2027
  for (let i = 0, len = dupleNodes.length, d, c, ch, parent; i < len; i++) {
@@ -2049,30 +2053,8 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
2049
2053
  if (!util.isComponent(oNode)) {
2050
2054
  let offset = 1;
2051
2055
  if (oNode.nodeType === 3) {
2052
- const previous = oNode.previousSibling;
2053
- const next = oNode.nextSibling;
2054
- const previousText = (!previous || previous.nodeType === 1 || util.onlyZeroWidthSpace(previous)) ? '' : previous.textContent;
2055
- const nextText = (!next || next.nodeType === 1 || util.onlyZeroWidthSpace(next)) ? '' : next.textContent;
2056
-
2057
- if (previous && previousText.length > 0) {
2058
- oNode.textContent = previousText + oNode.textContent;
2059
- util.removeItem(previous);
2060
- }
2061
-
2062
- if (next && next.length > 0) {
2063
- oNode.textContent += nextText;
2064
- util.removeItem(next);
2065
- }
2066
-
2067
- const newRange = {
2068
- container: oNode,
2069
- startOffset: previousText.length,
2070
- endOffset: oNode.textContent.length - nextText.length
2071
- };
2072
-
2073
- this.setRange(oNode, newRange.startOffset, oNode, newRange.endOffset);
2074
-
2075
- return newRange;
2056
+ offset = oNode.textContent.length;
2057
+ this.setRange(oNode, offset, oNode, offset);
2076
2058
  } else if (!util.isBreak(oNode) && !util.isListCell(oNode) && util.isFormatElement(parentNode)) {
2077
2059
  let zeroWidth = null;
2078
2060
  if (!oNode.previousSibling || util.isBreak(oNode.previousSibling)) {
@@ -2094,9 +2076,6 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
2094
2076
  this.setRange(oNode, offset, oNode, offset);
2095
2077
  }
2096
2078
 
2097
- // history stack
2098
- this.history.push(true);
2099
-
2100
2079
  return oNode;
2101
2080
  }
2102
2081
  },
@@ -5320,7 +5299,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
5320
5299
  r = style[i].match(/([a-zA-Z0-9-]+)(:)([^"']+)/);
5321
5300
  if (r && !/inherit|initial|revert|unset/i.test(r[3])) {
5322
5301
  const k = util.kebabToCamelCase(r[1].trim());
5323
- const v = this.wwComputedStyle[k].replace(/"/g, '');
5302
+ const v = this.wwComputedStyle[k] ? this.wwComputedStyle[k].replace(/"/g, '') : '';
5324
5303
  const c = r[3].trim();
5325
5304
  switch (k) {
5326
5305
  case 'fontFamily':
@@ -5943,7 +5922,9 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
5943
5922
  // set whitelist
5944
5923
  const getRegList = function (str, str2) { return !str ? '^' : (str === '*' ? '[a-z-]+' : (!str2 ? str : (str + '|' + str2))); };
5945
5924
  // tags
5946
- const defaultAttr = 'contenteditable|colspan|rowspan|target|href|download|rel|src|alt|class|type|controls|origin-size';
5925
+ const videoAttr = '|controls|autoplay|loop|muted|poster|preload|playsinline';
5926
+ const iframeAttr = '|allowfullscreen|sandbox|loading|allow|referrerpolicy|frameborder|scrolling';
5927
+ const defaultAttr = 'contenteditable|colspan|rowspan|target|href|download|rel|src|alt|class|type|origin-size' + videoAttr + iframeAttr;
5947
5928
  const dataAttr = 'data-format|data-size|data-file-size|data-file-name|data-origin|data-align|data-image-link|data-rotate|data-proportion|data-percentage|data-exp|data-font-size';
5948
5929
  this._allowHTMLComments = options._editorTagsWhitelist.indexOf('//') > -1 || options._editorTagsWhitelist === '*';
5949
5930
  // html check
@@ -6445,6 +6426,10 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
6445
6426
  },
6446
6427
 
6447
6428
  _applyTagEffects: function () {
6429
+ if (util.hasClass(context.element.wysiwyg, 'se-read-only')) {
6430
+ return false;
6431
+ }
6432
+
6448
6433
  let selectionNode = core.getSelectionNode();
6449
6434
  if (selectionNode === core.effectNode) return;
6450
6435
  core.effectNode = selectionNode;
@@ -6626,6 +6611,11 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
6626
6611
  },
6627
6612
 
6628
6613
  onClick_wysiwyg: function (e) {
6614
+ // if (util.hasClass(context.element.wysiwyg, 'se-read-only')) {
6615
+ // e.preventDefault();
6616
+ // return false;
6617
+ // }
6618
+
6629
6619
  const targetElement = e.target;
6630
6620
 
6631
6621
  if (core.isReadOnly) {
@@ -25,6 +25,11 @@ export default {
25
25
  context.math.focusElement = math_dialog.querySelector('.se-math-exp');
26
26
  context.math.previewElement = math_dialog.querySelector('.se-math-preview');
27
27
  context.math.fontSizeElement = math_dialog.querySelector('.se-math-size');
28
+ context.math.focusElement.addEventListener('paste', function (e) {
29
+ if (typeof core.functions.onPasteMath === 'function') {
30
+ core.functions.onPasteMath(e, core);
31
+ }
32
+ }, false);
28
33
  context.math.focusElement.addEventListener(core.util.isIE ? 'textinput' : 'input', this._renderMathExp.bind(core, context.math), false);
29
34
  context.math.fontSizeElement.addEventListener('change', function (e) { this.fontSize = e.target.value; }.bind(context.math.previewElement.style), false);
30
35
 
@@ -29,6 +29,7 @@ export default {
29
29
  _align: 'none',
30
30
  _floatClassRegExp: '__se__float\\-[a-z]+',
31
31
  _youtubeQuery: options.youtubeQuery,
32
+ _vimeoQuery: options.vimeoQuery,
32
33
  _videoRatio: (options.videoRatio * 100) + '%',
33
34
  _defaultRatio: (options.videoRatio * 100) + '%',
34
35
  _linkValue: '',
@@ -540,6 +541,15 @@ export default {
540
541
  url = url.slice(0, -1);
541
542
  }
542
543
  url = 'https://player.vimeo.com/video/' + url.slice(url.lastIndexOf('/') + 1);
544
+
545
+ if (contextVideo._vimeoQuery.length > 0) {
546
+ if (/\?/.test(url)) {
547
+ const splitUrl = url.split('?');
548
+ url = splitUrl[0] + '?' + contextVideo._vimeoQuery + '&' + splitUrl[1];
549
+ } else {
550
+ url += '?' + contextVideo._vimeoQuery;
551
+ }
552
+ }
543
553
  }
544
554
 
545
555
  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);