suneditor 2.43.3 → 2.43.6

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
@@ -459,13 +459,6 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
459
459
  DEL: ['text-decoration']
460
460
  },
461
461
 
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
462
  /**
470
463
  * @description Style button related to edit area
471
464
  * @property {Element} fullScreen fullScreen button element
@@ -475,19 +468,6 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
475
468
  */
476
469
  _styleCommandMap: null,
477
470
 
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
471
  /**
492
472
  * @description Variables used internally in editor operation
493
473
  * @property {Boolean} isCodeView State of code view
@@ -525,8 +505,9 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
525
505
 
526
506
  /**
527
507
  * @description Save the current buttons states to "allCommandButtons" object
508
+ * @private
528
509
  */
529
- saveButtonStates: function () {
510
+ _saveButtonStates: function () {
530
511
  if (!this.allCommandButtons) this.allCommandButtons = {};
531
512
 
532
513
  const currentButtons = this.context.element._buttonTray.querySelectorAll('.se-menu-list button[data-display]');
@@ -540,8 +521,9 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
540
521
 
541
522
  /**
542
523
  * @description Recover the current buttons states from "allCommandButtons" object
524
+ * @private
543
525
  */
544
- recoverButtonStates: function () {
526
+ _recoverButtonStates: function () {
545
527
  if (this.allCommandButtons) {
546
528
  const currentButtons = this.context.element._buttonTray.querySelectorAll('.se-menu-list button[data-display]');
547
529
  for (let i = 0, button, command, oldButton; i < currentButtons.length; i++) {
@@ -1692,152 +1674,261 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
1692
1674
  return null;
1693
1675
  }
1694
1676
 
1695
- const freeFormat = util.getFreeFormatElement(this.getSelectionNode(), null);
1677
+ let range = this.getRange();
1678
+ let line = util.isListCell(range.commonAncestorContainer) ? range.commonAncestorContainer : util.getFormatElement(this.getSelectionNode(), null);
1679
+ let insertListCell = util.isListCell(line) && (util.isListCell(oNode) || util.isList(oNode));
1680
+
1681
+ let parentNode, originAfter, tempAfterNode, tempParentNode = null;
1682
+ const freeFormat = util.isFreeFormatElement(line);
1696
1683
  const isFormats = (!freeFormat && (util.isFormatElement(oNode) || util.isRangeFormatElement(oNode))) || util.isComponent(oNode);
1697
1684
 
1685
+ if (insertListCell) {
1686
+ tempAfterNode = afterNode || util.isList(oNode) ? line.lastChild : line.nextElementSibling;
1687
+ tempParentNode = util.isList(oNode) ? line : (tempAfterNode || line).parentNode;
1688
+ }
1689
+
1698
1690
  if (!afterNode && (isFormats || util.isComponent(oNode) || util.isMedia(oNode))) {
1691
+ const isEdge = this.isEdgePoint(range.endContainer, range.endOffset, 'end');
1699
1692
  const r = this.removeNode();
1700
- if (r.container.nodeType === 3 || util.isBreak(r.container)) {
1701
- const depthFormat = util.getParentElement(r.container, function (current) { return this.isRangeFormatElement(current) || this.isListCell(current); }.bind(util));
1702
- afterNode = util.splitElement(r.container, r.offset, !depthFormat ? 0 : util.getElementDepth(depthFormat) + 1);
1703
- if (afterNode) afterNode = afterNode.previousSibling;
1693
+ const container = r.container;
1694
+ const prevContainer = r.prevContainer;
1695
+
1696
+ if (insertListCell && prevContainer) {
1697
+ tempParentNode = prevContainer.nodeType === 3 ? prevContainer.parentNode : prevContainer;
1698
+ if (tempParentNode.contains(container)) {
1699
+ let sameParent = true;
1700
+ tempAfterNode = container;
1701
+ while (tempAfterNode.parentNode && tempAfterNode.parentNode !== tempParentNode) {
1702
+ tempAfterNode = tempAfterNode.parentNode;
1703
+ sameParent = false;
1704
+ }
1705
+ if (sameParent && container === prevContainer) tempAfterNode = tempAfterNode.nextSibling;
1706
+ } else {
1707
+ tempAfterNode = null;
1708
+ }
1709
+ } else if (insertListCell && util.isListCell(container) && !line.parentElement) {
1710
+ line = util.createElement('LI');
1711
+ tempParentNode.appendChild(line);
1712
+ container.appendChild(tempParentNode);
1713
+ tempAfterNode = null;
1714
+ } else if (container.nodeType === 3 || util.isBreak(container) || insertListCell) {
1715
+ const depthFormat = util.getParentElement(container, function (current) { return this.isRangeFormatElement(current) || this.isListCell(current); }.bind(util));
1716
+ afterNode = util.splitElement(container, r.offset, !depthFormat ? 0 : util.getElementDepth(depthFormat) + 1);
1717
+ if (afterNode) {
1718
+ if (insertListCell) {
1719
+ if (line.contains(container)) {
1720
+ const subList = util.isList(line.lastElementChild);
1721
+ let newCell = null;
1722
+ if (!isEdge) {
1723
+ newCell = line.cloneNode(false);
1724
+ newCell.appendChild(afterNode.textContent.trim() ? afterNode : util.createTextNode(util.zeroWidthSpace));
1725
+ }
1726
+ if (subList) {
1727
+ if (!newCell) {
1728
+ newCell = line.cloneNode(false);
1729
+ newCell.appendChild(util.createTextNode(util.zeroWidthSpace));
1730
+ }
1731
+ newCell.appendChild(line.lastElementChild);
1732
+ }
1733
+ if (newCell) {
1734
+ tempParentNode.insertBefore(newCell, line.nextElementSibling);
1735
+ tempAfterNode = afterNode = newCell;
1736
+ }
1737
+ }
1738
+ } else {
1739
+ afterNode = afterNode.previousSibling;
1740
+ }
1741
+ }
1704
1742
  }
1705
1743
  }
1706
1744
 
1707
- const range = (!afterNode && !isFormats) ? this.getRange_addLine(this.getRange(), null) : this.getRange();
1745
+ range = (!afterNode && !isFormats) ? this.getRange_addLine(this.getRange(), null) : this.getRange();
1708
1746
  const commonCon = range.commonAncestorContainer;
1709
1747
  const startOff = range.startOffset;
1710
1748
  const endOff = range.endOffset;
1711
1749
  const formatRange = range.startContainer === commonCon && util.isFormatElement(commonCon);
1712
1750
  const startCon = formatRange ? (commonCon.childNodes[startOff] || commonCon.childNodes[0] || range.startContainer) : range.startContainer;
1713
1751
  const endCon = formatRange ? (commonCon.childNodes[endOff] || commonCon.childNodes[commonCon.childNodes.length - 1] || range.endContainer) : range.endContainer;
1714
- let parentNode, originAfter = null;
1715
-
1716
- if (!afterNode) {
1717
- parentNode = startCon;
1718
- if (startCon.nodeType === 3) {
1719
- parentNode = startCon.parentNode;
1720
- }
1721
1752
 
1722
- /** No Select range node */
1723
- if (range.collapsed) {
1724
- if (commonCon.nodeType === 3) {
1725
- if (commonCon.textContent.length > endOff) afterNode = commonCon.splitText(endOff);
1726
- else afterNode = commonCon.nextSibling;
1727
- } else {
1728
- if (!util.isBreak(parentNode)) {
1729
- let c = parentNode.childNodes[startOff];
1730
- const focusNode = (c && c.nodeType === 3 && util.onlyZeroWidthSpace(c) && util.isBreak(c.nextSibling)) ? c.nextSibling : c;
1731
- if (focusNode) {
1732
- if (!focusNode.nextSibling) {
1733
- parentNode.removeChild(focusNode);
1734
- afterNode = null;
1753
+ if (!insertListCell) {
1754
+ if (!afterNode) {
1755
+ parentNode = startCon;
1756
+ if (startCon.nodeType === 3) {
1757
+ parentNode = startCon.parentNode;
1758
+ }
1759
+
1760
+ /** No Select range node */
1761
+ if (range.collapsed) {
1762
+ if (commonCon.nodeType === 3) {
1763
+ if (commonCon.textContent.length > endOff) afterNode = commonCon.splitText(endOff);
1764
+ else afterNode = commonCon.nextSibling;
1765
+ } else {
1766
+ if (!util.isBreak(parentNode)) {
1767
+ let c = parentNode.childNodes[startOff];
1768
+ const focusNode = (c && c.nodeType === 3 && util.onlyZeroWidthSpace(c) && util.isBreak(c.nextSibling)) ? c.nextSibling : c;
1769
+ if (focusNode) {
1770
+ if (!focusNode.nextSibling) {
1771
+ parentNode.removeChild(focusNode);
1772
+ afterNode = null;
1773
+ } else {
1774
+ afterNode = (util.isBreak(focusNode) && !util.isBreak(oNode)) ? focusNode : focusNode.nextSibling;
1775
+ }
1735
1776
  } else {
1736
- afterNode = (util.isBreak(focusNode) && !util.isBreak(oNode)) ? focusNode : focusNode.nextSibling;
1777
+ afterNode = null;
1737
1778
  }
1738
1779
  } else {
1739
- afterNode = null;
1780
+ afterNode = parentNode;
1781
+ parentNode = parentNode.parentNode;
1740
1782
  }
1741
- } else {
1742
- afterNode = parentNode;
1743
- parentNode = parentNode.parentNode;
1744
1783
  }
1745
- }
1746
- } else { /** Select range nodes */
1747
- const isSameContainer = startCon === endCon;
1748
-
1749
- if (isSameContainer) {
1750
- if (this.isEdgePoint(endCon, endOff)) afterNode = endCon.nextSibling;
1751
- else afterNode = endCon.splitText(endOff);
1752
-
1753
- let removeNode = startCon;
1754
- if (!this.isEdgePoint(startCon, startOff)) removeNode = startCon.splitText(startOff);
1755
-
1756
- parentNode.removeChild(removeNode);
1757
- if (parentNode.childNodes.length === 0 && isFormats) {
1758
- parentNode.innerHTML = '<br>';
1759
- }
1760
- }
1761
- else {
1762
- const removedTag = this.removeNode();
1763
- const container = removedTag.container;
1764
- const prevContainer = removedTag.prevContainer;
1765
- if (container && container.childNodes.length === 0 && isFormats) {
1766
- if (util.isFormatElement(container)) {
1767
- container.innerHTML = '<br>';
1768
- } else if (util.isRangeFormatElement(container)) {
1769
- container.innerHTML = '<' + options.defaultTag + '><br></' + options.defaultTag + '>';
1784
+ } else { /** Select range nodes */
1785
+ const isSameContainer = startCon === endCon;
1786
+
1787
+ if (isSameContainer) {
1788
+ if (this.isEdgePoint(endCon, endOff)) afterNode = endCon.nextSibling;
1789
+ else afterNode = endCon.splitText(endOff);
1790
+
1791
+ let removeNode = startCon;
1792
+ if (!this.isEdgePoint(startCon, startOff)) removeNode = startCon.splitText(startOff);
1793
+
1794
+ parentNode.removeChild(removeNode);
1795
+ if (parentNode.childNodes.length === 0 && isFormats) {
1796
+ parentNode.innerHTML = '<br>';
1770
1797
  }
1771
1798
  }
1772
-
1773
- if (!isFormats && prevContainer) {
1774
- parentNode = prevContainer.nodeType === 3 ? prevContainer.parentNode : prevContainer;
1775
- if (parentNode.contains(container)) {
1776
- let sameParent = true;
1777
- afterNode = container;
1778
- while (afterNode.parentNode !== parentNode) {
1779
- afterNode = afterNode.parentNode;
1780
- sameParent = false;
1799
+ else {
1800
+ const removedTag = this.removeNode();
1801
+ const container = removedTag.container;
1802
+ const prevContainer = removedTag.prevContainer;
1803
+
1804
+ if (container && container.childNodes.length === 0 && isFormats) {
1805
+ if (util.isFormatElement(container)) {
1806
+ container.innerHTML = '<br>';
1807
+ } else if (util.isRangeFormatElement(container)) {
1808
+ container.innerHTML = '<' + options.defaultTag + '><br></' + options.defaultTag + '>';
1781
1809
  }
1782
- if (sameParent && container === prevContainer) afterNode = afterNode.nextSibling;
1783
- } else {
1810
+ }
1811
+
1812
+ if (util.isListCell(container) && oNode.nodeType === 3) {
1813
+ parentNode = container;
1784
1814
  afterNode = null;
1815
+ } else if (!isFormats && prevContainer) {
1816
+ parentNode = prevContainer.nodeType === 3 ? prevContainer.parentNode : prevContainer;
1817
+ if (parentNode.contains(container)) {
1818
+ let sameParent = true;
1819
+ afterNode = container;
1820
+ while (afterNode.parentNode && afterNode.parentNode !== parentNode) {
1821
+ afterNode = afterNode.parentNode;
1822
+ sameParent = false;
1823
+ }
1824
+ if (sameParent && container === prevContainer) afterNode = afterNode.nextSibling;
1825
+ } else {
1826
+ afterNode = null;
1827
+ }
1828
+ } else {
1829
+ afterNode = isFormats ? endCon : container === prevContainer ? container.nextSibling : container;
1830
+ parentNode = (!afterNode || !afterNode.parentNode) ? commonCon : afterNode.parentNode;
1831
+ }
1832
+
1833
+ while (afterNode && !util.isFormatElement(afterNode) && afterNode.parentNode !== commonCon) {
1834
+ afterNode = afterNode.parentNode;
1785
1835
  }
1786
- } else {
1787
- afterNode = isFormats ? endCon : container === prevContainer ? container.nextSibling : container;
1788
- parentNode = (!afterNode || !afterNode.parentNode) ? commonCon : afterNode.parentNode;
1789
- }
1790
-
1791
- while (afterNode && !util.isFormatElement(afterNode) && afterNode.parentNode !== commonCon) {
1792
- afterNode = afterNode.parentNode;
1793
1836
  }
1794
1837
  }
1838
+ } else { // has afterNode
1839
+ parentNode = afterNode.parentNode;
1840
+ afterNode = afterNode.nextSibling;
1841
+ originAfter = true;
1795
1842
  }
1796
1843
  }
1797
- // has afterNode
1798
- else {
1799
- parentNode = afterNode.parentNode;
1800
- afterNode = afterNode.nextSibling;
1801
- originAfter = true;
1802
- }
1803
1844
 
1804
- // --- insert node ---
1805
1845
  try {
1806
- if (util.isWysiwygDiv(afterNode) || parentNode === context.element.wysiwyg.parentNode) {
1807
- parentNode = context.element.wysiwyg;
1808
- afterNode = null;
1846
+ // set node
1847
+ if (!insertListCell) {
1848
+ if (util.isWysiwygDiv(afterNode) || parentNode === context.element.wysiwyg.parentNode) {
1849
+ parentNode = context.element.wysiwyg;
1850
+ afterNode = null;
1851
+ }
1852
+
1853
+ if (util.isFormatElement(oNode) || util.isRangeFormatElement(oNode) || (!util.isListCell(parentNode) && util.isComponent(oNode))) {
1854
+ const oldParent = parentNode;
1855
+ if (util.isList(afterNode)) {
1856
+ parentNode = afterNode;
1857
+ afterNode = null;
1858
+ } else if (util.isListCell(afterNode)) {
1859
+ parentNode = afterNode.previousElementSibling || afterNode;
1860
+ } else if (!originAfter && !afterNode) {
1861
+ const r = this.removeNode();
1862
+ 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;
1863
+ const rangeCon = util.isWysiwygDiv(container) || util.isRangeFormatElement(container);
1864
+ parentNode = rangeCon ? container : container.parentNode;
1865
+ afterNode = rangeCon ? null : container.nextSibling;
1866
+ }
1867
+
1868
+ if (oldParent.childNodes.length === 0 && parentNode !== oldParent) util.removeItem(oldParent);
1869
+ }
1870
+
1871
+ if (isFormats && !freeFormat && !util.isRangeFormatElement(parentNode) && !util.isListCell(parentNode) && !util.isWysiwygDiv(parentNode)) {
1872
+ afterNode = parentNode.nextElementSibling;
1873
+ parentNode = parentNode.parentNode;
1874
+ }
1875
+
1876
+ if (util.isWysiwygDiv(parentNode) && (oNode.nodeType === 3 || util.isBreak(oNode))) {
1877
+ const fNode = util.createElement(options.defaultTag);
1878
+ fNode.appendChild(oNode);
1879
+ oNode = fNode;
1880
+ }
1809
1881
  }
1810
1882
 
1811
- if (util.isFormatElement(oNode) || util.isRangeFormatElement(oNode) || (!util.isListCell(parentNode) && util.isComponent(oNode))) {
1812
- const oldParent = parentNode;
1813
- if (util.isList(afterNode)) {
1814
- parentNode = afterNode;
1883
+ // insert--
1884
+ if (insertListCell) {
1885
+ if (!tempParentNode.parentNode) {
1886
+ parentNode = context.element.wysiwyg;
1815
1887
  afterNode = null;
1816
- } else if (util.isListCell(afterNode)) {
1817
- parentNode = afterNode.previousElementSibling || afterNode;
1818
- } else if (!originAfter && !afterNode) {
1819
- const r = this.removeNode();
1820
- 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;
1821
- const rangeCon = util.isWysiwygDiv(container) || util.isRangeFormatElement(container);
1822
- parentNode = rangeCon ? container : container.parentNode;
1823
- afterNode = rangeCon ? null : container.nextSibling;
1888
+ } else {
1889
+ parentNode = tempParentNode;
1890
+ afterNode = tempAfterNode;
1824
1891
  }
1825
-
1826
- if (oldParent.childNodes.length === 0 && parentNode !== oldParent) util.removeItem(oldParent);
1892
+ } else {
1893
+ afterNode = parentNode === afterNode ? parentNode.lastChild : afterNode;
1827
1894
  }
1828
1895
 
1829
- if (isFormats && !freeFormat && !util.isRangeFormatElement(parentNode) && !util.isListCell(parentNode) && !util.isWysiwygDiv(parentNode)) {
1830
- afterNode = parentNode.nextElementSibling;
1831
- parentNode = parentNode.parentNode;
1896
+ if (util.isListCell(oNode) && !util.isList(parentNode)) {
1897
+ if (util.isListCell(parentNode)) {
1898
+ afterNode = parentNode.nextElementSibling;
1899
+ parentNode = parentNode.parentNode;
1900
+ } else {
1901
+ const ul = util.createElement('ol');
1902
+ parentNode.insertBefore(ul, afterNode);
1903
+ parentNode = ul;
1904
+ afterNode = null;
1905
+ }
1906
+ insertListCell = true;
1832
1907
  }
1833
1908
 
1834
- if (util.isWysiwygDiv(parentNode) && (oNode.nodeType === 3 || util.isBreak(oNode))) {
1835
- const fNode = util.createElement(options.defaultTag);
1836
- fNode.appendChild(oNode);
1837
- oNode = fNode;
1838
- }
1909
+ parentNode.insertBefore(oNode, afterNode);
1910
+
1911
+ if (insertListCell) {
1912
+ if (util.onlyZeroWidthSpace(line.textContent.trim())) {
1913
+ util.removeItem(line);
1914
+ oNode = oNode.lastChild;
1915
+ } else {
1916
+ const chList = util.getArrayItem(line.children, util.isList);
1917
+ if (chList) {
1918
+ if (oNode !== chList) {
1919
+ oNode.appendChild(chList);
1920
+ oNode = chList.previousSibling;
1921
+ } else {
1922
+ parentNode.appendChild(oNode);
1923
+ oNode = parentNode;
1924
+ }
1839
1925
 
1840
- parentNode.insertBefore(oNode, parentNode === afterNode ? parentNode.lastChild : afterNode);
1926
+ if (util.onlyZeroWidthSpace(line.textContent.trim())) {
1927
+ util.removeItem(line);
1928
+ }
1929
+ }
1930
+ }
1931
+ }
1841
1932
  } catch (e) {
1842
1933
  parentNode.appendChild(oNode);
1843
1934
  } finally {
@@ -2006,28 +2097,11 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
2006
2097
  startIndex = endIndex = 0;
2007
2098
  }
2008
2099
 
2009
- function remove (item) {
2010
- const format = util.getFormatElement(item, null);
2011
- util.removeItem(item);
2012
-
2013
- if(util.isListCell(format)) {
2014
- const list = util.getArrayItem(format.children, util.isList, false);
2015
- if (list) {
2016
- const child = list.firstElementChild;
2017
- const children = child.childNodes;
2018
- while (children[0]) {
2019
- format.insertBefore(children[0], list);
2020
- }
2021
- util.removeItemAllParents(child, null, null);
2022
- }
2023
- }
2024
- }
2025
-
2026
2100
  for (let i = startIndex; i <= endIndex; i++) {
2027
2101
  const item = childNodes[i];
2028
2102
 
2029
2103
  if (item.length === 0 || (item.nodeType === 3 && item.data === undefined)) {
2030
- remove(item);
2104
+ this._nodeRemoveListItem(item);
2031
2105
  continue;
2032
2106
  }
2033
2107
 
@@ -2047,7 +2121,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
2047
2121
  if (beforeNode.length > 0) {
2048
2122
  startCon.data = beforeNode.data;
2049
2123
  } else {
2050
- remove(startCon);
2124
+ this._nodeRemoveListItem(startCon);
2051
2125
  }
2052
2126
 
2053
2127
  if (item === endCon) break;
@@ -2065,24 +2139,26 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
2065
2139
  if (afterNode.length > 0) {
2066
2140
  endCon.data = afterNode.data;
2067
2141
  } else {
2068
- remove(endCon);
2142
+ this._nodeRemoveListItem(endCon);
2069
2143
  }
2070
2144
 
2071
2145
  continue;
2072
2146
  }
2073
2147
 
2074
- remove(item);
2148
+ this._nodeRemoveListItem(item);
2075
2149
  }
2076
2150
 
2077
- container = endCon && endCon.parentNode ? endCon : startCon && startCon.parentNode ? startCon : (range.endContainer || range.startContainer);
2151
+ const endUl = util.getParentElement(endCon, 'ul');
2152
+ const startLi = util.getParentElement(startCon, 'li');
2153
+ if (endUl && startLi && startLi.contains(endUl)) {
2154
+ container = endUl.previousSibling;
2155
+ offset = container.textContent.length;
2156
+ } else {
2157
+ container = endCon && endCon.parentNode ? endCon : startCon && startCon.parentNode ? startCon : (range.endContainer || range.startContainer);
2158
+ }
2078
2159
 
2079
2160
  if (!util.isWysiwygDiv(container) && container.childNodes.length === 0) {
2080
- const rc = util.removeItemAllParents(container, function (current) {
2081
- if (this.isComponent(current)) return false;
2082
- const text = current.textContent;
2083
- return text.length === 0 || /^(\n|\u200B)+$/.test(text);
2084
- }.bind(util), null);
2085
-
2161
+ const rc = util.removeItemAllParents(container, null, null);
2086
2162
  if (rc) container = rc.sc || rc.ec || context.element.wysiwyg;
2087
2163
  }
2088
2164
 
@@ -2098,6 +2174,19 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
2098
2174
  };
2099
2175
  },
2100
2176
 
2177
+ _nodeRemoveListItem: function (item) {
2178
+ const format = util.getFormatElement(item, null);
2179
+ util.removeItem(item);
2180
+
2181
+ if(!util.isListCell(format)) return;
2182
+
2183
+ util.removeItemAllParents(format, null, null);
2184
+
2185
+ if (format && util.isList(format.firstChild)) {
2186
+ format.insertBefore(util.createTextNode(util.zeroWidthSpace), format.firstChild);
2187
+ }
2188
+ },
2189
+
2101
2190
  /**
2102
2191
  * @description Appended all selected format Element to the argument element and insert
2103
2192
  * @param {Element} rangeElement Element of wrap the arguments (BLOCKQUOTE...)
@@ -2810,20 +2899,26 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
2810
2899
 
2811
2900
  // one line
2812
2901
  if (oneLine) {
2813
- this._resetCommonListCell(lineNodes[0], styleArray);
2902
+ if (this._resetCommonListCell(lineNodes[0], styleArray)) range = this.setRange(startCon, startOff, endCon, endOff);
2903
+
2814
2904
  const newRange = this._nodeChange_oneLine(lineNodes[0], newNode, validation, startCon, startOff, endCon, endOff, isRemoveFormat, isRemoveNode, range.collapsed, _removeCheck, _getMaintainedNode, _isMaintainedNode);
2815
2905
  start.container = newRange.startContainer;
2816
2906
  start.offset = newRange.startOffset;
2817
2907
  end.container = newRange.endContainer;
2818
2908
  end.offset = newRange.endOffset;
2909
+
2819
2910
  if (start.container === end.container && util.onlyZeroWidthSpace(start.container)) {
2820
2911
  start.offset = end.offset = 1;
2821
2912
  }
2822
2913
  this._setCommonListStyle(newRange.ancestor, null);
2823
2914
  } else { // multi line
2915
+ let appliedCommonList = false;
2916
+ if (endLength > 0 && this._resetCommonListCell(lineNodes[endLength], styleArray)) appliedCommonList = true;
2917
+ if (this._resetCommonListCell(lineNodes[0], styleArray)) appliedCommonList = true;
2918
+ if (appliedCommonList) this.setRange(startCon, startOff, endCon, endOff);
2919
+
2824
2920
  // end
2825
2921
  if (endLength > 0) {
2826
- this._resetCommonListCell(lineNodes[endLength], styleArray);
2827
2922
  newNode = appendNode.cloneNode(false);
2828
2923
  end = this._nodeChange_endLine(lineNodes[endLength], newNode, validation, endCon, endOff, isRemoveFormat, isRemoveNode, _removeCheck, _getMaintainedNode, _isMaintainedNode);
2829
2924
  }
@@ -2841,7 +2936,6 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
2841
2936
  }
2842
2937
 
2843
2938
  // start
2844
- this._resetCommonListCell(lineNodes[0], styleArray);
2845
2939
  newNode = appendNode.cloneNode(false);
2846
2940
  start = this._nodeChange_startLine(lineNodes[0], newNode, validation, startCon, startOff, isRemoveFormat, isRemoveNode, _removeCheck, _getMaintainedNode, _isMaintainedNode, end.container);
2847
2941
 
@@ -2901,9 +2995,11 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
2901
2995
  }
2902
2996
 
2903
2997
  let sel = refer.cloneNode(false);
2904
- let r = null;
2998
+ let r = null, appliedEl = false;
2905
2999
  for (let i = 0, len = children.length, c, s; i < len; i++) {
2906
3000
  c = children[i];
3001
+ if (options._textTagsMap[c.nodeName.toLowerCase()]) continue;
3002
+
2907
3003
  s = util.getValues(c.style);
2908
3004
  if (s.length === 0 || (ec.some(function (k) {return s.indexOf(k) === -1;}) && s.some(function(k) {ec.indexOf(k) > -1;}))) {
2909
3005
  r = c.nextSibling;
@@ -2912,11 +3008,19 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
2912
3008
  el.insertBefore(sel, r);
2913
3009
  sel = refer.cloneNode(false);
2914
3010
  r = null;
3011
+ appliedEl = true;
2915
3012
  }
2916
3013
  }
2917
3014
 
2918
- if (sel.childNodes.length > 0) el.insertBefore(sel, r);
2919
- if (!elStyles.length) el.removeAttribute('style');
3015
+ if (sel.childNodes.length > 0) {
3016
+ el.insertBefore(sel, r);
3017
+ appliedEl = true;
3018
+ }
3019
+ if (!elStyles.length) {
3020
+ el.removeAttribute('style');
3021
+ }
3022
+
3023
+ return appliedEl;
2920
3024
  },
2921
3025
 
2922
3026
  /**
@@ -2934,40 +3038,39 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
2934
3038
  if (!child || children.length > 1 || child.nodeType !== 1) return;
2935
3039
 
2936
3040
  // set cell style---
2937
- const commonStyleElements = [];
2938
3041
  const childStyle = child.style;
2939
3042
  const elStyle = el.style;
3043
+ const nodeName = child.nodeName.toLowerCase();
3044
+ let appliedEl = false;
2940
3045
 
2941
3046
  // 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;
3047
+ if (options._textTagsMap[nodeName] === options._defaultCommand.bold.toLowerCase()) elStyle.fontWeight = 'bold';
3048
+ if (options._textTagsMap[nodeName] === options._defaultCommand.italic.toLowerCase()) elStyle.fontStyle = 'italic';
2946
3049
 
2947
3050
  // styles
2948
3051
  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]);
3052
+ if (cKeys.length > 0) {
3053
+ for (let i = 0, len = this._listCamel.length; i < len; i++) {
3054
+ if (cKeys.indexOf(this._listKebab[i]) > -1) {
3055
+ elStyle[this._listCamel[i]] = childStyle[this._listCamel[i]];
3056
+ childStyle.removeProperty(this._listKebab[i]);
3057
+ appliedEl = true;
3058
+ }
2953
3059
  }
2954
3060
  }
2955
-
2956
- // remove child
2957
- if (!childStyle.length) commonStyleElements.push(child);
2958
3061
 
2959
3062
  this._setCommonListStyle(el, child);
3063
+ if (!appliedEl) return;
2960
3064
 
2961
3065
  // 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;
3066
+ if (!childStyle.length) {
3067
+ const ch = child.childNodes;
3068
+ const p = child.parentNode;
3069
+ const n = child.nextSibling;
2967
3070
  while (ch.length > 0) {
2968
3071
  p.insertBefore(ch[0], n);
2969
3072
  }
2970
- util.removeItem(commonStyleElements[i]);
3073
+ util.removeItem(child);
2971
3074
  }
2972
3075
  },
2973
3076
 
@@ -4284,7 +4387,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
4284
4387
  wysiwyg.appendChild(format);
4285
4388
  last = br;
4286
4389
  }
4287
- this.setRange(first, 0, last, last.textContent.length);
4390
+ event._showToolbarBalloon(this.setRange(first, 0, last, last.textContent.length));
4288
4391
  break;
4289
4392
  case 'codeView':
4290
4393
  this.toggleCodeView();
@@ -4337,7 +4440,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
4337
4440
  if (context.tool.save) context.tool.save.setAttribute('disabled', true);
4338
4441
  break;
4339
4442
  default : // 'STRONG', 'U', 'EM', 'DEL', 'SUB', 'SUP'..
4340
- command = this._defaultCommand[command.toLowerCase()] || command;
4443
+ command = options._defaultCommand[command.toLowerCase()] || command;
4341
4444
  if (!this.commandMap[command]) this.commandMap[command] = target;
4342
4445
 
4343
4446
  const nodesMap = this._variable.currentNodesMap;
@@ -5152,7 +5255,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
5152
5255
  for (let i = 0, t; i < domTree.length; i++) {
5153
5256
  t = domTree[i];
5154
5257
 
5155
- if (!util.isFormatElement(t) && !util.isComponent(t) && !util.isMedia(t)) {
5258
+ if (!util.isFormatElement(t) && !util.isRangeFormatElement(t) && !util.isComponent(t) && !util.isMedia(t)) {
5156
5259
  if (!p) p = util.createElement(options.defaultTag);
5157
5260
  p.appendChild(t);
5158
5261
  i--;
@@ -5626,12 +5729,10 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
5626
5729
  this.codeViewDisabledButtons = context.element._buttonTray.querySelectorAll('.se-menu-list button[data-display]:not([class~="se-code-view-enabled"]):not([data-display="MORE"])');
5627
5730
  this.resizingDisabledButtons = context.element._buttonTray.querySelectorAll('.se-menu-list button[data-display]:not([class~="se-resizing-enabled"]):not([data-display="MORE"])');
5628
5731
 
5629
- this.saveButtonStates();
5732
+ this._saveButtonStates();
5630
5733
 
5631
5734
  const tool = context.tool;
5632
5735
  this.commandMap = {
5633
- SUB: tool.subscript,
5634
- SUP: tool.superscript,
5635
5736
  OUTDENT: tool.outdent,
5636
5737
  INDENT: tool.indent
5637
5738
  };
@@ -5639,6 +5740,8 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
5639
5740
  this.commandMap[options.textTags.underline.toUpperCase()] = tool.underline;
5640
5741
  this.commandMap[options.textTags.italic.toUpperCase()] = tool.italic;
5641
5742
  this.commandMap[options.textTags.strike.toUpperCase()] = tool.strike;
5743
+ this.commandMap[options.textTags.sub.toUpperCase()] = tool.subscript;
5744
+ this.commandMap[options.textTags.sup.toUpperCase()] = tool.superscript;
5642
5745
 
5643
5746
  this._styleCommandMap = {
5644
5747
  fullScreen: tool.fullScreen,
@@ -5965,7 +6068,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
5965
6068
  break;
5966
6069
  }
5967
6070
 
5968
- if (!command) return keyStr === 'B'; // chromium - bold disabled
6071
+ if (!command) return !!keyStr;
5969
6072
 
5970
6073
  core.commandHandler(core.commandMap[command], command);
5971
6074
  return true;
@@ -5978,7 +6081,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
5978
6081
 
5979
6082
  const marginDir = options.rtl ? 'marginRight' : 'marginLeft';
5980
6083
  const commandMap = core.commandMap;
5981
- const classOnCheck = this._onButtonsCheck;
6084
+ const classOnCheck = event._onButtonsCheck;
5982
6085
  const commandMapNodes = [];
5983
6086
  const currentNodes = [];
5984
6087
 
@@ -7233,6 +7336,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
7233
7336
  onBlur_wysiwyg: function (e) {
7234
7337
  if (core._antiBlur || core._variable.isCodeView) return;
7235
7338
  core.hasFocus = false;
7339
+ core.effectNode = null;
7236
7340
  core.controllersOff();
7237
7341
  if (core._isInline || core._isBalloon) event._hideToolbar();
7238
7342
 
@@ -7589,23 +7693,23 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
7589
7693
  if (cleanData) {
7590
7694
  if (util.isListCell(util.getFormatElement(core.getSelectionNode(), null))) {
7591
7695
  const dom = (_d.createRange().createContextualFragment(cleanData));
7592
- if (dom.childNodes[0].nodeType === 1) {
7593
- cleanData = event._convertListCell(dom);
7594
- }
7696
+ const domTree = dom.childNodes;
7697
+ if (domTree.length > 1 && domTree[0].nodeType === 1) cleanData = event._convertListCell(domTree);
7595
7698
  }
7596
7699
  functions.insertHTML(cleanData, true, false);
7597
7700
  return false;
7598
7701
  }
7599
7702
  },
7600
7703
 
7601
- _convertListCell: function (dom) {
7602
- const domTree = dom.childNodes;
7704
+ _convertListCell: function (domTree) {
7603
7705
  let html = '';
7604
7706
 
7605
7707
  for (let i = 0, len = domTree.length, node; i < len; i++) {
7606
7708
  node = domTree[i];
7607
7709
  if (node.nodeType === 1) {
7608
- if (util.isFormatElement(node)) {
7710
+ if (util.isListCell(node) || util.isList(node)) {
7711
+ html += node.outerHTML;
7712
+ } else if (util.isFormatElement(node)) {
7609
7713
  html += '<li>' +(node.innerHTML.trim() || '<br>') + '</li>';
7610
7714
  } else if (util.isRangeFormatElement(node) && !util.isTable(node)) {
7611
7715
  html += event._convertListCell(node);
@@ -8117,11 +8221,11 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
8117
8221
  context.tool = newContext.tool;
8118
8222
  if (options.iframe) context.element.wysiwyg = core._wd.body;
8119
8223
 
8120
- core.recoverButtonStates();
8121
-
8224
+ core._recoverButtonStates();
8122
8225
  core._cachingButtons();
8123
8226
  core.history._resetCachingButton();
8124
8227
 
8228
+ core.effectNode = null;
8125
8229
  if (core.hasFocus) event._applyTagEffects();
8126
8230
  if (core.isReadOnly) util.setDisabledButtons(true, core.resizingDisabledButtons);
8127
8231
  if (typeof functions.onSetToolbarButtons === 'function') functions.onSetToolbarButtons(newToolbar._buttonTray.querySelectorAll('button'), core);