JSFiddle - React, Tailwind, and code Playground

by adil_invideo

HTML

<div id="content" contenteditable="true">
  This is going
  <span class="highlight_string">to be</span>
  fun
</div>
<button id="split_btn">
Split
</button>

CSS

.highlight_string{
  color: orange;
}

TypeScript

const contentEditableDiv = document.getElementById('content');
const content = contentEditableDiv.innerHTML;
console.log(content);
const parsed = new DOMParser().parseFromString(content, 'text/html');
console.log(parsed.body.firstChild.innerHTML);

function getSplitter() {
  const splitter = document.createElement('div');
  splitter.id = 'splitter';
  splitter.style.display = 'none';
  return splitter;
};

function hasSelection() {
  return document.getSelection();
}

function repairText(content: string) {

  const openingTag = "<span class=\"highlight_string\">";
  const closingTag = '</span>';

  const matches1 = content.match(/<span class=\"highlight_string\">/g);
  const matches2 = content.match(/<\/span>/g);

  const count1 = matches1 === null ? 0 : matches1.length;
  const count2 = matches2 === null ? 0 : matches2.length;

  if (count1 === count2) return content;

  // time to repair
  if (count1 > count2) {
    return content + closingTag;
  }

  if (count2 > count1) {
    return openingTag + content;
  }

  return content;
};

function split(content: string) {
  if (!hasSelection()) throw new Error('No selection');
  const splitter = getSplitter();
  const splitIdentifier = splitter.outerHTML;
  console.log('splitIdentifier', splitIdentifier);
  document.getSelection().getRangeAt(0).insertNode(splitter);
  const splitText = contentEditableDiv.innerHTML
    .split(splitIdentifier).map(repairText);
  splitter.parentNode.removeChild(splitter);
  return splitText;
};

document.getElementById('split_btn').onclick = () => {
  const data = split(contentEditableDiv.innerHTML);
  console.log('SPLIT', data);
};