-
Notifications
You must be signed in to change notification settings - Fork 83
fix Firefox arrow navigation bug #683
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
fix Firefox arrow navigation bug #683
Conversation
All contributors have signed the CLA ✍️ ✅ |
recheck |
src/MarkdownTextInput.web.tsx
Outdated
@@ -526,6 +528,15 @@ const MarkdownTextInput = React.forwardRef<MarkdownTextInput, MarkdownTextInputP | |||
onKeyPress(event); | |||
} | |||
|
|||
// Handle ArrowRight for consistent navigation across grapheme clusters (like emojis) on firefox |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Handle ArrowRight for consistent navigation across grapheme clusters (like emojis) on firefox | |
// Handle ArrowRight for consistent navigation across grapheme clusters (like emojis) on Firefox |
src/MarkdownTextInput.web.tsx
Outdated
@@ -526,6 +528,15 @@ const MarkdownTextInput = React.forwardRef<MarkdownTextInput, MarkdownTextInputP | |||
onKeyPress(event); | |||
} | |||
|
|||
// Handle ArrowRight for consistent navigation across grapheme clusters (like emojis) on firefox | |||
if (e.key === 'ArrowRight' && BrowserUtils.isFirefox && !nativeEvent.altKey) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (e.key === 'ArrowRight' && BrowserUtils.isFirefox && !nativeEvent.altKey) { | |
if (BrowserUtils.isFirefox && e.key === 'ArrowRight' && !nativeEvent.altKey) { |
describe('handleFirefoxArrowKeyNavigation', () => { | ||
beforeEach(() => { | ||
jest.clearAllMocks(); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's add a newline here
}); | |
}); | |
const segmenter = new Intl.Segmenter('en', {granularity: 'grapheme'}); | ||
const graphemes = Array.from(segmenter.segment(text)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How long does this step take for longer values (approx 5000 characters)?
Can we somehow avoid allocating an array of graphemes and use the returned iterable instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For inputs ok ~ 0.5 M characters the whole handleFirefoxRightArrowKeyNavigation
takes 40 - 60 ms
. With iterating directly for (const {index, segment} of segmenter.segment(text))
that time is 15 - 30ms
.
For input size of ~ 50K it's 10-20ms
for Array
and 8 - 15 ms
Does not seem like much, but I can change it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While testing noticed that the issue is also present for left arrow when navigating backwards and /or with multiple emojis. Added code and test cases to cover that.
const segmenter = new Intl.Segmenter('en', {granularity: 'grapheme'}); | ||
const graphemes = Array.from(segmenter.segment(text)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For inputs ok ~ 0.5 M characters the whole handleFirefoxRightArrowKeyNavigation
takes 40 - 60 ms
. With iterating directly for (const {index, segment} of segmenter.segment(text))
that time is 15 - 30ms
.
For input size of ~ 50K it's 10-20ms
for Array
and 8 - 15 ms
Does not seem like much, but I can change it
Fixes navigation bug on Firefox, where navigation using arrows over emojis requires 2 key presses.
Screen.Recording.2025-05-21.at.09.55.11.mov
Details
In Firefox, the arrow key navigation treats surrogate pairs (like emojis) as two separate code units, while Chromium browsers treat them as a single character. This discrepancy causes the “double-arrow press” behaviour.
Related Issues
GH_LINK
Manual Tests
Videos
Before
LM_emojis_before.mov
After
LM_emojis_after.mov
Linked PRs