Created attachment 504572 [details]
Minimal test case
When editing a contenteditable element, -moz-user-select:all elements are treated as atoms (i.e. single characters) when you delete them, but as totally absent when you navigate with the arrow keys.
When hitting backspace, the following happens (| is the cursor, <atom> is the -moz-user-select:all element):
That's good, and everything makes sense to me there. However, when I hit the left arrow, this happens:
It would be more consistent if after hitting the left arrow, you got "123|<atom>" instead.
In general, I would assume that if it takes me N presses of the backspace key to delete everything, it should also take N presses of the left arrow to get to the beginning.
Attached is a minimal test case that you can play with to see this in action.
Oh, one more thing I just noticed, which is especially weird considering how backspace works. If I press delete, the following happens:
The result should probably be "|123" in this case.
A cross-browser test-case, using contenteditable=false as the atom:
Start before "A" and hit the right arrow key.
IE9: Three presses to get to the end
Firefox 12.0a1 (2012-01-24): Two presses gets to the end
Chrome 17 dev: Three presses gets to the end
Opera Next 12.00 alpha: Behaves weirdly
I don't plan to write a spec for this anytime soon, but IMO IE and WebKit are correct here.
Also, FWIW: I was speaking with a MediaWiki developer working on a Google Docs-style replacement for contenteditable because it's so buggy and inconsistent between browsers. This is one of the problems he cited as a reason not to use contenteditable. The use-case is having non-editable atoms in text, like the 's and s here (link may go stale):
Any news on this? Or, failing that, a pointer of where to start looking so I can fix it myself?
I have not had a chance to work on this yet. It would be great if you can, Jim!
To get started, I suggest you set a breakpoint on nsFrameSelection::MoveCaret, open the test case, place the caret after the user-select:all section for example (using the mouse so that the breakpoint doesn't get triggered needlessly), and then press Left. Now you should break inside the debugger, where you need to step through the caret navigation code to see what's going wrong.
Please let me know if you need help. Thanks!