Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 27 additions & 18 deletions Source/WebCore/loader/FrameLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<Frame> protect(m_frame);

// Anchor target is ignored when the download attribute is set since it will download the hyperlink rather than follow it.
Expand Down Expand Up @@ -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<FormState>&&, NavigationPolicyDecision navigationPolicyDecision) {
continueFragmentScrollAfterNavigationPolicy(request, requesterOrigin.ptr(), navigationPolicyDecision == NavigationPolicyDecision::ContinueLoad);
}, PolicyDecisionMode::Synchronous);

if (resetLoadTypeAfterFragmentNavigation)
policyChecker().setLoadType(loadType);

return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<WebDocumentLoader*>(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<WebDocumentLoader*>(coreFrame->loader().documentLoader());

navigationActionData.clientRedirectSourceForHistory = documentLoader->clientRedirectSourceForHistory();
Expand Down