Index: third_party/WebKit/Source/core/layout/LayoutObject.cpp |
diff --git a/third_party/WebKit/Source/core/layout/LayoutObject.cpp b/third_party/WebKit/Source/core/layout/LayoutObject.cpp |
index 37f163851d52e143dff84248748b9b67fc700f65..bf883fdfadcfb9f0b6b578a78134db2e66cdcb4f 100644 |
--- a/third_party/WebKit/Source/core/layout/LayoutObject.cpp |
+++ b/third_party/WebKit/Source/core/layout/LayoutObject.cpp |
@@ -1712,6 +1712,24 @@ static inline bool areCursorsEqual(const ComputedStyle* a, const ComputedStyle* |
return a->cursor() == b->cursor() && (a->cursors() == b->cursors() || areNonIdenticalCursorListsEqual(a, b)); |
} |
+void LayoutObject::setScrollAnchorDisablingStyleChangedOnAncestor() |
+{ |
+ // Walk up the parent chain and find the first scrolling block to disable |
+ // scroll anchoring on. |
+ LayoutObject* object = parent(); |
+ Element* viewportDefiningElement = document().viewportDefiningElement(); |
+ while (object) { |
+ if (object->isLayoutBlock()) { |
+ LayoutBlock* block = toLayoutBlock(object); |
+ if (block->hasOverflowClip() || block->node() == viewportDefiningElement) { |
+ block->setScrollAnchorDisablingStyleChanged(true); |
+ return; |
+ } |
+ } |
+ object = object->parent(); |
+ } |
+} |
+ |
void LayoutObject::styleDidChange(StyleDifference diff, const ComputedStyle* oldStyle) |
{ |
if (s_affectsParentBlock) |
@@ -1723,6 +1741,11 @@ void LayoutObject::styleDidChange(StyleDifference diff, const ComputedStyle* old |
if (diff.needsFullLayout()) { |
LayoutCounter::layoutObjectStyleChanged(*this, oldStyle, *m_style); |
+ // If the in-flow state of an element is changed, disable scroll |
+ // anchoring on the containing scroller. |
+ if (oldStyle->hasOutOfFlowPosition() != m_style->hasOutOfFlowPosition()) |
+ setScrollAnchorDisablingStyleChangedOnAncestor(); |
+ |
// If the object already needs layout, then setNeedsLayout won't do |
// any work. But if the containing block has changed, then we may need |
// to mark the new containing blocks for layout. The change that can |