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();