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/inline/ng_inline_items_builder.h" | 5 #include "core/layout/ng/inline/ng_inline_items_builder.h" |
6 | 6 |
7 #include "core/layout/LayoutInline.h" | 7 #include "core/layout/LayoutInline.h" |
8 #include "core/layout/ng/inline/ng_inline_node.h" | 8 #include "core/layout/ng/inline/ng_inline_node.h" |
9 #include "core/style/ComputedStyle.h" | 9 #include "core/style/ComputedStyle.h" |
10 #include "testing/gtest/include/gtest/gtest.h" | 10 #include "testing/gtest/include/gtest/gtest.h" |
(...skipping 11 matching lines...) Expand all Loading... |
22 class NGInlineItemsBuilderTest : public ::testing::Test { | 22 class NGInlineItemsBuilderTest : public ::testing::Test { |
23 protected: | 23 protected: |
24 void SetUp() override { style_ = ComputedStyle::Create(); } | 24 void SetUp() override { style_ = ComputedStyle::Create(); } |
25 | 25 |
26 void SetWhiteSpace(EWhiteSpace whitespace) { | 26 void SetWhiteSpace(EWhiteSpace whitespace) { |
27 style_->SetWhiteSpace(whitespace); | 27 style_->SetWhiteSpace(whitespace); |
28 } | 28 } |
29 | 29 |
30 const String& TestAppend(const String inputs[], int size) { | 30 const String& TestAppend(const String inputs[], int size) { |
31 items_.clear(); | 31 items_.clear(); |
32 NGInlineItemsBuilder builder(&items_); | 32 removed_indexes_.clear(); |
| 33 NGInlineItemsBuilder builder(&items_, &removed_indexes_); |
33 for (int i = 0; i < size; i++) | 34 for (int i = 0; i < size; i++) |
34 builder.Append(inputs[i], style_.Get()); | 35 builder.Append(inputs[i], style_.Get()); |
35 text_ = builder.ToString(); | 36 text_ = builder.ToString(); |
36 ValidateItems(); | 37 ValidateItems(); |
37 return text_; | 38 return text_; |
38 } | 39 } |
39 | 40 |
40 const String& TestAppend(const String& input) { | 41 const String& TestAppend(const String& input) { |
41 String inputs[] = {input}; | 42 String inputs[] = {input}; |
42 return TestAppend(inputs, 1); | 43 return TestAppend(inputs, 1); |
(...skipping 15 matching lines...) Expand all Loading... |
58 unsigned current_offset = 0; | 59 unsigned current_offset = 0; |
59 for (unsigned i = 0; i < items_.size(); i++) { | 60 for (unsigned i = 0; i < items_.size(); i++) { |
60 const NGInlineItem& item = items_[i]; | 61 const NGInlineItem& item = items_[i]; |
61 EXPECT_EQ(current_offset, item.StartOffset()); | 62 EXPECT_EQ(current_offset, item.StartOffset()); |
62 EXPECT_LT(item.StartOffset(), item.EndOffset()); | 63 EXPECT_LT(item.StartOffset(), item.EndOffset()); |
63 current_offset = item.EndOffset(); | 64 current_offset = item.EndOffset(); |
64 } | 65 } |
65 EXPECT_EQ(current_offset, text_.length()); | 66 EXPECT_EQ(current_offset, text_.length()); |
66 } | 67 } |
67 | 68 |
| 69 void ValidateRemovedIndexes(const Vector<Vector<unsigned>>& expected) { |
| 70 ASSERT_EQ(expected.size(), removed_indexes_.size()); |
| 71 for (unsigned i = 0; i < expected.size(); ++i) { |
| 72 ASSERT_EQ(expected[i].size(), removed_indexes_[i].size()) << i; |
| 73 for (unsigned j = 0; j < expected[i].size(); ++j) |
| 74 EXPECT_EQ(expected[i][j], removed_indexes_[i][j]) << i << " " << j; |
| 75 } |
| 76 } |
| 77 |
68 Vector<NGInlineItem> items_; | 78 Vector<NGInlineItem> items_; |
| 79 Vector<Vector<unsigned>> removed_indexes_; |
69 String text_; | 80 String text_; |
70 RefPtr<ComputedStyle> style_; | 81 RefPtr<ComputedStyle> style_; |
71 }; | 82 }; |
72 | 83 |
73 #define TestWhitespaceValue(expected, input, whitespace) \ | 84 #define TestWhitespaceValue(expected, input, whitespace) \ |
74 SetWhiteSpace(whitespace); \ | 85 SetWhiteSpace(whitespace); \ |
75 EXPECT_EQ(expected, TestAppend(input)) << "white-space: " #whitespace; | 86 EXPECT_EQ(expected, TestAppend(input)) << "white-space: " #whitespace; |
76 | 87 |
77 TEST_F(NGInlineItemsBuilderTest, CollapseSpaces) { | 88 TEST_F(NGInlineItemsBuilderTest, CollapseSpaces) { |
78 String input("text text text text"); | 89 String input("text text text text"); |
79 String collapsed("text text text text"); | 90 String collapsed("text text text text"); |
| 91 Vector<Vector<unsigned>> collapsed_result = {{10, 16, 17}}; |
| 92 Vector<Vector<unsigned>> uncollapsed_result = {{}}; |
80 TestWhitespaceValue(collapsed, input, EWhiteSpace::kNormal); | 93 TestWhitespaceValue(collapsed, input, EWhiteSpace::kNormal); |
| 94 ValidateRemovedIndexes(collapsed_result); |
81 TestWhitespaceValue(collapsed, input, EWhiteSpace::kNowrap); | 95 TestWhitespaceValue(collapsed, input, EWhiteSpace::kNowrap); |
| 96 ValidateRemovedIndexes(collapsed_result); |
82 TestWhitespaceValue(collapsed, input, EWhiteSpace::kWebkitNowrap); | 97 TestWhitespaceValue(collapsed, input, EWhiteSpace::kWebkitNowrap); |
| 98 ValidateRemovedIndexes(collapsed_result); |
83 TestWhitespaceValue(collapsed, input, EWhiteSpace::kPreLine); | 99 TestWhitespaceValue(collapsed, input, EWhiteSpace::kPreLine); |
| 100 ValidateRemovedIndexes(collapsed_result); |
84 TestWhitespaceValue(input, input, EWhiteSpace::kPre); | 101 TestWhitespaceValue(input, input, EWhiteSpace::kPre); |
| 102 ValidateRemovedIndexes(uncollapsed_result); |
85 TestWhitespaceValue(input, input, EWhiteSpace::kPreWrap); | 103 TestWhitespaceValue(input, input, EWhiteSpace::kPreWrap); |
| 104 ValidateRemovedIndexes(uncollapsed_result); |
86 } | 105 } |
87 | 106 |
88 TEST_F(NGInlineItemsBuilderTest, CollapseTabs) { | 107 TEST_F(NGInlineItemsBuilderTest, CollapseTabs) { |
89 String input("text\ttext\t text \t text"); | 108 String input("text\ttext\t text \t text"); |
90 String collapsed("text text text text"); | 109 String collapsed("text text text text"); |
| 110 Vector<Vector<unsigned>> collapsed_result = {{10, 16, 17}}; |
| 111 Vector<Vector<unsigned>> uncollapsed_result = {{}}; |
91 TestWhitespaceValue(collapsed, input, EWhiteSpace::kNormal); | 112 TestWhitespaceValue(collapsed, input, EWhiteSpace::kNormal); |
| 113 ValidateRemovedIndexes(collapsed_result); |
92 TestWhitespaceValue(collapsed, input, EWhiteSpace::kNowrap); | 114 TestWhitespaceValue(collapsed, input, EWhiteSpace::kNowrap); |
| 115 ValidateRemovedIndexes(collapsed_result); |
93 TestWhitespaceValue(collapsed, input, EWhiteSpace::kWebkitNowrap); | 116 TestWhitespaceValue(collapsed, input, EWhiteSpace::kWebkitNowrap); |
| 117 ValidateRemovedIndexes(collapsed_result); |
94 TestWhitespaceValue(collapsed, input, EWhiteSpace::kPreLine); | 118 TestWhitespaceValue(collapsed, input, EWhiteSpace::kPreLine); |
| 119 ValidateRemovedIndexes(collapsed_result); |
95 TestWhitespaceValue(input, input, EWhiteSpace::kPre); | 120 TestWhitespaceValue(input, input, EWhiteSpace::kPre); |
| 121 ValidateRemovedIndexes(uncollapsed_result); |
96 TestWhitespaceValue(input, input, EWhiteSpace::kPreWrap); | 122 TestWhitespaceValue(input, input, EWhiteSpace::kPreWrap); |
| 123 ValidateRemovedIndexes(uncollapsed_result); |
97 } | 124 } |
98 | 125 |
99 TEST_F(NGInlineItemsBuilderTest, CollapseNewLines) { | 126 TEST_F(NGInlineItemsBuilderTest, CollapseNewLines) { |
100 String input("text\ntext \n text\n\ntext"); | 127 String input("text\ntext \n text\n\ntext"); |
101 String collapsed("text text text text"); | 128 String collapsed("text text text text"); |
| 129 Vector<Vector<unsigned>> collapsed_result = {{10, 11, 17}}; |
| 130 Vector<Vector<unsigned>> uncollapsed_result = {{}}; |
102 TestWhitespaceValue(collapsed, input, EWhiteSpace::kNormal); | 131 TestWhitespaceValue(collapsed, input, EWhiteSpace::kNormal); |
| 132 ValidateRemovedIndexes(collapsed_result); |
103 TestWhitespaceValue(collapsed, input, EWhiteSpace::kNowrap); | 133 TestWhitespaceValue(collapsed, input, EWhiteSpace::kNowrap); |
| 134 ValidateRemovedIndexes(collapsed_result); |
104 TestWhitespaceValue("text\ntext\ntext\n\ntext", input, EWhiteSpace::kPreLine); | 135 TestWhitespaceValue("text\ntext\ntext\n\ntext", input, EWhiteSpace::kPreLine); |
| 136 ValidateRemovedIndexes({{9, 11}}); |
105 TestWhitespaceValue(input, input, EWhiteSpace::kPre); | 137 TestWhitespaceValue(input, input, EWhiteSpace::kPre); |
| 138 ValidateRemovedIndexes(uncollapsed_result); |
106 TestWhitespaceValue(input, input, EWhiteSpace::kPreWrap); | 139 TestWhitespaceValue(input, input, EWhiteSpace::kPreWrap); |
| 140 ValidateRemovedIndexes(uncollapsed_result); |
107 } | 141 } |
108 | 142 |
109 TEST_F(NGInlineItemsBuilderTest, CollapseNewlinesAsSpaces) { | 143 TEST_F(NGInlineItemsBuilderTest, CollapseNewlinesAsSpaces) { |
110 EXPECT_EQ("text text", TestAppend("text\ntext")); | 144 EXPECT_EQ("text text", TestAppend("text\ntext")); |
| 145 ValidateRemovedIndexes({{}}); |
111 EXPECT_EQ("text text", TestAppend("text\n\ntext")); | 146 EXPECT_EQ("text text", TestAppend("text\n\ntext")); |
| 147 ValidateRemovedIndexes({{5}}); |
112 EXPECT_EQ("text text", TestAppend("text \n\n text")); | 148 EXPECT_EQ("text text", TestAppend("text \n\n text")); |
| 149 ValidateRemovedIndexes({{5, 6, 7}}); |
113 EXPECT_EQ("text text", TestAppend("text \n \n text")); | 150 EXPECT_EQ("text text", TestAppend("text \n \n text")); |
| 151 ValidateRemovedIndexes({{5, 6, 7, 8}}); |
114 } | 152 } |
115 | 153 |
116 TEST_F(NGInlineItemsBuilderTest, CollapseAcrossElements) { | 154 TEST_F(NGInlineItemsBuilderTest, CollapseAcrossElements) { |
117 EXPECT_EQ("text text", TestAppend("text ", " text")) | 155 EXPECT_EQ("text text", TestAppend("text ", " text")) |
118 << "Spaces are collapsed even when across elements."; | 156 << "Spaces are collapsed even when across elements."; |
| 157 ValidateRemovedIndexes({{}, {0}}); |
119 } | 158 } |
120 | 159 |
121 TEST_F(NGInlineItemsBuilderTest, CollapseLeadingSpaces) { | 160 TEST_F(NGInlineItemsBuilderTest, CollapseLeadingSpaces) { |
122 EXPECT_EQ("text", TestAppend(" text")); | 161 EXPECT_EQ("text", TestAppend(" text")); |
| 162 ValidateRemovedIndexes({{0, 1}}); |
123 EXPECT_EQ("text", TestAppend(" ", "text")); | 163 EXPECT_EQ("text", TestAppend(" ", "text")); |
| 164 ValidateRemovedIndexes({{0}, {}}); |
124 EXPECT_EQ("text", TestAppend(" ", " text")); | 165 EXPECT_EQ("text", TestAppend(" ", " text")); |
| 166 ValidateRemovedIndexes({{0}, {0}}); |
125 } | 167 } |
126 | 168 |
127 TEST_F(NGInlineItemsBuilderTest, CollapseTrailingSpaces) { | 169 TEST_F(NGInlineItemsBuilderTest, CollapseTrailingSpaces) { |
128 EXPECT_EQ("text", TestAppend("text ")); | 170 EXPECT_EQ("text", TestAppend("text ")); |
| 171 ValidateRemovedIndexes({{4, 5}}); |
129 EXPECT_EQ("text", TestAppend("text", " ")); | 172 EXPECT_EQ("text", TestAppend("text", " ")); |
| 173 ValidateRemovedIndexes({{}, {0}}); |
130 EXPECT_EQ("text", TestAppend("text ", " ")); | 174 EXPECT_EQ("text", TestAppend("text ", " ")); |
| 175 ValidateRemovedIndexes({{4}, {0}}); |
131 } | 176 } |
132 | 177 |
133 TEST_F(NGInlineItemsBuilderTest, CollapseAllSpaces) { | 178 TEST_F(NGInlineItemsBuilderTest, CollapseAllSpaces) { |
134 EXPECT_EQ("", TestAppend(" ")); | 179 EXPECT_EQ("", TestAppend(" ")); |
| 180 ValidateRemovedIndexes({{0, 1}}); |
135 EXPECT_EQ("", TestAppend(" ", " ")); | 181 EXPECT_EQ("", TestAppend(" ", " ")); |
| 182 ValidateRemovedIndexes({{0, 1}, {0, 1}}); |
136 EXPECT_EQ("", TestAppend(" ", "\n")); | 183 EXPECT_EQ("", TestAppend(" ", "\n")); |
| 184 ValidateRemovedIndexes({{0, 1}, {0}}); |
137 EXPECT_EQ("", TestAppend("\n", " ")); | 185 EXPECT_EQ("", TestAppend("\n", " ")); |
| 186 ValidateRemovedIndexes({{0}, {0, 1}}); |
138 } | 187 } |
139 | 188 |
140 TEST_F(NGInlineItemsBuilderTest, CollapseLeadingNewlines) { | 189 TEST_F(NGInlineItemsBuilderTest, CollapseLeadingNewlines) { |
141 EXPECT_EQ("text", TestAppend("\ntext")); | 190 EXPECT_EQ("text", TestAppend("\ntext")); |
| 191 ValidateRemovedIndexes({{0}}); |
142 EXPECT_EQ("text", TestAppend("\n\ntext")); | 192 EXPECT_EQ("text", TestAppend("\n\ntext")); |
| 193 ValidateRemovedIndexes({{0, 1}}); |
143 EXPECT_EQ("text", TestAppend("\n", "text")); | 194 EXPECT_EQ("text", TestAppend("\n", "text")); |
| 195 ValidateRemovedIndexes({{0}, {}}); |
144 EXPECT_EQ("text", TestAppend("\n\n", "text")); | 196 EXPECT_EQ("text", TestAppend("\n\n", "text")); |
| 197 ValidateRemovedIndexes({{0, 1}, {}}); |
145 EXPECT_EQ("text", TestAppend(" \n", "text")); | 198 EXPECT_EQ("text", TestAppend(" \n", "text")); |
| 199 ValidateRemovedIndexes({{0, 1}, {}}); |
146 EXPECT_EQ("text", TestAppend("\n", " text")); | 200 EXPECT_EQ("text", TestAppend("\n", " text")); |
| 201 ValidateRemovedIndexes({{0}, {0}}); |
147 EXPECT_EQ("text", TestAppend("\n\n", " text")); | 202 EXPECT_EQ("text", TestAppend("\n\n", " text")); |
| 203 ValidateRemovedIndexes({{0, 1}, {0}}); |
148 EXPECT_EQ("text", TestAppend(" \n", " text")); | 204 EXPECT_EQ("text", TestAppend(" \n", " text")); |
| 205 ValidateRemovedIndexes({{0, 1}, {0}}); |
149 EXPECT_EQ("text", TestAppend("\n", "\ntext")); | 206 EXPECT_EQ("text", TestAppend("\n", "\ntext")); |
| 207 ValidateRemovedIndexes({{0}, {0}}); |
150 EXPECT_EQ("text", TestAppend("\n\n", "\ntext")); | 208 EXPECT_EQ("text", TestAppend("\n\n", "\ntext")); |
| 209 ValidateRemovedIndexes({{0, 1}, {0}}); |
151 EXPECT_EQ("text", TestAppend(" \n", "\ntext")); | 210 EXPECT_EQ("text", TestAppend(" \n", "\ntext")); |
| 211 ValidateRemovedIndexes({{0, 1}, {0}}); |
152 } | 212 } |
153 | 213 |
154 TEST_F(NGInlineItemsBuilderTest, CollapseTrailingNewlines) { | 214 TEST_F(NGInlineItemsBuilderTest, CollapseTrailingNewlines) { |
155 EXPECT_EQ("text", TestAppend("text\n")); | 215 EXPECT_EQ("text", TestAppend("text\n")); |
| 216 ValidateRemovedIndexes({{4}}); |
156 EXPECT_EQ("text", TestAppend("text", "\n")); | 217 EXPECT_EQ("text", TestAppend("text", "\n")); |
| 218 ValidateRemovedIndexes({{}, {0}}); |
157 EXPECT_EQ("text", TestAppend("text\n", "\n")); | 219 EXPECT_EQ("text", TestAppend("text\n", "\n")); |
| 220 ValidateRemovedIndexes({{4}, {0}}); |
158 EXPECT_EQ("text", TestAppend("text\n", " ")); | 221 EXPECT_EQ("text", TestAppend("text\n", " ")); |
| 222 ValidateRemovedIndexes({{4}, {0}}); |
159 EXPECT_EQ("text", TestAppend("text ", "\n")); | 223 EXPECT_EQ("text", TestAppend("text ", "\n")); |
| 224 ValidateRemovedIndexes({{4}, {0}}); |
160 } | 225 } |
161 | 226 |
162 TEST_F(NGInlineItemsBuilderTest, CollapseBeforeNewlineAcrossElements) { | 227 TEST_F(NGInlineItemsBuilderTest, CollapseBeforeNewlineAcrossElements) { |
163 EXPECT_EQ("text text", TestAppend("text ", "\ntext")); | 228 EXPECT_EQ("text text", TestAppend("text ", "\ntext")); |
| 229 ValidateRemovedIndexes({{}, {0}}); |
164 EXPECT_EQ("text text", TestAppend("text", " ", "\ntext")); | 230 EXPECT_EQ("text text", TestAppend("text", " ", "\ntext")); |
| 231 ValidateRemovedIndexes({{}, {}, {0}}); |
165 } | 232 } |
166 | 233 |
167 TEST_F(NGInlineItemsBuilderTest, CollapseBeforeAndAfterNewline) { | 234 TEST_F(NGInlineItemsBuilderTest, CollapseBeforeAndAfterNewline) { |
168 SetWhiteSpace(EWhiteSpace::kPreLine); | 235 SetWhiteSpace(EWhiteSpace::kPreLine); |
169 EXPECT_EQ("text\ntext", TestAppend("text \n text")) | 236 EXPECT_EQ("text\ntext", TestAppend("text \n text")) |
170 << "Spaces before and after newline are removed."; | 237 << "Spaces before and after newline are removed."; |
| 238 ValidateRemovedIndexes({{4, 5, 7, 8}}); |
171 } | 239 } |
172 | 240 |
173 TEST_F(NGInlineItemsBuilderTest, | 241 TEST_F(NGInlineItemsBuilderTest, |
174 CollapsibleSpaceAfterNonCollapsibleSpaceAcrossElements) { | 242 CollapsibleSpaceAfterNonCollapsibleSpaceAcrossElements) { |
175 NGInlineItemsBuilder builder(&items_); | 243 NGInlineItemsBuilder builder(&items_, &removed_indexes_); |
176 RefPtr<ComputedStyle> pre_wrap(CreateWhitespaceStyle(EWhiteSpace::kPreWrap)); | 244 RefPtr<ComputedStyle> pre_wrap(CreateWhitespaceStyle(EWhiteSpace::kPreWrap)); |
177 builder.Append("text ", pre_wrap.Get()); | 245 builder.Append("text ", pre_wrap.Get()); |
178 builder.Append(" text", style_.Get()); | 246 builder.Append(" text", style_.Get()); |
179 EXPECT_EQ("text text", builder.ToString()) | 247 EXPECT_EQ("text text", builder.ToString()) |
180 << "The whitespace in constructions like '<span style=\"white-space: " | 248 << "The whitespace in constructions like '<span style=\"white-space: " |
181 "pre-wrap\">text <span><span> text</span>' does not collapse."; | 249 "pre-wrap\">text <span><span> text</span>' does not collapse."; |
| 250 ValidateRemovedIndexes({{}, {}}); |
182 } | 251 } |
183 | 252 |
184 TEST_F(NGInlineItemsBuilderTest, CollapseZeroWidthSpaces) { | 253 TEST_F(NGInlineItemsBuilderTest, CollapseZeroWidthSpaces) { |
185 EXPECT_EQ(String(u"text\u200Btext"), TestAppend(u"text\u200B\ntext")) | 254 EXPECT_EQ(String(u"text\u200Btext"), TestAppend(u"text\u200B\ntext")) |
186 << "Newline is removed if the character before is ZWS."; | 255 << "Newline is removed if the character before is ZWS."; |
| 256 ValidateRemovedIndexes({{5}}); |
187 EXPECT_EQ(String(u"text\u200Btext"), TestAppend(u"text\n\u200Btext")) | 257 EXPECT_EQ(String(u"text\u200Btext"), TestAppend(u"text\n\u200Btext")) |
188 << "Newline is removed if the character after is ZWS."; | 258 << "Newline is removed if the character after is ZWS."; |
| 259 ValidateRemovedIndexes({{4}}); |
189 EXPECT_EQ(String(u"text\u200B\u200Btext"), | 260 EXPECT_EQ(String(u"text\u200B\u200Btext"), |
190 TestAppend(u"text\u200B\n\u200Btext")) | 261 TestAppend(u"text\u200B\n\u200Btext")) |
191 << "Newline is removed if the character before/after is ZWS."; | 262 << "Newline is removed if the character before/after is ZWS."; |
| 263 ValidateRemovedIndexes({{5}}); |
192 | 264 |
193 EXPECT_EQ(String(u"text\u200Btext"), TestAppend(u"text\n", u"\u200Btext")) | 265 EXPECT_EQ(String(u"text\u200Btext"), TestAppend(u"text\n", u"\u200Btext")) |
194 << "Newline is removed if the character after across elements is ZWS."; | 266 << "Newline is removed if the character after across elements is ZWS."; |
| 267 ValidateRemovedIndexes({{4}, {}}); |
195 EXPECT_EQ(String(u"text\u200Btext"), TestAppend(u"text\u200B", u"\ntext")) | 268 EXPECT_EQ(String(u"text\u200Btext"), TestAppend(u"text\u200B", u"\ntext")) |
196 << "Newline is removed if the character before is ZWS even across " | 269 << "Newline is removed if the character before is ZWS even across " |
197 "elements."; | 270 "elements."; |
| 271 ValidateRemovedIndexes({{}, {0}}); |
198 | 272 |
199 EXPECT_EQ(String(u"text\u200Btext"), TestAppend(u"text \n", u"\u200Btext")) | 273 EXPECT_EQ(String(u"text\u200Btext"), TestAppend(u"text \n", u"\u200Btext")) |
200 << "Collapsible space before newline does not affect the result."; | 274 << "Collapsible space before newline does not affect the result."; |
| 275 ValidateRemovedIndexes({{4, 5}, {}}); |
201 | 276 |
202 EXPECT_EQ(String(u"text\u200Btext"), TestAppend(u"text\u200B\n", u" text")) | 277 EXPECT_EQ(String(u"text\u200Btext"), TestAppend(u"text\u200B\n", u" text")) |
203 << "Collapsible space after newline is removed even when the " | 278 << "Collapsible space after newline is removed even when the " |
204 "newline was removed."; | 279 "newline was removed."; |
| 280 ValidateRemovedIndexes({{5}, {0}}); |
205 } | 281 } |
206 | 282 |
207 TEST_F(NGInlineItemsBuilderTest, CollapseEastAsianWidth) { | 283 TEST_F(NGInlineItemsBuilderTest, CollapseEastAsianWidth) { |
208 EXPECT_EQ(String(u"\u4E00\u4E00"), TestAppend(u"\u4E00\n\u4E00")) | 284 EXPECT_EQ(String(u"\u4E00\u4E00"), TestAppend(u"\u4E00\n\u4E00")) |
209 << "Newline is removed when both sides are Wide."; | 285 << "Newline is removed when both sides are Wide."; |
| 286 ValidateRemovedIndexes({{1}}); |
210 | 287 |
211 EXPECT_EQ(String(u"\u4E00 A"), TestAppend(u"\u4E00\nA")) | 288 EXPECT_EQ(String(u"\u4E00 A"), TestAppend(u"\u4E00\nA")) |
212 << "Newline is not removed when after is Narrow."; | 289 << "Newline is not removed when after is Narrow."; |
| 290 ValidateRemovedIndexes({{}}); |
213 EXPECT_EQ(String(u"A \u4E00"), TestAppend(u"A\n\u4E00")) | 291 EXPECT_EQ(String(u"A \u4E00"), TestAppend(u"A\n\u4E00")) |
214 << "Newline is not removed when before is Narrow."; | 292 << "Newline is not removed when before is Narrow."; |
| 293 ValidateRemovedIndexes({{}}); |
215 | 294 |
216 EXPECT_EQ(String(u"\u4E00\u4E00"), TestAppend(u"\u4E00\n", u"\u4E00")) | 295 EXPECT_EQ(String(u"\u4E00\u4E00"), TestAppend(u"\u4E00\n", u"\u4E00")) |
217 << "Newline at the end of elements is removed when both sides are Wide."; | 296 << "Newline at the end of elements is removed when both sides are Wide."; |
| 297 ValidateRemovedIndexes({{1}, {}}); |
218 EXPECT_EQ(String(u"\u4E00\u4E00"), TestAppend(u"\u4E00", u"\n\u4E00")) | 298 EXPECT_EQ(String(u"\u4E00\u4E00"), TestAppend(u"\u4E00", u"\n\u4E00")) |
219 << "Newline at the beginning of elements is removed " | 299 << "Newline at the beginning of elements is removed " |
220 "when both sides are Wide."; | 300 "when both sides are Wide."; |
| 301 ValidateRemovedIndexes({{}, {0}}); |
221 } | 302 } |
222 | 303 |
223 TEST_F(NGInlineItemsBuilderTest, CollapseAroundReplacedElement) { | 304 TEST_F(NGInlineItemsBuilderTest, CollapseAroundReplacedElement) { |
224 NGInlineItemsBuilder builder(&items_); | 305 NGInlineItemsBuilder builder(&items_, &removed_indexes_); |
225 builder.Append("Hello ", style_.Get()); | 306 builder.Append("Hello ", style_.Get()); |
226 builder.Append(NGInlineItem::kAtomicInline, kObjectReplacementCharacter); | 307 builder.Append(NGInlineItem::kAtomicInline, kObjectReplacementCharacter); |
227 builder.Append(" World", style_.Get()); | 308 builder.Append(" World", style_.Get()); |
228 EXPECT_EQ(String(u"Hello \uFFFC World"), builder.ToString()); | 309 EXPECT_EQ(String(u"Hello \uFFFC World"), builder.ToString()); |
| 310 ValidateRemovedIndexes({{}, {}}); |
229 } | 311 } |
230 | 312 |
231 TEST_F(NGInlineItemsBuilderTest, CollapseNewlineAfterObject) { | 313 TEST_F(NGInlineItemsBuilderTest, CollapseNewlineAfterObject) { |
232 NGInlineItemsBuilder builder(&items_); | 314 NGInlineItemsBuilder builder(&items_, &removed_indexes_); |
233 builder.Append(NGInlineItem::kAtomicInline, kObjectReplacementCharacter); | 315 builder.Append(NGInlineItem::kAtomicInline, kObjectReplacementCharacter); |
234 builder.Append("\n", style_.Get()); | 316 builder.Append("\n", style_.Get()); |
235 builder.Append(NGInlineItem::kAtomicInline, kObjectReplacementCharacter); | 317 builder.Append(NGInlineItem::kAtomicInline, kObjectReplacementCharacter); |
236 EXPECT_EQ(String(u"\uFFFC \uFFFC"), builder.ToString()); | 318 EXPECT_EQ(String(u"\uFFFC \uFFFC"), builder.ToString()); |
237 EXPECT_EQ(3u, items_.size()); | 319 EXPECT_EQ(3u, items_.size()); |
238 EXPECT_EQ(nullptr, items_[0].Style()); | 320 EXPECT_EQ(nullptr, items_[0].Style()); |
239 EXPECT_EQ(style_.Get(), items_[1].Style()); | 321 EXPECT_EQ(style_.Get(), items_[1].Style()); |
240 EXPECT_EQ(nullptr, items_[2].Style()); | 322 EXPECT_EQ(nullptr, items_[2].Style()); |
| 323 ValidateRemovedIndexes({{}}); |
241 } | 324 } |
242 | 325 |
243 TEST_F(NGInlineItemsBuilderTest, AppendEmptyString) { | 326 TEST_F(NGInlineItemsBuilderTest, AppendEmptyString) { |
244 EXPECT_EQ("", TestAppend("")); | 327 EXPECT_EQ("", TestAppend("")); |
245 EXPECT_EQ(0u, items_.size()); | 328 EXPECT_EQ(0u, items_.size()); |
| 329 ValidateRemovedIndexes({{}}); |
246 } | 330 } |
247 | 331 |
248 TEST_F(NGInlineItemsBuilderTest, NewLines) { | 332 TEST_F(NGInlineItemsBuilderTest, NewLines) { |
249 SetWhiteSpace(EWhiteSpace::kPre); | 333 SetWhiteSpace(EWhiteSpace::kPre); |
250 EXPECT_EQ("apple\norange\ngrape\n", TestAppend("apple\norange\ngrape\n")); | 334 EXPECT_EQ("apple\norange\ngrape\n", TestAppend("apple\norange\ngrape\n")); |
251 EXPECT_EQ(6u, items_.size()); | 335 EXPECT_EQ(6u, items_.size()); |
252 EXPECT_EQ(NGInlineItem::kText, items_[0].Type()); | 336 EXPECT_EQ(NGInlineItem::kText, items_[0].Type()); |
253 EXPECT_EQ(NGInlineItem::kControl, items_[1].Type()); | 337 EXPECT_EQ(NGInlineItem::kControl, items_[1].Type()); |
254 EXPECT_EQ(NGInlineItem::kText, items_[2].Type()); | 338 EXPECT_EQ(NGInlineItem::kText, items_[2].Type()); |
255 EXPECT_EQ(NGInlineItem::kControl, items_[3].Type()); | 339 EXPECT_EQ(NGInlineItem::kControl, items_[3].Type()); |
256 EXPECT_EQ(NGInlineItem::kText, items_[4].Type()); | 340 EXPECT_EQ(NGInlineItem::kText, items_[4].Type()); |
257 EXPECT_EQ(NGInlineItem::kControl, items_[5].Type()); | 341 EXPECT_EQ(NGInlineItem::kControl, items_[5].Type()); |
| 342 ValidateRemovedIndexes({{}}); |
258 } | 343 } |
259 | 344 |
260 TEST_F(NGInlineItemsBuilderTest, Empty) { | 345 TEST_F(NGInlineItemsBuilderTest, Empty) { |
261 Vector<NGInlineItem> items; | 346 Vector<NGInlineItem> items; |
262 NGInlineItemsBuilder builder(&items); | 347 NGInlineItemsBuilder builder(&items, &removed_indexes_); |
263 RefPtr<ComputedStyle> block_style(ComputedStyle::Create()); | 348 RefPtr<ComputedStyle> block_style(ComputedStyle::Create()); |
264 builder.EnterBlock(block_style.Get()); | 349 builder.EnterBlock(block_style.Get()); |
265 builder.ExitBlock(); | 350 builder.ExitBlock(); |
266 | 351 |
267 EXPECT_EQ("", builder.ToString()); | 352 EXPECT_EQ("", builder.ToString()); |
| 353 ValidateRemovedIndexes({}); |
268 } | 354 } |
269 | 355 |
270 TEST_F(NGInlineItemsBuilderTest, BidiBlockOverride) { | 356 TEST_F(NGInlineItemsBuilderTest, BidiBlockOverride) { |
271 Vector<NGInlineItem> items; | 357 Vector<NGInlineItem> items; |
272 NGInlineItemsBuilder builder(&items); | 358 NGInlineItemsBuilder builder(&items, &removed_indexes_); |
273 RefPtr<ComputedStyle> block_style(ComputedStyle::Create()); | 359 RefPtr<ComputedStyle> block_style(ComputedStyle::Create()); |
274 block_style->SetUnicodeBidi(UnicodeBidi::kBidiOverride); | 360 block_style->SetUnicodeBidi(UnicodeBidi::kBidiOverride); |
275 block_style->SetDirection(TextDirection::kRtl); | 361 block_style->SetDirection(TextDirection::kRtl); |
276 builder.EnterBlock(block_style.Get()); | 362 builder.EnterBlock(block_style.Get()); |
277 builder.Append("Hello", style_.Get()); | 363 builder.Append("Hello", style_.Get()); |
278 builder.ExitBlock(); | 364 builder.ExitBlock(); |
279 | 365 |
280 // Expected control characters as defined in: | 366 // Expected control characters as defined in: |
281 // https://drafts.csswg.org/css-writing-modes-3/#bidi-control-codes-injection-
table | 367 // https://drafts.csswg.org/css-writing-modes-3/#bidi-control-codes-injection-
table |
282 EXPECT_EQ(String(u"\u202E" | 368 EXPECT_EQ(String(u"\u202E" |
283 u"Hello" | 369 u"Hello" |
284 u"\u202C"), | 370 u"\u202C"), |
285 builder.ToString()); | 371 builder.ToString()); |
| 372 ValidateRemovedIndexes({{}}); |
286 } | 373 } |
287 | 374 |
288 static std::unique_ptr<LayoutInline> CreateLayoutInline( | 375 static std::unique_ptr<LayoutInline> CreateLayoutInline( |
289 void (*initialize_style)(ComputedStyle*)) { | 376 void (*initialize_style)(ComputedStyle*)) { |
290 RefPtr<ComputedStyle> style(ComputedStyle::Create()); | 377 RefPtr<ComputedStyle> style(ComputedStyle::Create()); |
291 initialize_style(style.Get()); | 378 initialize_style(style.Get()); |
292 std::unique_ptr<LayoutInline> node = WTF::MakeUnique<LayoutInline>(nullptr); | 379 std::unique_ptr<LayoutInline> node = WTF::MakeUnique<LayoutInline>(nullptr); |
293 node->SetStyleInternal(std::move(style)); | 380 node->SetStyleInternal(std::move(style)); |
294 return node; | 381 return node; |
295 } | 382 } |
296 | 383 |
297 TEST_F(NGInlineItemsBuilderTest, BidiIsolate) { | 384 TEST_F(NGInlineItemsBuilderTest, BidiIsolate) { |
298 Vector<NGInlineItem> items; | 385 Vector<NGInlineItem> items; |
299 NGInlineItemsBuilder builder(&items); | 386 NGInlineItemsBuilder builder(&items, &removed_indexes_); |
300 builder.Append("Hello ", style_.Get()); | 387 builder.Append("Hello ", style_.Get()); |
301 std::unique_ptr<LayoutInline> isolate_rtl( | 388 std::unique_ptr<LayoutInline> isolate_rtl( |
302 CreateLayoutInline([](ComputedStyle* style) { | 389 CreateLayoutInline([](ComputedStyle* style) { |
303 style->SetUnicodeBidi(UnicodeBidi::kIsolate); | 390 style->SetUnicodeBidi(UnicodeBidi::kIsolate); |
304 style->SetDirection(TextDirection::kRtl); | 391 style->SetDirection(TextDirection::kRtl); |
305 })); | 392 })); |
306 builder.EnterInline(isolate_rtl.get()); | 393 builder.EnterInline(isolate_rtl.get()); |
307 builder.Append(u"\u05E2\u05D1\u05E8\u05D9\u05EA", style_.Get()); | 394 builder.Append(u"\u05E2\u05D1\u05E8\u05D9\u05EA", style_.Get()); |
308 builder.ExitInline(isolate_rtl.get()); | 395 builder.ExitInline(isolate_rtl.get()); |
309 builder.Append(" World", style_.Get()); | 396 builder.Append(" World", style_.Get()); |
310 | 397 |
311 // Expected control characters as defined in: | 398 // Expected control characters as defined in: |
312 // https://drafts.csswg.org/css-writing-modes-3/#bidi-control-codes-injection-
table | 399 // https://drafts.csswg.org/css-writing-modes-3/#bidi-control-codes-injection-
table |
313 EXPECT_EQ(String(u"Hello " | 400 EXPECT_EQ(String(u"Hello " |
314 u"\u2067" | 401 u"\u2067" |
315 u"\u05E2\u05D1\u05E8\u05D9\u05EA" | 402 u"\u05E2\u05D1\u05E8\u05D9\u05EA" |
316 u"\u2069" | 403 u"\u2069" |
317 u" World"), | 404 u" World"), |
318 builder.ToString()); | 405 builder.ToString()); |
| 406 ValidateRemovedIndexes({{}, {}, {}}); |
319 } | 407 } |
320 | 408 |
321 TEST_F(NGInlineItemsBuilderTest, BidiIsolateOverride) { | 409 TEST_F(NGInlineItemsBuilderTest, BidiIsolateOverride) { |
322 Vector<NGInlineItem> items; | 410 Vector<NGInlineItem> items; |
323 NGInlineItemsBuilder builder(&items); | 411 NGInlineItemsBuilder builder(&items, &removed_indexes_); |
324 builder.Append("Hello ", style_.Get()); | 412 builder.Append("Hello ", style_.Get()); |
325 std::unique_ptr<LayoutInline> isolate_override_rtl( | 413 std::unique_ptr<LayoutInline> isolate_override_rtl( |
326 CreateLayoutInline([](ComputedStyle* style) { | 414 CreateLayoutInline([](ComputedStyle* style) { |
327 style->SetUnicodeBidi(UnicodeBidi::kIsolateOverride); | 415 style->SetUnicodeBidi(UnicodeBidi::kIsolateOverride); |
328 style->SetDirection(TextDirection::kRtl); | 416 style->SetDirection(TextDirection::kRtl); |
329 })); | 417 })); |
330 builder.EnterInline(isolate_override_rtl.get()); | 418 builder.EnterInline(isolate_override_rtl.get()); |
331 builder.Append(u"\u05E2\u05D1\u05E8\u05D9\u05EA", style_.Get()); | 419 builder.Append(u"\u05E2\u05D1\u05E8\u05D9\u05EA", style_.Get()); |
332 builder.ExitInline(isolate_override_rtl.get()); | 420 builder.ExitInline(isolate_override_rtl.get()); |
333 builder.Append(" World", style_.Get()); | 421 builder.Append(" World", style_.Get()); |
334 | 422 |
335 // Expected control characters as defined in: | 423 // Expected control characters as defined in: |
336 // https://drafts.csswg.org/css-writing-modes-3/#bidi-control-codes-injection-
table | 424 // https://drafts.csswg.org/css-writing-modes-3/#bidi-control-codes-injection-
table |
337 EXPECT_EQ(String(u"Hello " | 425 EXPECT_EQ(String(u"Hello " |
338 u"\u2068\u202E" | 426 u"\u2068\u202E" |
339 u"\u05E2\u05D1\u05E8\u05D9\u05EA" | 427 u"\u05E2\u05D1\u05E8\u05D9\u05EA" |
340 u"\u202C\u2069" | 428 u"\u202C\u2069" |
341 u" World"), | 429 u" World"), |
342 builder.ToString()); | 430 builder.ToString()); |
| 431 ValidateRemovedIndexes({{}, {}, {}}); |
343 } | 432 } |
344 | 433 |
345 } // namespace | 434 } // namespace |
346 | 435 |
347 } // namespace blink | 436 } // namespace blink |
OLD | NEW |