Commit 3d27469c authored by Robert Flack's avatar Robert Flack Committed by Commit Bot

Fix crash when sticky element is removed from root without compositing update.

BUG=755307

Cq-Include-Trybots: master.tryserver.chromium.linux:linux_layout_tests_slimming_paint_v2
Change-Id: I494ab70535eb14de98f1eb78d6e74aebef565e52
Reviewed-on: https://chromium-review.googlesource.com/690857
Commit-Queue: Robert Flack <flackr@chromium.org>
Reviewed-by: default avatarChris Harrelson <chrishtr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#505393}
parent 5ddc9618
...@@ -989,4 +989,52 @@ TEST_F(LayoutBoxModelObjectTest, InvalidatePaintLayerOnStackedChange) { ...@@ -989,4 +989,52 @@ TEST_F(LayoutBoxModelObjectTest, InvalidatePaintLayerOnStackedChange) {
target->Layer()->CompositingContainer()); target->Layer()->CompositingContainer());
} }
// Tests that when a sticky object is removed from the root scroller it
// correctly clears its viewport constrained position: https://crbug.com/755307.
TEST_F(LayoutBoxModelObjectTest, StickyRemovedFromRootScrollableArea) {
SetBodyInnerHTML(
"<style>"
"body { height: 5000px; }"
"#scroller { height: 100px; }"
"#sticky { position: sticky; top: 0; height: 50px; width: 50px; }"
"</style>"
"<div id='scroller'>"
" <div id='sticky'></div>"
" </div>");
LayoutBoxModelObject* sticky =
ToLayoutBoxModelObject(GetLayoutObjectByElementId("sticky"));
LayoutBoxModelObject* scroller =
ToLayoutBoxModelObject(GetLayoutObjectByElementId("scroller"));
// The 'scroller' starts as non-overflow, so the sticky element's ancestor
// overflow layer should be the outer scroller.
EXPECT_TRUE(sticky->Layer()->AncestorOverflowLayer()->IsRootLayer());
// We need the sticky element to not be a PaintLayer child of the scroller,
// so that it is later reparented under the scroller's PaintLayer
EXPECT_FALSE(scroller->Layer());
// Now make the scroller into an actual scroller. This will reparent the
// sticky element to be a child of the scroller, and will set its previous
// overflow layer to nullptr.
ToElement(scroller->GetNode())
->SetInlineStyleProperty(CSSPropertyOverflow, "scroll");
GetDocument().View()->UpdateAllLifecyclePhases();
// The sticky element should no longer be viewport constrained.
EXPECT_FALSE(GetDocument().View()->HasViewportConstrainedObjects());
// Making the scroller have visible overflow but still have a PaintLayer
// (in this case by making it position: relative) will cause us to need to
// recompute the sticky element's ancestor overflow layer.
ToElement(scroller->GetNode())
->SetInlineStyleProperty(CSSPropertyPosition, "relative");
ToElement(scroller->GetNode())
->SetInlineStyleProperty(CSSPropertyOverflow, "visible");
// Now try to scroll to the sticky element, this used to crash.
GetDocument().GetFrame()->DomWindow()->scrollTo(0, 500);
}
} // namespace blink } // namespace blink
...@@ -3229,6 +3229,15 @@ void PaintLayer::RemoveAncestorOverflowLayer(const PaintLayer* removed_layer) { ...@@ -3229,6 +3229,15 @@ void PaintLayer::RemoveAncestorOverflowLayer(const PaintLayer* removed_layer) {
return; return;
if (AncestorOverflowLayer()) { if (AncestorOverflowLayer()) {
// If the previous AncestorOverflowLayer is the root and this object is a
// sticky viewport constrained object, it is no longer known to be
// constrained by the root.
if (AncestorOverflowLayer()->IsRootLayer() &&
GetLayoutObject().Style()->HasStickyConstrainedPosition()) {
GetLayoutObject().View()->GetFrameView()->RemoveViewportConstrainedObject(
GetLayoutObject());
}
if (PaintLayerScrollableArea* ancestor_scrollable_area = if (PaintLayerScrollableArea* ancestor_scrollable_area =
AncestorOverflowLayer()->GetScrollableArea()) { AncestorOverflowLayer()->GetScrollableArea()) {
// TODO(pdr): When slimming paint v2 is enabled, we will need to // TODO(pdr): When slimming paint v2 is enabled, we will need to
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment