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

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

Issue 2002623003: Exclude position:absolute elements when picking an anchor for ScrollAnchoring (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: exclude only for non-zero top/left/bottom/right Created 4 years, 6 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
« no previous file with comments | « no previous file | third_party/WebKit/Source/core/layout/ScrollAnchorTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | third_party/WebKit/Source/core/layout/ScrollAnchorTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698