mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 12:51:06 +00:00
Bug 1763134 - Stop navigation with "wait" equal "none" when beforeunload prompt is open. r=webdriver-reviewers,jdescottes
Differential Revision: https://phabricator.services.mozilla.com/D218331
This commit is contained in:
parent
305e77adde
commit
3ce23807a4
@ -12,6 +12,8 @@ ChromeUtils.defineESModuleGetters(lazy, {
|
||||
|
||||
Deferred: "chrome://remote/content/shared/Sync.sys.mjs",
|
||||
Log: "chrome://remote/content/shared/Log.sys.mjs",
|
||||
PromptListener:
|
||||
"chrome://remote/content/shared/listeners/PromptListener.sys.mjs",
|
||||
truncate: "chrome://remote/content/shared/Format.sys.mjs",
|
||||
});
|
||||
|
||||
@ -140,6 +142,7 @@ export class ProgressListener {
|
||||
|
||||
#deferredNavigation;
|
||||
#errorName;
|
||||
#promptListener;
|
||||
#seenStartFlag;
|
||||
#targetURI;
|
||||
#unloadTimerId;
|
||||
@ -159,6 +162,8 @@ export class ProgressListener {
|
||||
* Flag to indicate that the Promise has to be resolved when the
|
||||
* page load has been started. Otherwise wait until the page has
|
||||
* finished loading. Defaults to `false`.
|
||||
* @param {string=} options.targetURI
|
||||
* The target URI for the navigation.
|
||||
* @param {number=} options.unloadTimeout
|
||||
* Time to allow before the page gets unloaded. Defaults to 200ms on
|
||||
* regular platforms. A multiplier will be applied on slower platforms
|
||||
@ -174,6 +179,7 @@ export class ProgressListener {
|
||||
const {
|
||||
expectNavigation = false,
|
||||
resolveWhenStarted = false,
|
||||
targetURI,
|
||||
unloadTimeout = DEFAULT_UNLOAD_TIMEOUT,
|
||||
waitForExplicitStart = false,
|
||||
} = options;
|
||||
@ -187,8 +193,18 @@ export class ProgressListener {
|
||||
this.#deferredNavigation = null;
|
||||
this.#errorName = null;
|
||||
this.#seenStartFlag = false;
|
||||
this.#targetURI = null;
|
||||
this.#targetURI = targetURI;
|
||||
this.#unloadTimerId = null;
|
||||
|
||||
this.#promptListener = new lazy.PromptListener();
|
||||
this.#promptListener.on("opened", this.#onPromptOpened);
|
||||
this.#promptListener.startListening();
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.#promptListener.stopListening();
|
||||
this.#promptListener.off("opened", this.#onPromptOpened);
|
||||
this.#promptListener.destroy();
|
||||
}
|
||||
|
||||
get #messagePrefix() {
|
||||
@ -322,6 +338,31 @@ export class ProgressListener {
|
||||
return null;
|
||||
}
|
||||
|
||||
#onPromptOpened = (eventName, data) => {
|
||||
const { prompt, contentBrowser } = data;
|
||||
const { promptType } = prompt;
|
||||
|
||||
this.#trace(`A prompt of type=${promptType} is open`);
|
||||
// Prompt open events come for top level context,
|
||||
// that's why in case of navigation in iframe we also have to find
|
||||
// top level context to identify if this navigation is affected.
|
||||
const topLevelContext = this.browsingContext.top
|
||||
? this.browsingContext.top
|
||||
: this.browsingContext;
|
||||
if (
|
||||
topLevelContext === contentBrowser.browsingContext &&
|
||||
promptType === "beforeunload" &&
|
||||
this.#resolveWhenStarted
|
||||
) {
|
||||
this.#trace(
|
||||
"A beforeunload prompt is open in the context of the navigated context and resolveWhenStarted=true. " +
|
||||
"Stopping the navigation."
|
||||
);
|
||||
this.#seenStartFlag = true;
|
||||
this.stop();
|
||||
}
|
||||
};
|
||||
|
||||
#setUnloadTimer() {
|
||||
if (this.#expectNavigation) {
|
||||
this.#trace("Skip setting the unload timer");
|
||||
|
@ -294,7 +294,9 @@ class NavigationRegistry extends EventEmitter {
|
||||
|
||||
let navigation = this.#navigations.get(navigableId);
|
||||
if (navigation && !navigation.finished) {
|
||||
if (navigation.url === url) {
|
||||
// Bug 1908952. As soon as we have support for the "url" field in case of beforeunload
|
||||
// prompt being open, we can remove "!navigation.url" check.
|
||||
if (!navigation.url || navigation.url === url) {
|
||||
// If we are already monitoring a navigation for this navigable and the same url,
|
||||
// for which we did not receive a navigation-stopped event, this navigation
|
||||
// is already tracked and we don't want to create another id & event.
|
||||
|
@ -175,8 +175,6 @@ class BrowsingContextModule extends RootBiDiModule {
|
||||
this.#contextListener.on("attached", this.#onContextAttached);
|
||||
this.#contextListener.on("discarded", this.#onContextDiscarded);
|
||||
|
||||
// Create the navigation listener and listen to "fragment-navigated" and
|
||||
// "navigation-started" events.
|
||||
this.#navigationListener = new lazy.NavigationListener(
|
||||
this.messageHandler.navigationManager
|
||||
);
|
||||
@ -1133,6 +1131,7 @@ class BrowsingContextModule extends RootBiDiModule {
|
||||
});
|
||||
},
|
||||
{
|
||||
targetURI,
|
||||
wait,
|
||||
}
|
||||
);
|
||||
@ -1539,6 +1538,8 @@ class BrowsingContextModule extends RootBiDiModule {
|
||||
* @param {Function} startNavigationFn
|
||||
* A callback that starts a navigation.
|
||||
* @param {object} options
|
||||
* @param {string=} options.targetURI
|
||||
* The target URI for the navigation.
|
||||
* @param {WaitCondition} options.wait
|
||||
* The WaitCondition to use to wait for the navigation.
|
||||
*
|
||||
@ -1546,7 +1547,7 @@ class BrowsingContextModule extends RootBiDiModule {
|
||||
* A Promise that resolves to navigate results when the navigation is done.
|
||||
*/
|
||||
async #awaitNavigation(webProgress, startNavigationFn, options) {
|
||||
const { wait } = options;
|
||||
const { targetURI, wait } = options;
|
||||
|
||||
const context = webProgress.browsingContext;
|
||||
const browserId = context.browserId;
|
||||
@ -1555,6 +1556,7 @@ class BrowsingContextModule extends RootBiDiModule {
|
||||
const listener = new lazy.ProgressListener(webProgress, {
|
||||
expectNavigation: true,
|
||||
resolveWhenStarted,
|
||||
targetURI,
|
||||
// In case the webprogress is already navigating, always wait for an
|
||||
// explicit start flag.
|
||||
waitForExplicitStart: true,
|
||||
|
Loading…
Reference in New Issue
Block a user