Chrome and FireFox behave very differently in terms of what happens when you attempt to select the position before a DIV usingrange.setStartBefore() when the DIV is preceded by a textnode.
Consider the HTML:
<div contenteditable="true" id="edit">foo<div id="test">bar</div></div>
I want to select the end of the textnode foo.. You use a range to accomplish this as in:
// for FireFox make sure the editable div is focused so we can see the cursordocument.getElementById( 'test' ).focus();// select the spot before the DIV.var sel = document.getSelection();var range = document.createRange();var dom_node = document.getElementById( 'test' );// this is the critical methodrange.setStartBefore( dom_node );range.collapse( true );sel.removeAllRanges();sel.addRange( range );// ask the browser what is selectedconsole.log( "selection is :", document.getSelection().getRangeAt(0) );
In Chrome, the resulting range has a startContainer of the textnode and a startOffset of 3, which conveniently points to the just past the o in foo. The cursor moves after foo.
However, in FireFox, the resulting range has a startContainer of the <div> and a startOffset of 1 which means its pointing at the textnode but doesnt give you any indication of where in the textnode its pointing. Also, the cursor moves before the b in bar.
It gets more confusing if the HTML is changed to:
<div contenteditable="true"><div>foo</div><div id="test">bar</div></div>
If the same experiment is run again, FireFox behaves as before and returns the editable <div> with an offset of 1 pointing at the element before <div id=test>, which is the previous DIV. That makes sense The cursor again is placed before the b in bar, which doesnt make sense to me.
In this situation, Chome does is completely unexpected.
The range returned by Chrome
has a startContainer with a textnode with length of 0
andnextSibling or prevSibling that are both null
but a parentNode that is set to the <div id=test>
at least if Chrome Developer Tools are to be believed. I think its time for anotherStackOverflow question. You can see an example of this here.