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