Skip to content

Commit 172ea28

Browse files
committed
Rename Navigation to Movement for consistency, update feature flag name
1 parent 6085b1c commit 172ea28

1 file changed

Lines changed: 29 additions & 21 deletions

File tree

Editing/bidi-visual-order-caret-navigation-explainer.md renamed to Editing/bidi-visual-order-caret-movement-explainer.md

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
# Visual Order Caret Navigation for Bidirectional Text
1+
# Visual Order Caret Movement for Bidirectional Text
22

33
## Authors
44

55
- Samba Murthy Bandaru (sambamurthy.bandaru@microsoft.com)
66

77
## Participate
8-
- Feature request: [Visual order caret navigation for bidi text](https://issues.chromium.org/issues/499819853)
8+
- Feature request: [Visual-order caret movement for bidi text](https://issues.chromium.org/issues/499819853)
99
- Spec: [Selection API -- `Selection.modify()`](https://w3c.github.io/selection-api/#dom-selection-modify)
1010
- [Chromium editing-dev group](https://groups.google.com/a/chromium.org/g/editing-dev)
1111

@@ -21,7 +21,7 @@
2121
- [Non-Goals](#non-goals)
2222
- [Proposed Solution](#proposed-solution)
2323
- [The API Surface](#the-api-surface)
24-
- [Feature Activation](#feature-activation)
24+
- [Feature Activation and Rollout Plan](#feature-activation-and-rollout-plan)
2525
- [Privacy and Security Considerations](#privacy-and-security-considerations)
2626
- [Performance Impact](#performance-impact)
2727
- [Interoperability](#interoperability)
@@ -48,7 +48,7 @@ This makes the current caret movement visually inconsistent:
4848

4949
This behavior is confusing and disorienting, particularly for users who routinely work with bidirectional content.
5050

51-
This explainer proposes implementing **visual caret navigation** in Chromium -- arrow key movement that always follows the on-screen direction, so that Right moves the caret rightward and Left moves it leftward regardless of text or line direction. The feature will be gated behind a feature flag for incremental rollout.
51+
This explainer proposes implementing **visual caret movement** in Chromium -- arrow key movement that always follows the on-screen direction, so that Right moves the caret rightward and Left moves it leftward regardless of text or line direction. The feature will be gated behind a feature flag for incremental rollout.
5252

5353
## The Bidirectional Text Problem
5454

@@ -88,31 +88,33 @@ Visual movement solves this by moving the caret based on its **screen position**
8888

8989
## Goals
9090

91-
1. **Provide visual caret movement** — Right always moves rightward, Left always moves leftward — matching the mental model that user research confirms almost all participants expect.
91+
1. **Provide visual caret movement** — Right always moves rightward, Left always moves leftward — matching the mental model that most users of bidirectional text would expect.
9292

9393
2. **Predictable caret behavior at bidi boundaries** — The caret should move smoothly in the arrow key's direction when crossing between LTR and RTL text runs.
9494

9595
3. **Align with Firefox and Safari,** which already use visual caret movement by default.
9696

9797
4. **Gate behind a feature flag** for safe incremental rollout, with no behavior change for users who do not opt in.
9898

99-
5. **Correctly handle all bidi scenarios**: simple LTR/RTL boundaries, multiple bidi runs, nested bidi embeddings, bidi control characters, CSS `direction`/`unicode-bidi` overrides, and cross-line navigation.
99+
5. **Correctly handle all bidi scenarios**: simple LTR/RTL boundaries, multiple bidi runs, nested bidi embeddings, bidi control characters, CSS `direction`/`unicode-bidi` overrides, and cross-line movement.
100100

101101
## Non-Goals
102102

103103
1. **Changing selection extension behavior.** Shift+Arrow selection operates on logical DOM offsets. True visual selection across bidi boundaries would require multi-range selection support in Chromium, which does not exist today. This is a potential future extension but is out of scope.
104104

105105
## Proposed Solution
106106

107-
When the `BidiVisualOrderCaretNavigation` feature flag is enabled, Chromium's arrow key handling switches to visual (screen-order) caret movement. The implementation works by leveraging Blink's existing inline layout fragments, which are already stored in visual display order after bidi reordering. This allows the algorithm to walk through text in the order it appears on screen rather than the order it is stored in memory.
107+
When the `BidiVisualOrderCaretMovement` feature flag is enabled, Chromium's arrow key handling switches to visual (screen-order) caret movement. The implementation works by leveraging Blink's existing inline layout fragments, which are already stored in visual display order after bidi reordering. This allows the algorithm to walk through text in the order it appears on screen rather than the order it is stored in memory.
108108

109109
At a high level:
110110

111111
1. When a user presses an arrow key, the caret's current position is resolved to the layout fragment it belongs to.
112-
2. The caret advances in the visual direction within that fragment. For LTR text, moving right increments the position; for RTL text, moving right decrements it.
112+
2. The caret advances in the visual direction within that fragment. For LTR text, moving right increments the position; for RTL text, moving right decrements it — in both cases the caret moves rightward on screen.
113113
3. When the caret reaches the edge of a fragment, it uses the **bidi level** of the current and adjacent fragments to determine which edge to enter — ensuring the caret crosses bidi boundaries smoothly without jumping.
114114
4. At line boundaries, the caret moves to the next or previous line as expected.
115115

116+
Word-level movement (Ctrl+Left/Right on Windows, Option+Left/Right on macOS) and `Selection.modify()` with `'word'` granularity also follow the same visual direction.
117+
116118
## The API Surface
117119

118120
The existing [`Selection.modify()`](https://w3c.github.io/selection-api/#dom-selection-modify) API already distinguishes visual and logical directions:
@@ -129,27 +131,33 @@ selection.modify('move', 'backward', 'character');
129131

130132
With this feature enabled, `'left'` and `'right'` will perform true visual movement in bidi text, while `'forward'` and `'backward'` will continue to perform logical movement. This matches the behavior of Firefox and Safari.
131133

132-
## Feature Activation
134+
## Feature Activation and Rollout Plan
133135

134136
The feature is currently gated behind a disabled-by-default runtime flag:
135137

136-
- **Command line:** `--enable-blink-features=BidiVisualOrderCaretNavigation`
137-
- **Rollout plan:** A `chrome://flags` entry, followed by enabling by default.
138+
- **Command line:** `--enable-blink-features=BidiVisualOrderCaretMovement`
138139

139-
## Privacy and Security Considerations
140+
**Rollout phases:**
141+
142+
1. **Phase 1 (current):** Feature flag disabled by default. Developers and testers can opt in via the command-line flag above.
143+
2. **Phase 2:** Expose a `chrome://flags` entry so that users can enable visual caret movement without command-line flags.
144+
3. **Phase 3:** Enable by default for all users.
140145

141-
This feature introduces no new privacy or security concerns.
146+
Until the feature is enabled, caret behavior remains unchanged — existing logical movement continues to work exactly as it does today. No user-visible changes occur without explicit opt-in during Phases 1 and 2.
142147

143-
- **No new APIs that expose user information.** The `Selection.modify()` API already exists; this feature changes the behavior of existing direction parameters, not the API surface.
144-
- **Feature flag gated.** The feature is disabled by default and requires explicit opt-in during the experimental phase.
148+
## Privacy and Security Considerations
149+
150+
This feature introduces no new privacy or security concerns. The `Selection.modify()` API already exists; this feature changes the behavior of existing direction parameters, not the API surface. No new APIs are introduced and no user information is exposed.
145151

146152
## Performance Impact
147153

148154
This feature introduces minimal overhead. Each caret movement requires one additional lookup to resolve the visual position from the layout fragments, which is negligible.
149155

150156
## Interoperability
151157

152-
This feature aligns Chromium with the default behavior of both Firefox (Gecko) and Safari (WebKit), which use visual caret movement for bidirectional text. Chrome is currently the only major browser that uses logical movement by default. By adopting visual caret movement, this feature improves cross-browser consistency for developers and users working with bidirectional content. The existing [`Selection.modify()`](https://w3c.github.io/selection-api/#dom-selection-modify) API semantics for `'left'`/`'right'` directions are preserved and made consistent with their documented visual behavior.
158+
This feature aligns Chromium with the default behavior of both Firefox (Gecko) and Safari (WebKit), which use visual caret movement for bidirectional text. Chrome is currently the only major browser that uses logical movement by default. By adopting visual caret movement, this feature improves cross-browser consistency for developers and users working with bidirectional content.
159+
160+
The [`Selection.modify()`](https://w3c.github.io/selection-api/#dom-selection-modify) API already defines `'left'`/`'right'` as visual directions and `'forward'`/`'backward'` as logical directions. Currently in Chromium, `'left'`/`'right'` behave the same as `'forward'`/`'backward'` (logical movement). With this feature enabled, `'left'`/`'right'` will perform true visual movement, making their behavior consistent with the spec and with Firefox and Safari.
153161

154162
Beyond browsers, visual caret movement is also the default in macOS native text editing (TextKit) and GTK on Linux, and is an option in Microsoft Word.
155163

@@ -159,21 +167,21 @@ No alternatives were considered. Visual caret movement is the established defaul
159167

160168
## Standards Position
161169

162-
- **W3C:** No specification mandates logical or visual caret movement. The CSS Text Module and the `Selection` API leave movement behavior to UA implementation.
163-
- **WHATWG:** The `Selection.modify()` method's `'left'`/`'right'` parameters are already defined as visual directions, distinct from `'forward'`/`'backward'` (logical). This feature makes `'left'`/`'right'` behave consistently with their documented semantics.
170+
- **W3C:** No specification mandates logical or visual caret movement. The CSS Text Module and the Selection API leave movement behavior to UA implementation. However, the [`Selection.modify()`](https://w3c.github.io/selection-api/#dom-selection-modify) method's `'left'`/`'right'` parameters are already defined as visual directions, distinct from `'forward'`/`'backward'` (logical). This feature makes `'left'`/`'right'` behave consistently with their documented semantics.
164171

165172
## Target Users
166173

167174
- Users who create or consume content in bidirectional scripts (Arabic, Hebrew etc.)
168175
- Web developers building multilingual editing experiences
169176
- Accessibility users who rely on consistent and predictable caret behavior
170177

171-
User research with Arabic–English bilingual users confirms that almost all participants expect visual caret movement — Left always moves left, Right always moves right — regardless of script direction.
178+
An unmoderated usability study with Arabic–English bilingual users found that the overwhelming expectation is visual caret movement — Left always moves left, Right always moves right — regardless of script direction.
172179

173180
## References
174181

175182
1. **Unicode Bidirectional Algorithm (UAX #9):** https://unicode.org/reports/tr9/
176-
2. **WHATWG Selection API -- `Selection.modify()`:** https://w3c.github.io/selection-api/#dom-selection-modify
183+
2. **W3C Selection API -- `Selection.modify()`:** https://w3c.github.io/selection-api/#dom-selection-modify
177184
3. **Firefox `bidi.edit.caret_movement_style` preference:** https://kb.mozillazine.org/bidi.edit.caret_movement_style
178185
4. **macOS TextKit 2 — NSTextSelectionNavigation:** https://developer.apple.com/documentation/uikit/nstextselectionnavigation/direction
179-
5. **Chromium M76 visual navigation removal:** https://crbug.com/972750, https://crbug.com/834765
186+
5. **Chromium M76 switch to logical caret movement:** [PSA: Changing Left/Right Caret Movement from Visual to Logical](https://groups.google.com/a/chromium.org/g/blink-dev/c/Rm1CGy6RBAI/m/uYN8IiZlCgAJ)
187+
6. [[Research findings] Bidirectional text editing](https://microsoftapc-my.sharepoint.com/:w:/g/personal/prashasingh_microsoft_com/IQBmQdITYWCYRqBUtV0ygufVAc_2_w2NVqNE5-fvB3pxIxg?e=wcaccI)

0 commit comments

Comments
 (0)