Repository navigation
WEBDEV-9219: Localize the topnav strings - #125
Conversation
Ports ia-topnav out of the iaux monorepo as ia-topnav, with every sub-element namespaced ia-topnav-* so it can't collide with the copies petabox and offshoot still load. element-names.test.ts holds that line: it checks the new names register and that all 17 generic names the old package claims stay free, since both packages load during the migration and a duplicate define throws rather than degrading. Ported from the WEBDEV-9036 branch rather than iaux master, so the uploader and biblio admin sections are here from the start. That PR touches most of what this move carries, so porting master would have meant doing the same work twice. No dependencies added, two dropped. ia-wayback-search only supplied a base class, and importing it registered the generic ia-wayback-search tag as a side effect, so it's one flattened element now. ia-styles only supplied the sr-only block, which is now a shared style in themes. Per-component style modules became inline styles, which is what every other element here does. The shared subnav fragment keeps a plain name at the component root. The user menu and signed-out dropdown returned exactly the base class's styles, and Lit already inherits those, so the overrides are gone. Three things dropped as dead: the ia-icon element, which nothing imported or rendered and which squatted a generic name; a write-only state field on the login button; and the redundant style overrides above. Two bugs came out of the move. Two tests had every assertion commented out, so they passed while checking nothing; both are rewritten against real behavior, taking the component from 52 tests to 94. And the wayback search's desktop icon read a variable nothing sets, with no fallback, so its fill resolved to invalid and painted black against the dark nav. It follows the topnav's own icon color now. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JpyQxVSkZFrWxxGamCcNhY
Four assertions used `to.not.be.undefined` on a querySelector result. querySelector returns null, so they passed whether or not the element was found. Switching them to `to.exist` failed two tests that had never actually run: The wayback test looked for the search inside the web subnav, but the subnav renders the slider and the search sits one level inside that. The selector never matched. The login button test clicked the toggle and expected an active class. The button owns no open state; it reports the click and the parent sets openMenu. Standalone it can never go active. It now checks both halves of that contract, the event on click and the class once openMenu is set. The dropdown-menu test also registered the base class as `dropdown-menu` at module scope, a name element-names.test.ts asserts stays free. Both only passed because vitest isolates each file in its own page, so turning isolation off would have failed one of them depending on load order. The base class is registered nowhere in the source, so the test now mounts it under a tag inside the topnav's own namespace. Also drops a comment that explained the icon fill by contrast with its old package, and moves the wayback search to the getter form of styles that every other element here uses. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JpyQxVSkZFrWxxGamCcNhY
The topnav's :host declares every other color knob, but this one had gone missing, so the nested wayback search read an undefined variable and the desktop glyph painted black. The package README still documents it as var(--grey20), which is what it goes back to. The search keeps a fallback to the topnav's general icon color for the case where it is mounted on its own. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JpyQxVSkZFrWxxGamCcNhY
The fallback only fires when the search is mounted outside a topnav, and in that case none of the topnav's greys are declared either, so a var() fallback is as unresolved as the value it was covering for. fill inherits, so that paints black rather than falling through. A literal is the only fallback that actually does anything there. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JpyQxVSkZFrWxxGamCcNhY
…opnav * origin/main: v0.3.0 (#96) WEBDEV-8969: Migrate radio-player into elements (#86) WEBDEV-8974: Migrate the radio player search handler into elements (#85) WEBDEV-8968: Migrate transcript-view into elements (#84) WEBDEV-8967: Migrate expandable-search-bar into elements (#83) WEBDEV-8966: Migrate scrubber-bar into elements (#82) WEBDEV-8965: Migrate playback-controls into elements (#80) WEBDEV-8964: Migrate waveform-progress into elements (#78) WEBDEV-8963: Migrate audio-element into elements (#77) # Conflicts: # src/elements/index.ts
Vitest writes these under .vitest-attachments when a test attaches an image, so they are run output, not source. main already ignores the directory, but .gitignore only applies to untracked files and these had already been committed here, so the rule never caught them. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DaEr5YT1xpjK5ydNZPvjwx
…opnav * origin/main: 1.1.1 (#118) WEBDEV-9132: Fix Safari image-viewer wide-layout breakpoint (#115) 1.1.0 (#116) WEBDEV-9129: Exclude story files from coverage reporting (#113) WEBDEV-9121: Migrate histogram-date-range into elements (#112) WEBDEV-9130: Exclude nested dist and worktree tests from local runs (#114) v1.0.0 (#111) WEBDEV-9025: Add a CLAUDE.md covering the publish flow (#94) WEBDEV-9063: Typecheck in CI (#107) v0.4.1 (#108) WEBDEV-9066: Guard custom element registration against duplicate defines (#106) v0.4.0 (#99) WEBDEV-9022: Migrate the image viewer into elements (#93)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013RS8ThjiMNiq7HBBAGash1
The topnav is on every page and none of it was translated. It never imported
@lit/localize, so switching to Spanish left the whole header in English,
including the accessible names, which a screen reader then reads in English
over Spanish content.
28 strings across 8 components now go through msg(). Three needed more than a
wrapper:
- ia-topnav-media-button composed its tooltip as `${prefix} ${mediatype} menu`
from a getter returning 'Collapse' or 'Expand'. Word order around the
mediatype differs by language, so that getter becomes a `tooltip` getter
returning one whole phrase per state with the mediatype as a placeholder.
- ia-topnav-primary-nav's user menu tooltip was a ternary over two bare
strings; each branch is its own message now.
- ia-topnav-wayback-search's intro is one sentence carrying both a count and a
link, so it uses msg(html`...`) and the anchor becomes a placeholder rather
than being split across messages.
The mobile donate link's screen reader label also had literal double quotes
inside the span, which were read out as part of the accessible name. They are
gone.
Not in here:
- data/menus.ts holds 132 menu labels, about 97 of them translatable and the
rest collection and product names. Which is which needs a decision per
entry, and buildTopNavMenus() is called by the host rather than at render,
so the labels would freeze at whatever locale was active then. WEBDEV-9221.
- The 15 shared icon constants in assets/img carry their own <title> and
<desc> accessible names and are module-scope html templates, so a msg()
there would resolve once at import. Localizing them means converting them to
functions and updating their 10 call sites, some outside the topnav.
WEBDEV-9222. This is why the hamburger's closed state is localized and its
opened state, which delegates to the shared close icon, is not.
Elements has no lit-localize.json and no @lit/localize-tools, so none of this
extracts yet. Five other components here already call msg() the same way.
Where the translations live is WEBDEV-9218.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HjwDQaR3hvZ8J2PP4117W2
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #125 +/- ##
==========================================
+ Coverage 90.31% 90.41% +0.10%
==========================================
Files 94 94
Lines 3334 3339 +5
Branches 796 799 +3
==========================================
+ Hits 3011 3019 +8
+ Misses 138 137 -1
+ Partials 185 183 -2 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Move only, no behaviour change. In each component the properties come first, then lifecycles, then render, then the helpers, with styles at the bottom. A diff review checked it at the class-member level: every member is byte-identical to before, only its position moved, and instance fields keep their relative order. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HjwDQaR3hvZ8J2PP4117W2
- Combine the small lib helpers into lib/helpers.ts with a test, and drop the unused makeBooleanFromString and the redundant query handler (the wayback search already defaults to the same one). - Add unit tests for the keyboard navigation. - Drop sr-only-styles. The hidden input labels become aria-labels and the mobile donate heart uses ia-sr-only-text. - Inline the desktop subnav and hamburger templates into render. - Build the menus in willUpdate so they're right on the first render. - Default buildTopNavMenus' userid to '' rather than a placeholder and fix its docs. - Tighten the tests Isa flagged and cover localLinks being set. - Add an archive.org font size toggle to the topnav demo. It's on when the topnav is the element being viewed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HjwDQaR3hvZ8J2PP4117W2
… WEBDEV-9219-localize-topnav * origin/WEBDEV-9038-migrate-topnav: WEBDEV-9038: Address review on the topnav migration WEBDEV-9038: Put the topnav components' members in house order # Conflicts: # src/elements/ia-topnav/ia-topnav-login-button.ts # src/elements/ia-topnav/ia-topnav-media-button.ts # src/elements/ia-topnav/ia-topnav-media-subnav.ts # src/elements/ia-topnav/ia-topnav-primary-nav.ts # src/elements/ia-topnav/ia-topnav-save-page-form.ts # src/elements/ia-topnav/ia-topnav-wayback-search.ts # src/elements/ia-topnav/ia-topnav-wayback-slider.ts
The top-level media buttons (Texts, Video, Audio, Software, Images, Donate, More) came from a module-scope array, so their labels would resolve once at import. They are built by a function at render now, and wrapped in msg(). Wayback Machine stays as is, it's a product name. None of the topnav components had @Localized(), so a setLocale() after first render left them in the old language. Every topnav component that calls msg() has it now, including the dropdown menu base class. Two more strings: - The Wayback search's "1 trillion" page count was a default in the module-scope config. It is msg('1 trillion') in the search's render now, used when the host passes no count. The search's own stale '916 billion' default is gone, so it shows the same figure in both places. - The dropdown's "New feature: <title>" callout aria-label was never wrapped. A test with a test-only pseudo-locale switches the locale after first render and checks the media buttons, a component string, the callout label and the page count. It fails if any of the fixes is reverted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N6GtWdx3xKytP8c8CLtpAX
nsharma123
left a comment
There was a problem hiding this comment.
Code and QA review of WEBDEV-9219.
Checks: all 127 topnav tests pass on the PR branch, and typecheck and lint are clean. lit-localize extract over the topnav files gives 37 messages, with placeholders kept for mediatype, screenName and link.title.
QA: the review-app steps all pass in English. The English → Spanish → English round trip on the WEBDEV-9223 demo restores English cleanly. Two topnav strings are still wrong in Spanish; see the inline comments.
The two bugs should be fixed before merge. The XLIFF placeholder note is minor.
…opnav * origin/main: WEBDEV-9276: Add a slow-test check to CI (#141) WEBDEV-9249: Add a language switch to the elements demo (#135) WEBDEV-9226: Set up string extraction and publish locale data (#129) 1.1.5 (#142) WEBDEV-9256: Give the focused-story test room for a slow lazy import (#138) 1.1.4 (#140) WEBDEV-9050: Migrate the donation banner thermometer into elements (#97) 1.1.3 (#139) WEBDEV-9138: Fade between modes instead of swapping (#117) WEBDEV-9214: Remove the package root export (#124) # Conflicts: # src/elements/index.ts
… WEBDEV-9219-localize-topnav * origin/WEBDEV-9038-migrate-topnav: WEBDEV-9276: Add a slow-test check to CI (#141) WEBDEV-9249: Add a language switch to the elements demo (#135) WEBDEV-9226: Set up string extraction and publish locale data (#129) 1.1.5 (#142) WEBDEV-9256: Give the focused-story test room for a slow lazy import (#138) 1.1.4 (#140) WEBDEV-9050: Migrate the donation banner thermometer into elements (#97) 1.1.3 (#139) WEBDEV-9138: Fade between modes instead of swapping (#117) WEBDEV-9214: Remove the package root export (#124)
…edia tooltips The count now reaches the Wayback search when the host supplies its own config, and buildTopNavMenus no longer edits the shared default config. Media button tooltips are whole phrases per menu instead of embedding the internal mediatype key. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SaShDa2UqoyBesN4MLf9pA
The story-template applies settings to the first slotted element, which was a wrapper div, so the Wayback pages archived input never reached ia-topnav. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SaShDa2UqoyBesN4MLf9pA
nsharma123
left a comment
There was a problem hiding this comment.
Re-reviewed 5f544b1 and 6f2fa22, and approving.
- All 131 topnav tests pass; typecheck and lint are clean. Extraction gives 53 messages, all whole phrases.
- Review-app QA passes, including Apply for the Wayback count.
- I checked Spanish with a throwaway test of the offshoot flow: host config plus count, a locale switch, then a host config swap. It passes. The WEBDEV-9223 demo is still pinned to
1.1.3-l10n-demo.2, so it needs a re-pin to show the fix.
FYI, not blocking:
buildTopNavMenusdropped a positional parameter. Nothing calls it outside elements today.- The story's Wayback input placeholder still says "916 billion".
* origin/main: WEBDEV-9051: Migrate the donation form models, currency validator and form section into elements (#98)
* origin/main: 1.1.6 (#145) WEBDEV-9329: Update the Firefox add-on link in ia-topnav (#143) WEBDEV-9241: Add ia-wayback-search-form for the home page Wayback block (#134) WEBDEV-9219: Localize the topnav strings (#125) WEBDEV-9051: Migrate the donation form models, currency validator and form section into elements (#98) WEBDEV-9038: Migrate the topnav into elements (#95)
* origin/WEBDEV-9107-migrate-reviews: 1.1.6 (#145) WEBDEV-9329: Update the Firefox add-on link in ia-topnav (#143) WEBDEV-9241: Add ia-wayback-search-form for the home page Wayback block (#134) WEBDEV-9219: Localize the topnav strings (#125) WEBDEV-9051: Migrate the donation form models, currency validator and form section into elements (#98) WEBDEV-9038: Migrate the topnav into elements (#95)
* origin/WEBDEV-8840-review-service: 1.1.6 (#145) WEBDEV-9329: Update the Firefox add-on link in ia-topnav (#143) WEBDEV-9241: Add ia-wayback-search-form for the home page Wayback block (#134) WEBDEV-9219: Localize the topnav strings (#125) WEBDEV-9051: Migrate the donation form models, currency validator and form section into elements (#98) WEBDEV-9038: Migrate the topnav into elements (#95)
… into WEBDEV-9242-localize-ia-dropdown * origin/WEBDEV-8812-migrate-ia-dropdown: 1.1.6 (#145) WEBDEV-9329: Update the Firefox add-on link in ia-topnav (#143) WEBDEV-9241: Add ia-wayback-search-form for the home page Wayback block (#134) WEBDEV-9219: Localize the topnav strings (#125) WEBDEV-9051: Migrate the donation form models, currency validator and form section into elements (#98) WEBDEV-9038: Migrate the topnav into elements (#95) WEBDEV-9276: Add a slow-test check to CI (#141) WEBDEV-9249: Add a language switch to the elements demo (#135) WEBDEV-9226: Set up string extraction and publish locale data (#129) 1.1.5 (#142) WEBDEV-9256: Give the focused-story test room for a slow lazy import (#138) 1.1.4 (#140) WEBDEV-9050: Migrate the donation banner thermometer into elements (#97) 1.1.3 (#139) WEBDEV-9138: Fade between modes instead of swapping (#117) WEBDEV-9214: Remove the package root export (#124)
Stacked on #95 (WEBDEV-9038), which brings the topnav into elements. Merge that first. This targets its branch and I'll retarget to
mainonce it lands.The topnav is on every page and none of it was translated, including the accessible names, so a screen reader read English over Spanish content.
37 strings across 10 components now go through
msg(), and every topnav component that callsmsg()has@localized(), so a locale switch after first render re-renders them. A few needed more than a wrapper:ia-topnav-media-menu: the top-level buttons (Texts, Video, Audio, Software, Images, Donate, More) came from a module-scope array, which would freeze the labels at import. It's a function called at render now. Wayback Machine stays unwrapped (product name).ia-topnav-media-buttonbuilt its tooltip as${prefix} ${mediatype} menu. Word order differs by language, so it's one whole phrase per state with the mediatype as a placeholder.ia-topnav-primary-nav's user menu tooltip was a ternary over two bare strings. Each branch is its own message.ia-topnav-wayback-search's intro is one sentence with a count and a link, so it usesmsg(html...)with the anchor as a placeholder.defaultTopNavConfig. It'smsg('1 trillion')in the wayback search's render now, used when the host passes no count. The search's own'916 billion'default is gone too.dropdown-menu's "New feature: <title>" callout aria-label wasn't wrapped.Also dropped the literal double quotes inside the mobile donate link's
sr-onlyspan. They were read out as part of the accessible name.Checked
typecheckandlintclean. 861 tests pass.ia-topnav-localization.test.tssets a test-only pseudo-locale after first render and checks the media buttons, a component string, the callout label and the page count. It fails if@localized()is removed or the media menu array goes back to module scope.Not here
data/menus.tsmenu labels. WEBDEV-9221, stacked on this.<title>/<desc>and are module-scopehtmltemplates. WEBDEV-9222. That's why the hamburger's closed state is localized and its opened state, which uses the shared close icon, isn't.WEBDEV-9219: https://webarchive.jira.com/browse/WEBDEV-9219
🤖 Generated with Claude Code
https://claude.ai/code/session_01N6GtWdx3xKytP8c8CLtpAX