el-text-editor 0.0.92 → 0.0.94

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.
@@ -1734,13 +1734,11 @@ class ElTextEditorComponent {
1734
1734
  // this.savedSelection = null;
1735
1735
  // }
1736
1736
  setTextColor(event) {
1737
- console.log("clicked");
1738
1737
  if (!this.savedSelection) {
1739
1738
  console.warn("No saved selection available!");
1740
1739
  return;
1741
1740
  }
1742
1741
  const color = event.target.value;
1743
- console.log("color", color);
1744
1742
  this.selectedTextColor = color;
1745
1743
  const selection = window.getSelection();
1746
1744
  if (!selection || selection.rangeCount === 0) {
@@ -1749,60 +1747,102 @@ class ElTextEditorComponent {
1749
1747
  }
1750
1748
  selection.removeAllRanges();
1751
1749
  selection.addRange(this.savedSelection);
1752
- const range = this.savedSelection;
1753
- const getParentElement = (node) => {
1754
- let currentNode = node;
1755
- if (currentNode && currentNode.nodeType === Node.TEXT_NODE) {
1756
- currentNode = currentNode.parentNode;
1750
+ const range = this.savedSelection.cloneRange();
1751
+ const wrapTextNode = (textNode, start, end) => {
1752
+ const span = document.createElement("span");
1753
+ span.style.color = color;
1754
+ const selectedText = textNode.textContent.slice(start, end);
1755
+ span.textContent = selectedText;
1756
+ const beforeText = textNode.textContent.slice(0, start);
1757
+ const afterText = textNode.textContent.slice(end);
1758
+ const fragment = document.createDocumentFragment();
1759
+ if (beforeText)
1760
+ fragment.appendChild(document.createTextNode(beforeText));
1761
+ fragment.appendChild(span);
1762
+ if (afterText)
1763
+ fragment.appendChild(document.createTextNode(afterText));
1764
+ textNode.replaceWith(fragment);
1765
+ };
1766
+ const processNode = (node) => {
1767
+ if (node.nodeType === Node.TEXT_NODE) {
1768
+ wrapTextNode(node, 0, (node.textContent || "").length);
1757
1769
  }
1758
- while (currentNode && currentNode instanceof HTMLElement) {
1759
- return currentNode;
1770
+ else if (node.nodeType === Node.ELEMENT_NODE) {
1771
+ const element = node;
1772
+ if (["LI", "P", "DIV", "TABLE", "TD", "TH"].includes(element.tagName)) {
1773
+ element.style.color = color; // Apply directly for block and table elements
1774
+ }
1760
1775
  }
1761
- return null;
1762
1776
  };
1763
- const parentElement = getParentElement(range.commonAncestorContainer) ||
1764
- getParentElement(range.startContainer) ||
1765
- getParentElement(range.endContainer);
1766
- if (!parentElement) {
1767
- console.error("No valid parent element found!");
1768
- return;
1769
- }
1770
- // **Handle Table Cell Case**
1771
- if (parentElement.tagName === "TD") {
1772
- parentElement.style.color = color; // Apply color directly to cell
1773
- return;
1777
+ const startContainer = range.startContainer;
1778
+ const endContainer = range.endContainer;
1779
+ if (startContainer === endContainer &&
1780
+ startContainer.nodeType === Node.TEXT_NODE) {
1781
+ wrapTextNode(startContainer, range.startOffset, range.endOffset);
1774
1782
  }
1775
- // **Handle Normal Text Case**
1776
- const selectedText = selection.toString();
1777
- if (selectedText) {
1783
+ else {
1784
+ const treeWalker = document.createTreeWalker(range.commonAncestorContainer, NodeFilter.SHOW_TEXT, {
1785
+ acceptNode: (node) => {
1786
+ return range.intersectsNode(node)
1787
+ ? NodeFilter.FILTER_ACCEPT
1788
+ : NodeFilter.FILTER_REJECT;
1789
+ },
1790
+ });
1778
1791
  const textNodes = [];
1779
- const walker = document.createTreeWalker(parentElement, NodeFilter.SHOW_TEXT, null);
1780
1792
  let node;
1781
- while ((node = walker.nextNode())) {
1793
+ while ((node = treeWalker.nextNode())) {
1782
1794
  textNodes.push(node);
1783
1795
  }
1784
1796
  for (const textNode of textNodes) {
1785
- const text = textNode.textContent || "";
1786
- const index = text.indexOf(selectedText);
1787
- if (index !== -1) {
1788
- const span = document.createElement("span");
1789
- span.style.color = color;
1790
- span.textContent = selectedText;
1791
- const beforeText = text.slice(0, index);
1792
- const afterText = text.slice(index + selectedText.length);
1793
- const fragment = document.createDocumentFragment();
1794
- if (beforeText)
1795
- fragment.appendChild(document.createTextNode(beforeText));
1796
- fragment.appendChild(span);
1797
- if (afterText)
1798
- fragment.appendChild(document.createTextNode(afterText));
1799
- textNode.replaceWith(fragment);
1800
- break; // Apply only once per selection
1797
+ if (textNode === startContainer) {
1798
+ wrapTextNode(textNode, range.startOffset, textNode.textContent.length);
1799
+ }
1800
+ else if (textNode === endContainer) {
1801
+ wrapTextNode(textNode, 0, range.endOffset);
1802
+ }
1803
+ else {
1804
+ wrapTextNode(textNode, 0, textNode.textContent.length);
1801
1805
  }
1802
1806
  }
1803
1807
  }
1804
1808
  this.savedSelection = null;
1805
1809
  }
1810
+ // Helper method to recursively apply color to all text nodes in a fragment
1811
+ applyColorToContents(node, color) {
1812
+ if (node.nodeType === Node.TEXT_NODE && node.textContent?.trim()) {
1813
+ const span = document.createElement("span");
1814
+ span.style.color = color;
1815
+ span.textContent = node.textContent;
1816
+ if (node.parentNode) {
1817
+ node.parentNode.replaceChild(span, node);
1818
+ }
1819
+ return;
1820
+ }
1821
+ if (node.nodeType === Node.ELEMENT_NODE) {
1822
+ if (node instanceof HTMLLIElement) {
1823
+ const childNodes = Array.from(node.childNodes);
1824
+ childNodes.forEach((child) => {
1825
+ if (child.nodeType === Node.TEXT_NODE && child.textContent?.trim()) {
1826
+ const span = document.createElement("span");
1827
+ span.style.color = color;
1828
+ span.textContent = child.textContent;
1829
+ child.replaceWith(span);
1830
+ }
1831
+ else if (child.nodeType === Node.ELEMENT_NODE) {
1832
+ this.applyColorToContents(child, color);
1833
+ }
1834
+ });
1835
+ }
1836
+ else {
1837
+ const childNodes = Array.from(node.childNodes);
1838
+ childNodes.forEach((child) => this.applyColorToContents(child, color));
1839
+ }
1840
+ }
1841
+ if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
1842
+ const childNodes = Array.from(node.childNodes);
1843
+ childNodes.forEach((child) => this.applyColorToContents(child, color));
1844
+ }
1845
+ }
1806
1846
  setBackgroundColor(event) {
1807
1847
  if (this.savedSelection) {
1808
1848
  const color = event.target.value;