Index: third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp |
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp |
index 65b51facee107278481b66940237bd329a578948..721d604875fab9db7bbdb4d25d1c7a11e1d4b1a8 100644 |
--- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp |
+++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp |
@@ -8,6 +8,7 @@ |
#include "core/paint/ObjectPaintProperties.h" |
#include "core/paint/PaintPropertyTreePrinter.h" |
#include "platform/graphics/paint/GeometryMapper.h" |
+#include "platform/graphics/paint/ScrollPaintPropertyNode.h" |
#include "platform/graphics/paint/TransformPaintPropertyNode.h" |
#include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h" |
#include "platform/testing/UnitTestHelpers.h" |
@@ -78,6 +79,14 @@ public: |
return frameView->contentClip(); |
} |
+ const ScrollPaintPropertyNode* frameScroll() |
+ { |
+ FrameView* frameView = document().view(); |
+ if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) |
+ return frameView->layoutView()->objectPaintProperties()->scroll(); |
+ return frameView->scroll(); |
+ } |
+ |
private: |
void SetUp() override |
{ |
@@ -133,7 +142,13 @@ TEST_P(PaintPropertyTreeBuilderTest, FixedPosition) |
{ |
loadTestData("fixed-position.html"); |
+ Element* positionedScroll = document().getElementById("positionedScroll"); |
+ positionedScroll->setScrollTop(3); |
+ Element* transformedScroll = document().getElementById("transformedScroll"); |
+ transformedScroll->setScrollTop(5); |
+ |
FrameView* frameView = document().view(); |
+ frameView->updateAllLifecyclePhases(); |
// target1 is a fixed-position element inside an absolute-position scrolling element. |
// It should be attached under the viewport to skip scrolling and offset of the parent. |
@@ -145,20 +160,32 @@ TEST_P(PaintPropertyTreeBuilderTest, FixedPosition) |
EXPECT_EQ(FloatRoundedRect(0, 0, 100, 100), target1Properties->overflowClip()->clipRect()); |
// Likewise, it inherits clip from the viewport, skipping overflow clip of the scroller. |
EXPECT_EQ(frameContentClip(), target1Properties->overflowClip()->parent()); |
+ // target1 should not have it's own scroll node and instead should inherit positionedScroll's. |
+ const ObjectPaintProperties* positionedScrollProperties = positionedScroll->layoutObject()->objectPaintProperties(); |
+ EXPECT_EQ(frameScroll(), positionedScrollProperties->scroll()->parent()); |
+ EXPECT_EQ(TransformationMatrix().translate(0, -3), positionedScrollProperties->scroll()->scrollOffsetTranslation()->matrix()); |
+ EXPECT_EQ(nullptr, target1Properties->scroll()); |
+ |
CHECK_EXACT_VISUAL_RECT(LayoutRect(200, 150, 100, 100), target1->layoutObject(), frameView->layoutView()); |
// target2 is a fixed-position element inside a transformed scrolling element. |
// It should be attached under the scrolled box of the transformed element. |
Element* target2 = document().getElementById("target2"); |
const ObjectPaintProperties* target2Properties = target2->layoutObject()->objectPaintProperties(); |
- Element* scroller = document().getElementById("scroller"); |
+ Element* scroller = document().getElementById("transformedScroll"); |
const ObjectPaintProperties* scrollerProperties = scroller->layoutObject()->objectPaintProperties(); |
EXPECT_EQ(TransformationMatrix().translate(200, 150), target2Properties->paintOffsetTranslation()->matrix()); |
EXPECT_EQ(scrollerProperties->scrollTranslation(), target2Properties->paintOffsetTranslation()->parent()); |
EXPECT_EQ(target2Properties->paintOffsetTranslation(), target2Properties->overflowClip()->localTransformSpace()); |
EXPECT_EQ(FloatRoundedRect(0, 0, 100, 100), target2Properties->overflowClip()->clipRect()); |
EXPECT_EQ(scrollerProperties->overflowClip(), target2Properties->overflowClip()->parent()); |
- CHECK_EXACT_VISUAL_RECT(LayoutRect(208, 158, 200, 100), target2->layoutObject(), frameView->layoutView()); |
+ // target2 should not have it's own scroll node and instead should inherit transformedScroll's. |
+ const ObjectPaintProperties* transformedScrollProperties = transformedScroll->layoutObject()->objectPaintProperties(); |
+ EXPECT_EQ(frameScroll(), transformedScrollProperties->scroll()->parent()); |
+ EXPECT_EQ(TransformationMatrix().translate(0, -5), transformedScrollProperties->scroll()->scrollOffsetTranslation()->matrix()); |
+ EXPECT_EQ(nullptr, target2Properties->scroll()); |
+ |
+ CHECK_EXACT_VISUAL_RECT(LayoutRect(208, 153, 200, 100), target2->layoutObject(), frameView->layoutView()); |
} |
TEST_P(PaintPropertyTreeBuilderTest, PositionAndScroll) |
@@ -173,11 +200,16 @@ TEST_P(PaintPropertyTreeBuilderTest, PositionAndScroll) |
EXPECT_EQ(TransformationMatrix().translate(0, -100), scrollerProperties->scrollTranslation()->matrix()); |
EXPECT_EQ(frameScrollTranslation(), scrollerProperties->scrollTranslation()->parent()); |
EXPECT_EQ(frameScrollTranslation(), scrollerProperties->overflowClip()->localTransformSpace()); |
- EXPECT_EQ(FloatRoundedRect(120, 340, 400, 300), scrollerProperties->overflowClip()->clipRect()); |
+ EXPECT_EQ(frameScroll(), scrollerProperties->scroll()->parent()); |
+ EXPECT_EQ(FloatSize(413, 317), scrollerProperties->scroll()->clip()); |
+ EXPECT_EQ(FloatSize(660, 10200), scrollerProperties->scroll()->bounds()); |
+ EXPECT_FALSE(scrollerProperties->scroll()->userScrollableHorizontal()); |
+ EXPECT_TRUE(scrollerProperties->scroll()->userScrollableVertical()); |
+ EXPECT_EQ(FloatRoundedRect(120, 340, 413, 317), scrollerProperties->overflowClip()->clipRect()); |
EXPECT_EQ(frameContentClip(), scrollerProperties->overflowClip()->parent()); |
// http://crbug.com/638415 |
if (!RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { |
- CHECK_EXACT_VISUAL_RECT(LayoutRect(120, 340, 400, 300), scroller->layoutObject(), frameView->layoutView()); |
+ CHECK_EXACT_VISUAL_RECT(LayoutRect(120, 340, 413, 317), scroller->layoutObject(), frameView->layoutView()); |
} |
// The relative-positioned element should have accumulated box offset (exclude scrolling), |
@@ -1714,4 +1746,150 @@ TEST_P(PaintPropertyTreeBuilderTest, SvgLocalToBorderBoxTransformContentsPropert |
EXPECT_EQ(svgWithViewBoxProperties->svgLocalToBorderBoxTransform(), contentsProperties.transform); |
} |
+TEST_P(PaintPropertyTreeBuilderTest, OverflowHiddenScrollProperties) |
+{ |
+ setBodyInnerHTML( |
+ "<style>" |
+ " body {" |
+ " margin: 0px;" |
+ " }" |
+ " #overflowHidden {" |
+ " overflow: hidden;" |
+ " width: 5px;" |
+ " height: 3px;" |
+ " }" |
+ " .forceScroll {" |
+ " height: 79px;" |
+ " }" |
+ "</style>" |
+ "<div id='overflowHidden'>" |
+ " <div class='forceScroll'></div>" |
+ "</div>"); |
+ |
+ Element* overflowHidden = document().getElementById("overflowHidden"); |
+ overflowHidden->setScrollTop(37); |
+ |
+ document().view()->updateAllLifecyclePhases(); |
+ |
+ const ObjectPaintProperties* overflowHiddenScrollProperties = overflowHidden->layoutObject()->objectPaintProperties(); |
+ EXPECT_EQ(frameScroll(), overflowHiddenScrollProperties->scroll()->parent()); |
+ EXPECT_EQ(TransformationMatrix().translate(0, -37), overflowHiddenScrollProperties->scroll()->scrollOffsetTranslation()->matrix()); |
+ // This should match the overflow's dimensions. |
+ EXPECT_EQ(FloatSize(5, 3), overflowHiddenScrollProperties->scroll()->clip()); |
+ // The scrolling content's bounds should include both the overflow's dimensions (5x3) and the |
+ // 0x79 "forceScroll" object. |
+ EXPECT_EQ(FloatSize(5, 79), overflowHiddenScrollProperties->scroll()->bounds()); |
+ // Although overflow: hidden is programmatically scrollable, it is not user scrollable. |
+ EXPECT_FALSE(overflowHiddenScrollProperties->scroll()->userScrollableHorizontal()); |
+ EXPECT_FALSE(overflowHiddenScrollProperties->scroll()->userScrollableVertical()); |
+} |
+ |
+TEST_P(PaintPropertyTreeBuilderTest, NestedScrollProperties) |
+{ |
+ setBodyInnerHTML( |
+ "<style>" |
+ " * {" |
+ " margin: 0px;" |
+ " }" |
+ " #overflowA {" |
+ " overflow: scroll;" |
+ " width: 5px;" |
+ " height: 3px;" |
+ " }" |
+ " #overflowB {" |
+ " overflow: scroll;" |
+ " width: 9px;" |
+ " height: 7px;" |
+ " }" |
+ " .forceScroll {" |
+ " height: 100px;" |
+ " }" |
+ "</style>" |
+ "<div id='overflowA'>" |
+ " <div id='overflowB'>" |
+ " <div class='forceScroll'></div>" |
+ " </div>" |
+ " <div class='forceScroll'></div>" |
+ "</div>"); |
+ |
+ Element* overflowA = document().getElementById("overflowA"); |
+ overflowA->setScrollTop(37); |
+ Element* overflowB = document().getElementById("overflowB"); |
+ overflowB->setScrollTop(41); |
+ |
+ document().view()->updateAllLifecyclePhases(); |
+ |
+ const ObjectPaintProperties* overflowAScrollProperties = overflowA->layoutObject()->objectPaintProperties(); |
+ EXPECT_EQ(frameScroll(), overflowAScrollProperties->scroll()->parent()); |
+ EXPECT_EQ(TransformationMatrix().translate(0, -37), overflowAScrollProperties->scroll()->scrollOffsetTranslation()->matrix()); |
+ EXPECT_EQ(FloatSize(5, 3), overflowAScrollProperties->scroll()->clip()); |
+ // 107 is the forceScroll element plus the height of the overflow scroll child (overflowB). |
+ EXPECT_EQ(FloatSize(9, 107), overflowAScrollProperties->scroll()->bounds()); |
+ EXPECT_TRUE(overflowAScrollProperties->scroll()->userScrollableHorizontal()); |
+ EXPECT_TRUE(overflowAScrollProperties->scroll()->userScrollableVertical()); |
+ |
+ const ObjectPaintProperties* overflowBScrollProperties = overflowB->layoutObject()->objectPaintProperties(); |
+ // The overflow child's scroll node should be a child of the parent's (overflowA) scroll node. |
+ EXPECT_EQ(overflowAScrollProperties->scroll(), overflowBScrollProperties->scroll()->parent()); |
+ EXPECT_EQ(TransformationMatrix().translate(0, -41), overflowBScrollProperties->scroll()->scrollOffsetTranslation()->matrix()); |
+ EXPECT_EQ(FloatSize(9, 7), overflowBScrollProperties->scroll()->clip()); |
+ EXPECT_EQ(FloatSize(9, 100), overflowBScrollProperties->scroll()->bounds()); |
+ EXPECT_TRUE(overflowBScrollProperties->scroll()->userScrollableHorizontal()); |
+ EXPECT_TRUE(overflowBScrollProperties->scroll()->userScrollableVertical()); |
+} |
+ |
+TEST_P(PaintPropertyTreeBuilderTest, PositionedScrollerIsNotNested) |
+{ |
+ setBodyInnerHTML( |
+ "<style>" |
+ " * {" |
+ " margin: 0px;" |
+ " }" |
+ " #overflow {" |
+ " overflow: scroll;" |
+ " width: 5px;" |
+ " height: 3px;" |
+ " }" |
+ " #positionedOverflow {" |
+ " position: absolute;" |
+ " top: 0;" |
+ " left: 0;" |
+ " overflow: scroll;" |
+ " width: 9px;" |
+ " height: 7px;" |
+ " }" |
+ " .forceScroll {" |
+ " height: 100px;" |
+ " }" |
+ "</style>" |
+ "<div id='overflow'>" |
+ " <div id='positionedOverflow'>" |
+ " <div class='forceScroll'></div>" |
+ " </div>" |
+ " <div class='forceScroll'></div>" |
+ "</div>"); |
+ |
+ Element* overflow = document().getElementById("overflow"); |
+ overflow->setScrollTop(37); |
+ Element* positionedOverflow = document().getElementById("positionedOverflow"); |
+ positionedOverflow->setScrollTop(41); |
+ |
+ document().view()->updateAllLifecyclePhases(); |
+ |
+ const ObjectPaintProperties* overflowScrollProperties = overflow->layoutObject()->objectPaintProperties(); |
+ EXPECT_EQ(frameScroll(), overflowScrollProperties->scroll()->parent()); |
+ EXPECT_EQ(TransformationMatrix().translate(0, -37), overflowScrollProperties->scroll()->scrollOffsetTranslation()->matrix()); |
+ EXPECT_EQ(FloatSize(5, 3), overflowScrollProperties->scroll()->clip()); |
+ // The height should be 100px because the (dom-order) overflow child is positioned and does not |
+ // contribute to the height. Only the 100px "forceScroll" height is present. |
+ EXPECT_EQ(FloatSize(5, 100), overflowScrollProperties->scroll()->bounds()); |
+ |
+ const ObjectPaintProperties* positionedOverflowScrollProperties = positionedOverflow->layoutObject()->objectPaintProperties(); |
+ // The positioned overflow scroll node is parented under the frame, not the dom-order parent. |
+ EXPECT_EQ(frameScroll(), positionedOverflowScrollProperties->scroll()->parent()); |
+ EXPECT_EQ(TransformationMatrix().translate(0, -41), positionedOverflowScrollProperties->scroll()->scrollOffsetTranslation()->matrix()); |
+ EXPECT_EQ(FloatSize(9, 7), positionedOverflowScrollProperties->scroll()->clip()); |
+ EXPECT_EQ(FloatSize(9, 100), positionedOverflowScrollProperties->scroll()->bounds()); |
+} |
+ |
} // namespace blink |