If you set the editable div style to "display:inline-block; white-space: pre-wrap" you don't get new child divs when you enter a new line, you just get LF character (i.e. 
);.
function showCursPos(){
selection = document.getSelection();
childOffset = selection.focusOffset;
const range = document.createRange();
eDiv = document.getElementById("eDiv");
range.setStart(eDiv, 0);
range.setEnd(selection.focusNode, childOffset);
var sHtml = range.toString();
p = sHtml.length;
sHtml=sHtml.replace(/(\r)/gm, "\\r");
sHtml=sHtml.replace(/(\n)/gm, "\\n");
document.getElementById("caretPosHtml").value=p;
document.getElementById("exHtml").value=sHtml;
}
_x000D_
click/type in div below:
<br>
<div contenteditable name="eDiv" id="eDiv"
onkeyup="showCursPos()" onclick="showCursPos()"
style="width: 10em; border: 1px solid; display:inline-block; white-space: pre-wrap; "
>123 456 789</div>
<p>
html caret position:<br> <input type="text" id="caretPosHtml">
<p>
html from start of div:<br> <input type="text" id="exHtml">
_x000D_
What I noticed was when you press "enter" in the editable div, it creates a new node, so the focusOffset resets to zero. This is why I've had to add a range variable, and extend it from the child nodes' focusOffset back to the start of eDiv (and thus capturing all text in-between).