diff --git a/docshell/base/BrowsingContext.cpp b/docshell/base/BrowsingContext.cpp index 620d3afac8c1..d5a46d0a130e 100644 --- a/docshell/base/BrowsingContext.cpp +++ b/docshell/base/BrowsingContext.cpp @@ -806,7 +806,8 @@ void BrowsingContext::Location(JSContext* aCx, } nsresult BrowsingContext::LoadURI(BrowsingContext* aAccessor, - nsDocShellLoadState* aLoadState) { + nsDocShellLoadState* aLoadState, + bool aSetNavigating) { // Per spec, most load attempts are silently ignored when a BrowsingContext is // null (which in our code corresponds to discarded), so we simply fail // silently in those cases. Regardless, we cannot trigger loads in/from @@ -816,12 +817,12 @@ nsresult BrowsingContext::LoadURI(BrowsingContext* aAccessor, } if (mDocShell) { - return mDocShell->LoadURI(aLoadState); + return mDocShell->LoadURI(aLoadState, aSetNavigating); } if (!aAccessor && XRE_IsParentProcess()) { Unused << Canonical()->GetCurrentWindowGlobal()->SendLoadURIInChild( - aLoadState); + aLoadState, aSetNavigating); } else { MOZ_DIAGNOSTIC_ASSERT(aAccessor); MOZ_DIAGNOSTIC_ASSERT(aAccessor->Group() == Group()); @@ -830,7 +831,7 @@ nsresult BrowsingContext::LoadURI(BrowsingContext* aAccessor, MOZ_DIAGNOSTIC_ASSERT(win); if (WindowGlobalChild* wgc = win->GetCurrentInnerWindow()->GetWindowGlobalChild()) { - wgc->SendLoadURI(this, aLoadState); + wgc->SendLoadURI(this, aLoadState, aSetNavigating); } } return NS_OK; diff --git a/docshell/base/BrowsingContext.h b/docshell/base/BrowsingContext.h index f1516708943c..5cf08f05d0ea 100644 --- a/docshell/base/BrowsingContext.h +++ b/docshell/base/BrowsingContext.h @@ -185,7 +185,8 @@ class BrowsingContext : public nsWrapperCache, public BrowsingContextBase { // Triggers a load in the process which currently owns this BrowsingContext. // aAccessor is the context which initiated the load, and may be null only for // in-process BrowsingContexts. - nsresult LoadURI(BrowsingContext* aAccessor, nsDocShellLoadState* aLoadState); + nsresult LoadURI(BrowsingContext* aAccessor, nsDocShellLoadState* aLoadState, + bool aSetNavigating = false); // Determine if the current BrowsingContext was 'cached' by the logic in // CacheChildren. diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 9dd4ff6ff43e..0ba173b11b69 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -689,7 +689,7 @@ nsDocShell::SetCancelContentJSEpoch(int32_t aEpoch) { } NS_IMETHODIMP -nsDocShell::LoadURI(nsDocShellLoadState* aLoadState) { +nsDocShell::LoadURI(nsDocShellLoadState* aLoadState, bool aSetNavigating) { MOZ_ASSERT(aLoadState, "Must have a valid load state!"); MOZ_ASSERT( (aLoadState->LoadFlags() & INTERNAL_LOAD_FLAGS_LOADURI_SETUP_FLAGS) == 0, @@ -704,6 +704,13 @@ nsDocShell::LoadURI(nsDocShellLoadState* aLoadState) { } } + bool oldIsNavigating = mIsNavigating; + auto cleanupIsNavigating = + MakeScopeExit([&]() { mIsNavigating = oldIsNavigating; }); + if (aSetNavigating) { + mIsNavigating = true; + } + PopupBlocker::PopupControlState popupState; if (aLoadState->LoadFlags() & LOAD_FLAGS_ALLOW_POPUPS) { popupState = PopupBlocker::openAllowed; @@ -3848,8 +3855,7 @@ nsresult nsDocShell::LoadURI(const nsAString& aURI, return NS_ERROR_FAILURE; } - rv = LoadURI(loadState); - return rv; + return LoadURI(loadState, true); } NS_IMETHODIMP @@ -5740,7 +5746,7 @@ nsDocShell::ForceRefreshURI(nsIURI* aURI, nsIPrincipal* aPrincipal, * LoadURI(...) will cancel all refresh timers... This causes the * Timer and its refreshData instance to be released... */ - LoadURI(loadState); + LoadURI(loadState, false); return NS_OK; } diff --git a/docshell/base/nsIDocShell.idl b/docshell/base/nsIDocShell.idl index 7dd8692e3427..6251da852c0f 100644 --- a/docshell/base/nsIDocShell.idl +++ b/docshell/base/nsIDocShell.idl @@ -84,9 +84,11 @@ interface nsIDocShell : nsIDocShellTreeItem * however, the URL dispatcher will go through its normal process of content * loading. * - * @param loadState - This is the extended load info for this load. + * @param aLoadState This is the extended load info for this load. + * @param aSetNavigating If we should set isNavigating to true while initiating + * the load. */ - [noscript]void loadURI(in nsDocShellLoadStatePtr loadState); + [noscript]void loadURI(in nsDocShellLoadStatePtr aLoadState, in boolean aSetNavigating); /** * Do either a history.pushState() or history.replaceState() operation, diff --git a/docshell/shistory/nsSHistory.cpp b/docshell/shistory/nsSHistory.cpp index c42f27824969..7f45f0b8146d 100644 --- a/docshell/shistory/nsSHistory.cpp +++ b/docshell/shistory/nsSHistory.cpp @@ -1482,5 +1482,5 @@ nsresult nsSHistory::InitiateLoad(nsISHEntry* aFrameEntry, loadState->SetCsp(csp); // Time to initiate a document load - return aFrameDS->LoadURI(loadState); + return aFrameDS->LoadURI(loadState, false); } diff --git a/dom/base/nsFrameLoader.cpp b/dom/base/nsFrameLoader.cpp index 53262c63f4d9..3a54a033d665 100644 --- a/dom/base/nsFrameLoader.cpp +++ b/dom/base/nsFrameLoader.cpp @@ -667,7 +667,7 @@ nsresult nsFrameLoader::ReallyStartLoadingInternal() { mNeedsAsyncDestroy = true; loadState->SetLoadFlags(flags); loadState->SetFirstParty(false); - rv = GetDocShell()->LoadURI(loadState); + rv = GetDocShell()->LoadURI(loadState, false); mNeedsAsyncDestroy = tmpState; mURIToLoad = nullptr; NS_ENSURE_SUCCESS(rv, rv); diff --git a/dom/clients/manager/ClientNavigateOpChild.cpp b/dom/clients/manager/ClientNavigateOpChild.cpp index 797c784df81e..294afa3bb04b 100644 --- a/dom/clients/manager/ClientNavigateOpChild.cpp +++ b/dom/clients/manager/ClientNavigateOpChild.cpp @@ -238,7 +238,7 @@ RefPtr ClientNavigateOpChild::DoNavigate( loadState->SetSourceDocShell(docShell); loadState->SetLoadFlags(nsIWebNavigation::LOAD_FLAGS_NONE); loadState->SetFirstParty(true); - rv = docShell->LoadURI(loadState); + rv = docShell->LoadURI(loadState, false); if (NS_FAILED(rv)) { return ClientOpPromise::CreateAndReject(rv, __func__); } diff --git a/dom/ipc/PWindowGlobal.ipdl b/dom/ipc/PWindowGlobal.ipdl index 5ff8bcf6ed2e..40c4cfb0cb0b 100644 --- a/dom/ipc/PWindowGlobal.ipdl +++ b/dom/ipc/PWindowGlobal.ipdl @@ -53,7 +53,7 @@ child: */ async GetSecurityInfo() returns(nsCString? serializedSecInfo); - async LoadURIInChild(nsDocShellLoadState aLoadState); + async LoadURIInChild(nsDocShellLoadState aLoadState, bool aSetNavigating); both: async RawMessage(JSWindowActorMessageMeta aMetadata, ClonedMessageData aData); @@ -62,7 +62,7 @@ parent: // Load the given URI load state into the current owner process of the given // BrowsingContext. aTargetBC must be in the same BrowsingContextGroup as this // window global. - async LoadURI(BrowsingContext aTargetBC, nsDocShellLoadState aLoadState); + async LoadURI(BrowsingContext aTargetBC, nsDocShellLoadState aLoadState, bool aSetNavigating); /// Update the URI of the document in this WindowGlobal. async UpdateDocumentURI(nsIURI aUri); diff --git a/dom/ipc/WindowGlobalChild.cpp b/dom/ipc/WindowGlobalChild.cpp index 94aa12183483..d5cac31c37cd 100644 --- a/dom/ipc/WindowGlobalChild.cpp +++ b/dom/ipc/WindowGlobalChild.cpp @@ -234,8 +234,11 @@ void WindowGlobalChild::Destroy() { } mozilla::ipc::IPCResult WindowGlobalChild::RecvLoadURIInChild( - nsDocShellLoadState* aLoadState) { - mWindowGlobal->GetDocShell()->LoadURI(aLoadState); + nsDocShellLoadState* aLoadState, bool aSetNavigating) { + mWindowGlobal->GetDocShell()->LoadURI(aLoadState, aSetNavigating); + if (aSetNavigating) { + mWindowGlobal->GetBrowserChild()->NotifyNavigationFinished(); + } return IPC_OK(); } diff --git a/dom/ipc/WindowGlobalChild.h b/dom/ipc/WindowGlobalChild.h index a046f8a3d392..4dd89c68e896 100644 --- a/dom/ipc/WindowGlobalChild.h +++ b/dom/ipc/WindowGlobalChild.h @@ -114,7 +114,8 @@ class WindowGlobalChild final : public WindowGlobalActor, mozilla::ipc::IPCResult RecvRawMessage(const JSWindowActorMessageMeta& aMeta, const ClonedMessageData& aData); - mozilla::ipc::IPCResult RecvLoadURIInChild(nsDocShellLoadState* aLoadState); + mozilla::ipc::IPCResult RecvLoadURIInChild(nsDocShellLoadState* aLoadState, + bool aSetNavigating); mozilla::ipc::IPCResult RecvChangeFrameRemoteness( dom::BrowsingContext* aBc, const nsString& aRemoteType, diff --git a/dom/ipc/WindowGlobalParent.cpp b/dom/ipc/WindowGlobalParent.cpp index bd174e13388a..6546e4b1fdc3 100644 --- a/dom/ipc/WindowGlobalParent.cpp +++ b/dom/ipc/WindowGlobalParent.cpp @@ -175,7 +175,8 @@ bool WindowGlobalParent::IsProcessRoot() { } mozilla::ipc::IPCResult WindowGlobalParent::RecvLoadURI( - dom::BrowsingContext* aTargetBC, nsDocShellLoadState* aLoadState) { + dom::BrowsingContext* aTargetBC, nsDocShellLoadState* aLoadState, + bool aSetNavigating) { if (!aTargetBC || aTargetBC->IsDiscarded()) { MOZ_LOG( BrowsingContext::GetLog(), LogLevel::Debug, @@ -200,7 +201,7 @@ mozilla::ipc::IPCResult WindowGlobalParent::RecvLoadURI( return IPC_OK(); } - Unused << wgp->SendLoadURIInChild(aLoadState); + Unused << wgp->SendLoadURIInChild(aLoadState, aSetNavigating); return IPC_OK(); } diff --git a/dom/ipc/WindowGlobalParent.h b/dom/ipc/WindowGlobalParent.h index 785521cc2545..a7e5c088ac03 100644 --- a/dom/ipc/WindowGlobalParent.h +++ b/dom/ipc/WindowGlobalParent.h @@ -140,7 +140,8 @@ class WindowGlobalParent final : public WindowGlobalActor, // IPC messages mozilla::ipc::IPCResult RecvLoadURI(dom::BrowsingContext* aTargetBC, - nsDocShellLoadState* aLoadState); + nsDocShellLoadState* aLoadState, + bool aSetNavigating); mozilla::ipc::IPCResult RecvUpdateDocumentURI(nsIURI* aURI); mozilla::ipc::IPCResult RecvSetIsInitialDocument(bool aIsInitialDocument) { mIsInitialDocument = aIsInitialDocument;