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

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

Issue 1123563003: Improving direction-based selection strategy. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Removing anonymous namespace and marking functions static instead. Created 5 years, 6 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
« no previous file with comments | « Source/core/editing/GranularityStrategy.cpp ('k') | Source/core/editing/VisibleUnits.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "config.h"
6
7 #include "bindings/core/v8/ExceptionStatePlaceholder.h"
8 #include "core/HTMLNames.h"
9 #include "core/dom/Document.h"
10 #include "core/dom/Element.h"
11 #include "core/dom/Text.h"
12 #include "core/editing/FrameSelection.h"
13 #include "core/frame/FrameView.h"
14 #include "core/frame/Settings.h"
15 #include "core/html/HTMLBodyElement.h"
16 #include "core/html/HTMLDocument.h"
17 #include "core/testing/DummyPageHolder.h"
18 #include "wtf/OwnPtr.h"
19 #include "wtf/PassRefPtr.h"
20 #include "wtf/RefPtr.h"
21 #include "wtf/StdLibExtras.h"
22 #include "wtf/testing/WTFTestHelpers.h"
23 #include <gtest/gtest.h>
24
25 using namespace blink;
26
27 namespace {
28
29 #define EXPECT_EQ_SELECTED_TEXT(text) \
30 EXPECT_EQ(text, WebString(selection().selectedText()).utf8())
31
32 IntPoint visiblePositionToContentsPoint(const VisiblePosition& pos)
33 {
34 IntPoint result = pos.absoluteCaretBounds().minXMaxYCorner();
35 // Need to move the point at least by 1 - caret's minXMaxYCorner is not
36 // evaluated to the same line as the text by hit testing.
37 result.move(0, -1);
38 return result;
39 }
40
41 class GranularityStrategyTest : public ::testing::Test {
42 protected:
43 virtual void SetUp() override;
44
45 DummyPageHolder& dummyPageHolder() const { return *m_dummyPageHolder; }
46 HTMLDocument& document() const;
47 void setSelection(const VisibleSelection&);
48 FrameSelection& selection() const;
49 PassRefPtrWillBeRawPtr<Text> appendTextNode(const String& data);
50 int layoutCount() const { return m_dummyPageHolder->frameView().layoutCount( ); }
51 void setInnerHTML(const char*);
52 // Parses the text node, appending the info to m_letterPos and m_wordMiddles .
53 void parseText(Text*);
54 void parseText(std::vector<Text*>);
55
56 PassRefPtrWillBeRawPtr<Text> setupTranslateZ(WTF::String);
57 PassRefPtrWillBeRawPtr<Text> setupTransform(WTF::String);
58 PassRefPtrWillBeRawPtr<Text> setupRotate(WTF::String);
59 void setupTextSpan(WTF::String str1, WTF::String str2, WTF::String str3, siz e_t selBegin, size_t selEnd);
60 void setupVerticalAlign(WTF::String str1, WTF::String str2, WTF::String str3 , size_t selBegin, size_t selEnd);
61 void setupFontSize(WTF::String str1, WTF::String str2, WTF::String str3, siz e_t selBegin, size_t selEnd);
62
63 void testDirectionExpand();
64 void testDirectionShrink();
65 void testDirectionSwitchSide();
66
67 // Pixel coordinates of the positions for each letter within the text being tested.
68 std::vector<IntPoint> m_letterPos;
69 // Pixel coordinates of the middles of the words in the text being tested.
70 // (y coordinate is based on y coordinates of m_letterPos)
71 std::vector<IntPoint> m_wordMiddles;
72
73 private:
74 OwnPtr<DummyPageHolder> m_dummyPageHolder;
75 RawPtr<HTMLDocument> m_document;
76 };
77
78 void GranularityStrategyTest::SetUp()
79 {
80 m_dummyPageHolder = DummyPageHolder::create(IntSize(800, 600));
81 m_document = toHTMLDocument(&m_dummyPageHolder->document());
82 ASSERT(m_document);
83 dummyPageHolder().frame().settings()->setDefaultFontSize(12);
84 dummyPageHolder().frame().settings()->setSelectionStrategy(SelectionStrategy ::Direction);
85 }
86
87 HTMLDocument& GranularityStrategyTest::document() const
88 {
89 return *m_document;
90 }
91
92 void GranularityStrategyTest::setSelection(const VisibleSelection& newSelection)
93 {
94 m_dummyPageHolder->frame().selection().setSelection(newSelection);
95 }
96
97 FrameSelection& GranularityStrategyTest::selection() const
98 {
99 return m_dummyPageHolder->frame().selection();
100 }
101
102 PassRefPtrWillBeRawPtr<Text> GranularityStrategyTest::appendTextNode(const Strin g& data)
103 {
104 RefPtrWillBeRawPtr<Text> text = document().createTextNode(data);
105 document().body()->appendChild(text);
106 return text.release();
107 }
108
109 void GranularityStrategyTest::setInnerHTML(const char* htmlContent)
110 {
111 document().documentElement()->setInnerHTML(String::fromUTF8(htmlContent), AS SERT_NO_EXCEPTION);
112 document().view()->updateLayoutAndStyleForPainting();
113 }
114
115 void GranularityStrategyTest::parseText(Text* text)
116 {
117 std::vector<Text*> vec;
118 vec.push_back(text);
119 parseText(vec);
120 }
121
122 void GranularityStrategyTest::parseText(std::vector<Text*> textNodes)
123 {
124 bool wordStarted = false;
125 int wordStartIndex = 0;
126 for (Text* text : textNodes) {
127 int wordStartIndexOffset = m_letterPos.size();
128 WTF::String str = text->wholeText();
129 for (size_t i = 0; i < str.length(); i++) {
130 m_letterPos.push_back(visiblePositionToContentsPoint(VisiblePosition (Position(text, i))));
131 char c = str.characterAt(i);
132 if (isASCIIAlphanumeric(c) && !wordStarted) {
133 wordStartIndex = i + wordStartIndexOffset;
134 wordStarted = true;
135 } else if (!isASCIIAlphanumeric(c) && wordStarted) {
136 IntPoint wordMiddle((m_letterPos[wordStartIndex].x() + m_letterP os[i + wordStartIndexOffset].x()) / 2, m_letterPos[wordStartIndex].y());
137 m_wordMiddles.push_back(wordMiddle);
138 wordStarted = false;
139 }
140 }
141 }
142 if (wordStarted) {
143 Text* lastNode = textNodes[textNodes.size() - 1];
144 int xEnd = visiblePositionToContentsPoint(VisiblePosition(Position(lastN ode, lastNode->wholeText().length()))).x();
145 IntPoint wordMiddle((m_letterPos[wordStartIndex].x() + xEnd) / 2, m_lett erPos[wordStartIndex].y());
146 m_wordMiddles.push_back(wordMiddle);
147 }
148 }
149
150 PassRefPtrWillBeRawPtr<Text> GranularityStrategyTest::setupTranslateZ(WTF::Strin g str)
151 {
152 setInnerHTML(
153 "<html>"
154 "<head>"
155 "<style>"
156 "div {"
157 "transform: translateZ(0);"
158 "}"
159 "</style>"
160 "</head>"
161 "<body>"
162 "<div id='mytext'></div>"
163 "</body>"
164 "</html>");
165
166 RefPtrWillBeRawPtr<Text> text = document().createTextNode(str);
167 Element* div = document().getElementById("mytext");
168 div->appendChild(text);
169
170 document().view()->updateLayoutAndStyleForPainting();
171
172 parseText(text.get());
173 return text.release();
174 }
175
176 PassRefPtrWillBeRawPtr<Text> GranularityStrategyTest::setupTransform(WTF::String str)
177 {
178 setInnerHTML(
179 "<html>"
180 "<head>"
181 "<style>"
182 "div {"
183 "transform: scale(1,-1) translate(0,-100px);"
184 "}"
185 "</style>"
186 "</head>"
187 "<body>"
188 "<div id='mytext'></div>"
189 "</body>"
190 "</html>");
191
192 RefPtrWillBeRawPtr<Text> text = document().createTextNode(str);
193 Element* div = document().getElementById("mytext");
194 div->appendChild(text);
195
196 document().view()->updateLayoutAndStyleForPainting();
197
198 parseText(text.get());
199 return text.release();
200 }
201
202 PassRefPtrWillBeRawPtr<Text> GranularityStrategyTest::setupRotate(WTF::String st r)
203 {
204 setInnerHTML(
205 "<html>"
206 "<head>"
207 "<style>"
208 "div {"
209 "transform: translate(0px,600px) rotate(90deg);"
210 "}"
211 "</style>"
212 "</head>"
213 "<body>"
214 "<div id='mytext'></div>"
215 "</body>"
216 "</html>");
217
218 RefPtrWillBeRawPtr<Text> text = document().createTextNode(str);
219 Element* div = document().getElementById("mytext");
220 div->appendChild(text);
221
222 document().view()->updateLayoutAndStyleForPainting();
223
224 parseText(text.get());
225 return text.release();
226 }
227
228 void GranularityStrategyTest::setupTextSpan(WTF::String str1, WTF::String str2, WTF::String str3, size_t selBegin, size_t selEnd)
229 {
230 RefPtrWillBeRawPtr<Text> text1 = document().createTextNode(str1);
231 RefPtrWillBeRawPtr<Text> text2 = document().createTextNode(str2);
232 RefPtrWillBeRawPtr<Text> text3 = document().createTextNode(str3);
233 RefPtrWillBeRawPtr<Element> span = document().createElement(HTMLNames::spanT ag, true);
234 Element* div = document().getElementById("mytext");
235 div->appendChild(text1);
236 div->appendChild(span);
237 span->appendChild(text2);
238 div->appendChild(text3);
239
240 document().view()->updateLayoutAndStyleForPainting();
241
242 std::vector<IntPoint> letterPos;
243 std::vector<IntPoint> wordMiddlePos;
244
245 std::vector<Text*> textNodes;
246 textNodes.push_back(text1.get());
247 textNodes.push_back(text2.get());
248 textNodes.push_back(text3.get());
249 parseText(textNodes);
250
251 Position p1;
252 Position p2;
253 if (selBegin < str1.length())
254 p1 = Position(text1, selBegin);
255 else if (selBegin < str1.length() + str2.length())
256 p1 = Position(text2, selBegin - str1.length());
257 else
258 p1 = Position(text3, selBegin - str1.length() - str2.length());
259 if (selEnd < str1.length())
260 p2 = Position(text1, selEnd);
261 else if (selEnd < str1.length() + str2.length())
262 p2 = Position(text2, selEnd - str1.length());
263 else
264 p2 = Position(text3, selEnd - str1.length() - str2.length());
265
266 selection().setSelection(VisibleSelection(p1, p2));
267 }
268
269 void GranularityStrategyTest::setupVerticalAlign(WTF::String str1, WTF::String s tr2, WTF::String str3, size_t selBegin, size_t selEnd)
270 {
271 setInnerHTML(
272 "<html>"
273 "<head>"
274 "<style>"
275 "span {"
276 "vertical-align:20px;"
277 "}"
278 "</style>"
279 "</head>"
280 "<body>"
281 "<div id='mytext'></div>"
282 "</body>"
283 "</html>");
284
285 setupTextSpan(str1, str2, str3, selBegin, selEnd);
286 }
287
288 void GranularityStrategyTest::setupFontSize(WTF::String str1, WTF::String str2, WTF::String str3, size_t selBegin, size_t selEnd)
289 {
290 setInnerHTML(
291 "<html>"
292 "<head>"
293 "<style>"
294 "span {"
295 "font-size: 200%;"
296 "}"
297 "</style>"
298 "</head>"
299 "<body>"
300 "<div id='mytext'></div>"
301 "</body>"
302 "</html>");
303
304 setupTextSpan(str1, str2, str3, selBegin, selEnd);
305 }
306
307
308 // Tests expanding selection on text "abcdef ghij kl mno^p|>qr stuvwi inm mnii, "
309 // (^ means base, | means extent, < means start, and > means end).
310 // Text needs to be laid out on a single line with no rotation.
311 void GranularityStrategyTest::testDirectionExpand()
312 {
313 // Expand selection using character granularity until the end of the word
314 // is reached.
315 // "abcdef ghij kl mno^pq|>r stuvwi inm mnii,"
316 selection().moveRangeSelectionExtent(m_letterPos[20]);
317 EXPECT_EQ_SELECTED_TEXT("pq");
318 // Move to the same postion shouldn't change anything.
319 selection().moveRangeSelectionExtent(m_letterPos[20]);
320 EXPECT_EQ_SELECTED_TEXT("pq");
321 // "abcdef ghij kl mno^pqr|> stuvwi inm mnii,"
322 selection().moveRangeSelectionExtent(m_letterPos[21]);
323 EXPECT_EQ_SELECTED_TEXT("pqr");
324 // Selection should stay the same until the middle of the word is passed.
325 // "abcdef ghij kl mno^pqr |>stuvwi inm mnii," -
326 selection().moveRangeSelectionExtent(m_letterPos[22]);
327 EXPECT_EQ_SELECTED_TEXT("pqr ");
328 // "abcdef ghij kl mno^pqr >st|uvwi inm mnii,"
329 selection().moveRangeSelectionExtent(m_letterPos[24]);
330 EXPECT_EQ_SELECTED_TEXT("pqr ");
331 IntPoint p = m_wordMiddles[4];
332 p.move(-1, 0);
333 selection().moveRangeSelectionExtent(p);
334 EXPECT_EQ_SELECTED_TEXT("pqr ");
335 p.move(1, 0);
336 selection().moveRangeSelectionExtent(p);
337 EXPECT_EQ_SELECTED_TEXT("pqr stuvwi");
338 // Selection should stay the same until the end of the word is reached.
339 // "abcdef ghij kl mno^pqr stuvw|i> inm mnii,"
340 selection().moveRangeSelectionExtent(m_letterPos[27]);
341 EXPECT_EQ_SELECTED_TEXT("pqr stuvwi");
342 // "abcdef ghij kl mno^pqr stuvwi|> inm mnii,"
343 selection().moveRangeSelectionExtent(m_letterPos[28]);
344 EXPECT_EQ_SELECTED_TEXT("pqr stuvwi");
345 // "abcdef ghij kl mno^pqr stuvwi |>inm mnii,"
346 selection().moveRangeSelectionExtent(m_letterPos[29]);
347 EXPECT_EQ_SELECTED_TEXT("pqr stuvwi ");
348 // Now expand slowly to the middle of word #5.
349 int y = m_letterPos[29].y();
350 for (int x = m_letterPos[29].x() + 1; x < m_wordMiddles[5].x(); x++) {
351 selection().moveRangeSelectionExtent(IntPoint(x, y));
352 selection().moveRangeSelectionExtent(IntPoint(x, y));
353 EXPECT_EQ_SELECTED_TEXT("pqr stuvwi ");
354 }
355 selection().moveRangeSelectionExtent(m_wordMiddles[5]);
356 EXPECT_EQ_SELECTED_TEXT("pqr stuvwi inm");
357 // Jump over quickly to just before the middle of the word #6 and then
358 // move over it.
359 p = m_wordMiddles[6];
360 p.move(-1, 0);
361 selection().moveRangeSelectionExtent(p);
362 EXPECT_EQ_SELECTED_TEXT("pqr stuvwi inm ");
363 p.move(1, 0);
364 selection().moveRangeSelectionExtent(p);
365 EXPECT_EQ_SELECTED_TEXT("pqr stuvwi inm mnii");
366 }
367
368 // Tests shrinking selection on text "abcdef ghij kl mno^pqr|> iiinmni, abc"
369 // (^ means base, | means extent, < means start, and > means end).
370 // Text needs to be laid out on a single line with no rotation.
371 void GranularityStrategyTest::testDirectionShrink()
372 {
373 // Move to the middle of word #4 to it and then move back, confirming
374 // that the selection end is moving with the extent. The offset between the
375 // extent and the selection end will be equal to half the width of "iiinmni" .
376 selection().moveRangeSelectionExtent(m_wordMiddles[4]);
377 EXPECT_EQ_SELECTED_TEXT("pqr iiinmni");
378 IntPoint p = m_wordMiddles[4];
379 p.move(m_letterPos[28].x() - m_letterPos[29].x(), 0);
380 selection().moveRangeSelectionExtent(p);
381 EXPECT_EQ_SELECTED_TEXT("pqr iiinmn");
382 p.move(m_letterPos[27].x() - m_letterPos[28].x(), 0);
383 selection().moveRangeSelectionExtent(p);
384 EXPECT_EQ_SELECTED_TEXT("pqr iiinm");
385 p.move(m_letterPos[26].x() - m_letterPos[27].x(), 0);
386 selection().moveRangeSelectionExtent(p);
387 EXPECT_EQ_SELECTED_TEXT("pqr iiin");
388 // Move right by the width of char 30 ('m'). Selection shouldn't change,
389 // but offset should be reduced.
390 p.move(m_letterPos[27].x() - m_letterPos[26].x(), 0);
391 selection().moveRangeSelectionExtent(p);
392 EXPECT_EQ_SELECTED_TEXT("pqr iiin");
393 // Move back a couple of character widths and confirm the selection still
394 // updates accordingly.
395 p.move(m_letterPos[25].x() - m_letterPos[26].x(), 0);
396 selection().moveRangeSelectionExtent(p);
397 EXPECT_EQ_SELECTED_TEXT("pqr iii");
398 p.move(m_letterPos[24].x() - m_letterPos[25].x(), 0);
399 selection().moveRangeSelectionExtent(p);
400 EXPECT_EQ_SELECTED_TEXT("pqr ii");
401 // "Catch up" with the handle - move the extent to where the handle is.
402 // "abcdef ghij kl mno^pqr ii|>inmni, abc"
403 selection().moveRangeSelectionExtent(m_letterPos[24]);
404 EXPECT_EQ_SELECTED_TEXT("pqr ii");
405 // Move ahead and confirm the selection expands accordingly
406 // "abcdef ghij kl mno^pqr iii|>nmni, abc"
407 selection().moveRangeSelectionExtent(m_letterPos[25]);
408 EXPECT_EQ_SELECTED_TEXT("pqr iii");
409
410 // Confirm we stay in character granularity if the user moves within a word.
411 // "abcdef ghij kl mno^pqr |>iiinmni, abc"
412 selection().moveRangeSelectionExtent(m_letterPos[22]);
413 EXPECT_EQ_SELECTED_TEXT("pqr ");
414 // It's possible to get a move when position doesn't change.
415 // It shouldn't affect anything.
416 p = m_letterPos[22];
417 p.move(1, 0);
418 selection().moveRangeSelectionExtent(p);
419 EXPECT_EQ_SELECTED_TEXT("pqr ");
420 // "abcdef ghij kl mno^pqr i|>iinmni, abc"
421 selection().moveRangeSelectionExtent(m_letterPos[23]);
422 EXPECT_EQ_SELECTED_TEXT("pqr i");
423 }
424
425 // Tests moving selection extent over to the other side of the base
426 // on text "abcd efgh ijkl mno^pqr|> iiinmni, abc"
427 // (^ means base, | means extent, < means start, and > means end).
428 // Text needs to be laid out on a single line with no rotation.
429 void GranularityStrategyTest::testDirectionSwitchSide()
430 {
431 // Move to the middle of word #4, selecting it - this will set the offset to
432 // be half the width of "iiinmni.
433 selection().moveRangeSelectionExtent(m_wordMiddles[4]);
434 EXPECT_EQ_SELECTED_TEXT("pqr iiinmni");
435 // Move back leaving only one letter selected.
436 IntPoint p = m_wordMiddles[4];
437 p.move(m_letterPos[19].x() - m_letterPos[29].x(), 0);
438 selection().moveRangeSelectionExtent(p);
439 EXPECT_EQ_SELECTED_TEXT("p");
440 // Confirm selection doesn't change if extent is positioned at base.
441 p.move(m_letterPos[18].x() - m_letterPos[19].x(), 0);
442 selection().moveRangeSelectionExtent(p);
443 EXPECT_EQ_SELECTED_TEXT("p");
444 // Move over to the other side of the base. Confirm the offset is preserved.
445 // (i.e. the selection start stays on the right of the extent)
446 // Confirm we stay in character granularity until the beginning of the word
447 // is passed.
448 p.move(m_letterPos[17].x() - m_letterPos[18].x(), 0);
449 selection().moveRangeSelectionExtent(p);
450 EXPECT_EQ_SELECTED_TEXT("o");
451 p.move(m_letterPos[16].x() - m_letterPos[17].x(), 0);
452 selection().moveRangeSelectionExtent(p);
453 EXPECT_EQ_SELECTED_TEXT("no");
454 p.move(m_letterPos[14].x() - m_letterPos[16].x(), 0);
455 selection().moveRangeSelectionExtent(p);
456 EXPECT_EQ_SELECTED_TEXT(" mno");
457 // Move to just one pixel on the right before the middle of the word #2.
458 // We should switch to word granularity, so the selection shouldn't change.
459 p.move(m_wordMiddles[2].x() - m_letterPos[14].x() + 1, 0);
460 selection().moveRangeSelectionExtent(p);
461 EXPECT_EQ_SELECTED_TEXT(" mno");
462 // Move over the middle of the word. The word should get selected.
463 // This should reduce the offset, but it should still stay greated than 0,
464 // since the width of "iiinmni" is greater than the width of "ijkl".
465 p.move(-2, 0);
466 selection().moveRangeSelectionExtent(p);
467 EXPECT_EQ_SELECTED_TEXT("ijkl mno");
468 // Move to just one pixel on the right of the middle of word #1.
469 // The selection should now include the space between the words.
470 p.move(m_wordMiddles[1].x() - m_letterPos[10].x() + 1, 0);
471 selection().moveRangeSelectionExtent(p);
472 EXPECT_EQ_SELECTED_TEXT(" ijkl mno");
473 // Move over the middle of the word. The word should get selected.
474 p.move(-2, 0);
475 selection().moveRangeSelectionExtent(p);
476 EXPECT_EQ_SELECTED_TEXT("efgh ijkl mno");
477 }
478
479 // Test for the default CharacterGranularityStrategy
480 TEST_F(GranularityStrategyTest, Character)
481 {
482 dummyPageHolder().frame().settings()->setSelectionStrategy(SelectionStrategy ::Character);
483 dummyPageHolder().frame().settings()->setDefaultFontSize(12);
484 // "Foo Bar Baz,"
485 RefPtrWillBeRawPtr<Text> text = appendTextNode("Foo Bar Baz,");
486 // "Foo B^a|>r Baz," (^ means base, | means extent, , < means start, and > m eans end).
487 selection().setSelection(VisibleSelection(Position(text, 5), Position(text, 6)));
488 EXPECT_EQ_SELECTED_TEXT("a");
489 // "Foo B^ar B|>az,"
490 selection().moveRangeSelectionExtent(visiblePositionToContentsPoint(VisibleP osition(Position(text, 9))));
491 EXPECT_EQ_SELECTED_TEXT("ar B");
492 // "F<|oo B^ar Baz,"
493 selection().moveRangeSelectionExtent(visiblePositionToContentsPoint(VisibleP osition(Position(text, 1))));
494 EXPECT_EQ_SELECTED_TEXT("oo B");
495 }
496
497 // DirectionGranularityStrategy strategy on rotated text should revert to the
498 // same behavior as CharacterGranularityStrategy
499 TEST_F(GranularityStrategyTest, DirectionRotate)
500 {
501 RefPtrWillBeRawPtr<Text> text = setupRotate("Foo Bar Baz,");
502 // "Foo B^a|>r Baz," (^ means base, | means extent, , < means start, and > m eans end).
503 selection().setSelection(VisibleSelection(Position(text, 5), Position(text, 6)));
504 EXPECT_EQ_SELECTED_TEXT("a");
505 IntPoint p = m_letterPos[9];
506 // Need to move by one pixel, otherwise this point is not evaluated
507 // to the same line as the text by hit testing.
508 p.move(1, 0);
509 // "Foo B^ar B|>az,"
510 selection().moveRangeSelectionExtent(p);
511 EXPECT_EQ_SELECTED_TEXT("ar B");
512 p = m_letterPos[1];
513 p.move(1, 0);
514 // "F<|oo B^ar Baz,"
515 selection().moveRangeSelectionExtent(p);
516 EXPECT_EQ_SELECTED_TEXT("oo B");
517 }
518
519 TEST_F(GranularityStrategyTest, DirectionExpandTranslateZ)
520 {
521 RefPtrWillBeRawPtr<Text> text = setupTranslateZ("abcdef ghij kl mnopqr stuvw i inm mnii,");
522 // "abcdef ghij kl mno^p|>qr stuvwi inm mnii," (^ means base, | means exten t, < means start, and > means end).
523 selection().setSelection(VisibleSelection(Position(text, 18), Position(text, 19)));
524 EXPECT_EQ_SELECTED_TEXT("p");
525 testDirectionExpand();
526 }
527
528 TEST_F(GranularityStrategyTest, DirectionExpandTransform)
529 {
530 RefPtrWillBeRawPtr<Text> text = setupTransform("abcdef ghij kl mnopqr stuvwi inm mnii,");
531 // "abcdef ghij kl mno^p|>qr stuvwi inm mnii," (^ means base, | means exten t, < means start, and > means end).
532 selection().setSelection(VisibleSelection(Position(text, 18), Position(text, 19)));
533 EXPECT_EQ_SELECTED_TEXT("p");
534 testDirectionExpand();
535 }
536
537 TEST_F(GranularityStrategyTest, DirectionExpandVerticalAlign)
538 {
539 // "abcdef ghij kl mno^p|>qr stuvwi inm mnii," (^ means base, | means exten t, < means start, and > means end).
540 setupVerticalAlign("abcdef ghij kl m", "nopq", "r stuvwi inm mnii,", 18, 19) ;
541 EXPECT_EQ_SELECTED_TEXT("p");
542 testDirectionExpand();
543 }
544
545 TEST_F(GranularityStrategyTest, DirectionExpandFontSizes)
546 {
547 setupFontSize("abcdef ghij kl mnopqr st", "uv", "wi inm mnii,", 18, 19);
548 EXPECT_EQ_SELECTED_TEXT("p");
549 testDirectionExpand();
550 }
551
552 TEST_F(GranularityStrategyTest, DirectionShrinkTranslateZ)
553 {
554 RefPtrWillBeRawPtr<Text> text = setupTranslateZ("abcdef ghij kl mnopqr iiinm ni, abc");
555 selection().setSelection(VisibleSelection(Position(text, 18), Position(text, 21)));
556 EXPECT_EQ_SELECTED_TEXT("pqr");
557 testDirectionShrink();
558 }
559
560 TEST_F(GranularityStrategyTest, DirectionShrinkTransform)
561 {
562 RefPtrWillBeRawPtr<Text> text = setupTransform("abcdef ghij kl mnopqr iiinmn i, abc");
563 selection().setSelection(VisibleSelection(Position(text, 18), Position(text, 21)));
564 EXPECT_EQ_SELECTED_TEXT("pqr");
565 testDirectionShrink();
566 }
567
568 TEST_F(GranularityStrategyTest, DirectionShrinkVerticalAlign)
569 {
570 setupVerticalAlign("abcdef ghij kl mnopqr ii", "inm", "ni, abc", 18, 21);
571 EXPECT_EQ_SELECTED_TEXT("pqr");
572 testDirectionShrink();
573 }
574
575 TEST_F(GranularityStrategyTest, DirectionShrinkFontSizes)
576 {
577 setupFontSize("abcdef ghij kl mnopqr ii", "inm", "ni, abc", 18, 21);
578 EXPECT_EQ_SELECTED_TEXT("pqr");
579 testDirectionShrink();
580 }
581
582 TEST_F(GranularityStrategyTest, DirectionSwitchSideTranslateZ)
583 {
584 RefPtrWillBeRawPtr<Text> text = setupTranslateZ("abcd efgh ijkl mnopqr iiinm ni, abc");
585 selection().setSelection(VisibleSelection(Position(text, 18), Position(text, 21)));
586 EXPECT_EQ_SELECTED_TEXT("pqr");
587 testDirectionSwitchSide();
588 }
589
590 TEST_F(GranularityStrategyTest, DirectionSwitchSideTransform)
591 {
592 RefPtrWillBeRawPtr<Text> text = setupTransform("abcd efgh ijkl mnopqr iiinmn i, abc");
593 selection().setSelection(VisibleSelection(Position(text, 18), Position(text, 21)));
594 EXPECT_EQ_SELECTED_TEXT("pqr");
595 testDirectionSwitchSide();
596 }
597
598 TEST_F(GranularityStrategyTest, DirectionSwitchSideVerticalAlign)
599 {
600 setupVerticalAlign("abcd efgh ijkl", " mnopqr", " iiinmni, abc", 18, 21);
601 EXPECT_EQ_SELECTED_TEXT("pqr");
602 testDirectionSwitchSide();
603 }
604
605 TEST_F(GranularityStrategyTest, DirectionSwitchSideFontSizes)
606 {
607 setupFontSize("abcd efgh i", "jk", "l mnopqr iiinmni, abc", 18, 21);
608 EXPECT_EQ_SELECTED_TEXT("pqr");
609 testDirectionSwitchSide();
610 }
611
612 // Tests moving extent over to the other side of the vase and immediately
613 // passing the word boundary and going into word granularity.
614 TEST_F(GranularityStrategyTest, DirectionSwitchSideWordGranularityThenShrink)
615 {
616 dummyPageHolder().frame().settings()->setDefaultFontSize(12);
617 WTF::String str = "ab cd efghijkl mnopqr iiin, abc";
618 RefPtrWillBeRawPtr<Text> text = document().createTextNode(str);
619 document().body()->appendChild(text);
620 dummyPageHolder().frame().settings()->setSelectionStrategy(SelectionStrategy ::Direction);
621
622 parseText(text.get());
623
624 // "abcd efgh ijkl mno^pqr|> iiin, abc" (^ means base, | means extent, < mea ns start, and > means end).
625 selection().setSelection(VisibleSelection(Position(text, 18), Position(text, 21)));
626 EXPECT_EQ_SELECTED_TEXT("pqr");
627 // Move to the middle of word #4 selecting it - this will set the offset to
628 // be half the width of "iiin".
629 selection().moveRangeSelectionExtent(m_wordMiddles[4]);
630 EXPECT_EQ_SELECTED_TEXT("pqr iiin");
631 // Move to the middle of word #2 - extent will switch over to the other
632 // side of the base, and we should enter word granularity since we pass
633 // the word boundary. The offset should become negative since the width
634 // of "efghjkkl" is greater than that of "iiin".
635 int offset = m_letterPos[26].x() - m_wordMiddles[4].x();
636 IntPoint p = IntPoint(m_wordMiddles[2].x() - offset - 1, m_wordMiddles[2].y( ));
637 selection().moveRangeSelectionExtent(p);
638 EXPECT_EQ_SELECTED_TEXT("efghijkl mno");
639 p.move(m_letterPos[7].x() - m_letterPos[6].x(), 0);
640 selection().moveRangeSelectionExtent(p);
641 EXPECT_EQ_SELECTED_TEXT("fghijkl mno");
642 }
643
644 // Make sure we switch to word granularity right away when starting on a
645 // word boundary and extending.
646 TEST_F(GranularityStrategyTest, DirectionSwitchStartOnBoundary)
647 {
648 dummyPageHolder().frame().settings()->setDefaultFontSize(12);
649 WTF::String str = "ab cd efghijkl mnopqr iiin, abc";
650 RefPtrWillBeRawPtr<Text> text = document().createTextNode(str);
651 document().body()->appendChild(text);
652 dummyPageHolder().frame().settings()->setSelectionStrategy(SelectionStrategy ::Direction);
653
654 parseText(text.get());
655
656 // "ab cd efghijkl ^mnopqr |>stuvwi inm," (^ means base and | means extent,
657 // > means end).
658 selection().setSelection(VisibleSelection(Position(text, 15), Position(text, 22)));
659 EXPECT_EQ_SELECTED_TEXT("mnopqr ");
660 selection().moveRangeSelectionExtent(m_wordMiddles[4]);
661 EXPECT_EQ_SELECTED_TEXT("mnopqr iiin");
662 }
663 }
OLDNEW
« no previous file with comments | « Source/core/editing/GranularityStrategy.cpp ('k') | Source/core/editing/VisibleUnits.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698