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

Side by Side Diff: third_party/WebKit/Source/core/page/scrolling/RootScrollerController.cpp

Issue 2280453002: Split RootScrollerController into top-document and child-document classes (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@rootScrollerIFrames2
Patch Set: Created 4 years, 3 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/page/scrolling/RootScrollerController.h" 5 #include "core/page/scrolling/RootScrollerController.h"
6 6
7 #include "core/dom/Document.h" 7 #include "core/dom/Document.h"
8 #include "core/dom/Element.h" 8 #include "core/dom/Element.h"
9 #include "core/frame/FrameHost.h" 9 #include "core/frame/FrameHost.h"
10 #include "core/frame/FrameView.h" 10 #include "core/frame/FrameView.h"
11 #include "core/frame/TopControls.h"
12 #include "core/frame/VisualViewport.h"
13 #include "core/layout/LayoutBox.h" 11 #include "core/layout/LayoutBox.h"
14 #include "core/page/ChromeClient.h"
15 #include "core/page/Page.h"
16 #include "core/page/scrolling/OverscrollController.h"
17 #include "core/page/scrolling/ViewportScrollCallback.h"
18 #include "core/paint/PaintLayerScrollableArea.h" 12 #include "core/paint/PaintLayerScrollableArea.h"
19 #include "platform/graphics/GraphicsLayer.h" 13 #include "platform/graphics/GraphicsLayer.h"
20 #include "platform/scroll/ScrollableArea.h" 14 #include "platform/scroll/ScrollableArea.h"
21 15
22 namespace blink { 16 namespace blink {
23 17
24 class RootFrameViewport; 18 class RootFrameViewport;
25 19
26 namespace { 20 namespace {
27 21
28 ScrollableArea* scrollableAreaFor(const Element& element)
29 {
30 if (!element.layoutObject() || !element.layoutObject()->isBox())
31 return nullptr;
32
33 LayoutBox* box = toLayoutBox(element.layoutObject());
34
35 // For a FrameView, we use the layoutViewport rather than the
36 // getScrollableArea() since that could be the RootFrameViewport. The
37 // rootScroller's ScrollableArea will be swapped in as the layout viewport
38 // in RootFrameViewport so we need to ensure we get the layout viewport.
39 if (box->isDocumentElement())
40 return element.document().view()->layoutViewportScrollableArea();
41
42 return static_cast<PaintInvalidationCapableScrollableArea*>(
43 box->getScrollableArea());
44 }
45
46 bool fillsViewport(const Element& element) 22 bool fillsViewport(const Element& element)
47 { 23 {
48 DCHECK(element.layoutObject()); 24 DCHECK(element.layoutObject());
49 DCHECK(element.layoutObject()->isBox()); 25 DCHECK(element.layoutObject()->isBox());
50 26
51 LayoutObject* layoutObject = element.layoutObject(); 27 LayoutObject* layoutObject = element.layoutObject();
52 28
53 // TODO(bokan): Broken for OOPIF. 29 // TODO(bokan): Broken for OOPIF.
54 Document& topDocument = element.document().topDocument(); 30 Document& topDocument = element.document().topDocument();
55 31
56 Vector<FloatQuad> quads; 32 Vector<FloatQuad> quads;
57 layoutObject->absoluteQuads(quads); 33 layoutObject->absoluteQuads(quads);
58 DCHECK_EQ(quads.size(), 1u); 34 DCHECK_EQ(quads.size(), 1u);
59 35
60 if (!quads[0].isRectilinear()) 36 if (!quads[0].isRectilinear())
61 return false; 37 return false;
62 38
63 LayoutRect boundingBox(quads[0].boundingBox()); 39 LayoutRect boundingBox(quads[0].boundingBox());
64 40
65 return boundingBox.location() == LayoutPoint::zero() 41 return boundingBox.location() == LayoutPoint::zero()
66 && boundingBox.size() == topDocument.layoutViewItem().size(); 42 && boundingBox.size() == topDocument.layoutViewItem().size();
67 } 43 }
68 44
69 bool isValidRootScroller(const Element& element)
70 {
71 if (!element.layoutObject())
72 return false;
73
74 if (!scrollableAreaFor(element))
75 return false;
76
77 if (!fillsViewport(element))
78 return false;
79
80 return true;
81 }
82
83 } // namespace 45 } // namespace
84 46
47 // static
48 RootScrollerController* RootScrollerController::create(Document& document)
49 {
50 return new RootScrollerController(document);
51 }
52
85 RootScrollerController::RootScrollerController(Document& document) 53 RootScrollerController::RootScrollerController(Document& document)
86 : m_document(&document) 54 : m_document(&document)
87 { 55 {
88 } 56 }
89 57
90 DEFINE_TRACE(RootScrollerController) 58 DEFINE_TRACE(RootScrollerController)
91 { 59 {
92 visitor->trace(m_document); 60 visitor->trace(m_document);
93 visitor->trace(m_viewportApplyScroll);
94 visitor->trace(m_rootScroller); 61 visitor->trace(m_rootScroller);
95 visitor->trace(m_effectiveRootScroller); 62 visitor->trace(m_effectiveRootScroller);
96 visitor->trace(m_currentViewportApplyScrollHost);
97 } 63 }
98 64
99 void RootScrollerController::set(Element* newRootScroller) 65 void RootScrollerController::set(Element* newRootScroller)
100 { 66 {
101 m_rootScroller = newRootScroller; 67 m_rootScroller = newRootScroller;
102 updateEffectiveRootScroller(); 68 updateEffectiveRootScroller();
103 } 69 }
104 70
105 Element* RootScrollerController::get() const 71 Element* RootScrollerController::get() const
106 { 72 {
(...skipping 16 matching lines...) Expand all
123 m_rootScroller && isValidRootScroller(*m_rootScroller); 89 m_rootScroller && isValidRootScroller(*m_rootScroller);
124 90
125 Element* newEffectiveRootScroller = rootScrollerValid 91 Element* newEffectiveRootScroller = rootScrollerValid
126 ? m_rootScroller.get() 92 ? m_rootScroller.get()
127 : defaultEffectiveRootScroller(); 93 : defaultEffectiveRootScroller();
128 94
129 if (m_effectiveRootScroller == newEffectiveRootScroller) 95 if (m_effectiveRootScroller == newEffectiveRootScroller)
130 return; 96 return;
131 97
132 m_effectiveRootScroller = newEffectiveRootScroller; 98 m_effectiveRootScroller = newEffectiveRootScroller;
133
134 if (m_document->isInMainFrame())
135 setViewportApplyScrollOnRootScroller();
136 } 99 }
137 100
138 void RootScrollerController::setViewportApplyScrollOnRootScroller() 101 ScrollableArea* RootScrollerController::scrollableAreaFor(
102 const Element& element) const
139 { 103 {
140 DCHECK(m_document->isInMainFrame()); 104 if (!element.layoutObject() || !element.layoutObject()->isBox())
105 return nullptr;
141 106
142 if (!m_viewportApplyScroll || !m_effectiveRootScroller) 107 LayoutBox* box = toLayoutBox(element.layoutObject());
143 return;
144 108
145 ScrollableArea* targetScroller = 109 // For a FrameView, we use the layoutViewport rather than the
146 scrollableAreaFor(*m_effectiveRootScroller); 110 // getScrollableArea() since that could be the RootFrameViewport. The
111 // rootScroller's ScrollableArea will be swapped in as the layout viewport
112 // in RootFrameViewport so we need to ensure we get the layout viewport.
113 if (box->isDocumentElement())
114 return element.document().view()->layoutViewportScrollableArea();
147 115
148 if (!targetScroller) 116 return static_cast<PaintInvalidationCapableScrollableArea*>(
149 return; 117 box->getScrollableArea());
118 }
150 119
151 if (m_currentViewportApplyScrollHost) 120 bool RootScrollerController::isValidRootScroller(const Element& element) const
152 m_currentViewportApplyScrollHost->removeApplyScroll(); 121 {
122 if (!element.layoutObject())
123 return false;
153 124
154 // Use disable-native-scroll since the ViewportScrollCallback needs to 125 if (!scrollableAreaFor(element))
155 // apply scroll actions both before (TopControls) and after (overscroll) 126 return false;
156 // scrolling the element so it will apply scroll to the element itself.
157 m_effectiveRootScroller->setApplyScroll(
158 m_viewportApplyScroll, "disable-native-scroll");
159 127
160 m_currentViewportApplyScrollHost = m_effectiveRootScroller; 128 if (!fillsViewport(element))
129 return false;
161 130
162 // Ideally, scroll customization would pass the current element to scroll to 131 return true;
163 // the apply scroll callback but this doesn't happen today so we set it
164 // through a back door here. This is also needed by the
165 // ViewportScrollCallback to swap the target into the layout viewport
166 // in RootFrameViewport.
167 m_viewportApplyScroll->setScroller(targetScroller);
168 } 132 }
169 133
170 void RootScrollerController::didUpdateCompositing() 134 void RootScrollerController::didUpdateCompositing()
171 { 135 {
172 FrameHost* frameHost = m_document->frameHost();
173
174 // Let the compositor-side counterpart know about this change.
175 if (frameHost && m_document->isInMainFrame())
176 frameHost->chromeClient().registerViewportLayers();
177 } 136 }
178 137
179 void RootScrollerController::didAttachDocument() 138 void RootScrollerController::didAttachDocument()
180 { 139 {
181 if (!m_document->isInMainFrame())
182 return;
183
184 FrameHost* frameHost = m_document->frameHost();
185 FrameView* frameView = m_document->view();
186
187 if (!frameHost || !frameView)
188 return;
189
190 RootFrameViewport* rootFrameViewport = frameView->getRootFrameViewport();
191 DCHECK(rootFrameViewport);
192
193 m_viewportApplyScroll = ViewportScrollCallback::create(
194 &frameHost->topControls(),
195 &frameHost->overscrollController(),
196 *rootFrameViewport);
197
198 updateEffectiveRootScroller();
199 } 140 }
200 141
201 GraphicsLayer* RootScrollerController::rootScrollerLayer() 142 GraphicsLayer* RootScrollerController::rootScrollerLayer()
202 { 143 {
203 if (!m_effectiveRootScroller) 144 if (!m_effectiveRootScroller)
204 return nullptr; 145 return nullptr;
205 146
206 ScrollableArea* area = scrollableAreaFor(*m_effectiveRootScroller); 147 ScrollableArea* area = scrollableAreaFor(*m_effectiveRootScroller);
207 148
208 if (!area) 149 if (!area)
209 return nullptr; 150 return nullptr;
210 151
211 GraphicsLayer* graphicsLayer = area->layerForScrolling(); 152 GraphicsLayer* graphicsLayer = area->layerForScrolling();
212 153
213 // TODO(bokan): We should assert graphicsLayer here and 154 // TODO(bokan): We should assert graphicsLayer here and
214 // RootScrollerController should do whatever needs to happen to ensure 155 // RootScrollerController should do whatever needs to happen to ensure
215 // the root scroller gets composited. 156 // the root scroller gets composited.
216 157
217 return graphicsLayer; 158 return graphicsLayer;
218 } 159 }
219 160
220 bool RootScrollerController::isViewportScrollCallback( 161 bool RootScrollerController::isViewportScrollCallback(
221 const ScrollStateCallback* callback) const 162 const ScrollStateCallback* callback) const
222 { 163 {
223 if (!callback) 164 // Only the top document's controller has the ViewportScrollCallback.
224 return false; 165 DCHECK(!m_document->isInMainFrame());
tdresser 2016/08/25 14:59:21 Maybe indicate that the top documents controller w
bokan 2016/08/25 15:14:13 Done.
225 166 RootScrollerController* topDocumentController =
226 return callback == m_viewportApplyScroll.get(); 167 m_document->topDocument().rootScrollerController();
168 return topDocumentController->isViewportScrollCallback(callback);
227 } 169 }
228 170
229 Element* RootScrollerController::defaultEffectiveRootScroller() 171 Element* RootScrollerController::defaultEffectiveRootScroller()
230 { 172 {
231 DCHECK(m_document); 173 DCHECK(m_document);
232 return m_document->documentElement(); 174 return m_document->documentElement();
233 } 175 }
234 176
235 } // namespace blink 177 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698