Skip to content

fix(a11y): clear stale Loading aria-label + name title controls#153

Open
JohnMcLear wants to merge 1 commit into
mainfrom
fix/a11y-title-aria-7255
Open

fix(a11y): clear stale Loading aria-label + name title controls#153
JohnMcLear wants to merge 1 commit into
mainfrom
fix/a11y-title-aria-7255

Conversation

@JohnMcLear

Copy link
Copy Markdown
Member

Summary

Three accessibility regressions called out in the 2026-05-16 follow-up on
ether/etherpad#7255 (the
screen-reader-inspector screenshots in the issue comment).

1. Stale aria-label=\"Loading...\" on the title anchor

The <a> wrapping the loading text carried data-l10n-id=\"pad.loading\". After
etherpad PR #7584, html10n auto-populates aria-label on any node with a
data-l10n-id, leaving the anchor with aria-label=\"Loading...\" data-l10n-aria-label=\"true\". The three title-swap sites (initial render,
recieveTitleMessage, save click) only cleared data-l10n-id, so the
aria-label stayed \"Loading...\" forever — AT users heard \"Loading...\"
even after the pad title was set (e.g. to \"Test\").

This PR moves data-l10n-id onto an inner <span> so html10n's auto-aria-label
lands on the span (which gets replaced wholesale on title swap) rather than
persisting on the anchor. Centralises the three title-swap sites through a
single applyLiveTitle helper that also defensively strips
aria-label / data-l10n-aria-label off the anchor.

2. Pencil-icon edit button had no accessible name

The edit button was a <div> with no accessible name and no native focus /
Enter / Space handling — AT users couldn't tell it was a button and couldn't
activate it from the keyboard. Promote it to <button type=\"button\"> and
reset its native chrome in CSS so the glyph keeps centering the same way it did
when it was a div.

3. Title input had no associated label

The text input had no label — screen readers announced just \"edit text\".
Add aria-labelledby pointing at a translated visually-hidden span so the
input's accessible name is \"Pad title\".

Same aria-labelledby treatment for the OK save button.

The three new labels are visually hidden via a plugin-scoped
.ep_set_title_sr_only class (clip-rect pattern).

Test plan

  • pnpm run lint
  • Existing title.spec.ts regression test still passes (#pad_title > #title > h1 > a has "JohnMcLear" after save)
  • New "Title-bar elements have accessible names" spec asserts:
    • #edit_title has role=button + aria-labelledby
    • #input_title has aria-labelledby
    • save button has aria-labelledby
    • after a title swap, the anchor has no aria-label, data-l10n-aria-label, or data-l10n-id
  • Manual: open a pad in Firefox/Chrome with the accessibility inspector and confirm the title anchor's accessible name is the pad title (not "Loading...")

Three accessibility regressions called out in the 2026-05-16 follow-up on
ether/etherpad#7255 (the screen-reader-inspector screenshots in the issue
comment):

(1) The <a> wrapping the loading text carried data-l10n-id="pad.loading".
After etherpad PR #7584, html10n auto-populates aria-label on any node
with a data-l10n-id, leaving the anchor with
`aria-label="Loading..." data-l10n-aria-label="true"`. The plugin's three
title-swap sites (initial render, recieveTitleMessage, save click) only
cleared data-l10n-id, so the anchor's aria-label stayed "Loading..."
forever — AT users heard "Loading..." even after the pad title was set
to e.g. "Test".

Move data-l10n-id onto an inner <span> instead of the <a>, so html10n's
auto-aria-label lands on the span (which is replaced wholesale on title
swap) rather than persisting on the anchor. Centralise the three
title-swap sites through a single `applyLiveTitle` helper that also
defensively strips aria-label / data-l10n-aria-label off the anchor in
case an older template version is in play.

(2) The pencil-icon edit button was a <div> with no accessible name and
no native focus / Enter / Space handling — AT users couldn't tell it was
a button and couldn't activate it from the keyboard. Promote it to
<button type="button"> and reset its native chrome in CSS so the glyph
keeps centering the same way it did when it was a div. Same fix for the
OK save button (already <button>, just adds aria-labelledby).

(3) The text input had no associated label — screen readers announced
just "edit text". Add aria-labelledby pointing at a translated
visually-hidden span so the input's accessible name is "Pad title".

The three new labels are visually hidden via a plugin-scoped
.ep_set_title_sr_only class (clip-rect pattern). Adds en.json entries
for the three labels and a regression Playwright spec that asserts both
the aria-labelledby wiring and the absence of stale aria-label
attributes after the title swap.

Refs ether/etherpad#7255

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant