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

Unified Diff: third_party/WebKit/Source/core/layout/ScrollAnchor.cpp

Issue 2245873002: Disable anchoring if ancestor changes padding or margin (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 4 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/layout/ScrollAnchor.cpp
diff --git a/third_party/WebKit/Source/core/layout/ScrollAnchor.cpp b/third_party/WebKit/Source/core/layout/ScrollAnchor.cpp
index d16bbed3575f12d768200941106ed21011b8e089..3e9f636fcac1a2ea744e1a4f8fd3edd0501fcec1 100644
--- a/third_party/WebKit/Source/core/layout/ScrollAnchor.cpp
+++ b/third_party/WebKit/Source/core/layout/ScrollAnchor.cpp
@@ -19,6 +19,7 @@ static const int kMaxAdjustments = 20;
ScrollAnchor::ScrollAnchor()
: m_hasBounced(false)
, m_adjustmentCount(0)
+ , m_anyAncestorChangedPaddingOrMargin(false)
{
}
@@ -199,13 +200,18 @@ void ScrollAnchor::save()
clear();
return;
}
- if (m_current)
+
+ if (m_current) {
+ m_anyAncestorChangedPaddingOrMargin = paddingOrBorderChanged();
return;
+ }
findAnchor();
if (!m_current)
return;
+ m_anyAncestorChangedPaddingOrMargin = paddingOrBorderChanged();
+
m_current.m_anchorObject->setIsScrollAnchorObject();
m_current.m_savedRelativeOffset = computeRelativeOffset(
m_current.m_anchorObject, m_scroller, m_current.m_corner);
@@ -240,6 +246,18 @@ IntSize ScrollAnchor::computeAdjustment(const AnchorPoint& anchorPoint) const
roundedIntSize(anchorPoint.m_savedRelativeOffset);
}
+bool ScrollAnchor::paddingOrBorderChanged() const
+{
+ LayoutObject* current = anchorObject();
+ while (current && current != scrollerLayoutBox(m_scroller)) {
+ if (current->isLayoutBlock()
+ && (toLayoutBlock(current)->heightAvailableToChildrenChanged()))
+ return true;
+ current = current->parent();
+ }
+ return false;
+}
+
void ScrollAnchor::restore()
{
DCHECK(m_scroller);
@@ -250,11 +268,23 @@ void ScrollAnchor::restore()
adjust(-m_lastAdjustment);
return;
}
+
if (!m_current)
return;
+
+ // Authors often change the padding or margin when trying to simulate
+ // position:sticky on headers. Use this as a heuristic to disable scroll
+ // anchoring so that we don't conflict with JS changes.
+ // TODO(ymalik): Does this change allow us to remove the de-bouncing hack?
+ if (m_anyAncestorChangedPaddingOrMargin) {
+ clear();
+ return;
+ }
+
IntSize adjustment = computeAdjustment(m_current);
if (adjustment.isZero())
return;
+
if (adjustment == -m_lastAdjustment && m_hasBounced) {
// Don't bounce more than once.
clear();
« 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