summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-as-formatting-context-expected.txt1
-rw-r--r--third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-as-formatting-context.html24
-rw-r--r--third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-with-absolute-position-expected.html10
-rw-r--r--third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-with-absolute-position.html23
-rw-r--r--third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-with-box-shadow-expected.html10
-rw-r--r--third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-with-box-shadow.html16
-rw-r--r--third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-with-fixed-position-expected.html10
-rw-r--r--third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-with-fixed-position.html23
-rw-r--r--third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-with-transformed-descendant-expected.html10
-rw-r--r--third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-with-transformed-descendant.html22
-rw-r--r--third_party/WebKit/LayoutTests/hittesting/paint-containment-hittest-expected.txt12
-rw-r--r--third_party/WebKit/LayoutTests/hittesting/paint-containment-hittest.html63
-rw-r--r--third_party/WebKit/Source/core/core.gypi1
-rw-r--r--third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp2
-rw-r--r--third_party/WebKit/Source/core/css/resolver/StyleAdjuster.cpp3
-rw-r--r--third_party/WebKit/Source/core/layout/LayoutBlock.cpp2
-rw-r--r--third_party/WebKit/Source/core/layout/LayoutBox.cpp2
-rw-r--r--third_party/WebKit/Source/core/layout/LayoutInline.cpp6
-rw-r--r--third_party/WebKit/Source/core/layout/LayoutInline.h2
-rw-r--r--third_party/WebKit/Source/core/layout/LayoutObject.h4
-rw-r--r--third_party/WebKit/Source/core/layout/PaintContainmentTest.cpp55
-rw-r--r--third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp2
-rw-r--r--third_party/WebKit/Source/core/layout/compositing/CompositingInputsUpdater.cpp16
-rw-r--r--third_party/WebKit/Source/core/layout/compositing/CompositingInputsUpdater.h4
-rw-r--r--third_party/WebKit/Source/core/layout/compositing/CompositingRequirementsUpdater.cpp2
-rw-r--r--third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.cpp2
-rw-r--r--third_party/WebKit/Source/core/paint/BoxClipper.cpp7
-rw-r--r--third_party/WebKit/Source/core/paint/PaintLayer.cpp31
-rw-r--r--third_party/WebKit/Source/core/paint/PaintLayer.h16
-rw-r--r--third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp12
-rw-r--r--third_party/WebKit/Source/core/style/ComputedStyle.h1
31 files changed, 343 insertions, 51 deletions
diff --git a/third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-as-formatting-context-expected.txt b/third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-as-formatting-context-expected.txt
new file mode 100644
index 0000000..7ef22e9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-as-formatting-context-expected.txt
@@ -0,0 +1 @@
+PASS
diff --git a/third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-as-formatting-context.html b/third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-as-formatting-context.html
new file mode 100644
index 0000000..128a79b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-as-formatting-context.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<style>
+div {
+ height: 100px;
+ width: 100%;
+}
+.container {
+ contain: paint;
+ border: 1px solid black;
+}
+.overhangingContainer {
+ height: 10px;
+}
+.overhangingFloat {
+ float: left;
+}
+</style>
+<body>
+<div class="overhangingContainer"><div class="overhangingFloat"></div></div>
+<div class="container" data-offset-y=108></div>
+<script src="../../../resources/check-layout.js"></script>
+<script>
+checkLayout(".container");
+</script> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-with-absolute-position-expected.html b/third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-with-absolute-position-expected.html
new file mode 100644
index 0000000..b880446
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-with-absolute-position-expected.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<style>
+div {
+ width: 100px;
+ height: 100px;
+ background-color: green;
+}
+</style>
+<body>
+<div></div> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-with-absolute-position.html b/third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-with-absolute-position.html
new file mode 100644
index 0000000..bac8d56
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-with-absolute-position.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<style>
+div {
+ width: 100px;
+ height: 50px;
+}
+.container {
+ contain: paint;
+ background-color: green;
+}
+.absolute {
+ position: absolute;
+ top: 0px;
+ left: 100px;
+ background-color: red;
+}
+.inline {
+ display: inline-block;
+}
+</style>
+<body>
+<div class="container"><div class="absolute"></div></div>
+<div class="container inline"><div class="absolute"></div></div> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-with-box-shadow-expected.html b/third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-with-box-shadow-expected.html
new file mode 100644
index 0000000..b880446
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-with-box-shadow-expected.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<style>
+div {
+ width: 100px;
+ height: 100px;
+ background-color: green;
+}
+</style>
+<body>
+<div></div> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-with-box-shadow.html b/third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-with-box-shadow.html
new file mode 100644
index 0000000..ffa0f31
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-with-box-shadow.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<style>
+div {
+ width: 100px;
+ height: 100px;
+}
+#container {
+ contain: paint;
+}
+#child {
+ background-color: green;
+ -webkit-box-shadow: 0 0 100px 100px red;
+}
+</style>
+<body>
+<div id="container"><div id="child"></div></div> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-with-fixed-position-expected.html b/third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-with-fixed-position-expected.html
new file mode 100644
index 0000000..b880446
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-with-fixed-position-expected.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<style>
+div {
+ width: 100px;
+ height: 100px;
+ background-color: green;
+}
+</style>
+<body>
+<div></div> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-with-fixed-position.html b/third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-with-fixed-position.html
new file mode 100644
index 0000000..f028d8c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-with-fixed-position.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<style>
+div {
+ width: 100px;
+ height: 50px;
+}
+.container {
+ contain: paint;
+ background-color: green;
+}
+.fixed {
+ position: fixed;
+ top: 0px;
+ left: 100px;
+ background-color: red;
+}
+.inline {
+ display: inline-block;
+}
+</style>
+<body>
+<div class="container"><div class="fixed"></div></div>
+<div class="container inline"><div class="fixed"></div></div> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-with-transformed-descendant-expected.html b/third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-with-transformed-descendant-expected.html
new file mode 100644
index 0000000..b880446
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-with-transformed-descendant-expected.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<style>
+div {
+ width: 100px;
+ height: 100px;
+ background-color: green;
+}
+</style>
+<body>
+<div></div> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-with-transformed-descendant.html b/third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-with-transformed-descendant.html
new file mode 100644
index 0000000..d11d1821
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/css/containment/paint-containment-with-transformed-descendant.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<style>
+div {
+ width: 100px;
+ height: 50px;
+}
+.container {
+ contain: paint;
+ background-color: green;
+}
+.transform {
+ background-color: red;
+ top: 100px;
+ transform: translateZ(0) scaleY(2) translateX(100px);
+}
+.inline {
+ display: inline-block;
+}
+</style>
+<body>
+<div class="container"><div class="transform"></div></div>
+<div class="container inline"><div class="transform"></div></div> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/hittesting/paint-containment-hittest-expected.txt b/third_party/WebKit/LayoutTests/hittesting/paint-containment-hittest-expected.txt
new file mode 100644
index 0000000..7282117
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/hittesting/paint-containment-hittest-expected.txt
@@ -0,0 +1,12 @@
+Hit testing should respect clips established by contain: paint.
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+PASS document.elementFromPoint(centerX, centerY).id is 'containTransform'
+PASS document.elementFromPoint(centerX, centerY).id is 'containAbsolute'
+PASS document.elementFromPoint(centerX, centerY).id is 'containFixed'
+PASS document.elementFromPoint(centerX, centerY).id is 'body'
+PASS document.elementFromPoint(centerX, centerY).id is 'body'
+PASS document.elementFromPoint(centerX, centerY).id is 'body'
+
diff --git a/third_party/WebKit/LayoutTests/hittesting/paint-containment-hittest.html b/third_party/WebKit/LayoutTests/hittesting/paint-containment-hittest.html
new file mode 100644
index 0000000..24f7bd1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/hittesting/paint-containment-hittest.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<script src="../resources/js-test.js"></script>
+<script>
+var centerX;
+var centerY;
+function hitTestCenterOfElement(elementID, expectedID)
+{
+ var element = document.getElementById(elementID);
+ var rect = element.getBoundingClientRect();
+ centerX = rect.left + (rect.width / 2);
+ centerY = rect.top + (rect.height / 2);
+ shouldBe("document.elementFromPoint(centerX, centerY).id", "'" + expectedID + "'");
+}
+
+function test() {
+ hitTestCenterOfElement("containTransform", "containTransform");
+ hitTestCenterOfElement("containAbsolute", "containAbsolute");
+ hitTestCenterOfElement("containFixed", "containFixed");
+
+ hitTestCenterOfElement("transform", "body");
+ hitTestCenterOfElement("absolute", "body");
+ hitTestCenterOfElement("fixed", "body");
+}
+</script>
+<style>
+div {
+ width: 100px;
+ height: 100px;
+ background-color: green;
+}
+div > div {
+ background-color: red;
+}
+.paintContainment {
+ contain: paint;
+ margin: 10px;
+}
+#transform {
+ transform: translateZ(0) translateX(100px);
+}
+#absolute {
+ position: absolute;
+ top: 0px;
+ left: 100px;
+}
+#fixed {
+ position: fixed;
+ top: 0px;
+ left: 100px;
+}
+</style>
+<body onload="test()" id="body">
+ <p>Hit testing should respect clips established by contain: paint.</p>
+<div id="containTransform" class="paintContainment">
+ <div id="transform"></div>
+</div>
+<div id="containAbsolute" class="paintContainment">
+ <div id="absolute"></div>
+</div>
+<div id="containFixed" class="paintContainment">
+ <div id="fixed"></div>
+</div>
+<pre id="console"></pre>
diff --git a/third_party/WebKit/Source/core/core.gypi b/third_party/WebKit/Source/core/core.gypi
index a9098c0..f623675e 100644
--- a/third_party/WebKit/Source/core/core.gypi
+++ b/third_party/WebKit/Source/core/core.gypi
@@ -3930,6 +3930,7 @@
'layout/MultiColumnFragmentainerGroupTest.cpp',
'layout/OverflowModelTest.cpp',
'layout/PaginationTest.cpp',
+ 'layout/PaintContainmentTest.cpp',
'layout/compositing/CompositedLayerMappingTest.cpp',
'layout/shapes/BoxShapeTest.cpp',
'loader/FrameFetchContextTest.cpp',
diff --git a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
index a3ca171..4f41f9a 100644
--- a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
+++ b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
@@ -2711,7 +2711,7 @@ PassRefPtrWillBeRawPtr<CSSValue> ComputedStyleCSSValueMapping::get(CSSPropertyID
list->append(cssValuePool().createIdentifierValue(CSSValueStyle));
if (style.contain() & ContainsLayout)
list->append(cssValuePool().createIdentifierValue(CSSValueLayout));
- if (style.contain() & ContainsPaint)
+ if (style.containsPaint())
list->append(cssValuePool().createIdentifierValue(CSSValuePaint));
ASSERT(list->length());
return list.release();
diff --git a/third_party/WebKit/Source/core/css/resolver/StyleAdjuster.cpp b/third_party/WebKit/Source/core/css/resolver/StyleAdjuster.cpp
index 9d584a4..e129549 100644
--- a/third_party/WebKit/Source/core/css/resolver/StyleAdjuster.cpp
+++ b/third_party/WebKit/Source/core/css/resolver/StyleAdjuster.cpp
@@ -203,7 +203,8 @@ void StyleAdjuster::adjustComputedStyle(ComputedStyle& style, const ComputedStyl
|| style.hasIsolation()
|| style.position() == FixedPosition
|| isInTopLayer(element, style)
- || hasWillChangeThatCreatesStackingContext(style)))
+ || hasWillChangeThatCreatesStackingContext(style)
+ || style.containsPaint()))
style.setZIndex(0);
if (doesNotInheritTextDecoration(style, element))
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlock.cpp b/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
index 3e18330..ecc2c5f 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
@@ -1007,7 +1007,7 @@ bool LayoutBlock::createsNewFormattingContext() const
{
return isInlineBlockOrInlineTable() || isFloatingOrOutOfFlowPositioned() || hasOverflowClip() || isFlexItemIncludingDeprecated()
|| style()->specifiesColumns() || isLayoutFlowThread() || isTableCell() || isTableCaption() || isFieldset() || isWritingModeRoot()
- || isDocumentElement() || isColumnSpanAll() || isGridItem();
+ || isDocumentElement() || isColumnSpanAll() || isGridItem() || style()->containsPaint();
}
void LayoutBlock::updateBlockChildDirtyBitsBeforeLayout(bool relayoutChildren, LayoutBox& child)
diff --git a/third_party/WebKit/Source/core/layout/LayoutBox.cpp b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
index 31f903a..f8986d1 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBox.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
@@ -4058,7 +4058,7 @@ static bool shouldBeConsideredAsReplaced(Node* node)
bool LayoutBox::avoidsFloats() const
{
- return isAtomicInlineLevel() || shouldBeConsideredAsReplaced(node()) || hasOverflowClip() || isHR() || isLegend() || isWritingModeRoot() || isFlexItemIncludingDeprecated();
+ return isAtomicInlineLevel() || shouldBeConsideredAsReplaced(node()) || hasOverflowClip() || isHR() || isLegend() || isWritingModeRoot() || isFlexItemIncludingDeprecated() || style()->containsPaint();
}
bool LayoutBox::hasNonCompositedScrollbars() const
diff --git a/third_party/WebKit/Source/core/layout/LayoutInline.cpp b/third_party/WebKit/Source/core/layout/LayoutInline.cpp
index 4fe1686..38409e2 100644
--- a/third_party/WebKit/Source/core/layout/LayoutInline.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutInline.cpp
@@ -1142,6 +1142,12 @@ LayoutSize LayoutInline::offsetFromContainer(const LayoutObject* container, cons
return offset;
}
+PaintLayerType LayoutInline::layerTypeRequired() const
+{
+ return isInFlowPositioned() || createsGroup() || hasClipPath() || style()->shouldCompositeForCurrentAnimations()
+ || style()->hasCompositorProxy() || style()->containsPaint() ? NormalPaintLayer : NoPaintLayer;
+}
+
void LayoutInline::mapLocalToContainer(const LayoutBoxModelObject* paintInvalidationContainer, TransformState& transformState, MapCoordinatesFlags mode, bool* wasFixed, const PaintInvalidationState* paintInvalidationState) const
{
if (paintInvalidationContainer == this)
diff --git a/third_party/WebKit/Source/core/layout/LayoutInline.h b/third_party/WebKit/Source/core/layout/LayoutInline.h
index 2987d26..354505c 100644
--- a/third_party/WebKit/Source/core/layout/LayoutInline.h
+++ b/third_party/WebKit/Source/core/layout/LayoutInline.h
@@ -228,7 +228,7 @@ private:
bool nodeAtPoint(HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) final;
- PaintLayerType layerTypeRequired() const override { return isInFlowPositioned() || createsGroup() || hasClipPath() || style()->shouldCompositeForCurrentAnimations() || style()->hasCompositorProxy() ? NormalPaintLayer : NoPaintLayer; }
+ PaintLayerType layerTypeRequired() const override;
LayoutUnit offsetLeft() const final;
LayoutUnit offsetTop() const final;
diff --git a/third_party/WebKit/Source/core/layout/LayoutObject.h b/third_party/WebKit/Source/core/layout/LayoutObject.h
index a45e243..9dc0b50 100644
--- a/third_party/WebKit/Source/core/layout/LayoutObject.h
+++ b/third_party/WebKit/Source/core/layout/LayoutObject.h
@@ -698,7 +698,7 @@ public:
bool hasClip() const { return isOutOfFlowPositioned() && !style()->hasAutoClip(); }
bool hasOverflowClip() const { return m_bitfields.hasOverflowClip(); }
- bool hasClipOrOverflowClip() const { return hasClip() || hasOverflowClip(); }
+ bool hasClipRelatedProperty() const { return hasClip() || hasOverflowClip() || style()->containsPaint(); }
bool hasTransformRelatedProperty() const { return m_bitfields.hasTransformRelatedProperty(); }
bool hasMask() const { return style() && style()->hasMask(); }
@@ -930,7 +930,7 @@ public:
bool canContainFixedPositionObjects() const
{
- return isLayoutView() || (hasTransformRelatedProperty() && isLayoutBlock()) || isSVGForeignObject();
+ return isLayoutView() || (hasTransformRelatedProperty() && isLayoutBlock()) || isSVGForeignObject() || style()->containsPaint();
}
// Convert the given local point to absolute coordinates
diff --git a/third_party/WebKit/Source/core/layout/PaintContainmentTest.cpp b/third_party/WebKit/Source/core/layout/PaintContainmentTest.cpp
new file mode 100644
index 0000000..36547ba
--- /dev/null
+++ b/third_party/WebKit/Source/core/layout/PaintContainmentTest.cpp
@@ -0,0 +1,55 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+
+#include "core/layout/LayoutBlock.h"
+#include "core/layout/LayoutInline.h"
+#include "core/layout/LayoutTestHelper.h"
+#include "core/paint/PaintLayer.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace blink {
+
+class PaintContainmentTest : public RenderingTest {
+};
+
+static void checkIsClippingStackingContextAndContainer(LayoutBoxModelObject& obj)
+{
+ EXPECT_TRUE(obj.canContainFixedPositionObjects());
+ EXPECT_TRUE(obj.hasClipRelatedProperty());
+ EXPECT_TRUE(obj.style()->containsPaint());
+
+ // TODO(leviw): Ideally, we wouldn't require a paint layer to handle the clipping
+ // and stacking performed by paint containment.
+ ASSERT(obj.layer());
+ PaintLayer* layer = obj.layer();
+ EXPECT_TRUE(layer->stackingNode() && layer->stackingNode()->isStackingContext());
+}
+
+TEST_F(PaintContainmentTest, BlockPaintContainment)
+{
+ setBodyInnerHTML("<div id='div' style='contain: paint'></div>");
+ Element* div = document().getElementById(AtomicString("div"));
+ ASSERT(div);
+ LayoutObject* obj = div->layoutObject();
+ ASSERT(obj && obj->isLayoutBlock());
+ LayoutBlock& block = toLayoutBlock(*obj);
+ EXPECT_TRUE(block.createsNewFormattingContext());
+ EXPECT_FALSE(block.canBeScrolledAndHasScrollableArea());
+ checkIsClippingStackingContextAndContainer(block);
+}
+
+TEST_F(PaintContainmentTest, InlinePaintContainment)
+{
+ setBodyInnerHTML("<div><span id='test' style='contain: paint'>Foo</span></div>");
+ Element* span = document().getElementById(AtomicString("test"));
+ ASSERT(span);
+ LayoutObject* obj = span->layoutObject();
+ ASSERT(obj && obj->isInline());
+ LayoutInline& layoutInline = toLayoutInline(*obj);
+ checkIsClippingStackingContextAndContainer(layoutInline);
+}
+
+}
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
index 485f65d7..5467894 100644
--- a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
+++ b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
@@ -568,7 +568,7 @@ bool CompositedLayerMapping::updateGraphicsLayerConfiguration()
static IntRect clipBox(LayoutBox* layoutObject)
{
LayoutRect result = LayoutRect(LayoutRect::infiniteIntRect());
- if (layoutObject->hasOverflowClip())
+ if (layoutObject->hasOverflowClip() || layoutObject->style()->containsPaint())
result = layoutObject->overflowClipRect(LayoutPoint());
if (layoutObject->hasClip())
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositingInputsUpdater.cpp b/third_party/WebKit/Source/core/layout/compositing/CompositingInputsUpdater.cpp
index 851df37..3ce313b 100644
--- a/third_party/WebKit/Source/core/layout/compositing/CompositingInputsUpdater.cpp
+++ b/third_party/WebKit/Source/core/layout/compositing/CompositingInputsUpdater.cpp
@@ -37,7 +37,7 @@ static const PaintLayer* findParentLayerOnClippingContainerChain(const PaintLaye
for (current = current->parent(); current && !current->canContainFixedPositionObjects(); current = current->parent()) {
// All types of clips apply to fixed-position descendants of other fixed-position elements.
// Note: it's unclear whether this is what the spec says. Firefox does not clip, but Chrome does.
- if (current->style()->position() == FixedPosition && current->hasClipOrOverflowClip()) {
+ if (current->style()->position() == FixedPosition && current->hasClipRelatedProperty()) {
ASSERT(current->hasLayer());
return static_cast<const LayoutBoxModelObject*>(current)->layer();
}
@@ -56,7 +56,7 @@ static const PaintLayer* findParentLayerOnClippingContainerChain(const PaintLaye
if (current->hasLayer())
return static_cast<const LayoutBoxModelObject*>(current)->layer();
// Having clip or overflow clip forces the LayoutObject to become a layer.
- ASSERT(!current->hasClipOrOverflowClip());
+ ASSERT(!current->hasClipRelatedProperty());
}
ASSERT_NOT_REACHED();
return nullptr;
@@ -82,7 +82,7 @@ static bool hasClippedStackingAncestor(const PaintLayer* layer, const PaintLayer
if (current == clippingLayer)
return foundInterveningClip;
- if (current->layoutObject()->hasClipOrOverflowClip() && !clippingLayoutObject->isDescendantOf(current->layoutObject()))
+ if (current->layoutObject()->hasClipRelatedProperty() && !clippingLayoutObject->isDescendantOf(current->layoutObject()))
foundInterveningClip = true;
if (const LayoutObject* container = current->clippingContainer()) {
@@ -130,10 +130,10 @@ void CompositingInputsUpdater::updateRecursive(PaintLayer* layer, UpdateType upd
bool layerIsFixedPosition = layer->layoutObject()->style()->position() == FixedPosition;
properties.nearestFixedPositionLayer = layerIsFixedPosition ? layer : parent->nearestFixedPositionLayer();
- if (info.hasAncestorWithClipOrOverflowClip) {
+ if (info.hasAncestorWithClipRelatedProperty) {
const PaintLayer* parentLayerOnClippingContainerChain = findParentLayerOnClippingContainerChain(layer);
- const bool parentHasClipOrOverflowClip = parentLayerOnClippingContainerChain->layoutObject()->hasClipOrOverflowClip();
- properties.clippingContainer = parentHasClipOrOverflowClip ? parentLayerOnClippingContainerChain->layoutObject() : parentLayerOnClippingContainerChain->clippingContainer();
+ const bool parentHasClipRelatedProperty = parentLayerOnClippingContainerChain->layoutObject()->hasClipRelatedProperty();
+ properties.clippingContainer = parentHasClipRelatedProperty ? parentLayerOnClippingContainerChain->layoutObject() : parentLayerOnClippingContainerChain->clippingContainer();
}
if (info.lastScrollingAncestor) {
@@ -167,8 +167,8 @@ void CompositingInputsUpdater::updateRecursive(PaintLayer* layer, UpdateType upd
if (layer->scrollsOverflow())
info.lastScrollingAncestor = layer;
- if (layer->layoutObject()->hasClipOrOverflowClip())
- info.hasAncestorWithClipOrOverflowClip = true;
+ if (layer->layoutObject()->hasClipRelatedProperty())
+ info.hasAncestorWithClipRelatedProperty = true;
if (layer->layoutObject()->hasClipPath())
info.hasAncestorWithClipPath = true;
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositingInputsUpdater.h b/third_party/WebKit/Source/core/layout/compositing/CompositingInputsUpdater.h
index 0c646a4..d182c926 100644
--- a/third_party/WebKit/Source/core/layout/compositing/CompositingInputsUpdater.h
+++ b/third_party/WebKit/Source/core/layout/compositing/CompositingInputsUpdater.h
@@ -35,7 +35,7 @@ private:
: ancestorStackingContext(nullptr)
, enclosingCompositedLayer(nullptr)
, lastScrollingAncestor(nullptr)
- , hasAncestorWithClipOrOverflowClip(false)
+ , hasAncestorWithClipRelatedProperty(false)
, hasAncestorWithClipPath(false)
{
}
@@ -48,7 +48,7 @@ private:
// actually controls the scrolling of this layer, which we find on the
// containing block chain.
PaintLayer* lastScrollingAncestor;
- bool hasAncestorWithClipOrOverflowClip;
+ bool hasAncestorWithClipRelatedProperty;
bool hasAncestorWithClipPath;
};
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositingRequirementsUpdater.cpp b/third_party/WebKit/Source/core/layout/compositing/CompositingRequirementsUpdater.cpp
index a58e642..69d03b0 100644
--- a/third_party/WebKit/Source/core/layout/compositing/CompositingRequirementsUpdater.cpp
+++ b/third_party/WebKit/Source/core/layout/compositing/CompositingRequirementsUpdater.cpp
@@ -166,7 +166,7 @@ static CompositingReasons subtreeReasonsForCompositing(PaintLayer* layer, bool h
// FIXME: This should move into CompositingReasonFinder::potentialCompositingReasonsFromStyle, but
// theres a poor interaction with LayoutTextControlSingleLine, which sets this hasOverflowClip directly.
- if (layer->layoutObject()->hasClipOrOverflowClip())
+ if (layer->layoutObject()->hasClipRelatedProperty())
subtreeReasons |= CompositingReasonClipsCompositingDescendants;
if (layer->layoutObject()->style()->position() == FixedPosition)
diff --git a/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.cpp b/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.cpp
index 969d1ef6..4146ce8 100644
--- a/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.cpp
+++ b/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.cpp
@@ -777,7 +777,7 @@ bool PaintLayerCompositor::canBeComposited(const PaintLayer* layer) const
// into the hierarchy between this layer and its children in the z-order hierarchy.
bool PaintLayerCompositor::clipsCompositingDescendants(const PaintLayer* layer) const
{
- return layer->hasCompositingDescendant() && layer->layoutObject()->hasClipOrOverflowClip();
+ return layer->hasCompositingDescendant() && layer->layoutObject()->hasClipRelatedProperty();
}
// If an element has composited negative z-index children, those children paint in front of the
diff --git a/third_party/WebKit/Source/core/paint/BoxClipper.cpp b/third_party/WebKit/Source/core/paint/BoxClipper.cpp
index ac13973..09f10cf 100644
--- a/third_party/WebKit/Source/core/paint/BoxClipper.cpp
+++ b/third_party/WebKit/Source/core/paint/BoxClipper.cpp
@@ -24,9 +24,10 @@ BoxClipper::BoxClipper(const LayoutBox& box, const PaintInfo& paintInfo, const L
return;
bool isControlClip = m_box.hasControlClip();
- bool isOverflowClip = m_box.hasOverflowClip() && !m_box.layer()->isSelfPaintingLayer();
+ bool isOverflowOrContainmentClip = (m_box.hasOverflowClip() && !m_box.layer()->isSelfPaintingLayer())
+ || m_box.style()->containsPaint();
- if (!isControlClip && !isOverflowClip)
+ if (!isControlClip && !isOverflowOrContainmentClip)
return;
LayoutRect clipRect = isControlClip ? m_box.controlClipRect(accumulatedOffset) : m_box.overflowClipRect(accumulatedOffset);
@@ -64,7 +65,7 @@ BoxClipper::~BoxClipper()
if (m_clipType == DisplayItem::UninitializedType)
return;
- ASSERT(m_box.hasControlClip() || (m_box.hasOverflowClip() && !m_box.layer()->isSelfPaintingLayer()));
+ ASSERT(m_box.hasControlClip() || (m_box.hasOverflowClip() && !m_box.layer()->isSelfPaintingLayer()) || m_box.style()->containsPaint());
m_paintInfo.context.paintController().endItem<EndClipDisplayItem>(m_box, DisplayItem::clipTypeToEndClipType(m_clipType));
}
diff --git a/third_party/WebKit/Source/core/paint/PaintLayer.cpp b/third_party/WebKit/Source/core/paint/PaintLayer.cpp
index a764e09..e28864f 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayer.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayer.cpp
@@ -752,15 +752,15 @@ bool PaintLayer::updateLayerPosition()
}
// Subtract our parent's scroll offset.
- if (PaintLayer* positionedParent = layoutObject()->isOutOfFlowPositioned() ? enclosingPositionedAncestor() : nullptr) {
+ if (PaintLayer* containingLayer = layoutObject()->isOutOfFlowPositioned() ? containingLayerForOutOfFlowPositioned() : nullptr) {
// For positioned layers, we subtract out the enclosing positioned layer's scroll offset.
- if (positionedParent->layoutObject()->hasOverflowClip()) {
- IntSize offset = positionedParent->layoutBox()->scrolledContentOffset();
+ if (containingLayer->layoutObject()->hasOverflowClip()) {
+ IntSize offset = containingLayer->layoutBox()->scrolledContentOffset();
localPoint -= offset;
}
- if (positionedParent->layoutObject()->isInFlowPositioned() && positionedParent->layoutObject()->isLayoutInline()) {
- LayoutSize offset = toLayoutInline(positionedParent->layoutObject())->offsetForInFlowPositionedInline(*toLayoutBox(layoutObject()));
+ if (containingLayer->layoutObject()->isInFlowPositioned() && containingLayer->layoutObject()->isLayoutInline()) {
+ LayoutSize offset = toLayoutInline(containingLayer->layoutObject())->offsetForInFlowPositionedInline(*toLayoutBox(layoutObject()));
localPoint += offset;
}
} else if (parent() && parent()->layoutObject()->hasOverflowClip()) {
@@ -818,19 +818,28 @@ FloatPoint PaintLayer::perspectiveOrigin() const
return FloatPoint(floatValueForLength(style.perspectiveOriginX(), borderBox.width().toFloat()), floatValueForLength(style.perspectiveOriginY(), borderBox.height().toFloat()));
}
-static inline bool isFixedPositionedContainer(PaintLayer* layer)
+static inline bool isContainerForFixedPositioned(PaintLayer* layer)
{
return layer->isRootLayer() || layer->hasTransformRelatedProperty();
}
-PaintLayer* PaintLayer::enclosingPositionedAncestor(const PaintLayer* ancestor, bool* skippedAncestor) const
+static inline bool isContainerForPositioned(PaintLayer* layer)
+{
+ // FIXME: This is not in sync with containingBlock.
+ // LayoutObject::canContainFixedPositionObjects() should probably be used
+ // instead.
+ LayoutBoxModelObject* layerlayoutObject = layer->layoutObject();
+ return layer->isRootLayer() || layerlayoutObject->isPositioned() || layer->hasTransformRelatedProperty() || layerlayoutObject->style()->containsPaint();
+}
+
+PaintLayer* PaintLayer::containingLayerForOutOfFlowPositioned(const PaintLayer* ancestor, bool* skippedAncestor) const
{
ASSERT(!ancestor || skippedAncestor); // If we have specified an ancestor, surely the caller needs to know whether we skipped it.
if (skippedAncestor)
*skippedAncestor = false;
if (layoutObject()->style()->position() == FixedPosition) {
PaintLayer* curr = parent();
- while (curr && !isFixedPositionedContainer(curr)) {
+ while (curr && !isContainerForFixedPositioned(curr)) {
if (skippedAncestor && curr == ancestor)
*skippedAncestor = true;
curr = curr->parent();
@@ -840,7 +849,7 @@ PaintLayer* PaintLayer::enclosingPositionedAncestor(const PaintLayer* ancestor,
}
PaintLayer* curr = parent();
- while (curr && !curr->isPositionedContainer()) {
+ while (curr && !isContainerForPositioned(curr)) {
if (skippedAncestor && curr == ancestor)
*skippedAncestor = true;
curr = curr->parent();
@@ -1277,7 +1286,7 @@ static inline const PaintLayer* accumulateOffsetTowardsAncestor(const PaintLayer
PaintLayer* parentLayer;
if (position == AbsolutePosition || position == FixedPosition) {
bool foundAncestorFirst;
- parentLayer = layer->enclosingPositionedAncestor(ancestorLayer, &foundAncestorFirst);
+ parentLayer = layer->containingLayerForOutOfFlowPositioned(ancestorLayer, &foundAncestorFirst);
if (foundAncestorFirst) {
// Found ancestorLayer before the container of the out-of-flow object, so compute offset
@@ -2371,7 +2380,7 @@ bool PaintLayer::backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect)
// We can't consult child layers if we clip, since they might cover
// parts of the rect that are clipped out.
- if (layoutObject()->hasOverflowClip())
+ if (layoutObject()->hasOverflowClip() || layoutObject()->style()->containsPaint())
return false;
return childBackgroundIsKnownToBeOpaqueInRect(localRect);
diff --git a/third_party/WebKit/Source/core/paint/PaintLayer.h b/third_party/WebKit/Source/core/paint/PaintLayer.h
index e02293d..17a1633 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayer.h
+++ b/third_party/WebKit/Source/core/paint/PaintLayer.h
@@ -261,14 +261,13 @@ public:
bool hasVisibleNonLayerContent() const { return m_hasVisibleNonLayerContent; }
bool hasNonCompositedChild() const { ASSERT(isAllowedToQueryCompositingState()); return m_hasNonCompositedChild; }
- // Gets the ancestor layer that serves as the containing block of this layer. It is assumed
- // that this layer is established by an out-of-flow positioned layout object (i.e. either
- // absolutely or fixed positioned).
+ // Gets the ancestor layer that serves as the containing block of this layer. This is either
+ // another out of flow positioned layer, or one that contains paint.
// If |ancestor| is specified, |*skippedAncestor| will be set to true if |ancestor| is found in
// the ancestry chain between this layer and the containing block layer; if not found, it will
// be set to false. Either both |ancestor| and |skippedAncestor| should be nullptr, or none of
// them should.
- PaintLayer* enclosingPositionedAncestor(const PaintLayer* ancestor = nullptr, bool* skippedAncestor = nullptr) const;
+ PaintLayer* containingLayerForOutOfFlowPositioned(const PaintLayer* ancestor = nullptr, bool* skippedAncestor = nullptr) const;
bool isPaintInvalidationContainer() const;
@@ -459,15 +458,6 @@ public:
PaintLayerClipper& clipper() { return m_clipper; }
const PaintLayerClipper& clipper() const { return m_clipper; }
- inline bool isPositionedContainer() const
- {
- // FIXME: This is not in sync with containingBlock.
- // LayoutObject::canContainFixedPositionObjects() should probably be used
- // instead.
- LayoutBoxModelObject* layerlayoutObject = layoutObject();
- return isRootLayer() || layerlayoutObject->isPositioned() || hasTransformRelatedProperty();
- }
-
bool scrollsOverflow() const;
CompositingReasons potentialCompositingReasonsFromStyle() const { return m_potentialCompositingReasonsFromStyle; }
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp b/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp
index 0ff40ac..3b11423 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp
@@ -69,12 +69,12 @@ static void adjustClipRectsForChildren(const LayoutObject& layoutObject, ClipRec
static void applyClipRects(const ClipRectsContext& context, const LayoutObject& layoutObject, LayoutPoint offset, ClipRects& clipRects)
{
- ASSERT(layoutObject.hasOverflowClip() || layoutObject.hasClip());
+ ASSERT(layoutObject.hasOverflowClip() || layoutObject.hasClip() || layoutObject.style()->containsPaint());
LayoutView* view = layoutObject.view();
ASSERT(view);
if (clipRects.fixed() && context.rootLayer->layoutObject() == view)
offset -= toIntSize(view->frameView()->scrollPosition());
- if (layoutObject.hasOverflowClip()) {
+ if (layoutObject.hasOverflowClip() || layoutObject.style()->containsPaint()) {
ClipRect newOverflowClip = toLayoutBox(layoutObject).overflowClipRect(offset, context.scrollbarRelevancy);
newOverflowClip.setHasRadius(layoutObject.style()->hasBorderRadius());
clipRects.setOverflowClipRect(intersection(newOverflowClip, clipRects.overflowClipRect()));
@@ -82,6 +82,10 @@ static void applyClipRects(const ClipRectsContext& context, const LayoutObject&
clipRects.setPosClipRect(intersection(newOverflowClip, clipRects.posClipRect()));
if (layoutObject.isLayoutView())
clipRects.setFixedClipRect(intersection(newOverflowClip, clipRects.fixedClipRect()));
+ if (layoutObject.style()->containsPaint()) {
+ clipRects.setPosClipRect(intersection(newOverflowClip, clipRects.posClipRect()));
+ clipRects.setFixedClipRect(intersection(newOverflowClip, clipRects.fixedClipRect()));
+ }
}
if (layoutObject.hasClip()) {
LayoutRect newClip = toLayoutBox(layoutObject).clipRect(offset);
@@ -213,7 +217,7 @@ void PaintLayerClipper::calculateRects(const ClipRectsContext& context, const La
layerBounds = LayoutRect(offset, LayoutSize(m_layoutObject.layer()->size()));
// Update the clip rects that will be passed to child layers.
- if (m_layoutObject.hasOverflowClip() && shouldRespectOverflowClip(context)) {
+ if ((m_layoutObject.hasOverflowClip() && shouldRespectOverflowClip(context)) || m_layoutObject.style()->containsPaint()) {
foregroundRect.intersect(toLayoutBox(m_layoutObject).overflowClipRect(offset, context.scrollbarRelevancy));
if (m_layoutObject.style()->hasBorderRadius())
foregroundRect.setHasRadius(true);
@@ -267,7 +271,7 @@ void PaintLayerClipper::calculateClipRects(const ClipRectsContext& context, Clip
adjustClipRectsForChildren(m_layoutObject, clipRects);
- if ((m_layoutObject.hasOverflowClip() && shouldRespectOverflowClip(context)) || m_layoutObject.hasClip()) {
+ if ((m_layoutObject.hasOverflowClip() && shouldRespectOverflowClip(context)) || m_layoutObject.hasClip() || m_layoutObject.style()->containsPaint()) {
// This offset cannot use convertToLayerCoords, because sometimes our rootLayer may be across
// some transformed layer boundary, for example, in the PaintLayerCompositor overlapMap, where
// clipRects are needed in view space.
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.h b/third_party/WebKit/Source/core/style/ComputedStyle.h
index cd4edb0..2e1b0ea 100644
--- a/third_party/WebKit/Source/core/style/ComputedStyle.h
+++ b/third_party/WebKit/Source/core/style/ComputedStyle.h
@@ -826,6 +826,7 @@ public:
bool hasVisualOverflowingEffect() const { return boxShadow() || hasBorderImageOutsets() || hasOutline(); }
Containment contain() const { return static_cast<Containment>(rareNonInheritedData->m_contain); }
+ bool containsPaint() const { return rareNonInheritedData->m_contain & ContainsPaint; }
EBoxSizing boxSizing() const { return m_box->boxSizing(); }
EUserModify userModify() const { return static_cast<EUserModify>(rareInheritedData->userModify); }