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 |