Closed Bug 1689739 Opened 4 years ago Closed 4 years ago

Selection setters e.g. selection.collapse() implicitly depends on the current bidi level

Categories

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

defect

Tracking

()

RESOLVED WONTFIX

People

(Reporter: saschanaz, Assigned: saschanaz)

References

(Blocks 2 open bugs)

Details

Attachments

(2 files, 1 obsolete file)

Attached file bug1623290-2.html
  1. Open the attachment
  2. Click somewhere between abc
  3. Wait a bit and see where the caret goes.
  4. Click somewhere between אבג
  5. 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.

Attached file bug1623290-3.html (obsolete) —

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: nobody → krosylight
Severity: -- → S3
Priority: -- → P2
Attached file bug1623290-3.html

Infinite loop-free replacement, see comment #1.

Attachment #9200146 - Attachment is obsolete: true

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?

Flags: needinfo?(mbrodesser)
Flags: needinfo?(masayuki)

:saschanaz: don't know off-hand. :jfkthame might.

Flags: needinfo?(mbrodesser) → needinfo?(jfkthame)

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.

Flags: needinfo?(jfkthame)

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).

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.

Status: NEW → RESOLVED
Closed: 4 years ago
Flags: needinfo?(masayuki)
Resolution: --- → WONTFIX
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: