suneditor 2.43.5 → 2.43.8

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/src/lib/core.js CHANGED
@@ -41,6 +41,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
41
41
  _parser: new _w.DOMParser(),
42
42
  _prevRtl: options.rtl,
43
43
  _editorHeight: 0,
44
+ _editorHeightPadding: 0,
44
45
  _listCamel: options.__listCommonStyle,
45
46
  _listKebab: util.camelToKebabCase(options.__listCommonStyle),
46
47
 
@@ -459,13 +460,6 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
459
460
  DEL: ['text-decoration']
460
461
  },
461
462
 
462
- /**
463
- * @description Contains pairs of all "data-commands" and "elements" setted in toolbar over time
464
- * Used primarily to save and recover button states after the toolbar re-creation
465
- * Updates each "_cachingButtons()" invocation
466
- */
467
- allCommandButtons: null,
468
-
469
463
  /**
470
464
  * @description Style button related to edit area
471
465
  * @property {Element} fullScreen fullScreen button element
@@ -510,6 +504,42 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
510
504
  _lineBreakDir: ''
511
505
  },
512
506
 
507
+ /**
508
+ * @description Save the current buttons states to "allCommandButtons" object
509
+ * @private
510
+ */
511
+ _saveButtonStates: function () {
512
+ if (!this.allCommandButtons) this.allCommandButtons = {};
513
+
514
+ const currentButtons = this.context.element._buttonTray.querySelectorAll('.se-menu-list button[data-display]');
515
+ for (let i = 0, element, command; i < currentButtons.length; i++) {
516
+ element = currentButtons[i];
517
+ command = element.getAttribute('data-command');
518
+
519
+ this.allCommandButtons[command] = element;
520
+ }
521
+ },
522
+
523
+ /**
524
+ * @description Recover the current buttons states from "allCommandButtons" object
525
+ * @private
526
+ */
527
+ _recoverButtonStates: function () {
528
+ if (this.allCommandButtons) {
529
+ const currentButtons = this.context.element._buttonTray.querySelectorAll('.se-menu-list button[data-display]');
530
+ for (let i = 0, button, command, oldButton; i < currentButtons.length; i++) {
531
+ button = currentButtons[i];
532
+ command = button.getAttribute('data-command');
533
+
534
+ oldButton = this.allCommandButtons[command];
535
+ if (oldButton) {
536
+ button.parentElement.replaceChild(oldButton, button);
537
+ if (this.context.tool[command]) this.context.tool[command] = oldButton;
538
+ }
539
+ }
540
+ }
541
+ },
542
+
513
543
  /**
514
544
  * @description If the plugin is not added, add the plugin and call the 'add' function.
515
545
  * If the plugin is added call callBack function.
@@ -1471,7 +1501,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
1471
1501
 
1472
1502
  const currentFormatEl = util.getFormatElement(this.getSelectionNode(), null);
1473
1503
  let oFormat = null;
1474
- if (util.isFreeFormatElement(currentFormatEl || element.parentNode)) {
1504
+ if (!util.isFormatElement(element) && util.isFreeFormatElement(currentFormatEl || element.parentNode)) {
1475
1505
  oFormat = util.createElement('BR');
1476
1506
  } else {
1477
1507
  const oFormatName = formatNode ? (typeof formatNode === 'string' ? formatNode : formatNode.nodeName) : (util.isFormatElement(currentFormatEl) && !util.isRangeFormatElement(currentFormatEl) && !util.isFreeFormatElement(currentFormatEl)) ? currentFormatEl.nodeName : options.defaultTag;
@@ -1645,165 +1675,261 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
1645
1675
  return null;
1646
1676
  }
1647
1677
 
1648
- const line = util.getFormatElement(this.getSelectionNode(), null);
1649
- const listCell = util.isListCell(line);
1678
+ let range = this.getRange();
1679
+ let line = util.isListCell(range.commonAncestorContainer) ? range.commonAncestorContainer : util.getFormatElement(this.getSelectionNode(), null);
1680
+ let insertListCell = util.isListCell(line) && (util.isListCell(oNode) || util.isList(oNode));
1681
+
1682
+ let parentNode, originAfter, tempAfterNode, tempParentNode = null;
1650
1683
  const freeFormat = util.isFreeFormatElement(line);
1651
1684
  const isFormats = (!freeFormat && (util.isFormatElement(oNode) || util.isRangeFormatElement(oNode))) || util.isComponent(oNode);
1652
1685
 
1686
+ if (insertListCell) {
1687
+ tempAfterNode = afterNode || util.isList(oNode) ? line.lastChild : line.nextElementSibling;
1688
+ tempParentNode = util.isList(oNode) ? line : (tempAfterNode || line).parentNode;
1689
+ }
1690
+
1653
1691
  if (!afterNode && (isFormats || util.isComponent(oNode) || util.isMedia(oNode))) {
1692
+ const isEdge = this.isEdgePoint(range.endContainer, range.endOffset, 'end');
1654
1693
  const r = this.removeNode();
1655
- if (r.container.nodeType === 3 || util.isBreak(r.container)) {
1656
- const depthFormat = util.getParentElement(r.container, function (current) { return this.isRangeFormatElement(current) || this.isListCell(current); }.bind(util));
1657
- afterNode = util.splitElement(r.container, r.offset, !depthFormat ? 0 : util.getElementDepth(depthFormat) + 1);
1658
- if (afterNode) afterNode = afterNode.previousSibling;
1694
+ const container = r.container;
1695
+ const prevContainer = (container === r.prevContainer && range.collapsed) ? null : r.prevContainer;
1696
+
1697
+ if (insertListCell && prevContainer) {
1698
+ tempParentNode = prevContainer.nodeType === 3 ? prevContainer.parentNode : prevContainer;
1699
+ if (tempParentNode.contains(container)) {
1700
+ let sameParent = true;
1701
+ tempAfterNode = container;
1702
+ while (tempAfterNode.parentNode && tempAfterNode.parentNode !== tempParentNode) {
1703
+ tempAfterNode = tempAfterNode.parentNode;
1704
+ sameParent = false;
1705
+ }
1706
+ if (sameParent && container === prevContainer) tempAfterNode = tempAfterNode.nextSibling;
1707
+ } else {
1708
+ tempAfterNode = null;
1709
+ }
1710
+ } else if (insertListCell && util.isListCell(container) && !line.parentElement) {
1711
+ line = util.createElement('LI');
1712
+ tempParentNode.appendChild(line);
1713
+ container.appendChild(tempParentNode);
1714
+ tempAfterNode = null;
1715
+ } else if (container.nodeType === 3 || util.isBreak(container) || insertListCell) {
1716
+ const depthFormat = util.getParentElement(container, function (current) { return this.isRangeFormatElement(current) || this.isListCell(current); }.bind(util));
1717
+ afterNode = util.splitElement(container, r.offset, !depthFormat ? 0 : util.getElementDepth(depthFormat) + 1);
1718
+ if (afterNode) {
1719
+ if (insertListCell) {
1720
+ if (line.contains(container)) {
1721
+ const subList = util.isList(line.lastElementChild);
1722
+ let newCell = null;
1723
+ if (!isEdge) {
1724
+ newCell = line.cloneNode(false);
1725
+ newCell.appendChild(afterNode.textContent.trim() ? afterNode : util.createTextNode(util.zeroWidthSpace));
1726
+ }
1727
+ if (subList) {
1728
+ if (!newCell) {
1729
+ newCell = line.cloneNode(false);
1730
+ newCell.appendChild(util.createTextNode(util.zeroWidthSpace));
1731
+ }
1732
+ newCell.appendChild(line.lastElementChild);
1733
+ }
1734
+ if (newCell) {
1735
+ line.parentNode.insertBefore(newCell, line.nextElementSibling);
1736
+ tempAfterNode = afterNode = newCell;
1737
+ }
1738
+ }
1739
+ } else {
1740
+ afterNode = afterNode.previousSibling;
1741
+ }
1742
+ }
1659
1743
  }
1660
1744
  }
1661
1745
 
1662
- const range = (!afterNode && !isFormats) ? this.getRange_addLine(this.getRange(), null) : this.getRange();
1746
+ range = (!afterNode && !isFormats) ? this.getRange_addLine(this.getRange(), null) : this.getRange();
1663
1747
  const commonCon = range.commonAncestorContainer;
1664
1748
  const startOff = range.startOffset;
1665
1749
  const endOff = range.endOffset;
1666
1750
  const formatRange = range.startContainer === commonCon && util.isFormatElement(commonCon);
1667
1751
  const startCon = formatRange ? (commonCon.childNodes[startOff] || commonCon.childNodes[0] || range.startContainer) : range.startContainer;
1668
1752
  const endCon = formatRange ? (commonCon.childNodes[endOff] || commonCon.childNodes[commonCon.childNodes.length - 1] || range.endContainer) : range.endContainer;
1669
- let parentNode, originAfter = null;
1670
1753
 
1671
- if (!afterNode) {
1672
- parentNode = startCon;
1673
- if (startCon.nodeType === 3) {
1674
- parentNode = startCon.parentNode;
1675
- }
1676
-
1677
- /** No Select range node */
1678
- if (range.collapsed) {
1679
- if (commonCon.nodeType === 3) {
1680
- if (commonCon.textContent.length > endOff) afterNode = commonCon.splitText(endOff);
1681
- else afterNode = commonCon.nextSibling;
1682
- } else {
1683
- if (!util.isBreak(parentNode)) {
1684
- let c = parentNode.childNodes[startOff];
1685
- const focusNode = (c && c.nodeType === 3 && util.onlyZeroWidthSpace(c) && util.isBreak(c.nextSibling)) ? c.nextSibling : c;
1686
- if (focusNode) {
1687
- if (!focusNode.nextSibling) {
1688
- parentNode.removeChild(focusNode);
1689
- afterNode = null;
1754
+ if (!insertListCell) {
1755
+ if (!afterNode) {
1756
+ parentNode = startCon;
1757
+ if (startCon.nodeType === 3) {
1758
+ parentNode = startCon.parentNode;
1759
+ }
1760
+
1761
+ /** No Select range node */
1762
+ if (range.collapsed) {
1763
+ if (commonCon.nodeType === 3) {
1764
+ if (commonCon.textContent.length > endOff) afterNode = commonCon.splitText(endOff);
1765
+ else afterNode = commonCon.nextSibling;
1766
+ } else {
1767
+ if (!util.isBreak(parentNode)) {
1768
+ let c = parentNode.childNodes[startOff];
1769
+ const focusNode = (c && c.nodeType === 3 && util.onlyZeroWidthSpace(c) && util.isBreak(c.nextSibling)) ? c.nextSibling : c;
1770
+ if (focusNode) {
1771
+ if (!focusNode.nextSibling) {
1772
+ parentNode.removeChild(focusNode);
1773
+ afterNode = null;
1774
+ } else {
1775
+ afterNode = (util.isBreak(focusNode) && !util.isBreak(oNode)) ? focusNode : focusNode.nextSibling;
1776
+ }
1690
1777
  } else {
1691
- afterNode = (util.isBreak(focusNode) && !util.isBreak(oNode)) ? focusNode : focusNode.nextSibling;
1778
+ afterNode = null;
1692
1779
  }
1693
1780
  } else {
1694
- afterNode = null;
1781
+ afterNode = parentNode;
1782
+ parentNode = parentNode.parentNode;
1695
1783
  }
1696
- } else {
1697
- afterNode = parentNode;
1698
- parentNode = parentNode.parentNode;
1699
1784
  }
1700
- }
1701
- } else { /** Select range nodes */
1702
- const isSameContainer = startCon === endCon;
1703
-
1704
- if (isSameContainer) {
1705
- if (this.isEdgePoint(endCon, endOff)) afterNode = endCon.nextSibling;
1706
- else afterNode = endCon.splitText(endOff);
1707
-
1708
- let removeNode = startCon;
1709
- if (!this.isEdgePoint(startCon, startOff)) removeNode = startCon.splitText(startOff);
1710
-
1711
- parentNode.removeChild(removeNode);
1712
- if (parentNode.childNodes.length === 0 && isFormats) {
1713
- parentNode.innerHTML = '<br>';
1714
- }
1715
- }
1716
- else {
1717
- const removedTag = this.removeNode();
1718
- const container = removedTag.container;
1719
- const prevContainer = removedTag.prevContainer;
1720
- if (container && container.childNodes.length === 0 && isFormats) {
1721
- if (util.isFormatElement(container)) {
1722
- container.innerHTML = '<br>';
1723
- } else if (util.isRangeFormatElement(container)) {
1724
- container.innerHTML = '<' + options.defaultTag + '><br></' + options.defaultTag + '>';
1785
+ } else { /** Select range nodes */
1786
+ const isSameContainer = startCon === endCon;
1787
+
1788
+ if (isSameContainer) {
1789
+ if (this.isEdgePoint(endCon, endOff)) afterNode = endCon.nextSibling;
1790
+ else afterNode = endCon.splitText(endOff);
1791
+
1792
+ let removeNode = startCon;
1793
+ if (!this.isEdgePoint(startCon, startOff)) removeNode = startCon.splitText(startOff);
1794
+
1795
+ parentNode.removeChild(removeNode);
1796
+ if (parentNode.childNodes.length === 0 && isFormats) {
1797
+ parentNode.innerHTML = '<br>';
1725
1798
  }
1726
1799
  }
1727
-
1728
- if (!isFormats && prevContainer) {
1729
- parentNode = prevContainer.nodeType === 3 ? prevContainer.parentNode : prevContainer;
1730
- if (parentNode.contains(container)) {
1731
- let sameParent = true;
1732
- afterNode = container;
1733
- while (afterNode.parentNode !== parentNode) {
1734
- afterNode = afterNode.parentNode;
1735
- sameParent = false;
1800
+ else {
1801
+ const removedTag = this.removeNode();
1802
+ const container = removedTag.container;
1803
+ const prevContainer = removedTag.prevContainer;
1804
+
1805
+ if (container && container.childNodes.length === 0 && isFormats) {
1806
+ if (util.isFormatElement(container)) {
1807
+ container.innerHTML = '<br>';
1808
+ } else if (util.isRangeFormatElement(container)) {
1809
+ container.innerHTML = '<' + options.defaultTag + '><br></' + options.defaultTag + '>';
1736
1810
  }
1737
- if (sameParent && container === prevContainer) afterNode = afterNode.nextSibling;
1738
- } else {
1811
+ }
1812
+
1813
+ if (util.isListCell(container) && oNode.nodeType === 3) {
1814
+ parentNode = container;
1739
1815
  afterNode = null;
1816
+ } else if (!isFormats && prevContainer) {
1817
+ parentNode = prevContainer.nodeType === 3 ? prevContainer.parentNode : prevContainer;
1818
+ if (parentNode.contains(container)) {
1819
+ let sameParent = true;
1820
+ afterNode = container;
1821
+ while (afterNode.parentNode && afterNode.parentNode !== parentNode) {
1822
+ afterNode = afterNode.parentNode;
1823
+ sameParent = false;
1824
+ }
1825
+ if (sameParent && container === prevContainer) afterNode = afterNode.nextSibling;
1826
+ } else {
1827
+ afterNode = null;
1828
+ }
1829
+ } else {
1830
+ afterNode = isFormats ? endCon : container === prevContainer ? container.nextSibling : container;
1831
+ parentNode = (!afterNode || !afterNode.parentNode) ? commonCon : afterNode.parentNode;
1832
+ }
1833
+
1834
+ while (afterNode && !util.isFormatElement(afterNode) && afterNode.parentNode !== commonCon) {
1835
+ afterNode = afterNode.parentNode;
1740
1836
  }
1741
- } else {
1742
- afterNode = isFormats ? endCon : container === prevContainer ? container.nextSibling : container;
1743
- parentNode = (!afterNode || !afterNode.parentNode) ? commonCon : afterNode.parentNode;
1744
- }
1745
-
1746
- while (afterNode && !util.isFormatElement(afterNode) && afterNode.parentNode !== commonCon) {
1747
- afterNode = afterNode.parentNode;
1748
1837
  }
1749
1838
  }
1839
+ } else { // has afterNode
1840
+ parentNode = afterNode.parentNode;
1841
+ afterNode = afterNode.nextSibling;
1842
+ originAfter = true;
1750
1843
  }
1751
1844
  }
1752
- // has afterNode
1753
- else {
1754
- parentNode = afterNode.parentNode;
1755
- afterNode = afterNode.nextSibling;
1756
- originAfter = true;
1757
- }
1758
1845
 
1759
- // --- insert node ---
1760
1846
  try {
1761
- if (util.isWysiwygDiv(afterNode) || parentNode === context.element.wysiwyg.parentNode) {
1762
- parentNode = context.element.wysiwyg;
1763
- afterNode = null;
1764
- }
1765
-
1766
- if (util.isFormatElement(oNode) || util.isRangeFormatElement(oNode) || (!util.isListCell(parentNode) && util.isComponent(oNode))) {
1767
- const oldParent = parentNode;
1768
- if (util.isList(afterNode)) {
1769
- parentNode = afterNode;
1847
+ // set node
1848
+ if (!insertListCell) {
1849
+ if (util.isWysiwygDiv(afterNode) || parentNode === context.element.wysiwyg.parentNode) {
1850
+ parentNode = context.element.wysiwyg;
1770
1851
  afterNode = null;
1771
- } else if (util.isListCell(afterNode)) {
1772
- parentNode = afterNode.previousElementSibling || afterNode;
1773
- } else if (!originAfter && !afterNode) {
1774
- const r = this.removeNode();
1775
- const container = r.container.nodeType === 3 ? (util.isListCell(util.getFormatElement(r.container, null)) ? r.container : (util.getFormatElement(r.container, null) || r.container.parentNode)) : r.container;
1776
- const rangeCon = util.isWysiwygDiv(container) || util.isRangeFormatElement(container);
1777
- parentNode = rangeCon ? container : container.parentNode;
1778
- afterNode = rangeCon ? null : container.nextSibling;
1779
1852
  }
1780
-
1781
- if (oldParent.childNodes.length === 0 && parentNode !== oldParent) util.removeItem(oldParent);
1782
- }
1783
-
1784
- if (isFormats && !freeFormat && !util.isRangeFormatElement(parentNode) && !util.isListCell(parentNode) && !util.isWysiwygDiv(parentNode)) {
1785
- afterNode = parentNode.nextElementSibling;
1786
- parentNode = parentNode.parentNode;
1787
- }
1788
-
1789
- if (util.isWysiwygDiv(parentNode) && (oNode.nodeType === 3 || util.isBreak(oNode))) {
1790
- const fNode = util.createElement(options.defaultTag);
1791
- fNode.appendChild(oNode);
1792
- oNode = fNode;
1853
+
1854
+ if (util.isFormatElement(oNode) || util.isRangeFormatElement(oNode) || (!util.isListCell(parentNode) && util.isComponent(oNode))) {
1855
+ const oldParent = parentNode;
1856
+ if (util.isList(afterNode)) {
1857
+ parentNode = afterNode;
1858
+ afterNode = null;
1859
+ } else if (util.isListCell(afterNode)) {
1860
+ parentNode = afterNode.previousElementSibling || afterNode;
1861
+ } else if (!originAfter && !afterNode) {
1862
+ const r = this.removeNode();
1863
+ const container = r.container.nodeType === 3 ? (util.isListCell(util.getFormatElement(r.container, null)) ? r.container : (util.getFormatElement(r.container, null) || r.container.parentNode)) : r.container;
1864
+ const rangeCon = util.isWysiwygDiv(container) || util.isRangeFormatElement(container);
1865
+ parentNode = rangeCon ? container : container.parentNode;
1866
+ afterNode = rangeCon ? null : container.nextSibling;
1867
+ }
1868
+
1869
+ if (oldParent.childNodes.length === 0 && parentNode !== oldParent) util.removeItem(oldParent);
1870
+ }
1871
+
1872
+ if (isFormats && !freeFormat && !util.isRangeFormatElement(parentNode) && !util.isListCell(parentNode) && !util.isWysiwygDiv(parentNode)) {
1873
+ afterNode = parentNode.nextElementSibling;
1874
+ parentNode = parentNode.parentNode;
1875
+ }
1876
+
1877
+ if (util.isWysiwygDiv(parentNode) && (oNode.nodeType === 3 || util.isBreak(oNode))) {
1878
+ const fNode = util.createElement(options.defaultTag);
1879
+ fNode.appendChild(oNode);
1880
+ oNode = fNode;
1881
+ }
1793
1882
  }
1794
1883
 
1795
1884
  // 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);
1885
+ if (insertListCell) {
1886
+ if (!tempParentNode.parentNode) {
1887
+ parentNode = context.element.wysiwyg;
1888
+ afterNode = null;
1889
+ } else {
1890
+ parentNode = tempParentNode;
1891
+ afterNode = tempAfterNode;
1892
+ }
1801
1893
  } else {
1802
1894
  afterNode = parentNode === afterNode ? parentNode.lastChild : afterNode;
1803
1895
  }
1804
1896
 
1897
+ if (util.isListCell(oNode) && !util.isList(parentNode)) {
1898
+ if (util.isListCell(parentNode)) {
1899
+ afterNode = parentNode.nextElementSibling;
1900
+ parentNode = parentNode.parentNode;
1901
+ } else {
1902
+ const ul = util.createElement('ol');
1903
+ parentNode.insertBefore(ul, afterNode);
1904
+ parentNode = ul;
1905
+ afterNode = null;
1906
+ }
1907
+ insertListCell = true;
1908
+ }
1909
+
1805
1910
  parentNode.insertBefore(oNode, afterNode);
1806
- if (emptyListCell) util.removeItem(line);
1911
+
1912
+ if (insertListCell) {
1913
+ if (util.onlyZeroWidthSpace(line.textContent.trim())) {
1914
+ util.removeItem(line);
1915
+ oNode = oNode.lastChild;
1916
+ } else {
1917
+ const chList = util.getArrayItem(line.children, util.isList);
1918
+ if (chList) {
1919
+ if (oNode !== chList) {
1920
+ oNode.appendChild(chList);
1921
+ oNode = chList.previousSibling;
1922
+ } else {
1923
+ parentNode.appendChild(oNode);
1924
+ oNode = parentNode;
1925
+ }
1926
+
1927
+ if (util.onlyZeroWidthSpace(line.textContent.trim())) {
1928
+ util.removeItem(line);
1929
+ }
1930
+ }
1931
+ }
1932
+ }
1807
1933
  } catch (e) {
1808
1934
  parentNode.appendChild(oNode);
1809
1935
  } finally {
@@ -1972,28 +2098,11 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
1972
2098
  startIndex = endIndex = 0;
1973
2099
  }
1974
2100
 
1975
- function remove (item) {
1976
- const format = util.getFormatElement(item, null);
1977
- util.removeItem(item);
1978
-
1979
- if(util.isListCell(format)) {
1980
- const list = util.getArrayItem(format.children, util.isList, false);
1981
- if (list) {
1982
- const child = list.firstElementChild;
1983
- const children = child.childNodes;
1984
- while (children[0]) {
1985
- format.insertBefore(children[0], list);
1986
- }
1987
- util.removeItemAllParents(child, null, null);
1988
- }
1989
- }
1990
- }
1991
-
1992
2101
  for (let i = startIndex; i <= endIndex; i++) {
1993
2102
  const item = childNodes[i];
1994
2103
 
1995
2104
  if (item.length === 0 || (item.nodeType === 3 && item.data === undefined)) {
1996
- remove(item);
2105
+ this._nodeRemoveListItem(item);
1997
2106
  continue;
1998
2107
  }
1999
2108
 
@@ -2013,7 +2122,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
2013
2122
  if (beforeNode.length > 0) {
2014
2123
  startCon.data = beforeNode.data;
2015
2124
  } else {
2016
- remove(startCon);
2125
+ this._nodeRemoveListItem(startCon);
2017
2126
  }
2018
2127
 
2019
2128
  if (item === endCon) break;
@@ -2031,24 +2140,26 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
2031
2140
  if (afterNode.length > 0) {
2032
2141
  endCon.data = afterNode.data;
2033
2142
  } else {
2034
- remove(endCon);
2143
+ this._nodeRemoveListItem(endCon);
2035
2144
  }
2036
2145
 
2037
2146
  continue;
2038
2147
  }
2039
2148
 
2040
- remove(item);
2149
+ this._nodeRemoveListItem(item);
2041
2150
  }
2042
2151
 
2043
- container = endCon && endCon.parentNode ? endCon : startCon && startCon.parentNode ? startCon : (range.endContainer || range.startContainer);
2152
+ const endUl = util.getParentElement(endCon, 'ul');
2153
+ const startLi = util.getParentElement(startCon, 'li');
2154
+ if (endUl && startLi && startLi.contains(endUl)) {
2155
+ container = endUl.previousSibling;
2156
+ offset = container.textContent.length;
2157
+ } else {
2158
+ container = endCon && endCon.parentNode ? endCon : startCon && startCon.parentNode ? startCon : (range.endContainer || range.startContainer);
2159
+ }
2044
2160
 
2045
2161
  if (!util.isWysiwygDiv(container) && container.childNodes.length === 0) {
2046
- const rc = util.removeItemAllParents(container, function (current) {
2047
- if (this.isComponent(current)) return false;
2048
- const text = current.textContent;
2049
- return text.length === 0 || /^(\n|\u200B)+$/.test(text);
2050
- }.bind(util), null);
2051
-
2162
+ const rc = util.removeItemAllParents(container, null, null);
2052
2163
  if (rc) container = rc.sc || rc.ec || context.element.wysiwyg;
2053
2164
  }
2054
2165
 
@@ -2064,6 +2175,19 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
2064
2175
  };
2065
2176
  },
2066
2177
 
2178
+ _nodeRemoveListItem: function (item) {
2179
+ const format = util.getFormatElement(item, null);
2180
+ util.removeItem(item);
2181
+
2182
+ if(!util.isListCell(format)) return;
2183
+
2184
+ util.removeItemAllParents(format, null, null);
2185
+
2186
+ if (format && util.isList(format.firstChild)) {
2187
+ format.insertBefore(util.createTextNode(util.zeroWidthSpace), format.firstChild);
2188
+ }
2189
+ },
2190
+
2067
2191
  /**
2068
2192
  * @description Appended all selected format Element to the argument element and insert
2069
2193
  * @param {Element} rangeElement Element of wrap the arguments (BLOCKQUOTE...)
@@ -4908,10 +5032,16 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
4908
5032
  // element
4909
5033
  if (node.nodeType === 1) {
4910
5034
  if (util._disallowedTags(node)) return '';
5035
+
5036
+ const ch = util.getListChildNodes(node, function(current) { return util.isSpanWithoutAttr(current); }) || [];
5037
+ for (let i = ch.length - 1; i >= 0; i--) {
5038
+ ch[i].outerHTML = ch[i].innerHTML;
5039
+ }
5040
+
4911
5041
  if (!requireFormat || (util.isFormatElement(node) || util.isRangeFormatElement(node) || util.isComponent(node) || util.isMedia(node) || (util.isAnchor(node) && util.isMedia(node.firstElementChild)))) {
4912
- return node.outerHTML;
5042
+ return util.isSpanWithoutAttr(node) ? node.innerHTML : node.outerHTML;
4913
5043
  } else {
4914
- return '<' + defaultTag + '>' + node.outerHTML + '</' + defaultTag + '>';
5044
+ return '<' + defaultTag + '>' + (util.isSpanWithoutAttr(node) ? node.innerHTML : node.outerHTML) + '</' + defaultTag + '>';
4915
5045
  }
4916
5046
  }
4917
5047
  // text
@@ -5001,7 +5131,37 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
5001
5131
  const sv = m.match(/style\s*=\s*(?:"|')[^"']*(?:"|')/);
5002
5132
  if (sv) {
5003
5133
  if (!v) v = [];
5004
- v.push(sv[0]);
5134
+ const style = sv[0].replace(/&quot;/g, '').match(/\s*(font-family|font-size|color|background-color)\s*:[^;]+(?!;)*/ig);
5135
+ if (style) {
5136
+ const allowedStyle = [];
5137
+ for (let i = 0, len = style.length, r; i < len; i++) {
5138
+ r = style[i].match(/(.+)(:)([^:]+$)/);
5139
+ if (r && !/inherit|initial/i.test(r[3])) {
5140
+ const k = util.kebabToCamelCase(r[1].trim());
5141
+ const v = this.wwComputedStyle[k].replace(/"/g, '');
5142
+ const c = r[3].trim();
5143
+ switch (k) {
5144
+ case 'fontFamily':
5145
+ if (options.plugins.font ? options.font.indexOf(c) === -1 : true) continue;
5146
+ break;
5147
+ case 'fontSize':
5148
+ if (!options.plugins.fontSize) continue;
5149
+ break;
5150
+ case 'color':
5151
+ if (!options.plugins.fontColor) continue;
5152
+ break;
5153
+ case 'backgroundColor':
5154
+ if (!options.plugins.hiliteColor) continue;
5155
+ break;
5156
+ }
5157
+
5158
+ if (v !== c) {
5159
+ allowedStyle.push(r[0]);
5160
+ }
5161
+ }
5162
+ }
5163
+ if (allowedStyle.length > 0) v.push('style="' + allowedStyle.join(';') + '"');
5164
+ }
5005
5165
  }
5006
5166
  }
5007
5167
 
@@ -5030,14 +5190,82 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
5030
5190
 
5031
5191
  if (v) {
5032
5192
  for (let i = 0, len = v.length; i < len; i++) {
5033
- if (lowLevelCheck && /^class="(?!(__se__|se-|katex))/.test(v[i])) continue;
5034
- t += ' ' + (/^(?:href|src)\s*=\s*('|"|\s)*javascript\s*\:/i.test(v[i]) ? '' : v[i]);
5193
+ if (lowLevelCheck && /^class="(?!(__se__|se-|katex))/.test(v[i].trim())) continue;
5194
+ t += ' ' + (/^(?:href|src)\s*=\s*('|"|\s)*javascript\s*\:/i.test(v[i].trim()) ? '' : v[i]);
5035
5195
  }
5036
5196
  }
5037
5197
 
5038
5198
  return t;
5039
5199
  },
5040
5200
 
5201
+ /**
5202
+ * @description Determines if formatting is required and returns a domTree
5203
+ * @param {Element} dom documentFragment
5204
+ * @returns {Element}
5205
+ * @private
5206
+ */
5207
+ _editFormat: function (dom) {
5208
+ let value = '', f;
5209
+ const tempTree = dom.childNodes;
5210
+ for (let i = 0, len = tempTree.length, n; i < len; i++) {
5211
+ n = tempTree[i];
5212
+ if (!util.isFormatElement(n) && !util.isRangeFormatElement(n) && !util.isComponent(n) && !/meta/i.test(n.nodeName)) {
5213
+ if (!f) f = util.createElement(options.defaultTag);
5214
+ f.appendChild(n);
5215
+ i--; len--;
5216
+ } else {
5217
+ if (f) {
5218
+ value += f.outerHTML;
5219
+ f = null;
5220
+ }
5221
+ value += n.outerHTML;
5222
+ }
5223
+ }
5224
+
5225
+ if (f) value += f.outerHTML;
5226
+
5227
+ return _d.createRange().createContextualFragment(value);
5228
+ },
5229
+
5230
+ _convertListCell: function (domTree) {
5231
+ let html = '';
5232
+
5233
+ for (let i = 0, len = domTree.length, node; i < len; i++) {
5234
+ node = domTree[i];
5235
+ if (node.nodeType === 1) {
5236
+ if (util.isList(node)) {
5237
+ html += node.innerHTML;
5238
+ } else if (util.isListCell(node)) {
5239
+ html += node.outerHTML;
5240
+ } else if (util.isFormatElement(node)) {
5241
+ html += '<li>' +(node.innerHTML.trim() || '<br>') + '</li>';
5242
+ } else if (util.isRangeFormatElement(node) && !util.isTable(node)) {
5243
+ html += this._convertListCell(node);
5244
+ } else {
5245
+ html += '<li>' + node.outerHTML + '</li>';
5246
+ }
5247
+ } else {
5248
+ html += '<li>' + (node.textContent || '<br>') + '</li>';
5249
+ }
5250
+ }
5251
+
5252
+ return html;
5253
+ },
5254
+
5255
+ _isFormatData: function (domTree) {
5256
+ let requireFormat = false;
5257
+
5258
+ for (let i = 0, len = domTree.length, t; i < len; i++) {
5259
+ t = domTree[i];
5260
+ if (t.nodeType === 1 && !util.isTextStyleElement(t) && !util.isBreak(t) && !util._disallowedTags(t)) {
5261
+ requireFormat = true;
5262
+ break;
5263
+ }
5264
+ }
5265
+
5266
+ return requireFormat;
5267
+ },
5268
+
5041
5269
  /**
5042
5270
  * @description Gets the clean HTML code for editor
5043
5271
  * @param {String} html HTML string
@@ -5071,16 +5299,12 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
5071
5299
  }
5072
5300
  }
5073
5301
 
5074
- const domTree = dom.childNodes;
5302
+ let domTree = dom.childNodes;
5075
5303
  let cleanHTML = '';
5076
- let requireFormat = false;
5304
+ const requireFormat = this._isFormatData(domTree);
5077
5305
 
5078
- for (let i = 0, len = domTree.length, t; i < len; i++) {
5079
- t = domTree[i];
5080
- if (t.nodeType === 1 && !util.isTextStyleElement(t) && !util.isBreak(t) && !util._disallowedTags(t)) {
5081
- requireFormat = true;
5082
- break;
5083
- }
5306
+ if(requireFormat) {
5307
+ domTree = this._editFormat(dom).childNodes;
5084
5308
  }
5085
5309
 
5086
5310
  for (let i = 0, len = domTree.length; i < len; i++) {
@@ -5443,6 +5667,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
5443
5667
  this._charTypeHTML = options.charCounterType === 'byte-html';
5444
5668
  this.wwComputedStyle = _w.getComputedStyle(context.element.wysiwyg);
5445
5669
  this._editorHeight = context.element.wysiwygFrame.offsetHeight;
5670
+ this._editorHeightPadding = util.getNumber(this.wwComputedStyle.getPropertyValue('padding-top')) + util.getNumber(this.wwComputedStyle.getPropertyValue('padding-bottom'));
5446
5671
 
5447
5672
  if (!options.iframe && typeof _w.ShadowRoot === 'function') {
5448
5673
  let child = context.element.wysiwygFrame;
@@ -5606,6 +5831,8 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
5606
5831
  this.codeViewDisabledButtons = context.element._buttonTray.querySelectorAll('.se-menu-list button[data-display]:not([class~="se-code-view-enabled"]):not([data-display="MORE"])');
5607
5832
  this.resizingDisabledButtons = context.element._buttonTray.querySelectorAll('.se-menu-list button[data-display]:not([class~="se-resizing-enabled"]):not([data-display="MORE"])');
5608
5833
 
5834
+ this._saveButtonStates();
5835
+
5609
5836
  const tool = context.tool;
5610
5837
  this.commandMap = {
5611
5838
  OUTDENT: tool.outdent,
@@ -5674,7 +5901,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
5674
5901
  },
5675
5902
 
5676
5903
  __callResizeFunction: function (h, resizeObserverEntry) {
5677
- h = h === -1 ? resizeObserverEntry.borderBoxSize[0].blockSize : h;
5904
+ h = h === -1 ? (resizeObserverEntry.borderBoxSize ? resizeObserverEntry.borderBoxSize[0].blockSize : (resizeObserverEntry.contentRect.height + this._editorHeightPadding)) : h;
5678
5905
  if (this._editorHeight !== h) {
5679
5906
  if (typeof functions.onResizeEditor === 'function') functions.onResizeEditor(h, this._editorHeight, core, resizeObserverEntry);
5680
5907
  this._editorHeight = h;
@@ -5943,7 +6170,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
5943
6170
  break;
5944
6171
  }
5945
6172
 
5946
- if (!command) return keyStr === 'B'; // chromium - bold disabled
6173
+ if (!command) return !!keyStr;
5947
6174
 
5948
6175
  core.commandHandler(core.commandMap[command], command);
5949
6176
  return true;
@@ -7566,41 +7793,11 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
7566
7793
  }
7567
7794
 
7568
7795
  if (cleanData) {
7569
- if (util.isListCell(util.getFormatElement(core.getSelectionNode(), null))) {
7570
- const dom = (_d.createRange().createContextualFragment(cleanData));
7571
- if (dom.childNodes[0].nodeType === 1) {
7572
- cleanData = event._convertListCell(dom);
7573
- }
7574
- }
7575
7796
  functions.insertHTML(cleanData, true, false);
7576
7797
  return false;
7577
7798
  }
7578
7799
  },
7579
7800
 
7580
- _convertListCell: function (dom) {
7581
- const domTree = dom.childNodes;
7582
- let html = '';
7583
-
7584
- for (let i = 0, len = domTree.length, node; i < len; i++) {
7585
- node = domTree[i];
7586
- if (node.nodeType === 1) {
7587
- if (util.isListCell(node)) {
7588
- html += node.outerHTML;
7589
- } else if (util.isFormatElement(node)) {
7590
- html += '<li>' +(node.innerHTML.trim() || '<br>') + '</li>';
7591
- } else if (util.isRangeFormatElement(node) && !util.isTable(node)) {
7592
- html += event._convertListCell(node);
7593
- } else {
7594
- html += '<li>' + node.outerHTML + '</li>';
7595
- }
7596
- } else {
7597
- html += '<li>' + (node.textContent || '<br>') + '</li>';
7598
- }
7599
- }
7600
-
7601
- return html;
7602
- },
7603
-
7604
7801
  onMouseMove_wysiwyg: function (e) {
7605
7802
  if (core.isDisabled || core.isReadOnly) return false;
7606
7803
  const component = util.getParentElement(e.target, util.isComponent);
@@ -8098,6 +8295,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
8098
8295
  context.tool = newContext.tool;
8099
8296
  if (options.iframe) context.element.wysiwyg = core._wd.body;
8100
8297
 
8298
+ core._recoverButtonStates();
8101
8299
  core._cachingButtons();
8102
8300
  core.history._resetCachingButton();
8103
8301
 
@@ -8315,10 +8513,16 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
8315
8513
  */
8316
8514
  insertHTML: function (html, notCleaningData, checkCharCount, rangeSelection) {
8317
8515
  if (!context.element.wysiwygFrame.contains(core.getSelection().focusNode)) core.focus();
8318
-
8516
+
8319
8517
  if (typeof html === 'string') {
8320
8518
  if (!notCleaningData) html = core.cleanHTML(html, null, null);
8321
8519
  try {
8520
+ if (util.isListCell(util.getFormatElement(core.getSelectionNode(), null))) {
8521
+ const dom = _d.createRange().createContextualFragment(html);
8522
+ const domTree = dom.childNodes;
8523
+ if (core._isFormatData(domTree)) html = core._convertListCell(domTree);
8524
+ }
8525
+
8322
8526
  const dom = _d.createRange().createContextualFragment(html);
8323
8527
  const domTree = dom.childNodes;
8324
8528