Webpage remediation: Node's batch return type, and keyboard-accessible install tabs - #69
Merged
Merged
Conversation
…reader The tab strip carried `role="tablist"`, `role="tab"` and `aria-selected` and nothing else, which is the half of the pattern that describes the widget without making it work. Nothing tied a tab to the panel it controls, so a screen reader had no way to say what the panel belonged to: the tabs now carry `aria-controls` and the panel carries `role="tabpanel"` and `aria-labelledby`. Two of these render on the landing page, so the ids are per-instance. Every tab was in the page's tab sequence, so reaching the code below the strip meant pressing Tab past nine languages, and the arrow keys did nothing. Only the selected tab is reachable with Tab now, and Left, Right, Home and End move between them and wrap, which is what the pattern asks for. The copy button is revealed on hover, which left it invisible and unreachable to anyone driving the page from the keyboard; focus inside the panel now reveals it too. Copy failures were swallowed. A denied clipboard permission, or the page served over plain http, left the button reading "Copy" and nothing on the clipboard. It says "Copy failed" instead, and the result goes through a live region -- without one, a screen reader never hears that the label changed at all.
The Node page carried the WASM shape in two places — a heading and the inline comment. WASM hands back a `Float64Array`; the napi binding returns a plain `Array` of numbers, which is what its own `index.d.ts` declares. A TypeScript reader following the page would type the result as a typed array and reach for `subarray` or `set` on something that has neither. The "NaN during warmup" half was right and stays: napi maps the core's `Option<f64>` to NaN rather than null. Checked the other eight language pages against the real bindings while here — C, C#, Go, Java, Python, R, Rust and WASM all describe what they return.
kingchenc
marked this pull request as ready for review
August 25, 2026 10:42
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.
The marketing-site half of the audit remediation in wickra-lib/wickra#393.
Node's
batchreturns anArray, not aFloat64Array. The Node pagecarried the WASM shape in two places, a heading and an inline comment. WASM hands
back a
Float64Array; the napi binding returns a plainArrayof numbers, whichis what its own
index.d.tsdeclares. A TypeScript reader following the pagewould type the result as a typed array and reach for
subarrayorsetonsomething that has neither. The "NaN during warmup" half was right and stays:
napi maps the core's
Option<f64>to NaN rather than null.The other eight language pages were checked against the real bindings while
there — C, C#, Go, Java, Python, R, Rust and WASM all describe what they return.
The install tabs are usable from a keyboard and a screen reader. Full ARIA
tabs with roving tabindex, Arrow/Home/End, and copy failures reported through a
live region instead of a button that looks like it worked and did nothing.
Unlike the docs PR, nothing here depends on #393 shipping first: the site has no
snippet checks against the core.
vitepress buildrenders clean locally, and thedocumented
import { RSI } from 'wickra'was verified to work against theCommonJS napi module — Node's lexer detects the named exports.
Draft so it lands alongside the rest of the remediation.