JSFiddle - React, Tailwind, and code Playground

by isqua

HTML

<div id="input" contenteditable>
<blockquote>
123
<blockquote>
456
<blockquote>
789
</blockquote>
456
</blockquote>
123
</blockquote>
</div>

CSS

#input
{
  background: #fff;
  padding: 20px;
}
blockquote {
  border-left: 2px solid orange;
  padding-left: 10px;
}

JavaScript

var input = document.querySelector('#input');

input.addEventListener('keydown', function(e, data) {
		if (e.keyCode === 13) {
    		e.preventDefault();
    		split();
    }
});

function split() {
    var sel = window.getSelection(),
    		range,
    		textNode,
    		elem;
        
    if (sel.rangeCount) {
    		range = sel.getRangeAt(0);
        textNode = range.commonAncestorContainer;
        elem = textNode.parentNode;
        if (isBlockquote(elem.parentNode)) {
        		splitBlockquote(textNode, range.endOffset, findTopBlockquote(elem));
        }
    }
}

function isBlockquote(elem) {
		return elem.tagName.toLowerCase() === 'blockquote';
}

function findTopBlockquote(elem) {
		while (isBlockquote(elem.parentNode)) {
        elem = elem.parentNode;
    }
    
    return elem;
}

function splitBlockquote(textNode, pos, topBq) {
    var parent = topBq.parentNode,
        parentPos = getNodeIndex(parent, topBq),
        doc = textNode.ownerDocument,
        range = doc.createRange(),
        fragment,
        div = createExtra(div);

    range.setStart(parent, parentPos);
    range.setEnd(textNode, pos);
    fragment = range.extractContents();
    fragment.appendChild(div);
  
    parent.insertBefore(fragment, topBq);
    select(div);
}

function getNodeIndex(parent, node) {
    var index = parent.childNodes.length - 1;
    
    while (index > 0 && node !== parent.childNodes[index]) {
        index--;
    }

    return index;
}

function createExtra(tag) {
		var elem = document.createElement(tag);
    
    elem.innerHTML = '&nbsp;'
    
    return elem;
}

function select(elem) {
		var sel = window.getSelection();
    
    sel.removeAllRanges();
    sel.selectAllChildren(elem);
}