Skip to content

PRO-1168: fix: don't flag .ogg audio as video content in video_present rule#1817

Open
pattonwebz wants to merge 2 commits into
developfrom
william/pro-1168-audio-block-detected-as-video-block-resulting-in-video-is
Open

PRO-1168: fix: don't flag .ogg audio as video content in video_present rule#1817
pattonwebz wants to merge 2 commits into
developfrom
william/pro-1168-audio-block-detected-as-video-block-resulting-in-video-is

Conversation

@pattonwebz

@pattonwebz pattonwebz commented Jul 2, 2026

Copy link
Copy Markdown
Member

Summary

  • The Gutenberg Audio block's Ogg Vorbis sample file (.ogg) was being detected as video content by the video_present rule, because .ogg is also a valid Ogg Theora video extension.
  • .ogg stays in videoExtensions (Ogg can still carry Theora video), but a .ogg match is now only counted as video when it isn't attached to an <audio> element or one of its <source> children.

Test plan

  • Added regression tests reproducing the bug (plain <audio src="....ogg">, the real wp-block-audio figure markup, and a <source> inside <audio>) — confirmed these failed before the fix.
  • Added tests locking in that .ogg still triggers the rule outside an audio container (native <video>, standalone <source>).
  • npx jest --config=./tests/jest/jest.config.js — 847/847 passing, no regressions.

Fixes #1816.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved video detection to avoid falsely flagging .ogg sources that appear within audio contexts (such as audio elements and audio block structures).
    • Continued to flag .ogg when it’s used in actual video-related scenarios, including standalone video sources and <video> elements.
  • Tests
    • Expanded rule coverage with additional .ogg cases to confirm both violations and non-violations across relevant HTML structures.

The Gutenberg Audio block's Ogg Vorbis sample file was being detected
as video because .ogg is also a valid Ogg Theora video extension.
Only treat a .ogg match as video when it isn't attached to an <audio>
element or one of its <source> children.

Fixes #1816, PRO-1168.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 08b6a964-bde4-4ab2-8835-7568a74daf38

📥 Commits

Reviewing files that changed from the base of the PR and between 38c3c23 and e770024.

📒 Files selected for processing (1)
  • src/pageScanner/checks/is-video-detected.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/pageScanner/checks/is-video-detected.js

📝 Walkthrough

Walkthrough

The video detection check now ignores .ogg matches inside <audio> contexts, and the Jest coverage adds .ogg cases for both video and audio paths.

Changes

Ogg Audio Detection Fix

Layer / File(s) Summary
Ogg exclusion logic
src/pageScanner/checks/is-video-detected.js
Adds audio-container detection and skips .ogg video matches for <audio> elements and <source> children of <audio>, while reusing precomputed lowercase source values.
Test coverage for ogg handling
tests/jest/rules/videoElementPresent.test.js
Adds .ogg violation cases for <video> and standalone <source>, plus non-violation cases for <audio>, Gutenberg audio blocks, and <audio>-wrapped <source> elements.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main fix: preventing .ogg audio from being flagged as video in the video_present rule.
Linked Issues check ✅ Passed The changes address #1816 by excluding audio-context .ogg from video detection and adding regression tests for audio blocks.
Out of Scope Changes check ✅ Passed The diff stays focused on the .ogg audio/video detection bug and related tests, with no unrelated changes evident.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch william/pro-1168-audio-block-detected-as-video-block-resulting-in-video-is

Comment @coderabbitai help to get the list of available commands.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request prevents .ogg audio files (such as those in Gutenberg Audio blocks) from being incorrectly flagged as video content by ensuring that .ogg matches are only counted as video when they are not associated with an element. Comprehensive Jest tests have been added to verify this behavior. The review feedback suggests valuable performance optimizations, specifically to avoid redundant string lowercasing inside the loop and to restrict DOM parent traversal to only when the element tag is 'source'.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines 40 to 57
const parentTag = node.parentNode ? node.parentNode.nodeName.toLowerCase() : '';
const isInAudioContainer = tag === 'audio' || ( tag === 'source' && parentTag === 'audio' );

