| Index: Source/core/layout/LayoutBlock.cpp
|
| diff --git a/Source/core/layout/LayoutBlock.cpp b/Source/core/layout/LayoutBlock.cpp
|
| index d1a61fd3345cb31e0d994a61f1afe1da5ef30bfa..fa932f399a3c6d203678879da1e655ede2136269 100644
|
| --- a/Source/core/layout/LayoutBlock.cpp
|
| +++ b/Source/core/layout/LayoutBlock.cpp
|
| @@ -1681,6 +1681,22 @@ LayoutUnit LayoutBlock::marginIntrinsicLogicalWidthForChild(LayoutBox& child) co
|
| return margin;
|
| }
|
|
|
| +static bool needsLayoutDueToStaticPosition(LayoutObject* child)
|
| +{
|
| + // When a non-positioned block element moves, it may have positioned children that are implicitly positioned relative to the
|
| + // non-positioned block. In block flow we can detect these when we layout the non-positioned block (by noticing the change
|
| + // in the immediate parent's logical top in |adjustPositionedBlock|). In line layout we always need to mark the positioned
|
| + // child for layout if its statically positioned in the direction in which the object lays out.
|
| + // crbug.com/490322(rhogan): We probably need to move the block layout case in here too, as marking a positioned object for
|
| + // layout while laying out an object's children invalidly assumes that our positionedObjects list is in DOM order and that
|
| + // we could never mark a positioned object for layout *after* we've laid it out in layoutPositionedObjects.
|
| + if (!child->parent()->childrenInline())
|
| + return false;
|
| + const ComputedStyle* style = child->style();
|
| + bool isHorizontal = style->isHorizontalWritingMode();
|
| + return style->isDisplayInlineType() ? style->hasStaticInlinePosition(isHorizontal) : style->hasStaticBlockPosition(isHorizontal);
|
| +}
|
| +
|
| void LayoutBlock::layoutPositionedObjects(bool relayoutChildren, PositionedLayoutBehavior info)
|
| {
|
| TrackedLayoutBoxListHashSet* positionedDescendants = positionedObjects();
|
| @@ -1703,11 +1719,7 @@ void LayoutBlock::layoutPositionedObjects(bool relayoutChildren, PositionedLayou
|
| continue;
|
| }
|
|
|
| - // When a non-positioned block element moves, it may have positioned children that are implicitly positioned relative to the
|
| - // non-positioned block. Rather than trying to detect all of these movement cases, we just always lay out positioned
|
| - // objects that are positioned implicitly like this. Such objects are rare, and so in typical DHTML menu usage (where everything is
|
| - // positioned explicitly) this should not incur a performance penalty.
|
| - if (relayoutChildren || (positionedObject->style()->hasStaticBlockPosition(isHorizontalWritingMode()) && positionedObject->parent() != this))
|
| + if (relayoutChildren || needsLayoutDueToStaticPosition(positionedObject))
|
| layoutScope.setChildNeedsLayout(positionedObject);
|
|
|
| // If relayoutChildren is set and the child has percentage padding or an embedded content box, we also need to invalidate the childs pref widths.
|
|
|