Open Bug 339400 Opened 19 years ago Updated 4 years ago

Collapse multiple selection controllers into one

Categories

(Core :: DOM: Selection, defect, P5)

defect

Tracking

()

People

(Reporter: pkasting, Unassigned)

References

(Blocks 2 open bugs)

Details

A document may have many selection controllers: one to handle selections in all non-editable areas, and then a separate controller for each editable area. However, there is (according to roc) supposed to be an invariant that we only have one non-empty selection (normal selection, at least; I'm ignoring spellchecking etc.) in the document at one time. This selection may hold multiple ranges, but there shouldn't be multiple selection controllers holding non-empty normal selections. The current many-controller design makes this invariant difficult to maintain, and the controllers don't seem to go out of their way to enforce it. There also seems to be no way to query a document to find what the "one existing selection" is, as if that selection is on an editable area's selection controller you just get nothing from the appropriate funciton calls. (Sadly, my filing this from home means I don't have the list of those calls in front of me, but think of things like GetSelection()). Without yet understanding the selection controller model well enough, it seems like two ways to maintain the invariant better would be: (a) Slave all editable selection controllers to the document's "master" selection controller and have everyone notify each other properly when something changes (b) Get rid of all the editable elements' selection controllers and just use one selection controller for everything. Either of these would be a HUGE boon in the typeaheadfind code, where searching in editable content (bug 189039) is made extremely difficult by the hairy selection/focus issues here. This would also aid web developers with problems such as http://www.squarefree.com/2006/05/06/finding-the-textarea-selection/ . It might also make bug 339398 "just work".
Blocks: 339398
See also some discussion on the (now INVALID) bug 336936.
Blocks: 85686
Comment #0 solution (a) is probably easier to implement. I've been doing some thinking on how to pull this off. There are at least a couple general ways I can see: (1) Keep the selection controllers tied to each other in a tree structure (2) Keep a master pointer to the "current" selection controller, and provide an easy way of finding this value from inside a given selection controller. In either case, what we probably want to do is remove any selection-modifying code from focus/blur handlers, and instead have the current selection collapse any time the cursor moves or another selection has a range added to it. I think selection controllers in chrome (the URL bar, search box, etc.) should be tied into this system too. What seems tricky to me about all this is handling tabs. When the user makes a selection in one tab, changes tabs, and makes a new seelction, should the old selection cancel? It would make the UI easier and more consistent if it did, but I suspect most people's reaction is "no, it shouldn't". Consider how to deal with the following cases, then: (1) Select text, switch tabs, select in URL bar. Now switch back. What happens? I think the only solution we can do here is a hack that says "when switching tabs, collapse any selections in chrome". This duplicates the current behavior (that is accomplished via focus/blur). Otherwise, we either need to pick a selection to cancel once we've switched back, or break the "one selection at a time" invariant. (2) Select text, switch tabs, select more text. Now select text in another X windows app. Now switch back to the first tab. What happens? Even if bug 339397 is fixed (which I hope it will be), this will effectively expose another instance of it: Firefox shows some selected text that isn't actually middle-click-pasteable. I suppose the fix for 339397 could be to cancel all selections in all tabs, but I'm not sure how to set this up in code... I don't want to make Gecko depend on the XUL layout. **** I'd also like to note a design roc proposed in bug 336936 comment #19: "For each top-level window, only display the selection associated with focus." ...This is a little closer to what we try to do now than what I'm proposing, but it has the glaring deficiency that it breaks FAYT, which has to be able to display a selection in an unfocused area.
CCing Hixie in hopes he can contribute to design/intended behavior in the context of the WHATWG specs (specifically, Web Applications section 5.5).
As far as WHATWG is concerned, you should follow platform conventions. If the platform has only one concept of selection, then you should have only one selection. If each widget is able to have its own selection, then each widget should have its own selection. Etc. The APIs in 5.5 merely reflect whatever the actual selection(s) is (or are), whether it is possible to actually set two selections or not is up to the platform. (Which means it could defer across platforms, too -- in particular, I don't think Mac OS X and Windows XP have the same semantics here.)
It looked to me like 5.5 was reverse-engineered from some of the existing Firefox design, such as having a selection for the document and then one for each input/textarea. I don't know what the various platforms' conventions for selection are, I'll have to investigate.
Note: we definitely break roc's proposed invariant right now. All kinds of selection controllers hold non-empty selections simultaneously, and we just do tricks with hiding them on blur to make it look as if there's one selection. See bug 339398 for a patch that exposes this.
OS: Linux → All
Hardware: PC → All
Assignee: selection → nobody
QA Contact: selection
Whiteboard: [feature] p=0
No longer blocks: fxdesktopbacklog
Flags: firefox-backlog+
Whiteboard: [feature] p=0 → p=0
Flags: firefox-backlog+ → firefox-backlog-
Whiteboard: p=0

Bulk-downgrade of unassigned, >=5 years untouched DOM/Storage bugs' priority and severity.

If you have reason to believe this is wrong, please write a comment and ni :jstutte.

Severity: normal → S4
Priority: -- → P5
You need to log in before you can comment on or make changes to this bug.