| 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 |