JSFiddle - React, Tailwind, and code Playground

by timdown

HTML

<script src="http://rangy.googlecode.com/svn/trunk/currentrelease/uncompressed/rangy-core.js"></script>
<div contenteditable="true">
    "Hello "
    <button contenteditable="false" data-id="147" id="nonEditable">@John Smith</button>
    " "
</div>

JavaScript

document.onkeypress = function(e) {
    e = e || window.event;
    var keyCode = e.which || e.keyCode;
    if (keyCode !== 8) {
        return;
    }
    
    var sel = rangy.getSelection();
    if (sel.rangeCount === 0) {
        return;
    }
    
    var selRange = sel.getRangeAt(0);
    if (!selRange.collapsed) {
        return;
    }
    
    var nonEditable = document.getElementById("nonEditable");
    if (!nonEditable) {
        return;
    }
    
    // Check the caret is located after the non-editable element
    var range = rangy.createRange();
    range.collapseAfter(nonEditable);
    
    if (selRange.compareBoundaryPoints(range.START_TO_END, range) == -1) {
        return;
    }
    
    // Check whether there is any text between the caret and the non-editable element.
    // If not, delete the element and move the caret to where it had been
    range.setEnd(selRange.startContainer, selRange.startOffset);
    if (range.toString() === "") {
        selRange.collapseBefore(nonEditable);
        nonEditable.parentNode.removeChild(nonEditable);
        sel.setSingleRange(selRange);
        
        // Prevent the default browser behaviour
        return false;
    }
};