I'm having an unusual problem with an IE document with contentEditable set to true. Calling select() on a range that is positioned at the end of a text node that immediately precedes a block element causes the selection to be shifted to the right one character and appear where it shouldn't. I've submitted a bug to Microsoft against IE8. If you can, please vote for this issue so that it can be fixed.
https://connect.microsoft.com/IE/feedback/ViewFeedback.aspx?FeedbackID=390995
I've written a test case to demonstrate the effect:
<html>
<body>
<iframe id="editable">
<html>
<body>
<div id="test">
Click to the right of this line ->
<p id="par">Block Element</p>
</div>
</body>
</html>
</iframe>
<input id="mytrigger" type="button" value="Then Click here to Save and Restore" />
<script type="text/javascript">
window.onload = function() {
var iframe = document.getElementById('editable');
var doc = iframe.contentDocument || iframe.contentWindow.document;
// An IFRAME without a source points to a blank document. Here we'll
// copy the content we stored in between the IFRAME tags into that
// document. It's a hack to allow us to use only one HTML file for this
// test.
doc.body.innerHTML = iframe.textContent || iframe.innerHTML;
// Marke the IFRAME as an editable document
if (doc.body.contentEditable) {
doc.body.contentEditable = true;
} else {
var mydoc = doc;
doc.designMode = 'On';
}
// A function to demonstrate the bug.
var myhandler = function() {
// Step 1 Get the current selection
var selection = doc.selection || iframe.contentWindow.getSelection();
var range = selection.createRange ? selection.createRange() : selection.getRangeAt(0);
// Step 2 Restore the selection
if (range.select) {
range.select();
} else {
selection.removeAllRanges();
selection.addRange(range);
doc.body.focus();
}
}
// Set up the button to perform the test code.
var button = document.getElementById('mytrigger');
if (button.addEventListener) {
button.addEventListener('click', myhandler, false);
} else {
button.attachEvent('onclick', myhandler);
}
}
</script>
</body>
</html>
The problem is exposed in the myhandler function. This is all that I'm doing, there is no Step 3 in between the saving and restoring the selection, and yet the cursor moves. It doesn't seem to happen unless the selection is empty (ie. I have a blinking cursor, but no text), and it only seems to happen whenever the cursor is at the end of a text node that immediately precedes a block node.
It seems that the range is still in the correct position (if I call parentElement on the range it returns the div), but if I get a new range from the current selection, the new range is inside the paragraph tag, and that is its parentElement.
How do I work around this and consistently save and restore the selection in internet explorer?