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/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" | 11 #include "core/frame/TopControls.h" |
12 #include "core/layout/LayoutBox.h" | 12 #include "core/layout/LayoutBox.h" |
13 #include "core/page/Page.h" | 13 #include "core/page/Page.h" |
14 #include "core/page/scrolling/OverscrollController.h" | 14 #include "core/page/scrolling/OverscrollController.h" |
15 #include "core/page/scrolling/ViewportScrollCallback.h" | 15 #include "core/page/scrolling/ViewportScrollCallback.h" |
16 #include "core/paint/PaintLayerScrollableArea.h" | 16 #include "core/paint/PaintLayerScrollableArea.h" |
17 #include "platform/scroll/ScrollableArea.h" | 17 #include "platform/scroll/ScrollableArea.h" |
18 | 18 |
19 namespace blink { | 19 namespace blink { |
20 | 20 |
21 namespace { | 21 namespace { |
22 | 22 |
23 ScrollableArea* scrollableAreaFor(const Element& element) | 23 ScrollableArea* scrollableAreaFor(const Element& element) |
24 { | 24 { |
25 if (!element.layoutObject() || !element.layoutObject()->isBox()) | 25 if (!element.layoutObject() || !element.layoutObject()->isBox()) |
26 return nullptr; | 26 return nullptr; |
27 | 27 |
28 LayoutBox* box = toLayoutBox(element.layoutObject()); | 28 LayoutBox* box = toLayoutBox(element.layoutObject()); |
29 | 29 |
| 30 // For a FrameView, we use the layoutViewport rather than the |
| 31 // getScrollableArea() since that could be the RootFrameViewport. The |
| 32 // rootScroller's ScrollableArea will be swapped in as the layout viewport |
| 33 // in RootFrameViewport so we need to ensure we get the layout viewport. |
30 if (box->isDocumentElement()) | 34 if (box->isDocumentElement()) |
31 return element.document().view()->getScrollableArea(); | 35 return element.document().view()->layoutViewportScrollableArea(); |
32 | 36 |
33 return static_cast<PaintInvalidationCapableScrollableArea*>( | 37 return static_cast<PaintInvalidationCapableScrollableArea*>( |
34 box->getScrollableArea()); | 38 box->getScrollableArea()); |
35 } | 39 } |
36 | 40 |
37 bool fillsViewport(const Element& element) | 41 bool fillsViewport(const Element& element) |
38 { | 42 { |
39 DCHECK(element.layoutObject()); | 43 DCHECK(element.layoutObject()); |
40 DCHECK(element.layoutObject()->isBox()); | 44 DCHECK(element.layoutObject()->isBox()); |
41 | 45 |
(...skipping 24 matching lines...) Expand all Loading... |
66 return false; | 70 return false; |
67 | 71 |
68 if (!fillsViewport(element)) | 72 if (!fillsViewport(element)) |
69 return false; | 73 return false; |
70 | 74 |
71 return true; | 75 return true; |
72 } | 76 } |
73 | 77 |
74 } // namespace | 78 } // namespace |
75 | 79 |
76 RootScrollerController::RootScrollerController(Document& document, ViewportScrol
lCallback* applyScrollCallback) | 80 RootScrollerController::RootScrollerController(Document& document) |
77 : m_document(&document) | 81 : m_document(&document) |
78 , m_viewportApplyScroll(applyScrollCallback) | |
79 { | 82 { |
80 } | 83 } |
81 | 84 |
82 DEFINE_TRACE(RootScrollerController) | 85 DEFINE_TRACE(RootScrollerController) |
83 { | 86 { |
84 visitor->trace(m_document); | 87 visitor->trace(m_document); |
85 visitor->trace(m_viewportApplyScroll); | 88 visitor->trace(m_viewportApplyScroll); |
86 visitor->trace(m_rootScroller); | 89 visitor->trace(m_rootScroller); |
87 visitor->trace(m_effectiveRootScroller); | 90 visitor->trace(m_effectiveRootScroller); |
88 } | 91 } |
(...skipping 12 matching lines...) Expand all Loading... |
101 Element* RootScrollerController::effectiveRootScroller() const | 104 Element* RootScrollerController::effectiveRootScroller() const |
102 { | 105 { |
103 return m_effectiveRootScroller; | 106 return m_effectiveRootScroller; |
104 } | 107 } |
105 | 108 |
106 void RootScrollerController::didUpdateLayout() | 109 void RootScrollerController::didUpdateLayout() |
107 { | 110 { |
108 updateEffectiveRootScroller(); | 111 updateEffectiveRootScroller(); |
109 } | 112 } |
110 | 113 |
| 114 void RootScrollerController::setViewportScrollCallback(ViewportScrollCallback* c
allback) |
| 115 { |
| 116 m_viewportApplyScroll = callback; |
| 117 moveViewportApplyScroll(m_effectiveRootScroller); |
| 118 } |
| 119 |
111 void RootScrollerController::updateEffectiveRootScroller() | 120 void RootScrollerController::updateEffectiveRootScroller() |
112 { | 121 { |
113 bool rootScrollerValid = | 122 bool rootScrollerValid = |
114 m_rootScroller && isValidRootScroller(*m_rootScroller); | 123 m_rootScroller && isValidRootScroller(*m_rootScroller); |
115 | 124 |
116 Element* newEffectiveRootScroller = rootScrollerValid | 125 Element* newEffectiveRootScroller = rootScrollerValid |
117 ? m_rootScroller.get() | 126 ? m_rootScroller.get() |
118 : defaultEffectiveRootScroller(); | 127 : defaultEffectiveRootScroller(); |
119 | 128 |
120 if (m_effectiveRootScroller == newEffectiveRootScroller) | 129 if (m_effectiveRootScroller == newEffectiveRootScroller) |
121 return; | 130 return; |
122 | 131 |
123 moveViewportApplyScroll(newEffectiveRootScroller); | 132 if (moveViewportApplyScroll(newEffectiveRootScroller)) |
124 m_effectiveRootScroller = newEffectiveRootScroller; | 133 m_effectiveRootScroller = newEffectiveRootScroller; |
125 } | 134 } |
126 | 135 |
127 void RootScrollerController::moveViewportApplyScroll(Element* target) | 136 bool RootScrollerController::moveViewportApplyScroll(Element* target) |
128 { | 137 { |
129 if (!m_viewportApplyScroll) | 138 if (!m_viewportApplyScroll || !target) |
130 return; | 139 return false; |
| 140 |
| 141 ScrollableArea* targetScroller = scrollableAreaFor(*target); |
| 142 if (!targetScroller) |
| 143 return false; |
131 | 144 |
132 if (m_effectiveRootScroller) | 145 if (m_effectiveRootScroller) |
133 m_effectiveRootScroller->removeApplyScroll(); | 146 m_effectiveRootScroller->removeApplyScroll(); |
134 | 147 |
135 ScrollableArea* targetScroller = | 148 // Use disable-native-scroll since the ViewportScrollCallback needs to |
136 target ? scrollableAreaFor(*target) : nullptr; | 149 // apply scroll actions both before (TopControls) and after (overscroll) |
137 | 150 // scrolling the element so it will apply scroll to the element itself. |
138 if (targetScroller) { | 151 target->setApplyScroll(m_viewportApplyScroll, "disable-native-scroll"); |
139 // Use disable-native-scroll since the ViewportScrollCallback needs to | |
140 // apply scroll actions both before (TopControls) and after (overscroll) | |
141 // scrolling the element so it will apply scroll to the element itself. | |
142 target->setApplyScroll( | |
143 m_viewportApplyScroll, | |
144 "disable-native-scroll"); | |
145 } | |
146 | 152 |
147 // Ideally, scroll customization would pass the current element to scroll to | 153 // Ideally, scroll customization would pass the current element to scroll to |
148 // the apply scroll callback but this doesn't happen today so we set it | 154 // the apply scroll callback but this doesn't happen today so we set it |
149 // through a back door here. | 155 // through a back door here. This is also needed by the |
| 156 // RootViewportScrollCallback to swap the target into the layout viewport |
| 157 // in RootFrameViewport. |
150 m_viewportApplyScroll->setScroller(targetScroller); | 158 m_viewportApplyScroll->setScroller(targetScroller); |
| 159 |
| 160 return true; |
151 } | 161 } |
152 | 162 |
153 Element* RootScrollerController::defaultEffectiveRootScroller() | 163 Element* RootScrollerController::defaultEffectiveRootScroller() |
154 { | 164 { |
155 DCHECK(m_document); | 165 DCHECK(m_document); |
156 return m_document->documentElement(); | 166 return m_document->documentElement(); |
157 } | 167 } |
158 | 168 |
159 } // namespace blink | 169 } // namespace blink |
OLD | NEW |