diff --git a/Source/WebCore/loader/FrameLoader.cpp b/Source/WebCore/loader/FrameLoader.cpp
index 55d4f50ec2360..1323de47ece5d 100644
--- a/Source/WebCore/loader/FrameLoader.cpp
+++ b/Source/WebCore/loader/FrameLoader.cpp
@@ -1349,23 +1349,6 @@ void FrameLoader::loadURL(FrameLoadRequest&& frameLoadRequest, const String& ref
if (m_inStopAllLoaders || m_inClearProvisionalLoadForPolicyCheck)
return;
- static bool keepNavigationOnFragmentLoad = false;
- static bool keepNavigationOnFragmentLoadInitialized = false;
-
- if (!keepNavigationOnFragmentLoadInitialized) {
- keepNavigationOnFragmentLoad = !!getenv("WPE_KEEP_NAVIGATION_ON_FRAGMENT_LOAD");
- keepNavigationOnFragmentLoadInitialized = true;
- }
-
- // If we have a policy or provisional request for a different document, a fragment scroll should be cancelled.
- if (keepNavigationOnFragmentLoad && (m_policyDocumentLoader && !equalIgnoringFragmentIdentifier(m_policyDocumentLoader->request().url(), frameLoadRequest.resourceRequest().url()) ||
- m_provisionalDocumentLoader && !equalIgnoringFragmentIdentifier(m_provisionalDocumentLoader->request().url(), frameLoadRequest.resourceRequest().url()))) {
- const auto fragmentNavigationURL = frameLoadRequest.resourceRequest().url();
- const auto navigationURL = m_policyDocumentLoader ? m_policyDocumentLoader->request().url(): m_provisionalDocumentLoader->request().url();
- FRAMELOADER_RELEASE_LOG(ResourceLoading, "loadURL: fragment navigation: %s is cancelled because of ongoing navigation change to url: %s", fragmentNavigationURL.string().utf8().data(), navigationURL.string().utf8().data());
- return;
- }
-
Ref protect(m_frame);
// Anchor target is ignored when the download attribute is set since it will download the hyperlink rather than follow it.
@@ -1427,14 +1410,40 @@ void FrameLoader::loadURL(FrameLoadRequest&& frameLoadRequest, const String& ref
// exactly the same so pages with '#' links and DHTML side effects
// work properly.
if (shouldPerformFragmentNavigation(isFormSubmission, httpMethod, newLoadType, newURL)) {
+
+ static bool keepNavigationOnFragmentLoad = false;
+ static bool keepNavigationOnFragmentLoadInitialized = false;
+
+ if (!keepNavigationOnFragmentLoadInitialized) {
+ keepNavigationOnFragmentLoad = !!getenv("WPE_KEEP_NAVIGATION_ON_FRAGMENT_LOAD");
+ keepNavigationOnFragmentLoadInitialized = true;
+ }
+
oldDocumentLoader->setTriggeringAction(WTFMove(action));
oldDocumentLoader->setLastCheckedRequest(ResourceRequest());
- policyChecker().stopCheck();
+ auto loadType = policyChecker().loadType();
+ bool resetLoadTypeAfterFragmentNavigation = false;
+ if (keepNavigationOnFragmentLoad && (m_policyDocumentLoader && !equalIgnoringFragmentIdentifier(m_policyDocumentLoader->request().url(), frameLoadRequest.resourceRequest().url()) ||
+ m_provisionalDocumentLoader && !equalIgnoringFragmentIdentifier(m_provisionalDocumentLoader->request().url(), frameLoadRequest.resourceRequest().url()))) {
+ resetLoadTypeAfterFragmentNavigation = true;
+
+ const auto fragmentNavigationURL = frameLoadRequest.resourceRequest().url();
+ const auto navigationURL = m_policyDocumentLoader ? m_policyDocumentLoader->request().url(): m_provisionalDocumentLoader->request().url();
+ FRAMELOADER_RELEASE_LOG(ResourceLoading, "loadURL: navigation to: %s will be continued after fragment navigation to url: %s",
+ navigationURL.string().utf8().data(), fragmentNavigationURL.string().utf8().data());
+ } else {
+ policyChecker().stopCheck();
+ }
+
policyChecker().setLoadType(newLoadType);
RELEASE_ASSERT(!isBackForwardLoadType(newLoadType) || history().provisionalItem());
policyChecker().checkNavigationPolicy(WTFMove(request), ResourceResponse { } /* redirectResponse */, oldDocumentLoader.get(), WTFMove(formState), [this, protectedFrame = Ref { m_frame }, requesterOrigin = Ref { frameLoadRequest.requesterSecurityOrigin() }] (const ResourceRequest& request, WeakPtr&&, NavigationPolicyDecision navigationPolicyDecision) {
continueFragmentScrollAfterNavigationPolicy(request, requesterOrigin.ptr(), navigationPolicyDecision == NavigationPolicyDecision::ContinueLoad);
}, PolicyDecisionMode::Synchronous);
+
+ if (resetLoadTypeAfterFragmentNavigation)
+ policyChecker().setLoadType(loadType);
+
return;
}
diff --git a/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp b/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp
index eff7e85973e0a..2cdb167411741 100644
--- a/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp
+++ b/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp
@@ -1022,7 +1022,9 @@ void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(const Navigat
// the provisional load's DocumentLoader needs to receive navigation policy decisions. We need a better model for this state.
documentLoader = static_cast(coreFrame->loader().provisionalDocumentLoader());
}
- if (!documentLoader)
+ // PolicyDecisionMode::Synchronous means that it is a FragmentNavigation and in that case we should use documentLoader,
+ // because there can be ongoing (in policy or provisional state) navigation.
+ if (!documentLoader || policyDecisionMode == PolicyDecisionMode::Synchronous)
documentLoader = static_cast(coreFrame->loader().documentLoader());
navigationActionData.clientRedirectSourceForHistory = documentLoader->clientRedirectSourceForHistory();