Bug 1672479: Fix beforeunload handling in location.refresh under SHiP. r=peterv

Per spec, whenever a "beforeunload" event handler which would affect a
`location.reload()` call exists, it must be called before the `reload()` call
returns. If a handler requests to block the navigation and we choose to
display a confirmation prompt, that must also be displayed before the call
returns.

With session history in parent, though, that currently does not happen,
because `location.reload()` triggers an async IPC call to the parent process,
and only attempts the actual reload (and thus beforeunload dispatch and
prompting) once it returns, which is too late to affect the caller.

This patch changes the handling in this case to manually perform permit unload
checks before taking an async code path. This still leaves the opportunity for
session history handlers in the parent to cancel the load asynchronously, but
that doesn't violate any spec-defined behavior.

Differential Revision: https://phabricator.services.mozilla.com/D94354
This commit is contained in:
Kris Maglione
2020-12-14 21:25:46 +00:00
parent 61679bc765
commit 9e07a6556c
6 changed files with 48 additions and 9 deletions

View File

@@ -38,7 +38,8 @@ nsDocShellLoadState::nsDocShellLoadState(nsIURI* aURI)
nsDocShellLoadState::nsDocShellLoadState(
const DocShellLoadStateInit& aLoadState)
: mLoadIdentifier(aLoadState.LoadIdentifier()) {
: mNotifiedBeforeUnloadListeners(false),
mLoadIdentifier(aLoadState.LoadIdentifier()) {
MOZ_ASSERT(aLoadState.URI(), "Cannot create a LoadState with a null URI!");
mResultPrincipalURI = aLoadState.ResultPrincipalURI();
mResultPrincipalURIIsSome = aLoadState.ResultPrincipalURIIsSome();
@@ -94,6 +95,7 @@ nsDocShellLoadState::nsDocShellLoadState(const nsDocShellLoadState& aOther)
mLoadReplace(aOther.mLoadReplace),
mInheritPrincipal(aOther.mInheritPrincipal),
mPrincipalIsExplicit(aOther.mPrincipalIsExplicit),
mNotifiedBeforeUnloadListeners(aOther.mNotifiedBeforeUnloadListeners),
mPrincipalToInherit(aOther.mPrincipalToInherit),
mPartitionedPrincipalToInherit(aOther.mPartitionedPrincipalToInherit),
mForceAllowDataURI(aOther.mForceAllowDataURI),
@@ -133,6 +135,7 @@ nsDocShellLoadState::nsDocShellLoadState(nsIURI* aURI, uint64_t aLoadIdentifier)
mLoadReplace(false),
mInheritPrincipal(false),
mPrincipalIsExplicit(false),
mNotifiedBeforeUnloadListeners(false),
mForceAllowDataURI(false),
mOriginalFrameSrc(false),
mIsFormSubmission(false),
@@ -465,6 +468,15 @@ void nsDocShellLoadState::SetPrincipalIsExplicit(bool aPrincipalIsExplicit) {
mPrincipalIsExplicit = aPrincipalIsExplicit;
}
bool nsDocShellLoadState::NotifiedBeforeUnloadListeners() const {
return mNotifiedBeforeUnloadListeners;
}
void nsDocShellLoadState::SetNotifiedBeforeUnloadListeners(
bool aNotifiedBeforeUnloadListeners) {
mNotifiedBeforeUnloadListeners = aNotifiedBeforeUnloadListeners;
}
bool nsDocShellLoadState::ForceAllowDataURI() const {
return mForceAllowDataURI;
}