fix: keep player-button tooltip inside the fullscreen element - #4298
Draft
Laaaaksh wants to merge 2 commits into
Draft
fix: keep player-button tooltip inside the fullscreen element#4298Laaaaksh wants to merge 2 commits into
Laaaaksh wants to merge 2 commits into
Conversation
Custom player-button tooltips (e.g. the playback speed button) are appended to document.body. Once the player enters the browser's Fullscreen API, only the fullscreen element's subtree is painted, so a tooltip parented to document.body renders behind the video instead of above it. Append the tooltip to document.fullscreenElement when one is active, falling back to document.body otherwise. Fixes code-charity#4294
…tooltip stacking tests
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.
Fixes #4294
Reproduction
On a real
youtube.com/watchpage with the extension's actual button/tooltipcode (
ImprovedTube.createPlayerButtoninjs&css/web-accessible/functions.js), hover a custom player button (e.g. theplayback speed button) while the player is in the browser's native
Fullscreen mode (the
.html5-video-playerelement via the Fullscreen API,same as YouTube's own fullscreen button uses).
document.elementFromPoint()at the tooltip's own coordinates returns the<video>element, not the tooltip, and a screenshot confirms no tooltip ispainted anywhere near the button.
Root cause: the tooltip
<div class="it-player-button--tooltip">is alwaysappended to
document.body. Per the Fullscreen API spec, once an element(here
.html5-video-player) is the document'sfullscreenElement, only thatelement's own subtree is painted — siblings/ancestors like
document.body'sother children stop rendering. A
position: fixedelement outside thefullscreen subtree therefore renders behind (i.e. not on top of) the video,
matching the reporter's screenshot and description ("tooltips are hidden
behind the video player").
Note: PR #4295 ("fix: show player tooltips above video") was merged into
mastershortly before this branch and also targeted tooltip/videolayering, but issue #4294 remained open — its z-index change didn't address
this fullscreen-subtree stacking root cause, which is orthogonal to z-index.
What changed
In
ImprovedTube.createPlayerButton's mouseover handler(
js&css/web-accessible/functions.js), the tooltip is now appended to thecurrent fullscreen element instead of always
document.body:so it stays inside the rendered subtree whether or not the player is
fullscreen. The vendor-prefixed fallbacks match the same set the codebase
already checks elsewhere for fullscreen detection (
player.js:458-463),covering engines that only expose a prefixed API.
How it was tested
session against a live
youtube.com/watchpage, injecting the extension'sactual
createPlayerButton/tooltip code and CSS): confirmed the tooltipwas invisible in fullscreen before the fix (screenshot +
elementFromPointcheck), and confirmed it renders visibly above the video in fullscreen
after the fix, while remaining unchanged/visible in normal mode
(screenshots taken before/after).
.improvedtube-player-button:hover::aftertooltip style (used for the buttons below the player, e.g. Loop/PiP/
Screenshot) — untouched by this change, no regression there.
tests/unit/tooltip-fullscreen-stacking.test.js: behavioral unittests that extract the real
createPlayerButtonsource, run it in avmsandbox against a fake DOM, fire a real
mouseover, and assert where thetooltip actually gets parented — covering
document.fullscreenElement,the
webkit/moz-prefixed fallbacks, the non-fullscreendocument.bodycase, and that
mouseleavestill cleans up a reparented tooltip. Three ofthe four tests fail against the pre-fix code, confirming they're real
regression coverage, not just source-text assertions.
npm run lint— clean, no errors.npm test— 25 suites / 117 tests passed.no-mistakesvalidationpipeline (independent review, test, lint, and doc gates) end-to-end, which
passed and additionally suggested the vendor-prefix fallback and the
stronger behavioral tests above — both incorporated.
Anything I was unsure about
I was not able to get the packaged extension itself to load in this
sandboxed browser-automation environment:
--load-extension+--disable-extensions-exceptis present in Chrome's actual command line(verified via
chrome://version), and I also confirmed Developer Mode wasgenuinely persisted on in the profile (
chrome://extensions), butchrome://extensionsstill reports 0 installed items either way, and noerror card appears. This looks like the automation harness's Chrome
(
--enable-automation) suppressing unpacked-extension loading rather thananything about this extension's manifest.
Because of that, "live" verification here was done by pulling the actual,
current
ImprovedTube.createPlayerButtonfunction verbatim out ofjs&css/web-accessible/functions.js(post-fix) plus the real.it-player-button--tooltipCSS fromstyles.css, and executing that exactcode, unmodified, against a real
youtube.com/watchpage — creating thereal playback-speed button, dispatching a real
mouseover, and enteringreal browser Fullscreen (
Element.requestFullscreen(), the same APIYouTube's own fullscreen button uses). Screenshots confirm the tooltip is
invisible in fullscreen before the fix and clearly visible above the video
in fullscreen after it, with no change in normal/theater mode. This
exercises the identical code path a loaded extension would run; the one gap
is that it wasn't driven through the packaged extension's content-script
injection itself. A maintainer with a normal desktop Chrome/Firefox profile
may still want to do one final sanity check loading the built extension for
real, though the root cause (Fullscreen API only paints the fullscreen
element's subtree) is browser-spec-defined and not environment-specific.
This change was AI-assisted.