commit fd1c94fadb4403faac2c29eb33d9aaf24c87c159
parent 47fddd61988c0427ef186b069c785e0de1d2e9f1
Author: Atila Butkovits <abutkovits@mozilla.com>
Date: Mon, 1 Dec 2025 14:03:25 +0200
Revert "Bug 2002289 Fix OOP-frame JSWA fullscreen problem r=edgar" for causing failures at element-request-fullscreen-cross-origin-multi-steps.sub.html.
This reverts commit 8dcaa274e8e4b84231ddffaab33f86d52aa96262.
Diffstat:
4 files changed, 5 insertions(+), 285 deletions(-)
diff --git a/dom/base/Document.cpp b/dom/base/Document.cpp
@@ -16411,24 +16411,6 @@ const char* Document::GetFullscreenError(CallerType aCallerType) {
return nullptr;
}
-// Informs JSWA Fullscreen implementation to resume via sending
-// "MozDOMFullscreen:Entered".
-static inline void PropagateFullscreenRequest(Document* aDoc,
- Element* aElement) {
- nsContentUtils::DispatchEventOnlyToChrome(
- aDoc, aElement, u"MozDOMFullscreen:Entered"_ns, CanBubble::eYes,
- Cancelable::eNo, /* DefaultAction */ nullptr);
-}
-
-static bool ElementIsRemoteFrame(Element* aElement) {
- MOZ_ASSERT(aElement);
- RefPtr<nsFrameLoader> loader;
- if (RefPtr<nsFrameLoaderOwner> loaderOwner = do_QueryObject(aElement)) {
- loader = loaderOwner->GetFrameLoader();
- }
- return loader && loader->IsRemoteFrame();
-}
-
bool Document::FullscreenElementReadyCheck(FullscreenRequest& aRequest) {
Element* elem = aRequest.Element();
// Strictly speaking, this isn't part of the fullscreen element ready
@@ -16437,19 +16419,7 @@ bool Document::FullscreenElementReadyCheck(FullscreenRequest& aRequest) {
// should change and no event should be dispatched, but we still need
// to resolve the returned promise.
Element* fullscreenElement = GetUnretargetedFullscreenElement();
- if (NS_WARN_IF(elem == fullscreenElement)) {
- // But this introduces behavior that we now need to account for;
- // because we can have arbitrary depth of OOP-frames, we may hit this check
- // for a process that already is fullscreen, e.g. the parent process.
- // If the target element is a frame or we're the parent process, just resume
- // the JS Window Actor messaging without doing any more work.
- // We know for sure, that the document must be fullscreened already, so
- // there is no request to the OS for fullscreen that needs to be made, for
- // instance. Note: this is just for JSWA not the platform-only fullscreen
- // implementation.
- if (ElementIsRemoteFrame(elem)) {
- PropagateFullscreenRequest(this, elem);
- }
+ if (elem == fullscreenElement) {
aRequest.MayResolvePromise();
return false;
}
@@ -16777,16 +16747,10 @@ bool Document::ApplyFullscreen(UniquePtr<FullscreenRequest> aRequest) {
// notifying parent process to enter fullscreen. Note that chrome
// code may also want to listen to MozDOMFullscreen:NewOrigin event
// to pop up warning UI.
- // We also need to propagate the message in the JSWA message chain,
- // so that if out of process sub-frames, that has requested fs
- // gets notified to resume it's request. We can know, that the request did not
- // originate from this process, if the JS promise is null.
- if (!aRequest->GetPromise() || !previousFullscreenDoc) {
- MOZ_ASSERT(
- (previousFullscreenDoc &&
- ElementIsRemoteFrame(child->GetUnretargetedFullscreenElement())) ||
- !previousFullscreenDoc);
- PropagateFullscreenRequest(this, elem);
+ if (!previousFullscreenDoc) {
+ nsContentUtils::DispatchEventOnlyToChrome(
+ this, elem, u"MozDOMFullscreen:Entered"_ns, CanBubble::eYes,
+ Cancelable::eNo, /* DefaultAction */ nullptr);
}
// The origin which is fullscreen gets changed. Trigger an event so
diff --git a/testing/web-platform/mozilla/tests/fullscreen/api/element-request-fullscreen-cross-origin-multi-steps.sub.html b/testing/web-platform/mozilla/tests/fullscreen/api/element-request-fullscreen-cross-origin-multi-steps.sub.html
@@ -1,132 +0,0 @@
-<!DOCTYPE html>
-<title>
- Element#requestFullscreen() works properly with a tree of cross-origin iframes, with multiple requests
-</title>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/resources/testdriver.js"></script>
-<script src="/resources/testdriver-vendor.js"></script>
-
-<body>
- <script>
- function waitFor(action, frameName) {
- return new Promise((resolve) => {
- window.addEventListener("message", function listener(e) {
- if (e.data.action === action && e.data.name === frameName) {
- window.removeEventListener("message", listener);
- resolve(event.data);
- }
- });
- });
- }
-
- function compare_report(report, frame, expectedIndex) {
- assert_array_equals(report.events, frame.expectedEvents[expectedIndex], `compare events for ${frame.name}`);
- assert_equals(report.fullscreenElementIsNull, frame.expectedNullFullscreenElement[expectedIndex], `frame ${frame.name} has expected fullscreen element`);
- }
-
- const iframes = [
- {
- name: "A",
- src: "http://{{hosts[][]}}:{{ports[http][0]}}/_mozilla/fullscreen/api/resources/recursive-iframe-fullscreen.html?a",
- allow_fullscreen: true,
- expectedEvents: [["fullscreenchange"], []],
- expectedNullFullscreenElement: [false, false]
- },
- { // first check should see its body go fs, 2nd should see it's <iframe> go fs
- name: "B",
- src: "http://{{hosts[alt][]}}:{{ports[http][1]}}/_mozilla/fullscreen/api/resources/recursive-iframe-fullscreen.html?b",
- allow_fullscreen: true,
- expectedEvents: [["fullscreenchange"], ["fullscreenchange"]],
- expectedNullFullscreenElement: [false, false]
- },
- {
- name: "C",
- src: "http://{{hosts[][www]}}:{{ports[http][0]}}/_mozilla/fullscreen/api/resources/recursive-iframe-fullscreen.html?c",
- allow_fullscreen: true,
- expectedEvents: [[], ["fullscreenchange"]],
- expectedNullFullscreenElement: [true, false]
- },
- {
- name: "D",
- src: "http://{{hosts[][]}}:{{ports[http][1]}}/_mozilla/fullscreen/api/resources/recursive-iframe-fullscreen.html?d",
- allow_fullscreen: true,
- expectedEvents: [[],["fullscreenchange"]],
- expectedNullFullscreenElement: [true, false]
- },
- {
- name: "E",
- src: "http://{{hosts[][]}}:{{ports[http][0]}}/_mozilla/fullscreen/api/resources/recursive-iframe-fullscreen.html?e",
- allow_fullscreen: true,
- expectedEvents: [[],[]],
- expectedNullFullscreenElement: [true, true]
- },
- ];
-
- promise_setup(async () => {
- // Add the first iframe.
- const iframeDetails = iframes[0];
- const childFrame = document.createElement("iframe");
- childFrame.allow = iframeDetails.allow_fullscreen ? "fullscreen" : "";
- childFrame.name = iframeDetails.name;
- childFrame.style.width = "100%";
- childFrame.style.height = "100%";
- childFrame.src = iframeDetails.src;
- await new Promise((resolve) => {
- childFrame.onload = resolve;
- document.body.appendChild(childFrame);
- });
-
- // Create the nested iframes.
- for (let i = 1; i < iframes.length; i++) {
- const parentName = iframes[i - 1].name;
- const details = iframes[i];
- childFrame.contentWindow.postMessage(
- { action: "addIframe", iframe: details, name: parentName },
- "*"
- );
- await waitFor("load", details.name);
- }
- });
-
- promise_test(async (t) => {
- t.add_cleanup(async () => {
- if (document.fullscreenElement) {
- await new Promise((resolve) => {
- document.addEventListener("fullscreenchange", resolve, { once: true });
- document.exitFullscreen();
- });
- }
- });
- document.onfullscreenerror = t.unreached_func(
- "fullscreenerror event fired"
- );
-
- const childFrame = document.querySelector("iframe[name=A]");
-
- const requestFullscreenIn = (name) => {
- const action = "requestFullscreen";
- childFrame.contentWindow.postMessage({ action, name }, "*");
- return waitFor(action, name);
- }
-
- const verifyResult = async (expectedResultIndex) => {
- for (const frame of iframes) {
- const data = {
- action: "requestReport",
- name: frame.name,
- };
- childFrame.contentWindow.postMessage(data, "*");
- const { report } = await waitFor("report", frame.name);
- compare_report(report, frame, expectedResultIndex);
- }
- }
-
- await requestFullscreenIn("B");
- await verifyResult(0);
-
- await requestFullscreenIn("D");
- await verifyResult(1);
- }, "Element#requestFullscreen() works properly with a tree of cross-origin iframes");
- </script>
-</body>
diff --git a/testing/web-platform/mozilla/tests/fullscreen/api/resources/recursive-iframe-fullscreen.html b/testing/web-platform/mozilla/tests/fullscreen/api/resources/recursive-iframe-fullscreen.html
@@ -1,87 +0,0 @@
-<!DOCTYPE html>
-<meta charset="utf-8" />
-<title>Recursive IFrame Fullscreen API success reporter</title>
-<body>
- <script src="/resources/testdriver.js"></script>
- <script src="/resources/testdriver-vendor.js"></script>
- <script src="trusted-click.js"></script>
- <script>
- let child_frame = null;
- let events = [];
-
- document.onfullscreenchange = () => {
- events.push("fullscreenchange");
- };
-
- document.onfullscreenerror = () => {
- events.push("fullscreenerror");
- };
-
- function send_report() {
- window.top.postMessage(
- {
- name: window.name,
- action: "report",
- report: {
- api: "fullscreen",
- frame: window.name,
- fullscreenElementIsNull: document.fullscreenElement === null,
- events,
- },
- },
- "*"
- );
- events = [];
- }
-
- async function create_child_frame({ src, name, allow_fullscreen }) {
- child_frame = document.createElement("iframe");
- child_frame.allow = allow_fullscreen ? "fullscreen" : "";
- child_frame.name = name;
- child_frame.style.width = "100%";
- child_frame.style.height = "100%";
- document.body.appendChild(child_frame);
- await new Promise((resolve) => {
- child_frame.addEventListener("load", resolve, { once: true });
- child_frame.src = src;
- });
- window.top.postMessage({ action: "load", name }, "*");
- }
-
- async function go_fullscreen() {
- await trusted_click(document.body);
- let error;
- try {
- await document.body.requestFullscreen();
- } catch (err) {
- error = err.name;
- } finally {
- window.top.postMessage(
- { action: "requestFullscreen", name: window.name, error },
- "*"
- );
- }
- }
-
- window.addEventListener("message", async (e) => {
- // Massage is not for us, try to pass it on...
- if (e.data.name !== window.name) {
- child_frame?.contentWindow.postMessage(e.data, "*");
- return;
- }
- switch (e.data.action) {
- case "requestReport":
- send_report();
- break;
- case "requestFullscreen":
- await go_fullscreen();
- break;
- case "addIframe":
- await create_child_frame(e.data.iframe);
- break;
- default:
- window.top.postMessage(e.data, "*");
- }
- });
- </script>
-</body>
diff --git a/testing/web-platform/mozilla/tests/fullscreen/api/resources/trusted-click.js b/testing/web-platform/mozilla/tests/fullscreen/api/resources/trusted-click.js
@@ -1,25 +0,0 @@
-/**
- * Invokes callback from a trusted click event, avoiding interception by fullscreen element.
- *
- * @param {Element} container - Element where button will be created and clicked.
- */
-function trusted_click(container = document.body) {
- var document = container.ownerDocument;
- var button = document.createElement("button");
- button.textContent = "click to continue test";
- button.style.display = "block";
- button.style.fontSize = "20px";
- button.style.padding = "10px";
- button.addEventListener("click", () => {
- button.remove();
- });
- container.appendChild(button);
- if (window.top !== window) test_driver.set_test_context(window.top);
- // Race them for manually testing...
- return Promise.race([
- test_driver.click(button),
- new Promise((resolve) => {
- button.addEventListener("click", resolve);
- }),
- ]);
-}