Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(122)

Side by Side Diff: third_party/WebKit/Source/core/layout/ScrollAnchor.cpp

Issue 2360833002: Only anchor along the block layout axis. (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/LayoutBlockFlow.h" 9 #include "core/layout/LayoutBlockFlow.h"
10 #include "core/layout/api/LayoutBoxItem.h" 10 #include "core/layout/api/LayoutBoxItem.h"
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 LayoutBox* box = scroller->layoutBox(); 50 LayoutBox* box = scroller->layoutBox();
51 DCHECK(box); 51 DCHECK(box);
52 return box; 52 return box;
53 } 53 }
54 54
55 static LayoutBoxItem scrollerLayoutBoxItem(const ScrollableArea* scroller) 55 static LayoutBoxItem scrollerLayoutBoxItem(const ScrollableArea* scroller)
56 { 56 {
57 return LayoutBoxItem(scrollerLayoutBox(scroller)); 57 return LayoutBoxItem(scrollerLayoutBox(scroller));
58 } 58 }
59 59
60 static Corner cornerFromCandidateRect(const LayoutObject* layoutObject) 60 static Corner cornerToAnchor(const ScrollableArea* scroller)
61 { 61 {
62 ASSERT(layoutObject); 62 const ComputedStyle* style = scrollerLayoutBox(scroller)->style();
63 if (layoutObject->style()->isFlippedBlocksWritingMode() 63 if (style->isFlippedBlocksWritingMode() || !style->isLeftToRightDirection())
64 || !layoutObject->style()->isLeftToRightDirection())
65 return Corner::TopRight; 64 return Corner::TopRight;
66 return Corner::TopLeft; 65 return Corner::TopLeft;
67 } 66 }
68 67
69 static LayoutPoint cornerPointOfRect(LayoutRect rect, Corner whichCorner) 68 static LayoutPoint cornerPointOfRect(LayoutRect rect, Corner whichCorner)
70 { 69 {
71 switch (whichCorner) { 70 switch (whichCorner) {
72 case Corner::TopLeft: return rect.minXMinYCorner(); 71 case Corner::TopLeft: return rect.minXMinYCorner();
73 case Corner::TopRight: return rect.maxXMinYCorner(); 72 case Corner::TopRight: return rect.maxXMinYCorner();
74 } 73 }
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 if (candidate->style()->overflowAnchor() == AnchorNone) 152 if (candidate->style()->overflowAnchor() == AnchorNone)
154 return ExamineResult(Skip); 153 return ExamineResult(Skip);
155 154
156 LayoutRect candidateRect = relativeBounds(candidate, m_scroller); 155 LayoutRect candidateRect = relativeBounds(candidate, m_scroller);
157 LayoutRect visibleRect = scrollerLayoutBoxItem(m_scroller).overflowClipRect( LayoutPoint()); 156 LayoutRect visibleRect = scrollerLayoutBoxItem(m_scroller).overflowClipRect( LayoutPoint());
158 157
159 bool occupiesSpace = candidateRect.width() > 0 && candidateRect.height() > 0 ; 158 bool occupiesSpace = candidateRect.width() > 0 && candidateRect.height() > 0 ;
160 if (occupiesSpace && visibleRect.intersects(candidateRect)) { 159 if (occupiesSpace && visibleRect.intersects(candidateRect)) {
161 return ExamineResult( 160 return ExamineResult(
162 visibleRect.contains(candidateRect) ? Return : Constrain, 161 visibleRect.contains(candidateRect) ? Return : Constrain,
163 cornerFromCandidateRect(candidate)); 162 cornerToAnchor(m_scroller));
164 } else { 163 } else {
165 return ExamineResult(Skip); 164 return ExamineResult(Skip);
166 } 165 }
167 } 166 }
168 167
169 void ScrollAnchor::findAnchor() 168 void ScrollAnchor::findAnchor()
170 { 169 {
171 TRACE_EVENT0("blink", "ScrollAnchor::findAnchor"); 170 TRACE_EVENT0("blink", "ScrollAnchor::findAnchor");
172 SCOPED_BLINK_UMA_HISTOGRAM_TIMER("Layout.ScrollAnchor.TimeToFindAnchor"); 171 SCOPED_BLINK_UMA_HISTOGRAM_TIMER("Layout.ScrollAnchor.TimeToFindAnchor");
173 172
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 current = current->parent(); 210 current = current->parent();
212 } 211 }
213 } 212 }
214 213
215 void ScrollAnchor::save() 214 void ScrollAnchor::save()
216 { 215 {
217 if (m_saved) 216 if (m_saved)
218 return; 217 return;
219 m_saved = true; 218 m_saved = true;
220 DCHECK(m_scroller); 219 DCHECK(m_scroller);
221 if (m_scroller->scrollPosition() == IntPoint::zero()) { 220
221 ScrollbarOrientation blockLayoutAxis =
222 scrollerLayoutBox(m_scroller)->isHorizontalWritingMode() ? VerticalScrol lbar : HorizontalScrollbar;
223 if (m_scroller->scrollPosition(blockLayoutAxis) == 0) {
222 clear(); 224 clear();
223 return; 225 return;
224 } 226 }
225 227
226 if (!m_anchorObject) { 228 if (!m_anchorObject) {
227 findAnchor(); 229 findAnchor();
228 if (!m_anchorObject) 230 if (!m_anchorObject)
229 return; 231 return;
230 232
231 m_anchorObject->setIsScrollAnchorObject(); 233 m_anchorObject->setIsScrollAnchorObject();
232 m_savedRelativeOffset = computeRelativeOffset( 234 m_savedRelativeOffset = computeRelativeOffset(
233 m_anchorObject, m_scroller, m_corner); 235 m_anchorObject, m_scroller, m_corner);
234 } 236 }
235 237
236 // Note that we must compute this during save() since the scroller's 238 // Note that we must compute this during save() since the scroller's
237 // descendants have finished layout (and had the bit cleared) by the 239 // descendants have finished layout (and had the bit cleared) by the
238 // time restore() is called. 240 // time restore() is called.
239 m_scrollAnchorDisablingStyleChanged = computeScrollAnchorDisablingStyleChang ed(); 241 m_scrollAnchorDisablingStyleChanged = computeScrollAnchorDisablingStyleChang ed();
240 } 242 }
241 243
242 IntSize ScrollAnchor::computeAdjustment() const 244 IntSize ScrollAnchor::computeAdjustment() const
243 { 245 {
244 // The anchor node can report fractional positions, but it is DIP-snapped wh en 246 // The anchor node can report fractional positions, but it is DIP-snapped wh en
245 // painting (crbug.com/610805), so we must round the offsets to determine th e 247 // painting (crbug.com/610805), so we must round the offsets to determine th e
246 // visual delta. If we scroll by the delta in LayoutUnits, the snapping of t he 248 // visual delta. If we scroll by the delta in LayoutUnits, the snapping of t he
247 // anchor node may round differently from the snapping of the scroll positio n. 249 // anchor node may round differently from the snapping of the scroll positio n.
248 // (For example, anchor moving from 2.4px -> 2.6px is really 2px -> 3px, so we 250 // (For example, anchor moving from 2.4px -> 2.6px is really 2px -> 3px, so we
249 // should scroll by 1px instead of 0.2px.) This is true regardless of whethe r 251 // should scroll by 1px instead of 0.2px.) This is true regardless of whethe r
250 // the ScrollableArea actually uses fractional scroll positions. 252 // the ScrollableArea actually uses fractional scroll positions.
251 return roundedIntSize(computeRelativeOffset(m_anchorObject, m_scroller, m_co rner)) - 253 IntSize delta = roundedIntSize(computeRelativeOffset(m_anchorObject, m_scrol ler, m_corner)) -
252 roundedIntSize(m_savedRelativeOffset); 254 roundedIntSize(m_savedRelativeOffset);
255
256 // Only adjust on the block layout axis.
257 if (scrollerLayoutBox(m_scroller)->isHorizontalWritingMode())
258 delta.setWidth(0);
259 else
260 delta.setHeight(0);
261 return delta;
253 } 262 }
254 263
255 void ScrollAnchor::restore() 264 void ScrollAnchor::restore()
256 { 265 {
257 if (!m_saved) 266 if (!m_saved)
258 return; 267 return;
259 m_saved = false; 268 m_saved = false;
260 DCHECK(m_scroller); 269 DCHECK(m_scroller);
261 if (!m_anchorObject) 270 if (!m_anchorObject)
262 return; 271 return;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 return m_anchorObject == layoutObject; 309 return m_anchorObject == layoutObject;
301 } 310 }
302 311
303 void ScrollAnchor::notifyRemoved(LayoutObject* layoutObject) 312 void ScrollAnchor::notifyRemoved(LayoutObject* layoutObject)
304 { 313 {
305 if (m_anchorObject == layoutObject) 314 if (m_anchorObject == layoutObject)
306 clear(); 315 clear();
307 } 316 }
308 317
309 } // namespace blink 318 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698