suneditor 2.44.0 → 2.44.2

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.44.0",
3
+ "version": "2.44.2",
4
4
  "description": "Pure JavaScript based WYSIWYG web editor",
5
5
  "author": "JiHong.Lee",
6
6
  "license": "MIT",
package/src/lib/core.js CHANGED
@@ -474,8 +474,8 @@ 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*[^-a-zA-Z](font-family|font-size|color|background-color)\\s*:[^;]+(?!;)*', 'ig'),
478
+ format: new _w.RegExp('\\s*[^-a-zA-Z](text-align|margin-left|margin-right)\\s*:[^;]+(?!;)*', 'ig'),
479
479
  fontSizeUnit: new _w.RegExp('\\d+' + options.fontSizeUnit + '$', 'i'),
480
480
  },
481
481
 
@@ -1671,6 +1671,51 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
1671
1671
  }
1672
1672
  },
1673
1673
 
1674
+ _checkDuplicateNode: function (oNode, parentNode) {
1675
+ (function recursionFunc(current) {
1676
+ core._dupleCheck(current, parentNode);
1677
+ const childNodes = current.childNodes;
1678
+ for (let i = 0, len = childNodes.length; i < len; i++) {
1679
+ recursionFunc(childNodes[i]);
1680
+ }
1681
+ })(oNode);
1682
+ },
1683
+
1684
+ _dupleCheck: function (oNode, parentNode) {
1685
+ if (!util.isTextStyleElement(oNode)) return;
1686
+
1687
+ const oStyles = (oNode.style.cssText.match(/[^;]+;/g) || []).map(function(v){ return v.trim(); });
1688
+ const nodeName = oNode.nodeName;
1689
+ if (/^span$/i.test(nodeName) && oStyles.length === 0) return oNode;
1690
+
1691
+ let duple = false;
1692
+ (function recursionFunc(ancestor) {
1693
+ if (util.isWysiwygDiv(ancestor) || !util.isTextStyleElement(ancestor)) return;
1694
+
1695
+ if (ancestor.nodeName === nodeName) {
1696
+ duple = true;
1697
+ (ancestor.style.cssText.match(/[^;]+;/g) || []).forEach(function(v){
1698
+ let i;
1699
+ if ((i = oStyles.indexOf(v.trim())) > -1) {
1700
+ oStyles.splice(i, 1);
1701
+ }
1702
+ });
1703
+ ancestor.classList.forEach(function(v){
1704
+ oNode.classList.remove(v);
1705
+ });
1706
+ }
1707
+
1708
+ recursionFunc(ancestor.parentElement);
1709
+ })(parentNode);
1710
+
1711
+ if (duple) {
1712
+ if (!(oNode.style.cssText = oStyles.join(' '))) oNode.removeAttribute('style');
1713
+ if (!oNode.attributes.length) oNode.setAttribute('data-se-duple', 'true');
1714
+ }
1715
+
1716
+ return oNode;
1717
+ },
1718
+
1674
1719
  /**
1675
1720
  * @description Delete selected node and insert argument value node and return.
1676
1721
  * If the "afterNode" exists, it is inserted after the "afterNode"
@@ -1916,6 +1961,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
1916
1961
  insertListCell = true;
1917
1962
  }
1918
1963
 
1964
+ this._checkDuplicateNode(oNode, parentNode);
1919
1965
  parentNode.insertBefore(oNode, afterNode);
1920
1966
 
1921
1967
  if (insertListCell) {
@@ -1939,9 +1985,27 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
1939
1985
  }
1940
1986
  }
1941
1987
  }
1942
- } catch (e) {
1988
+ } catch (error) {
1943
1989
  parentNode.appendChild(oNode);
1990
+ console.warn('[SUNEDITOR.insertNode.warn] ' + error);
1944
1991
  } finally {
1992
+ const dupleNodes = parentNode.querySelectorAll('[data-se-duple]');
1993
+ if (dupleNodes.length > 0) {
1994
+ for (let i = 0, len = dupleNodes.length, d, c, ch, parent; i < len; i++) {
1995
+ d = dupleNodes[i];
1996
+ ch = d.childNodes;
1997
+ parent = d.parentNode;
1998
+
1999
+ while (ch[0]) {
2000
+ c = ch[0];
2001
+ parent.insertBefore(c, d);
2002
+ }
2003
+
2004
+ if (d === oNode) oNode = c;
2005
+ util.removeItem(d);
2006
+ }
2007
+ }
2008
+
1945
2009
  if ((util.isFormatElement(oNode) || util.isComponent(oNode)) && startCon === endCon) {
1946
2010
  const cItem = util.getFormatElement(commonCon, null);
1947
2011
  if (cItem && cItem.nodeType === 1 && util.isEmptyLine(cItem)) {
@@ -5132,7 +5196,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
5132
5196
  case '%':
5133
5197
  return (pxSize * 0.0625).toFixed(2) + to;
5134
5198
  case 'pt':
5135
- return this._w.Math.floor(pxSize / 1.333) + to;
5199
+ return this.floor(pxSize / 1.333) + to;
5136
5200
  default: // px
5137
5201
  return pxSize + to;
5138
5202
  }
@@ -5146,7 +5210,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
5146
5210
  if (style) {
5147
5211
  const allowedStyle = [];
5148
5212
  for (let i = 0, len = style.length, r; i < len; i++) {
5149
- r = style[i].match(/(.+)(:)([^:]+$)/);
5213
+ r = style[i].match(/([a-zA-Z0-9-]+)(:)([^:]+$)/);
5150
5214
  if (r && !/inherit|initial/i.test(r[3])) {
5151
5215
  const k = util.kebabToCamelCase(r[1].trim());
5152
5216
  const v = this.wwComputedStyle[k].replace(/"/g, '');
@@ -7819,7 +7883,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
7819
7883
  const onlyText = !cleanData;
7820
7884
 
7821
7885
  if (!onlyText) {
7822
- cleanData = cleanData.replace(/^<html>\r\n<body>\r\n\x3C!--StartFragment--\>|\x3C!--EndFragment-->\r\n<\/body\>\r\n<\/html>$/g, '');
7886
+ cleanData = cleanData.replace(/^<html>\r?\n?<body>\r?\n?\x3C!--StartFragment--\>|\x3C!--EndFragment-->\r?\n?<\/body\>\r?\n?<\/html>$/g, '');
7823
7887
  if (MSData) {
7824
7888
  cleanData = cleanData.replace(/\n/g, ' ');
7825
7889
  plainText = plainText.replace(/\n/g, ' ');