I'm making an editor and I have a DOM structure like
<div id="container" contenteditable=true>
<div id="one">Some fancy text</div>
<div id="two">Some other text</div>
<div id="three">and that's enough!</div>
</div>
In this editor, text written is inside the div 'container' which is a content editable div and then divided in several internal divs, changing while the user writes. In my structure, programmatically, during the webpage life, a lot of divs get added, removed and moved inside 'container', even changing id. I need no extra div block being inside the main divs (the ones with the numeric ids) and so I force programmatically adding a br on pression of a return instead of wrapping text in divs like firefox would normally do.
Due to a problem in Firefox, the caret (cursor) acts really weird and I can't solve the issue.
The problem seems to be known. Firefox solves this putting extra divs in html around the text when a return is pressed.
In my case, avoiding this, the first time you press a return at the end of the last div, the caret moves correctly (if you keep writing, it writes in the correct position on a new line), but displays in a strange position, like at the beginning of the previous line. This happens only at the very end of the last div.
It is shown here too, but proposed solution are not working for me Firefox sets wrong caret position contentEditable with :before
Here you can see the problem showing itself:
window.addEventListener('keydown', function (event) {
if(event.keyCode === 13){
event.preventDefault(); // Ensure it is only this code that runs
console.log("+++ Pressed return and adding a br!");
addHtmlElementAtCursor('br');
return false;
}
});
function keyPress(event) {
}
function addHtmlElementAtCursor(element) {
var sel, range, textNode;
if (window.getSelection) {
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt(0);
range.deleteContents();
if (element==' ') {
textNode = document.createTextNode('\u00A0');
}else{
textNode = document.createElement(element);
}
range.insertNode(textNode);
// Move caret to the end of the newly inserted text node
range.setStartAfter(textNode, textNode.length);
range.setEndAfter(textNode, textNode.length);
sel.removeAllRanges();
sel.addRange(range);
}
} else if (document.selection && document.selection.createRange) {
range = document.selection.createRange();
range.pasteHTML(text);
}
}
<div id="container" contenteditable=true>
<div id="one">some text</div>
<div id="two">some other text</div>
<div id="three">some other other text, try to give a return after the laste e of 'here' -> HERE</div>
</div>