JSFiddle - React, Tailwind, and code Playground

by gibito

HTML

<script src="http://rangy.googlecode.com/svn-history/r527/trunk/currentrelease/rangy-core.js"></script>
<script src="http://rangy.googlecode.com/svn/branches/1point2/src/js/modules/rangy-selectionsaverestore.js"></script>
<div id="area" style="width:100%;height:2em;" 
    contentEditable="true";
    onkeyup="formatText();"
    onclick="formatText();"
    ></div>

CSS

<style type="text/css">
/*demo page css*/
body { font: 80% "Trebuchet MS", sans-serif; margin: 20px;} /* set the right and left margin*/

input, #area {
    width: 75%;
    font-family: monospace;
    font-size: 1.3em;
    border: 2px solid #bbb;
    border-radius: 0.5em;
    padding: 0.2em 0.3em 0.2em 0.4em;
    background-color: transparent;
    outline: none; /* removes dotted outline */
}

table { 
    
    font: 100% "Trebuchet MS", sans-serif; 
    border: 2px solid #bbb;
    border-radius: 0.5em;
    table-layout: fixed; 
}

    
#formulaBarStringTransparent {
    background-color: transparent;
    color: transparent;
    position: relative;
}

#styledInput {
    position: absolute;
    margin-left: 4px;
}


</style>

JavaScript

function saveSelection(containerEl) {
    var charIndex = 0, start = 0, end = 0, foundStart = false, stop = {};
    var sel = rangy.getSelection(), range;
    
    function traverseTextNodes(node, range) {
        if (node.nodeType == 3) {
            if (!foundStart && node == range.startContainer) {
                start = charIndex + range.startOffset;
                foundStart = true;
            }
            
            if (foundStart && node == range.endContainer) {
                end = charIndex + range.endOffset;
                throw stop;
            }
            charIndex += node.length;
            
            
        }  else {
            for (var i = 0, len = node.childNodes.length; i < len; ++i) {
                traverseTextNodes(node.childNodes[i], range);
            }    
        }
    }
    
    
    if (sel.rangeCount) {
        try {
            traverseTextNodes(containerEl, sel.getRangeAt(0));
        } catch (ex) {
            if (ex != stop) {
                throw ex;
            }
        }
    }
    
    
    return {
        start: start,
        end: end
    };
    
    
}



function restoreSelection(containerEl, savedSel) {
    var charIndex = 0, range = rangy.createRange(), foundStart = false, stop = {};
    range.collapseToPoint(containerEl, 0);
    
    function traverseTextNodes(node) {
        if (node.nodeType == 3) {
            var nextCharIndex = charIndex + node.length;
            if (!foundStart && savedSel.start >= charIndex && savedSel.start <= nextCharIndex) {
                range.setStart(node, savedSel.start - charIndex);
                foundStart = true;
            }
            if (foundStart && savedSel.end >= charIndex && savedSel.end <= nextCharIndex) {
                range.setEnd(node, savedSel.end - charIndex);
                throw stop;
            }
            charIndex = nextCharIndex;
        }     
        
        else {
            for (var i = 0, len = node.childNodes.length; i < len;...