| Index: third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
|
| diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
|
| index 5a627a037a844570a70db6d54df4fbe64439033e..3e8e63a2ce6fdaf4f8cb42b2f5e5dce0e79a1a75 100644
|
| --- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
|
| +++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
|
| @@ -658,6 +658,45 @@ void PaintPropertyTreeBuilder::updateOutOfFlowContext(
|
| properties->clearCssClipFixedPosition();
|
| }
|
|
|
| +// Override ContainerContext based on the properties of a container that was
|
| +// previously walked in a subtree other than the current subtree being walked.
|
| +// Used for out-of-flow positioned descendants of multi-column spanner when
|
| +// the container is not in the normal tree walk order.
|
| +// For example:
|
| +// <div id="columns" style="columns: 2">
|
| +// <div id="relative" style="position: relative">
|
| +// <div id="spanner" style="column-span: all">
|
| +// <div id="absolute" style="position: absolute"></div>
|
| +// </div>
|
| +// </div>
|
| +// <div>
|
| +// The real container of "absolute" is "relative" which is not in the tree-walk
|
| +// order of "columns" -> spanner placeholder -> spanner -> absolute. Here we
|
| +// rebuild a ContainerContext based on the properties of "relative" for
|
| +// "absolute".
|
| +static void overrideContainerContextFromContainer(
|
| + const LayoutObject& container,
|
| + PaintPropertyTreeBuilderContext::ContainerContext& context) {
|
| + // The container is never a LayoutInline. In the above example, if we change
|
| + // the container to an inline, there must be an anonymous blocks created
|
| + // because the spanner is always a block.
|
| + DCHECK(container.isLayoutBlock());
|
| +
|
| + const auto* properties =
|
| + container.objectPaintProperties()->localBorderBoxProperties();
|
| + DCHECK(properties);
|
| +
|
| + context.transform = properties->propertyTreeState.transform();
|
| + context.paintOffset = properties->paintOffset;
|
| + context.shouldFlattenInheritedTransform =
|
| + context.transform && context.transform->flattensInheritedTransform();
|
| + context.renderingContextID =
|
| + context.transform ? context.transform->renderingContextID() : 0;
|
| + context.clip = properties->propertyTreeState.clip();
|
| + context.scroll = const_cast<ScrollPaintPropertyNode*>(
|
| + properties->propertyTreeState.scroll());
|
| +}
|
| +
|
| static void deriveBorderBoxFromContainerContext(
|
| const LayoutObject& object,
|
| PaintPropertyTreeBuilderContext& context) {
|
| @@ -673,9 +712,23 @@ static void deriveBorderBoxFromContainerContext(
|
| context.current.paintOffset += boxModelObject.offsetForInFlowPosition();
|
| break;
|
| case AbsolutePosition: {
|
| - context.current = context.absolutePosition;
|
| + if (context.isUnderMultiColumnSpanner) {
|
| + const LayoutObject* container = boxModelObject.container();
|
| + if (container != context.containerForAbsolutePosition) {
|
| + // The container of the absolute-position is not in the normal tree-
|
| + // walk order.
|
| + context.containerForAbsolutePosition =
|
| + toLayoutBoxModelObject(container);
|
| + overrideContainerContextFromContainer(*container, context.current);
|
| + }
|
| + } else {
|
| + DCHECK(context.containerForAbsolutePosition ==
|
| + boxModelObject.container());
|
| + context.current = context.absolutePosition;
|
| + }
|
|
|
| - // Absolutely positioned content in an inline should be positioned relative to the inline.
|
| + // Absolutely positioned content in an inline should be positioned
|
| + // relative to the inline.
|
| const LayoutObject* container = context.containerForAbsolutePosition;
|
| if (container && container->isInFlowPositioned() &&
|
| container->isLayoutInline()) {
|
| @@ -690,7 +743,14 @@ static void deriveBorderBoxFromContainerContext(
|
| context.current.paintOffset += boxModelObject.offsetForInFlowPosition();
|
| break;
|
| case FixedPosition:
|
| - context.current = context.fixedPosition;
|
| + if (context.isUnderMultiColumnSpanner) {
|
| + // The container of the fixed-position object may or may not be in the
|
| + // normal tree-walk order.
|
| + overrideContainerContextFromContainer(*boxModelObject.container(),
|
| + context.current);
|
| + } else {
|
| + context.current = context.fixedPosition;
|
| + }
|
| break;
|
| default:
|
| ASSERT_NOT_REACHED();
|
|
|