Skip to content

fix(watch-later): inject button outside aria-hidden anchor (#4305) - #4307

Open
shoaibyazdani wants to merge 1 commit into
code-charity:masterfrom
shoaibyazdani:fix/watch-later-aria-hidden
Open

fix(watch-later): inject button outside aria-hidden anchor (#4305)#4307
shoaibyazdani wants to merge 1 commit into
code-charity:masterfrom
shoaibyazdani:fix/watch-later-aria-hidden

Conversation

@shoaibyazdani

Copy link
Copy Markdown

Summary

Fixes #4305.

YouTube marks thumbnail anchors (e.g. <a class="ytLockupViewModelContentImage">) with aria-hidden="true". The Watch Later button was being appended as a direct child of the anchor via thumbnail.appendChild(button), so when a user clicked the button the browser blocked focus with:

Blocked aria-hidden on an element because its descendant retained focus. The focus must not be hidden from assistive technology users.

Appending the button to the thumbnail's parent container (the renderer — ytd-rich-item-renderer / yt-lockup-view-model / etc.) keeps the button focusable while preserving YouTube's a11y semantics.

Why this works

  • The button uses position: absolute; top: 4px; right: 4px; and is already positioned relative to a higher ancestor (the renderer). Moving it from the anchor to the renderer's child list doesn't change visual placement.
  • findNativeWatchLaterButton(container) works correctly because that helper uses closest() to locate the renderer internally — passing the renderer directly just short-circuits the lookup.
  • always mode is unaffected. The existing *:hover>.it-watch-later-button selector still matches because the button's direct parent (the renderer) is now what gets hovered — so hover semantics still work, just with a slightly larger hover area. If reviewers prefer to preserve link-only hover, the selector can be tightened in a follow-up.

Changes

  • js&css/extension/www.youtube.com/general/general.jsaddWatchLaterButton: append to thumbnail.parentElement instead of thumbnail; track container so the click handler can pass it to findNativeWatchLaterButton (which uses closest() anyway, but passing the renderer explicitly is cleaner).
  • tests/unit/watch-later-buttons.test.js — added a test asserting the button is not appended directly to the thumbnail anchor.

Test

PASS tests/unit/watch-later-buttons.test.js
  Watch Later thumbnail buttons
    ✓ registers the feature with init
    ✓ adds a hover and always menu option
    ✓ uses the native Watch Later control before the Innertube fallback
    ✓ styles hover and always visibility states
    ✓ injects button outside the aria-hidden thumbnail anchor (#4305)

Tests:       5 passed, 5 total

Notes

…ity#4305)

YouTube marks thumbnail anchors (e.g. <a class="ytLockupViewModelContentImage">) with aria-hidden="true". The Watch Later button was appended as a direct child of the anchor, so clicking the button triggered the browser's focus-block warning:

  Blocked aria-hidden on an element because its descendant retained focus.

Append the button to the thumbnail's parent container (the renderer — ytd-rich-item-renderer, yt-lockup-view-model, etc.) instead. The button is positioned absolutely so visual placement is unchanged.

- addWatchLaterButton: append to thumbnail.parentElement; track container for the click handler so it can be passed to findNativeWatchLaterButton (which uses closest() to locate the renderer internally anyway).
- findNativeWatchLaterButton(container) still resolves the same renderer via closest(), so this is a no-op for the native-button lookup.
- Existing hover selector *:hover>.it-watch-later-button still matches because the button's new direct parent (the renderer) is what gets hovered.
- New test: 'injects button outside the aria-hidden thumbnail anchor (code-charity#4305)'.
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.

🐞Watch Later button throws error

1 participant