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