Skip to content
Merged
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
43 changes: 25 additions & 18 deletions Source/WebCore/loader/FrameLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1482,23 +1482,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 = m_frame.get();

// Anchor target is ignored when the download attribute is set since it will download the hyperlink rather than follow it.
Expand Down Expand Up @@ -1577,15 +1560,39 @@ void FrameLoader::loadURL(FrameLoadRequest&& frameLoadRequest, const String& ref

if (!dispatchNavigateEvent(newURL, newLoadType, action, frameLoadRequest.navigationHistoryBehavior(), true))
return;
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) || frame->history().provisionalItem());
policyChecker().checkNavigationPolicy(WTFMove(request), ResourceResponse { } /* redirectResponse */, oldDocumentLoader.get(), WTFMove(formState), [this, frame, requesterOrigin = Ref { frameLoadRequest.requesterSecurityOrigin() }, historyHandling = frameLoadRequest.navigationHistoryBehavior()] (const ResourceRequest& request, WeakPtr<FormState>&&, NavigationPolicyDecision navigationPolicyDecision) {
continueFragmentScrollAfterNavigationPolicy(request, requesterOrigin.ptr(), navigationPolicyDecision == NavigationPolicyDecision::ContinueLoad, historyHandling);
}, PolicyDecisionMode::Synchronous);

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

return;
}

Expand Down
4 changes: 4 additions & 0 deletions Source/WebCore/loader/PolicyChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,10 @@ void PolicyChecker::checkNavigationPolicy(ResourceRequest&& request, const Resou
}

auto documentLoader = frameLoader->loaderForWebsitePolicies();
// 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 (policyDecisionMode == PolicyDecisionMode::Synchronous)
documentLoader = frameLoader->documentLoader();
auto clientRedirectSourceForHistory = documentLoader ? documentLoader->clientRedirectSourceForHistory() : String();
auto navigationID = documentLoader ? documentLoader->navigationID() : 0;
bool hasOpener = !!frame->opener();
Expand Down