Chromium Code Reviews| 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 4bb1a9269d1804bc20db1ce51fa2ea7f888a0d57..4af33f6fce1caf8b5a702cdad435e6b1c617937b 100644 |
| --- a/third_party/WebKit/Source/core/layout/LayoutObject.cpp |
| +++ b/third_party/WebKit/Source/core/layout/LayoutObject.cpp |
| @@ -612,7 +612,11 @@ PaintLayer* LayoutObject::enclosingLayer() const { |
| PaintLayer* LayoutObject::paintingLayer() const { |
| for (const LayoutObject* current = this; current; |
| - current = current->paintInvalidationParent()) { |
| + // Use containingBlock instead of paintInvalidationParent for floating |
| + // object to omit any self-painting layers of inline objects that don't |
| + // paint the floating object. |
| + current = current->isFloating() ? current->containingBlock() |
| + : current->paintInvalidationParent()) { |
| if (current->hasLayer() && |
| toLayoutBoxModelObject(current)->layer()->isSelfPaintingLayer()) |
| return toLayoutBoxModelObject(current)->layer(); |
| @@ -887,53 +891,69 @@ LayoutBlock* LayoutObject::containerForFixedPosition( |
| return toLayoutBlock(object); |
| } |
| -LayoutBlock* LayoutObject::containingBlockForAbsolutePosition() const { |
| - LayoutObject* o = containerForAbsolutePosition(); |
| +LayoutBlock* LayoutObject::containingBlockForAbsolutePosition( |
| + const LayoutBoxModelObject* ancestor, |
| + bool* ancestorSkipped, |
| + bool* filterSkipped) const { |
| + LayoutObject* object = |
| + containerForAbsolutePosition(ancestor, ancestorSkipped, filterSkipped); |
| // For relpositioned inlines, we return the nearest non-anonymous enclosing |
| // block. We don't try to return the inline itself. This allows us to avoid |
| // having a positioned objects list in all LayoutInlines and lets us return a |
| // strongly-typed LayoutBlock* result from this method. The container() method |
| // can actually be used to obtain the inline directly. |
| - if (o && o->isInline() && !o->isAtomicInlineLevel()) { |
| - ASSERT(o->style()->hasInFlowPosition()); |
| - o = o->containingBlock(); |
| + if (object && object->isInline() && !object->isAtomicInlineLevel()) { |
| + DCHECK(object->style()->hasInFlowPosition()); |
| + object = object->containingBlock(ancestor, ancestorSkipped, filterSkipped); |
| } |
| - if (o && !o->isLayoutBlock()) |
| - o = o->containingBlock(); |
| + if (object && !object->isLayoutBlock()) |
| + object = object->containingBlock(ancestor, ancestorSkipped, filterSkipped); |
| - while (o && o->isAnonymousBlock()) |
| - o = o->containingBlock(); |
| + while (object && object->isAnonymousBlock()) |
| + object = object->containingBlock(ancestor, ancestorSkipped, filterSkipped); |
| - if (!o || !o->isLayoutBlock()) |
| + if (!object || !object->isLayoutBlock()) |
| return nullptr; // This can still happen in case of an orphaned tree |
| - return toLayoutBlock(o); |
| + return toLayoutBlock(object); |
| } |
| -LayoutBlock* LayoutObject::containingBlock() const { |
| - LayoutObject* o = parent(); |
| - if (!o && isLayoutScrollbarPart()) |
| - o = toLayoutScrollbarPart(this)->layoutObjectOwningScrollbar(); |
| +LayoutBlock* LayoutObject::containingBlock(const LayoutBoxModelObject* ancestor, |
| + bool* ancestorSkipped, |
| + bool* filterSkipped) const { |
| + LayoutObject* object = parent(); |
| + if (!object && isLayoutScrollbarPart()) |
| + object = toLayoutScrollbarPart(this)->layoutObjectOwningScrollbar(); |
| if (!isTextOrSVGChild()) { |
| - if (m_style->position() == FixedPosition) |
| - return containerForFixedPosition(); |
| - if (m_style->position() == AbsolutePosition) |
| - return containingBlockForAbsolutePosition(); |
| + if (m_style->position() == FixedPosition) { |
| + return containerForFixedPosition(ancestor, ancestorSkipped, |
| + filterSkipped); |
| + } |
| + if (m_style->position() == AbsolutePosition) { |
| + return containingBlockForAbsolutePosition(ancestor, ancestorSkipped, |
| + filterSkipped); |
| + } |
| } |
| if (isColumnSpanAll()) { |
| - o = spannerPlaceholder()->containingBlock(); |
| + object = spannerPlaceholder()->containingBlock(); |
| } else { |
| - while (o && ((o->isInline() && !o->isAtomicInlineLevel()) || |
| - !o->isLayoutBlock())) |
| - o = o->parent(); |
| + while (object && ((object->isInline() && !object->isAtomicInlineLevel()) || |
| + !object->isLayoutBlock())) { |
| + if (ancestorSkipped && object == ancestor) |
| + *ancestorSkipped = true; |
| + |
| + if (filterSkipped && object->hasFilterInducingProperty()) |
| + *filterSkipped = true; |
| + object = object->parent(); |
| + } |
| } |
| - if (!o || !o->isLayoutBlock()) |
| + if (!object || !object->isLayoutBlock()) |
| return nullptr; // This can still happen in case of an orphaned tree |
| - return toLayoutBlock(o); |
| + return toLayoutBlock(object); |
| } |
| FloatRect LayoutObject::absoluteBoundingBoxFloatRect() const { |
| @@ -1024,7 +1044,7 @@ void LayoutObject::paint(const PaintInfo&, const LayoutPoint&) const {} |
| const LayoutBoxModelObject& LayoutObject::containerForPaintInvalidation() |
| const { |
| - RELEASE_ASSERT(isRooted()); |
| + CHECK(isRooted()); |
| if (const LayoutBoxModelObject* paintInvalidationContainer = |
| enclosingCompositedContainer()) |
| @@ -1033,12 +1053,11 @@ const LayoutBoxModelObject& LayoutObject::containerForPaintInvalidation() |
| // If the current frame is not composited, we send just return the main |
| // frame's LayoutView so that we generate invalidations on the window. |
| const LayoutView* layoutView = view(); |
| - while ( |
| - LayoutAPIShim::layoutObjectFrom(layoutView->frame()->ownerLayoutItem())) |
| - layoutView = |
| - LayoutAPIShim::layoutObjectFrom(layoutView->frame()->ownerLayoutItem()) |
| - ->view(); |
| - ASSERT(layoutView); |
| + while (const LayoutObject* ownerObject = LayoutAPIShim::constLayoutObjectFrom( |
| + layoutView->frame()->ownerLayoutItem())) |
| + layoutView = ownerObject->view(); |
| + |
| + DCHECK(layoutView); |
| return *layoutView; |
| } |
| @@ -2522,6 +2541,9 @@ LayoutObject* LayoutObject::container(const LayoutBoxModelObject* ancestor, |
| return multicolContainer; |
| } |
| + if (isFloating()) |
|
chrishtr
2016/12/16 18:50:20
I'm concerned about side-effects of modifying cont
Xianzhu
2016/12/16 19:08:49
Paint invalidation of float-under-inline was broke
wkorman
2016/12/16 19:40:31
Are there any ramifications to using containingBlo
Xianzhu
2016/12/16 20:06:42
According to https://www.w3.org/TR/CSS2/visuren.ht
wkorman
2016/12/16 21:50:40
I was thinking the same as the tests you've alread
|
| + return containingBlock(ancestor, ancestorSkipped, filterSkipped); |
| + |
| return o; |
| } |