| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "core/layout/LayoutObject.h" | |
| 6 | |
| 7 #include "core/layout/LayoutTestHelper.h" | 5 #include "core/layout/LayoutTestHelper.h" |
| 8 #include "core/layout/LayoutView.h" | 6 #include "core/layout/LayoutView.h" |
| 7 #include "core/layout/PaintInvalidationState.h" |
| 9 #include "testing/gtest/include/gtest/gtest.h" | 8 #include "testing/gtest/include/gtest/gtest.h" |
| 10 | 9 |
| 11 namespace blink { | 10 namespace blink { |
| 12 | 11 |
| 13 class LayoutObjectTest : public RenderingTest { | 12 class VisualRectMappingTest : public RenderingTest { |
| 14 public: | 13 public: |
| 15 LayoutObjectTest() | 14 VisualRectMappingTest() |
| 16 : RenderingTest(SingleChildFrameLoaderClient::create()) {} | 15 : RenderingTest(SingleChildFrameLoaderClient::create()) {} |
| 17 protected: | 16 protected: |
| 18 LayoutView& layoutView() const { return *document().layoutView(); } | 17 LayoutView& layoutView() const { return *document().layoutView(); } |
| 18 |
| 19 void checkPaintInvalidationStateRectMapping(const LayoutRect& expectedRect,
const LayoutRect& rect, const LayoutObject& object, const LayoutView& layoutView
, const LayoutObject& paintInvalidationContainer) |
| 20 { |
| 21 Vector<const LayoutObject*> ancestors; |
| 22 for (const LayoutObject* ancestor = &object; ancestor != layoutView; anc
estor = ancestor->parentCrossingFrameBoundaries()) |
| 23 ancestors.append(ancestor); |
| 24 |
| 25 Vector<Optional<PaintInvalidationState>> paintInvalidationStates(ancesto
rs.size() + 1); |
| 26 Vector<LayoutObject*> pendingDelayedPaintInvalidations; |
| 27 paintInvalidationStates[0].emplace(layoutView, pendingDelayedPaintInvali
dations); |
| 28 if (layoutView != object) |
| 29 paintInvalidationStates[0]->updateForChildren(); |
| 30 for (size_t i = 1; i < paintInvalidationStates.size(); ++i) { |
| 31 paintInvalidationStates[i].emplace(*paintInvalidationStates[i - 1],
*ancestors[ancestors.size() - i]); |
| 32 if (paintInvalidationStates[i]->m_currentObject != object) |
| 33 paintInvalidationStates[i]->updateForChildren(); |
| 34 } |
| 35 |
| 36 const PaintInvalidationState& paintInvalidationState = *paintInvalidatio
nStates.last(); |
| 37 ASSERT_EQ(paintInvalidationState.m_currentObject, object); |
| 38 ASSERT_EQ(paintInvalidationState.paintInvalidationContainer(), paintInva
lidationContainer); |
| 39 |
| 40 LayoutRect r = rect; |
| 41 paintInvalidationState.mapLocalRectToPaintInvalidationBacking(r); |
| 42 EXPECT_EQ(expectedRect, r); |
| 43 } |
| 19 }; | 44 }; |
| 20 | 45 |
| 21 TEST_F(LayoutObjectTest, LayoutDecoratedNameCalledWithPositionedObject) | 46 TEST_F(VisualRectMappingTest, LayoutText) |
| 22 { | |
| 23 setBodyInnerHTML("<div id='div' style='position: fixed'>test</div>"); | |
| 24 Element* div = document().getElementById(AtomicString("div")); | |
| 25 ASSERT(div); | |
| 26 LayoutObject* obj = div->layoutObject(); | |
| 27 ASSERT(obj); | |
| 28 EXPECT_STREQ("LayoutBlockFlow (positioned)", obj->decoratedName().ascii().da
ta()); | |
| 29 } | |
| 30 | |
| 31 | |
| 32 // Some display checks. | |
| 33 TEST_F(LayoutObjectTest, DisplayNoneCreateObject) | |
| 34 { | |
| 35 setBodyInnerHTML("<div style='display:none'></div>"); | |
| 36 EXPECT_EQ(nullptr, document().body()->firstChild()->layoutObject()); | |
| 37 } | |
| 38 | |
| 39 TEST_F(LayoutObjectTest, DisplayBlockCreateObject) | |
| 40 { | |
| 41 setBodyInnerHTML("<foo style='display:block'></foo>"); | |
| 42 LayoutObject* layoutObject = document().body()->firstChild()->layoutObject()
; | |
| 43 EXPECT_NE(nullptr, layoutObject); | |
| 44 EXPECT_TRUE(layoutObject->isLayoutBlockFlow()); | |
| 45 EXPECT_FALSE(layoutObject->isInline()); | |
| 46 } | |
| 47 | |
| 48 TEST_F(LayoutObjectTest, DisplayInlineBlockCreateObject) | |
| 49 { | |
| 50 setBodyInnerHTML("<foo style='display:inline-block'></foo>"); | |
| 51 LayoutObject* layoutObject = document().body()->firstChild()->layoutObject()
; | |
| 52 EXPECT_NE(nullptr, layoutObject); | |
| 53 EXPECT_TRUE(layoutObject->isLayoutBlockFlow()); | |
| 54 EXPECT_TRUE(layoutObject->isInline()); | |
| 55 } | |
| 56 | |
| 57 | |
| 58 | |
| 59 // Containing block test. | |
| 60 TEST_F(LayoutObjectTest, ContainingBlockLayoutViewShouldBeNull) | |
| 61 { | |
| 62 EXPECT_EQ(nullptr, layoutView().containingBlock()); | |
| 63 } | |
| 64 | |
| 65 TEST_F(LayoutObjectTest, ContainingBlockBodyShouldBeDocumentElement) | |
| 66 { | |
| 67 EXPECT_EQ(document().body()->layoutObject()->containingBlock(), document().d
ocumentElement()->layoutObject()); | |
| 68 } | |
| 69 | |
| 70 TEST_F(LayoutObjectTest, ContainingBlockDocumentElementShouldBeLayoutView) | |
| 71 { | |
| 72 EXPECT_EQ(document().documentElement()->layoutObject()->containingBlock(), l
ayoutView()); | |
| 73 } | |
| 74 | |
| 75 TEST_F(LayoutObjectTest, ContainingBlockStaticLayoutObjectShouldBeParent) | |
| 76 { | |
| 77 setBodyInnerHTML("<foo style='position:static'></foo>"); | |
| 78 LayoutObject* bodyLayoutObject = document().body()->layoutObject(); | |
| 79 LayoutObject* layoutObject = bodyLayoutObject->slowFirstChild(); | |
| 80 EXPECT_EQ(layoutObject->containingBlock(), bodyLayoutObject); | |
| 81 } | |
| 82 | |
| 83 TEST_F(LayoutObjectTest, ContainingBlockAbsoluteLayoutObjectShouldBeLayoutView) | |
| 84 { | |
| 85 setBodyInnerHTML("<foo style='position:absolute'></foo>"); | |
| 86 LayoutObject* layoutObject = document().body()->layoutObject()->slowFirstChi
ld(); | |
| 87 EXPECT_EQ(layoutObject->containingBlock(), layoutView()); | |
| 88 } | |
| 89 | |
| 90 TEST_F(LayoutObjectTest, ContainingBlockAbsoluteLayoutObjectShouldBeNonStaticall
yPositionedBlockAncestor) | |
| 91 { | |
| 92 setBodyInnerHTML("<div style='position:relative'><bar style='position:absolu
te'></bar></div>"); | |
| 93 LayoutObject* containingBlocklayoutObject = document().body()->layoutObject(
)->slowFirstChild(); | |
| 94 LayoutObject* layoutObject = containingBlocklayoutObject->slowFirstChild(); | |
| 95 EXPECT_EQ(layoutObject->containingBlock(), containingBlocklayoutObject); | |
| 96 } | |
| 97 | |
| 98 TEST_F(LayoutObjectTest, ContainingBlockAbsoluteLayoutObjectShouldNotBeNonStatic
lyPositionedInlineAncestor) | |
| 99 { | |
| 100 setBodyInnerHTML("<span style='position:relative'><bar style='position:absol
ute'></bar></span>"); | |
| 101 LayoutObject* bodyLayoutObject = document().body()->layoutObject(); | |
| 102 LayoutObject* layoutObject = bodyLayoutObject->slowFirstChild()->slowFirstCh
ild(); | |
| 103 | |
| 104 // Sanity check: Make sure we don't generate anonymous objects. | |
| 105 EXPECT_EQ(nullptr, bodyLayoutObject->slowFirstChild()->nextSibling()); | |
| 106 EXPECT_EQ(nullptr, layoutObject->slowFirstChild()); | |
| 107 EXPECT_EQ(nullptr, layoutObject->nextSibling()); | |
| 108 | |
| 109 EXPECT_EQ(layoutObject->containingBlock(), bodyLayoutObject); | |
| 110 } | |
| 111 | |
| 112 TEST_F(LayoutObjectTest, LayoutTextMapToVisualRectInAncestorSpace) | |
| 113 { | 47 { |
| 114 setBodyInnerHTML( | 48 setBodyInnerHTML( |
| 115 "<style>body { margin: 0; }</style>" | 49 "<style>body { margin: 0; }</style>" |
| 116 "<div id='container' style='overflow: scroll; width: 50px; height: 50px'
>" | 50 "<div id='container' style='overflow: scroll; width: 50px; height: 50px'
>" |
| 117 " <span><img style='width: 20px; height: 100px'></span>" | 51 " <span><img style='width: 20px; height: 100px'></span>" |
| 118 " text text text text text text text" | 52 " text text text text text text text" |
| 119 "</div>"); | 53 "</div>"); |
| 120 | 54 |
| 121 LayoutBlock* container = toLayoutBlock(getLayoutObjectByElementId("container
")); | 55 LayoutBlock* container = toLayoutBlock(getLayoutObjectByElementId("container
")); |
| 122 LayoutText* text = toLayoutText(container->lastChild()); | 56 LayoutText* text = toLayoutText(container->lastChild()); |
| 123 | 57 |
| 124 container->setScrollTop(LayoutUnit(50)); | 58 container->setScrollTop(LayoutUnit(50)); |
| 125 LayoutRect rect(0, 60, 20, 80); | 59 LayoutRect originalRect(0, 60, 20, 80); |
| 60 LayoutRect rect = originalRect; |
| 126 EXPECT_TRUE(text->mapToVisualRectInAncestorSpace(container, rect)); | 61 EXPECT_TRUE(text->mapToVisualRectInAncestorSpace(container, rect)); |
| 127 EXPECT_EQ(rect, LayoutRect(0, 10, 20, 80)); | 62 EXPECT_EQ(rect, LayoutRect(0, 10, 20, 80)); |
| 128 | 63 |
| 64 rect = originalRect; |
| 65 EXPECT_TRUE(text->mapToVisualRectInAncestorSpace(&layoutView(), rect)); |
| 66 EXPECT_EQ(rect, LayoutRect(0, 10, 20, 40)); |
| 67 checkPaintInvalidationStateRectMapping(rect, originalRect, *text, layoutView
(), layoutView()); |
| 68 |
| 129 rect = LayoutRect(0, 60, 80, 0); | 69 rect = LayoutRect(0, 60, 80, 0); |
| 130 EXPECT_TRUE(text->mapToVisualRectInAncestorSpace(container, rect, EdgeInclus
ive)); | 70 EXPECT_TRUE(text->mapToVisualRectInAncestorSpace(container, rect, EdgeInclus
ive)); |
| 131 EXPECT_EQ(rect, LayoutRect(0, 10, 80, 0)); | 71 EXPECT_EQ(rect, LayoutRect(0, 10, 80, 0)); |
| 132 } | 72 } |
| 133 | 73 |
| 134 TEST_F(LayoutObjectTest, LayoutInlineMapToVisualRectInAncestorSpace) | 74 TEST_F(VisualRectMappingTest, LayoutInline) |
| 135 { | 75 { |
| 136 document().setBaseURLOverride(KURL(ParsedURLString, "http://test.com")); | 76 document().setBaseURLOverride(KURL(ParsedURLString, "http://test.com")); |
| 137 setBodyInnerHTML( | 77 setBodyInnerHTML( |
| 138 "<style>body { margin: 0; }</style>" | 78 "<style>body { margin: 0; }</style>" |
| 139 "<div id='container' style='overflow: scroll; width: 50px; height: 50px'
>" | 79 "<div id='container' style='overflow: scroll; width: 50px; height: 50px'
>" |
| 140 " <span><img style='width: 20px; height: 100px'></span>" | 80 " <span><img style='width: 20px; height: 100px'></span>" |
| 141 " <span id=leaf></span></div>"); | 81 " <span id=leaf></span></div>"); |
| 142 | 82 |
| 143 LayoutBlock* container = toLayoutBlock(getLayoutObjectByElementId("container
")); | 83 LayoutBlock* container = toLayoutBlock(getLayoutObjectByElementId("container
")); |
| 144 LayoutObject* leaf = container->lastChild(); | 84 LayoutObject* leaf = container->lastChild(); |
| 145 | 85 |
| 146 container->setScrollTop(LayoutUnit(50)); | 86 container->setScrollTop(LayoutUnit(50)); |
| 147 LayoutRect rect(0, 60, 20, 80); | 87 LayoutRect originalRect(0, 60, 20, 80); |
| 88 LayoutRect rect = originalRect; |
| 148 EXPECT_TRUE(leaf->mapToVisualRectInAncestorSpace(container, rect)); | 89 EXPECT_TRUE(leaf->mapToVisualRectInAncestorSpace(container, rect)); |
| 149 EXPECT_EQ(rect, LayoutRect(0, 10, 20, 80)); | 90 EXPECT_EQ(rect, LayoutRect(0, 10, 20, 80)); |
| 150 | 91 |
| 92 rect = originalRect; |
| 93 EXPECT_TRUE(leaf->mapToVisualRectInAncestorSpace(&layoutView(), rect)); |
| 94 EXPECT_EQ(rect, LayoutRect(0, 10, 20, 40)); |
| 95 checkPaintInvalidationStateRectMapping(rect, originalRect, *leaf, layoutView
(), layoutView()); |
| 96 |
| 151 rect = LayoutRect(0, 60, 80, 0); | 97 rect = LayoutRect(0, 60, 80, 0); |
| 152 EXPECT_TRUE(leaf->mapToVisualRectInAncestorSpace(container, rect, EdgeInclus
ive)); | 98 EXPECT_TRUE(leaf->mapToVisualRectInAncestorSpace(container, rect, EdgeInclus
ive)); |
| 153 EXPECT_EQ(rect, LayoutRect(0, 10, 80, 0)); | 99 EXPECT_EQ(rect, LayoutRect(0, 10, 80, 0)); |
| 154 } | 100 } |
| 155 | 101 |
| 156 TEST_F(LayoutObjectTest, LayoutViewMapToVisualRectInAncestorSpace) | 102 TEST_F(VisualRectMappingTest, LayoutView) |
| 157 { | 103 { |
| 158 document().setBaseURLOverride(KURL(ParsedURLString, "http://test.com")); | 104 document().setBaseURLOverride(KURL(ParsedURLString, "http://test.com")); |
| 159 setBodyInnerHTML( | 105 setBodyInnerHTML( |
| 160 "<style>body { margin: 0; }</style>" | 106 "<style>body { margin: 0; }</style>" |
| 161 "<div id=frameContainer>" | 107 "<div id=frameContainer>" |
| 162 " <iframe id=frame src='http://test.com' width='50' height='50' frameBo
rder='0'></iframe>" | 108 " <iframe id=frame src='http://test.com' width='50' height='50' frameBo
rder='0'></iframe>" |
| 163 "</div>"); | 109 "</div>"); |
| 164 | 110 |
| 165 Document& frameDocument = setupChildIframe("frame", "<style>body { margin: 0
; }</style><span><img style='width: 20px; height: 100px'></span>text text text")
; | 111 Document& frameDocument = setupChildIframe("frame", "<style>body { margin: 0
; }</style><span><img style='width: 20px; height: 100px'></span>text text text")
; |
| 166 frameDocument.updateLayout(); | 112 document().view()->updateAllLifecyclePhases(); |
| 167 | 113 |
| 168 LayoutBlock* frameContainer = toLayoutBlock(getLayoutObjectByElementId("fram
eContainer")); | 114 LayoutBlock* frameContainer = toLayoutBlock(getLayoutObjectByElementId("fram
eContainer")); |
| 169 LayoutBlock* frameBody = toLayoutBlock(frameDocument.body()->layoutObject())
; | 115 LayoutBlock* frameBody = toLayoutBlock(frameDocument.body()->layoutObject())
; |
| 170 LayoutText* frameText = toLayoutText(frameBody->lastChild()); | 116 LayoutText* frameText = toLayoutText(frameBody->lastChild()); |
| 171 | 117 |
| 172 // This case involves clipping: frame height is 50, y-coordinate of result r
ect is 13, | 118 // This case involves clipping: frame height is 50, y-coordinate of result r
ect is 13, |
| 173 // so height should be clipped to (50 - 13) == 37. | 119 // so height should be clipped to (50 - 13) == 37. |
| 174 frameDocument.view()->setScrollPosition(DoublePoint(0, 47), ProgrammaticScro
ll); | 120 frameDocument.view()->setScrollPosition(DoublePoint(0, 47), ProgrammaticScro
ll); |
| 175 LayoutRect rect(4, 60, 20, 80); | 121 LayoutRect originalRect(4, 60, 20, 80); |
| 122 LayoutRect rect = originalRect; |
| 176 EXPECT_TRUE(frameText->mapToVisualRectInAncestorSpace(frameContainer, rect))
; | 123 EXPECT_TRUE(frameText->mapToVisualRectInAncestorSpace(frameContainer, rect))
; |
| 177 EXPECT_EQ(rect, LayoutRect(4, 13, 20, 37)); | 124 EXPECT_EQ(rect, LayoutRect(4, 13, 20, 37)); |
| 178 | 125 |
| 126 rect = originalRect; |
| 127 EXPECT_TRUE(frameText->mapToVisualRectInAncestorSpace(&layoutView(), rect)); |
| 128 EXPECT_EQ(rect, LayoutRect(4, 13, 20, 37)); |
| 129 checkPaintInvalidationStateRectMapping(rect, originalRect, *frameText, layou
tView(), layoutView()); |
| 130 |
| 179 rect = LayoutRect(4, 60, 0, 80); | 131 rect = LayoutRect(4, 60, 0, 80); |
| 180 EXPECT_TRUE(frameText->mapToVisualRectInAncestorSpace(frameContainer, rect,
EdgeInclusive)); | 132 EXPECT_TRUE(frameText->mapToVisualRectInAncestorSpace(frameContainer, rect,
EdgeInclusive)); |
| 181 EXPECT_EQ(rect, LayoutRect(4, 13, 0, 37)); | 133 EXPECT_EQ(rect, LayoutRect(4, 13, 0, 37)); |
| 182 } | 134 } |
| 183 | 135 |
| 184 TEST_F(LayoutObjectTest, LayoutViewMapToVisualRectInAncestorSpaceSubpixelRoundin
g) | 136 TEST_F(VisualRectMappingTest, LayoutViewSubpixelRounding) |
| 185 { | 137 { |
| 186 document().setBaseURLOverride(KURL(ParsedURLString, "http://test.com")); | 138 document().setBaseURLOverride(KURL(ParsedURLString, "http://test.com")); |
| 187 setBodyInnerHTML( | 139 setBodyInnerHTML( |
| 188 "<style>body { margin: 0; }</style>" | 140 "<style>body { margin: 0; }</style>" |
| 189 "<div id=frameContainer style='position: relative; left: 0.5px'>" | 141 "<div id=frameContainer style='position: relative; left: 0.5px'>" |
| 190 " <iframe id=frame style='position: relative; left: 0.5px' src='http://
test.com' width='200' height='200' frameBorder='0'></iframe>" | 142 " <iframe id=frame style='position: relative; left: 0.5px' src='http://
test.com' width='200' height='200' frameBorder='0'></iframe>" |
| 191 "</div>"); | 143 "</div>"); |
| 192 | 144 |
| 193 Document& frameDocument = setupChildIframe( | 145 Document& frameDocument = setupChildIframe( |
| 194 "frame", "<style>body { margin: 0; }</style><div id='target' style='posi
tion: relative; width: 100px; height: 100px; left: 0.5px'>"); | 146 "frame", "<style>body { margin: 0; }</style><div id='target' style='posi
tion: relative; width: 100px; height: 100px; left: 0.5px'>"); |
| 195 frameDocument.updateLayout(); | 147 document().view()->updateAllLifecyclePhases(); |
| 196 | 148 |
| 197 LayoutBlock* frameContainer = toLayoutBlock(getLayoutObjectByElementId("fram
eContainer")); | 149 LayoutBlock* frameContainer = toLayoutBlock(getLayoutObjectByElementId("fram
eContainer")); |
| 198 LayoutObject* target = frameDocument.getElementById("target")->layoutObject(
); | 150 LayoutObject* target = frameDocument.getElementById("target")->layoutObject(
); |
| 199 LayoutRect rect(0, 0, 100, 100); | 151 LayoutRect rect(0, 0, 100, 100); |
| 200 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(frameContainer, rect)); | 152 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(frameContainer, rect)); |
| 201 // When passing from the iframe to the parent frame, the rect of (0.5, 0, 10
0, 100) is expanded to (0, 0, 100, 100), and then offset by | 153 // When passing from the iframe to the parent frame, the rect of (0.5, 0, 10
0, 100) is expanded to (0, 0, 100, 100), and then offset by |
| 202 // the 0.5 offset of frameContainer. | 154 // the 0.5 offset of frameContainer. |
| 203 EXPECT_EQ(LayoutRect(LayoutPoint(DoublePoint(0.5, 0)), LayoutSize(101, 100))
, rect); | 155 EXPECT_EQ(LayoutRect(LayoutPoint(DoublePoint(0.5, 0)), LayoutSize(101, 100))
, rect); |
| 204 } | 156 } |
| 205 | 157 |
| 206 TEST_F(LayoutObjectTest, OverflowRectMappingWithSelfFlippedWritingMode) | 158 TEST_F(VisualRectMappingTest, SelfFlippedWritingMode) |
| 207 { | 159 { |
| 208 setBodyInnerHTML( | 160 setBodyInnerHTML( |
| 209 "<div id='target' style='writing-mode: vertical-rl; box-shadow: 40px 20p
x black;" | 161 "<div id='target' style='writing-mode: vertical-rl; box-shadow: 40px 20p
x black;" |
| 210 " width: 100px; height: 50px; position: absolute; top: 111px; left: 2
22px'>" | 162 " width: 100px; height: 50px; position: absolute; top: 111px; left: 2
22px'>" |
| 211 "</div>"); | 163 "</div>"); |
| 212 | 164 |
| 213 LayoutBlock* target = toLayoutBlock(getLayoutObjectByElementId("target")); | 165 LayoutBlock* target = toLayoutBlock(getLayoutObjectByElementId("target")); |
| 214 LayoutRect overflowRect = target->localOverflowRectForPaintInvalidation(); | 166 LayoutRect overflowRect = target->localOverflowRectForPaintInvalidation(); |
| 215 // -40 = -box_shadow_offset_x(40) (with target's top-right corner as the ori
gin) | 167 // -40 = -box_shadow_offset_x(40) (with target's top-right corner as the ori
gin) |
| 216 // 140 = width(100) + box_shadow_offset_x(40) | 168 // 140 = width(100) + box_shadow_offset_x(40) |
| 217 // 70 = height(50) + box_shadow_offset_y(20) | 169 // 70 = height(50) + box_shadow_offset_y(20) |
| 218 EXPECT_EQ(LayoutRect(-40, 0, 140, 70), overflowRect); | 170 EXPECT_EQ(LayoutRect(-40, 0, 140, 70), overflowRect); |
| 219 | 171 |
| 220 LayoutRect rect = overflowRect; | 172 LayoutRect rect = overflowRect; |
| 221 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(target, rect)); | 173 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(target, rect)); |
| 222 // This rect is in physical coordinates of target. | 174 // This rect is in physical coordinates of target. |
| 223 EXPECT_EQ(LayoutRect(0, 0, 140, 70), rect); | 175 EXPECT_EQ(LayoutRect(0, 0, 140, 70), rect); |
| 224 | 176 |
| 225 rect = overflowRect; | 177 rect = overflowRect; |
| 226 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(&layoutView(), rect)); | 178 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(&layoutView(), rect)); |
| 227 EXPECT_EQ(LayoutRect(222, 111, 140, 70), rect); | 179 EXPECT_EQ(LayoutRect(222, 111, 140, 70), rect); |
| 180 checkPaintInvalidationStateRectMapping(rect, overflowRect, *target, layoutVi
ew(), layoutView()); |
| 228 } | 181 } |
| 229 | 182 |
| 230 TEST_F(LayoutObjectTest, OverflowRectMappingWithContainerFlippedWritingMode) | 183 TEST_F(VisualRectMappingTest, ContainerFlippedWritingMode) |
| 231 { | 184 { |
| 232 setBodyInnerHTML( | 185 setBodyInnerHTML( |
| 233 "<div id='container' style='writing-mode: vertical-rl; position: absolut
e; top: 111px; left: 222px'>" | 186 "<div id='container' style='writing-mode: vertical-rl; position: absolut
e; top: 111px; left: 222px'>" |
| 234 " <div id='target' style='box-shadow: 40px 20px black; width: 100px;
height: 90px'></div>" | 187 " <div id='target' style='box-shadow: 40px 20px black; width: 100px;
height: 90px'></div>" |
| 235 " <div style='width: 100px; height: 100px'></div>" | 188 " <div style='width: 100px; height: 100px'></div>" |
| 236 "</div>"); | 189 "</div>"); |
| 237 | 190 |
| 238 LayoutBlock* target = toLayoutBlock(getLayoutObjectByElementId("target")); | 191 LayoutBlock* target = toLayoutBlock(getLayoutObjectByElementId("target")); |
| 239 LayoutRect targetOverflowRect = target->localOverflowRectForPaintInvalidatio
n(); | 192 LayoutRect targetOverflowRect = target->localOverflowRectForPaintInvalidatio
n(); |
| 240 // -40 = -box_shadow_offset_x(40) (with target's top-right corner as the ori
gin) | 193 // -40 = -box_shadow_offset_x(40) (with target's top-right corner as the ori
gin) |
| 241 // 140 = width(100) + box_shadow_offset_x(40) | 194 // 140 = width(100) + box_shadow_offset_x(40) |
| 242 // 110 = height(90) + box_shadow_offset_y(20) | 195 // 110 = height(90) + box_shadow_offset_y(20) |
| 243 EXPECT_EQ(LayoutRect(-40, 0, 140, 110), targetOverflowRect); | 196 EXPECT_EQ(LayoutRect(-40, 0, 140, 110), targetOverflowRect); |
| 244 | 197 |
| 245 LayoutRect rect = targetOverflowRect; | 198 LayoutRect rect = targetOverflowRect; |
| 246 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(target, rect)); | 199 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(target, rect)); |
| 247 // This rect is in physical coordinates of target. | 200 // This rect is in physical coordinates of target. |
| 248 EXPECT_EQ(LayoutRect(0, 0, 140, 110), rect); | 201 EXPECT_EQ(LayoutRect(0, 0, 140, 110), rect); |
| 249 | 202 |
| 250 LayoutBlock* container = toLayoutBlock(getLayoutObjectByElementId("container
")); | 203 LayoutBlock* container = toLayoutBlock(getLayoutObjectByElementId("container
")); |
| 251 rect = targetOverflowRect; | 204 rect = targetOverflowRect; |
| 252 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(container, rect)); | 205 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(container, rect)); |
| 253 // 100 is the physical x location of target in container. | 206 // 100 is the physical x location of target in container. |
| 254 EXPECT_EQ(LayoutRect(100, 0, 140, 110), rect); | 207 EXPECT_EQ(LayoutRect(100, 0, 140, 110), rect); |
| 255 rect = targetOverflowRect; | 208 rect = targetOverflowRect; |
| 256 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(&layoutView(), rect)); | 209 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(&layoutView(), rect)); |
| 257 EXPECT_EQ(LayoutRect(322, 111, 140, 110), rect); | 210 EXPECT_EQ(LayoutRect(322, 111, 140, 110), rect); |
| 211 checkPaintInvalidationStateRectMapping(rect, targetOverflowRect, *target, la
youtView(), layoutView()); |
| 258 | 212 |
| 259 LayoutRect containerOverflowRect = container->localOverflowRectForPaintInval
idation(); | 213 LayoutRect containerOverflowRect = container->localOverflowRectForPaintInval
idation(); |
| 260 EXPECT_EQ(LayoutRect(-40, 0, 240, 110), containerOverflowRect); | 214 EXPECT_EQ(LayoutRect(-40, 0, 240, 110), containerOverflowRect); |
| 261 rect = containerOverflowRect; | 215 rect = containerOverflowRect; |
| 262 EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(container, rect)); | 216 EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(container, rect)); |
| 263 EXPECT_EQ(LayoutRect(0, 0, 240, 110), rect); | 217 EXPECT_EQ(LayoutRect(0, 0, 240, 110), rect); |
| 264 rect = containerOverflowRect; | 218 rect = containerOverflowRect; |
| 265 EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(&layoutView(), rect)); | 219 EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(&layoutView(), rect)); |
| 266 EXPECT_EQ(LayoutRect(222, 111, 240, 110), rect); | 220 EXPECT_EQ(LayoutRect(222, 111, 240, 110), rect); |
| 221 checkPaintInvalidationStateRectMapping(rect, containerOverflowRect, *contain
er, layoutView(), layoutView()); |
| 267 } | 222 } |
| 268 | 223 |
| 269 TEST_F(LayoutObjectTest, OverflowRectMappingWithContainerOverflowClip) | 224 TEST_F(VisualRectMappingTest, ContainerOverflowClip) |
| 270 { | 225 { |
| 271 setBodyInnerHTML( | 226 setBodyInnerHTML( |
| 272 "<div id='container' style='position: absolute; top: 111px; left: 222px;
" | 227 "<div id='container' style='position: absolute; top: 111px; left: 222px;
" |
| 273 " border: 10px solid red; overflow: hidden; width: 50px; height: 80px
;'>" | 228 " border: 10px solid red; overflow: hidden; width: 50px; height: 80px
;'>" |
| 274 " <div id='target' style='box-shadow: 40px 20px black; width: 100px;
height: 90px'></div>" | 229 " <div id='target' style='box-shadow: 40px 20px black; width: 100px;
height: 90px'></div>" |
| 275 "</div>"); | 230 "</div>"); |
| 276 | 231 |
| 277 LayoutBlock* container = toLayoutBlock(getLayoutObjectByElementId("container
")); | 232 LayoutBlock* container = toLayoutBlock(getLayoutObjectByElementId("container
")); |
| 278 EXPECT_EQ(LayoutUnit(0), container->scrollTop()); | 233 EXPECT_EQ(LayoutUnit(0), container->scrollTop()); |
| 279 EXPECT_EQ(LayoutUnit(0), container->scrollLeft()); | 234 EXPECT_EQ(LayoutUnit(0), container->scrollLeft()); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 294 // 2 = target_x(0) + container_border_left(10) - scroll_left(8) | 249 // 2 = target_x(0) + container_border_left(10) - scroll_left(8) |
| 295 // 3 = target_y(0) + container_border_top(10) - scroll_top(7) | 250 // 3 = target_y(0) + container_border_top(10) - scroll_top(7) |
| 296 // Rect is not clipped by container's overflow clip. | 251 // Rect is not clipped by container's overflow clip. |
| 297 EXPECT_EQ(LayoutRect(2, 3, 140, 110), rect); | 252 EXPECT_EQ(LayoutRect(2, 3, 140, 110), rect); |
| 298 | 253 |
| 299 rect = targetOverflowRect; | 254 rect = targetOverflowRect; |
| 300 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(&layoutView(), rect)); | 255 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(&layoutView(), rect)); |
| 301 // (2, 3, 140, 100) is first clipped by container's overflow clip, to (10, 1
0, 50, 80), | 256 // (2, 3, 140, 100) is first clipped by container's overflow clip, to (10, 1
0, 50, 80), |
| 302 // then is by added container's offset in LayoutView (111, 222). | 257 // then is by added container's offset in LayoutView (111, 222). |
| 303 EXPECT_EQ(LayoutRect(232, 121, 50, 80), rect); | 258 EXPECT_EQ(LayoutRect(232, 121, 50, 80), rect); |
| 259 checkPaintInvalidationStateRectMapping(rect, targetOverflowRect, *target, la
youtView(), layoutView()); |
| 304 | 260 |
| 305 LayoutRect containerOverflowRect = container->localOverflowRectForPaintInval
idation(); | 261 LayoutRect containerOverflowRect = container->localOverflowRectForPaintInval
idation(); |
| 306 // Because container has overflow clip, its visual overflow doesn't include
overflow from children. | 262 // Because container has overflow clip, its visual overflow doesn't include
overflow from children. |
| 307 // 70 = width(50) + border_left_width(10) + border_right_width(10) | 263 // 70 = width(50) + border_left_width(10) + border_right_width(10) |
| 308 // 100 = height(80) + border_top_width(10) + border_bottom_width(10) | 264 // 100 = height(80) + border_top_width(10) + border_bottom_width(10) |
| 309 EXPECT_EQ(LayoutRect(0, 0, 70, 100), containerOverflowRect); | 265 EXPECT_EQ(LayoutRect(0, 0, 70, 100), containerOverflowRect); |
| 310 rect = containerOverflowRect; | 266 rect = containerOverflowRect; |
| 311 EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(container, rect)); | 267 EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(container, rect)); |
| 312 // Container should not apply overflow clip on its own overflow rect. | 268 // Container should not apply overflow clip on its own overflow rect. |
| 313 EXPECT_EQ(LayoutRect(0, 0, 70, 100), rect); | 269 EXPECT_EQ(LayoutRect(0, 0, 70, 100), rect); |
| 314 | 270 |
| 315 rect = containerOverflowRect; | 271 rect = containerOverflowRect; |
| 316 EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(&layoutView(), rect)); | 272 EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(&layoutView(), rect)); |
| 317 EXPECT_EQ(LayoutRect(222, 111, 70, 100), rect); | 273 EXPECT_EQ(LayoutRect(222, 111, 70, 100), rect); |
| 274 checkPaintInvalidationStateRectMapping(rect, containerOverflowRect, *contain
er, layoutView(), layoutView()); |
| 318 } | 275 } |
| 319 | 276 |
| 320 TEST_F(LayoutObjectTest, OverflowRectMappingWithContainerFlippedWritingModeAndOv
erflowClip) | 277 TEST_F(VisualRectMappingTest, ContainerFlippedWritingModeAndOverflowClip) |
| 321 { | 278 { |
| 322 setBodyInnerHTML( | 279 setBodyInnerHTML( |
| 323 "<div id='container' style='writing-mode: vertical-rl; position: absolut
e; top: 111px; left: 222px;" | 280 "<div id='container' style='writing-mode: vertical-rl; position: absolut
e; top: 111px; left: 222px;" |
| 324 " border: solid red; border-width: 10px 20px 30px 40px;" | 281 " border: solid red; border-width: 10px 20px 30px 40px;" |
| 325 " overflow: hidden; width: 50px; height: 80px'>" | 282 " overflow: hidden; width: 50px; height: 80px'>" |
| 326 " <div id='target' style='box-shadow: 40px 20px black; width: 100px;
height: 90px'></div>" | 283 " <div id='target' style='box-shadow: 40px 20px black; width: 100px;
height: 90px'></div>" |
| 327 " <div style='width: 100px; height: 100px'></div>" | 284 " <div style='width: 100px; height: 100px'></div>" |
| 328 "</div>"); | 285 "</div>"); |
| 329 | 286 |
| 330 LayoutBlock* container = toLayoutBlock(getLayoutObjectByElementId("container
")); | 287 LayoutBlock* container = toLayoutBlock(getLayoutObjectByElementId("container
")); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 354 // Rect is not clipped by container's overflow clip. | 311 // Rect is not clipped by container's overflow clip. |
| 355 EXPECT_EQ(LayoutRect(-2, 3, 140, 110), rect); | 312 EXPECT_EQ(LayoutRect(-2, 3, 140, 110), rect); |
| 356 | 313 |
| 357 rect = targetOverflowRect; | 314 rect = targetOverflowRect; |
| 358 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(&layoutView(), rect)); | 315 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(&layoutView(), rect)); |
| 359 // (-2, 3, 140, 100) is first clipped by container's overflow clip, to (40,
10, 50, 80), | 316 // (-2, 3, 140, 100) is first clipped by container's overflow clip, to (40,
10, 50, 80), |
| 360 // then is added by container's offset in LayoutView (111, 222). | 317 // then is added by container's offset in LayoutView (111, 222). |
| 361 // TODO(crbug.com/600039): rect.x() should be 262 (left + border-left), but
is offset | 318 // TODO(crbug.com/600039): rect.x() should be 262 (left + border-left), but
is offset |
| 362 // by extra horizontal border-widths because of layout error. | 319 // by extra horizontal border-widths because of layout error. |
| 363 EXPECT_EQ(LayoutRect(322, 121, 50, 80), rect); | 320 EXPECT_EQ(LayoutRect(322, 121, 50, 80), rect); |
| 321 checkPaintInvalidationStateRectMapping(rect, targetOverflowRect, *target, la
youtView(), layoutView()); |
| 364 | 322 |
| 365 LayoutRect containerOverflowRect = container->localOverflowRectForPaintInval
idation(); | 323 LayoutRect containerOverflowRect = container->localOverflowRectForPaintInval
idation(); |
| 366 // Because container has overflow clip, its visual overflow doesn't include
overflow from children. | 324 // Because container has overflow clip, its visual overflow doesn't include
overflow from children. |
| 367 // 110 = width(50) + border_left_width(40) + border_right_width(20) | 325 // 110 = width(50) + border_left_width(40) + border_right_width(20) |
| 368 // 120 = height(80) + border_top_width(10) + border_bottom_width(30) | 326 // 120 = height(80) + border_top_width(10) + border_bottom_width(30) |
| 369 EXPECT_EQ(LayoutRect(0, 0, 110, 120), containerOverflowRect); | 327 EXPECT_EQ(LayoutRect(0, 0, 110, 120), containerOverflowRect); |
| 370 | 328 |
| 371 rect = containerOverflowRect; | 329 rect = containerOverflowRect; |
| 372 EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(container, rect)); | 330 EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(container, rect)); |
| 373 EXPECT_EQ(LayoutRect(0, 0, 110, 120), rect); | 331 EXPECT_EQ(LayoutRect(0, 0, 110, 120), rect); |
| 374 | 332 |
| 375 rect = containerOverflowRect; | 333 rect = containerOverflowRect; |
| 376 EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(&layoutView(), rect)); | 334 EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(&layoutView(), rect)); |
| 377 // TODO(crbug.com/600039): rect.x() should be 222 (left), but is offset by e
xtra horizontal | 335 // TODO(crbug.com/600039): rect.x() should be 222 (left), but is offset by e
xtra horizontal |
| 378 // border-widths because of layout error. | 336 // border-widths because of layout error. |
| 379 EXPECT_EQ(LayoutRect(282, 111, 110, 120), rect); | 337 EXPECT_EQ(LayoutRect(282, 111, 110, 120), rect); |
| 338 checkPaintInvalidationStateRectMapping(rect, containerOverflowRect, *contain
er, layoutView(), layoutView()); |
| 380 } | 339 } |
| 381 | 340 |
| 382 } // namespace blink | 341 } // namespace blink |
| OLD | NEW |