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/frame/FrameView.h" | 7 #include "core/frame/FrameView.h" |
8 #include "core/frame/UseCounter.h" | 8 #include "core/frame/UseCounter.h" |
9 #include "core/layout/line/InlineTextBox.h" | 9 #include "core/layout/line/InlineTextBox.h" |
10 #include "core/paint/PaintLayerScrollableArea.h" | 10 #include "core/paint/PaintLayerScrollableArea.h" |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
97 if (scroller->isFrameView()) | 97 if (scroller->isFrameView()) |
98 relativeBounds.moveBy(-flooredIntPoint(scroller->scrollPositionDouble()) ); | 98 relativeBounds.moveBy(-flooredIntPoint(scroller->scrollPositionDouble()) ); |
99 return relativeBounds; | 99 return relativeBounds; |
100 } | 100 } |
101 | 101 |
102 static LayoutPoint computeRelativeOffset(const LayoutObject* layoutObject, const ScrollableArea* scroller, Corner corner) | 102 static LayoutPoint computeRelativeOffset(const LayoutObject* layoutObject, const ScrollableArea* scroller, Corner corner) |
103 { | 103 { |
104 return cornerPointOfRect(relativeBounds(layoutObject, scroller), corner); | 104 return cornerPointOfRect(relativeBounds(layoutObject, scroller), corner); |
105 } | 105 } |
106 | 106 |
107 static bool candidateMovesWithScroller(const LayoutObject* candidate, const Scro llableArea* scroller) | 107 static bool candidateMayMoveWithScroller(const LayoutObject* candidate, const Sc rollableArea* scroller) |
108 { | 108 { |
109 if (candidate->style() && candidate->style()->hasViewportConstrainedPosition ()) | 109 if (const ComputedStyle* style = candidate->style()) { |
110 return false; | 110 if (style->hasViewportConstrainedPosition()) |
111 return false; | |
112 | |
113 if (style->hasOutOfFlowPosition()) { | |
114 // Absolute positioned elements with non-zero scrollTop/Left/Bottom/ | |
115 // Right can stick to the viewport. | |
116 if (!style->top().isZero()) | |
skobes
2016/06/01 04:38:55
nit: this would be more concise with ||
| |
117 return false; | |
118 if (!style->left().isZero()) | |
119 return false; | |
120 if (!style->bottom().isZero()) | |
121 return false; | |
122 if (!style->right().isZero()) | |
123 return false; | |
124 } | |
125 } | |
111 | 126 |
112 bool skippedByContainerLookup = false; | 127 bool skippedByContainerLookup = false; |
113 candidate->container(scrollerLayoutBox(scroller), &skippedByContainerLookup) ; | 128 candidate->container(scrollerLayoutBox(scroller), &skippedByContainerLookup) ; |
114 return !skippedByContainerLookup; | 129 return !skippedByContainerLookup; |
115 } | 130 } |
116 | 131 |
117 ScrollAnchor::ExamineResult ScrollAnchor::examine(const LayoutObject* candidate) const | 132 ScrollAnchor::ExamineResult ScrollAnchor::examine(const LayoutObject* candidate) const |
118 { | 133 { |
119 if (candidate->isLayoutInline()) | 134 if (candidate->isLayoutInline()) |
120 return ExamineResult(Continue); | 135 return ExamineResult(Continue); |
121 | 136 |
122 if (!candidate->isText() && !candidate->isBox()) | 137 if (!candidate->isText() && !candidate->isBox()) |
123 return ExamineResult(Skip); | 138 return ExamineResult(Skip); |
124 | 139 |
125 if (!candidateMovesWithScroller(candidate, m_scroller)) | 140 if (!candidateMayMoveWithScroller(candidate, m_scroller)) |
126 return ExamineResult(Skip); | 141 return ExamineResult(Skip); |
127 | 142 |
128 LayoutRect candidateRect = relativeBounds(candidate, m_scroller); | 143 LayoutRect candidateRect = relativeBounds(candidate, m_scroller); |
129 LayoutRect visibleRect = scrollerLayoutBoxItem(m_scroller).overflowClipRect( LayoutPoint()); | 144 LayoutRect visibleRect = scrollerLayoutBoxItem(m_scroller).overflowClipRect( LayoutPoint()); |
130 | 145 |
131 bool occupiesSpace = candidateRect.width() > 0 && candidateRect.height() > 0 ; | 146 bool occupiesSpace = candidateRect.width() > 0 && candidateRect.height() > 0 ; |
132 if (occupiesSpace && visibleRect.intersects(candidateRect)) { | 147 if (occupiesSpace && visibleRect.intersects(candidateRect)) { |
133 return ExamineResult( | 148 return ExamineResult( |
134 visibleRect.contains(candidateRect) ? Return : Constrain, | 149 visibleRect.contains(candidateRect) ? Return : Constrain, |
135 cornerFromCandidateRect(candidate)); | 150 cornerFromCandidateRect(candidate)); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
181 return; | 196 return; |
182 | 197 |
183 m_current.m_anchorObject->setIsScrollAnchorObject(); | 198 m_current.m_anchorObject->setIsScrollAnchorObject(); |
184 m_current.m_savedRelativeOffset = computeRelativeOffset( | 199 m_current.m_savedRelativeOffset = computeRelativeOffset( |
185 m_current.m_anchorObject, m_scroller, m_current.m_corner); | 200 m_current.m_anchorObject, m_scroller, m_current.m_corner); |
186 | 201 |
187 if (m_lastAdjusted) { | 202 if (m_lastAdjusted) { |
188 // We need to update m_lastAdjusted.m_savedRelativeOffset, since it is | 203 // We need to update m_lastAdjusted.m_savedRelativeOffset, since it is |
189 // relative to the visible rect and the user may have scrolled since the | 204 // relative to the visible rect and the user may have scrolled since the |
190 // last adjustment. | 205 // last adjustment. |
191 if (!candidateMovesWithScroller(m_lastAdjusted.m_anchorObject, m_scrolle r)) { | 206 if (!candidateMayMoveWithScroller(m_lastAdjusted.m_anchorObject, m_scrol ler)) { |
192 m_lastAdjusted.clear(); | 207 m_lastAdjusted.clear(); |
193 } else if (m_lastAdjusted.m_anchorObject == m_current.m_anchorObject | 208 } else if (m_lastAdjusted.m_anchorObject == m_current.m_anchorObject |
194 && m_lastAdjusted.m_corner == m_current.m_corner) { | 209 && m_lastAdjusted.m_corner == m_current.m_corner) { |
195 m_lastAdjusted.m_savedRelativeOffset = m_current.m_savedRelativeOffs et; | 210 m_lastAdjusted.m_savedRelativeOffset = m_current.m_savedRelativeOffs et; |
196 } else { | 211 } else { |
197 m_lastAdjusted.m_savedRelativeOffset = computeRelativeOffset( | 212 m_lastAdjusted.m_savedRelativeOffset = computeRelativeOffset( |
198 m_lastAdjusted.m_anchorObject, m_scroller, m_lastAdjusted.m_corn er); | 213 m_lastAdjusted.m_anchorObject, m_scroller, m_lastAdjusted.m_corn er); |
199 } | 214 } |
200 } | 215 } |
201 } | 216 } |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
294 | 309 |
295 void ScrollAnchor::notifyRemoved(LayoutObject* layoutObject) | 310 void ScrollAnchor::notifyRemoved(LayoutObject* layoutObject) |
296 { | 311 { |
297 if (m_current.m_anchorObject == layoutObject) | 312 if (m_current.m_anchorObject == layoutObject) |
298 m_current.clear(); | 313 m_current.clear(); |
299 if (m_lastAdjusted.m_anchorObject == layoutObject) | 314 if (m_lastAdjusted.m_anchorObject == layoutObject) |
300 m_lastAdjusted.clear(); | 315 m_lastAdjusted.clear(); |
301 } | 316 } |
302 | 317 |
303 } // namespace blink | 318 } // namespace blink |
OLD | NEW |