| 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/LayoutBlockFlow.h" | 9 #include "core/layout/LayoutBlockFlow.h" |
| 10 #include "core/layout/api/LayoutBoxItem.h" | 10 #include "core/layout/api/LayoutBoxItem.h" |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 } | 27 } |
| 28 | 28 |
| 29 ScrollAnchor::~ScrollAnchor() {} | 29 ScrollAnchor::~ScrollAnchor() {} |
| 30 | 30 |
| 31 void ScrollAnchor::setScroller(ScrollableArea* scroller) { | 31 void ScrollAnchor::setScroller(ScrollableArea* scroller) { |
| 32 DCHECK(m_scroller != scroller); | 32 DCHECK(m_scroller != scroller); |
| 33 DCHECK(scroller); | 33 DCHECK(scroller); |
| 34 DCHECK(scroller->isRootFrameViewport() || scroller->isFrameView() || | 34 DCHECK(scroller->isRootFrameViewport() || scroller->isFrameView() || |
| 35 scroller->isPaintLayerScrollableArea()); | 35 scroller->isPaintLayerScrollableArea()); |
| 36 m_scroller = scroller; | 36 m_scroller = scroller; |
| 37 clear(); | 37 clearForContainingScroller(); |
| 38 } | 38 } |
| 39 | 39 |
| 40 // TODO(pilgrim) replace all instances of scrollerLayoutBox with scrollerLayoutB
oxItem | 40 // TODO(pilgrim) replace all instances of scrollerLayoutBox with scrollerLayoutB
oxItem |
| 41 // https://crbug.com/499321 | 41 // https://crbug.com/499321 |
| 42 static LayoutBox* scrollerLayoutBox(const ScrollableArea* scroller) { | 42 static LayoutBox* scrollerLayoutBox(const ScrollableArea* scroller) { |
| 43 LayoutBox* box = scroller->layoutBox(); | 43 LayoutBox* box = scroller->layoutBox(); |
| 44 DCHECK(box); | 44 DCHECK(box); |
| 45 return box; | 45 return box; |
| 46 } | 46 } |
| 47 | 47 |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 if (m_saved) | 215 if (m_saved) |
| 216 return; | 216 return; |
| 217 m_saved = true; | 217 m_saved = true; |
| 218 DCHECK(m_scroller); | 218 DCHECK(m_scroller); |
| 219 | 219 |
| 220 ScrollbarOrientation blockLayoutAxis = | 220 ScrollbarOrientation blockLayoutAxis = |
| 221 scrollerLayoutBox(m_scroller)->isHorizontalWritingMode() | 221 scrollerLayoutBox(m_scroller)->isHorizontalWritingMode() |
| 222 ? VerticalScrollbar | 222 ? VerticalScrollbar |
| 223 : HorizontalScrollbar; | 223 : HorizontalScrollbar; |
| 224 if (m_scroller->scrollPosition(blockLayoutAxis) == 0) { | 224 if (m_scroller->scrollPosition(blockLayoutAxis) == 0) { |
| 225 clear(); | 225 clearForContainingScroller(); |
| 226 return; | 226 return; |
| 227 } | 227 } |
| 228 | 228 |
| 229 if (!m_anchorObject) { | 229 if (!m_anchorObject) { |
| 230 findAnchor(); | 230 findAnchor(); |
| 231 if (!m_anchorObject) | 231 if (!m_anchorObject) |
| 232 return; | 232 return; |
| 233 | 233 |
| 234 m_anchorObject->setIsScrollAnchorObject(); | 234 m_anchorObject->setIsScrollAnchorObject(true); |
| 235 m_savedRelativeOffset = | 235 m_savedRelativeOffset = |
| 236 computeRelativeOffset(m_anchorObject, m_scroller, m_corner); | 236 computeRelativeOffset(m_anchorObject, m_scroller, m_corner); |
| 237 } | 237 } |
| 238 | 238 |
| 239 // Note that we must compute this during save() since the scroller's | 239 // Note that we must compute this during save() since the scroller's |
| 240 // descendants have finished layout (and had the bit cleared) by the | 240 // descendants have finished layout (and had the bit cleared) by the |
| 241 // time restore() is called. | 241 // time restore() is called. |
| 242 m_scrollAnchorDisablingStyleChanged = | 242 m_scrollAnchorDisablingStyleChanged = |
| 243 computeScrollAnchorDisablingStyleChanged(); | 243 computeScrollAnchorDisablingStyleChanged(); |
| 244 } | 244 } |
| (...skipping 26 matching lines...) Expand all Loading... |
| 271 if (!m_anchorObject) | 271 if (!m_anchorObject) |
| 272 return; | 272 return; |
| 273 IntSize adjustment = computeAdjustment(); | 273 IntSize adjustment = computeAdjustment(); |
| 274 if (adjustment.isZero()) | 274 if (adjustment.isZero()) |
| 275 return; | 275 return; |
| 276 | 276 |
| 277 if (m_scrollAnchorDisablingStyleChanged) { | 277 if (m_scrollAnchorDisablingStyleChanged) { |
| 278 // Note that we only clear if the adjustment would have been non-zero. | 278 // Note that we only clear if the adjustment would have been non-zero. |
| 279 // This minimizes redundant calls to findAnchor. | 279 // This minimizes redundant calls to findAnchor. |
| 280 // TODO(skobes): add UMA metric for this. | 280 // TODO(skobes): add UMA metric for this. |
| 281 clear(); | 281 clearForContainingScroller(); |
| 282 | 282 |
| 283 DEFINE_STATIC_LOCAL(EnumerationHistogram, suppressedBySanaclapHistogram, | 283 DEFINE_STATIC_LOCAL(EnumerationHistogram, suppressedBySanaclapHistogram, |
| 284 ("Layout.ScrollAnchor.SuppressedBySanaclap", 2)); | 284 ("Layout.ScrollAnchor.SuppressedBySanaclap", 2)); |
| 285 suppressedBySanaclapHistogram.count(1); | 285 suppressedBySanaclapHistogram.count(1); |
| 286 | 286 |
| 287 return; | 287 return; |
| 288 } | 288 } |
| 289 | 289 |
| 290 m_scroller->setScrollPosition(m_scroller->scrollPositionDouble() + adjustment, | 290 m_scroller->setScrollPosition(m_scroller->scrollPositionDouble() + adjustment, |
| 291 AnchoringScroll); | 291 AnchoringScroll); |
| 292 | 292 |
| 293 // Update UMA metric. | 293 // Update UMA metric. |
| 294 DEFINE_STATIC_LOCAL(EnumerationHistogram, adjustedOffsetHistogram, | 294 DEFINE_STATIC_LOCAL(EnumerationHistogram, adjustedOffsetHistogram, |
| 295 ("Layout.ScrollAnchor.AdjustedScrollOffset", 2)); | 295 ("Layout.ScrollAnchor.AdjustedScrollOffset", 2)); |
| 296 adjustedOffsetHistogram.count(1); | 296 adjustedOffsetHistogram.count(1); |
| 297 UseCounter::count(scrollerLayoutBox(m_scroller)->document(), | 297 UseCounter::count(scrollerLayoutBox(m_scroller)->document(), |
| 298 UseCounter::ScrollAnchored); | 298 UseCounter::ScrollAnchored); |
| 299 } | 299 } |
| 300 | 300 |
| 301 void ScrollAnchor::clear() { | 301 void ScrollAnchor::releaseAnchor() { |
| 302 m_anchorObject = nullptr; |
| 303 } |
| 304 |
| 305 void ScrollAnchor::clearForContainingScroller() { |
| 302 LayoutObject* anchorObject = m_anchorObject; | 306 LayoutObject* anchorObject = m_anchorObject; |
| 303 m_anchorObject = nullptr; | 307 releaseAnchor(); |
| 304 | 308 |
| 305 if (anchorObject) | 309 if (anchorObject) |
| 306 anchorObject->maybeClearIsScrollAnchorObject(); | 310 anchorObject->maybeClearIsScrollAnchorObject(); |
| 307 } | 311 } |
| 308 | 312 |
| 313 void ScrollAnchor::clear() { |
| 314 if (m_anchorObject) |
| 315 m_anchorObject->clearScrollAnchors(); |
| 316 else |
| 317 scrollerLayoutBox(m_scroller)->clearScrollAnchors(); |
| 318 } |
| 319 |
| 309 bool ScrollAnchor::refersTo(const LayoutObject* layoutObject) const { | 320 bool ScrollAnchor::refersTo(const LayoutObject* layoutObject) const { |
| 310 return m_anchorObject == layoutObject; | 321 return m_anchorObject == layoutObject; |
| 311 } | 322 } |
| 312 | 323 |
| 313 void ScrollAnchor::notifyRemoved(LayoutObject* layoutObject) { | |
| 314 if (m_anchorObject == layoutObject) | |
| 315 clear(); | |
| 316 } | |
| 317 | |
| 318 } // namespace blink | 324 } // namespace blink |
| OLD | NEW |