mirror of
https://github.com/SoPat712/Speeder.git
synced 2026-10-08 03:03:14 -04:00
fix(controller): preserve overlays in Firefox fullscreen
This commit is contained in:
3 files changed
+80
-7
No files matched your search
@@ -3144,6 +3144,12 @@ function setupControllerHostTracking(videoController, wrapper, mount) {
|
||||
resizeObserver.observe(geometryMount);
|
||||
}
|
||||
|
||||
var mediaGeometryEvents = ["loadedmetadata", "play", "playing"];
|
||||
mediaGeometryEvents.forEach(function(eventName) {
|
||||
videoController.video.addEventListener(eventName, schedule, {
|
||||
passive: true
|
||||
});
|
||||
});
|
||||
win.addEventListener("resize", schedule, { passive: true });
|
||||
doc.addEventListener("fullscreenchange", schedule, { passive: true });
|
||||
geometryMount.addEventListener("scroll", schedule, { passive: true });
|
||||
@@ -3154,6 +3160,9 @@ function setupControllerHostTracking(videoController, wrapper, mount) {
|
||||
if (resizeObserver) resizeObserver.disconnect();
|
||||
if (frameId !== null) win.cancelAnimationFrame(frameId);
|
||||
if (geometryRetryTimer !== null) win.clearTimeout(geometryRetryTimer);
|
||||
mediaGeometryEvents.forEach(function(eventName) {
|
||||
videoController.video.removeEventListener(eventName, schedule);
|
||||
});
|
||||
win.removeEventListener("resize", schedule);
|
||||
doc.removeEventListener("fullscreenchange", schedule);
|
||||
geometryMount.removeEventListener("scroll", schedule);
|
||||
@@ -3329,8 +3338,15 @@ function syncControllerFullscreenMount(videoController) {
|
||||
(fullscreenElement === video ||
|
||||
isComposedDescendant(video, fullscreenElement))
|
||||
);
|
||||
var normalGeometryMount = getControllerGeometryMount(targetMount);
|
||||
var normalMountIsAlreadyFullscreenVisible = Boolean(
|
||||
fullscreenElement &&
|
||||
fullscreenElement !== video &&
|
||||
normalGeometryMount &&
|
||||
isComposedDescendant(normalGeometryMount, fullscreenElement)
|
||||
);
|
||||
|
||||
if (ownsFullscreen) {
|
||||
if (ownsFullscreen && !normalMountIsAlreadyFullscreenVisible) {
|
||||
targetMount = getControllerMount(video, fullscreenElement);
|
||||
} else if (!fullscreenElement && (!targetMount || !targetMount.isConnected)) {
|
||||
targetMount = getControllerMount(video);
|
||||
@@ -3950,6 +3966,9 @@ function defineVideoController() {
|
||||
const speed = this.video.playbackRate.toFixed(2);
|
||||
var wrapper = doc.createElement("div");
|
||||
wrapper.classList.add("vsc-controller");
|
||||
// Keep the host out of player layout while its shadow stylesheet loads.
|
||||
wrapper.style.position = "absolute";
|
||||
wrapper.style.pointerEvents = "none";
|
||||
if (!hasUsableMediaSource(this.video))
|
||||
wrapper.classList.add("vsc-nosource");
|
||||
if (tc.settings.startHidden) wrapper.classList.add("vsc-hidden");
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
:host {
|
||||
position: absolute !important;
|
||||
top: 0 !important;
|
||||
left: 0 !important;
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
pointer-events: none !important;
|
||||
z-index: 2147483647 !important;
|
||||
white-space: normal;
|
||||
@@ -15,7 +11,6 @@
|
||||
base absolute host rule. */
|
||||
:host(.vsc-fullscreen-popover) {
|
||||
position: fixed !important;
|
||||
inset: auto !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
border: 0 !important;
|
||||
|
||||
@@ -2,7 +2,8 @@ const {
|
||||
createChromeMock,
|
||||
evaluateScript,
|
||||
flushAsyncWork,
|
||||
loadHtmlString
|
||||
loadHtmlString,
|
||||
readWorkspaceFile
|
||||
} = require("./helpers/extension-test-utils");
|
||||
|
||||
function bootInject(options) {
|
||||
@@ -280,6 +281,45 @@ describe("inject.js media/controller lifecycle regressions", () => {
|
||||
expect(video.vsc.div.style.getPropertyValue("height")).toBe("226px");
|
||||
});
|
||||
|
||||
it("does not let shadow host defaults override measured geometry", () => {
|
||||
const shadowCss = readWorkspaceFile("extension/content/shadow.css");
|
||||
const hostRule = shadowCss.match(/:host\s*\{([^}]*)\}/)[1];
|
||||
const fullscreenRule = shadowCss.match(
|
||||
/:host\(\.vsc-fullscreen-popover\)\s*\{([^}]*)\}/
|
||||
)[1];
|
||||
|
||||
expect(hostRule).not.toMatch(/\b(?:top|left|width|height)\s*:/);
|
||||
expect(fullscreenRule).not.toMatch(/\binset\s*:/);
|
||||
});
|
||||
|
||||
it("repositions a Shorts controller when playback moves the video on-screen", async () => {
|
||||
vi.useFakeTimers();
|
||||
bootInject({ url: "https://www.youtube.com/shorts/example" });
|
||||
await settleLifecycle();
|
||||
|
||||
const player = document.createElement("div");
|
||||
player.className = "html5-video-player";
|
||||
const video = document.createElement("video");
|
||||
const playerRect = makeRect(40, 64, 351, 624);
|
||||
let videoRect = makeRect(40, -560, 351, 624);
|
||||
|
||||
setRect(player, playerRect);
|
||||
setBoxMetrics(player, playerRect.width, playerRect.height);
|
||||
video.getBoundingClientRect = () => videoRect;
|
||||
video.src = "blob:https://www.youtube.com/shorts";
|
||||
player.appendChild(video);
|
||||
document.body.appendChild(player);
|
||||
|
||||
window.ensureController(video, player);
|
||||
expect(video.vsc.div.style.getPropertyValue("top")).toBe("-624px");
|
||||
|
||||
videoRect = playerRect;
|
||||
video.dispatchEvent(new Event("playing"));
|
||||
await vi.advanceTimersByTimeAsync(0);
|
||||
|
||||
expect(video.vsc.div.style.getPropertyValue("top")).toBe("0px");
|
||||
});
|
||||
|
||||
it("targets the controller nearest the pointer unless change-all is selected", async () => {
|
||||
bootInject();
|
||||
await settleLifecycle();
|
||||
@@ -638,6 +678,25 @@ describe("inject.js media/controller lifecycle regressions", () => {
|
||||
controller.controllerHostCleanup();
|
||||
});
|
||||
|
||||
it("keeps a visible player-local host when Firefox fullscreens the page root", async () => {
|
||||
bootInject();
|
||||
await settleLifecycle();
|
||||
|
||||
const { mount, controller, wrapper } = createControlledVideo();
|
||||
setRect(document.documentElement, makeRect(0, 0, 0, 0));
|
||||
Object.defineProperty(document, "fullscreenElement", {
|
||||
configurable: true,
|
||||
value: document.documentElement
|
||||
});
|
||||
|
||||
window.syncControllerFullscreenMount(controller);
|
||||
|
||||
expect(wrapper.parentElement).toBe(mount);
|
||||
expect(wrapper.classList.contains("vsc-geometry-hidden")).toBe(false);
|
||||
expect(document.documentElement.style.position).toBe("");
|
||||
expect(document.documentElement.style.isolation).toBe("");
|
||||
});
|
||||
|
||||
it("only promotes the directly-fullscreen video's controller", async () => {
|
||||
bootInject();
|
||||
await settleLifecycle();
|
||||
|
||||
Reference in new issue
Block a user