Ehsan, Ryosuke, and I agreed in a face-to-face meeting last year that Gecko should stop supporting multi-range selections. I've updated the editing spec accordingly. The major motivations are:
1) No other browser engine supports multiple ranges per selection, and they appear to have no interest in supporting them ever.
2) They're a corner case that absolutely no one is ever going to get right. During testing, web developers will only ever see one range, because the ability to create multiple ranges is only available in Gecko and only works if you know the secret trick to do it. Web apps consistently assume that getRangeAt(0) will return the only range in the selection. Even Gecko code often gets this wrong -- Ehsan had a demo where a certain sequence of actions with a three-range selection would cause the first execCommand() to first affect only the first range, then the second to affect only the second range, then the third to affect only the third. IIRC, he said he had no idea why it happened. If Gecko developers can't get it right, web authors stand no chance.
The feature is just not worth the added complexity and potential for errors. If we want to support selections that aren't contiguous in the DOM, we should use a different API that doesn't make such selections a special case. For instance, something that returns a list of selected nodes. This might be simpler for authors anyway than the current Range business, which is a mess because you can have many different endpoints that are visually the same.
This is pretty disappointing. Having multiple selection support in the editor in particular is going to be increasingly important as we try to drive progress toward web applications on the desktop, where multiple selection is a common feature in applications such as text editors and word processors. Being able to apply styling to a number of ranges of text all at once is inordinately useful (something I do all. the. time, except when working on MDN content, since the browser doesn't support it).
I really would like us to reconsider this decision.
Hmm -- confirmed that LibreOffice supports discontinuous selections. Maybe we should come up with a new (non-Range) API that handles such selections better, instead of removing support entirely.
Note that if you want to select a table column you have to have support for multi-range selections.
A non-Range API might make sense, of course.
A new MultipleRange API, perhaps, or MultiSelection, available on the DOM to handle multiple selections.
It might be sufficient to make it so that only web browser can create a multi-range selection. One of the complexities of supporting multi-range selection is that we let scripts set ranges. If it's only used in situations like selecting table cells, then the degree of freedom drops significantly. Of course, ranges could be mutated directly by scripts so we have to do something about that as well.
Having properly supported multi-range selections exposed to the web with a sane API which wouldn't make them such an edge case that everybody would get wrong will be useful, but there's no spec and no proposal for that yet, as far as I know, and I think that's a discussion not related to the current bug.
I agree with everything that Aryeh said in comment 0. Currently Gecko uses multi-range selections for at least two things, unless I'm forgetting something: table cell selection and other selection types (such as spellchecking, etc.)
For table cell selections, we can stop exposing multiple ranges to the web, but that would technically be lying, so I'm not quite sure what makes sense there. For other selection types, we should probably keep multiple-range selections around internally (unless we come up with a better implementation mechanism), but for the purposes of editing operations, we can stop pretending to handle multi-range selections.
Should I file a bug proposing we look at coming up with an API for multi-range editor selections then?
(In reply to Ehsan Akhgari [:ehsan] from comment #6)
> Currently Gecko uses multi-range selections for at least two things,
> unless I'm forgetting something: table cell selection and other selection types
> (such as spellchecking, etc.)
Gecko supports selecting multiple ranges of content also in non-table contexts,
for example multiple (non-consecutive) spans of text or other content.
(In reply to Mats Palmgren [:mats] from comment #8)
> (In reply to Ehsan Akhgari [:ehsan] from comment #6)
> > Currently Gecko uses multi-range selections for at least two things,
> > unless I'm forgetting something: table cell selection and other selection types
> > (such as spellchecking, etc.)
> Gecko supports selecting multiple ranges of content also in non-table
> for example multiple (non-consecutive) spans of text or other content.
Yes, but we're considering removing them!
Yes, I understand that. I just wanted to complete the picture about our current
support of multiple ranges for others reading this bug.
(In reply to Aryeh Gregor from comment #2)
> Hmm -- confirmed that LibreOffice supports discontinuous selections. Maybe
> we should come up with a new (non-Range) API that handles such selections
> better, instead of removing support entirely.
MS Office (Word) and Open Office (Writer) also support multi-range selections when editing text.
For Firefox, multi-range selections (e.g. of text) can also be printed and copied. Even in simple <textarea> input boxes (like the one where I'm writing this comment), multi-range selections can be copied, cut and deleted.
For Thunderbird composition, multi-range selections are pretty broken, but it would be very desirable to have them working for ux-consistency with all major office word processor applications as mentioned above.
(In reply to Eric Shepherd [:sheppy] from comment #1)
> This is pretty disappointing. Having multiple selection support in the
> editor in particular is going to be increasingly important ...
> I really would like us to reconsider this decision.
(notwithstanding better technical implementations)
Some related discussion starts here:
The real problem here is the API, where Selections virtually always have one range but technically can have more. I'm not convinced that we should stop supporting non-contiguous selections -- just the way they're exposed to scripts is terrible. I think we can come up with a better way.
I think this boils down to the fact that if the browser exposes multi-range selections to the user, then it must handle them throughout its code. That means proper handling in the editing commands, exposing proper APIs to the web apps, etc.
There is also the fact that other browser engines are simply not interested in supporting multi-range selections at all. And I can't really blame them, since implementing them properly is very hard.
I think lying about the selection to the web APIs is OK as long as we limit the ways in which users can create such selections. We definitely would want to prevent selection.addRange to actually add a range. I think we also want to disable doing multi-range selections by holding down Ctrl, as that is something that users are likely to do for editing but not copying, but we'd probably want to keep Ctrl-clicking working to select table cells, as that is useful for copying cells.
We may even want to go to great lengths to prevent Ctrl-clicking cell selection to work on editable tables, to minimize the confusion.
I'm not sure if Boris has seen this discussion, but I'd like to know his thoughts on this as well.
I haven't seen it, but I also don't have strong thoughts on this. I agree it's a hard problem and that selling other UAs on it might be tough. :(
(In reply to Ehsan Akhgari [:ehsan] from comment #14)
> Hmm, why do you think the API is the only problem here?
Because an API that didn't make discontiguous selections a special case would get rid of all the problems. E.g., instead of a selection being made of zero or more ranges, say it's zero or more nodes. Then any processing of the selection contents would require iterating through all the nodes, and in most cases you'd handle discontiguous selections with no extra effort. Obviously this won't quite work, because of CharacterData, and you'd need to handle the cursor separately, and it would require a lot of thought and attention to use-cases to make the API good, but something along those lines might do the trick.
> What should happen
> when a user does select multiple ranges and then performs an editing action
> through execCommand?
If the API is just a list of nodes, for argument's sake, then whether the selection is contiguous doesn't matter.
So for instance, currently for the indent command (and lots of other block commands), we do something like this: extend the range until its endpoints fall on block boundaries. Then do something to all the blocks (e.g., wrap in a <blockquote>). Given this algorithm, working with multiple ranges requires a lot of care. In particular, if you try just applying it sequentially to each range, you might indent the same block several times, if you have a selection like <p>[foo]bar[baz]</p>.
Now suppose you didn't have ranges, just a list of selected nodes. How would you get the same effect? Even if the selection is contiguous, you'd naturally do something like: find the nearest block ancestor of each node, then remove duplicates, then wrap each block in the list. You have to remove duplicates anyway to deal with cases like <p><i>foo</i>[bar<b>baz]</b></p>, which will be given to you as "bar" plus "<b>baz</b>" or such. So then if the selection is not contiguous, the exact same code magically still works.
> What if they trigger an editing action implemented in
> of the ranges)?
The Range-based API is the problem -- that's the whole point. If pages use it, then they're not going to handle discontiguous selections without a lot of extra work. Of course we can't get rid of it, so pages that continue to use it will always have bugs -- I don't think that's avoidable.
> There is also the fact that other browser engines are simply not interested
> in supporting multi-range selections at all. And I can't really blame them,
> since implementing them properly is very hard.
I suspect it wouldn't be so hard if we stopped basing everything on ranges. That may be easier said than done, of course! When I have some free time, I could mock up an API with examples, if you're interested. I've been thinking about this a bit.