fix(a11y): drop role=textbox / aria-multiline from innerdocbody (#7778)#7782
Conversation
Murphy's 2026-05-16 re-test of #7255 reported "you still can't cycle through the text properly line by line to press links and such". The narrower toolbar/measurement fixes in #7777 don't address this — it's caused by the editor body advertising textbox semantics. role="textbox" + aria-multiline="true" pin NVDA/JAWS into focus mode for the whole pad. In focus mode arrow keys move the caret one character at a time, the P/H/K rotor shortcuts are suppressed, and links don't surface in the links list. That matches Murphy's symptoms exactly. contenteditable="true" by itself is enough to tell AT this is editable. Without the textbox role, NVDA/JAWS browse the content as document-mode HTML — line-by-line arrow nav, headings rotor, links list all return. aria-label / aria-describedby stay so the pad is still announced as "Pad content" with the keyboard hint on focus. This is the lighter alternative to the AT-only read mirror originally sketched in #7778 — ARIA-only, no DOM restructuring, no plugin impact. Refs #7255 #7777
Qodo reviews are paused for this user.Troubleshooting steps vary by plan Learn more → On a Teams plan? Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center? |
Review Summary by QodoRemove textbox role from editor body for AT navigation
WalkthroughsDescription• Removes role="textbox" and aria-multiline="true" from innerdocbody element - These attributes forced NVDA/JAWS into focus mode, hiding links/headings from rotor - Prevented line-by-line arrow navigation through pad content • Retains aria-label and aria-describedby for accessibility announcements • Adds Playwright regression test to ensure attributes remain absent Diagramflowchart LR
A["innerdocbody element"] -->|remove| B["role=textbox"]
A -->|remove| C["aria-multiline=true"]
A -->|keep| D["aria-label=Pad content"]
A -->|keep| E["aria-describedby=editor-keyboard-hint"]
B -->|result| F["AT browses as document"]
C -->|result| F
F -->|enables| G["Line-by-line navigation"]
F -->|enables| H["Rotor access to links/headings"]
File Changes1. src/static/js/ace.ts
|
Code Review by Qodo
Context used 1. Non-retrying attr assertions
|
|
Waiting user testing. |
Summary
role="textbox"andaria-multiline="true"frominnerdocbodyaria-label="Pad content"andaria-describedby="editor-keyboard-hint"Lighter alternative to the AT-only read mirror originally sketched in #7778 — pure ARIA strip, no DOM restructuring, no plugin impact.
Why
Murphy's 2026-05-16 re-test of #7255 said "you still can't cycle through the text properly line by line to press links and such". The narrower fixes in #7777 don't address that — it's the textbox role doing the damage:
role="textbox"+aria-multiline="true"pin NVDA/JAWS into focus mode for the entire pad.contenteditable="true"alone is enough to tell AT this is editable. Without the textbox role, NVDA/JAWS browse the content as document-mode HTML, restoring line-by-line arrow nav and rotor access to headings + links.Acceptance criteria from #7778 — partial
This is the cheap experiment first. If the ARIA strip alone unblocks line / link / heading navigation in real AT, the heavier mirror approach in #7778 isn't needed. If headings still feel flat, we layer
role="paragraph"onto each<div class="ace-line">next.Test plan
innerdocbody does not advertise role=textbox / aria-multiline (#7778)Playwright test passesRefs #7255 #7777
🤖 Generated with Claude Code