Commit 1d796f2b authored by Dominic Farolino's avatar Dominic Farolino Committed by Commit Bot

Frame::Navigate is responsible for immediately clearing frame observers

Context: LazyLoadFrameObserver::LoadImmediately only expects to ever be
called one time.

Before this CL, both LocalFrame::Navigate and RemoteFrame::Navigate
didn't immediately call HTMLFrameOwnerElement::CancelPendingLazyLoad().
Therefore if LazyLoadFrameObserver::LoadImmediately() was called, and
attempts to navigate a frame but the navigation fails before
CancelPendingLazyLoad() was called (which can happen due to the
navigation rate limiter etc.), LazyLoadFrameObserver::LoadImmedaitely
may be called a second time by the underlying intersection observer
which still observes the element.

R=sclittle@chromium.org

Bug: 1106290
Change-Id: I77f052c5d5a113d0c35f702322d6dc6ec831650b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2303352Reviewed-by: default avatarScott Little <sclittle@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Commit-Queue: Dominic Farolino <dom@chromium.org>
Cr-Commit-Position: refs/heads/master@{#790733}
parent 47296147
...@@ -453,6 +453,9 @@ bool LocalFrame::IsLocalRoot() const { ...@@ -453,6 +453,9 @@ bool LocalFrame::IsLocalRoot() const {
void LocalFrame::Navigate(FrameLoadRequest& request, void LocalFrame::Navigate(FrameLoadRequest& request,
WebFrameLoadType frame_load_type) { WebFrameLoadType frame_load_type) {
if (HTMLFrameOwnerElement* element = DeprecatedLocalOwner())
element->CancelPendingLazyLoad();
if (!navigation_rate_limiter().CanProceed()) if (!navigation_rate_limiter().CanProceed())
return; return;
if (request.ClientRedirectReason() != ClientNavigationReason::kNone) { if (request.ClientRedirectReason() != ClientNavigationReason::kNone) {
......
...@@ -139,12 +139,12 @@ void RemoteFrame::Navigate(FrameLoadRequest& frame_request, ...@@ -139,12 +139,12 @@ void RemoteFrame::Navigate(FrameLoadRequest& frame_request,
// local frames. // local frames.
DCHECK_EQ(kNavigationPolicyCurrentTab, frame_request.GetNavigationPolicy()); DCHECK_EQ(kNavigationPolicyCurrentTab, frame_request.GetNavigationPolicy());
if (!navigation_rate_limiter().CanProceed())
return;
if (HTMLFrameOwnerElement* element = DeprecatedLocalOwner()) if (HTMLFrameOwnerElement* element = DeprecatedLocalOwner())
element->CancelPendingLazyLoad(); element->CancelPendingLazyLoad();
if (!navigation_rate_limiter().CanProceed())
return;
frame_request.SetFrameType(IsMainFrame() frame_request.SetFrameType(IsMainFrame()
? mojom::RequestContextFrameType::kTopLevel ? mojom::RequestContextFrameType::kTopLevel
: mojom::RequestContextFrameType::kNested); : mojom::RequestContextFrameType::kNested);
......
...@@ -157,8 +157,6 @@ void LazyLoadFrameObserver::LoadIfHiddenOrNearViewport( ...@@ -157,8 +157,6 @@ void LazyLoadFrameObserver::LoadIfHiddenOrNearViewport(
} }
void LazyLoadFrameObserver::LoadImmediately() { void LazyLoadFrameObserver::LoadImmediately() {
// TODO(domfarolino): Change the CHECKs to DCHECKs once we confirm there are
// no crashes.
CHECK(IsLazyLoadPending()); CHECK(IsLazyLoadPending());
CHECK(lazy_load_request_info_); CHECK(lazy_load_request_info_);
...@@ -181,8 +179,6 @@ void LazyLoadFrameObserver::LoadImmediately() { ...@@ -181,8 +179,6 @@ void LazyLoadFrameObserver::LoadImmediately() {
// DisconnectContentFrame() if the content frame changes. // DisconnectContentFrame() if the content frame changes.
CHECK(element_->ContentFrame()); CHECK(element_->ContentFrame());
// Note that calling both FrameLoader::StartNavigation() and Frame::Navigate()
// causes the |lazy_load_intersection_observer_| to be disconnected.
FrameLoadRequest request(element_->GetDocument().domWindow(), FrameLoadRequest request(element_->GetDocument().domWindow(),
scoped_request_info->resource_request); scoped_request_info->resource_request);
...@@ -195,6 +191,8 @@ void LazyLoadFrameObserver::LoadImmediately() { ...@@ -195,6 +191,8 @@ void LazyLoadFrameObserver::LoadImmediately() {
scoped_request_info->frame_load_type); scoped_request_info->frame_load_type);
} }
// Note that whatever we delegate to for the navigation is responsible for
// clearing the frame's lazy load frame observer via |CancelPendingLayLoad()|.
CHECK(!IsLazyLoadPending()); CHECK(!IsLazyLoadPending());
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment