In the course of FCKeditor 2.5 and 2.6 development, I've seen many tickets surrounding buggy selection behaviors of browsers, and they take a lot of time and "creativity" to fix. e.g.
#1383 (what I'm working on currently)
#1519 (to be fixed in 2.6.1)
#2103 (newly reported)
#332 (fixed with an ugly hack)
#393 (ugly hack, again)
#534 (more ugly hack)
#539 (yet another ugly hack)
#994 (hack and spam, hack and spam, etc.)
#1005 (spam, hack, sausage, and hack)
#1034 (you know the drill)
#1061
#1663
etc.
This got me thinking... if instead of letting the browser take the caret (or selection) to wherever it pleases that don't necessarily make sense and that we can't really predict... why not control the movement of the cursor ourselves? While its effects may not be immediately obvious to users, it can save us a lot of time on thinking up weird hacks for browser selection bugs, and thus give us more time to fix other issues. The controlled selection idea actually isn't wholly an idea of mine, but something Fred discussed with me back when FCKeditor 2.5 was still being developed. But take this idea closer to reality, I did some more thinking and experiments on the issue.
To seize control of the caret/selection, we need to first stop the browser from moving the caret by itself, or at least know the caret's position is changed after the browser did it. The browser moves the caret or selection in three pathways:
We have complete control over (3), since FCKeditor is the only thing responsible for invoking editor commands. The control over (2) can be seized in Firefox, Safari and Opera, but seemingly not in IE, by the following JavaScript:
Complete control over (1) can be seized in all supported browsers:
Although the mouse control isn't complete, it might turn out to be unnecessary since mouse selection (e.g. dragging a text range) is hard to emulate in JavaScript, and so far most (if not all) of the selection bugs are concerned about keyboard selection only.
#1383 (what I'm working on currently)
#1519 (to be fixed in 2.6.1)
#2103 (newly reported)
#332 (fixed with an ugly hack)
#393 (ugly hack, again)
#534 (more ugly hack)
#539 (yet another ugly hack)
#994 (hack and spam, hack and spam, etc.)
#1005 (spam, hack, sausage, and hack)
#1034 (you know the drill)
#1061
#1663
etc.
This got me thinking... if instead of letting the browser take the caret (or selection) to wherever it pleases that don't necessarily make sense and that we can't really predict... why not control the movement of the cursor ourselves? While its effects may not be immediately obvious to users, it can save us a lot of time on thinking up weird hacks for browser selection bugs, and thus give us more time to fix other issues. The controlled selection idea actually isn't wholly an idea of mine, but something Fred discussed with me back when FCKeditor 2.5 was still being developed. But take this idea closer to reality, I did some more thinking and experiments on the issue.
To seize control of the caret/selection, we need to first stop the browser from moving the caret by itself, or at least know the caret's position is changed after the browser did it. The browser moves the caret or selection in three pathways:
- By the keyboard, e.g. the arrow keys, Enter, Backspace, Delete, PageUp, PageDown, etc.;
- By the mouse, click and drags;
- By editor commands, i.e. document.execCommand().
We have complete control over (3), since FCKeditor is the only thing responsible for invoking editor commands. The control over (2) can be seized in Firefox, Safari and Opera, but seemingly not in IE, by the following JavaScript:
document.addEventListener('mousedown', function(evt){evt.preventDefault();}, false);
Complete control over (1) can be seized in all supported browsers:
document.addEventListener('keydown', function(evt){evt.preventDefault();}, false); // Safari and Firefox document.addEventListener('keypress', function(evt){evt.preventDefault();}, false); // Opera 9.50 document.attachEvent('onkeydown', function(evt){evt.returnValue = false;}); // IE
Although the mouse control isn't complete, it might turn out to be unnecessary since mouse selection (e.g. dragging a text range) is hard to emulate in JavaScript, and so far most (if not all) of the selection bugs are concerned about keyboard selection only.
Re: Managed selection
As of FCKeditor 2.6, we've actually already got some of keyboard caret movements controlled, in $FCKeditor/editor/_source/classes/fckenterkey.js. In particular, most of the behaviors of the Enter key, Shift-Enter, and some of the behaviors of Backspace, Ctrl/Meta-Backspace and Delete are already controlled by the JavaScript logic in FCKeditor.
What we have not yet implemented -
Re: Managed selection
2. Ctrl+Home, Ctrl+End to jump to top/bottom of document
3. Ctrl+Page up/down behaves differently to just page up/down in MSWord, and presumably in other editors. The effect in Word is to make the caret jump to the exact top of each page, rather than just moving a page relative to current position. This wouldn't be the case in FCK since we don't have discrete pages. But perhaps it could jump from one heading to the next?
4. Shift+ any of the above to create a selection from the caret movement.
5. Ctrl+Up/down has a useful behaviour in many editors. It scrolls the document up or down *without moving the caret*. This would be nice to replicate.
6. Does anyone use Eclipse? It lets you use Alt+Up/Down to move the current line or selection up or down within the document. This is often awesome for coding, but probably not so useful in a web content editor... But it's an option that alt+arrows could have a new behaviour attached, assuming the key event can be captured.
7. Cut/copy/paste are obviously all closely related to caret and selection positions (in fact, surely the main reasons why text needs to be selected!) ... so I think they need to be mentioned since they are fairly key to the discussion. As for implementation details, assuming that selection and caret positions are correct, cut/copy/paste will presumably still work as expected...
Some of the above would obviously be new features, rather than just replicating current behaviour. However my thinking is to emulate as many features of desktop editors as possible!
Re: Managed selection
Let me try to summarize the conclusions we had, regarding managed selection, after a nice chatting with Martin on IRC.
Managed selection for objects, like images, tables, rows, columns(!), cells, lists, list items, etc, may be doable. It is important to understand if it is really needed though.
A fully managed selection sytem for text, mainly collapsed selection sounds like a crazy thing to do. I've done a lot of research over it in the past. My conclusion was that we would have the following results:
But, looking at all bugs we have found previously regarding caret position and selection, we could consider handling the following cases:
We could think about an event system for the above actions, observing the browser behavior to them, correcting the results if needed, for those well known selection issues.
The "selection position before key event" is one of the key things. It will help us fixing several known selection problems, like "caret before image" or "caret at the end of a table cell".
So, we also need a set of functions to easily check the contents around a selection, like "what's after/before" or "is start/end of".
And let me paste an important thing I've said on IRC: "Of course, all those event watching and checks must perform like a jet. It can easily become a critical piece of code".
I hope all this makes sense.
Frederico Knabben
CKEditor Project Lead and CKSource Owner
--
Follow us on: Twitter | Facebook | Google+ | LinkedIn