0

Defer navigation cancellations when navigations are deferred

(cherry picked from commit d6cd41c67f)

Bug: 357977710
Change-Id: I067a5c957f10454c19b99f448119b5b568a2d27f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6318765
Commit-Queue: Andrey Kosyakov <caseq@chromium.org>
Reviewed-by: Dmitry Gozman <dgozman@chromium.org>
Reviewed-by: Philip Pfaffe <pfaffe@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1429609}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6350177
Commit-Queue: Dmitry Gozman <dgozman@chromium.org>
Cr-Commit-Position: refs/branch-heads/7049@{#575}
Cr-Branched-From: 2dab7846d0951a552bdc4f350dad497f986e6fed-refs/heads/main@{#1427262}
This commit is contained in:
Andrey Kosyakov
2025-03-13 00:16:41 -07:00
committed by Chromium LUCI CQ
parent 436151b6a2
commit 4301f3caba
4 changed files with 36 additions and 2 deletions
content/renderer
third_party/blink/web_tests/http/tests/inspector-protocol/runtime

@ -4469,6 +4469,15 @@ base::UnguessableToken RenderFrameImpl::GetDevToolsFrameToken() {
void RenderFrameImpl::AbortClientNavigation(bool for_new_navigation) {
CHECK(in_frame_tree_);
// If the navigations are deferred, cancellations should be deferred too.
client_navigation_throttler_.DispatchOrScheduleNavigation(
base::BindOnce(&RenderFrameImpl::AbortClientNavigationImpl,
base::Unretained(this), for_new_navigation));
}
void RenderFrameImpl::AbortClientNavigationImpl(bool for_new_navigation) {
CHECK(navigation_client_impl_);
is_requesting_navigation_ = false;
if (mhtml_body_loader_client_) {
mhtml_body_loader_client_->Detach();
@ -4478,7 +4487,6 @@ void RenderFrameImpl::AbortClientNavigation(bool for_new_navigation) {
// See comment in header for more information of how navigation cleanup works.
// Note: This might not actually cancel the navigation if the navigation is
// already in the process of committing to a different RenderFrame.
if (for_new_navigation) {
navigation_client_impl_->ResetForNewNavigation(
/*is_duplicate_navigation=*/false);
@ -5727,7 +5735,6 @@ void RenderFrameImpl::BeginNavigation(
for (auto& observer : observers_) {
observer.DidStartNavigation(info->url_request.Url(), info->navigation_type);
}
is_requesting_navigation_ = true;
// Everything else is handled asynchronously by the browser process through
// BeginNavigation.
@ -6179,6 +6186,8 @@ void RenderFrameImpl::BeginNavigationInternal(
// Provisional frames shouldn't initiate navigations.
CHECK(!GetWebFrame()->IsProvisional());
is_requesting_navigation_ = true;
// Set SiteForCookies.
WebDocument frame_document = frame_->GetDocument();
if (info->frame_type == blink::mojom::RequestContextFrameType::kTopLevel) {

@ -1243,6 +1243,10 @@ class CONTENT_EXPORT RenderFrameImpl
// CommitNavigation() and DidCommitNavigation().
void ResetMembersUsedForDurationOfCommit();
// Actual implementation of AbortClientNavigation(), as one may be deferred in
// case the page is being instrumented by devtools,
void AbortClientNavigationImpl(bool for_new_navigation);
// Stores the WebLocalFrame we are associated with. This is null from the
// constructor until BindToFrame() is called, and it is null after
// FrameDetached() is called until destruction (which is asynchronous in the

@ -0,0 +1,3 @@
Tests that client-side navigation can be cancelled.
http://first.test:8000/inspector-protocol/resources/test-page.html

@ -0,0 +1,18 @@
(async function(/** @type {import('test_runner').TestRunner} */ testRunner) {
const {session, dp} = await testRunner.startURL(
'http://first.test:8000/inspector-protocol/resources/test-page.html',
`Tests that client-side navigation can be cancelled.`);
await dp.Page.enable();
const navigate_to = 'http://second.test:8000/inspector-protocol/resources/test-page.html';
session.evaluate(`
location.href = '${navigate_to}';
window.stop();
`);
await dp.Page.onceFrameStartedLoading();
await dp.Page.onceFrameStoppedLoading();
testRunner.log(await session.evaluate('location.href'));
testRunner.completeTest();
})