Commit fce2e397 authored by Chris Harrelson's avatar Chris Harrelson Committed by Commit Bot

Force an intersection observation after calling observe().

Bug: 742413
Change-Id: I43129261e2c69d32b4e2b31a66d6d4f3bef52a36
Reviewed-on: https://chromium-review.googlesource.com/571417Reviewed-by: default avatarEmil A Eklund <eae@chromium.org>
Commit-Queue: Chris Harrelson <chrishtr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#487579}
parent f3c08c1c
......@@ -215,6 +215,7 @@ LocalFrameView::LocalFrameView(LocalFrame& frame, IntRect frame_rect)
suppress_adjust_view_size_(false),
allows_layout_invalidation_after_layout_clean_(true),
forcing_layout_parent_view_(false),
needs_intersection_observation_(false),
main_thread_scrolling_reasons_(0) {
Init();
}
......@@ -4965,6 +4966,7 @@ void LocalFrameView::UpdateViewportIntersectionsForSubtree(
child = child->Tree().NextSibling()) {
child->View()->UpdateViewportIntersectionsForSubtree(target_state);
}
needs_intersection_observation_ = false;
}
void LocalFrameView::UpdateRenderThrottlingStatusForTesting() {
......@@ -5125,9 +5127,15 @@ void LocalFrameView::RecordDeferredLoadingStats() {
total_screens_away));
}
void LocalFrameView::SetNeedsIntersectionObservation() {
needs_intersection_observation_ = true;
if (LocalFrameView* parent = ParentFrameView())
parent->SetNeedsIntersectionObservation();
}
bool LocalFrameView::ShouldThrottleRendering() const {
return CanThrottleRendering() && frame_->GetDocument() &&
Lifecycle().ThrottlingAllowed();
return CanThrottleRendering() && !needs_intersection_observation_ &&
frame_->GetDocument() && Lifecycle().ThrottlingAllowed();
}
bool LocalFrameView::CanThrottleRendering() const {
......
......@@ -182,6 +182,10 @@ class CORE_EXPORT LocalFrameView final
void SetNeedsUpdateGeometries() { needs_update_geometries_ = true; }
void UpdateGeometry() override;
// Marks this frame, and ancestor frames, as needing one intersection
// observervation. This overrides throttling for one frame.
void SetNeedsIntersectionObservation();
// Methods for getting/setting the size Blink should use to layout the
// contents.
// NOTE: Scrollbar exclusion is based on the LocalFrameView's scrollbars. To
......@@ -1191,6 +1195,7 @@ class CORE_EXPORT LocalFrameView final
bool suppress_adjust_view_size_;
bool allows_layout_invalidation_after_layout_clean_;
bool forcing_layout_parent_view_;
bool needs_intersection_observation_;
Member<ElementVisibilityObserver> visibility_observer_;
......
......@@ -246,8 +246,12 @@ void IntersectionObserver::observe(Element* target,
new IntersectionObservation(*this, *target);
target->EnsureIntersectionObserverData().AddObservation(*observation);
observations_.insert(observation);
if (LocalFrameView* frame_view = target_frame->View())
if (LocalFrameView* frame_view = target_frame->View()) {
// The IntersectionObsever spec requires that at least one observation
// be recorded afer observe() is called, even if the frame is throttled.
frame_view->SetNeedsIntersectionObservation();
frame_view->ScheduleAnimation();
}
}
void IntersectionObserver::unobserve(Element* target,
......
......@@ -189,6 +189,43 @@ TEST_P(FrameThrottlingTest, HiddenCrossOriginFramesAreThrottled) {
EXPECT_TRUE(inner_frame_document->View()->CanThrottleRendering());
}
TEST_P(FrameThrottlingTest, IntersectionObservationOverridesThrottling) {
// Create a document with doubly nested iframes.
SimRequest main_resource("https://example.com/", "text/html");
SimRequest frame_resource("https://example.com/iframe.html", "text/html");
LoadURL("https://example.com/");
main_resource.Complete("<iframe id=frame src=iframe.html></iframe>");
frame_resource.Complete("<iframe id=innerFrame sandbox></iframe>");
auto* frame_element =
toHTMLIFrameElement(GetDocument().getElementById("frame"));
auto* frame_document = frame_element->contentDocument();
auto* inner_frame_element =
toHTMLIFrameElement(frame_document->getElementById("innerFrame"));
auto* inner_frame_document = inner_frame_element->contentDocument();
DocumentLifecycle::AllowThrottlingScope throttling_scope(
GetDocument().Lifecycle());
// Hidden cross origin frames are throttled.
frame_element->setAttribute(styleAttr, "transform: translateY(480px)");
CompositeFrame();
EXPECT_FALSE(GetDocument().View()->CanThrottleRendering());
EXPECT_FALSE(frame_document->View()->CanThrottleRendering());
EXPECT_TRUE(inner_frame_document->View()->ShouldThrottleRendering());
// An intersection observation overrides...
inner_frame_document->View()->SetNeedsIntersectionObservation();
EXPECT_FALSE(inner_frame_document->View()->ShouldThrottleRendering());
inner_frame_document->View()->ScheduleAnimation();
CompositeFrame();
// ...but only for one frame.
EXPECT_TRUE(inner_frame_document->View()->ShouldThrottleRendering());
}
TEST_P(FrameThrottlingTest, HiddenCrossOriginZeroByZeroFramesAreNotThrottled) {
// Create a document with doubly nested iframes.
SimRequest main_resource("https://example.com/", "text/html");
......
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