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/layout/ng/ng_block_node.h" | 7 #include "core/layout/ng/ng_block_node.h" |
8 #include "core/layout/ng/ng_constraint_space.h" | 8 #include "core/layout/ng/ng_constraint_space.h" |
9 #include "core/layout/ng/ng_constraint_space_builder.h" | 9 #include "core/layout/ng/ng_constraint_space_builder.h" |
10 #include "core/layout/ng/ng_layout_coordinator.h" | 10 #include "core/layout/ng/ng_layout_coordinator.h" |
(...skipping 829 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
840 first_child->SetNextSibling(second_child); | 840 first_child->SetNextSibling(second_child); |
841 | 841 |
842 auto* space = ConstructConstraintSpace( | 842 auto* space = ConstructConstraintSpace( |
843 kHorizontalTopBottom, TextDirection::kLtr, | 843 kHorizontalTopBottom, TextDirection::kLtr, |
844 NGLogicalSize(LayoutUnit(100), NGSizeIndefinite), true); | 844 NGLogicalSize(LayoutUnit(100), NGSizeIndefinite), true); |
845 NGPhysicalFragment* frag = RunBlockLayoutAlgorithm(space, first_child); | 845 NGPhysicalFragment* frag = RunBlockLayoutAlgorithm(space, first_child); |
846 | 846 |
847 EXPECT_EQ(LayoutUnit(30), frag->Width()); | 847 EXPECT_EQ(LayoutUnit(30), frag->Width()); |
848 } | 848 } |
849 | 849 |
850 class FragmentChildIterator | |
eae
2017/01/12 23:36:23
This class seem pretty useful, perhaps move out of
mstensho (USE GERRIT)
2017/01/13 14:30:18
Are you suggesting that I move it out to a separat
| |
851 : public GarbageCollectedFinalized<FragmentChildIterator> { | |
852 public: | |
853 FragmentChildIterator() {} | |
854 FragmentChildIterator(const NGPhysicalBoxFragment* parent) { | |
855 SetParent(parent); | |
856 } | |
857 void SetParent(const NGPhysicalBoxFragment* parent) { | |
858 parent_ = parent; | |
859 index_ = 0; | |
860 } | |
861 | |
862 const NGPhysicalBoxFragment* NextChild() { | |
863 if (!parent_) | |
864 return nullptr; | |
865 if (index_ >= parent_->Children().size()) | |
866 return nullptr; | |
867 while (parent_->Children()[index_]->Type() != | |
868 NGPhysicalFragment::kFragmentBox) { | |
869 ++index_; | |
870 if (index_ >= parent_->Children().size()) | |
871 return nullptr; | |
872 } | |
873 return toNGPhysicalBoxFragment(parent_->Children()[index_++]); | |
874 } | |
875 | |
876 DEFINE_INLINE_TRACE() { visitor->trace(parent_); } | |
877 | |
878 private: | |
879 Member<const NGPhysicalBoxFragment> parent_; | |
880 unsigned index_; | |
881 }; | |
882 | |
883 // Test case's HTML representation: | |
884 // <div id="parent" style="columns:2; column-fill:auto; column-gap:10px; | |
885 // width:210px; height:100px;"> | |
886 // </div> | |
887 TEST_F(NGBlockLayoutAlgorithmTest, EmptyMulticol) { | |
888 // parent | |
889 RefPtr<ComputedStyle> parent_style = ComputedStyle::create(); | |
890 parent_style->setColumnCount(2); | |
891 parent_style->setColumnFill(ColumnFillAuto); | |
892 parent_style->setColumnGap(10); | |
893 parent_style->setHeight(Length(100, Fixed)); | |
894 parent_style->setWidth(Length(210, Fixed)); | |
895 NGBlockNode* parent = new NGBlockNode(parent_style.get()); | |
896 | |
897 auto* space = ConstructConstraintSpace( | |
898 kHorizontalTopBottom, TextDirection::kLtr, | |
899 NGLogicalSize(LayoutUnit(1000), NGSizeIndefinite)); | |
900 const auto* fragment = RunBlockLayoutAlgorithm(space, parent); | |
901 FragmentChildIterator iterator(fragment); | |
902 fragment = iterator.NextChild(); | |
903 ASSERT_TRUE(fragment); | |
904 EXPECT_EQ(LayoutUnit(210), fragment->Width()); | |
905 EXPECT_EQ(LayoutUnit(100), fragment->Height()); | |
906 EXPECT_FALSE(iterator.NextChild()); | |
907 | |
908 // There should be nothing inside the multicol container. | |
909 EXPECT_FALSE(FragmentChildIterator(fragment).NextChild()); | |
910 } | |
911 | |
912 // Test case's HTML representation: | |
913 // <div id="parent" style="columns:2; column-fill:auto; column-gap:10px; | |
914 // width:210px; height:100px;"> | |
915 // <div id="child"></div> | |
916 // </div> | |
917 TEST_F(NGBlockLayoutAlgorithmTest, EmptyBlock) { | |
918 // parent | |
919 RefPtr<ComputedStyle> parent_style = ComputedStyle::create(); | |
920 parent_style->setColumnCount(2); | |
921 parent_style->setColumnFill(ColumnFillAuto); | |
922 parent_style->setColumnGap(10); | |
923 parent_style->setHeight(Length(100, Fixed)); | |
924 parent_style->setWidth(Length(210, Fixed)); | |
925 NGBlockNode* parent = new NGBlockNode(parent_style.get()); | |
926 | |
927 // child | |
928 RefPtr<ComputedStyle> child_style = ComputedStyle::create(); | |
929 NGBlockNode* child = new NGBlockNode(child_style.get()); | |
930 | |
931 parent->SetFirstChild(child); | |
932 | |
933 auto* space = ConstructConstraintSpace( | |
934 kHorizontalTopBottom, TextDirection::kLtr, | |
935 NGLogicalSize(LayoutUnit(1000), NGSizeIndefinite)); | |
936 const auto* fragment = RunBlockLayoutAlgorithm(space, parent); | |
937 FragmentChildIterator iterator(fragment); | |
938 fragment = iterator.NextChild(); | |
939 EXPECT_EQ(LayoutUnit(210), fragment->Width()); | |
940 EXPECT_EQ(LayoutUnit(100), fragment->Height()); | |
941 ASSERT_TRUE(fragment); | |
942 EXPECT_FALSE(iterator.NextChild()); | |
943 iterator.SetParent(fragment); | |
944 | |
945 // #child fragment in first column | |
946 fragment = iterator.NextChild(); | |
947 ASSERT_TRUE(fragment); | |
948 EXPECT_EQ(LayoutUnit(), fragment->LeftOffset()); | |
949 EXPECT_EQ(LayoutUnit(), fragment->TopOffset()); | |
950 EXPECT_EQ(LayoutUnit(100), fragment->Width()); | |
951 EXPECT_EQ(LayoutUnit(), fragment->Height()); | |
952 EXPECT_EQ(0UL, fragment->Children().size()); | |
953 EXPECT_FALSE(iterator.NextChild()); | |
954 } | |
955 | |
956 // Test case's HTML representation: | |
957 // <div id="parent" style="columns:2; column-fill:auto; column-gap:10px; | |
958 // width:310px; height:100px;"> | |
959 // <div id="child" style="width:60%; height:100px;"></div> | |
960 // </div> | |
961 TEST_F(NGBlockLayoutAlgorithmTest, BlockInOneColumn) { | |
962 // parent | |
963 RefPtr<ComputedStyle> parent_style = ComputedStyle::create(); | |
964 parent_style->setColumnCount(2); | |
965 parent_style->setColumnFill(ColumnFillAuto); | |
966 parent_style->setColumnGap(10); | |
967 parent_style->setHeight(Length(100, Fixed)); | |
968 parent_style->setWidth(Length(310, Fixed)); | |
969 NGBlockNode* parent = new NGBlockNode(parent_style.get()); | |
970 | |
971 // child | |
972 RefPtr<ComputedStyle> child_style = ComputedStyle::create(); | |
973 child_style->setWidth(Length(60, Percent)); | |
974 child_style->setHeight(Length(100, Fixed)); | |
975 NGBlockNode* child = new NGBlockNode(child_style.get()); | |
976 | |
977 parent->SetFirstChild(child); | |
978 | |
979 auto* space = ConstructConstraintSpace( | |
980 kHorizontalTopBottom, TextDirection::kLtr, | |
981 NGLogicalSize(LayoutUnit(1000), NGSizeIndefinite)); | |
982 const auto* fragment = RunBlockLayoutAlgorithm(space, parent); | |
983 | |
984 FragmentChildIterator iterator(fragment); | |
985 fragment = iterator.NextChild(); | |
986 ASSERT_TRUE(fragment); | |
987 EXPECT_EQ(LayoutUnit(310), fragment->Width()); | |
988 EXPECT_EQ(LayoutUnit(100), fragment->Height()); | |
989 EXPECT_FALSE(iterator.NextChild()); | |
990 iterator.SetParent(fragment); | |
991 | |
992 // #child fragment in first column | |
993 fragment = iterator.NextChild(); | |
994 ASSERT_TRUE(fragment); | |
995 EXPECT_EQ(LayoutUnit(), fragment->LeftOffset()); | |
996 EXPECT_EQ(LayoutUnit(), fragment->TopOffset()); | |
997 EXPECT_EQ(LayoutUnit(90), fragment->Width()); | |
998 EXPECT_EQ(LayoutUnit(100), fragment->Height()); | |
999 EXPECT_EQ(0UL, fragment->Children().size()); | |
1000 EXPECT_FALSE(iterator.NextChild()); | |
1001 } | |
1002 | |
1003 // Test case's HTML representation: | |
1004 // <div id="parent" style="columns:2; column-fill:auto; column-gap:10px; | |
1005 // width:210px; height:100px;"> | |
1006 // <div id="child" style="width:75%; height:150px;"></div> | |
1007 // </div> | |
1008 TEST_F(NGBlockLayoutAlgorithmTest, BlockInTwoColumns) { | |
1009 // parent | |
1010 RefPtr<ComputedStyle> parent_style = ComputedStyle::create(); | |
1011 parent_style->setColumnCount(2); | |
1012 parent_style->setColumnFill(ColumnFillAuto); | |
1013 parent_style->setColumnGap(10); | |
1014 parent_style->setHeight(Length(100, Fixed)); | |
1015 parent_style->setWidth(Length(210, Fixed)); | |
1016 NGBlockNode* parent = new NGBlockNode(parent_style.get()); | |
1017 | |
1018 // child | |
1019 RefPtr<ComputedStyle> child_style = ComputedStyle::create(); | |
1020 child_style->setWidth(Length(75, Percent)); | |
1021 child_style->setHeight(Length(150, Fixed)); | |
1022 NGBlockNode* child = new NGBlockNode(child_style.get()); | |
1023 | |
1024 parent->SetFirstChild(child); | |
1025 | |
1026 auto* space = ConstructConstraintSpace( | |
1027 kHorizontalTopBottom, TextDirection::kLtr, | |
1028 NGLogicalSize(LayoutUnit(1000), NGSizeIndefinite)); | |
1029 const auto* fragment = RunBlockLayoutAlgorithm(space, parent); | |
1030 | |
1031 FragmentChildIterator iterator(fragment); | |
1032 fragment = iterator.NextChild(); | |
1033 ASSERT_TRUE(fragment); | |
1034 EXPECT_EQ(LayoutUnit(210), fragment->Width()); | |
1035 EXPECT_EQ(LayoutUnit(100), fragment->Height()); | |
1036 EXPECT_FALSE(iterator.NextChild()); | |
1037 | |
1038 iterator.SetParent(fragment); | |
1039 // #child fragment in first column | |
1040 fragment = iterator.NextChild(); | |
1041 ASSERT_TRUE(fragment); | |
1042 EXPECT_EQ(LayoutUnit(), fragment->LeftOffset()); | |
1043 EXPECT_EQ(LayoutUnit(), fragment->TopOffset()); | |
1044 EXPECT_EQ(LayoutUnit(75), fragment->Width()); | |
1045 EXPECT_EQ(LayoutUnit(100), fragment->Height()); | |
1046 EXPECT_EQ(0UL, fragment->Children().size()); | |
1047 | |
1048 // #child fragment in second column | |
1049 fragment = iterator.NextChild(); | |
1050 ASSERT_TRUE(fragment); | |
1051 EXPECT_EQ(LayoutUnit(110), fragment->LeftOffset()); | |
1052 EXPECT_EQ(LayoutUnit(), fragment->TopOffset()); | |
1053 EXPECT_EQ(LayoutUnit(75), fragment->Width()); | |
1054 EXPECT_EQ(LayoutUnit(50), fragment->Height()); | |
1055 EXPECT_EQ(0U, fragment->Children().size()); | |
1056 EXPECT_FALSE(iterator.NextChild()); | |
1057 } | |
1058 | |
1059 // Test case's HTML representation: | |
1060 // <div id="parent" style="columns:3; column-fill:auto; column-gap:10px; | |
1061 // width:320px; height:100px;"> | |
1062 // <div id="child" style="width:75%; height:250px;"></div> | |
1063 // </div> | |
1064 TEST_F(NGBlockLayoutAlgorithmTest, BlockInThreeColumns) { | |
1065 // parent | |
1066 RefPtr<ComputedStyle> parent_style = ComputedStyle::create(); | |
1067 parent_style->setColumnCount(3); | |
1068 parent_style->setColumnFill(ColumnFillAuto); | |
1069 parent_style->setColumnGap(10); | |
1070 parent_style->setHeight(Length(100, Fixed)); | |
1071 parent_style->setWidth(Length(320, Fixed)); | |
1072 NGBlockNode* parent = new NGBlockNode(parent_style.get()); | |
1073 | |
1074 // child | |
1075 RefPtr<ComputedStyle> child_style = ComputedStyle::create(); | |
1076 child_style->setWidth(Length(75, Percent)); | |
1077 child_style->setHeight(Length(250, Fixed)); | |
1078 NGBlockNode* child = new NGBlockNode(child_style.get()); | |
1079 | |
1080 parent->SetFirstChild(child); | |
1081 | |
1082 auto* space = ConstructConstraintSpace( | |
1083 kHorizontalTopBottom, TextDirection::kLtr, | |
1084 NGLogicalSize(LayoutUnit(1000), NGSizeIndefinite)); | |
1085 const auto* fragment = RunBlockLayoutAlgorithm(space, parent); | |
1086 | |
1087 FragmentChildIterator iterator(fragment); | |
1088 fragment = iterator.NextChild(); | |
1089 ASSERT_TRUE(fragment); | |
1090 EXPECT_EQ(LayoutUnit(320), fragment->Width()); | |
1091 EXPECT_EQ(LayoutUnit(100), fragment->Height()); | |
1092 EXPECT_FALSE(iterator.NextChild()); | |
1093 | |
1094 iterator.SetParent(fragment); | |
1095 // #child fragment in first column | |
1096 fragment = iterator.NextChild(); | |
1097 ASSERT_TRUE(fragment); | |
1098 EXPECT_EQ(LayoutUnit(), fragment->LeftOffset()); | |
1099 EXPECT_EQ(LayoutUnit(), fragment->TopOffset()); | |
1100 EXPECT_EQ(LayoutUnit(75), fragment->Width()); | |
1101 EXPECT_EQ(LayoutUnit(100), fragment->Height()); | |
1102 EXPECT_EQ(0UL, fragment->Children().size()); | |
1103 | |
1104 // #child fragment in second column | |
1105 fragment = iterator.NextChild(); | |
1106 ASSERT_TRUE(fragment); | |
1107 EXPECT_EQ(LayoutUnit(110), fragment->LeftOffset()); | |
1108 EXPECT_EQ(LayoutUnit(), fragment->TopOffset()); | |
1109 EXPECT_EQ(LayoutUnit(75), fragment->Width()); | |
1110 EXPECT_EQ(LayoutUnit(100), fragment->Height()); | |
1111 EXPECT_EQ(0U, fragment->Children().size()); | |
1112 | |
1113 // #child fragment in third column | |
1114 fragment = iterator.NextChild(); | |
1115 ASSERT_TRUE(fragment); | |
1116 EXPECT_EQ(LayoutUnit(220), fragment->LeftOffset()); | |
1117 EXPECT_EQ(LayoutUnit(), fragment->TopOffset()); | |
1118 EXPECT_EQ(LayoutUnit(75), fragment->Width()); | |
1119 EXPECT_EQ(LayoutUnit(50), fragment->Height()); | |
1120 EXPECT_EQ(0U, fragment->Children().size()); | |
1121 EXPECT_FALSE(iterator.NextChild()); | |
1122 } | |
1123 | |
1124 // Test case's HTML representation: | |
1125 // <div id="parent" style="columns:2; column-fill:auto; column-gap:10px; | |
1126 // width:210px; height:100px;"> | |
1127 // <div id="child" style="width:1px; height:250px;"></div> | |
1128 // </div> | |
1129 TEST_F(NGBlockLayoutAlgorithmTest, ActualColumnCountGreaterThanSpecified) { | |
1130 // parent | |
1131 RefPtr<ComputedStyle> parent_style = ComputedStyle::create(); | |
1132 parent_style->setColumnCount(2); | |
1133 parent_style->setColumnFill(ColumnFillAuto); | |
1134 parent_style->setColumnGap(10); | |
1135 parent_style->setHeight(Length(100, Fixed)); | |
1136 parent_style->setWidth(Length(210, Fixed)); | |
1137 NGBlockNode* parent = new NGBlockNode(parent_style.get()); | |
1138 | |
1139 // child | |
1140 RefPtr<ComputedStyle> child_style = ComputedStyle::create(); | |
1141 child_style->setWidth(Length(1, Fixed)); | |
1142 child_style->setHeight(Length(250, Fixed)); | |
1143 NGBlockNode* child = new NGBlockNode(child_style.get()); | |
1144 | |
1145 parent->SetFirstChild(child); | |
1146 | |
1147 auto* space = ConstructConstraintSpace( | |
1148 kHorizontalTopBottom, TextDirection::kLtr, | |
1149 NGLogicalSize(LayoutUnit(1000), NGSizeIndefinite)); | |
1150 const auto* fragment = RunBlockLayoutAlgorithm(space, parent); | |
1151 | |
1152 FragmentChildIterator iterator(fragment); | |
1153 fragment = iterator.NextChild(); | |
1154 ASSERT_TRUE(fragment); | |
1155 EXPECT_EQ(LayoutUnit(210), fragment->Width()); | |
1156 EXPECT_EQ(LayoutUnit(100), fragment->Height()); | |
1157 EXPECT_FALSE(iterator.NextChild()); | |
1158 | |
1159 iterator.SetParent(fragment); | |
1160 // #child fragment in first column | |
1161 fragment = iterator.NextChild(); | |
1162 ASSERT_TRUE(fragment); | |
1163 EXPECT_EQ(LayoutUnit(), fragment->LeftOffset()); | |
1164 EXPECT_EQ(LayoutUnit(), fragment->TopOffset()); | |
1165 EXPECT_EQ(LayoutUnit(1), fragment->Width()); | |
1166 EXPECT_EQ(LayoutUnit(100), fragment->Height()); | |
1167 EXPECT_EQ(0UL, fragment->Children().size()); | |
1168 | |
1169 // #child fragment in second column | |
1170 fragment = iterator.NextChild(); | |
1171 ASSERT_TRUE(fragment); | |
1172 EXPECT_EQ(LayoutUnit(110), fragment->LeftOffset()); | |
1173 EXPECT_EQ(LayoutUnit(), fragment->TopOffset()); | |
1174 EXPECT_EQ(LayoutUnit(1), fragment->Width()); | |
1175 EXPECT_EQ(LayoutUnit(100), fragment->Height()); | |
1176 EXPECT_EQ(0U, fragment->Children().size()); | |
1177 | |
1178 // #child fragment in third column | |
1179 fragment = iterator.NextChild(); | |
1180 ASSERT_TRUE(fragment); | |
1181 EXPECT_EQ(LayoutUnit(220), fragment->LeftOffset()); | |
1182 EXPECT_EQ(LayoutUnit(), fragment->TopOffset()); | |
1183 EXPECT_EQ(LayoutUnit(1), fragment->Width()); | |
1184 EXPECT_EQ(LayoutUnit(50), fragment->Height()); | |
1185 EXPECT_EQ(0U, fragment->Children().size()); | |
1186 EXPECT_FALSE(iterator.NextChild()); | |
1187 } | |
1188 | |
1189 // Test case's HTML representation: | |
1190 // <div id="parent" style="columns:3; column-fill:auto; column-gap:10px; | |
1191 // width:320px; height:100px;"> | |
1192 // <div id="child1" style="width:75%; height:60px;"></div> | |
1193 // <div id="child2" style="width:85%; height:60px;"></div> | |
1194 // </div> | |
1195 TEST_F(NGBlockLayoutAlgorithmTest, TwoBlocksInTwoColumns) { | |
1196 // parent | |
1197 RefPtr<ComputedStyle> parent_style = ComputedStyle::create(); | |
1198 parent_style->setColumnCount(3); | |
1199 parent_style->setColumnFill(ColumnFillAuto); | |
1200 parent_style->setColumnGap(10); | |
1201 parent_style->setHeight(Length(100, Fixed)); | |
1202 parent_style->setWidth(Length(320, Fixed)); | |
1203 NGBlockNode* parent = new NGBlockNode(parent_style.get()); | |
1204 | |
1205 // child1 | |
1206 RefPtr<ComputedStyle> child1_style = ComputedStyle::create(); | |
1207 child1_style->setWidth(Length(75, Percent)); | |
1208 child1_style->setHeight(Length(60, Fixed)); | |
1209 NGBlockNode* child1 = new NGBlockNode(child1_style.get()); | |
1210 | |
1211 // child2 | |
1212 RefPtr<ComputedStyle> child2_style = ComputedStyle::create(); | |
1213 child2_style->setWidth(Length(85, Percent)); | |
1214 child2_style->setHeight(Length(60, Fixed)); | |
1215 NGBlockNode* child2 = new NGBlockNode(child2_style.get()); | |
1216 | |
1217 parent->SetFirstChild(child1); | |
1218 child1->SetNextSibling(child2); | |
1219 | |
1220 auto* space = ConstructConstraintSpace( | |
1221 kHorizontalTopBottom, TextDirection::kLtr, | |
1222 NGLogicalSize(LayoutUnit(1000), NGSizeIndefinite)); | |
1223 const auto* fragment = RunBlockLayoutAlgorithm(space, parent); | |
1224 | |
1225 FragmentChildIterator iterator(fragment); | |
1226 fragment = iterator.NextChild(); | |
1227 ASSERT_TRUE(fragment); | |
1228 EXPECT_EQ(LayoutUnit(320), fragment->Width()); | |
1229 EXPECT_EQ(LayoutUnit(100), fragment->Height()); | |
1230 EXPECT_FALSE(iterator.NextChild()); | |
1231 | |
1232 iterator.SetParent(fragment); | |
1233 // #child1 fragment in first column | |
1234 fragment = iterator.NextChild(); | |
1235 ASSERT_TRUE(fragment); | |
1236 EXPECT_EQ(LayoutUnit(), fragment->LeftOffset()); | |
1237 EXPECT_EQ(LayoutUnit(), fragment->TopOffset()); | |
1238 EXPECT_EQ(LayoutUnit(75), fragment->Width()); | |
1239 EXPECT_EQ(LayoutUnit(60), fragment->Height()); | |
1240 EXPECT_EQ(0UL, fragment->Children().size()); | |
1241 // #child2 fragment in first column | |
1242 fragment = iterator.NextChild(); | |
1243 ASSERT_TRUE(fragment); | |
1244 EXPECT_EQ(LayoutUnit(), fragment->LeftOffset()); | |
1245 EXPECT_EQ(LayoutUnit(60), fragment->TopOffset()); | |
1246 EXPECT_EQ(LayoutUnit(85), fragment->Width()); | |
1247 EXPECT_EQ(LayoutUnit(40), fragment->Height()); | |
1248 EXPECT_EQ(0UL, fragment->Children().size()); | |
1249 | |
1250 // #child2 fragment in second column | |
1251 fragment = iterator.NextChild(); | |
1252 ASSERT_TRUE(fragment); | |
1253 EXPECT_EQ(LayoutUnit(110), fragment->LeftOffset()); | |
1254 EXPECT_EQ(LayoutUnit(), fragment->TopOffset()); | |
1255 EXPECT_EQ(LayoutUnit(85), fragment->Width()); | |
1256 EXPECT_EQ(LayoutUnit(20), fragment->Height()); | |
1257 EXPECT_EQ(0U, fragment->Children().size()); | |
1258 EXPECT_FALSE(iterator.NextChild()); | |
1259 } | |
1260 | |
1261 // Test case's HTML representation: | |
1262 // <div id="parent" style="columns:3; column-fill:auto; column-gap:10px; | |
1263 // width:320px; height:100px;"> | |
1264 // <div id="child1" style="width:75%; height:60px;"> | |
1265 // <div id="grandchild1" style="width:50px; height:120px;"></div> | |
1266 // <div id="grandchild2" style="width:40px; height:20px;"></div> | |
1267 // </div> | |
1268 // <div id="child2" style="width:85%; height:10px;"></div> | |
1269 // </div> | |
1270 TEST_F(NGBlockLayoutAlgorithmTest, OverflowedBlock) { | |
1271 // parent | |
1272 RefPtr<ComputedStyle> parent_style = ComputedStyle::create(); | |
1273 parent_style->setColumnCount(3); | |
1274 parent_style->setColumnFill(ColumnFillAuto); | |
1275 parent_style->setColumnGap(10); | |
1276 parent_style->setHeight(Length(100, Fixed)); | |
1277 parent_style->setWidth(Length(320, Fixed)); | |
1278 NGBlockNode* parent = new NGBlockNode(parent_style.get()); | |
1279 | |
1280 // child1 | |
1281 RefPtr<ComputedStyle> child1_style = ComputedStyle::create(); | |
1282 child1_style->setWidth(Length(75, Percent)); | |
1283 child1_style->setHeight(Length(60, Fixed)); | |
1284 NGBlockNode* child1 = new NGBlockNode(child1_style.get()); | |
1285 | |
1286 // grandchild1 | |
1287 RefPtr<ComputedStyle> grandchild1_style = ComputedStyle::create(); | |
1288 grandchild1_style->setWidth(Length(50, Fixed)); | |
1289 grandchild1_style->setHeight(Length(120, Fixed)); | |
1290 NGBlockNode* grandchild1 = new NGBlockNode(grandchild1_style.get()); | |
1291 | |
1292 // grandchild2 | |
1293 RefPtr<ComputedStyle> grandchild2_style = ComputedStyle::create(); | |
1294 grandchild2_style->setWidth(Length(40, Fixed)); | |
1295 grandchild2_style->setHeight(Length(20, Fixed)); | |
1296 NGBlockNode* grandchild2 = new NGBlockNode(grandchild2_style.get()); | |
1297 | |
1298 // child2 | |
1299 RefPtr<ComputedStyle> child2_style = ComputedStyle::create(); | |
1300 child2_style->setWidth(Length(85, Percent)); | |
1301 child2_style->setHeight(Length(10, Fixed)); | |
1302 NGBlockNode* child2 = new NGBlockNode(child2_style.get()); | |
1303 | |
1304 parent->SetFirstChild(child1); | |
1305 child1->SetNextSibling(child2); | |
1306 child1->SetFirstChild(grandchild1); | |
1307 grandchild1->SetNextSibling(grandchild2); | |
1308 | |
1309 auto* space = ConstructConstraintSpace( | |
1310 kHorizontalTopBottom, TextDirection::kLtr, | |
1311 NGLogicalSize(LayoutUnit(1000), NGSizeIndefinite)); | |
1312 const auto* fragment = RunBlockLayoutAlgorithm(space, parent); | |
1313 | |
1314 FragmentChildIterator iterator(fragment); | |
1315 fragment = iterator.NextChild(); | |
1316 ASSERT_TRUE(fragment); | |
1317 EXPECT_EQ(LayoutUnit(320), fragment->Width()); | |
1318 EXPECT_EQ(LayoutUnit(100), fragment->Height()); | |
1319 EXPECT_FALSE(iterator.NextChild()); | |
1320 | |
1321 iterator.SetParent(fragment); | |
1322 // #child1 fragment in first column | |
1323 fragment = iterator.NextChild(); | |
1324 ASSERT_TRUE(fragment); | |
1325 EXPECT_EQ(LayoutUnit(), fragment->LeftOffset()); | |
1326 EXPECT_EQ(LayoutUnit(), fragment->TopOffset()); | |
1327 EXPECT_EQ(LayoutUnit(75), fragment->Width()); | |
1328 EXPECT_EQ(LayoutUnit(60), fragment->Height()); | |
1329 FragmentChildIterator grandchild_iterator(fragment); | |
1330 // #grandchild1 fragment in first column | |
1331 fragment = grandchild_iterator.NextChild(); | |
1332 ASSERT_TRUE(fragment); | |
1333 EXPECT_EQ(LayoutUnit(), fragment->LeftOffset()); | |
1334 EXPECT_EQ(LayoutUnit(), fragment->TopOffset()); | |
1335 EXPECT_EQ(LayoutUnit(50), fragment->Width()); | |
1336 EXPECT_EQ(LayoutUnit(100), fragment->Height()); | |
1337 EXPECT_FALSE(grandchild_iterator.NextChild()); | |
1338 // #child2 fragment in first column | |
1339 fragment = iterator.NextChild(); | |
1340 ASSERT_TRUE(fragment); | |
1341 EXPECT_EQ(LayoutUnit(), fragment->LeftOffset()); | |
1342 EXPECT_EQ(LayoutUnit(60), fragment->TopOffset()); | |
1343 EXPECT_EQ(LayoutUnit(85), fragment->Width()); | |
1344 EXPECT_EQ(LayoutUnit(10), fragment->Height()); | |
1345 EXPECT_EQ(0UL, fragment->Children().size()); | |
1346 | |
1347 // #child1 fragment in second column | |
1348 fragment = iterator.NextChild(); | |
1349 ASSERT_TRUE(fragment); | |
1350 EXPECT_EQ(LayoutUnit(110), fragment->LeftOffset()); | |
1351 EXPECT_EQ(LayoutUnit(), fragment->TopOffset()); | |
1352 EXPECT_EQ(LayoutUnit(75), fragment->Width()); | |
1353 EXPECT_EQ(LayoutUnit(), fragment->Height()); | |
1354 grandchild_iterator.SetParent(fragment); | |
1355 // #grandchild1 fragment in second column | |
1356 fragment = grandchild_iterator.NextChild(); | |
1357 ASSERT_TRUE(fragment); | |
1358 EXPECT_EQ(LayoutUnit(), fragment->LeftOffset()); | |
1359 EXPECT_EQ(LayoutUnit(), fragment->TopOffset()); | |
1360 EXPECT_EQ(LayoutUnit(50), fragment->Width()); | |
1361 EXPECT_EQ(LayoutUnit(20), fragment->Height()); | |
1362 // #grandchild2 fragment in second column | |
1363 fragment = grandchild_iterator.NextChild(); | |
1364 ASSERT_TRUE(fragment); | |
1365 EXPECT_EQ(LayoutUnit(), fragment->LeftOffset()); | |
1366 EXPECT_EQ(LayoutUnit(20), fragment->TopOffset()); | |
1367 EXPECT_EQ(LayoutUnit(40), fragment->Width()); | |
1368 EXPECT_EQ(LayoutUnit(20), fragment->Height()); | |
1369 EXPECT_FALSE(grandchild_iterator.NextChild()); | |
1370 EXPECT_FALSE(iterator.NextChild()); | |
1371 } | |
1372 | |
1373 // Test case's HTML representation: | |
1374 // <div id="parent" style="columns:3; column-fill:auto; column-gap:10px; | |
1375 // width:320px; height:100px;"> | |
1376 // <div id="child" style="float:left; width:75%; height:100px;"></div> | |
1377 // </div> | |
1378 TEST_F(NGBlockLayoutAlgorithmTest, FloatInOneColumn) { | |
1379 // parent | |
1380 RefPtr<ComputedStyle> parent_style = ComputedStyle::create(); | |
1381 parent_style->setColumnCount(3); | |
1382 parent_style->setColumnFill(ColumnFillAuto); | |
1383 parent_style->setColumnGap(10); | |
1384 parent_style->setHeight(Length(100, Fixed)); | |
1385 parent_style->setWidth(Length(320, Fixed)); | |
1386 NGBlockNode* parent = new NGBlockNode(parent_style.get()); | |
1387 | |
1388 // child | |
1389 RefPtr<ComputedStyle> child_style = ComputedStyle::create(); | |
1390 child_style->setFloating(EFloat::kLeft); | |
1391 child_style->setWidth(Length(75, Percent)); | |
1392 child_style->setHeight(Length(100, Fixed)); | |
1393 NGBlockNode* child = new NGBlockNode(child_style.get()); | |
1394 | |
1395 parent->SetFirstChild(child); | |
1396 | |
1397 auto* space = ConstructConstraintSpace( | |
1398 kHorizontalTopBottom, TextDirection::kLtr, | |
1399 NGLogicalSize(LayoutUnit(1000), NGSizeIndefinite)); | |
1400 const auto* fragment = RunBlockLayoutAlgorithm(space, parent); | |
1401 | |
1402 FragmentChildIterator iterator(fragment); | |
1403 fragment = iterator.NextChild(); | |
1404 ASSERT_TRUE(fragment); | |
1405 EXPECT_EQ(LayoutUnit(320), fragment->Width()); | |
1406 EXPECT_EQ(LayoutUnit(100), fragment->Height()); | |
1407 EXPECT_FALSE(iterator.NextChild()); | |
1408 | |
1409 iterator.SetParent(fragment); | |
1410 // #child fragment in first column | |
1411 fragment = iterator.NextChild(); | |
1412 ASSERT_TRUE(fragment); | |
1413 EXPECT_EQ(LayoutUnit(), fragment->LeftOffset()); | |
1414 EXPECT_EQ(LayoutUnit(), fragment->TopOffset()); | |
1415 EXPECT_EQ(LayoutUnit(75), fragment->Width()); | |
1416 EXPECT_EQ(LayoutUnit(100), fragment->Height()); | |
1417 EXPECT_EQ(0UL, fragment->Children().size()); | |
1418 EXPECT_FALSE(iterator.NextChild()); | |
1419 } | |
1420 | |
1421 // Test case's HTML representation: | |
1422 // <div id="parent" style="columns:3; column-fill:auto; column-gap:10px; | |
1423 // width:320px; height:100px;"> | |
1424 // <div id="child1" style="float:left; width:15%; height:100px;"></div> | |
1425 // <div id="child2" style="float:right; width:16%; height:100px;"></div> | |
1426 // </div> | |
1427 TEST_F(NGBlockLayoutAlgorithmTest, TwoFloatsInOneColumn) { | |
1428 // parent | |
1429 RefPtr<ComputedStyle> parent_style = ComputedStyle::create(); | |
1430 parent_style->setColumnCount(3); | |
1431 parent_style->setColumnFill(ColumnFillAuto); | |
1432 parent_style->setColumnGap(10); | |
1433 parent_style->setHeight(Length(100, Fixed)); | |
1434 parent_style->setWidth(Length(320, Fixed)); | |
1435 NGBlockNode* parent = new NGBlockNode(parent_style.get()); | |
1436 | |
1437 // child1 | |
1438 RefPtr<ComputedStyle> child1_style = ComputedStyle::create(); | |
1439 child1_style->setFloating(EFloat::kLeft); | |
1440 child1_style->setWidth(Length(15, Percent)); | |
1441 child1_style->setHeight(Length(100, Fixed)); | |
1442 NGBlockNode* child1 = new NGBlockNode(child1_style.get()); | |
1443 | |
1444 // child2 | |
1445 RefPtr<ComputedStyle> child2_style = ComputedStyle::create(); | |
1446 child2_style->setFloating(EFloat::kRight); | |
1447 child2_style->setWidth(Length(16, Percent)); | |
1448 child2_style->setHeight(Length(100, Fixed)); | |
1449 NGBlockNode* child2 = new NGBlockNode(child2_style.get()); | |
1450 | |
1451 parent->SetFirstChild(child1); | |
1452 child1->SetNextSibling(child2); | |
1453 | |
1454 auto* space = ConstructConstraintSpace( | |
1455 kHorizontalTopBottom, TextDirection::kLtr, | |
1456 NGLogicalSize(LayoutUnit(1000), NGSizeIndefinite)); | |
1457 const auto* fragment = RunBlockLayoutAlgorithm(space, parent); | |
1458 | |
1459 FragmentChildIterator iterator(fragment); | |
1460 fragment = iterator.NextChild(); | |
1461 ASSERT_TRUE(fragment); | |
1462 EXPECT_EQ(LayoutUnit(320), fragment->Width()); | |
1463 EXPECT_EQ(LayoutUnit(100), fragment->Height()); | |
1464 EXPECT_FALSE(iterator.NextChild()); | |
1465 | |
1466 iterator.SetParent(fragment); | |
1467 // #child1 fragment in first column | |
1468 fragment = iterator.NextChild(); | |
1469 ASSERT_TRUE(fragment); | |
1470 EXPECT_EQ(LayoutUnit(), fragment->LeftOffset()); | |
1471 EXPECT_EQ(LayoutUnit(), fragment->TopOffset()); | |
1472 EXPECT_EQ(LayoutUnit(15), fragment->Width()); | |
1473 EXPECT_EQ(LayoutUnit(100), fragment->Height()); | |
1474 EXPECT_EQ(0UL, fragment->Children().size()); | |
1475 // #child2 fragment in first column | |
1476 fragment = iterator.NextChild(); | |
1477 ASSERT_TRUE(fragment); | |
1478 EXPECT_EQ(LayoutUnit(84), fragment->LeftOffset()); | |
1479 EXPECT_EQ(LayoutUnit(), fragment->TopOffset()); | |
1480 EXPECT_EQ(LayoutUnit(16), fragment->Width()); | |
1481 EXPECT_EQ(LayoutUnit(100), fragment->Height()); | |
1482 EXPECT_EQ(0UL, fragment->Children().size()); | |
1483 EXPECT_FALSE(iterator.NextChild()); | |
1484 } | |
1485 | |
1486 // Test case's HTML representation: | |
1487 // <div id="parent" style="columns:3; column-fill:auto; column-gap:10px; | |
1488 // width:320px; height:100px;"> | |
1489 // <div id="child1" style="float:left; width:15%; height:150px;"></div> | |
1490 // <div id="child2" style="float:right; width:16%; height:150px;"></div> | |
1491 // </div> | |
1492 TEST_F(NGBlockLayoutAlgorithmTest, TwoFloatsInTwoColumns) { | |
1493 // parent | |
1494 RefPtr<ComputedStyle> parent_style = ComputedStyle::create(); | |
1495 parent_style->setColumnCount(3); | |
1496 parent_style->setColumnFill(ColumnFillAuto); | |
1497 parent_style->setColumnGap(10); | |
1498 parent_style->setHeight(Length(100, Fixed)); | |
1499 parent_style->setWidth(Length(320, Fixed)); | |
1500 NGBlockNode* parent = new NGBlockNode(parent_style.get()); | |
1501 | |
1502 // child1 | |
1503 RefPtr<ComputedStyle> child1_style = ComputedStyle::create(); | |
1504 child1_style->setFloating(EFloat::kLeft); | |
1505 child1_style->setWidth(Length(15, Percent)); | |
1506 child1_style->setHeight(Length(150, Fixed)); | |
1507 NGBlockNode* child1 = new NGBlockNode(child1_style.get()); | |
1508 | |
1509 // child2 | |
1510 RefPtr<ComputedStyle> child2_style = ComputedStyle::create(); | |
1511 child2_style->setFloating(EFloat::kRight); | |
1512 child2_style->setWidth(Length(16, Percent)); | |
1513 child2_style->setHeight(Length(150, Fixed)); | |
1514 NGBlockNode* child2 = new NGBlockNode(child2_style.get()); | |
1515 | |
1516 parent->SetFirstChild(child1); | |
1517 child1->SetNextSibling(child2); | |
1518 | |
1519 auto* space = ConstructConstraintSpace( | |
1520 kHorizontalTopBottom, TextDirection::kLtr, | |
1521 NGLogicalSize(LayoutUnit(1000), NGSizeIndefinite)); | |
1522 const auto* fragment = RunBlockLayoutAlgorithm(space, parent); | |
1523 | |
1524 FragmentChildIterator iterator(fragment); | |
1525 fragment = iterator.NextChild(); | |
1526 ASSERT_TRUE(fragment); | |
1527 EXPECT_EQ(LayoutUnit(320), fragment->Width()); | |
1528 EXPECT_EQ(LayoutUnit(100), fragment->Height()); | |
1529 EXPECT_FALSE(iterator.NextChild()); | |
1530 | |
1531 iterator.SetParent(fragment); | |
1532 // #child1 fragment in first column | |
1533 fragment = iterator.NextChild(); | |
1534 ASSERT_TRUE(fragment); | |
1535 EXPECT_EQ(LayoutUnit(), fragment->LeftOffset()); | |
1536 EXPECT_EQ(LayoutUnit(), fragment->TopOffset()); | |
1537 EXPECT_EQ(LayoutUnit(15), fragment->Width()); | |
1538 EXPECT_EQ(LayoutUnit(100), fragment->Height()); | |
1539 EXPECT_EQ(0UL, fragment->Children().size()); | |
1540 // #child2 fragment in first column | |
1541 fragment = iterator.NextChild(); | |
1542 ASSERT_TRUE(fragment); | |
1543 EXPECT_EQ(LayoutUnit(84), fragment->LeftOffset()); | |
1544 EXPECT_EQ(LayoutUnit(), fragment->TopOffset()); | |
1545 EXPECT_EQ(LayoutUnit(16), fragment->Width()); | |
1546 EXPECT_EQ(LayoutUnit(100), fragment->Height()); | |
1547 EXPECT_EQ(0UL, fragment->Children().size()); | |
1548 | |
1549 // #child1 fragment in second column | |
1550 fragment = iterator.NextChild(); | |
1551 ASSERT_TRUE(fragment); | |
1552 EXPECT_EQ(LayoutUnit(110), fragment->LeftOffset()); | |
1553 EXPECT_EQ(LayoutUnit(), fragment->TopOffset()); | |
1554 EXPECT_EQ(LayoutUnit(15), fragment->Width()); | |
1555 EXPECT_EQ(LayoutUnit(50), fragment->Height()); | |
1556 EXPECT_EQ(0UL, fragment->Children().size()); | |
1557 // #child2 fragment in second column | |
1558 fragment = iterator.NextChild(); | |
1559 ASSERT_TRUE(fragment); | |
1560 EXPECT_EQ(LayoutUnit(194), fragment->LeftOffset()); | |
1561 EXPECT_EQ(LayoutUnit(), fragment->TopOffset()); | |
1562 EXPECT_EQ(LayoutUnit(16), fragment->Width()); | |
1563 EXPECT_EQ(LayoutUnit(50), fragment->Height()); | |
1564 EXPECT_EQ(0UL, fragment->Children().size()); | |
1565 EXPECT_FALSE(iterator.NextChild()); | |
1566 } | |
1567 | |
850 } // namespace | 1568 } // namespace |
851 } // namespace blink | 1569 } // namespace blink |
OLD | NEW |