Adding a tooltip containing the word muted makes lint treat an unmuted video as muted. This suppresses both video_missing_muted and video_audio_double_source, although audio behavior has not changed.
Reproduction
From the repository root:
cat > /tmp/hf-d1.ts <<'TS'
const { lintHyperframeHtml } = await import(`${process.cwd()}/packages/lint/src/hyperframeLinter.ts`);
const wrap = (body: string) => `<html><body><div id="main" data-composition-id="main" data-no-timeline data-width="1920" data-height="1080" data-duration="10">${body}</div></body></html>`;
for (const title of ["", ' title="an unmuted muted clip"']) {
const html = wrap(`<video id="v" class="clip"${title} src="a.mp4" data-start="0" data-duration="3"></video><audio id="a" src="a.mp4" data-start="0" data-duration="3"></audio>`);
console.log(title || "without title", (await lintHyperframeHtml(html)).findings.map((f: {code: string}) => f.code));
}
TS
bun /tmp/hf-d1.ts
Observed:
without title [ "video_missing_muted", "video_audio_double_source" ]
title="an unmuted muted clip" []
Expected: both inputs produce the same two diagnostics. A word inside title is not a muted attribute.
Scope and suggested approach
hasAttrName regex-searches the raw attribute text, including quoted values. Replace that check with existing parsed attributes or quote-aware attribute-name detection. Preserve HTML Boolean semantics: muted, muted="", and even muted="false" are present attributes. Do not change runtime playback behavior or unrelated diagnostics.
Add cases to media.test.ts.
Acceptance criteria
- Text within a single- or double-quoted attribute value cannot impersonate
muted, crossorigin, or other names checked by this helper.
- Real bare/valued Boolean attributes and case-insensitive HTML attribute names retain their existing behavior.
- The reproduction yields the two expected errors both with and without the tooltip.
- Existing media-rule tests pass.
Estimated difficulty: easy. Reviewer/mentor: pending.
Related work
No matching active implementation found in the checked inventory. Issue #2775 concerns missing narration ledger entries and speech seam placement, not quoted-attribute parsing. Keep the scope in this helper; do not take over that audio-pipeline issue.
Validation
From a dependency-installed repository checkout, run the reproduction above with Bun. It imports source directly and does not need real media files, Chrome, or FFmpeg. Add regression cases in the linked existing suite, then run:
bun run --cwd packages/lint test src/rules/media.test.ts
bunx oxlint packages/lint/src/rules/media.ts packages/lint/src/rules/media.test.ts
bunx oxfmt --check packages/lint/src/rules/media.ts packages/lint/src/rules/media.test.ts
Discovery ran the minimal source-level reproduction, not the full test suite or a video render. Reproduced on fa4261beea63bb4f36ff6a2f20fb4646fae3f2c6 (0.8.68); relevant source is unchanged on origin/main at 86fa10ced4297bfd9f4fe67b6767afae7a07fd3c (0.8.69).
Overlap refresh: checked open issue/PR titles and bodies from the fresh publication inventory on 2026-09-23; no matching active implementation found. Before starting, check the discussion and linked PRs, then comment with your intended approach so ownership can be coordinated.
Adding a tooltip containing the word
mutedmakes lint treat an unmuted video as muted. This suppresses bothvideo_missing_mutedandvideo_audio_double_source, although audio behavior has not changed.Reproduction
From the repository root:
Observed:
Expected: both inputs produce the same two diagnostics. A word inside
titleis not amutedattribute.Scope and suggested approach
hasAttrName regex-searches the raw attribute text, including quoted values. Replace that check with existing parsed attributes or quote-aware attribute-name detection. Preserve HTML Boolean semantics:
muted,muted="", and evenmuted="false"are present attributes. Do not change runtime playback behavior or unrelated diagnostics.Add cases to media.test.ts.
Acceptance criteria
muted,crossorigin, or other names checked by this helper.Estimated difficulty: easy. Reviewer/mentor: pending.
Related work
No matching active implementation found in the checked inventory. Issue #2775 concerns missing narration ledger entries and speech seam placement, not quoted-attribute parsing. Keep the scope in this helper; do not take over that audio-pipeline issue.
Validation
From a dependency-installed repository checkout, run the reproduction above with Bun. It imports source directly and does not need real media files, Chrome, or FFmpeg. Add regression cases in the linked existing suite, then run:
bun run --cwd packages/lint test src/rules/media.test.ts bunx oxlint packages/lint/src/rules/media.ts packages/lint/src/rules/media.test.ts bunx oxfmt --check packages/lint/src/rules/media.ts packages/lint/src/rules/media.test.tsDiscovery ran the minimal source-level reproduction, not the full test suite or a video render. Reproduced on
fa4261beea63bb4f36ff6a2f20fb4646fae3f2c6(0.8.68); relevant source is unchanged onorigin/mainat86fa10ced4297bfd9f4fe67b6767afae7a07fd3c(0.8.69).Overlap refresh: checked open issue/PR titles and bodies from the fresh publication inventory on 2026-09-23; no matching active implementation found. Before starting, check the discussion and linked PRs, then comment with your intended approach so ownership can be coordinated.