OLD | NEW |
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/TopDocumentRootScrollerController.h" | 5 #include "core/page/scrolling/TopDocumentRootScrollerController.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/html/HTMLFrameOwnerElement.h" | 11 #include "core/html/HTMLFrameOwnerElement.h" |
12 #include "core/layout/LayoutView.h" | 12 #include "core/layout/LayoutView.h" |
13 #include "core/layout/compositing/PaintLayerCompositor.h" | 13 #include "core/layout/compositing/PaintLayerCompositor.h" |
14 #include "core/page/ChromeClient.h" | 14 #include "core/page/ChromeClient.h" |
| 15 #include "core/page/Page.h" |
15 #include "core/page/scrolling/OverscrollController.h" | 16 #include "core/page/scrolling/OverscrollController.h" |
| 17 #include "core/page/scrolling/RootScrollerUtil.h" |
16 #include "core/page/scrolling/ViewportScrollCallback.h" | 18 #include "core/page/scrolling/ViewportScrollCallback.h" |
17 #include "core/paint/PaintLayer.h" | 19 #include "core/paint/PaintLayer.h" |
18 #include "platform/scroll/ScrollableArea.h" | 20 #include "platform/scroll/ScrollableArea.h" |
19 | 21 |
20 namespace blink { | 22 namespace blink { |
21 | 23 |
22 // static | 24 // static |
23 TopDocumentRootScrollerController* TopDocumentRootScrollerController::create( | 25 TopDocumentRootScrollerController* TopDocumentRootScrollerController::create( |
24 Document& document) | 26 FrameHost& host) |
25 { | 27 { |
26 return new TopDocumentRootScrollerController(document); | 28 return new TopDocumentRootScrollerController(host); |
27 } | 29 } |
28 | 30 |
29 TopDocumentRootScrollerController::TopDocumentRootScrollerController( | 31 TopDocumentRootScrollerController::TopDocumentRootScrollerController( |
30 Document& document) | 32 FrameHost& host) |
31 : RootScrollerController(document) | 33 : m_frameHost(&host) |
32 { | 34 { |
33 } | 35 } |
34 | 36 |
35 DEFINE_TRACE(TopDocumentRootScrollerController) | 37 DEFINE_TRACE(TopDocumentRootScrollerController) |
36 { | 38 { |
37 visitor->trace(m_viewportApplyScroll); | 39 visitor->trace(m_viewportApplyScroll); |
38 visitor->trace(m_globalRootScroller); | 40 visitor->trace(m_globalRootScroller); |
39 RootScrollerController::trace(visitor); | 41 visitor->trace(m_frameHost); |
40 } | 42 } |
41 | 43 |
42 void TopDocumentRootScrollerController::globalRootScrollerMayHaveChanged() | 44 void TopDocumentRootScrollerController::didChangeRootScroller() |
43 { | 45 { |
44 updateGlobalRootScroller(); | 46 recomputeGlobalRootScroller(); |
45 } | 47 } |
46 | 48 |
47 Element* TopDocumentRootScrollerController::findGlobalRootScrollerElement() | 49 Element* TopDocumentRootScrollerController::findGlobalRootScrollerElement() |
48 { | 50 { |
49 Element* element = effectiveRootScroller(); | 51 if (!topDocument()) |
| 52 return nullptr; |
| 53 |
| 54 DCHECK(topDocument()->rootScrollerController()); |
| 55 Element* element = |
| 56 topDocument()->rootScrollerController()->effectiveRootScroller(); |
50 | 57 |
51 while (element && element->isFrameOwnerElement()) { | 58 while (element && element->isFrameOwnerElement()) { |
52 HTMLFrameOwnerElement* frameOwner = toHTMLFrameOwnerElement(element); | 59 HTMLFrameOwnerElement* frameOwner = toHTMLFrameOwnerElement(element); |
53 DCHECK(frameOwner); | 60 DCHECK(frameOwner); |
54 | 61 |
55 Document* iframeDocument = frameOwner->contentDocument(); | 62 Document* iframeDocument = frameOwner->contentDocument(); |
56 if (!iframeDocument) | 63 if (!iframeDocument) |
57 return element; | 64 return element; |
58 | 65 |
59 DCHECK(iframeDocument->rootScrollerController()); | 66 DCHECK(iframeDocument->rootScrollerController()); |
60 element = | 67 element = |
61 iframeDocument->rootScrollerController()->effectiveRootScroller(); | 68 iframeDocument->rootScrollerController()->effectiveRootScroller(); |
62 } | 69 } |
63 | 70 |
64 return element; | 71 return element; |
65 } | 72 } |
66 | 73 |
67 void TopDocumentRootScrollerController::updateGlobalRootScroller() | 74 void TopDocumentRootScrollerController::recomputeGlobalRootScroller() |
68 { | 75 { |
| 76 if (!m_viewportApplyScroll) |
| 77 return; |
| 78 |
69 Element* target = findGlobalRootScrollerElement(); | 79 Element* target = findGlobalRootScrollerElement(); |
70 | 80 if (!target) |
71 if (!m_viewportApplyScroll || !target) | |
72 return; | 81 return; |
73 | 82 |
74 ScrollableArea* targetScroller = | 83 ScrollableArea* targetScroller = |
75 scrollableAreaFor(*target); | 84 RootScrollerUtil::scrollableAreaFor(*target); |
76 | 85 |
77 if (!targetScroller) | 86 if (!targetScroller) |
78 return; | 87 return; |
79 | 88 |
80 if (m_globalRootScroller) | 89 if (m_globalRootScroller) |
81 m_globalRootScroller->removeApplyScroll(); | 90 m_globalRootScroller->removeApplyScroll(); |
82 | 91 |
83 // Use disable-native-scroll since the ViewportScrollCallback needs to | 92 // Use disable-native-scroll since the ViewportScrollCallback needs to |
84 // apply scroll actions both before (TopControls) and after (overscroll) | 93 // apply scroll actions both before (TopControls) and after (overscroll) |
85 // scrolling the element so it will apply scroll to the element itself. | 94 // scrolling the element so it will apply scroll to the element itself. |
(...skipping 13 matching lines...) Expand all Loading... |
99 setNeedsCompositingInputsUpdateOnGlobalRootScroller(); | 108 setNeedsCompositingInputsUpdateOnGlobalRootScroller(); |
100 | 109 |
101 // Ideally, scroll customization would pass the current element to scroll to | 110 // Ideally, scroll customization would pass the current element to scroll to |
102 // the apply scroll callback but this doesn't happen today so we set it | 111 // the apply scroll callback but this doesn't happen today so we set it |
103 // through a back door here. This is also needed by the | 112 // through a back door here. This is also needed by the |
104 // ViewportScrollCallback to swap the target into the layout viewport | 113 // ViewportScrollCallback to swap the target into the layout viewport |
105 // in RootFrameViewport. | 114 // in RootFrameViewport. |
106 m_viewportApplyScroll->setScroller(targetScroller); | 115 m_viewportApplyScroll->setScroller(targetScroller); |
107 } | 116 } |
108 | 117 |
| 118 Document* TopDocumentRootScrollerController::topDocument() const |
| 119 { |
| 120 if (!m_frameHost) |
| 121 return nullptr; |
| 122 |
| 123 if (!m_frameHost->page().mainFrame() |
| 124 || !m_frameHost->page().mainFrame()->isLocalFrame()) |
| 125 return nullptr; |
| 126 |
| 127 return toLocalFrame(m_frameHost->page().mainFrame())->document(); |
| 128 } |
| 129 |
109 void TopDocumentRootScrollerController | 130 void TopDocumentRootScrollerController |
110 ::setNeedsCompositingInputsUpdateOnGlobalRootScroller() | 131 ::setNeedsCompositingInputsUpdateOnGlobalRootScroller() |
111 { | 132 { |
112 if (!m_globalRootScroller) | 133 if (!m_globalRootScroller) |
113 return; | 134 return; |
114 | 135 |
115 PaintLayer* layer = m_globalRootScroller->document() | 136 PaintLayer* layer = m_globalRootScroller->document() |
116 .rootScrollerController()->rootScrollerPaintLayer(); | 137 .rootScrollerController()->rootScrollerPaintLayer(); |
117 | 138 |
118 if (layer) | 139 if (layer) |
119 layer->setNeedsCompositingInputsUpdate(); | 140 layer->setNeedsCompositingInputsUpdate(); |
120 | 141 |
121 if (LayoutView* view = m_globalRootScroller->document().layoutView()) { | 142 if (LayoutView* view = m_globalRootScroller->document().layoutView()) { |
122 view->compositor() | 143 view->compositor() |
123 ->setNeedsCompositingUpdate(CompositingUpdateRebuildTree); | 144 ->setNeedsCompositingUpdate(CompositingUpdateRebuildTree); |
124 } | 145 } |
125 } | 146 } |
126 | 147 |
127 void TopDocumentRootScrollerController::didUpdateCompositing() | 148 void TopDocumentRootScrollerController::didUpdateCompositing() |
128 { | 149 { |
129 RootScrollerController::didUpdateCompositing(); | 150 if (!m_frameHost) |
| 151 return; |
130 | 152 |
131 // Let the compositor-side counterpart know about this change. | 153 // Let the compositor-side counterpart know about this change. |
132 if (FrameHost* frameHost = m_document->frameHost()) | 154 m_frameHost->chromeClient().registerViewportLayers(); |
133 frameHost->chromeClient().registerViewportLayers(); | |
134 } | 155 } |
135 | 156 |
136 void TopDocumentRootScrollerController::didAttachDocument() | 157 void TopDocumentRootScrollerController::initializeViewportScrollCallback( |
| 158 RootFrameViewport& rootFrameViewport) |
137 { | 159 { |
138 FrameHost* frameHost = m_document->frameHost(); | 160 DCHECK(m_frameHost); |
139 FrameView* frameView = m_document->view(); | 161 m_viewportApplyScroll = ViewportScrollCallback::create( |
| 162 &m_frameHost->topControls(), |
| 163 &m_frameHost->overscrollController(), |
| 164 rootFrameViewport); |
140 | 165 |
141 if (!frameHost || !frameView) | 166 recomputeGlobalRootScroller(); |
142 return; | |
143 | |
144 RootFrameViewport* rootFrameViewport = frameView->getRootFrameViewport(); | |
145 DCHECK(rootFrameViewport); | |
146 | |
147 m_viewportApplyScroll = ViewportScrollCallback::create( | |
148 &frameHost->topControls(), | |
149 &frameHost->overscrollController(), | |
150 *rootFrameViewport); | |
151 | |
152 updateGlobalRootScroller(); | |
153 } | 167 } |
154 | 168 |
155 bool TopDocumentRootScrollerController::isViewportScrollCallback( | 169 bool TopDocumentRootScrollerController::isViewportScrollCallback( |
156 const ScrollStateCallback* callback) const | 170 const ScrollStateCallback* callback) const |
157 { | 171 { |
158 if (!callback) | 172 if (!callback) |
159 return false; | 173 return false; |
160 | 174 |
161 return callback == m_viewportApplyScroll.get(); | 175 return callback == m_viewportApplyScroll.get(); |
162 } | 176 } |
163 | 177 |
164 GraphicsLayer* TopDocumentRootScrollerController::rootScrollerLayer() | 178 GraphicsLayer* TopDocumentRootScrollerController::rootScrollerLayer() const |
165 { | 179 { |
166 if (!m_globalRootScroller) | 180 if (!m_globalRootScroller) |
167 return nullptr; | 181 return nullptr; |
168 | 182 |
169 ScrollableArea* area = scrollableAreaFor(*m_globalRootScroller); | 183 ScrollableArea* area = |
| 184 RootScrollerUtil::scrollableAreaFor(*m_globalRootScroller); |
170 | 185 |
171 if (!area) | 186 if (!area) |
172 return nullptr; | 187 return nullptr; |
173 | 188 |
174 GraphicsLayer* graphicsLayer = area->layerForScrolling(); | 189 GraphicsLayer* graphicsLayer = area->layerForScrolling(); |
175 | 190 |
176 // TODO(bokan): We should assert graphicsLayer here and | 191 // TODO(bokan): We should assert graphicsLayer here and |
177 // RootScrollerController should do whatever needs to happen to ensure | 192 // RootScrollerController should do whatever needs to happen to ensure |
178 // the root scroller gets composited. | 193 // the root scroller gets composited. |
179 | 194 |
180 return graphicsLayer; | 195 return graphicsLayer; |
181 } | 196 } |
182 | 197 |
183 Element* TopDocumentRootScrollerController::globalRootScroller() const | 198 Element* TopDocumentRootScrollerController::globalRootScroller() const |
184 { | 199 { |
185 return m_globalRootScroller.get(); | 200 return m_globalRootScroller.get(); |
186 } | 201 } |
187 | 202 |
188 } // namespace blink | 203 } // namespace blink |
OLD | NEW |