| Index: third_party/WebKit/Source/core/layout/VisualRectMappingTest.cpp
|
| diff --git a/third_party/WebKit/Source/core/layout/LayoutObjectTest.cpp b/third_party/WebKit/Source/core/layout/VisualRectMappingTest.cpp
|
| similarity index 74%
|
| copy from third_party/WebKit/Source/core/layout/LayoutObjectTest.cpp
|
| copy to third_party/WebKit/Source/core/layout/VisualRectMappingTest.cpp
|
| index c9d180173d078970d4ed7395e24fc7e72c944a17..ad96acc504575e55073f09970afda61a9608ed36 100644
|
| --- a/third_party/WebKit/Source/core/layout/LayoutObjectTest.cpp
|
| +++ b/third_party/WebKit/Source/core/layout/VisualRectMappingTest.cpp
|
| @@ -2,114 +2,48 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| -#include "core/layout/LayoutObject.h"
|
| -
|
| #include "core/layout/LayoutTestHelper.h"
|
| #include "core/layout/LayoutView.h"
|
| +#include "core/layout/PaintInvalidationState.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
|
|
| namespace blink {
|
|
|
| -class LayoutObjectTest : public RenderingTest {
|
| +class VisualRectMappingTest : public RenderingTest {
|
| public:
|
| - LayoutObjectTest()
|
| + VisualRectMappingTest()
|
| : RenderingTest(SingleChildFrameLoaderClient::create()) {}
|
| protected:
|
| LayoutView& layoutView() const { return *document().layoutView(); }
|
| -};
|
| -
|
| -TEST_F(LayoutObjectTest, LayoutDecoratedNameCalledWithPositionedObject)
|
| -{
|
| - setBodyInnerHTML("<div id='div' style='position: fixed'>test</div>");
|
| - Element* div = document().getElementById(AtomicString("div"));
|
| - ASSERT(div);
|
| - LayoutObject* obj = div->layoutObject();
|
| - ASSERT(obj);
|
| - EXPECT_STREQ("LayoutBlockFlow (positioned)", obj->decoratedName().ascii().data());
|
| -}
|
| -
|
| -
|
| -// Some display checks.
|
| -TEST_F(LayoutObjectTest, DisplayNoneCreateObject)
|
| -{
|
| - setBodyInnerHTML("<div style='display:none'></div>");
|
| - EXPECT_EQ(nullptr, document().body()->firstChild()->layoutObject());
|
| -}
|
| -
|
| -TEST_F(LayoutObjectTest, DisplayBlockCreateObject)
|
| -{
|
| - setBodyInnerHTML("<foo style='display:block'></foo>");
|
| - LayoutObject* layoutObject = document().body()->firstChild()->layoutObject();
|
| - EXPECT_NE(nullptr, layoutObject);
|
| - EXPECT_TRUE(layoutObject->isLayoutBlockFlow());
|
| - EXPECT_FALSE(layoutObject->isInline());
|
| -}
|
| -
|
| -TEST_F(LayoutObjectTest, DisplayInlineBlockCreateObject)
|
| -{
|
| - setBodyInnerHTML("<foo style='display:inline-block'></foo>");
|
| - LayoutObject* layoutObject = document().body()->firstChild()->layoutObject();
|
| - EXPECT_NE(nullptr, layoutObject);
|
| - EXPECT_TRUE(layoutObject->isLayoutBlockFlow());
|
| - EXPECT_TRUE(layoutObject->isInline());
|
| -}
|
| -
|
| -
|
| -
|
| -// Containing block test.
|
| -TEST_F(LayoutObjectTest, ContainingBlockLayoutViewShouldBeNull)
|
| -{
|
| - EXPECT_EQ(nullptr, layoutView().containingBlock());
|
| -}
|
| -
|
| -TEST_F(LayoutObjectTest, ContainingBlockBodyShouldBeDocumentElement)
|
| -{
|
| - EXPECT_EQ(document().body()->layoutObject()->containingBlock(), document().documentElement()->layoutObject());
|
| -}
|
| -
|
| -TEST_F(LayoutObjectTest, ContainingBlockDocumentElementShouldBeLayoutView)
|
| -{
|
| - EXPECT_EQ(document().documentElement()->layoutObject()->containingBlock(), layoutView());
|
| -}
|
| -
|
| -TEST_F(LayoutObjectTest, ContainingBlockStaticLayoutObjectShouldBeParent)
|
| -{
|
| - setBodyInnerHTML("<foo style='position:static'></foo>");
|
| - LayoutObject* bodyLayoutObject = document().body()->layoutObject();
|
| - LayoutObject* layoutObject = bodyLayoutObject->slowFirstChild();
|
| - EXPECT_EQ(layoutObject->containingBlock(), bodyLayoutObject);
|
| -}
|
| -
|
| -TEST_F(LayoutObjectTest, ContainingBlockAbsoluteLayoutObjectShouldBeLayoutView)
|
| -{
|
| - setBodyInnerHTML("<foo style='position:absolute'></foo>");
|
| - LayoutObject* layoutObject = document().body()->layoutObject()->slowFirstChild();
|
| - EXPECT_EQ(layoutObject->containingBlock(), layoutView());
|
| -}
|
| -
|
| -TEST_F(LayoutObjectTest, ContainingBlockAbsoluteLayoutObjectShouldBeNonStaticallyPositionedBlockAncestor)
|
| -{
|
| - setBodyInnerHTML("<div style='position:relative'><bar style='position:absolute'></bar></div>");
|
| - LayoutObject* containingBlocklayoutObject = document().body()->layoutObject()->slowFirstChild();
|
| - LayoutObject* layoutObject = containingBlocklayoutObject->slowFirstChild();
|
| - EXPECT_EQ(layoutObject->containingBlock(), containingBlocklayoutObject);
|
| -}
|
| -
|
| -TEST_F(LayoutObjectTest, ContainingBlockAbsoluteLayoutObjectShouldNotBeNonStaticlyPositionedInlineAncestor)
|
| -{
|
| - setBodyInnerHTML("<span style='position:relative'><bar style='position:absolute'></bar></span>");
|
| - LayoutObject* bodyLayoutObject = document().body()->layoutObject();
|
| - LayoutObject* layoutObject = bodyLayoutObject->slowFirstChild()->slowFirstChild();
|
| -
|
| - // Sanity check: Make sure we don't generate anonymous objects.
|
| - EXPECT_EQ(nullptr, bodyLayoutObject->slowFirstChild()->nextSibling());
|
| - EXPECT_EQ(nullptr, layoutObject->slowFirstChild());
|
| - EXPECT_EQ(nullptr, layoutObject->nextSibling());
|
|
|
| - EXPECT_EQ(layoutObject->containingBlock(), bodyLayoutObject);
|
| -}
|
| + void checkPaintInvalidationStateRectMapping(const LayoutRect& expectedRect, const LayoutRect& rect, const LayoutObject& object, const LayoutView& layoutView, const LayoutObject& paintInvalidationContainer)
|
| + {
|
| + Vector<const LayoutObject*> ancestors;
|
| + for (const LayoutObject* ancestor = &object; ancestor != layoutView; ancestor = ancestor->parentCrossingFrameBoundaries())
|
| + ancestors.append(ancestor);
|
| +
|
| + Vector<Optional<PaintInvalidationState>> paintInvalidationStates(ancestors.size() + 1);
|
| + Vector<LayoutObject*> pendingDelayedPaintInvalidations;
|
| + paintInvalidationStates[0].emplace(layoutView, pendingDelayedPaintInvalidations);
|
| + if (layoutView != object)
|
| + paintInvalidationStates[0]->updateForChildren();
|
| + for (size_t i = 1; i < paintInvalidationStates.size(); ++i) {
|
| + paintInvalidationStates[i].emplace(*paintInvalidationStates[i - 1], *ancestors[ancestors.size() - i]);
|
| + if (paintInvalidationStates[i]->m_currentObject != object)
|
| + paintInvalidationStates[i]->updateForChildren();
|
| + }
|
| +
|
| + const PaintInvalidationState& paintInvalidationState = *paintInvalidationStates.last();
|
| + ASSERT_EQ(paintInvalidationState.m_currentObject, object);
|
| + ASSERT_EQ(paintInvalidationState.paintInvalidationContainer(), paintInvalidationContainer);
|
| +
|
| + LayoutRect r = rect;
|
| + paintInvalidationState.mapLocalRectToPaintInvalidationBacking(r);
|
| + EXPECT_EQ(expectedRect, r);
|
| + }
|
| +};
|
|
|
| -TEST_F(LayoutObjectTest, LayoutTextMapToVisualRectInAncestorSpace)
|
| +TEST_F(VisualRectMappingTest, LayoutText)
|
| {
|
| setBodyInnerHTML(
|
| "<style>body { margin: 0; }</style>"
|
| @@ -122,16 +56,22 @@ TEST_F(LayoutObjectTest, LayoutTextMapToVisualRectInAncestorSpace)
|
| LayoutText* text = toLayoutText(container->lastChild());
|
|
|
| container->setScrollTop(LayoutUnit(50));
|
| - LayoutRect rect(0, 60, 20, 80);
|
| + LayoutRect originalRect(0, 60, 20, 80);
|
| + LayoutRect rect = originalRect;
|
| EXPECT_TRUE(text->mapToVisualRectInAncestorSpace(container, rect));
|
| EXPECT_EQ(rect, LayoutRect(0, 10, 20, 80));
|
|
|
| + rect = originalRect;
|
| + EXPECT_TRUE(text->mapToVisualRectInAncestorSpace(&layoutView(), rect));
|
| + EXPECT_EQ(rect, LayoutRect(0, 10, 20, 40));
|
| + checkPaintInvalidationStateRectMapping(rect, originalRect, *text, layoutView(), layoutView());
|
| +
|
| rect = LayoutRect(0, 60, 80, 0);
|
| EXPECT_TRUE(text->mapToVisualRectInAncestorSpace(container, rect, EdgeInclusive));
|
| EXPECT_EQ(rect, LayoutRect(0, 10, 80, 0));
|
| }
|
|
|
| -TEST_F(LayoutObjectTest, LayoutInlineMapToVisualRectInAncestorSpace)
|
| +TEST_F(VisualRectMappingTest, LayoutInline)
|
| {
|
| document().setBaseURLOverride(KURL(ParsedURLString, "http://test.com"));
|
| setBodyInnerHTML(
|
| @@ -144,16 +84,22 @@ TEST_F(LayoutObjectTest, LayoutInlineMapToVisualRectInAncestorSpace)
|
| LayoutObject* leaf = container->lastChild();
|
|
|
| container->setScrollTop(LayoutUnit(50));
|
| - LayoutRect rect(0, 60, 20, 80);
|
| + LayoutRect originalRect(0, 60, 20, 80);
|
| + LayoutRect rect = originalRect;
|
| EXPECT_TRUE(leaf->mapToVisualRectInAncestorSpace(container, rect));
|
| EXPECT_EQ(rect, LayoutRect(0, 10, 20, 80));
|
|
|
| + rect = originalRect;
|
| + EXPECT_TRUE(leaf->mapToVisualRectInAncestorSpace(&layoutView(), rect));
|
| + EXPECT_EQ(rect, LayoutRect(0, 10, 20, 40));
|
| + checkPaintInvalidationStateRectMapping(rect, originalRect, *leaf, layoutView(), layoutView());
|
| +
|
| rect = LayoutRect(0, 60, 80, 0);
|
| EXPECT_TRUE(leaf->mapToVisualRectInAncestorSpace(container, rect, EdgeInclusive));
|
| EXPECT_EQ(rect, LayoutRect(0, 10, 80, 0));
|
| }
|
|
|
| -TEST_F(LayoutObjectTest, LayoutViewMapToVisualRectInAncestorSpace)
|
| +TEST_F(VisualRectMappingTest, LayoutView)
|
| {
|
| document().setBaseURLOverride(KURL(ParsedURLString, "http://test.com"));
|
| setBodyInnerHTML(
|
| @@ -163,7 +109,7 @@ TEST_F(LayoutObjectTest, LayoutViewMapToVisualRectInAncestorSpace)
|
| "</div>");
|
|
|
| Document& frameDocument = setupChildIframe("frame", "<style>body { margin: 0; }</style><span><img style='width: 20px; height: 100px'></span>text text text");
|
| - frameDocument.updateLayout();
|
| + document().view()->updateAllLifecyclePhases();
|
|
|
| LayoutBlock* frameContainer = toLayoutBlock(getLayoutObjectByElementId("frameContainer"));
|
| LayoutBlock* frameBody = toLayoutBlock(frameDocument.body()->layoutObject());
|
| @@ -172,16 +118,22 @@ TEST_F(LayoutObjectTest, LayoutViewMapToVisualRectInAncestorSpace)
|
| // This case involves clipping: frame height is 50, y-coordinate of result rect is 13,
|
| // so height should be clipped to (50 - 13) == 37.
|
| frameDocument.view()->setScrollPosition(DoublePoint(0, 47), ProgrammaticScroll);
|
| - LayoutRect rect(4, 60, 20, 80);
|
| + LayoutRect originalRect(4, 60, 20, 80);
|
| + LayoutRect rect = originalRect;
|
| EXPECT_TRUE(frameText->mapToVisualRectInAncestorSpace(frameContainer, rect));
|
| EXPECT_EQ(rect, LayoutRect(4, 13, 20, 37));
|
|
|
| + rect = originalRect;
|
| + EXPECT_TRUE(frameText->mapToVisualRectInAncestorSpace(&layoutView(), rect));
|
| + EXPECT_EQ(rect, LayoutRect(4, 13, 20, 37));
|
| + checkPaintInvalidationStateRectMapping(rect, originalRect, *frameText, layoutView(), layoutView());
|
| +
|
| rect = LayoutRect(4, 60, 0, 80);
|
| EXPECT_TRUE(frameText->mapToVisualRectInAncestorSpace(frameContainer, rect, EdgeInclusive));
|
| EXPECT_EQ(rect, LayoutRect(4, 13, 0, 37));
|
| }
|
|
|
| -TEST_F(LayoutObjectTest, LayoutViewMapToVisualRectInAncestorSpaceSubpixelRounding)
|
| +TEST_F(VisualRectMappingTest, LayoutViewSubpixelRounding)
|
| {
|
| document().setBaseURLOverride(KURL(ParsedURLString, "http://test.com"));
|
| setBodyInnerHTML(
|
| @@ -192,7 +144,7 @@ TEST_F(LayoutObjectTest, LayoutViewMapToVisualRectInAncestorSpaceSubpixelRoundin
|
|
|
| Document& frameDocument = setupChildIframe(
|
| "frame", "<style>body { margin: 0; }</style><div id='target' style='position: relative; width: 100px; height: 100px; left: 0.5px'>");
|
| - frameDocument.updateLayout();
|
| + document().view()->updateAllLifecyclePhases();
|
|
|
| LayoutBlock* frameContainer = toLayoutBlock(getLayoutObjectByElementId("frameContainer"));
|
| LayoutObject* target = frameDocument.getElementById("target")->layoutObject();
|
| @@ -203,7 +155,7 @@ TEST_F(LayoutObjectTest, LayoutViewMapToVisualRectInAncestorSpaceSubpixelRoundin
|
| EXPECT_EQ(LayoutRect(LayoutPoint(DoublePoint(0.5, 0)), LayoutSize(101, 100)), rect);
|
| }
|
|
|
| -TEST_F(LayoutObjectTest, OverflowRectMappingWithSelfFlippedWritingMode)
|
| +TEST_F(VisualRectMappingTest, SelfFlippedWritingMode)
|
| {
|
| setBodyInnerHTML(
|
| "<div id='target' style='writing-mode: vertical-rl; box-shadow: 40px 20px black;"
|
| @@ -225,9 +177,10 @@ TEST_F(LayoutObjectTest, OverflowRectMappingWithSelfFlippedWritingMode)
|
| rect = overflowRect;
|
| EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(&layoutView(), rect));
|
| EXPECT_EQ(LayoutRect(222, 111, 140, 70), rect);
|
| + checkPaintInvalidationStateRectMapping(rect, overflowRect, *target, layoutView(), layoutView());
|
| }
|
|
|
| -TEST_F(LayoutObjectTest, OverflowRectMappingWithContainerFlippedWritingMode)
|
| +TEST_F(VisualRectMappingTest, ContainerFlippedWritingMode)
|
| {
|
| setBodyInnerHTML(
|
| "<div id='container' style='writing-mode: vertical-rl; position: absolute; top: 111px; left: 222px'>"
|
| @@ -255,6 +208,7 @@ TEST_F(LayoutObjectTest, OverflowRectMappingWithContainerFlippedWritingMode)
|
| rect = targetOverflowRect;
|
| EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(&layoutView(), rect));
|
| EXPECT_EQ(LayoutRect(322, 111, 140, 110), rect);
|
| + checkPaintInvalidationStateRectMapping(rect, targetOverflowRect, *target, layoutView(), layoutView());
|
|
|
| LayoutRect containerOverflowRect = container->localOverflowRectForPaintInvalidation();
|
| EXPECT_EQ(LayoutRect(-40, 0, 240, 110), containerOverflowRect);
|
| @@ -264,9 +218,10 @@ TEST_F(LayoutObjectTest, OverflowRectMappingWithContainerFlippedWritingMode)
|
| rect = containerOverflowRect;
|
| EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(&layoutView(), rect));
|
| EXPECT_EQ(LayoutRect(222, 111, 240, 110), rect);
|
| + checkPaintInvalidationStateRectMapping(rect, containerOverflowRect, *container, layoutView(), layoutView());
|
| }
|
|
|
| -TEST_F(LayoutObjectTest, OverflowRectMappingWithContainerOverflowClip)
|
| +TEST_F(VisualRectMappingTest, ContainerOverflowClip)
|
| {
|
| setBodyInnerHTML(
|
| "<div id='container' style='position: absolute; top: 111px; left: 222px;"
|
| @@ -301,6 +256,7 @@ TEST_F(LayoutObjectTest, OverflowRectMappingWithContainerOverflowClip)
|
| // (2, 3, 140, 100) is first clipped by container's overflow clip, to (10, 10, 50, 80),
|
| // then is by added container's offset in LayoutView (111, 222).
|
| EXPECT_EQ(LayoutRect(232, 121, 50, 80), rect);
|
| + checkPaintInvalidationStateRectMapping(rect, targetOverflowRect, *target, layoutView(), layoutView());
|
|
|
| LayoutRect containerOverflowRect = container->localOverflowRectForPaintInvalidation();
|
| // Because container has overflow clip, its visual overflow doesn't include overflow from children.
|
| @@ -315,9 +271,10 @@ TEST_F(LayoutObjectTest, OverflowRectMappingWithContainerOverflowClip)
|
| rect = containerOverflowRect;
|
| EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(&layoutView(), rect));
|
| EXPECT_EQ(LayoutRect(222, 111, 70, 100), rect);
|
| + checkPaintInvalidationStateRectMapping(rect, containerOverflowRect, *container, layoutView(), layoutView());
|
| }
|
|
|
| -TEST_F(LayoutObjectTest, OverflowRectMappingWithContainerFlippedWritingModeAndOverflowClip)
|
| +TEST_F(VisualRectMappingTest, ContainerFlippedWritingModeAndOverflowClip)
|
| {
|
| setBodyInnerHTML(
|
| "<div id='container' style='writing-mode: vertical-rl; position: absolute; top: 111px; left: 222px;"
|
| @@ -361,6 +318,7 @@ TEST_F(LayoutObjectTest, OverflowRectMappingWithContainerFlippedWritingModeAndOv
|
| // TODO(crbug.com/600039): rect.x() should be 262 (left + border-left), but is offset
|
| // by extra horizontal border-widths because of layout error.
|
| EXPECT_EQ(LayoutRect(322, 121, 50, 80), rect);
|
| + checkPaintInvalidationStateRectMapping(rect, targetOverflowRect, *target, layoutView(), layoutView());
|
|
|
| LayoutRect containerOverflowRect = container->localOverflowRectForPaintInvalidation();
|
| // Because container has overflow clip, its visual overflow doesn't include overflow from children.
|
| @@ -377,6 +335,7 @@ TEST_F(LayoutObjectTest, OverflowRectMappingWithContainerFlippedWritingModeAndOv
|
| // TODO(crbug.com/600039): rect.x() should be 222 (left), but is offset by extra horizontal
|
| // border-widths because of layout error.
|
| EXPECT_EQ(LayoutRect(282, 111, 110, 120), rect);
|
| + checkPaintInvalidationStateRectMapping(rect, containerOverflowRect, *container, layoutView(), layoutView());
|
| }
|
|
|
| } // namespace blink
|
|
|