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

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

Issue 2394053004: Clear scroll anchor on all parent scrollers from ScrollAnchor::clear (Closed)
Patch Set: review comments Created 4 years, 2 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"
11 #include "core/layout/line/InlineTextBox.h" 11 #include "core/layout/line/InlineTextBox.h"
12 #include "core/paint/PaintLayer.h"
12 #include "core/paint/PaintLayerScrollableArea.h" 13 #include "core/paint/PaintLayerScrollableArea.h"
13 #include "platform/Histogram.h" 14 #include "platform/Histogram.h"
14 15
15 namespace blink { 16 namespace blink {
16 17
17 using Corner = ScrollAnchor::Corner; 18 using Corner = ScrollAnchor::Corner;
18 19
19 ScrollAnchor::ScrollAnchor() 20 ScrollAnchor::ScrollAnchor()
20 : m_anchorObject(nullptr), 21 : m_anchorObject(nullptr),
21 m_corner(Corner::TopLeft), 22 m_corner(Corner::TopLeft),
22 m_scrollAnchorDisablingStyleChanged(false), 23 m_scrollAnchorDisablingStyleChanged(false),
23 m_saved(false) {} 24 m_saved(false) {}
24 25
25 ScrollAnchor::ScrollAnchor(ScrollableArea* scroller) : ScrollAnchor() { 26 ScrollAnchor::ScrollAnchor(ScrollableArea* scroller) : ScrollAnchor() {
26 setScroller(scroller); 27 setScroller(scroller);
27 } 28 }
28 29
29 ScrollAnchor::~ScrollAnchor() {} 30 ScrollAnchor::~ScrollAnchor() {}
30 31
31 void ScrollAnchor::setScroller(ScrollableArea* scroller) { 32 void ScrollAnchor::setScroller(ScrollableArea* scroller) {
32 DCHECK(m_scroller != scroller); 33 DCHECK(m_scroller != scroller);
33 DCHECK(scroller); 34 DCHECK(scroller);
34 DCHECK(scroller->isRootFrameViewport() || scroller->isFrameView() || 35 DCHECK(scroller->isRootFrameViewport() || scroller->isFrameView() ||
35 scroller->isPaintLayerScrollableArea()); 36 scroller->isPaintLayerScrollableArea());
36 m_scroller = scroller; 37 m_scroller = scroller;
37 clear(); 38 clearSelf();
38 } 39 }
39 40
40 // TODO(pilgrim): Replace all instances of scrollerLayoutBox with 41 // TODO(pilgrim): Replace all instances of scrollerLayoutBox with
41 // scrollerLayoutBoxItem, https://crbug.com/499321 42 // scrollerLayoutBoxItem, https://crbug.com/499321
42 static LayoutBox* scrollerLayoutBox(const ScrollableArea* scroller) { 43 static LayoutBox* scrollerLayoutBox(const ScrollableArea* scroller) {
43 LayoutBox* box = scroller->layoutBox(); 44 LayoutBox* box = scroller->layoutBox();
44 DCHECK(box); 45 DCHECK(box);
45 return box; 46 return box;
46 } 47 }
47 48
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 if (m_saved) 216 if (m_saved)
216 return; 217 return;
217 m_saved = true; 218 m_saved = true;
218 DCHECK(m_scroller); 219 DCHECK(m_scroller);
219 ScrollOffset scrollOffset = m_scroller->scrollOffset(); 220 ScrollOffset scrollOffset = m_scroller->scrollOffset();
220 float blockDirectionScrollOffset = 221 float blockDirectionScrollOffset =
221 scrollerLayoutBox(m_scroller)->isHorizontalWritingMode() 222 scrollerLayoutBox(m_scroller)->isHorizontalWritingMode()
222 ? scrollOffset.height() 223 ? scrollOffset.height()
223 : scrollOffset.width(); 224 : scrollOffset.width();
224 if (blockDirectionScrollOffset == 0) { 225 if (blockDirectionScrollOffset == 0) {
225 clear(); 226 clearSelf();
226 return; 227 return;
227 } 228 }
228 229
229 if (!m_anchorObject) { 230 if (!m_anchorObject) {
230 findAnchor(); 231 findAnchor();
231 if (!m_anchorObject) 232 if (!m_anchorObject)
232 return; 233 return;
233 234
234 m_anchorObject->setIsScrollAnchorObject(); 235 m_anchorObject->setIsScrollAnchorObject();
235 m_savedRelativeOffset = 236 m_savedRelativeOffset =
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
271 if (!m_anchorObject) 272 if (!m_anchorObject)
272 return; 273 return;
273 IntSize adjustment = computeAdjustment(); 274 IntSize adjustment = computeAdjustment();
274 if (adjustment.isZero()) 275 if (adjustment.isZero())
275 return; 276 return;
276 277
277 if (m_scrollAnchorDisablingStyleChanged) { 278 if (m_scrollAnchorDisablingStyleChanged) {
278 // Note that we only clear if the adjustment would have been non-zero. 279 // Note that we only clear if the adjustment would have been non-zero.
279 // This minimizes redundant calls to findAnchor. 280 // This minimizes redundant calls to findAnchor.
280 // TODO(skobes): add UMA metric for this. 281 // TODO(skobes): add UMA metric for this.
281 clear(); 282 clearSelf();
282 283
283 DEFINE_STATIC_LOCAL(EnumerationHistogram, suppressedBySanaclapHistogram, 284 DEFINE_STATIC_LOCAL(EnumerationHistogram, suppressedBySanaclapHistogram,
284 ("Layout.ScrollAnchor.SuppressedBySanaclap", 2)); 285 ("Layout.ScrollAnchor.SuppressedBySanaclap", 2));
285 suppressedBySanaclapHistogram.count(1); 286 suppressedBySanaclapHistogram.count(1);
286 287
287 return; 288 return;
288 } 289 }
289 290
290 m_scroller->setScrollOffset( 291 m_scroller->setScrollOffset(
291 m_scroller->scrollOffset() + FloatSize(adjustment), AnchoringScroll); 292 m_scroller->scrollOffset() + FloatSize(adjustment), AnchoringScroll);
292 293
293 // Update UMA metric. 294 // Update UMA metric.
294 DEFINE_STATIC_LOCAL(EnumerationHistogram, adjustedOffsetHistogram, 295 DEFINE_STATIC_LOCAL(EnumerationHistogram, adjustedOffsetHistogram,
295 ("Layout.ScrollAnchor.AdjustedScrollOffset", 2)); 296 ("Layout.ScrollAnchor.AdjustedScrollOffset", 2));
296 adjustedOffsetHistogram.count(1); 297 adjustedOffsetHistogram.count(1);
297 UseCounter::count(scrollerLayoutBox(m_scroller)->document(), 298 UseCounter::count(scrollerLayoutBox(m_scroller)->document(),
298 UseCounter::ScrollAnchored); 299 UseCounter::ScrollAnchored);
299 } 300 }
300 301
301 void ScrollAnchor::clear() { 302 void ScrollAnchor::clearSelf(bool unconditionally) {
302 LayoutObject* anchorObject = m_anchorObject; 303 LayoutObject* anchorObject = m_anchorObject;
303 m_anchorObject = nullptr; 304 m_anchorObject = nullptr;
304 305
305 if (anchorObject) 306 if (anchorObject)
306 anchorObject->maybeClearIsScrollAnchorObject(); 307 anchorObject->clearIsScrollAnchorObject(unconditionally);
308 }
309
310 void ScrollAnchor::clear() {
311 LayoutObject* layoutObject =
312 m_anchorObject ? m_anchorObject : scrollerLayoutBox(m_scroller);
313 PaintLayer* layer = nullptr;
314 if (LayoutObject* parent = layoutObject->parent())
315 layer = parent->enclosingLayer();
316
317 // Walk up the layer tree to clear any scroll anchors.
318 while (layer) {
319 if (PaintLayerScrollableArea* scrollableArea = layer->getScrollableArea()) {
320 ScrollAnchor* anchor = scrollableArea->scrollAnchor();
321 DCHECK(anchor);
322 anchor->clearSelf(true);
323 }
324 layer = layer->parent();
325 }
326
327 if (FrameView* view = layoutObject->frameView()) {
328 ScrollAnchor* anchor = view->scrollAnchor();
329 DCHECK(anchor);
330 anchor->clearSelf(true);
331 }
307 } 332 }
308 333
309 bool ScrollAnchor::refersTo(const LayoutObject* layoutObject) const { 334 bool ScrollAnchor::refersTo(const LayoutObject* layoutObject) const {
310 return m_anchorObject == layoutObject; 335 return m_anchorObject == layoutObject;
311 } 336 }
312 337
313 void ScrollAnchor::notifyRemoved(LayoutObject* layoutObject) { 338 void ScrollAnchor::notifyRemoved(LayoutObject* layoutObject) {
314 if (m_anchorObject == layoutObject) 339 if (m_anchorObject == layoutObject)
315 clear(); 340 clearSelf();
316 } 341 }
317 342
318 } // namespace blink 343 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/layout/ScrollAnchor.h ('k') | third_party/WebKit/Source/core/layout/ScrollAnchorTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698