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

Side by Side Diff: third_party/WebKit/Source/core/dom/ElementTest.cpp

Issue 2647533002: Force compositing inputs to be clean for getBoundingClientRect (Closed)
Patch Set: Rebase Created 3 years, 11 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 unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "core/dom/Element.h" 5 #include "core/dom/Element.h"
6 6
7 #include "core/dom/Document.h" 7 #include "core/dom/Document.h"
8 #include "core/frame/FrameView.h" 8 #include "core/frame/FrameView.h"
9 #include "core/html/HTMLHtmlElement.h" 9 #include "core/html/HTMLHtmlElement.h"
10 #include "core/layout/LayoutBoxModelObject.h"
11 #include "core/paint/PaintLayer.h"
10 #include "core/testing/DummyPageHolder.h" 12 #include "core/testing/DummyPageHolder.h"
11 #include "testing/gtest/include/gtest/gtest.h" 13 #include "testing/gtest/include/gtest/gtest.h"
12 #include <memory> 14 #include <memory>
13 15
14 namespace blink { 16 namespace blink {
15 17
16 TEST(ElementTest, SupportsFocus) { 18 TEST(ElementTest, SupportsFocus) {
17 std::unique_ptr<DummyPageHolder> pageHolder = DummyPageHolder::create(); 19 std::unique_ptr<DummyPageHolder> pageHolder = DummyPageHolder::create();
18 Document& document = pageHolder->document(); 20 Document& document = pageHolder->document();
19 DCHECK(isHTMLHtmlElement(document.documentElement())); 21 DCHECK(isHTMLHtmlElement(document.documentElement()));
20 document.setDesignMode("on"); 22 document.setDesignMode("on");
21 document.view()->updateAllLifecyclePhases(); 23 document.view()->updateAllLifecyclePhases();
22 EXPECT_TRUE(document.documentElement()->supportsFocus()) 24 EXPECT_TRUE(document.documentElement()->supportsFocus())
23 << "<html> with designMode=on should be focusable."; 25 << "<html> with designMode=on should be focusable.";
24 } 26 }
25 27
28 // Verifies that calling getBoundingClientRect cleans compositor inputs.
29 // Cleaning the compositor inputs is required so that position:sticky elements
30 // and their descendants have the correct location.
31 TEST(ElementTest, GetBoundingClientRectUpdatesCompositorInputs) {
32 std::unique_ptr<DummyPageHolder> pageHolder = DummyPageHolder::create();
33 Document& document = pageHolder->document();
34
35 document.view()->updateAllLifecyclePhases();
36 EXPECT_EQ(DocumentLifecycle::PaintClean, document.lifecycle().state());
37
38 document.body()->setInnerHTML("<div id='test'></div>");
39 EXPECT_EQ(DocumentLifecycle::VisualUpdatePending,
40 document.lifecycle().state());
41
42 document.body()->getBoundingClientRect();
43 EXPECT_EQ(DocumentLifecycle::CompositingClean, document.lifecycle().state());
44 }
45
46 // Verifies that calling scrollIntoView* cleans compositor inputs. Cleaning the
47 // compositor inputs is required so that position:sticky elements and their
48 // descendants have the correct location.
49 TEST(ElementTest, ScrollIntoViewUpdatesCompositorInputs) {
50 std::unique_ptr<DummyPageHolder> pageHolder = DummyPageHolder::create();
51 Document& document = pageHolder->document();
52
53 document.view()->updateAllLifecyclePhases();
54 EXPECT_EQ(DocumentLifecycle::PaintClean, document.lifecycle().state());
55
56 document.body()->setInnerHTML("<div id='test'></div>");
57 EXPECT_EQ(DocumentLifecycle::VisualUpdatePending,
58 document.lifecycle().state());
59
60 document.body()->scrollIntoView();
61 EXPECT_EQ(DocumentLifecycle::CompositingClean, document.lifecycle().state());
62
63 document.body()->setInnerHTML("<div id='test2'></div>");
64 EXPECT_EQ(DocumentLifecycle::VisualUpdatePending,
65 document.lifecycle().state());
66
67 document.body()->scrollIntoViewIfNeeded();
68 EXPECT_EQ(DocumentLifecycle::CompositingClean, document.lifecycle().state());
69 }
70
71 // Verifies that calling offsetTop/offsetLeft cleans compositor inputs.
72 // Cleaning the compositor inputs is required so that position:sticky elements
73 // and their descendants have the correct location.
74 TEST(ElementTest, OffsetTopAndLeftUpdateCompositorInputs) {
75 std::unique_ptr<DummyPageHolder> pageHolder = DummyPageHolder::create();
76 Document& document = pageHolder->document();
77
78 document.view()->updateAllLifecyclePhases();
79 EXPECT_EQ(DocumentLifecycle::PaintClean, document.lifecycle().state());
80
81 document.body()->setInnerHTML("<div id='test'></div>");
82 EXPECT_EQ(DocumentLifecycle::VisualUpdatePending,
83 document.lifecycle().state());
84
85 document.body()->offsetTop();
86 EXPECT_EQ(DocumentLifecycle::CompositingClean, document.lifecycle().state());
87
88 document.body()->setInnerHTML("<div id='test2'></div>");
89 EXPECT_EQ(DocumentLifecycle::VisualUpdatePending,
90 document.lifecycle().state());
91
92 document.body()->offsetLeft();
93 EXPECT_EQ(DocumentLifecycle::CompositingClean, document.lifecycle().state());
94 }
95
96 TEST(ElementTest, OffsetTopAndLeftCorrectForStickyElementsAfterInsertion) {
97 std::unique_ptr<DummyPageHolder> pageHolder = DummyPageHolder::create();
98 Document& document = pageHolder->document();
99
100 document.body()->setInnerHTML(
101 "<style>body { margin: 0 }"
102 "#scroller { overflow: scroll; height: 100px; width: 100px; }"
103 "#sticky { height: 25px; position: sticky; top: 0; left: 25px; }"
104 "#padding { height: 500px; width: 300px; }</style>"
105 "<div id='scroller'><div id='writer'></div><div id='sticky'></div>"
106 "<div id='padding'></div></div>");
107 document.view()->updateAllLifecyclePhases();
108
109 Element* scroller = document.getElementById("scroller");
110 Element* writer = document.getElementById("writer");
111 Element* sticky = document.getElementById("sticky");
112
113 ASSERT_TRUE(scroller);
114 ASSERT_TRUE(writer);
115 ASSERT_TRUE(sticky);
116
117 scroller->scrollTo(0, 200.0);
118
119 // After scrolling, the position:sticky element should be offset to stay at
120 // the top of the viewport.
121 EXPECT_EQ(scroller->scrollTop(), sticky->offsetTop());
122
123 // Insert a new <div> above the sticky. This will dirty layout.
124 writer->setInnerHTML("<div style='height: 100px;'></div>");
125 EXPECT_EQ(DocumentLifecycle::VisualUpdatePending,
126 document.lifecycle().state());
127
128 // Querying the new offset of the sticky element should now cause both layout
129 // and compositing inputs to be clean and should return the correct offset.
130 int offsetTop = sticky->offsetTop();
131 EXPECT_EQ(DocumentLifecycle::CompositingClean, document.lifecycle().state());
132 EXPECT_FALSE(
133 sticky->layoutBoxModelObject()->layer()->needsCompositingInputsUpdate());
134 EXPECT_EQ(scroller->scrollTop(), offsetTop);
135
136 scroller->scrollTo(50.0, 0);
137
138 // After scrolling, the position:sticky element should be offset to stay 25
139 // pixels from the left of the viewport.
140 EXPECT_EQ(scroller->scrollLeft() + 25, sticky->offsetLeft());
141
142 // Insert a new <div> above the sticky. This will dirty layout.
143 writer->setInnerHTML("<div style='width: 700px;'></div>");
144 EXPECT_EQ(DocumentLifecycle::VisualUpdatePending,
145 document.lifecycle().state());
146
147 // Again getting the offset should cause layout and compositing to be clean.
148 int offsetLeft = sticky->offsetLeft();
149 EXPECT_EQ(DocumentLifecycle::CompositingClean, document.lifecycle().state());
150 EXPECT_FALSE(
151 sticky->layoutBoxModelObject()->layer()->needsCompositingInputsUpdate());
152 EXPECT_EQ(scroller->scrollLeft() + 25, offsetLeft);
153 }
154
26 } // namespace blink 155 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/dom/Element.cpp ('k') | third_party/WebKit/Source/core/html/HTMLElement.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698