Skip to content

Commit c328144

Browse files
authored
Translate the line a screen reader says before each announcement (#654)
## Why Before each announcement, a screen reader reads a hidden line that `@wordpress/a11y` adds to the page: "Notifications". The package writes it at DOM-ready, which is before the renderer has loaded its locale from main, so it stayed English in every language. ## What changes Once `loadLocale()` has applied the locale, it writes that line again with `__('Notifications')`, next to where it already sets the window's title. It uses the same msgid as `@wordpress/a11y` and as the notifications region's label, so all three share one translation. If the paragraph were ever created after the locale loads instead, a11y's own `__()` would already be translated, and the null check skips the rewrite. ## How to test this A journey covers it, and it's red without the change: ```bash # from the repository root npm run build:once npx playwright test --project=journeys tests/e2e/journeys/i18n.spec.js -g "first-run screen" ``` The first-run en-XA journey now checks that `#a11y-speak-intro-text` reads `[Ñóţíƒíçáţíóñš~~~~]`. Without the fix it reads "Notifications". To look by hand (any platform, current head): run `npx electron . --lang=en-XA` from the repository root and inspect `#a11y-speak-intro-text` in DevTools. It's bracketed and accented. **What must not have happened:** in English the line still reads "Notifications", and announcements (`speak()`) still work. The full journey suite passes (147/147). ## Risks and limitations None known. The paragraph lives outside `#root`, so React never replaces it, and a11y's `speak()` and `clear()` only toggle its `hidden` attribute. ## Related Fixes #648. Part of #622. --- <details> <summary>Review outcome</summary> **0 [fix here] · 0 [follow-up].** - **Review:** completed by a separate agent with a fresh context, against `.github/instructions/code-review.instructions.md`. Reviewed head d6ce1eb, base 8303849 (trunk). `npm run lint` clean, `npm test` 2078/2078, full journey suite 147/147. - **Checked:** - **Order:** the bundle is loaded with `defer`, so `domReady` runs a11y's `setup()` while it loads, before the locale arrives. The paragraph exists when it's rewritten. - **Duplicates and resets:** the paragraph can't be created twice, and nothing writes English back to it. - **One copy:** there's one copy each of `@wordpress/a11y`, `@wordpress/i18n` and `@wordpress/hooks`, so a11y uses the app's i18n instance. - **Shared msgid:** sharing `'Notifications'` with the toast region's label is correct. - **Module rule:** a fixed DOM write beside `document.title` isn't a decision that belongs in a `.cjs` module. - **Journey:** it waits for the first render, so it can't race the rewrite. - **Style note, not applied:** the test comment says the scans miss the paragraph because it's hidden. It's also outside `#root`, which the scans don't look past. - **Since review:** none. </details> Nothing on screen changes, so there are no screenshots. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
1 parent 249d714 commit c328144

2 files changed

Lines changed: 9 additions & 0 deletions

File tree

‎src/renderer/index.jsx‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2490,6 +2490,11 @@ async function loadLocale() {
24902490
document.documentElement.lang = applyLocale(reply, { setLocaleData, addFilter });
24912491
document.documentElement.dir = textDirection(_x);
24922492
document.title = __('WordPress Contributor Toolkit');
2493+
// @wordpress/a11y wrote the line a screen reader says before each
2494+
// announcement at DOM-ready, before there was a locale, so it is written
2495+
// again in this one (#648).
2496+
const announcementsIntro = document.getElementById('a11y-speak-intro-text');
2497+
if (announcementsIntro) announcementsIntro.textContent = __('Notifications');
24932498
}
24942499

24952500
// The settings load before the first render too, beside the locale (#560):

‎tests/e2e/journeys/i18n.spec.js‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@ test( 'the first-run screen and the create-site dialog are fully translatable',
8080
await expect( createButton ).toBeVisible( { timeout: 30_000 } );
8181
await expect( page.locator( 'html' ) ).toHaveAttribute( 'lang', 'en-XA' );
8282
await expect( page ).toHaveTitle( pseudoLocalize( 'WordPress Contributor Toolkit' ) );
83+
// The line a screen reader says before each announcement, which
84+
// @wordpress/a11y writes before the locale arrives (#648). It is hidden
85+
// until something is announced, so the scans below never see it.
86+
await expect( page.locator( '#a11y-speak-intro-text' ) ).toHaveText( pseudoLocalize( 'Notifications' ) );
8387

8488
// The window with no site in it, and its footer.
8589
expect( await unwrapped( page.locator( '#root' ) ) ).toEqual( [] );

0 commit comments

Comments
 (0)