| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "config.h" | 5 #include "config.h" |
| 6 | 6 |
| 7 #include "core/dom/Document.h" | 7 #include "core/dom/Document.h" |
| 8 #include "core/frame/FrameView.h" | 8 #include "core/page/Page.h" |
| 9 #include "web/WebLocalFrameImpl.h" | 9 #include "web/WebLocalFrameImpl.h" |
| 10 #include "web/tests/FrameTestHelpers.h" | 10 #include "web/tests/FrameTestHelpers.h" |
| 11 #include "web/tests/sim/SimCompositor.h" | |
| 12 #include "web/tests/sim/SimLayerTreeView.h" | 11 #include "web/tests/sim/SimLayerTreeView.h" |
| 13 #include "web/tests/sim/SimNetwork.h" | 12 #include "web/tests/sim/SimNetwork.h" |
| 14 #include "web/tests/sim/SimRequest.h" | 13 #include "web/tests/sim/SimRequest.h" |
| 15 #include "web/tests/sim/SimWebViewClient.h" | 14 #include "web/tests/sim/SimWebViewClient.h" |
| 16 #include <gtest/gtest.h> | 15 #include <gtest/gtest.h> |
| 17 | 16 |
| 18 namespace blink { | 17 namespace blink { |
| 19 | 18 |
| 20 class DocumentLoadingRenderingTest : public ::testing::Test { | 19 class DocumentLoadingRenderingTest : public ::testing::Test { |
| 21 protected: | 20 protected: |
| 22 DocumentLoadingRenderingTest() | 21 DocumentLoadingRenderingTest() |
| 23 : m_webViewClient(m_layerTreeView) | 22 : m_webViewClient(m_layerTreeView) |
| 24 , m_compositor(m_layerTreeView) | |
| 25 { | 23 { |
| 26 m_webViewHelper.initialize(true, nullptr, &m_webViewClient); | 24 m_webViewHelper.initialize(true, nullptr, &m_webViewClient); |
| 27 m_compositor.setWebViewImpl(webView()); | 25 Document::setThreadedParsingEnabledForUnitTestsOnly(false); |
| 28 Document::setThreadedParsingEnabledForTesting(false); | |
| 29 } | 26 } |
| 30 | 27 |
| 31 virtual ~DocumentLoadingRenderingTest() | 28 virtual ~DocumentLoadingRenderingTest() |
| 32 { | 29 { |
| 33 Document::setThreadedParsingEnabledForTesting(true); | 30 Document::setThreadedParsingEnabledForUnitTestsOnly(true); |
| 34 } | 31 } |
| 35 | 32 |
| 36 void loadURL(const String& url) | 33 void loadURL(const String& url) |
| 37 { | 34 { |
| 38 WebURLRequest request; | 35 WebURLRequest request; |
| 39 request.initialize(); | 36 request.initialize(); |
| 40 request.setURL(KURL(ParsedURLString, url)); | 37 request.setURL(KURL(ParsedURLString, url)); |
| 41 webView().mainFrameImpl()->loadRequest(request); | 38 m_webViewHelper.webViewImpl()->mainFrameImpl()->loadRequest(request); |
| 42 } | 39 } |
| 43 | 40 |
| 44 Document& document() | 41 Document& document() { return *toLocalFrame(m_webViewHelper.webViewImpl()->p
age()->mainFrame())->document(); } |
| 45 { | |
| 46 return *webView().mainFrameImpl()->frame()->document(); | |
| 47 } | |
| 48 | |
| 49 WebViewImpl& webView() | |
| 50 { | |
| 51 return *m_webViewHelper.webViewImpl(); | |
| 52 } | |
| 53 | 42 |
| 54 SimNetwork m_network; | 43 SimNetwork m_network; |
| 55 SimLayerTreeView m_layerTreeView; | 44 SimLayerTreeView m_layerTreeView; |
| 56 SimWebViewClient m_webViewClient; | 45 SimWebViewClient m_webViewClient; |
| 57 SimCompositor m_compositor; | |
| 58 FrameTestHelpers::WebViewHelper m_webViewHelper; | 46 FrameTestHelpers::WebViewHelper m_webViewHelper; |
| 59 }; | 47 }; |
| 60 | 48 |
| 61 TEST_F(DocumentLoadingRenderingTest, ShouldResumeCommitsAfterBodyParsedWithoutSh
eets) | 49 TEST_F(DocumentLoadingRenderingTest, ShouldResumeCommitsAfterBodyParsedWithoutSh
eets) |
| 62 { | 50 { |
| 63 SimRequest mainResource("https://example.com/test.html", "text/html"); | 51 SimRequest mainResource("https://example.com/test.html", "text/html"); |
| 64 | 52 |
| 65 loadURL("https://example.com/test.html"); | 53 loadURL("https://example.com/test.html"); |
| 66 | 54 |
| 67 mainResource.start(); | 55 mainResource.start(); |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 EXPECT_NE(nullptr, element); | 193 EXPECT_NE(nullptr, element); |
| 206 element->setAttribute(HTMLNames::hrefAttr, "second.css"); | 194 element->setAttribute(HTMLNames::hrefAttr, "second.css"); |
| 207 EXPECT_FALSE(m_layerTreeView.needsAnimate()); | 195 EXPECT_FALSE(m_layerTreeView.needsAnimate()); |
| 208 | 196 |
| 209 secondCssResource.start(); | 197 secondCssResource.start(); |
| 210 secondCssResource.write("body { color: red; }"); | 198 secondCssResource.write("body { color: red; }"); |
| 211 secondCssResource.finish(); | 199 secondCssResource.finish(); |
| 212 EXPECT_TRUE(m_layerTreeView.needsAnimate()); | 200 EXPECT_TRUE(m_layerTreeView.needsAnimate()); |
| 213 } | 201 } |
| 214 | 202 |
| 215 TEST_F(DocumentLoadingRenderingTest, ShouldNotPaintIframeContentWithPendingSheet
s) | |
| 216 { | |
| 217 SimRequest mainResource("https://example.com/test.html", "text/html"); | |
| 218 SimRequest frameResource("https://example.com/frame.html", "text/html"); | |
| 219 SimRequest cssResource("https://example.com/test.css", "text/css"); | |
| 220 | |
| 221 loadURL("https://example.com/test.html"); | |
| 222 | |
| 223 webView().resize(WebSize(800, 600)); | |
| 224 | |
| 225 mainResource.start(); | |
| 226 mainResource.write( | |
| 227 "<!DOCTYPE html>" | |
| 228 "<iframe src=frame.html></iframe>" | |
| 229 "<p style='transform: translateZ(0)'>Hello World</p>" | |
| 230 ); | |
| 231 mainResource.finish(); | |
| 232 | |
| 233 // Main page is ready to begin painting as there's no pending sheets. | |
| 234 // The frame is not yet loaded, so we only paint the top level page. | |
| 235 auto frame1 = m_compositor.beginFrame(); | |
| 236 EXPECT_TRUE(frame1.didDrawText); | |
| 237 | |
| 238 frameResource.start(); | |
| 239 frameResource.write( | |
| 240 "<!DOCTYPE html>" | |
| 241 "<style>html { background: pink }</style>" | |
| 242 "<link rel=stylesheet href=test.css>" | |
| 243 "<p style='background: yellow'>Hello World</p>" | |
| 244 "<div style='transform: translateZ(0); background: green;'>" | |
| 245 " <p style='background: blue'>Hello Layer</p>" | |
| 246 " <div style='position: relative; background: red;'>Hello World</div>
" | |
| 247 "</div>" | |
| 248 ); | |
| 249 frameResource.finish(); | |
| 250 | |
| 251 // Trigger a layout with pending sheets. For example a page could trigger | |
| 252 // this by doing offsetTop in a setTimeout, or by a parent frame executing | |
| 253 // script that touched offsetTop in the child frame. | |
| 254 LocalFrame* childFrame = toLocalFrame(document().frame()->tree().firstChild(
)); | |
| 255 childFrame->document()->updateLayoutIgnorePendingStylesheets(); | |
| 256 | |
| 257 auto frame2 = m_compositor.beginFrame(); | |
| 258 | |
| 259 // The child frame still has pending sheets, and the parent frame has no | |
| 260 // invalid paint so we shouldn't draw any text. | |
| 261 EXPECT_FALSE(frame2.didDrawText); | |
| 262 | |
| 263 // One per DeprecatedPaintLayer, 2 in the main frame and 3 in the iframe = 5
. | |
| 264 // 1 for the background of the iframe. | |
| 265 // 1 for the background of the composited transform layer. | |
| 266 // TODO(esprehn): Why FOUC the background (borders, etc.) of iframes and | |
| 267 // composited layers? Seems like a bug. | |
| 268 EXPECT_EQ(7, frame2.drawCount); | |
| 269 | |
| 270 // Finish loading the sheets in the child frame. After it should issue a | |
| 271 // paint invalidation for every layer since frame2 painted them but skipped | |
| 272 // painting the real content to avoid FOUC. | |
| 273 cssResource.start(); | |
| 274 cssResource.finish(); | |
| 275 | |
| 276 // First frame where all frames are loaded, should paint the text in the | |
| 277 // child frame. | |
| 278 auto frame3 = m_compositor.beginFrame(); | |
| 279 EXPECT_TRUE(frame3.didDrawText); | |
| 280 } | |
| 281 | |
| 282 } // namespace blink | 203 } // namespace blink |
| OLD | NEW |