| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/layout/ScrollAnchor.h" | 5 #include "core/layout/ScrollAnchor.h" |
| 6 | 6 |
| 7 #include "core/layout/LayoutObject.h" | 7 #include "core/frame/FrameView.h" |
| 8 #include "platform/scroll/ScrollableArea.h" | 8 #include "core/layout/LayoutView.h" |
| 9 #include "core/paint/PaintLayerScrollableArea.h" |
| 9 #include "wtf/Assertions.h" | 10 #include "wtf/Assertions.h" |
| 10 | 11 |
| 11 namespace blink { | 12 namespace blink { |
| 12 | 13 |
| 13 ScrollAnchor::ScrollAnchor(ScrollableArea* scroller) | 14 ScrollAnchor::ScrollAnchor(ScrollableArea* scroller) |
| 14 : m_scroller(scroller) | 15 : m_scroller(scroller) |
| 15 , m_anchorObject(nullptr) | 16 , m_anchorObject(nullptr) |
| 16 { | 17 { |
| 17 ASSERT(m_scroller); | 18 ASSERT(m_scroller); |
| 18 ASSERT(m_scroller->isFrameView() || m_scroller->isPaintLayerScrollableArea()
); | 19 ASSERT(m_scroller->isFrameView() || m_scroller->isPaintLayerScrollableArea()
); |
| 19 } | 20 } |
| 20 | 21 |
| 21 ScrollAnchor::~ScrollAnchor() | 22 ScrollAnchor::~ScrollAnchor() |
| 22 { | 23 { |
| 23 } | 24 } |
| 24 | 25 |
| 26 static LayoutBox* scrollerLayoutBox(const ScrollableArea* scroller) |
| 27 { |
| 28 LayoutBox* box = scroller->isFrameView() |
| 29 ? toFrameView(scroller)->layoutView() |
| 30 : &toPaintLayerScrollableArea(scroller)->box(); |
| 31 ASSERT(box); |
| 32 return box; |
| 33 } |
| 34 |
| 25 static LayoutObject* findAnchor(const ScrollableArea* scroller) | 35 static LayoutObject* findAnchor(const ScrollableArea* scroller) |
| 26 { | 36 { |
| 27 // TODO(skobes): implement. | 37 LayoutBox* scrollerBox = scrollerLayoutBox(scroller); |
| 28 return nullptr; | 38 |
| 39 FloatRect absoluteVisibleRect = scroller->isFrameView() |
| 40 ? scroller->visibleContentRect() |
| 41 : scrollerBox->localToAbsoluteQuad( |
| 42 FloatQuad(FloatRect(scrollerBox->overflowClipRect(LayoutPoint())))).
boundingBox(); |
| 43 |
| 44 LayoutObject* child = scrollerBox->nextInPreOrder(scrollerBox); |
| 45 LayoutObject* candidate = nullptr; |
| 46 while (child) { |
| 47 // TODO(skobes): Compute scroller-relative bounds instead of absolute bo
unds. |
| 48 FloatRect childRect = child->absoluteBoundingBoxFloatRect(); |
| 49 if (absoluteVisibleRect.intersects(childRect)) |
| 50 candidate = child; |
| 51 if (absoluteVisibleRect.contains(childRect)) |
| 52 break; |
| 53 child = child->nextInPreOrder(scrollerBox); |
| 54 } |
| 55 return candidate; |
| 29 } | 56 } |
| 30 | 57 |
| 31 static DoublePoint computeRelativeOffset(const ScrollableArea* scroller, const L
ayoutObject* layoutObject) | 58 static DoublePoint computeRelativeOffset(const ScrollableArea* scroller, const L
ayoutObject* layoutObject) |
| 32 { | 59 { |
| 33 // TODO(skobes): implement. | 60 return DoublePoint(layoutObject->localToAbsolute() - scrollerLayoutBox(scrol
ler)->localToAbsolute()); |
| 34 return DoublePoint(); | |
| 35 } | 61 } |
| 36 | 62 |
| 37 void ScrollAnchor::save() | 63 void ScrollAnchor::save() |
| 38 { | 64 { |
| 39 if (!m_anchorObject) { | 65 if (m_anchorObject) |
| 40 m_anchorObject = findAnchor(m_scroller); | 66 return; |
| 41 if (!m_anchorObject) | 67 m_anchorObject = findAnchor(m_scroller); |
| 42 return; | 68 if (!m_anchorObject) |
| 43 m_anchorObject->setIsScrollAnchorObject(); | 69 return; |
| 44 } | 70 m_anchorObject->setIsScrollAnchorObject(); |
| 45 m_savedRelativeOffset = computeRelativeOffset(m_scroller, m_anchorObject); | 71 m_savedRelativeOffset = computeRelativeOffset(m_scroller, m_anchorObject); |
| 46 } | 72 } |
| 47 | 73 |
| 48 void ScrollAnchor::restore() | 74 void ScrollAnchor::restore() |
| 49 { | 75 { |
| 50 if (!m_anchorObject) | 76 if (!m_anchorObject) |
| 51 return; | 77 return; |
| 52 | 78 |
| 53 DoubleSize adjustment = computeRelativeOffset(m_scroller, m_anchorObject) -
m_savedRelativeOffset; | 79 DoubleSize adjustment = computeRelativeOffset(m_scroller, m_anchorObject) -
m_savedRelativeOffset; |
| 54 if (!adjustment.isZero()) | 80 if (!adjustment.isZero()) |
| 55 m_scroller->setScrollPosition(m_scroller->scrollPositionDouble() + adjus
tment, AnchoringScroll); | 81 m_scroller->setScrollPosition(m_scroller->scrollPositionDouble() + adjus
tment, AnchoringScroll); |
| 56 } | 82 } |
| 57 | 83 |
| 58 void ScrollAnchor::clear() | 84 void ScrollAnchor::clear() |
| 59 { | 85 { |
| 60 LayoutObject* anchorObject = m_anchorObject; | 86 LayoutObject* anchorObject = m_anchorObject; |
| 61 m_anchorObject = nullptr; | 87 m_anchorObject = nullptr; |
| 62 | 88 |
| 63 if (anchorObject) | 89 if (anchorObject) |
| 64 anchorObject->maybeClearIsScrollAnchorObject(); | 90 anchorObject->maybeClearIsScrollAnchorObject(); |
| 65 } | 91 } |
| 66 | 92 |
| 67 } // namespace blink | 93 } // namespace blink |
| OLD | NEW |