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

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

Issue 2293903002: Revert of 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"
11 #include "core/layout/LayoutBox.h" 13 #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"
12 #include "core/paint/PaintLayerScrollableArea.h" 18 #include "core/paint/PaintLayerScrollableArea.h"
13 #include "platform/graphics/GraphicsLayer.h" 19 #include "platform/graphics/GraphicsLayer.h"
14 #include "platform/scroll/ScrollableArea.h" 20 #include "platform/scroll/ScrollableArea.h"
15 21
16 namespace blink { 22 namespace blink {
17 23
18 class RootFrameViewport; 24 class RootFrameViewport;
19 25
20 namespace { 26 namespace {
21 27
22 bool fillsViewport(const Element& element) 28 ScrollableArea* scrollableAreaFor(const Element& element)
23 {
24 DCHECK(element.layoutObject());
25 DCHECK(element.layoutObject()->isBox());
26
27 LayoutObject* layoutObject = element.layoutObject();
28
29 // TODO(bokan): Broken for OOPIF.
30 Document& topDocument = element.document().topDocument();
31
32 Vector<FloatQuad> quads;
33 layoutObject->absoluteQuads(quads);
34 DCHECK_EQ(quads.size(), 1u);
35
36 if (!quads[0].isRectilinear())
37 return false;
38
39 LayoutRect boundingBox(quads[0].boundingBox());
40
41 return boundingBox.location() == LayoutPoint::zero()
42 && boundingBox.size() == topDocument.layoutViewItem().size();
43 }
44
45 } // namespace
46
47 // static
48 RootScrollerController* RootScrollerController::create(Document& document)
49 {
50 return new RootScrollerController(document);
51 }
52
53 RootScrollerController::RootScrollerController(Document& document)
54 : m_document(&document)
55 {
56 }
57
58 DEFINE_TRACE(RootScrollerController)
59 {
60 visitor->trace(m_document);
61 visitor->trace(m_rootScroller);
62 visitor->trace(m_effectiveRootScroller);
63 }
64
65 void RootScrollerController::set(Element* newRootScroller)
66 {
67 m_rootScroller = newRootScroller;
68 updateEffectiveRootScroller();
69 }
70
71 Element* RootScrollerController::get() const
72 {
73 return m_rootScroller;
74 }
75
76 Element* RootScrollerController::effectiveRootScroller() const
77 {
78 return m_effectiveRootScroller;
79 }
80
81 void RootScrollerController::didUpdateLayout()
82 {
83 updateEffectiveRootScroller();
84 }
85
86 void RootScrollerController::updateEffectiveRootScroller()
87 {
88 bool rootScrollerValid =
89 m_rootScroller && isValidRootScroller(*m_rootScroller);
90
91 Element* newEffectiveRootScroller = rootScrollerValid
92 ? m_rootScroller.get()
93 : defaultEffectiveRootScroller();
94
95 if (m_effectiveRootScroller == newEffectiveRootScroller)
96 return;
97
98 m_effectiveRootScroller = newEffectiveRootScroller;
99 }
100
101 ScrollableArea* RootScrollerController::scrollableAreaFor(
102 const Element& element) const
103 { 29 {
104 if (!element.layoutObject() || !element.layoutObject()->isBox()) 30 if (!element.layoutObject() || !element.layoutObject()->isBox())
105 return nullptr; 31 return nullptr;
106 32
107 LayoutBox* box = toLayoutBox(element.layoutObject()); 33 LayoutBox* box = toLayoutBox(element.layoutObject());
108 34
109 // For a FrameView, we use the layoutViewport rather than the 35 // For a FrameView, we use the layoutViewport rather than the
110 // getScrollableArea() since that could be the RootFrameViewport. The 36 // getScrollableArea() since that could be the RootFrameViewport. The
111 // rootScroller's ScrollableArea will be swapped in as the layout viewport 37 // rootScroller's ScrollableArea will be swapped in as the layout viewport
112 // in RootFrameViewport so we need to ensure we get the layout viewport. 38 // in RootFrameViewport so we need to ensure we get the layout viewport.
113 if (box->isDocumentElement()) 39 if (box->isDocumentElement())
114 return element.document().view()->layoutViewportScrollableArea(); 40 return element.document().view()->layoutViewportScrollableArea();
115 41
116 return static_cast<PaintInvalidationCapableScrollableArea*>( 42 return static_cast<PaintInvalidationCapableScrollableArea*>(
117 box->getScrollableArea()); 43 box->getScrollableArea());
118 } 44 }
119 45
120 bool RootScrollerController::isValidRootScroller(const Element& element) const 46 bool fillsViewport(const Element& element)
47 {
48 DCHECK(element.layoutObject());
49 DCHECK(element.layoutObject()->isBox());
50
51 LayoutObject* layoutObject = element.layoutObject();
52
53 // TODO(bokan): Broken for OOPIF.
54 Document& topDocument = element.document().topDocument();
55
56 Vector<FloatQuad> quads;
57 layoutObject->absoluteQuads(quads);
58 DCHECK_EQ(quads.size(), 1u);
59
60 if (!quads[0].isRectilinear())
61 return false;
62
63 LayoutRect boundingBox(quads[0].boundingBox());
64
65 return boundingBox.location() == LayoutPoint::zero()
66 && boundingBox.size() == topDocument.layoutViewItem().size();
67 }
68
69 bool isValidRootScroller(const Element& element)
121 { 70 {
122 if (!element.layoutObject()) 71 if (!element.layoutObject())
123 return false; 72 return false;
124 73
125 if (!scrollableAreaFor(element)) 74 if (!scrollableAreaFor(element))
126 return false; 75 return false;
127 76
128 if (!fillsViewport(element)) 77 if (!fillsViewport(element))
129 return false; 78 return false;
130 79
131 return true; 80 return true;
132 } 81 }
133 82
83 } // namespace
84
85 RootScrollerController::RootScrollerController(Document& document)
86 : m_document(&document)
87 {
88 }
89
90 DEFINE_TRACE(RootScrollerController)
91 {
92 visitor->trace(m_document);
93 visitor->trace(m_viewportApplyScroll);
94 visitor->trace(m_rootScroller);
95 visitor->trace(m_effectiveRootScroller);
96 visitor->trace(m_currentViewportApplyScrollHost);
97 }
98
99 void RootScrollerController::set(Element* newRootScroller)
100 {
101 m_rootScroller = newRootScroller;
102 updateEffectiveRootScroller();
103 }
104
105 Element* RootScrollerController::get() const
106 {
107 return m_rootScroller;
108 }
109
110 Element* RootScrollerController::effectiveRootScroller() const
111 {
112 return m_effectiveRootScroller;
113 }
114
115 void RootScrollerController::didUpdateLayout()
116 {
117 updateEffectiveRootScroller();
118 }
119
120 void RootScrollerController::updateEffectiveRootScroller()
121 {
122 bool rootScrollerValid =
123 m_rootScroller && isValidRootScroller(*m_rootScroller);
124
125 Element* newEffectiveRootScroller = rootScrollerValid
126 ? m_rootScroller.get()
127 : defaultEffectiveRootScroller();
128
129 if (m_effectiveRootScroller == newEffectiveRootScroller)
130 return;
131
132 m_effectiveRootScroller = newEffectiveRootScroller;
133
134 if (m_document->isInMainFrame())
135 setViewportApplyScrollOnRootScroller();
136 }
137
138 void RootScrollerController::setViewportApplyScrollOnRootScroller()
139 {
140 DCHECK(m_document->isInMainFrame());
141
142 if (!m_viewportApplyScroll || !m_effectiveRootScroller)
143 return;
144
145 ScrollableArea* targetScroller =
146 scrollableAreaFor(*m_effectiveRootScroller);
147
148 if (!targetScroller)
149 return;
150
151 if (m_currentViewportApplyScrollHost)
152 m_currentViewportApplyScrollHost->removeApplyScroll();
153
154 // Use disable-native-scroll since the ViewportScrollCallback needs to
155 // apply scroll actions both before (TopControls) and after (overscroll)
156 // scrolling the element so it will apply scroll to the element itself.
157 m_effectiveRootScroller->setApplyScroll(
158 m_viewportApplyScroll, "disable-native-scroll");
159
160 m_currentViewportApplyScrollHost = m_effectiveRootScroller;
161
162 // Ideally, scroll customization would pass the current element to scroll to
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 }
169
134 void RootScrollerController::didUpdateCompositing() 170 void RootScrollerController::didUpdateCompositing()
135 { 171 {
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();
136 } 177 }
137 178
138 void RootScrollerController::didAttachDocument() 179 void RootScrollerController::didAttachDocument()
139 { 180 {
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();
140 } 199 }
141 200
142 GraphicsLayer* RootScrollerController::rootScrollerLayer() 201 GraphicsLayer* RootScrollerController::rootScrollerLayer()
143 { 202 {
144 if (!m_effectiveRootScroller) 203 if (!m_effectiveRootScroller)
145 return nullptr; 204 return nullptr;
146 205
147 ScrollableArea* area = scrollableAreaFor(*m_effectiveRootScroller); 206 ScrollableArea* area = scrollableAreaFor(*m_effectiveRootScroller);
148 207
149 if (!area) 208 if (!area)
150 return nullptr; 209 return nullptr;
151 210
152 GraphicsLayer* graphicsLayer = area->layerForScrolling(); 211 GraphicsLayer* graphicsLayer = area->layerForScrolling();
153 212
154 // TODO(bokan): We should assert graphicsLayer here and 213 // TODO(bokan): We should assert graphicsLayer here and
155 // RootScrollerController should do whatever needs to happen to ensure 214 // RootScrollerController should do whatever needs to happen to ensure
156 // the root scroller gets composited. 215 // the root scroller gets composited.
157 216
158 return graphicsLayer; 217 return graphicsLayer;
159 } 218 }
160 219
161 bool RootScrollerController::isViewportScrollCallback( 220 bool RootScrollerController::isViewportScrollCallback(
162 const ScrollStateCallback* callback) const 221 const ScrollStateCallback* callback) const
163 { 222 {
164 // TopDocumentRootScrollerController must override this method to actually 223 if (!callback)
165 // do the comparison. 224 return false;
166 DCHECK(!m_document->isInMainFrame());
167 225
168 RootScrollerController* topDocumentController = 226 return callback == m_viewportApplyScroll.get();
169 m_document->topDocument().rootScrollerController();
170 return topDocumentController->isViewportScrollCallback(callback);
171 } 227 }
172 228
173 Element* RootScrollerController::defaultEffectiveRootScroller() 229 Element* RootScrollerController::defaultEffectiveRootScroller()
174 { 230 {
175 DCHECK(m_document); 231 DCHECK(m_document);
176 return m_document->documentElement(); 232 return m_document->documentElement();
177 } 233 }
178 234
179 } // namespace blink 235 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698