Selection setters e.g. selection.collapse() implicitly depends on the current bidi level
Categories
(Core :: DOM: Selection, defect, P2)
Tracking
()
People
(Reporter: saschanaz, Assigned: saschanaz)
References
(Blocks 2 open bugs)
Details
Attachments
(2 files, 1 obsolete file)
- Open the attachment
- Click somewhere between
abc
- Wait a bit and see where the caret goes.
- Click somewhere between
אבג
- Wait a bit and see where the caret goes.
Expected: The result should be same; it should go right between abc
and אבג
, as in Blink and WebKit.
Actual: It depends; it goes to the center in step 3 while to the left line end in step 5.
Currently there is at least one real world project that workarounds this with Gecko-specific Selection#caretBidiLevel
.
Assignee | ||
Comment 1•4 years ago
•
|
||
Another repro. Click אבג
and tap left arrow button until it reaches the leftmost position.
Expected: Nothing should happen
Actual: It teleports to the center, returns, then teleports, repeatedly.
Assignee | ||
Updated•4 years ago
|
Updated•4 years ago
|
Assignee | ||
Comment 2•4 years ago
•
|
||
Infinite loop-free replacement, see comment #1.
Assignee | ||
Comment 3•4 years ago
|
||
I think we can't simply remove this behavior unless we want to remove (or at least modify) the concept of bidi caret? Currently the caret on the same logical offset can appear at different places based on bidi caret level, being ambiguous:
אבגabc
^ offset 0 or 3, based on bidi level
^ also offset 0 or 3, based on bidi level
Doing selection.collapse(selection.focusNode, selection.focusOffset)
by definition must not move the caret, but if we remove the dependency on caret bidi level it can move, which could be a web compat problem.
I don't really understand why the current design allows such ambiguity about offset, do you have any thought?
Comment 4•4 years ago
|
||
:saschanaz: don't know off-hand. :jfkthame might.
Comment 5•4 years ago
|
||
The caret position is inherently ambiguous at direction boundaries. Gecko exposes this ambiguity and allows the user to work with it.
Try (in Firefox):
data:text/html;charset=utf-8,<div contenteditable style="font:100px sans-serif">abcdאבגדefgh
Suppose I want to add another Hebrew letter after "ד". The natural place to click, given that the Hebrew text runs right-to-left, is at the left (trailing) edge of the "ד". If I do that, I get a caret blinking between "d" and "ד", and if I then type more Hebrew, it appears there, as expected.
If instead I want to add some more English after the "d", where do I click to place the caret? At the right-hand (trailing) edge of the "d". That again gives me a caret blinking between the "d" and "ד". If I now type more English, it appears there, again as expected.
Trying the same thing in Chrome, it's much harder to add a Hebrew letter after the "ד", because if I click there (just like in Firefox) and get a caret there, where I want to insert more Hebrew text, the text I type will actually appear before the "א" instead. To insert more Hebrew after the current "אבגד" (so appending to the left end of it), I actually have to click and place the caret between the "א" and the "e" on screen.
So the point is that Firefox is attempting to distinguish between a caret position following the Latin letter "d" and a position following the Hebrew letter "ד", even though those two positions in the underlying text map to the same screen position. If I click on the right-hand edge of the "d" and then type, the text I type will be inserted after "d" (and before "א"), whereas if I click on the left-hand edge of the "ד", the text I type will be inserted after "ד" (and before "e"). Chrome, OTOH, is imposing a single interpretation (according to the overall paragraph direction, I believe) on these ambiguous boundary cases, rather than trying to support both possibilities.
Comment 6•4 years ago
|
||
So returning to the original example from comment #0:
Actual: It depends; it goes to the center in step 3 while to the left line end in step 5.
In step 3, the selection collapses to a position immediately preceding the letter "a" (i.e. at offset 3, before the 4th character in the text), so the caret appears before (to the left of) the LTR character "a" (in the middle of the line).
In step 5, the selection collapses to a position immediately following the letter "ג" (also at offset 3, following the 3rd character in the text), so the caret appears after (to the left of) the RTL character "ג" (at the left edge of the line).
Assignee | ||
Comment 7•4 years ago
•
|
||
Thanks Jonathan for the detailed explanation!
Given that our concept of caret bidi level supports better user experience, we probably should try standardizing Selection#caretBidiLevel
instead of removing it (https://github.com/w3c/selection-api/issues/57). Selection#collapse()
won't be able to mock the Gecko behavior without that API. I'll wontfix this and track the process in bug 1623290.
Description
•