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;...