Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(546)

Side by Side Diff: Source/core/editing/FrameSelectionTest.cpp

Issue 1123563003: Improving direction-based selection strategy. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Adding StrategyState enum to replace m_cleared, m_lastMoveShrunkSelection. Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "config.h" 5 #include "config.h"
6 #include "core/editing/FrameSelection.h" 6 #include "core/editing/FrameSelection.h"
7 7
8 #include "bindings/core/v8/ExceptionStatePlaceholder.h" 8 #include "bindings/core/v8/ExceptionStatePlaceholder.h"
9 #include "core/dom/Document.h" 9 #include "core/dom/Document.h"
10 #include "core/dom/Element.h" 10 #include "core/dom/Element.h"
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 return m_dummyPageHolder->frame().selection(); 64 return m_dummyPageHolder->frame().selection();
65 } 65 }
66 66
67 PassRefPtrWillBeRawPtr<Text> FrameSelectionTest::appendTextNode(const String& da ta) 67 PassRefPtrWillBeRawPtr<Text> FrameSelectionTest::appendTextNode(const String& da ta)
68 { 68 {
69 RefPtrWillBeRawPtr<Text> text = document().createTextNode(data); 69 RefPtrWillBeRawPtr<Text> text = document().createTextNode(data);
70 document().body()->appendChild(text); 70 document().body()->appendChild(text);
71 return text.release(); 71 return text.release();
72 } 72 }
73 73
74 IntPoint visiblePositionToContentsPoint(const VisiblePosition& pos)
75 {
76 return pos.absoluteCaretBounds().minXMinYCorner();
leviw_travelin_and_unemployed 2015/05/20 20:24:37 The minXMinYCorner is definitely what you want? Ho
mfomitchev 2015/05/20 21:37:29 I don't think y matters here, but I do want minX.
77 }
78
79 // Parses a text node populating the supplied vectors with positions of letters
80 // and words middles in the text. Whitespaces are not considered as separate wor ds.
81 void parseString(Text* text, std::vector<IntPoint>& letterPos, std::vector<IntPo int>& wordMiddles)
82 {
83 WTF::String str = text->wholeText();
84 int wordStartIndex = -1;
85 for (size_t i = 0; i < str.length(); i++) {
86 letterPos.push_back(visiblePositionToContentsPoint(VisiblePosition(Posit ion(text, i))));
leviw_travelin_and_unemployed 2015/05/20 20:24:37 Nit: Generally it would be cheaper to iterate on V
mfomitchev 2015/05/20 21:37:29 Acknowledged. I will clean it up after the rest of
87 char c = str.characterAt(i);
88 if (isASCIIAlphanumeric(c) && wordStartIndex < 0) {
89 wordStartIndex = i;
90 } else if (!isASCIIAlphanumeric(c) && wordStartIndex >= 0) {
91 IntPoint wordMiddle((letterPos[wordStartIndex].x() + letterPos[i].x( )) / 2, letterPos[wordStartIndex].y());
92 wordMiddles.push_back(wordMiddle);
93 wordStartIndex = -1;
94 }
95 }
96 if (wordStartIndex >=0) {
97 int xEnd = visiblePositionToContentsPoint(VisiblePosition(Position(text, str.length()))).x();
98 IntPoint wordMiddle((letterPos[wordStartIndex].x() + xEnd) / 2, letterPo s[wordStartIndex].y());
99 wordMiddles.push_back(wordMiddle);
100 }
101 }
102
74 TEST_F(FrameSelectionTest, SetValidSelection) 103 TEST_F(FrameSelectionTest, SetValidSelection)
75 { 104 {
76 RefPtrWillBeRawPtr<Text> text = appendTextNode("Hello, World!"); 105 RefPtrWillBeRawPtr<Text> text = appendTextNode("Hello, World!");
77 VisibleSelection validSelection(Position(text, 0), Position(text, 5)); 106 VisibleSelection validSelection(Position(text, 0), Position(text, 5));
78 EXPECT_FALSE(validSelection.isNone()); 107 EXPECT_FALSE(validSelection.isNone());
79 setSelection(validSelection); 108 setSelection(validSelection);
80 EXPECT_FALSE(selection().isNone()); 109 EXPECT_FALSE(selection().isNone());
81 } 110 }
82 111
83 TEST_F(FrameSelectionTest, SetInvalidSelection) 112 TEST_F(FrameSelectionTest, SetInvalidSelection)
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 // "Foo Bar | Baz," 192 // "Foo Bar | Baz,"
164 EXPECT_FALSE(selection().selectWordAroundPosition(VisiblePosition(Position(t ext, 13)))); 193 EXPECT_FALSE(selection().selectWordAroundPosition(VisiblePosition(Position(t ext, 13))));
165 // "Foo Bar Baz|," 194 // "Foo Bar Baz|,"
166 EXPECT_TRUE(selection().selectWordAroundPosition(VisiblePosition(Position(te xt, 22)))); 195 EXPECT_TRUE(selection().selectWordAroundPosition(VisiblePosition(Position(te xt, 22))));
167 EXPECT_EQ_SELECTED_TEXT("Baz"); 196 EXPECT_EQ_SELECTED_TEXT("Baz");
168 } 197 }
169 198
170 // Test for MoveRangeSelectionExtent with the default CharacterGranularityStrate gy 199 // Test for MoveRangeSelectionExtent with the default CharacterGranularityStrate gy
171 TEST_F(FrameSelectionTest, MoveRangeSelectionExtentCharacter) 200 TEST_F(FrameSelectionTest, MoveRangeSelectionExtentCharacter)
172 { 201 {
202 dummyPageHolder().frame().settings()->setDefaultFontSize(12);
173 // "Foo Bar Baz," 203 // "Foo Bar Baz,"
174 RefPtrWillBeRawPtr<Text> text = appendTextNode("Foo Bar Baz,"); 204 RefPtrWillBeRawPtr<Text> text = appendTextNode("Foo Bar Baz,");
175 // "Foo B|a>r Baz," (| means start and > means end). 205 // "Foo B^a|r Baz," (^ means base and | means extent).
176 selection().setSelection(VisibleSelection(Position(text, 5), Position(text, 6))); 206 selection().setSelection(VisibleSelection(Position(text, 5), Position(text, 6)));
177 EXPECT_EQ_SELECTED_TEXT("a"); 207 EXPECT_EQ_SELECTED_TEXT("a");
178 // "Foo B|ar B>az," with the Character granularity. 208 // "Foo B^ar B|az,"
179 selection().moveRangeSelectionExtent(VisiblePosition(Position(text, 1))); 209 selection().moveRangeSelectionExtent(visiblePositionToContentsPoint(VisibleP osition(Position(text, 9))));
210 EXPECT_EQ_SELECTED_TEXT("ar B");
211 // "F|oo B^ar Baz,"
212 selection().moveRangeSelectionExtent(visiblePositionToContentsPoint(VisibleP osition(Position(text, 1))));
180 EXPECT_EQ_SELECTED_TEXT("oo B"); 213 EXPECT_EQ_SELECTED_TEXT("oo B");
181 } 214 }
182 215
183 // Test for MoveRangeSelectionExtent with DirectionGranularityStrategy 216 // Test for MoveRangeSelectionExtent with DirectionGranularityStrategy
184 TEST_F(FrameSelectionTest, MoveRangeSelectionExtentDirection) 217 TEST_F(FrameSelectionTest, MoveRangeSelectionExtentDirectionExpand)
leviw_travelin_and_unemployed 2015/05/20 20:24:37 Do we have tests for vertical writing modes or tra
mfomitchev 2015/05/20 21:37:29 See comment above
185 { 218 {
186 RefPtrWillBeRawPtr<Text> text = document().createTextNode("abcdef ghij kl mn opqr stuvwx yzab,"); 219 dummyPageHolder().frame().settings()->setDefaultFontSize(12);
187 document().body()->appendChild(text); 220 WTF::String str = "abcdef ghij kl mnopqr stuvwi inm,";
188 dummyPageHolder().frame().settings()->setSelectionStrategy(SelectionStrategy ::Direction); 221 RefPtrWillBeRawPtr<Text> text = document().createTextNode(str);
189 222 document().body()->appendChild(text);
190 // "abcdef ghij kl mno|p>qr stuvwx yzab," (| means start and > means end). 223 dummyPageHolder().frame().settings()->setSelectionStrategy(SelectionStrategy ::Direction);
224
225 std::vector<IntPoint> letterPos;
226 std::vector<IntPoint> wordMiddlePos;
227 parseString(text.get(), letterPos, wordMiddlePos);
228
229 // "abcdef ghij kl mno^p|>qr stuvwi inm," (^ means base, | means extent, < m eans start, and > means end).
191 selection().setSelection(VisibleSelection(Position(text, 18), Position(text, 19))); 230 selection().setSelection(VisibleSelection(Position(text, 18), Position(text, 19)));
192 EXPECT_EQ_SELECTED_TEXT("p"); 231 EXPECT_EQ_SELECTED_TEXT("p");
193 // "abcdef ghij kl mno|pq>r stuvwx yzab," - expand selection using character granularity 232 // Expand selection using character granularity until the end of the word
194 // until the end of the word is reached. 233 // is reached.
195 selection().moveRangeSelectionExtent(VisiblePosition(Position(text, 20))); 234 // "abcdef ghij kl mno^pq|>r stuvwi inm,"
235 selection().moveRangeSelectionExtent(letterPos[20]);
196 EXPECT_EQ_SELECTED_TEXT("pq"); 236 EXPECT_EQ_SELECTED_TEXT("pq");
197 // "abcdef ghij kl mno|pqr> stuvwx yzab," 237 // Move to the same postion shouldn't change anything.
198 selection().moveRangeSelectionExtent(VisiblePosition(Position(text, 21))); 238 selection().moveRangeSelectionExtent(letterPos[20]);
199 EXPECT_EQ_SELECTED_TEXT("pqr"); 239 EXPECT_EQ_SELECTED_TEXT("pq");
200 // "abcdef ghij kl mno|pqr >stuvwx yzab," - confirm selection doesn't 240 // "abcdef ghij kl mno^pqr|> stuvwi inm,"
201 // jump over the beginning of the word. 241 selection().moveRangeSelectionExtent(letterPos[21]);
202 selection().moveRangeSelectionExtent(VisiblePosition(Position(text, 22))); 242 EXPECT_EQ_SELECTED_TEXT("pqr");
203 EXPECT_EQ_SELECTED_TEXT("pqr "); 243 // Selection should stay the same until the middle of the word is passed.
204 // "abcdef ghij kl mno|pqr s>tuvwx yzab," - confirm selection switches to wo rd granularity. 244 // "abcdef ghij kl mno^pqr |>stuvwi inm," -
205 selection().moveRangeSelectionExtent(VisiblePosition(Position(text, 23))); 245 selection().moveRangeSelectionExtent(letterPos[22]);
206 EXPECT_EQ_SELECTED_TEXT("pqr stuvwx"); 246 EXPECT_EQ_SELECTED_TEXT("pqr ");
207 // "abcdef ghij kl mno|pqr stu>vwx yzab," - selection stays the same. 247 // "abcdef ghij kl mno^pqr >st|uvwi inm,"
208 selection().moveRangeSelectionExtent(VisiblePosition(Position(text, 25))); 248 selection().moveRangeSelectionExtent(letterPos[24]);
209 EXPECT_EQ_SELECTED_TEXT("pqr stuvwx"); 249 EXPECT_EQ_SELECTED_TEXT("pqr ");
210 // "abcdef ghij kl mno|pqr stuvwx yz>ab," - next word. 250 IntPoint p = wordMiddlePos[4];
211 selection().moveRangeSelectionExtent(VisiblePosition(Position(text, 31))); 251 p.move(-1, 0);
212 EXPECT_EQ_SELECTED_TEXT("pqr stuvwx yzab"); 252 selection().moveRangeSelectionExtent(p);
213 // "abcdef ghij kl mno|pqr stuvwx y>zab," - move back one character - 253 EXPECT_EQ_SELECTED_TEXT("pqr ");
214 // confirm switch to character granularity. 254 p.move(1, 0);
215 selection().moveRangeSelectionExtent(VisiblePosition(Position(text, 30))); 255 selection().moveRangeSelectionExtent(p);
216 EXPECT_EQ_SELECTED_TEXT("pqr stuvwx y"); 256 EXPECT_EQ_SELECTED_TEXT("pqr stuvwi");
217 // "abcdef ghij kl mno|pqr stuvwx yz>ab," - stay in character granularity 257 // Selection should stay the same until the end of the word is reached.
218 // if the user moves the position within the word. 258 // "abcdef ghij kl mno^pqr stuvw|i> inm,"
219 selection().moveRangeSelectionExtent(VisiblePosition(Position(text, 31))); 259 selection().moveRangeSelectionExtent(letterPos[27]);
220 EXPECT_EQ_SELECTED_TEXT("pqr stuvwx yz"); 260 EXPECT_EQ_SELECTED_TEXT("pqr stuvwi");
221 // "abcdef ghij kl mno|pqr stuvwx >yzab," 261 // "abcdef ghij kl mno^pqr stuvwi|> inm,"
222 selection().moveRangeSelectionExtent(VisiblePosition(Position(text, 29))); 262 selection().moveRangeSelectionExtent(letterPos[28]);
223 EXPECT_EQ_SELECTED_TEXT("pqr stuvwx "); 263 EXPECT_EQ_SELECTED_TEXT("pqr stuvwi");
224 // "abcdef ghij kl mno|pqr stuvwx >yzab," - it's possible to get a move when 264 // "abcdef ghij kl mno^pqr stuvwi |>inm,"
225 // position doesn't change. It shouldn't affect anything. 265 selection().moveRangeSelectionExtent(letterPos[29]);
226 selection().moveRangeSelectionExtent(VisiblePosition(Position(text, 29))); 266 EXPECT_EQ_SELECTED_TEXT("pqr stuvwi ");
227 EXPECT_EQ_SELECTED_TEXT("pqr stuvwx "); 267 }
228 // "abcdef ghij kl mno|pqr stuvwx y>zab," 268
229 selection().moveRangeSelectionExtent(VisiblePosition(Position(text, 30))); 269 TEST_F(FrameSelectionTest, MoveRangeSelectionExtentDirectionShrink)
230 EXPECT_EQ_SELECTED_TEXT("pqr stuvwx y"); 270 {
231 // "abcdef ghij kl mno|pqr stuv>wx yzab," 271 dummyPageHolder().frame().settings()->setDefaultFontSize(12);
232 selection().moveRangeSelectionExtent(VisiblePosition(Position(text, 26))); 272 WTF::String str = "abcdef ghij kl mnopqr iiinmni, abc";
233 EXPECT_EQ_SELECTED_TEXT("pqr stuv"); 273 RefPtrWillBeRawPtr<Text> text = document().createTextNode(str);
234 // "abcdef ghij kl mno|pqr stuvw>x yzab," 274 document().body()->appendChild(text);
235 selection().moveRangeSelectionExtent(VisiblePosition(Position(text, 27))); 275 dummyPageHolder().frame().settings()->setSelectionStrategy(SelectionStrategy ::Direction);
236 EXPECT_EQ_SELECTED_TEXT("pqr stuvw"); 276
237 // "abcdef ghij kl mno|pqr stuvwx y>zab," - switch to word granularity 277 std::vector<IntPoint> letterPos;
238 // after expanding beyond the word boundary 278 std::vector<IntPoint> wordMiddlePos;
239 selection().moveRangeSelectionExtent(VisiblePosition(Position(text, 30))); 279 parseString(text.get(), letterPos, wordMiddlePos);
240 EXPECT_EQ_SELECTED_TEXT("pqr stuvwx yzab"); 280
241 // "abcdef ghij kl mn<o|pqr stuvwx yzab," - over to the other side of the ba se 281 // "abcdef ghij kl mno^pqr|> iiinmni, abc" (^ means base, | means extent, < means start, and > means end).
242 // - stay in character granularity until the beginning of the word is passed . 282 selection().setSelection(VisibleSelection(Position(text, 18), Position(text, 21)));
243 selection().moveRangeSelectionExtent(VisiblePosition(Position(text, 17))); 283 EXPECT_EQ_SELECTED_TEXT("pqr");
284 // Move to the middle of word #4 to it and then move back, confirming
285 // that the selection end is moving with the extent. The offset between the
286 // extent and the selection end will be equal to half the width of "iiinmni" .
287 selection().moveRangeSelectionExtent(wordMiddlePos[4]);
288 EXPECT_EQ_SELECTED_TEXT("pqr iiinmni");
289 IntPoint p = wordMiddlePos[4];
290 p.move(letterPos[28].x() - letterPos[29].x(), 0);
291 selection().moveRangeSelectionExtent(p);
292 EXPECT_EQ_SELECTED_TEXT("pqr iiinmn");
293 p.move(letterPos[27].x() - letterPos[28].x(), 0);
294 selection().moveRangeSelectionExtent(p);
295 EXPECT_EQ_SELECTED_TEXT("pqr iiinm");
296 p.move(letterPos[26].x() - letterPos[27].x(), 0);
297 selection().moveRangeSelectionExtent(p);
298 EXPECT_EQ_SELECTED_TEXT("pqr iiin");
299 // Move right by the width of char 30 ('m'). Selection shouldn't change,
300 // but offset should be reduced.
301 p.move(letterPos[27].x() - letterPos[26].x(), 0);
302 selection().moveRangeSelectionExtent(p);
303 EXPECT_EQ_SELECTED_TEXT("pqr iiin");
304 // Move back a couple of character widths and confirm the selection still
305 // updates accordingly.
306 p.move(letterPos[25].x() - letterPos[26].x(), 0);
307 selection().moveRangeSelectionExtent(p);
308 EXPECT_EQ_SELECTED_TEXT("pqr iii");
309 p.move(letterPos[24].x() - letterPos[25].x(), 0);
310 selection().moveRangeSelectionExtent(p);
311 EXPECT_EQ_SELECTED_TEXT("pqr ii");
312 // "Catch up" with the handle - move the extent to where the handle is.
313 // "abcdef ghij kl mno^pqr ii|>inmni, abc"
314 selection().moveRangeSelectionExtent(letterPos[24]);
315 EXPECT_EQ_SELECTED_TEXT("pqr ii");
316 // Move ahead and confirm the selection expands accordingly
317 // "abcdef ghij kl mno^pqr iii|>nmni, abc"
318 selection().moveRangeSelectionExtent(letterPos[25]);
319 EXPECT_EQ_SELECTED_TEXT("pqr iii");
320
321 // Confirm we stay in character granularity if the user moves within a word.
322 // "abcdef ghij kl mno^pqr |>iiinmni, abc"
323 selection().moveRangeSelectionExtent(letterPos[22]);
324 EXPECT_EQ_SELECTED_TEXT("pqr ");
325 // It's possible to get a move when position doesn't change.
326 // It shouldn't affect anything.
327 p = letterPos[22];
328 p.move(1, 0);
329 selection().moveRangeSelectionExtent(p);
330 EXPECT_EQ_SELECTED_TEXT("pqr ");
331 // "abcdef ghij kl mno^pqr i|>iinmni, abc"
332 selection().moveRangeSelectionExtent(letterPos[23]);
333 EXPECT_EQ_SELECTED_TEXT("pqr i");
334 }
335
336 TEST_F(FrameSelectionTest, MoveRangeSelectionExtentDirectionSwitchSide)
337 {
338 dummyPageHolder().frame().settings()->setDefaultFontSize(12);
339 WTF::String str = "abcd efgh ijkl mnopqr iiinmni, abc";
340 RefPtrWillBeRawPtr<Text> text = document().createTextNode(str);
341 document().body()->appendChild(text);
342 dummyPageHolder().frame().settings()->setSelectionStrategy(SelectionStrategy ::Direction);
343
344 std::vector<IntPoint> letterPos;
345 std::vector<IntPoint> wordMiddlePos;
346 parseString(text.get(), letterPos, wordMiddlePos);
347
348 // "abcd efgh ijkl mno^pqr|> iiinmni, abc" (^ means base, | means extent, < means start, and > means end).
349 selection().setSelection(VisibleSelection(Position(text, 18), Position(text, 21)));
350 EXPECT_EQ_SELECTED_TEXT("pqr");
351 // Move to the middle of word #4, selecting it - this will set the offset to
352 // be half the width of "iiinmni.
353 selection().moveRangeSelectionExtent(wordMiddlePos[4]);
354 EXPECT_EQ_SELECTED_TEXT("pqr iiinmni");
355 // Move back leaving only one letter selected.
356 IntPoint p = wordMiddlePos[4];
357 p.move(letterPos[19].x() - letterPos[29].x(), 0);
358 selection().moveRangeSelectionExtent(p);
359 EXPECT_EQ_SELECTED_TEXT("p");
360 // Confirm selection doesn't change if extent is positioned at base.
361 p.move(letterPos[18].x() - letterPos[19].x(), 0);
362 selection().moveRangeSelectionExtent(p);
363 EXPECT_EQ_SELECTED_TEXT("p");
364 // Move over to the other side of the base. Confirm the offset is preserved.
365 // (i.e. the selection start stays on the right of the extent)
366 // Confirm we stay in character granularity until the beginning of the word
367 // is passed.
368 p.move(letterPos[17].x() - letterPos[18].x(), 0);
369 selection().moveRangeSelectionExtent(p);
244 EXPECT_EQ_SELECTED_TEXT("o"); 370 EXPECT_EQ_SELECTED_TEXT("o");
245 // "abcdef ghij kl m<no|pqr stuvwx yzab," 371 p.move(letterPos[16].x() - letterPos[17].x(), 0);
246 selection().moveRangeSelectionExtent(VisiblePosition(Position(text, 16))); 372 selection().moveRangeSelectionExtent(p);
247 EXPECT_EQ_SELECTED_TEXT("no"); 373 EXPECT_EQ_SELECTED_TEXT("no");
248 // "abcdef ghij kl <mno|pqr stuvwx yzab," 374 p.move(letterPos[14].x() - letterPos[16].x(), 0);
249 selection().moveRangeSelectionExtent(VisiblePosition(Position(text, 15))); 375 selection().moveRangeSelectionExtent(p);
250 EXPECT_EQ_SELECTED_TEXT("mno"); 376 EXPECT_EQ_SELECTED_TEXT(" mno");
251 // "abcdef ghij kl mn<o|pqr stuvwx yzab," 377 // Move to just one pixel on the right before the middle of the word #2.
252 selection().moveRangeSelectionExtent(VisiblePosition(Position(text, 17))); 378 // We should switch to word granularity, so the selection shouldn't change.
253 EXPECT_EQ_SELECTED_TEXT("o"); 379 p.move(wordMiddlePos[2].x() - letterPos[14].x() + 1, 0);
254 // "abcdef ghij k<l mno|pqr stuvwx yzab," - switch to word granularity 380 selection().moveRangeSelectionExtent(p);
255 selection().moveRangeSelectionExtent(VisiblePosition(Position(text, 13))); 381 EXPECT_EQ_SELECTED_TEXT(" mno");
256 EXPECT_EQ_SELECTED_TEXT("kl mno"); 382 // Move over the middle of the word. The word should get selected.
257 // "abcd<ef ghij kl mno|pqr stuvwx yzab," 383 // This should reduce the offset, but it should still stay greated than 0,
258 selection().moveRangeSelectionExtent(VisiblePosition(Position(text, 4))); 384 // since the width of "iiinmni" is greater than the width of "ijkl".
259 EXPECT_EQ_SELECTED_TEXT("abcdef ghij kl mno"); 385 p.move(-2, 0);
260 // "abcde<f ghij kl mno|pqr stuvwx yzab," - decrease selection - 386 selection().moveRangeSelectionExtent(p);
261 // switch back to character granularity. 387 EXPECT_EQ_SELECTED_TEXT("ijkl mno");
262 selection().moveRangeSelectionExtent(VisiblePosition(Position(text, 5))); 388 // Move to just one pixel on the right of the middle of word #1.
263 EXPECT_EQ_SELECTED_TEXT("f ghij kl mno"); 389 // The selection should now include the space between the words.
264 // "abcdef ghij kl mn<o|pqr stuvwx yzab," 390 p.move(wordMiddlePos[1].x() - letterPos[10].x() + 1, 0);
265 selection().moveRangeSelectionExtent(VisiblePosition(Position(text, 17))); 391 selection().moveRangeSelectionExtent(p);
266 EXPECT_EQ_SELECTED_TEXT("o"); 392 EXPECT_EQ_SELECTED_TEXT(" ijkl mno");
267 // "abcdef ghij kl m<no|pqr stuvwx yzab," 393 // Move over the middle of the word. The word should get selected.
268 selection().moveRangeSelectionExtent(VisiblePosition(Position(text, 16))); 394 p.move(-2, 0);
269 EXPECT_EQ_SELECTED_TEXT("no"); 395 selection().moveRangeSelectionExtent(p);
270 // "abcdef ghij k<l mno|pqr stuvwx yzab," 396 EXPECT_EQ_SELECTED_TEXT("efgh ijkl mno");
271 selection().moveRangeSelectionExtent(VisiblePosition(Position(text, 13))); 397 }
272 EXPECT_EQ_SELECTED_TEXT("kl mno"); 398
273 399 // Tests moving extent over to the other side of the vase and immediately
274 // Make sure we switch to word granularity right away when starting on a 400 // passing the word boundary and going into word granularity.
275 // word boundary and extending. 401 TEST_F(FrameSelectionTest, MoveRangeSelectionExtentDirectionSwitchSideWordGranul arityThenShrink)
276 // "abcdef ghij kl |mnopqr >stuvwx yzab," (| means start and > means end). 402 {
403 dummyPageHolder().frame().settings()->setDefaultFontSize(12);
404 WTF::String str = "ab cd efghijkl mnopqr iiin, abc";
405 RefPtrWillBeRawPtr<Text> text = document().createTextNode(str);
406 document().body()->appendChild(text);
407 dummyPageHolder().frame().settings()->setSelectionStrategy(SelectionStrategy ::Direction);
408
409 std::vector<IntPoint> letterPos;
410 std::vector<IntPoint> wordMiddlePos;
411 parseString(text.get(), letterPos, wordMiddlePos);
412
413 // "abcd efgh ijkl mno^pqr|> iiin, abc" (^ means base, | means extent, < mea ns start, and > means end).
414 selection().setSelection(VisibleSelection(Position(text, 18), Position(text, 21)));
415 EXPECT_EQ_SELECTED_TEXT("pqr");
416 // Move to the middle of word #4 selecting it - this will set the offset to
417 // be half the width of "iiin".
418 selection().moveRangeSelectionExtent(wordMiddlePos[4]);
419 EXPECT_EQ_SELECTED_TEXT("pqr iiin");
420 // Move to the middle of word #2 - extent will switch over to the other
421 // side of the base, and we should enter word granularity since we pass
422 // the word boundary. The offset should become negative since the width
423 // of "efghjkkl" is greater than that of "iiin".
424 int offset = letterPos[26].x() - wordMiddlePos[4].x();
425 IntPoint p = IntPoint(wordMiddlePos[2].x() - offset - 1, wordMiddlePos[2].y( ));
426 selection().moveRangeSelectionExtent(p);
427 EXPECT_EQ_SELECTED_TEXT("efghijkl mno");
428 p.move(letterPos[7].x() - letterPos[6].x(), 0);
429 selection().moveRangeSelectionExtent(p);
430 EXPECT_EQ_SELECTED_TEXT("fghijkl mno");
431 }
432
433 // Make sure we switch to word granularity right away when starting on a
434 // word boundary and extending.
435 TEST_F(FrameSelectionTest, MoveRangeSelectionExtentDirectionSwitchStartOnBoundar y)
436 {
437 dummyPageHolder().frame().settings()->setDefaultFontSize(12);
438 WTF::String str = "ab cd efghijkl mnopqr iiin, abc";
439 RefPtrWillBeRawPtr<Text> text = document().createTextNode(str);
440 document().body()->appendChild(text);
441 dummyPageHolder().frame().settings()->setSelectionStrategy(SelectionStrategy ::Direction);
442
443 std::vector<IntPoint> letterPos;
444 std::vector<IntPoint> wordMiddlePos;
445 parseString(text.get(), letterPos, wordMiddlePos);
446
447 // "ab cd efghijkl ^mnopqr |>stuvwi inm," (^ means base and | means extent,
448 // > means end).
277 selection().setSelection(VisibleSelection(Position(text, 15), Position(text, 22))); 449 selection().setSelection(VisibleSelection(Position(text, 15), Position(text, 22)));
278 EXPECT_EQ_SELECTED_TEXT("mnopqr "); 450 EXPECT_EQ_SELECTED_TEXT("mnopqr ");
279 // "abcdef ghij kl |mnopqr s>tuvwx yzab," 451 selection().moveRangeSelectionExtent(wordMiddlePos[4]);
280 selection().moveRangeSelectionExtent(VisiblePosition(Position(text, 23))); 452 EXPECT_EQ_SELECTED_TEXT("mnopqr iiin");
281 EXPECT_EQ_SELECTED_TEXT("mnopqr stuvwx");
282
283 // Make sure we start in character granularity when moving extent over to th e other
284 // side of the base.
285 // "abcdef| ghij> kl mnopqr stuvwx yzab," (| means start and > means end).
286 selection().setSelection(VisibleSelection(Position(text, 6), Position(text, 11)));
287 EXPECT_EQ_SELECTED_TEXT(" ghij");
288 // "abcde<f| ghij kl mnopqr stuvwx yzab,"
289 selection().moveRangeSelectionExtent(VisiblePosition(Position(text, 5)));
290 EXPECT_EQ_SELECTED_TEXT("f");
291
292 // Make sure we switch to word granularity when moving over to the other
293 // side of the base and then passing over the word boundary.
294 // "abcdef |ghij> kl mnopqr stuvwx yzab,"
295 selection().setSelection(VisibleSelection(Position(text, 7), Position(text, 11)));
296 EXPECT_EQ_SELECTED_TEXT("ghij");
297 // "abcdef< |ghij kl mnopqr stuvwx yzab,"
298 selection().moveRangeSelectionExtent(VisiblePosition(Position(text, 6)));
299 EXPECT_EQ_SELECTED_TEXT(" ");
300 // "abcde<f |ghij kl mnopqr stuvwx yzab,"
301 selection().moveRangeSelectionExtent(VisiblePosition(Position(text, 5)));
302 EXPECT_EQ_SELECTED_TEXT("abcdef ");
303 } 453 }
304 454
305 TEST_F(FrameSelectionTest, MoveRangeSelectionTest) 455 TEST_F(FrameSelectionTest, MoveRangeSelectionTest)
306 { 456 {
307 // "Foo Bar Baz," 457 // "Foo Bar Baz,"
308 RefPtrWillBeRawPtr<Text> text = appendTextNode("Foo Bar Baz,"); 458 RefPtrWillBeRawPtr<Text> text = appendTextNode("Foo Bar Baz,");
309 // Itinitializes with "Foo B|a>r Baz," (| means start and > means end). 459 // Itinitializes with "Foo B|a>r Baz," (| means start and > means end).
310 selection().setSelection(VisibleSelection(Position(text, 5), Position(text, 6))); 460 selection().setSelection(VisibleSelection(Position(text, 5), Position(text, 6)));
311 EXPECT_EQ_SELECTED_TEXT("a"); 461 EXPECT_EQ_SELECTED_TEXT("a");
312 462
313 // "Foo B|ar B>az," with the Character granularity. 463 // "Foo B|ar B>az," with the Character granularity.
314 selection().moveRangeSelection(VisiblePosition(Position(text, 5)), VisiblePo sition(Position(text, 9)), CharacterGranularity); 464 selection().moveRangeSelection(VisiblePosition(Position(text, 5)), VisiblePo sition(Position(text, 9)), CharacterGranularity);
315 EXPECT_EQ_SELECTED_TEXT("ar B"); 465 EXPECT_EQ_SELECTED_TEXT("ar B");
316 // "Foo B|ar B>az," with the Word granularity. 466 // "Foo B|ar B>az," with the Word granularity.
317 selection().moveRangeSelection(VisiblePosition(Position(text, 5)), VisiblePo sition(Position(text, 9)), WordGranularity); 467 selection().moveRangeSelection(VisiblePosition(Position(text, 5)), VisiblePo sition(Position(text, 9)), WordGranularity);
318 EXPECT_EQ_SELECTED_TEXT("Bar Baz"); 468 EXPECT_EQ_SELECTED_TEXT("Bar Baz");
319 // "Fo<o B|ar Baz," with the Character granularity. 469 // "Fo<o B|ar Baz," with the Character granularity.
320 selection().moveRangeSelection(VisiblePosition(Position(text, 5)), VisiblePo sition(Position(text, 2)), CharacterGranularity); 470 selection().moveRangeSelection(VisiblePosition(Position(text, 5)), VisiblePo sition(Position(text, 2)), CharacterGranularity);
321 EXPECT_EQ_SELECTED_TEXT("o B"); 471 EXPECT_EQ_SELECTED_TEXT("o B");
322 // "Fo<o B|ar Baz," with the Word granularity. 472 // "Fo<o B|ar Baz," with the Word granularity.
323 selection().moveRangeSelection(VisiblePosition(Position(text, 5)), VisiblePo sition(Position(text, 2)), WordGranularity); 473 selection().moveRangeSelection(VisiblePosition(Position(text, 5)), VisiblePo sition(Position(text, 2)), WordGranularity);
324 EXPECT_EQ_SELECTED_TEXT("Foo Bar"); 474 EXPECT_EQ_SELECTED_TEXT("Foo Bar");
325 } 475 }
326 } 476 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698