const matchesExtension = videoExtensions.some( ( ext ) => {
const srcLower = src.toLowerCase();
const dataLower = data.toLowerCase();
// Check if the extension is at the end of the string or followed by a query parameter
return (
const matches = (
( srcLower.endsWith( ext ) || srcLower.includes( ext + '?' ) ) ||
( dataLower.endsWith( ext ) || dataLower.includes( ext + '?' ) )
);

if ( matches && ext === '.ogg' && isInAudioContainer ) {
return false;
}

return matches;
} );

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Performance & Cleanliness Improvement

  1. Avoid Unnecessary DOM Traversal: Currently, node.parentNode is accessed and toLowerCase() is called on its nodeName for every evaluated node, even when the node is not a <source> element. We can optimize this by only performing the parent check when tag === 'source'.
  2. Avoid Redundant String Operations: src.toLowerCase() and data.toLowerCase() are called inside the videoExtensions.some loop on every iteration (up to 22 times per node). Defining srcLower and dataLower once outside the loop significantly improves performance, especially on pages with many media elements.

Note: You can also update the matchesKeyword check (on line 59) to use the newly defined srcLower variable.

		const isInAudioContainer = tag === 'audio' || (
			tag === 'source' &&
			node.parentNode &&
			node.parentNode.nodeName.toLowerCase() === 'audio'
		);

		const srcLower = src.toLowerCase();
		const dataLower = data.toLowerCase();

		const matchesExtension = videoExtensions.some( ( ext ) => {
			// Check if the extension is at the end of the string or followed by a query parameter
			const matches = (
				( srcLower.endsWith( ext ) || srcLower.includes( ext + '?' ) ) ||
				( dataLower.endsWith( ext ) || dataLower.includes( ext + '?' ) )
			);

			if ( matches && ext === '.ogg' && isInAudioContainer ) {
				return false;
			}

			return matches;
		} );
References
  1. When traversing the DOM tree to check ancestors, use parentNode instead of parentElement if Shadow DOM support is required, as parentElement does not cross shadow boundaries.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/pageScanner/checks/is-video-detected.js (1)

36-56: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Generalize the audio-container exclusion beyond .ogg. videoExtensions also includes .webm, so audio-only WebM sources can still be flagged as video. A small ambiguous-extension list would cover the same false-positive for other dual-purpose containers too.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pageScanner/checks/is-video-detected.js` around lines 36 - 56, The
audio-container exclusion in is-video-detected should not be limited to .ogg,
because videoExtensions also contains other dual-purpose container formats like
.webm that can be used for audio-only media. Update the matching logic in
is-video-detected.js to use a small ambiguous-extension list and skip matches
for any of those extensions when the node is inside an audio element or audio
source, keeping the existing parentTag/isInAudioContainer checks and the
matchesExtension loop intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/pageScanner/checks/is-video-detected.js`:
- Around line 36-56: The audio-container exclusion in is-video-detected should
not be limited to .ogg, because videoExtensions also contains other dual-purpose
container formats like .webm that can be used for audio-only media. Update the
matching logic in is-video-detected.js to use a small ambiguous-extension list
and skip matches for any of those extensions when the node is inside an audio
element or audio source, keeping the existing parentTag/isInAudioContainer
checks and the matchesExtension loop intact.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 44908bda-9963-4fc7-b938-e8bc35c1a347

📥 Commits

Reviewing files that changed from the base of the PR and between 27c4c59 and 38c3c23.

📒 Files selected for processing (2)
  • src/pageScanner/checks/is-video-detected.js
  • tests/jest/rules/videoElementPresent.test.js

@pattonwebz pattonwebz changed the title fix: don't flag .ogg audio as video content in video_present rule PRO-1168: fix: don't flag .ogg audio as video content in video_present rule Jul 2, 2026
Only compute node.parentNode's tag when the node is a <source>, and
lowercase src/data once instead of on every iteration of the
extensions loop, per Gemini code review feedback on PR #1817.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@pattonwebz

Copy link
Copy Markdown
Member Author

@coderabbitai Thanks for the nitpick on src/pageScanner/checks/is-video-detected.js (36-56) re: generalizing the audio-container exclusion beyond .ogg to cover .webm and other dual-purpose containers.

We are intentionally scoping this fix to .ogg only. .ogg is the extension actually reported in issue #1816 (the Gutenberg Audio block's default sample file), and Ogg Vorbis-only audio commonly keeps the .ogg extension in the wild. By contrast, audio-only WebM/MP4/ASF conventionally use dedicated extensions (.weba, .m4a, .wma) rather than the ambiguous ones already in videoExtensions, so the real-world false-positive risk there is much lower. We'd rather keep this PR narrowly focused on the reported bug than expand the ambiguous-extension list speculatively; we can revisit .webm (or others) in a follow-up if it turns out to be a real problem in practice.

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

@pattonwebz Thanks for the detailed explanation — that reasoning makes sense. Scoping this fix specifically to .ogg (the extension actually reported in #1816) while leaving broader dual-purpose extension handling for a follow-up if it becomes a real-world issue is a reasonable trade-off, especially given .weba/.m4a/.wma are the conventional audio-only extensions for WebM/MP4/ASF. I agree the narrow fix is appropriate here.

If .webm or other extensions ever turn out to cause similar false positives in practice, happy to help open a follow-up issue at that point.


✏️ Learnings added
Learnt from: pattonwebz
URL: https://github.com/equalizedigital/accessibility-checker/pull/1817

Timestamp: 2026-07-02T14:10:31.588Z
Learning: In equalizedigital/accessibility-checker, src/pageScanner/checks/is-video-detected.js: the `video_present` rule's audio-container exclusion for the `videoExtensions` check is intentionally scoped to `.ogg` only (not generalized to `.webm` or other dual-purpose container extensions). Rationale: `.ogg` is the extension reported in issue `#1816` (Gutenberg Audio block's default sample file) and Ogg Vorbis-only audio commonly retains the `.ogg` extension, whereas audio-only WebM/MP4/ASF conventionally use dedicated extensions (`.weba`, `.m4a`, `.wma`) rather than the ambiguous ones in `videoExtensions`, making the false-positive risk there much lower. Expanding this exclusion to other extensions is deferred to a follow-up if it becomes a real-world problem.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

✅ Accessibility Checker build (primary only)

@github-actions github-actions Bot removed the gha-build label Jul 2, 2026
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.

Audio block detected as Vídeo block resulting in "Video is present" warning

1 participant