I had a little digging and, unfortunately, I do not see a workaround ... Although one thing I noticed when debugging javascript seems to be the problem with the range object itself, and not with the subsequent range.select() . If you look at the values ββof the range object returned by selection.createRange() , yes, the parent dom object may be correct, but the location information already refers to the beginning of the next line (e.g. offsetLeft / Top, boundingLeft / Top, etc. already wrong).
Based on the information here , here and here , I think you're out of luck with IE, since you only have access to the Microsoft TextRange object, which seems to be broken. From my experiments, you can move the range and position it exactly where it should be, but as soon as you do this, the range object automatically switches to the next line, even if you didn't try .select() it. For example, you can see the problem by putting this code between steps 1 and 2:
if (range.boundingWidth == 0) { //looks like its already at the start of the next line down... alert('default position: ' + range.offsetLeft + ', ' + range.offsetTop); //lets move the start of the range one character back //(ie select the last char on the line) range.moveStart("character", -1); //now the range looks good (except that its width will be one char); alert('one char back: ' + range.offsetLeft + ', ' + range.offsetTop); //calculate the true end of the line... var left = range.offsetLeft + range.boundingWidth; var top = range.offsetTop; //now we can collapse back down to 0 width range range.collapse(); //the position looks right alert('moving to: ' + left + ', ' + top); //move there. range.moveToPoint(left, top); //oops... on the next line again... stupid IE. alert('moved to: ' + range.offsetLeft + ', ' + range.offsetTop); }
So, unfortunately, there doesn't seem to be any way to make sure the range is in the right place when you select it again.
Obviously, there is a trivial fix for your code above by modifying Step 2 as follows:
// Step 2 Restore the selection if (range.select) { if (range.boundingWidth > 0) { range.select(); } } else { selection.removeAllRanges(); selection.addRange(range); doc.body.focus(); }
But, apparently, you really want to do something between Step 1 and Step 2 in your action, which includes moving the selection, therefore, the need to redial it. But just in case. :)
So, the best I can do is go and vote for your mistake ... I hope they fix it.