fix(editor): keep selections made through the accessibility API - #1245
Open
runjuu wants to merge 1 commit into
Open
fix(editor): keep selections made through the accessibility API#1245runjuu wants to merge 1 commit into
runjuu wants to merge 1 commit into
Conversation
The bubble menu collapses any non-empty selection it did not see the user make with the pointer or keyboard, on the assumption that such a selection was restored from saved view state. That also collapses selections created through the macOS accessibility API (VoiceOver, writing assistants) within one frame, so those tools cannot act on the text they selected. Mark the transaction dispatched by restoreEditorViewState with a meta key and collapse only selections carrying that marker. Every other selection without pointer or keyboard intent still hides the menu but is left alone.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Hi! I'm building Refine, a macOS grammar checker with
offline AI, and I ran into this while testing it against NoteGen. Refine selects the phrase it wants to
replace through the accessibility API, reads the selection back before
pasting, and finds a caret instead. That was surprising enough that I dug in.
What happens
Any selection created through the macOS accessibility API turns into a caret
within one frame of being set. The tool that made the selection can no longer
act on it. This hits every writing assistant that edits text inside other
apps that way, Grammarly's desktop app included, and it hits VoiceOver's text
selection too. In Refine's case the suggestion fails with an "unable to
apply" error.
The bubble menu's intent guard in
bubble-menu.tsxdoes this. It trusts onlyselections it saw the user make with the pointer or keyboard, and it collapses
every other non-empty selection to
selection.toon the assumption that theselection was restored from saved view state at app start or file reopen. An
accessibility client sets the DOM selection without a pointer or key event, so
the guard collapses it before anything can use it.
The change
restoreEditorViewStateintiptap-editor.tsxmarks the transaction thatre-applies the saved selection with a
VIEW_STATE_RESTORE_METAmeta key, inboth the desktop and the mobile branch.
updatePositioninbubble-menu.tsxreads that transaction from thetransactionevent and collapses a selection only when the marker ispresent. A selection without pointer or keyboard intent still hides the
menu, but stays in place.
selection-intent.tsholds the shared meta key.Three files, +25 / -6. Pointer and keyboard selections behave as before, and a
restored selection is still collapsed the way it was.
How to reproduce it
button, and pick the editor. The element should be a Text Area ("text
entry area").
paragraph and confirm.
you asked for, and "Selected Text" is empty.
As a control I ran the same steps on the ProseMirror demo at prosemirror.net
in Safari. The range stays put there, so this is NoteGen's guard rather than
WebKit or ProseMirror.
After the fix
Same steps, and the range stays selected with "Selected Text" showing the
requested characters. I verified this on a local debug build, where Refine's
suggestion now applies instead of failing its selection check.
Notes for review
what it was written for and keeps the menu hidden for a stale restored
selection.
handlePointerStartstill collapses on pointer down. I did not touch thatpath.
while the editor has focus" rule because it keeps the original behaviour
exactly where it was intended and nowhere else. If you would rather handle
it differently, I can rework it.
中文摘要:你好,我在开发 Refine(一款 macOS 上的离线 AI 语法检查工具)时发现了这个问题。通过辅助功能 API 创建的选区会在一帧内被折叠为光标,所有以这种方式在其他应用中编辑文本的写作助手(包括 Grammarly 桌面版)以及 VoiceOver 的文本选择都会受影响,工具因此无法对选中文本进行操作。原因是气泡菜单把所有非鼠标/键盘产生的选区都当作"从视图状态恢复的旧选区"折叠。此修复让恢复选区的事务携带标记,气泡菜单只折叠带标记的选区;鼠标/键盘选区和恢复选区的行为保持不变。