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