OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/ng/ng_block_layout_algorithm.h" | 5 #include "core/layout/ng/ng_block_layout_algorithm.h" |
6 | 6 |
7 #include "core/dom/NodeComputedStyle.h" | 7 #include "core/dom/NodeComputedStyle.h" |
8 #include "core/dom/TagCollection.h" | 8 #include "core/dom/TagCollection.h" |
9 #include "core/layout/LayoutTestHelper.h" | 9 #include "core/layout/LayoutTestHelper.h" |
10 #include "core/layout/ng/layout_ng_block_flow.h" | 10 #include "core/layout/ng/layout_ng_block_flow.h" |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 ASSERT_EQ(1UL, body_fragment->Children().size()); | 226 ASSERT_EQ(1UL, body_fragment->Children().size()); |
227 auto* container_fragment = | 227 auto* container_fragment = |
228 toNGPhysicalBoxFragment(body_fragment->Children()[0].get()); | 228 toNGPhysicalBoxFragment(body_fragment->Children()[0].get()); |
229 // 0 = collapsed with body's margin | 229 // 0 = collapsed with body's margin |
230 EXPECT_THAT(LayoutUnit(0), container_fragment->TopOffset()); | 230 EXPECT_THAT(LayoutUnit(0), container_fragment->TopOffset()); |
231 ASSERT_EQ(1UL, container_fragment->Children().size()); | 231 ASSERT_EQ(1UL, container_fragment->Children().size()); |
232 auto* first_child_fragment = | 232 auto* first_child_fragment = |
233 toNGPhysicalBoxFragment(container_fragment->Children()[0].get()); | 233 toNGPhysicalBoxFragment(container_fragment->Children()[0].get()); |
234 // 0 = collapsed with container's margin | 234 // 0 = collapsed with container's margin |
235 EXPECT_THAT(LayoutUnit(0), first_child_fragment->TopOffset()); | 235 EXPECT_THAT(LayoutUnit(0), first_child_fragment->TopOffset()); |
236 | |
237 // ** Verify layout tree ** | |
238 Element* first_child = document().getElementById("first-child"); | |
239 int first_child_block_offset = body_top_offset; | |
240 EXPECT_EQ(first_child_block_offset, first_child->offsetTop()); | |
241 | |
242 // float-child-left is positioned at the top edge of the container padding box | |
243 Element* float_child_left = document().getElementById("float-child-left"); | |
244 // 30 = std::max(first-child's margin 20, container's margin 10, | |
245 // body's margin 8) + float-child-left's margin 10 | |
246 int float_child_left_block_offset = 30; | |
247 EXPECT_EQ(float_child_left_block_offset, float_child_left->offsetTop()); | |
248 | |
249 // float-child-right is positioned at the top edge of container padding box | |
250 Element* float_child_right = document().getElementById("float-child-right"); | |
251 // Should be equal to first_child_block_offset | |
252 // 20 = std::max(first-child's margin 20, container's margin 10, | |
253 // body's margin 8) | |
254 int float_child_right_block_offset = 20; | |
255 EXPECT_EQ(float_child_right_block_offset, float_child_right->offsetTop()); | |
256 | |
257 // ** Verify exclusions ** | |
258 // float-child-left's height(10) + padding(2x10) + margin(2x10) = 50px | |
259 NGLogicalSize exclusion1_size = {LayoutUnit(50), LayoutUnit(50)}; | |
260 // float-child-left's inline offset | |
261 // 15 = body's margin(8) + container's inline padding(7) | |
262 NGLogicalOffset exclusion1_offset = {LayoutUnit(15), | |
263 LayoutUnit(first_child_block_offset)}; | |
264 NGLogicalRect exclusion1_rect = {exclusion1_offset, exclusion1_size}; | |
265 NGExclusion expected_exclusion1 = {exclusion1_rect, NGExclusion::kFloatLeft}; | |
266 | |
267 NGLogicalSize exclusion2_size = {LayoutUnit(30), LayoutUnit(30)}; | |
268 // float-child-right's inline offset | |
269 // right_float_offset = 200 container's width - right float width 30 = 170 | |
270 // 185 = body's margin(8) + right_float_offset(170) + container's padding(7) | |
271 NGLogicalOffset exclusion2_offset = {LayoutUnit(185), | |
272 LayoutUnit(first_child_block_offset)}; | |
273 NGLogicalRect exclusion2_rect = {exclusion2_offset, exclusion2_size}; | |
274 NGExclusion expected_exclusion2 = {exclusion2_rect, NGExclusion::kFloatRight}; | |
275 | |
276 EXPECT_THAT(space->Exclusions()->storage, | |
277 (ElementsAre(Pointee(expected_exclusion1), | |
278 Pointee(expected_exclusion2)))); | |
279 } | 236 } |
280 | 237 |
281 // Verifies the collapsing margins case for the next pairs: | 238 // Verifies the collapsing margins case for the next pairs: |
282 // - bottom margin of box and top margin of its next in-flow following sibling. | 239 // - bottom margin of box and top margin of its next in-flow following sibling. |
283 // - top and bottom margins of a box that does not establish a new block | 240 // - top and bottom margins of a box that does not establish a new block |
284 // formatting context and that has zero computed 'min-height', zero or 'auto' | 241 // formatting context and that has zero computed 'min-height', zero or 'auto' |
285 // computed 'height', and no in-flow children | 242 // computed 'height', and no in-flow children |
286 TEST_F(NGBlockLayoutAlgorithmTest, CollapsingMarginsCase2WithFloats) { | 243 TEST_F(NGBlockLayoutAlgorithmTest, CollapsingMarginsCase2WithFloats) { |
287 setBodyInnerHTML(R"HTML( | 244 setBodyInnerHTML(R"HTML( |
288 <style> | 245 <style> |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
332 // ** Run LayoutNG algorithm ** | 289 // ** Run LayoutNG algorithm ** |
333 RefPtr<NGConstraintSpace> space; | 290 RefPtr<NGConstraintSpace> space; |
334 RefPtr<NGPhysicalBoxFragment> fragment; | 291 RefPtr<NGPhysicalBoxFragment> fragment; |
335 std::tie(fragment, space) = RunBlockLayoutAlgorithmForElement( | 292 std::tie(fragment, space) = RunBlockLayoutAlgorithmForElement( |
336 document().getElementsByTagName("html")->item(0)); | 293 document().getElementsByTagName("html")->item(0)); |
337 | 294 |
338 auto* body_fragment = toNGPhysicalBoxFragment(fragment->Children()[0].get()); | 295 auto* body_fragment = toNGPhysicalBoxFragment(fragment->Children()[0].get()); |
339 // -7 = empty1's margin(-15) + body's margin(8) | 296 // -7 = empty1's margin(-15) + body's margin(8) |
340 int body_top_offset = -7; | 297 int body_top_offset = -7; |
341 EXPECT_THAT(LayoutUnit(body_top_offset), body_fragment->TopOffset()); | 298 EXPECT_THAT(LayoutUnit(body_top_offset), body_fragment->TopOffset()); |
342 int body_left_offset = 8; | |
343 EXPECT_THAT(LayoutUnit(body_top_offset), body_fragment->TopOffset()); | 299 EXPECT_THAT(LayoutUnit(body_top_offset), body_fragment->TopOffset()); |
344 ASSERT_EQ(3UL, body_fragment->Children().size()); | 300 ASSERT_EQ(3UL, body_fragment->Children().size()); |
345 | 301 |
346 auto* first_child_fragment = | 302 auto* first_child_fragment = |
347 toNGPhysicalBoxFragment(body_fragment->Children()[0].get()); | 303 toNGPhysicalBoxFragment(body_fragment->Children()[0].get()); |
348 EXPECT_THAT(LayoutUnit(), first_child_fragment->TopOffset()); | 304 EXPECT_THAT(LayoutUnit(), first_child_fragment->TopOffset()); |
349 | 305 |
350 auto* second_child_fragment = | 306 auto* second_child_fragment = |
351 toNGPhysicalBoxFragment(body_fragment->Children()[1].get()); | 307 toNGPhysicalBoxFragment(body_fragment->Children()[1].get()); |
352 // 40 = first_child's height(50) - margin's collapsing result(10) | 308 // 40 = first_child's height(50) - margin's collapsing result(10) |
(...skipping 14 matching lines...) Expand all Loading... |
367 auto float_nonempties_fragment = | 323 auto float_nonempties_fragment = |
368 body_fragment->PositionedFloats().at(0)->fragment; | 324 body_fragment->PositionedFloats().at(0)->fragment; |
369 // 70 = first_child's height(50) + first child's margin-bottom(20) | 325 // 70 = first_child's height(50) + first child's margin-bottom(20) |
370 EXPECT_THAT(LayoutUnit(70), float_nonempties_fragment->TopOffset()); | 326 EXPECT_THAT(LayoutUnit(70), float_nonempties_fragment->TopOffset()); |
371 EXPECT_THAT(LayoutUnit(0), float_nonempties_fragment->LeftOffset()); | 327 EXPECT_THAT(LayoutUnit(0), float_nonempties_fragment->LeftOffset()); |
372 | 328 |
373 // ** Verify layout tree ** | 329 // ** Verify layout tree ** |
374 Element* first_child = document().getElementById("first-child"); | 330 Element* first_child = document().getElementById("first-child"); |
375 // -7 = body_top_offset | 331 // -7 = body_top_offset |
376 EXPECT_EQ(body_top_offset, first_child->offsetTop()); | 332 EXPECT_EQ(body_top_offset, first_child->offsetTop()); |
377 | |
378 NGLogicalSize float_empties_exclusion_size = {LayoutUnit(30), LayoutUnit(30)}; | |
379 NGLogicalOffset float_empties_exclusion_offset = { | |
380 LayoutUnit(body_left_offset), LayoutUnit(body_top_offset)}; | |
381 NGLogicalRect float_empties_exclusion_rect = {float_empties_exclusion_offset, | |
382 float_empties_exclusion_size}; | |
383 NGExclusion float_empties_exclusion = {float_empties_exclusion_rect, | |
384 NGExclusion::kFloatLeft}; | |
385 | |
386 NGLogicalSize float_nonempties_exclusion_size = {LayoutUnit(40), | |
387 LayoutUnit(40)}; | |
388 // 63 = first_child_margin_strut(20) + first-child's height(50) + | |
389 // body_top_offset(-7) | |
390 NGLogicalOffset float_nonempties_exclusion_offset = { | |
391 LayoutUnit(body_left_offset), LayoutUnit(63)}; | |
392 NGLogicalRect float_nonempties_exclusion_rect = { | |
393 float_nonempties_exclusion_offset, float_nonempties_exclusion_size}; | |
394 NGExclusion float_nonempties_exclusion = {float_nonempties_exclusion_rect, | |
395 NGExclusion::kFloatLeft}; | |
396 | |
397 NGLogicalSize float_top_align_exclusion_size = {LayoutUnit(50), | |
398 LayoutUnit(50)}; | |
399 // 63 = float_nonempties_exclusion_offset because of the top edge alignment | |
400 // rule. | |
401 // 48 = body's margin + float_nonempties_exclusion_size | |
402 NGLogicalOffset float_top_align_exclusion_offset = {LayoutUnit(48), | |
403 LayoutUnit(63)}; | |
404 NGLogicalRect float_top_align_exclusion_rect = { | |
405 float_top_align_exclusion_offset, float_top_align_exclusion_size}; | |
406 NGExclusion float_top_align_exclusion = {float_top_align_exclusion_rect, | |
407 NGExclusion::kFloatLeft}; | |
408 | |
409 EXPECT_THAT(space->Exclusions()->storage, | |
410 (ElementsAre(Pointee(float_empties_exclusion), | |
411 Pointee(float_nonempties_exclusion), | |
412 Pointee(float_top_align_exclusion)))); | |
413 } | 333 } |
414 | 334 |
415 // Verifies the collapsing margins case for the next pair: | 335 // Verifies the collapsing margins case for the next pair: |
416 // - bottom margin of a last in-flow child and bottom margin of its parent if | 336 // - bottom margin of a last in-flow child and bottom margin of its parent if |
417 // the parent has 'auto' computed height | 337 // the parent has 'auto' computed height |
418 TEST_F(NGBlockLayoutAlgorithmTest, CollapsingMarginsCase3) { | 338 TEST_F(NGBlockLayoutAlgorithmTest, CollapsingMarginsCase3) { |
419 setBodyInnerHTML(R"HTML( | 339 setBodyInnerHTML(R"HTML( |
420 <style> | 340 <style> |
421 #container { | 341 #container { |
422 margin-bottom: 20px; | 342 margin-bottom: 20px; |
(...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1038 EXPECT_EQ(left_float_with_margin_block_offset, | 958 EXPECT_EQ(left_float_with_margin_block_offset, |
1039 left_float_with_margin->offsetTop()); | 959 left_float_with_margin->offsetTop()); |
1040 auto left_float_with_margin_fragment = | 960 auto left_float_with_margin_fragment = |
1041 container_fragment->PositionedFloats().at(3)->fragment; | 961 container_fragment->PositionedFloats().at(3)->fragment; |
1042 // 70 = left_float_with_margin_block_offset(78) - body's margin(8) | 962 // 70 = left_float_with_margin_block_offset(78) - body's margin(8) |
1043 EXPECT_THAT(LayoutUnit(left_float_with_margin_block_offset - 8), | 963 EXPECT_THAT(LayoutUnit(left_float_with_margin_block_offset - 8), |
1044 left_float_with_margin_fragment->TopOffset()); | 964 left_float_with_margin_fragment->TopOffset()); |
1045 // 10 = left_float_with_margin_inline_offset(18) - body's margin(8) | 965 // 10 = left_float_with_margin_inline_offset(18) - body's margin(8) |
1046 EXPECT_THAT(LayoutUnit(left_float_with_margin_inline_offset - 8), | 966 EXPECT_THAT(LayoutUnit(left_float_with_margin_inline_offset - 8), |
1047 left_float_with_margin_fragment->LeftOffset()); | 967 left_float_with_margin_fragment->LeftOffset()); |
1048 | |
1049 // ** Verify exclusions ** | |
1050 NGLogicalSize left_float_exclusion_size = {LayoutUnit(30), LayoutUnit(30)}; | |
1051 // this should be equal to body's margin(8) | |
1052 NGLogicalOffset left_float_exclusion_offset = {LayoutUnit(8), LayoutUnit(8)}; | |
1053 NGLogicalRect left_float_exclusion_rect = {left_float_exclusion_offset, | |
1054 left_float_exclusion_size}; | |
1055 NGExclusion left_float_exclusion = {left_float_exclusion_rect, | |
1056 NGExclusion::kFloatLeft}; | |
1057 | |
1058 NGLogicalSize left_wide_exclusion_size = {LayoutUnit(180), LayoutUnit(30)}; | |
1059 NGLogicalOffset left_wide_exclusion_offset = { | |
1060 LayoutUnit(8), LayoutUnit(left_wide_float_block_offset)}; | |
1061 NGLogicalRect left_wide_exclusion_rect = {left_wide_exclusion_offset, | |
1062 left_wide_exclusion_size}; | |
1063 NGExclusion left_wide_exclusion = {left_wide_exclusion_rect, | |
1064 NGExclusion::kFloatLeft}; | |
1065 | |
1066 NGLogicalSize right_float_exclusion_size = {LayoutUnit(50), LayoutUnit(50)}; | |
1067 NGLogicalOffset right_float_exclusion_offset = { | |
1068 LayoutUnit(right_float_inline_offset), | |
1069 LayoutUnit(right_float_block_offset)}; | |
1070 NGLogicalRect right_float_exclusion_rect = {right_float_exclusion_offset, | |
1071 right_float_exclusion_size}; | |
1072 NGExclusion right_float_exclusion = {right_float_exclusion_rect, | |
1073 NGExclusion::kFloatRight}; | |
1074 | |
1075 // left-float-with-margin's size(120) + margin(2x10) | |
1076 NGLogicalSize left_float_with_margin_exclusion_size = {LayoutUnit(140), | |
1077 LayoutUnit(140)}; | |
1078 // Exclusion starts from the right_float_block_offset position. | |
1079 NGLogicalOffset left_float_with_margin_exclusion_offset = { | |
1080 LayoutUnit(8), LayoutUnit(right_float_block_offset)}; | |
1081 NGLogicalRect left_float_with_margin_exclusion_rect = { | |
1082 left_float_with_margin_exclusion_offset, | |
1083 left_float_with_margin_exclusion_size}; | |
1084 NGExclusion left_float_with_margin_exclusion = { | |
1085 left_float_with_margin_exclusion_rect, NGExclusion::kFloatLeft}; | |
1086 | |
1087 EXPECT_THAT( | |
1088 space->Exclusions()->storage, | |
1089 (ElementsAre(Pointee(left_float_exclusion), Pointee(left_wide_exclusion), | |
1090 Pointee(right_float_exclusion), | |
1091 Pointee(left_float_with_margin_exclusion)))); | |
1092 } | 968 } |
1093 | 969 |
1094 // Verifies that NG block layout algorithm respects "clear" CSS property. | 970 // Verifies that NG block layout algorithm respects "clear" CSS property. |
1095 TEST_F(NGBlockLayoutAlgorithmTest, PositionFragmentsWithClear) { | 971 TEST_F(NGBlockLayoutAlgorithmTest, PositionFragmentsWithClear) { |
1096 setBodyInnerHTML(R"HTML( | 972 setBodyInnerHTML(R"HTML( |
1097 <style> | 973 <style> |
1098 #container { | 974 #container { |
1099 height: 200px; | 975 height: 200px; |
1100 width: 200px; | 976 width: 200px; |
1101 } | 977 } |
(...skipping 1231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2333 | 2209 |
2334 child = iterator.NextChild(); | 2210 child = iterator.NextChild(); |
2335 EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(100)), child->Size()); | 2211 EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(100)), child->Size()); |
2336 EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(40)), child->Offset()); | 2212 EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(40)), child->Offset()); |
2337 | 2213 |
2338 EXPECT_FALSE(iterator.NextChild()); | 2214 EXPECT_FALSE(iterator.NextChild()); |
2339 } | 2215 } |
2340 | 2216 |
2341 } // namespace | 2217 } // namespace |
2342 } // namespace blink | 2218 } // namespace blink |
OLD | NEW |