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.Release(); | 20 return style.Release(); |
20 } | 21 } |
21 | 22 |
| 23 static unsigned MaskForCollapsedIndexes(const Vector<unsigned>& indexes) { |
| 24 unsigned mask = 0; |
| 25 for (unsigned index : indexes) |
| 26 mask ^= 1u << index; |
| 27 return mask; |
| 28 } |
| 29 |
| 30 class MockOffsetMappingBuilder final : public NGOffsetMappingBuilder { |
| 31 STACK_ALLOCATED(); |
| 32 |
| 33 public: |
| 34 MockOffsetMappingBuilder() = default; |
| 35 ~MockOffsetMappingBuilder() final = default; |
| 36 |
| 37 void AppendBijection(unsigned length) final { |
| 38 ASSERT_LT(0u, length); |
| 39 ASSERT_GE(32u, total_length_ + length); |
| 40 total_length_ += length; |
| 41 } |
| 42 |
| 43 void AppendCollapsed(unsigned length) final { |
| 44 ASSERT_LT(0u, length); |
| 45 ASSERT_GE(32u, total_length_ + length); |
| 46 mask_ |= ((1u << length) - 1) << total_length_; |
| 47 total_length_ += length; |
| 48 } |
| 49 |
| 50 void CollapseLastCharacter() final { |
| 51 ASSERT_NE((1u << total_length_) - 1, mask_); |
| 52 for (unsigned i = (1u << total_length_); i >>= 1;) { |
| 53 if (!(mask_ & i)) { |
| 54 mask_ ^= i; |
| 55 return; |
| 56 } |
| 57 } |
| 58 } |
| 59 |
| 60 unsigned GetMask() const { return mask_; } |
| 61 |
| 62 private: |
| 63 unsigned total_length_ = 0; |
| 64 unsigned mask_ = 0; |
| 65 |
| 66 DISALLOW_COPY_AND_ASSIGN(MockOffsetMappingBuilder); |
| 67 }; |
| 68 |
22 class NGInlineItemsBuilderTest : public ::testing::Test { | 69 class NGInlineItemsBuilderTest : public ::testing::Test { |
23 protected: | 70 protected: |
24 void SetUp() override { style_ = ComputedStyle::Create(); } | 71 void SetUp() override { style_ = ComputedStyle::Create(); } |
25 | 72 |
26 void SetWhiteSpace(EWhiteSpace whitespace) { | 73 void SetWhiteSpace(EWhiteSpace whitespace) { |
27 style_->SetWhiteSpace(whitespace); | 74 style_->SetWhiteSpace(whitespace); |
28 } | 75 } |
29 | 76 |
30 const String& TestAppend(const String inputs[], int size) { | 77 const String& TestAppend(const String inputs[], int size) { |
31 items_.clear(); | 78 items_.clear(); |
32 NGInlineItemsBuilder builder(&items_); | 79 MockOffsetMappingBuilder mapping_builder; |
| 80 NGInlineItemsBuilder builder(&items_, &mapping_builder); |
33 for (int i = 0; i < size; i++) | 81 for (int i = 0; i < size; i++) |
34 builder.Append(inputs[i], style_.Get()); | 82 builder.Append(inputs[i], style_.Get()); |
35 text_ = builder.ToString(); | 83 text_ = builder.ToString(); |
36 ValidateItems(); | 84 ValidateItems(); |
| 85 mask_ = mapping_builder.GetMask(); |
37 return text_; | 86 return text_; |
38 } | 87 } |
39 | 88 |
40 const String& TestAppend(const String& input) { | 89 const String& TestAppend(const String& input) { |
41 String inputs[] = {input}; | 90 String inputs[] = {input}; |
42 return TestAppend(inputs, 1); | 91 return TestAppend(inputs, 1); |
43 } | 92 } |
44 | 93 |
45 const String& TestAppend(const String& input1, const String& input2) { | 94 const String& TestAppend(const String& input1, const String& input2) { |
46 String inputs[] = {input1, input2}; | 95 String inputs[] = {input1, input2}; |
(...skipping 13 matching lines...) Expand all Loading... |
60 const NGInlineItem& item = items_[i]; | 109 const NGInlineItem& item = items_[i]; |
61 EXPECT_EQ(current_offset, item.StartOffset()); | 110 EXPECT_EQ(current_offset, item.StartOffset()); |
62 EXPECT_LT(item.StartOffset(), item.EndOffset()); | 111 EXPECT_LT(item.StartOffset(), item.EndOffset()); |
63 current_offset = item.EndOffset(); | 112 current_offset = item.EndOffset(); |
64 } | 113 } |
65 EXPECT_EQ(current_offset, text_.length()); | 114 EXPECT_EQ(current_offset, text_.length()); |
66 } | 115 } |
67 | 116 |
68 Vector<NGInlineItem> items_; | 117 Vector<NGInlineItem> items_; |
69 String text_; | 118 String text_; |
| 119 unsigned mask_; |
70 RefPtr<ComputedStyle> style_; | 120 RefPtr<ComputedStyle> style_; |
71 }; | 121 }; |
72 | 122 |
73 #define TestWhitespaceValue(expected, input, whitespace) \ | 123 #define TestWhitespaceValue(expected_text, expected_mask, input, whitespace) \ |
74 SetWhiteSpace(whitespace); \ | 124 SetWhiteSpace(whitespace); \ |
75 EXPECT_EQ(expected, TestAppend(input)) << "white-space: " #whitespace; | 125 EXPECT_EQ(expected_text, TestAppend(input)) << "white-space: " #whitespace; \ |
| 126 EXPECT_EQ(expected_mask, mask_); |
76 | 127 |
77 TEST_F(NGInlineItemsBuilderTest, CollapseSpaces) { | 128 TEST_F(NGInlineItemsBuilderTest, CollapseSpaces) { |
78 String input("text text text text"); | 129 String input("text text text text"); |
79 String collapsed("text text text text"); | 130 String collapsed("text text text text"); |
80 TestWhitespaceValue(collapsed, input, EWhiteSpace::kNormal); | 131 unsigned collapsed_mask = MaskForCollapsedIndexes({10, 16, 17}); |
81 TestWhitespaceValue(collapsed, input, EWhiteSpace::kNowrap); | 132 TestWhitespaceValue(collapsed, collapsed_mask, input, EWhiteSpace::kNormal); |
82 TestWhitespaceValue(collapsed, input, EWhiteSpace::kWebkitNowrap); | 133 TestWhitespaceValue(collapsed, collapsed_mask, input, EWhiteSpace::kNowrap); |
83 TestWhitespaceValue(collapsed, input, EWhiteSpace::kPreLine); | 134 TestWhitespaceValue(collapsed, collapsed_mask, input, |
84 TestWhitespaceValue(input, input, EWhiteSpace::kPre); | 135 EWhiteSpace::kWebkitNowrap); |
85 TestWhitespaceValue(input, input, EWhiteSpace::kPreWrap); | 136 TestWhitespaceValue(collapsed, collapsed_mask, input, EWhiteSpace::kPreLine); |
| 137 TestWhitespaceValue(input, 0u, input, EWhiteSpace::kPre); |
| 138 TestWhitespaceValue(input, 0u, input, EWhiteSpace::kPreWrap); |
86 } | 139 } |
87 | 140 |
88 TEST_F(NGInlineItemsBuilderTest, CollapseTabs) { | 141 TEST_F(NGInlineItemsBuilderTest, CollapseTabs) { |
89 String input("text\ttext\t text \t text"); | 142 String input("text\ttext\t text \t text"); |
90 String collapsed("text text text text"); | 143 String collapsed("text text text text"); |
91 TestWhitespaceValue(collapsed, input, EWhiteSpace::kNormal); | 144 unsigned collapsed_mask = MaskForCollapsedIndexes({10, 16, 17}); |
92 TestWhitespaceValue(collapsed, input, EWhiteSpace::kNowrap); | 145 TestWhitespaceValue(collapsed, collapsed_mask, input, EWhiteSpace::kNormal); |
93 TestWhitespaceValue(collapsed, input, EWhiteSpace::kWebkitNowrap); | 146 TestWhitespaceValue(collapsed, collapsed_mask, input, EWhiteSpace::kNowrap); |
94 TestWhitespaceValue(collapsed, input, EWhiteSpace::kPreLine); | 147 TestWhitespaceValue(collapsed, collapsed_mask, input, |
95 TestWhitespaceValue(input, input, EWhiteSpace::kPre); | 148 EWhiteSpace::kWebkitNowrap); |
96 TestWhitespaceValue(input, input, EWhiteSpace::kPreWrap); | 149 TestWhitespaceValue(collapsed, collapsed_mask, input, EWhiteSpace::kPreLine); |
| 150 TestWhitespaceValue(input, 0u, input, EWhiteSpace::kPre); |
| 151 TestWhitespaceValue(input, 0u, input, EWhiteSpace::kPreWrap); |
97 } | 152 } |
98 | 153 |
99 TEST_F(NGInlineItemsBuilderTest, CollapseNewLines) { | 154 TEST_F(NGInlineItemsBuilderTest, CollapseNewLines) { |
100 String input("text\ntext \n text\n\ntext"); | 155 String input("text\ntext \n text\n\ntext"); |
101 String collapsed("text text text text"); | 156 String collapsed("text text text text"); |
102 TestWhitespaceValue(collapsed, input, EWhiteSpace::kNormal); | 157 unsigned collapsed_mask = MaskForCollapsedIndexes({10, 11, 17}); |
103 TestWhitespaceValue(collapsed, input, EWhiteSpace::kNowrap); | 158 TestWhitespaceValue(collapsed, collapsed_mask, input, EWhiteSpace::kNormal); |
104 TestWhitespaceValue("text\ntext\ntext\n\ntext", input, EWhiteSpace::kPreLine); | 159 TestWhitespaceValue(collapsed, collapsed_mask, input, EWhiteSpace::kNowrap); |
105 TestWhitespaceValue(input, input, EWhiteSpace::kPre); | 160 TestWhitespaceValue("text\ntext\ntext\n\ntext", |
106 TestWhitespaceValue(input, input, EWhiteSpace::kPreWrap); | 161 MaskForCollapsedIndexes({9, 11}), input, |
| 162 EWhiteSpace::kPreLine); |
| 163 TestWhitespaceValue(input, 0u, input, EWhiteSpace::kPre); |
| 164 TestWhitespaceValue(input, 0u, input, EWhiteSpace::kPreWrap); |
107 } | 165 } |
108 | 166 |
109 TEST_F(NGInlineItemsBuilderTest, CollapseNewlinesAsSpaces) { | 167 TEST_F(NGInlineItemsBuilderTest, CollapseNewlinesAsSpaces) { |
110 EXPECT_EQ("text text", TestAppend("text\ntext")); | 168 EXPECT_EQ("text text", TestAppend("text\ntext")); |
| 169 EXPECT_EQ(0u, mask_); |
111 EXPECT_EQ("text text", TestAppend("text\n\ntext")); | 170 EXPECT_EQ("text text", TestAppend("text\n\ntext")); |
| 171 EXPECT_EQ(MaskForCollapsedIndexes({5}), mask_); |
112 EXPECT_EQ("text text", TestAppend("text \n\n text")); | 172 EXPECT_EQ("text text", TestAppend("text \n\n text")); |
| 173 EXPECT_EQ(MaskForCollapsedIndexes({5, 6, 7}), mask_); |
113 EXPECT_EQ("text text", TestAppend("text \n \n text")); | 174 EXPECT_EQ("text text", TestAppend("text \n \n text")); |
| 175 EXPECT_EQ(MaskForCollapsedIndexes({5, 6, 7, 8}), mask_); |
114 } | 176 } |
115 | 177 |
116 TEST_F(NGInlineItemsBuilderTest, CollapseAcrossElements) { | 178 TEST_F(NGInlineItemsBuilderTest, CollapseAcrossElements) { |
117 EXPECT_EQ("text text", TestAppend("text ", " text")) | 179 EXPECT_EQ("text text", TestAppend("text ", " text")) |
118 << "Spaces are collapsed even when across elements."; | 180 << "Spaces are collapsed even when across elements."; |
| 181 EXPECT_EQ(MaskForCollapsedIndexes({5}), mask_); |
119 } | 182 } |
120 | 183 |
121 TEST_F(NGInlineItemsBuilderTest, CollapseLeadingSpaces) { | 184 TEST_F(NGInlineItemsBuilderTest, CollapseLeadingSpaces) { |
122 EXPECT_EQ("text", TestAppend(" text")); | 185 EXPECT_EQ("text", TestAppend(" text")); |
| 186 EXPECT_EQ(MaskForCollapsedIndexes({0, 1}), mask_); |
123 EXPECT_EQ("text", TestAppend(" ", "text")); | 187 EXPECT_EQ("text", TestAppend(" ", "text")); |
| 188 EXPECT_EQ(MaskForCollapsedIndexes({0}), mask_); |
124 EXPECT_EQ("text", TestAppend(" ", " text")); | 189 EXPECT_EQ("text", TestAppend(" ", " text")); |
| 190 EXPECT_EQ(MaskForCollapsedIndexes({0, 1}), mask_); |
125 } | 191 } |
126 | 192 |
127 TEST_F(NGInlineItemsBuilderTest, CollapseTrailingSpaces) { | 193 TEST_F(NGInlineItemsBuilderTest, CollapseTrailingSpaces) { |
128 EXPECT_EQ("text", TestAppend("text ")); | 194 EXPECT_EQ("text", TestAppend("text ")); |
| 195 EXPECT_EQ(MaskForCollapsedIndexes({4, 5}), mask_); |
129 EXPECT_EQ("text", TestAppend("text", " ")); | 196 EXPECT_EQ("text", TestAppend("text", " ")); |
| 197 EXPECT_EQ(MaskForCollapsedIndexes({4}), mask_); |
130 EXPECT_EQ("text", TestAppend("text ", " ")); | 198 EXPECT_EQ("text", TestAppend("text ", " ")); |
| 199 EXPECT_EQ(MaskForCollapsedIndexes({4, 5}), mask_); |
131 } | 200 } |
132 | 201 |
133 TEST_F(NGInlineItemsBuilderTest, CollapseAllSpaces) { | 202 TEST_F(NGInlineItemsBuilderTest, CollapseAllSpaces) { |
134 EXPECT_EQ("", TestAppend(" ")); | 203 EXPECT_EQ("", TestAppend(" ")); |
| 204 EXPECT_EQ(MaskForCollapsedIndexes({0, 1}), mask_); |
135 EXPECT_EQ("", TestAppend(" ", " ")); | 205 EXPECT_EQ("", TestAppend(" ", " ")); |
| 206 EXPECT_EQ(MaskForCollapsedIndexes({0, 1, 2, 3}), mask_); |
136 EXPECT_EQ("", TestAppend(" ", "\n")); | 207 EXPECT_EQ("", TestAppend(" ", "\n")); |
| 208 EXPECT_EQ(MaskForCollapsedIndexes({0, 1, 2}), mask_); |
137 EXPECT_EQ("", TestAppend("\n", " ")); | 209 EXPECT_EQ("", TestAppend("\n", " ")); |
| 210 EXPECT_EQ(MaskForCollapsedIndexes({0, 1, 2}), mask_); |
138 } | 211 } |
139 | 212 |
140 TEST_F(NGInlineItemsBuilderTest, CollapseLeadingNewlines) { | 213 TEST_F(NGInlineItemsBuilderTest, CollapseLeadingNewlines) { |
141 EXPECT_EQ("text", TestAppend("\ntext")); | 214 EXPECT_EQ("text", TestAppend("\ntext")); |
| 215 EXPECT_EQ(MaskForCollapsedIndexes({0}), mask_); |
142 EXPECT_EQ("text", TestAppend("\n\ntext")); | 216 EXPECT_EQ("text", TestAppend("\n\ntext")); |
| 217 EXPECT_EQ(MaskForCollapsedIndexes({0, 1}), mask_); |
143 EXPECT_EQ("text", TestAppend("\n", "text")); | 218 EXPECT_EQ("text", TestAppend("\n", "text")); |
| 219 EXPECT_EQ(MaskForCollapsedIndexes({0}), mask_); |
144 EXPECT_EQ("text", TestAppend("\n\n", "text")); | 220 EXPECT_EQ("text", TestAppend("\n\n", "text")); |
| 221 EXPECT_EQ(MaskForCollapsedIndexes({0, 1}), mask_); |
145 EXPECT_EQ("text", TestAppend(" \n", "text")); | 222 EXPECT_EQ("text", TestAppend(" \n", "text")); |
| 223 EXPECT_EQ(MaskForCollapsedIndexes({0, 1}), mask_); |
146 EXPECT_EQ("text", TestAppend("\n", " text")); | 224 EXPECT_EQ("text", TestAppend("\n", " text")); |
| 225 EXPECT_EQ(MaskForCollapsedIndexes({0, 1}), mask_); |
147 EXPECT_EQ("text", TestAppend("\n\n", " text")); | 226 EXPECT_EQ("text", TestAppend("\n\n", " text")); |
| 227 EXPECT_EQ(MaskForCollapsedIndexes({0, 1, 2}), mask_); |
148 EXPECT_EQ("text", TestAppend(" \n", " text")); | 228 EXPECT_EQ("text", TestAppend(" \n", " text")); |
| 229 EXPECT_EQ(MaskForCollapsedIndexes({0, 1, 2}), mask_); |
149 EXPECT_EQ("text", TestAppend("\n", "\ntext")); | 230 EXPECT_EQ("text", TestAppend("\n", "\ntext")); |
| 231 EXPECT_EQ(MaskForCollapsedIndexes({0, 1}), mask_); |
150 EXPECT_EQ("text", TestAppend("\n\n", "\ntext")); | 232 EXPECT_EQ("text", TestAppend("\n\n", "\ntext")); |
| 233 EXPECT_EQ(MaskForCollapsedIndexes({0, 1, 2}), mask_); |
151 EXPECT_EQ("text", TestAppend(" \n", "\ntext")); | 234 EXPECT_EQ("text", TestAppend(" \n", "\ntext")); |
| 235 EXPECT_EQ(MaskForCollapsedIndexes({0, 1, 2}), mask_); |
152 } | 236 } |
153 | 237 |
154 TEST_F(NGInlineItemsBuilderTest, CollapseTrailingNewlines) { | 238 TEST_F(NGInlineItemsBuilderTest, CollapseTrailingNewlines) { |
155 EXPECT_EQ("text", TestAppend("text\n")); | 239 EXPECT_EQ("text", TestAppend("text\n")); |
| 240 EXPECT_EQ(MaskForCollapsedIndexes({4}), mask_); |
156 EXPECT_EQ("text", TestAppend("text", "\n")); | 241 EXPECT_EQ("text", TestAppend("text", "\n")); |
| 242 EXPECT_EQ(MaskForCollapsedIndexes({4}), mask_); |
157 EXPECT_EQ("text", TestAppend("text\n", "\n")); | 243 EXPECT_EQ("text", TestAppend("text\n", "\n")); |
| 244 EXPECT_EQ(MaskForCollapsedIndexes({4, 5}), mask_); |
158 EXPECT_EQ("text", TestAppend("text\n", " ")); | 245 EXPECT_EQ("text", TestAppend("text\n", " ")); |
| 246 EXPECT_EQ(MaskForCollapsedIndexes({4, 5}), mask_); |
159 EXPECT_EQ("text", TestAppend("text ", "\n")); | 247 EXPECT_EQ("text", TestAppend("text ", "\n")); |
| 248 EXPECT_EQ(MaskForCollapsedIndexes({4, 5}), mask_); |
160 } | 249 } |
161 | 250 |
162 TEST_F(NGInlineItemsBuilderTest, CollapseBeforeNewlineAcrossElements) { | 251 TEST_F(NGInlineItemsBuilderTest, CollapseBeforeNewlineAcrossElements) { |
163 EXPECT_EQ("text text", TestAppend("text ", "\ntext")); | 252 EXPECT_EQ("text text", TestAppend("text ", "\ntext")); |
| 253 EXPECT_EQ(MaskForCollapsedIndexes({5}), mask_); |
164 EXPECT_EQ("text text", TestAppend("text", " ", "\ntext")); | 254 EXPECT_EQ("text text", TestAppend("text", " ", "\ntext")); |
| 255 EXPECT_EQ(MaskForCollapsedIndexes({5}), mask_); |
165 } | 256 } |
166 | 257 |
167 TEST_F(NGInlineItemsBuilderTest, CollapseBeforeAndAfterNewline) { | 258 TEST_F(NGInlineItemsBuilderTest, CollapseBeforeAndAfterNewline) { |
168 SetWhiteSpace(EWhiteSpace::kPreLine); | 259 SetWhiteSpace(EWhiteSpace::kPreLine); |
169 EXPECT_EQ("text\ntext", TestAppend("text \n text")) | 260 EXPECT_EQ("text\ntext", TestAppend("text \n text")) |
170 << "Spaces before and after newline are removed."; | 261 << "Spaces before and after newline are removed."; |
| 262 EXPECT_EQ(MaskForCollapsedIndexes({4, 5, 7, 8}), mask_); |
171 } | 263 } |
172 | 264 |
173 TEST_F(NGInlineItemsBuilderTest, | 265 TEST_F(NGInlineItemsBuilderTest, |
174 CollapsibleSpaceAfterNonCollapsibleSpaceAcrossElements) { | 266 CollapsibleSpaceAfterNonCollapsibleSpaceAcrossElements) { |
175 NGInlineItemsBuilder builder(&items_); | 267 MockOffsetMappingBuilder mapping_builder; |
| 268 NGInlineItemsBuilder builder(&items_, &mapping_builder); |
176 RefPtr<ComputedStyle> pre_wrap(CreateWhitespaceStyle(EWhiteSpace::kPreWrap)); | 269 RefPtr<ComputedStyle> pre_wrap(CreateWhitespaceStyle(EWhiteSpace::kPreWrap)); |
177 builder.Append("text ", pre_wrap.Get()); | 270 builder.Append("text ", pre_wrap.Get()); |
178 builder.Append(" text", style_.Get()); | 271 builder.Append(" text", style_.Get()); |
179 EXPECT_EQ("text text", builder.ToString()) | 272 EXPECT_EQ("text text", builder.ToString()) |
180 << "The whitespace in constructions like '<span style=\"white-space: " | 273 << "The whitespace in constructions like '<span style=\"white-space: " |
181 "pre-wrap\">text <span><span> text</span>' does not collapse."; | 274 "pre-wrap\">text <span><span> text</span>' does not collapse."; |
| 275 EXPECT_EQ(0u, mapping_builder.GetMask()); |
182 } | 276 } |
183 | 277 |
184 TEST_F(NGInlineItemsBuilderTest, CollapseZeroWidthSpaces) { | 278 TEST_F(NGInlineItemsBuilderTest, CollapseZeroWidthSpaces) { |
185 EXPECT_EQ(String(u"text\u200Btext"), TestAppend(u"text\u200B\ntext")) | 279 EXPECT_EQ(String(u"text\u200Btext"), TestAppend(u"text\u200B\ntext")) |
186 << "Newline is removed if the character before is ZWS."; | 280 << "Newline is removed if the character before is ZWS."; |
| 281 EXPECT_EQ(MaskForCollapsedIndexes({5}), mask_); |
187 EXPECT_EQ(String(u"text\u200Btext"), TestAppend(u"text\n\u200Btext")) | 282 EXPECT_EQ(String(u"text\u200Btext"), TestAppend(u"text\n\u200Btext")) |
188 << "Newline is removed if the character after is ZWS."; | 283 << "Newline is removed if the character after is ZWS."; |
| 284 EXPECT_EQ(MaskForCollapsedIndexes({4}), mask_); |
189 EXPECT_EQ(String(u"text\u200B\u200Btext"), | 285 EXPECT_EQ(String(u"text\u200B\u200Btext"), |
190 TestAppend(u"text\u200B\n\u200Btext")) | 286 TestAppend(u"text\u200B\n\u200Btext")) |
191 << "Newline is removed if the character before/after is ZWS."; | 287 << "Newline is removed if the character before/after is ZWS."; |
| 288 EXPECT_EQ(MaskForCollapsedIndexes({5}), mask_); |
192 | 289 |
193 EXPECT_EQ(String(u"text\u200Btext"), TestAppend(u"text\n", u"\u200Btext")) | 290 EXPECT_EQ(String(u"text\u200Btext"), TestAppend(u"text\n", u"\u200Btext")) |
194 << "Newline is removed if the character after across elements is ZWS."; | 291 << "Newline is removed if the character after across elements is ZWS."; |
| 292 EXPECT_EQ(MaskForCollapsedIndexes({4}), mask_); |
195 EXPECT_EQ(String(u"text\u200Btext"), TestAppend(u"text\u200B", u"\ntext")) | 293 EXPECT_EQ(String(u"text\u200Btext"), TestAppend(u"text\u200B", u"\ntext")) |
196 << "Newline is removed if the character before is ZWS even across " | 294 << "Newline is removed if the character before is ZWS even across " |
197 "elements."; | 295 "elements."; |
| 296 EXPECT_EQ(MaskForCollapsedIndexes({5}), mask_); |
198 | 297 |
199 EXPECT_EQ(String(u"text\u200Btext"), TestAppend(u"text \n", u"\u200Btext")) | 298 EXPECT_EQ(String(u"text\u200Btext"), TestAppend(u"text \n", u"\u200Btext")) |
200 << "Collapsible space before newline does not affect the result."; | 299 << "Collapsible space before newline does not affect the result."; |
| 300 EXPECT_EQ(MaskForCollapsedIndexes({4, 5}), mask_); |
201 | 301 |
202 EXPECT_EQ(String(u"text\u200Btext"), TestAppend(u"text\u200B\n", u" text")) | 302 EXPECT_EQ(String(u"text\u200Btext"), TestAppend(u"text\u200B\n", u" text")) |
203 << "Collapsible space after newline is removed even when the " | 303 << "Collapsible space after newline is removed even when the " |
204 "newline was removed."; | 304 "newline was removed."; |
| 305 EXPECT_EQ(MaskForCollapsedIndexes({5, 6}), mask_); |
205 } | 306 } |
206 | 307 |
207 TEST_F(NGInlineItemsBuilderTest, CollapseEastAsianWidth) { | 308 TEST_F(NGInlineItemsBuilderTest, CollapseEastAsianWidth) { |
208 EXPECT_EQ(String(u"\u4E00\u4E00"), TestAppend(u"\u4E00\n\u4E00")) | 309 EXPECT_EQ(String(u"\u4E00\u4E00"), TestAppend(u"\u4E00\n\u4E00")) |
209 << "Newline is removed when both sides are Wide."; | 310 << "Newline is removed when both sides are Wide."; |
| 311 EXPECT_EQ(MaskForCollapsedIndexes({1}), mask_); |
210 | 312 |
211 EXPECT_EQ(String(u"\u4E00 A"), TestAppend(u"\u4E00\nA")) | 313 EXPECT_EQ(String(u"\u4E00 A"), TestAppend(u"\u4E00\nA")) |
212 << "Newline is not removed when after is Narrow."; | 314 << "Newline is not removed when after is Narrow."; |
| 315 EXPECT_EQ(0u, mask_); |
213 EXPECT_EQ(String(u"A \u4E00"), TestAppend(u"A\n\u4E00")) | 316 EXPECT_EQ(String(u"A \u4E00"), TestAppend(u"A\n\u4E00")) |
214 << "Newline is not removed when before is Narrow."; | 317 << "Newline is not removed when before is Narrow."; |
| 318 EXPECT_EQ(0u, mask_); |
215 | 319 |
216 EXPECT_EQ(String(u"\u4E00\u4E00"), TestAppend(u"\u4E00\n", u"\u4E00")) | 320 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."; | 321 << "Newline at the end of elements is removed when both sides are Wide."; |
| 322 EXPECT_EQ(MaskForCollapsedIndexes({1}), mask_); |
218 EXPECT_EQ(String(u"\u4E00\u4E00"), TestAppend(u"\u4E00", u"\n\u4E00")) | 323 EXPECT_EQ(String(u"\u4E00\u4E00"), TestAppend(u"\u4E00", u"\n\u4E00")) |
219 << "Newline at the beginning of elements is removed " | 324 << "Newline at the beginning of elements is removed " |
220 "when both sides are Wide."; | 325 "when both sides are Wide."; |
| 326 EXPECT_EQ(MaskForCollapsedIndexes({1}), mask_); |
221 } | 327 } |
222 | 328 |
223 TEST_F(NGInlineItemsBuilderTest, CollapseAroundReplacedElement) { | 329 TEST_F(NGInlineItemsBuilderTest, CollapseAroundReplacedElement) { |
224 NGInlineItemsBuilder builder(&items_); | 330 MockOffsetMappingBuilder mapping_builder; |
| 331 NGInlineItemsBuilder builder(&items_, &mapping_builder); |
225 builder.Append("Hello ", style_.Get()); | 332 builder.Append("Hello ", style_.Get()); |
226 builder.Append(NGInlineItem::kAtomicInline, kObjectReplacementCharacter); | 333 builder.Append(NGInlineItem::kAtomicInline, kObjectReplacementCharacter); |
227 builder.Append(" World", style_.Get()); | 334 builder.Append(" World", style_.Get()); |
228 EXPECT_EQ(String(u"Hello \uFFFC World"), builder.ToString()); | 335 EXPECT_EQ(String(u"Hello \uFFFC World"), builder.ToString()); |
| 336 EXPECT_EQ(0u, mapping_builder.GetMask()); |
229 } | 337 } |
230 | 338 |
231 TEST_F(NGInlineItemsBuilderTest, CollapseNewlineAfterObject) { | 339 TEST_F(NGInlineItemsBuilderTest, CollapseNewlineAfterObject) { |
232 NGInlineItemsBuilder builder(&items_); | 340 MockOffsetMappingBuilder mapping_builder; |
| 341 NGInlineItemsBuilder builder(&items_, &mapping_builder); |
233 builder.Append(NGInlineItem::kAtomicInline, kObjectReplacementCharacter); | 342 builder.Append(NGInlineItem::kAtomicInline, kObjectReplacementCharacter); |
234 builder.Append("\n", style_.Get()); | 343 builder.Append("\n", style_.Get()); |
235 builder.Append(NGInlineItem::kAtomicInline, kObjectReplacementCharacter); | 344 builder.Append(NGInlineItem::kAtomicInline, kObjectReplacementCharacter); |
236 EXPECT_EQ(String(u"\uFFFC \uFFFC"), builder.ToString()); | 345 EXPECT_EQ(String(u"\uFFFC \uFFFC"), builder.ToString()); |
237 EXPECT_EQ(3u, items_.size()); | 346 EXPECT_EQ(3u, items_.size()); |
238 EXPECT_EQ(nullptr, items_[0].Style()); | 347 EXPECT_EQ(nullptr, items_[0].Style()); |
239 EXPECT_EQ(style_.Get(), items_[1].Style()); | 348 EXPECT_EQ(style_.Get(), items_[1].Style()); |
240 EXPECT_EQ(nullptr, items_[2].Style()); | 349 EXPECT_EQ(nullptr, items_[2].Style()); |
| 350 EXPECT_EQ(0u, mapping_builder.GetMask()); |
241 } | 351 } |
242 | 352 |
243 TEST_F(NGInlineItemsBuilderTest, AppendEmptyString) { | 353 TEST_F(NGInlineItemsBuilderTest, AppendEmptyString) { |
244 EXPECT_EQ("", TestAppend("")); | 354 EXPECT_EQ("", TestAppend("")); |
| 355 EXPECT_EQ(0u, mask_); |
245 EXPECT_EQ(0u, items_.size()); | 356 EXPECT_EQ(0u, items_.size()); |
246 } | 357 } |
247 | 358 |
248 TEST_F(NGInlineItemsBuilderTest, NewLines) { | 359 TEST_F(NGInlineItemsBuilderTest, NewLines) { |
249 SetWhiteSpace(EWhiteSpace::kPre); | 360 SetWhiteSpace(EWhiteSpace::kPre); |
250 EXPECT_EQ("apple\norange\ngrape\n", TestAppend("apple\norange\ngrape\n")); | 361 EXPECT_EQ("apple\norange\ngrape\n", TestAppend("apple\norange\ngrape\n")); |
| 362 EXPECT_EQ(0u, mask_); |
251 EXPECT_EQ(6u, items_.size()); | 363 EXPECT_EQ(6u, items_.size()); |
252 EXPECT_EQ(NGInlineItem::kText, items_[0].Type()); | 364 EXPECT_EQ(NGInlineItem::kText, items_[0].Type()); |
253 EXPECT_EQ(NGInlineItem::kControl, items_[1].Type()); | 365 EXPECT_EQ(NGInlineItem::kControl, items_[1].Type()); |
254 EXPECT_EQ(NGInlineItem::kText, items_[2].Type()); | 366 EXPECT_EQ(NGInlineItem::kText, items_[2].Type()); |
255 EXPECT_EQ(NGInlineItem::kControl, items_[3].Type()); | 367 EXPECT_EQ(NGInlineItem::kControl, items_[3].Type()); |
256 EXPECT_EQ(NGInlineItem::kText, items_[4].Type()); | 368 EXPECT_EQ(NGInlineItem::kText, items_[4].Type()); |
257 EXPECT_EQ(NGInlineItem::kControl, items_[5].Type()); | 369 EXPECT_EQ(NGInlineItem::kControl, items_[5].Type()); |
258 } | 370 } |
259 | 371 |
260 TEST_F(NGInlineItemsBuilderTest, Empty) { | 372 TEST_F(NGInlineItemsBuilderTest, Empty) { |
261 Vector<NGInlineItem> items; | 373 Vector<NGInlineItem> items; |
262 NGInlineItemsBuilder builder(&items); | 374 MockOffsetMappingBuilder mapping_builder; |
| 375 NGInlineItemsBuilder builder(&items, &mapping_builder); |
263 RefPtr<ComputedStyle> block_style(ComputedStyle::Create()); | 376 RefPtr<ComputedStyle> block_style(ComputedStyle::Create()); |
264 builder.EnterBlock(block_style.Get()); | 377 builder.EnterBlock(block_style.Get()); |
265 builder.ExitBlock(); | 378 builder.ExitBlock(); |
266 | 379 |
267 EXPECT_EQ("", builder.ToString()); | 380 EXPECT_EQ("", builder.ToString()); |
| 381 EXPECT_EQ(0u, mapping_builder.GetMask()); |
268 } | 382 } |
269 | 383 |
270 TEST_F(NGInlineItemsBuilderTest, BidiBlockOverride) { | 384 TEST_F(NGInlineItemsBuilderTest, BidiBlockOverride) { |
271 Vector<NGInlineItem> items; | 385 Vector<NGInlineItem> items; |
272 NGInlineItemsBuilder builder(&items); | 386 NGInlineItemsBuilder builder(&items); |
273 RefPtr<ComputedStyle> block_style(ComputedStyle::Create()); | 387 RefPtr<ComputedStyle> block_style(ComputedStyle::Create()); |
274 block_style->SetUnicodeBidi(UnicodeBidi::kBidiOverride); | 388 block_style->SetUnicodeBidi(UnicodeBidi::kBidiOverride); |
275 block_style->SetDirection(TextDirection::kRtl); | 389 block_style->SetDirection(TextDirection::kRtl); |
276 builder.EnterBlock(block_style.Get()); | 390 builder.EnterBlock(block_style.Get()); |
277 builder.Append("Hello", style_.Get()); | 391 builder.Append("Hello", style_.Get()); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 u"\u2068\u202E" | 452 u"\u2068\u202E" |
339 u"\u05E2\u05D1\u05E8\u05D9\u05EA" | 453 u"\u05E2\u05D1\u05E8\u05D9\u05EA" |
340 u"\u202C\u2069" | 454 u"\u202C\u2069" |
341 u" World"), | 455 u" World"), |
342 builder.ToString()); | 456 builder.ToString()); |
343 } | 457 } |
344 | 458 |
345 } // namespace | 459 } // namespace |
346 | 460 |
347 } // namespace blink | 461 } // namespace blink |
OLD | NEW |