Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1352)

Unified Diff: third_party/WebKit/Source/web/tests/FrameThrottlingTest.cpp

Issue 2885313003: [scheduler] Fix --disable-background-timer-throttling flag. (Closed)
Patch Set: fix test crash Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/web/tests/FrameThrottlingTest.cpp
diff --git a/third_party/WebKit/Source/web/tests/FrameThrottlingTest.cpp b/third_party/WebKit/Source/web/tests/FrameThrottlingTest.cpp
deleted file mode 100644
index e2a4891eabfac070d5db544b416c2ec9a0176d9f..0000000000000000000000000000000000000000
--- a/third_party/WebKit/Source/web/tests/FrameThrottlingTest.cpp
+++ /dev/null
@@ -1,1142 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "bindings/core/v8/ScriptController.h"
-#include "bindings/core/v8/ScriptSourceCode.h"
-#include "core/dom/Document.h"
-#include "core/dom/Element.h"
-#include "core/frame/FrameView.h"
-#include "core/frame/LocalFrame.h"
-#include "core/html/HTMLIFrameElement.h"
-#include "core/layout/api/LayoutViewItem.h"
-#include "core/layout/compositing/CompositedLayerMapping.h"
-#include "core/page/FocusController.h"
-#include "core/page/Page.h"
-#include "core/paint/PaintLayer.h"
-#include "platform/graphics/paint/TransformPaintPropertyNode.h"
-#include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h"
-#include "platform/testing/URLTestHelpers.h"
-#include "platform/testing/UnitTestHelpers.h"
-#include "public/platform/WebDisplayItemList.h"
-#include "public/platform/WebLayer.h"
-#include "public/web/WebFrameContentDumper.h"
-#include "public/web/WebHitTestResult.h"
-#include "public/web/WebSettings.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "web/WebLocalFrameImpl.h"
-#include "web/WebRemoteFrameImpl.h"
-#include "web/tests/sim/SimCompositor.h"
-#include "web/tests/sim/SimDisplayItemList.h"
-#include "web/tests/sim/SimRequest.h"
-#include "web/tests/sim/SimTest.h"
-
-using testing::_;
-
-namespace blink {
-
-using namespace HTMLNames;
-
-// NOTE: This test uses <iframe sandbox> to create cross origin iframes.
-
-namespace {
-
-class MockWebDisplayItemList : public WebDisplayItemList {
- public:
- ~MockWebDisplayItemList() override {}
-
- MOCK_METHOD2(AppendDrawingItem,
- void(const WebRect&, sk_sp<const PaintRecord>));
-};
-
-void PaintRecursively(GraphicsLayer* layer, WebDisplayItemList* display_items) {
- if (layer->DrawsContent()) {
- layer->SetNeedsDisplay();
- layer->ContentLayerDelegateForTesting()->PaintContents(
- display_items, ContentLayerDelegate::kPaintDefaultBehaviorForTest);
- }
- for (const auto& child : layer->Children())
- PaintRecursively(child, display_items);
-}
-
-} // namespace
-
-class FrameThrottlingTest : public SimTest,
- public ::testing::WithParamInterface<bool>,
- private ScopedRootLayerScrollingForTest {
- protected:
- FrameThrottlingTest() : ScopedRootLayerScrollingForTest(GetParam()) {
- WebView().Resize(WebSize(640, 480));
- }
-
- SimDisplayItemList CompositeFrame() {
- SimDisplayItemList display_items = Compositor().BeginFrame();
- // Ensure intersection observer notifications get delivered.
- testing::RunPendingTasks();
- return display_items;
- }
-
- // Number of rectangles that make up the root layer's touch handler region.
- size_t TouchHandlerRegionSize() {
- size_t result = 0;
- PaintLayer* layer =
- WebView().MainFrameImpl()->GetFrame()->ContentLayoutObject()->Layer();
- GraphicsLayer* own_graphics_layer =
- layer->GraphicsLayerBacking(&layer->GetLayoutObject());
- if (own_graphics_layer) {
- result +=
- own_graphics_layer->PlatformLayer()->TouchEventHandlerRegion().size();
- }
- GraphicsLayer* child_graphics_layer = layer->GraphicsLayerBacking();
- if (child_graphics_layer && child_graphics_layer != own_graphics_layer) {
- result += child_graphics_layer->PlatformLayer()
- ->TouchEventHandlerRegion()
- .size();
- }
- return result;
- }
-};
-
-INSTANTIATE_TEST_CASE_P(All, FrameThrottlingTest, ::testing::Bool());
-
-TEST_P(FrameThrottlingTest, ThrottleInvisibleFrames) {
- SimRequest main_resource("https://example.com/", "text/html");
-
- LoadURL("https://example.com/");
- main_resource.Complete("<iframe sandbox id=frame></iframe>");
-
- auto* frame_element =
- toHTMLIFrameElement(GetDocument().getElementById("frame"));
- auto* frame_document = frame_element->contentDocument();
-
- // Initially both frames are visible.
- EXPECT_FALSE(GetDocument().View()->IsHiddenForThrottling());
- EXPECT_FALSE(frame_document->View()->IsHiddenForThrottling());
-
- // Moving the child fully outside the parent makes it invisible.
- frame_element->setAttribute(styleAttr, "transform: translateY(480px)");
- CompositeFrame();
- EXPECT_FALSE(GetDocument().View()->IsHiddenForThrottling());
- EXPECT_TRUE(frame_document->View()->IsHiddenForThrottling());
-
- // A partially visible child is considered visible.
- frame_element->setAttribute(styleAttr,
- "transform: translate(-50px, 0px, 0px)");
- CompositeFrame();
- EXPECT_FALSE(GetDocument().View()->IsHiddenForThrottling());
- EXPECT_FALSE(frame_document->View()->IsHiddenForThrottling());
-}
-
-TEST_P(FrameThrottlingTest, HiddenSameOriginFramesAreNotThrottled) {
- 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></iframe>");
-
- auto* frame_element =
- toHTMLIFrameElement(GetDocument().getElementById("frame"));
- auto* frame_document = frame_element->contentDocument();
-
- HTMLIFrameElement* inner_frame_element =
- toHTMLIFrameElement(frame_document->getElementById("innerFrame"));
- auto* inner_frame_document = inner_frame_element->contentDocument();
-
- EXPECT_FALSE(GetDocument().View()->CanThrottleRendering());
- EXPECT_FALSE(frame_document->View()->CanThrottleRendering());
- EXPECT_FALSE(inner_frame_document->View()->CanThrottleRendering());
-
- // Hidden same origin frames are not throttled.
- frame_element->setAttribute(styleAttr, "transform: translateY(480px)");
- CompositeFrame();
- EXPECT_FALSE(GetDocument().View()->CanThrottleRendering());
- EXPECT_FALSE(frame_document->View()->CanThrottleRendering());
- EXPECT_FALSE(inner_frame_document->View()->CanThrottleRendering());
-}
-
-TEST_P(FrameThrottlingTest, HiddenCrossOriginFramesAreThrottled) {
- // 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();
-
- EXPECT_FALSE(GetDocument().View()->CanThrottleRendering());
- EXPECT_FALSE(frame_document->View()->CanThrottleRendering());
- EXPECT_FALSE(inner_frame_document->View()->CanThrottleRendering());
-
- // 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()->CanThrottleRendering());
-}
-
-TEST_P(FrameThrottlingTest, HiddenCrossOriginZeroByZeroFramesAreNotThrottled) {
- // 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 width=0 height=0 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();
-
- EXPECT_FALSE(GetDocument().View()->CanThrottleRendering());
- EXPECT_FALSE(frame_document->View()->CanThrottleRendering());
- EXPECT_FALSE(inner_frame_document->View()->CanThrottleRendering());
-
- // The frame is not throttled because its dimensions are 0x0.
- frame_element->setAttribute(styleAttr, "transform: translateY(480px)");
- CompositeFrame();
- EXPECT_FALSE(GetDocument().View()->CanThrottleRendering());
- EXPECT_FALSE(frame_document->View()->CanThrottleRendering());
- EXPECT_FALSE(inner_frame_document->View()->CanThrottleRendering());
-}
-
-TEST_P(FrameThrottlingTest, ThrottledLifecycleUpdate) {
- SimRequest main_resource("https://example.com/", "text/html");
-
- LoadURL("https://example.com/");
- main_resource.Complete("<iframe sandbox id=frame></iframe>");
-
- auto* frame_element =
- toHTMLIFrameElement(GetDocument().getElementById("frame"));
- auto* frame_document = frame_element->contentDocument();
-
- // Enable throttling for the child frame.
- frame_element->setAttribute(styleAttr, "transform: translateY(480px)");
- CompositeFrame();
- EXPECT_TRUE(frame_document->View()->CanThrottleRendering());
- EXPECT_EQ(DocumentLifecycle::kPaintClean,
- frame_document->Lifecycle().GetState());
-
- // Mutating the throttled frame followed by a beginFrame will not result in
- // a complete lifecycle update.
- // TODO(skyostil): these expectations are either wrong, or the test is
- // not exercising the code correctly. PaintClean means the entire lifecycle
- // ran.
- frame_element->setAttribute(widthAttr, "50");
- CompositeFrame();
- EXPECT_EQ(DocumentLifecycle::kPaintClean,
- frame_document->Lifecycle().GetState());
-
- // A hit test will not force a complete lifecycle update.
- WebView().HitTestResultAt(WebPoint(0, 0));
- EXPECT_EQ(DocumentLifecycle::kPaintClean,
- frame_document->Lifecycle().GetState());
-}
-
-TEST_P(FrameThrottlingTest, UnthrottlingFrameSchedulesAnimation) {
- SimRequest main_resource("https://example.com/", "text/html");
-
- LoadURL("https://example.com/");
- main_resource.Complete("<iframe sandbox id=frame></iframe>");
-
- auto* frame_element =
- toHTMLIFrameElement(GetDocument().getElementById("frame"));
-
- // First make the child hidden to enable throttling.
- frame_element->setAttribute(styleAttr, "transform: translateY(480px)");
- CompositeFrame();
- EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());
- EXPECT_FALSE(Compositor().NeedsBeginFrame());
-
- // Then bring it back on-screen. This should schedule an animation update.
- frame_element->setAttribute(styleAttr, "");
- CompositeFrame();
- EXPECT_TRUE(Compositor().NeedsBeginFrame());
-}
-
-TEST_P(FrameThrottlingTest, MutatingThrottledFrameDoesNotCauseAnimation) {
- 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 sandbox src=iframe.html></iframe>");
- frame_resource.Complete("<style> html { background: red; } </style>");
-
- // Check that the frame initially shows up.
- auto display_items1 = CompositeFrame();
- EXPECT_TRUE(display_items1.Contains(SimCanvas::kRect, "red"));
-
- auto* frame_element =
- toHTMLIFrameElement(GetDocument().getElementById("frame"));
-
- // Move the frame offscreen to throttle it.
- frame_element->setAttribute(styleAttr, "transform: translateY(480px)");
- CompositeFrame();
- EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());
-
- // Mutating the throttled frame should not cause an animation to be scheduled.
- frame_element->contentDocument()->documentElement()->setAttribute(
- styleAttr, "background: green");
- EXPECT_FALSE(Compositor().NeedsBeginFrame());
-
- // Move the frame back on screen to unthrottle it.
- frame_element->setAttribute(styleAttr, "");
- EXPECT_TRUE(Compositor().NeedsBeginFrame());
-
- // The first frame we composite after unthrottling won't contain the
- // frame's new contents because unthrottling happens at the end of the
- // lifecycle update. We need to do another composite to refresh the frame's
- // contents.
- auto display_items2 = CompositeFrame();
- EXPECT_FALSE(display_items2.Contains(SimCanvas::kRect, "green"));
- EXPECT_TRUE(Compositor().NeedsBeginFrame());
-
- auto display_items3 = CompositeFrame();
- EXPECT_TRUE(display_items3.Contains(SimCanvas::kRect, "green"));
-}
-
-TEST_P(FrameThrottlingTest, SynchronousLayoutInThrottledFrame) {
- // Create a hidden frame which is throttled.
- 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 sandbox src=iframe.html></iframe>");
- frame_resource.Complete("<div id=div></div>");
-
- auto* frame_element =
- toHTMLIFrameElement(GetDocument().getElementById("frame"));
-
- frame_element->setAttribute(styleAttr, "transform: translateY(480px)");
- CompositeFrame();
-
- // Change the size of a div in the throttled frame.
- auto* div_element = frame_element->contentDocument()->getElementById("div");
- div_element->setAttribute(styleAttr, "width: 50px");
-
- // Querying the width of the div should do a synchronous layout update even
- // though the frame is being throttled.
- EXPECT_EQ(50, div_element->clientWidth());
-}
-
-TEST_P(FrameThrottlingTest, UnthrottlingTriggersRepaint) {
- // Create a hidden frame which is throttled.
- 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 sandbox src=iframe.html></iframe>");
- frame_resource.Complete("<style> html { background: green; } </style>");
-
- // Move the frame offscreen to throttle it.
- auto* frame_element =
- toHTMLIFrameElement(GetDocument().getElementById("frame"));
- frame_element->setAttribute(styleAttr, "transform: translateY(480px)");
- EXPECT_FALSE(
- frame_element->contentDocument()->View()->CanThrottleRendering());
- CompositeFrame();
- EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());
-
- // Scroll down to unthrottle the frame. The first frame we composite after
- // scrolling won't contain the frame yet, but will schedule another repaint.
- WebView()
- .MainFrameImpl()
- ->GetFrameView()
- ->LayoutViewportScrollableArea()
- ->SetScrollOffset(ScrollOffset(0, 480), kProgrammaticScroll);
- auto display_items = CompositeFrame();
- EXPECT_FALSE(display_items.Contains(SimCanvas::kRect, "green"));
-
- // Now the frame contents should be visible again.
- auto display_items2 = CompositeFrame();
- EXPECT_TRUE(display_items2.Contains(SimCanvas::kRect, "green"));
-}
-
-TEST_P(FrameThrottlingTest, UnthrottlingTriggersRepaintInCompositedChild) {
- // Create a hidden frame with a composited child layer.
- 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 sandbox src=iframe.html></iframe>");
- frame_resource.Complete(
- "<style>"
- "div { "
- " width: 100px;"
- " height: 100px;"
- " background-color: green;"
- " transform: translateZ(0);"
- "}"
- "</style><div></div>");
-
- // Move the frame offscreen to throttle it.
- auto* frame_element =
- toHTMLIFrameElement(GetDocument().getElementById("frame"));
- frame_element->setAttribute(styleAttr, "transform: translateY(480px)");
- EXPECT_FALSE(
- frame_element->contentDocument()->View()->CanThrottleRendering());
- CompositeFrame();
- EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());
-
- // Scroll down to unthrottle the frame. The first frame we composite after
- // scrolling won't contain the frame yet, but will schedule another repaint.
- WebView()
- .MainFrameImpl()
- ->GetFrameView()
- ->LayoutViewportScrollableArea()
- ->SetScrollOffset(ScrollOffset(0, 480), kProgrammaticScroll);
- auto display_items = CompositeFrame();
- EXPECT_FALSE(display_items.Contains(SimCanvas::kRect, "green"));
-
- // Now the composited child contents should be visible again.
- auto display_items2 = CompositeFrame();
- EXPECT_TRUE(display_items2.Contains(SimCanvas::kRect, "green"));
-}
-
-TEST_P(FrameThrottlingTest, ChangeStyleInThrottledFrame) {
- // Create a hidden frame which is throttled.
- 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 sandbox src=iframe.html></iframe>");
- frame_resource.Complete("<style> html { background: red; } </style>");
-
- // Move the frame offscreen to throttle it.
- auto* frame_element =
- toHTMLIFrameElement(GetDocument().getElementById("frame"));
- frame_element->setAttribute(styleAttr, "transform: translateY(480px)");
- EXPECT_FALSE(
- frame_element->contentDocument()->View()->CanThrottleRendering());
- CompositeFrame();
- EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());
-
- // Change the background color of the frame's contents from red to green.
- frame_element->contentDocument()->body()->setAttribute(styleAttr,
- "background: green");
-
- // Scroll down to unthrottle the frame.
- WebView()
- .MainFrameImpl()
- ->GetFrameView()
- ->LayoutViewportScrollableArea()
- ->SetScrollOffset(ScrollOffset(0, 480), kProgrammaticScroll);
- auto display_items = CompositeFrame();
- EXPECT_FALSE(display_items.Contains(SimCanvas::kRect, "red"));
- EXPECT_FALSE(display_items.Contains(SimCanvas::kRect, "green"));
-
- // Make sure the new style shows up instead of the old one.
- auto display_items2 = CompositeFrame();
- EXPECT_TRUE(display_items2.Contains(SimCanvas::kRect, "green"));
-}
-
-TEST_P(FrameThrottlingTest, ChangeOriginInThrottledFrame) {
- // Create a hidden frame which is throttled.
- SimRequest main_resource("http://example.com/", "text/html");
- SimRequest frame_resource("http://sub.example.com/iframe.html", "text/html");
- LoadURL("http://example.com/");
- main_resource.Complete(
- "<iframe style='position: absolute; top: 10000px' id=frame "
- "src=http://sub.example.com/iframe.html></iframe>");
- frame_resource.Complete("");
-
- auto* frame_element =
- toHTMLIFrameElement(GetDocument().getElementById("frame"));
-
- CompositeFrame();
-
- EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());
- EXPECT_TRUE(
- frame_element->contentDocument()->GetFrame()->IsCrossOriginSubframe());
- EXPECT_FALSE(frame_element->contentDocument()
- ->View()
- ->GetLayoutView()
- ->NeedsPaintPropertyUpdate());
-
- NonThrowableExceptionState exception_state;
-
- // Security policy requires setting domain on both frames.
- GetDocument().setDomain(String("example.com"), exception_state);
- frame_element->contentDocument()->setDomain(String("example.com"),
- exception_state);
-
- EXPECT_FALSE(
- frame_element->contentDocument()->GetFrame()->IsCrossOriginSubframe());
- EXPECT_FALSE(
- frame_element->contentDocument()->View()->CanThrottleRendering());
- EXPECT_TRUE(frame_element->contentDocument()
- ->View()
- ->GetLayoutView()
- ->NeedsPaintPropertyUpdate());
-}
-
-TEST_P(FrameThrottlingTest, ThrottledFrameWithFocus) {
- WebView().GetSettings()->SetJavaScriptEnabled(true);
- WebView().GetSettings()->SetAcceleratedCompositingEnabled(true);
- RuntimeEnabledFeatures::setCompositedSelectionUpdateEnabled(true);
-
- // Create a hidden frame which is throttled and has a text selection.
- 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 sandbox=allow-scripts src=iframe.html></iframe>");
- frame_resource.Complete(
- "some text to select\n"
- "<script>\n"
- "var range = document.createRange();\n"
- "range.selectNode(document.body);\n"
- "window.getSelection().addRange(range);\n"
- "</script>\n");
-
- // Move the frame offscreen to throttle it.
- auto* frame_element =
- toHTMLIFrameElement(GetDocument().getElementById("frame"));
- frame_element->setAttribute(styleAttr, "transform: translateY(480px)");
- EXPECT_FALSE(
- frame_element->contentDocument()->View()->CanThrottleRendering());
- CompositeFrame();
- EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());
-
- // Give the frame focus and do another composite. The selection in the
- // compositor should be cleared because the frame is throttled.
- EXPECT_FALSE(Compositor().HasSelection());
- GetDocument().GetPage()->GetFocusController().SetFocusedFrame(
- frame_element->contentDocument()->GetFrame());
- GetDocument().body()->setAttribute(styleAttr, "background: green");
- CompositeFrame();
- EXPECT_FALSE(Compositor().HasSelection());
-}
-
-TEST_P(FrameThrottlingTest, ScrollingCoordinatorShouldSkipThrottledFrame) {
- WebView().GetSettings()->SetAcceleratedCompositingEnabled(true);
-
- // Create a hidden frame which is throttled.
- 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 sandbox src=iframe.html></iframe>");
- frame_resource.Complete(
- "<style> html { background-image: linear-gradient(red, blue); "
- "background-attachment: fixed; } </style>");
-
- // Move the frame offscreen to throttle it.
- auto* frame_element =
- toHTMLIFrameElement(GetDocument().getElementById("frame"));
- frame_element->setAttribute(styleAttr, "transform: translateY(480px)");
- EXPECT_FALSE(
- frame_element->contentDocument()->View()->CanThrottleRendering());
- CompositeFrame();
- EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());
-
- // Change style of the frame's content to make it in VisualUpdatePending
- // state.
- frame_element->contentDocument()->body()->setAttribute(styleAttr,
- "background: green");
- // Change root frame's layout so that the next lifecycle update will call
- // ScrollingCoordinator::updateAfterCompositingChangeIfNeeded().
- GetDocument().body()->setAttribute(styleAttr, "margin: 20px");
- EXPECT_EQ(DocumentLifecycle::kVisualUpdatePending,
- frame_element->contentDocument()->Lifecycle().GetState());
-
- DocumentLifecycle::AllowThrottlingScope throttling_scope(
- GetDocument().Lifecycle());
- // This will call ScrollingCoordinator::updateAfterCompositingChangeIfNeeded()
- // and should not cause assert failure about
- // isAllowedToQueryCompositingState() in the throttled frame.
- GetDocument().View()->UpdateAllLifecyclePhases();
- testing::RunPendingTasks();
- EXPECT_EQ(DocumentLifecycle::kVisualUpdatePending,
- frame_element->contentDocument()->Lifecycle().GetState());
- // The fixed background in the throttled sub frame should not cause main
- // thread scrolling.
- EXPECT_FALSE(GetDocument()
- .View()
- ->LayoutViewportScrollableArea()
- ->ShouldScrollOnMainThread());
-
- // Make the frame visible by changing its transform. This doesn't cause a
- // layout, but should still unthrottle the frame.
- frame_element->setAttribute(styleAttr, "transform: translateY(0px)");
- CompositeFrame();
- EXPECT_FALSE(
- frame_element->contentDocument()->View()->CanThrottleRendering());
- // The fixed background in the throttled sub frame should be considered.
- EXPECT_TRUE(frame_element->contentDocument()
- ->View()
- ->LayoutViewportScrollableArea()
- ->ShouldScrollOnMainThread());
- EXPECT_FALSE(GetDocument()
- .View()
- ->LayoutViewportScrollableArea()
- ->ShouldScrollOnMainThread());
-}
-
-TEST_P(FrameThrottlingTest, ScrollingCoordinatorShouldSkipThrottledLayer) {
- WebView().GetSettings()->SetJavaScriptEnabled(true);
- WebView().GetSettings()->SetAcceleratedCompositingEnabled(true);
- WebView().GetSettings()->SetPreferCompositingToLCDTextEnabled(true);
-
- // Create a hidden frame which is throttled and has a touch handler inside a
- // composited layer.
- 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 sandbox=allow-scripts src=iframe.html></iframe>");
- frame_resource.Complete(
- "<div id=div style='transform: translateZ(0)' ontouchstart='foo()'>touch "
- "handler</div>");
-
- // Move the frame offscreen to throttle it.
- auto* frame_element =
- toHTMLIFrameElement(GetDocument().getElementById("frame"));
- frame_element->setAttribute(styleAttr, "transform: translateY(480px)");
- EXPECT_FALSE(
- frame_element->contentDocument()->View()->CanThrottleRendering());
- CompositeFrame();
- EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());
-
- // Change style of the frame's content to make it in VisualUpdatePending
- // state.
- frame_element->contentDocument()->body()->setAttribute(styleAttr,
- "background: green");
- // Change root frame's layout so that the next lifecycle update will call
- // ScrollingCoordinator::updateAfterCompositingChangeIfNeeded().
- GetDocument().body()->setAttribute(styleAttr, "margin: 20px");
- EXPECT_EQ(DocumentLifecycle::kVisualUpdatePending,
- frame_element->contentDocument()->Lifecycle().GetState());
-
- DocumentLifecycle::AllowThrottlingScope throttling_scope(
- GetDocument().Lifecycle());
- // This will call ScrollingCoordinator::updateAfterCompositingChangeIfNeeded()
- // and should not cause assert failure about
- // isAllowedToQueryCompositingState() in the throttled frame.
- GetDocument().View()->UpdateAllLifecyclePhases();
- testing::RunPendingTasks();
- EXPECT_EQ(DocumentLifecycle::kVisualUpdatePending,
- frame_element->contentDocument()->Lifecycle().GetState());
-}
-
-TEST_P(FrameThrottlingTest,
- ScrollingCoordinatorShouldSkipCompositedThrottledFrame) {
- WebView().GetSettings()->SetAcceleratedCompositingEnabled(true);
- WebView().GetSettings()->SetPreferCompositingToLCDTextEnabled(true);
-
- // Create a hidden frame which is throttled.
- 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 sandbox src=iframe.html></iframe>");
- frame_resource.Complete("<div style='height: 2000px'></div>");
-
- // Move the frame offscreen to throttle it.
- auto* frame_element =
- toHTMLIFrameElement(GetDocument().getElementById("frame"));
- frame_element->setAttribute(styleAttr, "transform: translateY(480px)");
- EXPECT_FALSE(
- frame_element->contentDocument()->View()->CanThrottleRendering());
- CompositeFrame();
- EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());
-
- // Change style of the frame's content to make it in VisualUpdatePending
- // state.
- frame_element->contentDocument()->body()->setAttribute(styleAttr,
- "background: green");
- // Change root frame's layout so that the next lifecycle update will call
- // ScrollingCoordinator::updateAfterCompositingChangeIfNeeded().
- GetDocument().body()->setAttribute(styleAttr, "margin: 20px");
- EXPECT_EQ(DocumentLifecycle::kVisualUpdatePending,
- frame_element->contentDocument()->Lifecycle().GetState());
-
- DocumentLifecycle::AllowThrottlingScope throttling_scope(
- GetDocument().Lifecycle());
- // This will call ScrollingCoordinator::updateAfterCompositingChangeIfNeeded()
- // and should not cause assert failure about
- // isAllowedToQueryCompositingState() in the throttled frame.
- CompositeFrame();
- EXPECT_EQ(DocumentLifecycle::kVisualUpdatePending,
- frame_element->contentDocument()->Lifecycle().GetState());
-
- // Make the frame visible by changing its transform. This doesn't cause a
- // layout, but should still unthrottle the frame.
- frame_element->setAttribute(styleAttr, "transform: translateY(0px)");
- CompositeFrame(); // Unthrottle the frame.
- CompositeFrame(); // Handle the pending visual update of the unthrottled
- // frame.
- EXPECT_EQ(DocumentLifecycle::kPaintClean,
- frame_element->contentDocument()->Lifecycle().GetState());
- EXPECT_TRUE(
- frame_element->contentDocument()->View()->UsesCompositedScrolling());
-}
-
-TEST_P(FrameThrottlingTest, UnthrottleByTransformingWithoutLayout) {
- WebView().GetSettings()->SetAcceleratedCompositingEnabled(true);
-
- // Create a hidden frame which is throttled.
- 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 sandbox src=iframe.html></iframe>");
- frame_resource.Complete("");
-
- // Move the frame offscreen to throttle it.
- auto* frame_element =
- toHTMLIFrameElement(GetDocument().getElementById("frame"));
- frame_element->setAttribute(styleAttr, "transform: translateY(480px)");
- EXPECT_FALSE(
- frame_element->contentDocument()->View()->CanThrottleRendering());
- CompositeFrame();
- EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());
-
- // Make the frame visible by changing its transform. This doesn't cause a
- // layout, but should still unthrottle the frame.
- frame_element->setAttribute(styleAttr, "transform: translateY(0px)");
- CompositeFrame();
- EXPECT_FALSE(
- frame_element->contentDocument()->View()->CanThrottleRendering());
-}
-
-TEST_P(FrameThrottlingTest, ThrottledTopLevelEventHandlerIgnored) {
- WebView().GetSettings()->SetAcceleratedCompositingEnabled(true);
- WebView().GetSettings()->SetJavaScriptEnabled(true);
- EXPECT_EQ(0u, TouchHandlerRegionSize());
-
- // Create a frame which is throttled and has two different types of
- // top-level touchstart handlers.
- 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 sandbox=allow-scripts src=iframe.html></iframe>");
- frame_resource.Complete(
- "<script>"
- "window.addEventListener('touchstart', function(){}, {passive: false});"
- "document.addEventListener('touchstart', function(){}, {passive: false});"
- "</script>");
- auto* frame_element =
- toHTMLIFrameElement(GetDocument().getElementById("frame"));
- frame_element->setAttribute(styleAttr, "transform: translateY(480px)");
- CompositeFrame(); // Throttle the frame.
- CompositeFrame(); // Update touch handler regions.
-
- // The touch handlers in the throttled frame should have been ignored.
- EXPECT_EQ(0u, TouchHandlerRegionSize());
-
- // Unthrottling the frame makes the touch handlers active again. Note that
- // both handlers get combined into the same rectangle in the region, so
- // there is only one rectangle in total.
- frame_element->setAttribute(styleAttr, "transform: translateY(0px)");
- CompositeFrame(); // Unthrottle the frame.
- CompositeFrame(); // Update touch handler regions.
- EXPECT_EQ(1u, TouchHandlerRegionSize());
-}
-
-TEST_P(FrameThrottlingTest, ThrottledEventHandlerIgnored) {
- WebView().GetSettings()->SetAcceleratedCompositingEnabled(true);
- WebView().GetSettings()->SetJavaScriptEnabled(true);
- EXPECT_EQ(0u, TouchHandlerRegionSize());
-
- // Create a frame which is throttled and has a non-top-level touchstart
- // handler.
- 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 sandbox=allow-scripts src=iframe.html></iframe>");
- frame_resource.Complete(
- "<div id=d>touch handler</div>"
- "<script>"
- "document.querySelector('#d').addEventListener('touchstart', "
- "function(){});"
- "</script>");
- auto* frame_element =
- toHTMLIFrameElement(GetDocument().getElementById("frame"));
- frame_element->setAttribute(styleAttr, "transform: translateY(480px)");
- CompositeFrame(); // Throttle the frame.
- CompositeFrame(); // Update touch handler regions.
-
- // The touch handler in the throttled frame should have been ignored.
- EXPECT_EQ(0u, TouchHandlerRegionSize());
-
- // Unthrottling the frame makes the touch handler active again.
- frame_element->setAttribute(styleAttr, "transform: translateY(0px)");
- CompositeFrame(); // Unthrottle the frame.
- CompositeFrame(); // Update touch handler regions.
- EXPECT_EQ(1u, TouchHandlerRegionSize());
-}
-
-TEST_P(FrameThrottlingTest, DumpThrottledFrame) {
- WebView().GetSettings()->SetJavaScriptEnabled(true);
-
- // Create a frame which is throttled.
- 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(
- "main <iframe id=frame sandbox=allow-scripts src=iframe.html></iframe>");
- frame_resource.Complete("");
- auto* frame_element =
- toHTMLIFrameElement(GetDocument().getElementById("frame"));
- frame_element->setAttribute(styleAttr, "transform: translateY(480px)");
- CompositeFrame();
- EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());
-
- LocalFrame* local_frame = ToLocalFrame(frame_element->ContentFrame());
- local_frame->GetScriptController().ExecuteScriptInMainWorld(
- "document.body.innerHTML = 'throttled'");
- EXPECT_FALSE(Compositor().NeedsBeginFrame());
-
- // The dumped contents should not include the throttled frame.
- DocumentLifecycle::AllowThrottlingScope throttling_scope(
- GetDocument().Lifecycle());
- WebString result = WebFrameContentDumper::DeprecatedDumpFrameTreeAsText(
- WebView().MainFrameImpl(), 1024);
- EXPECT_NE(std::string::npos, result.Utf8().find("main"));
- EXPECT_EQ(std::string::npos, result.Utf8().find("throttled"));
-}
-
-TEST_P(FrameThrottlingTest, PaintingViaContentLayerDelegateIsThrottled) {
- WebView().GetSettings()->SetAcceleratedCompositingEnabled(true);
- WebView().GetSettings()->SetPreferCompositingToLCDTextEnabled(true);
-
- // Create a hidden frame which is throttled.
- 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 sandbox src=iframe.html></iframe>");
- frame_resource.Complete("throttled");
- CompositeFrame();
-
- // Move the frame offscreen to throttle it and make sure it is backed by a
- // graphics layer.
- auto* frame_element =
- toHTMLIFrameElement(GetDocument().getElementById("frame"));
- frame_element->setAttribute(styleAttr,
- "transform: translateY(480px) translateZ(0px)");
- EXPECT_FALSE(
- frame_element->contentDocument()->View()->CanThrottleRendering());
- CompositeFrame();
- EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());
-
- // If painting of the iframe is throttled, we should only receive two
- // drawing items.
- MockWebDisplayItemList display_items;
- EXPECT_CALL(display_items, AppendDrawingItem(_, _)).Times(2);
-
- GraphicsLayer* layer = WebView().RootGraphicsLayer();
- PaintRecursively(layer, &display_items);
-}
-
-TEST_P(FrameThrottlingTest, ThrottleSubtreeAtomically) {
- // Create two nested frames which are throttled.
- SimRequest main_resource("https://example.com/", "text/html");
- SimRequest frame_resource("https://example.com/iframe.html", "text/html");
- SimRequest child_frame_resource("https://example.com/child-iframe.html",
- "text/html");
-
- LoadURL("https://example.com/");
- main_resource.Complete("<iframe id=frame sandbox src=iframe.html></iframe>");
- frame_resource.Complete(
- "<iframe id=child-frame sandbox src=child-iframe.html></iframe>");
- child_frame_resource.Complete("");
-
- // Move both frames offscreen, but don't run the intersection observers yet.
- auto* frame_element =
- toHTMLIFrameElement(GetDocument().getElementById("frame"));
- auto* child_frame_element = toHTMLIFrameElement(
- frame_element->contentDocument()->getElementById("child-frame"));
- frame_element->setAttribute(styleAttr, "transform: translateY(480px)");
- Compositor().BeginFrame();
- EXPECT_FALSE(
- frame_element->contentDocument()->View()->CanThrottleRendering());
- EXPECT_FALSE(
- child_frame_element->contentDocument()->View()->CanThrottleRendering());
-
- // Only run the intersection observer for the parent frame. Both frames
- // should immediately become throttled. This simulates the case where a task
- // such as BeginMainFrame runs in the middle of dispatching intersection
- // observer notifications.
- frame_element->contentDocument()
- ->View()
- ->UpdateRenderThrottlingStatusForTesting();
- EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());
- EXPECT_TRUE(
- child_frame_element->contentDocument()->View()->CanThrottleRendering());
-
- // Both frames should still be throttled after the second notification.
- child_frame_element->contentDocument()
- ->View()
- ->UpdateRenderThrottlingStatusForTesting();
- EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());
- EXPECT_TRUE(
- child_frame_element->contentDocument()->View()->CanThrottleRendering());
-
- // Move the frame back on screen but don't update throttling yet.
- frame_element->setAttribute(styleAttr, "transform: translateY(0px)");
- Compositor().BeginFrame();
- EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());
- EXPECT_TRUE(
- child_frame_element->contentDocument()->View()->CanThrottleRendering());
-
- // Update throttling for the child. It should remain throttled because the
- // parent is still throttled.
- child_frame_element->contentDocument()
- ->View()
- ->UpdateRenderThrottlingStatusForTesting();
- EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());
- EXPECT_TRUE(
- child_frame_element->contentDocument()->View()->CanThrottleRendering());
-
- // Updating throttling on the parent should unthrottle both frames.
- frame_element->contentDocument()
- ->View()
- ->UpdateRenderThrottlingStatusForTesting();
- EXPECT_FALSE(
- frame_element->contentDocument()->View()->CanThrottleRendering());
- EXPECT_FALSE(
- child_frame_element->contentDocument()->View()->CanThrottleRendering());
-}
-
-TEST_P(FrameThrottlingTest, SkipPaintingLayersInThrottledFrames) {
- WebView().GetSettings()->SetAcceleratedCompositingEnabled(true);
- WebView().GetSettings()->SetPreferCompositingToLCDTextEnabled(true);
-
- 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 sandbox src=iframe.html></iframe>");
- frame_resource.Complete(
- "<div id=div style='transform: translateZ(0); background: "
- "red'>layer</div>");
- auto display_items = CompositeFrame();
- EXPECT_TRUE(display_items.Contains(SimCanvas::kRect, "red"));
-
- auto* frame_element =
- toHTMLIFrameElement(GetDocument().getElementById("frame"));
- frame_element->setAttribute(styleAttr, "transform: translateY(480px)");
- CompositeFrame();
- EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());
-
- auto* frame_document = frame_element->contentDocument();
- EXPECT_EQ(DocumentLifecycle::kPaintClean,
- frame_document->Lifecycle().GetState());
-
- // Simulate the paint for a graphics layer being externally invalidated
- // (e.g., by video playback).
- frame_document->View()
- ->GetLayoutViewItem()
- .InvalidatePaintForViewAndCompositedLayers();
-
- // The layer inside the throttled frame should not get painted.
- auto display_items2 = CompositeFrame();
- EXPECT_FALSE(display_items2.Contains(SimCanvas::kRect, "red"));
-}
-
-TEST_P(FrameThrottlingTest, SynchronousLayoutInAnimationFrameCallback) {
- WebView().GetSettings()->SetJavaScriptEnabled(true);
-
- // Prepare a page with two cross origin frames (from the same origin so they
- // are able to access eachother).
- SimRequest main_resource("https://example.com/", "text/html");
- SimRequest first_frame_resource("https://thirdparty.com/first.html",
- "text/html");
- SimRequest second_frame_resource("https://thirdparty.com/second.html",
- "text/html");
- LoadURL("https://example.com/");
- main_resource.Complete(
- "<iframe id=first name=first "
- "src='https://thirdparty.com/first.html'></iframe>\n"
- "<iframe id=second name=second "
- "src='https://thirdparty.com/second.html'></iframe>");
-
- // The first frame contains just a simple div. This frame will be made
- // throttled.
- first_frame_resource.Complete("<div id=d>first frame</div>");
-
- // The second frame just used to execute a requestAnimationFrame callback.
- second_frame_resource.Complete("");
-
- // Throttle the first frame.
- auto* first_frame_element =
- toHTMLIFrameElement(GetDocument().getElementById("first"));
- first_frame_element->setAttribute(styleAttr, "transform: translateY(480px)");
- CompositeFrame();
- EXPECT_TRUE(
- first_frame_element->contentDocument()->View()->CanThrottleRendering());
-
- // Run a animation frame callback in the second frame which mutates the
- // contents of the first frame and causes a synchronous style update. This
- // should not result in an unexpected lifecycle state even if the first
- // frame is throttled during the animation frame callback.
- auto* second_frame_element =
- toHTMLIFrameElement(GetDocument().getElementById("second"));
- LocalFrame* local_frame = ToLocalFrame(second_frame_element->ContentFrame());
- local_frame->GetScriptController().ExecuteScriptInMainWorld(
- "window.requestAnimationFrame(function() {\n"
- " var throttledFrame = window.parent.frames.first;\n"
- " throttledFrame.document.documentElement.style = 'margin: 50px';\n"
- " throttledFrame.document.querySelector('#d').getBoundingClientRect();\n"
- "});\n");
- CompositeFrame();
-}
-
-TEST_P(FrameThrottlingTest, AllowOneAnimationFrame) {
- WebView().GetSettings()->SetJavaScriptEnabled(true);
-
- // Prepare a page with two cross origin frames (from the same origin so they
- // are able to access eachother).
- SimRequest main_resource("https://example.com/", "text/html");
- SimRequest frame_resource("https://thirdparty.com/frame.html", "text/html");
- LoadURL("https://example.com/");
- main_resource.Complete(
- "<iframe id=frame style=\"position: fixed; top: -10000px\" "
- "src='https://thirdparty.com/frame.html'></iframe>");
-
- frame_resource.Complete(
- "<script>"
- "window.requestAnimationFrame(() => { window.didRaf = true; });"
- "</script>");
-
- auto* frame_element =
- toHTMLIFrameElement(GetDocument().getElementById("frame"));
- CompositeFrame();
- EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());
-
- LocalFrame* local_frame = ToLocalFrame(frame_element->ContentFrame());
- v8::HandleScope scope(v8::Isolate::GetCurrent());
- v8::Local<v8::Value> result =
- local_frame->GetScriptController().ExecuteScriptInMainWorldAndReturnValue(
- ScriptSourceCode("window.didRaf;"));
- EXPECT_TRUE(result->IsTrue());
-}
-
-TEST_P(FrameThrottlingTest, UpdatePaintPropertiesOnUnthrottling) {
- if (!RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled())
- return;
-
- 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 sandbox src=iframe.html></iframe>");
- frame_resource.Complete("<div id='div'>Inner</div>");
- CompositeFrame();
-
- auto* frame_element =
- toHTMLIFrameElement(GetDocument().getElementById("frame"));
- auto* frame_document = frame_element->contentDocument();
- auto* inner_div = frame_document->getElementById("div");
- auto* inner_div_object = inner_div->GetLayoutObject();
- EXPECT_FALSE(frame_document->View()->ShouldThrottleRendering());
-
- frame_element->setAttribute(HTMLNames::styleAttr,
- "transform: translateY(1000px)");
- CompositeFrame();
- EXPECT_TRUE(frame_document->View()->CanThrottleRendering());
- EXPECT_FALSE(inner_div_object->PaintProperties());
-
- // Mutating the throttled frame should not cause paint property update.
- inner_div->setAttribute(HTMLNames::styleAttr, "transform: translateY(20px)");
- EXPECT_FALSE(Compositor().NeedsBeginFrame());
- EXPECT_TRUE(frame_document->View()->CanThrottleRendering());
- {
- DocumentLifecycle::AllowThrottlingScope throttling_scope(
- GetDocument().Lifecycle());
- GetDocument().View()->UpdateAllLifecyclePhases();
- }
- EXPECT_FALSE(inner_div_object->PaintProperties());
-
- // Move the frame back on screen to unthrottle it.
- frame_element->setAttribute(HTMLNames::styleAttr, "");
- // The first update unthrottles the frame, the second actually update layout
- // and paint properties etc.
- CompositeFrame();
- CompositeFrame();
- EXPECT_FALSE(frame_document->View()->CanThrottleRendering());
- EXPECT_EQ(
- TransformationMatrix().Translate(0, 20),
- inner_div->GetLayoutObject()->PaintProperties()->Transform()->Matrix());
-}
-
-TEST_P(FrameThrottlingTest, DisplayNoneNotThrottled) {
- SimRequest main_resource("https://example.com/", "text/html");
-
- LoadURL("https://example.com/");
- main_resource.Complete(
- "<style>iframe { transform: translateY(480px); }</style>"
- "<iframe sandbox id=frame></iframe>");
-
- auto* frame_element =
- toHTMLIFrameElement(GetDocument().getElementById("frame"));
- auto* frame_document = frame_element->contentDocument();
-
- // Initially the frame is throttled as it is offscreen.
- CompositeFrame();
- EXPECT_TRUE(frame_document->View()->CanThrottleRendering());
-
- // Setting display:none unthrottles the frame.
- frame_element->setAttribute(styleAttr, "display: none");
- CompositeFrame();
- EXPECT_FALSE(frame_document->View()->CanThrottleRendering());
-}
-
-TEST_P(FrameThrottlingTest, DisplayNoneChildrenRemainThrottled) {
- // Create two nested frames which are throttled.
- SimRequest main_resource("https://example.com/", "text/html");
- SimRequest frame_resource("https://example.com/iframe.html", "text/html");
- SimRequest child_frame_resource("https://example.com/child-iframe.html",
- "text/html");
-
- LoadURL("https://example.com/");
- main_resource.Complete("<iframe id=frame sandbox src=iframe.html></iframe>");
- frame_resource.Complete(
- "<iframe id=child-frame sandbox src=child-iframe.html></iframe>");
- child_frame_resource.Complete("");
-
- // Move both frames offscreen to make them throttled.
- auto* frame_element =
- toHTMLIFrameElement(GetDocument().getElementById("frame"));
- auto* child_frame_element = toHTMLIFrameElement(
- frame_element->contentDocument()->getElementById("child-frame"));
- frame_element->setAttribute(styleAttr, "transform: translateY(480px)");
- CompositeFrame();
- EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());
- EXPECT_TRUE(
- child_frame_element->contentDocument()->View()->CanThrottleRendering());
-
- // Setting display:none for the parent frame unthrottles the parent but not
- // the child. This behavior matches Safari.
- frame_element->setAttribute(styleAttr, "display: none");
- CompositeFrame();
- EXPECT_FALSE(
- frame_element->contentDocument()->View()->CanThrottleRendering());
- EXPECT_TRUE(
- child_frame_element->contentDocument()->View()->CanThrottleRendering());
-}
-
-} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698