| OLD | NEW |
| 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 "web/TextFinder.h" | 5 #include "web/TextFinder.h" |
| 6 | 6 |
| 7 #include "bindings/core/v8/ExceptionStatePlaceholder.h" | 7 #include "bindings/core/v8/ExceptionStatePlaceholder.h" |
| 8 #include "core/dom/Document.h" | 8 #include "core/dom/Document.h" |
| 9 #include "core/dom/NodeList.h" | 9 #include "core/dom/NodeList.h" |
| 10 #include "core/dom/Range.h" | 10 #include "core/dom/Range.h" |
| (...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 301 document().body()->setInnerHTML("XXXXFindMeYYYYfindmeZZZZ"); | 301 document().body()->setInnerHTML("XXXXFindMeYYYYfindmeZZZZ"); |
| 302 document().updateStyleAndLayout(); | 302 document().updateStyleAndLayout(); |
| 303 | 303 |
| 304 Node* textNode = document().body()->firstChild(); | 304 Node* textNode = document().body()->firstChild(); |
| 305 | 305 |
| 306 int identifier = 0; | 306 int identifier = 0; |
| 307 WebString searchText(String("FindMe")); | 307 WebString searchText(String("FindMe")); |
| 308 WebFindOptions findOptions; // Default. | 308 WebFindOptions findOptions; // Default. |
| 309 | 309 |
| 310 textFinder().resetMatchCount(); | 310 textFinder().resetMatchCount(); |
| 311 textFinder().scopeStringMatches(identifier, searchText, findOptions, true); | 311 textFinder().startScopingStringMatches(identifier, searchText, findOptions); |
| 312 while (textFinder().scopingInProgress()) | 312 while (textFinder().scopingInProgress()) |
| 313 runPendingTasks(); | 313 runPendingTasks(); |
| 314 | 314 |
| 315 EXPECT_EQ(2, textFinder().totalMatchCount()); | 315 EXPECT_EQ(2, textFinder().totalMatchCount()); |
| 316 WebVector<WebFloatRect> matchRects; | 316 WebVector<WebFloatRect> matchRects; |
| 317 textFinder().findMatchRects(matchRects); | 317 textFinder().findMatchRects(matchRects); |
| 318 ASSERT_EQ(2u, matchRects.size()); | 318 ASSERT_EQ(2u, matchRects.size()); |
| 319 EXPECT_EQ(findInPageRect(textNode, 4, textNode, 10), matchRects[0]); | 319 EXPECT_EQ(findInPageRect(textNode, 4, textNode, 10), matchRects[0]); |
| 320 EXPECT_EQ(findInPageRect(textNode, 14, textNode, 20), matchRects[1]); | 320 EXPECT_EQ(findInPageRect(textNode, 14, textNode, 20), matchRects[1]); |
| 321 } | 321 } |
| 322 | 322 |
| 323 TEST_F(TextFinderTest, ScopeTextMatchesRepeated) { |
| 324 document().body()->setInnerHTML("XXXXFindMeYYYYfindmeZZZZ"); |
| 325 document().updateStyleAndLayout(); |
| 326 |
| 327 Node* textNode = document().body()->firstChild(); |
| 328 |
| 329 int identifier = 0; |
| 330 WebString searchText1(String("XFindMe")); |
| 331 WebString searchText2(String("FindMe")); |
| 332 WebFindOptions findOptions; // Default. |
| 333 |
| 334 textFinder().resetMatchCount(); |
| 335 textFinder().startScopingStringMatches(identifier, searchText1, findOptions); |
| 336 textFinder().startScopingStringMatches(identifier, searchText2, findOptions); |
| 337 while (textFinder().scopingInProgress()) |
| 338 runPendingTasks(); |
| 339 |
| 340 // Only searchText2 should be highlighted. |
| 341 EXPECT_EQ(2, textFinder().totalMatchCount()); |
| 342 WebVector<WebFloatRect> matchRects; |
| 343 textFinder().findMatchRects(matchRects); |
| 344 ASSERT_EQ(2u, matchRects.size()); |
| 345 EXPECT_EQ(findInPageRect(textNode, 4, textNode, 10), matchRects[0]); |
| 346 EXPECT_EQ(findInPageRect(textNode, 14, textNode, 20), matchRects[1]); |
| 347 } |
| 348 |
| 323 TEST_F(TextFinderTest, ScopeTextMatchesWithShadowDOM) { | 349 TEST_F(TextFinderTest, ScopeTextMatchesWithShadowDOM) { |
| 324 document().body()->setInnerHTML("<b>FOO</b><i>foo</i>"); | 350 document().body()->setInnerHTML("<b>FOO</b><i>foo</i>"); |
| 325 ShadowRoot* shadowRoot = document().body()->createShadowRootInternal( | 351 ShadowRoot* shadowRoot = document().body()->createShadowRootInternal( |
| 326 ShadowRootType::V0, ASSERT_NO_EXCEPTION); | 352 ShadowRootType::V0, ASSERT_NO_EXCEPTION); |
| 327 shadowRoot->setInnerHTML( | 353 shadowRoot->setInnerHTML( |
| 328 "<content select=\"i\"></content><u>Foo</u><content></content>"); | 354 "<content select=\"i\"></content><u>Foo</u><content></content>"); |
| 329 Node* textInBElement = document().body()->firstChild()->firstChild(); | 355 Node* textInBElement = document().body()->firstChild()->firstChild(); |
| 330 Node* textInIElement = document().body()->lastChild()->firstChild(); | 356 Node* textInIElement = document().body()->lastChild()->firstChild(); |
| 331 Node* textInUElement = shadowRoot->childNodes()->item(1)->firstChild(); | 357 Node* textInUElement = shadowRoot->childNodes()->item(1)->firstChild(); |
| 332 document().updateStyleAndLayout(); | 358 document().updateStyleAndLayout(); |
| 333 | 359 |
| 334 int identifier = 0; | 360 int identifier = 0; |
| 335 WebString searchText(String("fOO")); | 361 WebString searchText(String("fOO")); |
| 336 WebFindOptions findOptions; // Default. | 362 WebFindOptions findOptions; // Default. |
| 337 | 363 |
| 338 textFinder().resetMatchCount(); | 364 textFinder().resetMatchCount(); |
| 339 textFinder().scopeStringMatches(identifier, searchText, findOptions, true); | 365 textFinder().startScopingStringMatches(identifier, searchText, findOptions); |
| 340 while (textFinder().scopingInProgress()) | 366 while (textFinder().scopingInProgress()) |
| 341 runPendingTasks(); | 367 runPendingTasks(); |
| 342 | 368 |
| 343 // TextIterator currently returns the matches in the flat tree order, | 369 // TextIterator currently returns the matches in the flat tree order, |
| 344 // so in this case the matches will be returned in the order of | 370 // so in this case the matches will be returned in the order of |
| 345 // <i> -> <u> -> <b>. | 371 // <i> -> <u> -> <b>. |
| 346 EXPECT_EQ(3, textFinder().totalMatchCount()); | 372 EXPECT_EQ(3, textFinder().totalMatchCount()); |
| 347 WebVector<WebFloatRect> matchRects; | 373 WebVector<WebFloatRect> matchRects; |
| 348 textFinder().findMatchRects(matchRects); | 374 textFinder().findMatchRects(matchRects); |
| 349 ASSERT_EQ(3u, matchRects.size()); | 375 ASSERT_EQ(3u, matchRects.size()); |
| 350 EXPECT_EQ(findInPageRect(textInIElement, 0, textInIElement, 3), | 376 EXPECT_EQ(findInPageRect(textInIElement, 0, textInIElement, 3), |
| 351 matchRects[0]); | 377 matchRects[0]); |
| 352 EXPECT_EQ(findInPageRect(textInUElement, 0, textInUElement, 3), | 378 EXPECT_EQ(findInPageRect(textInUElement, 0, textInUElement, 3), |
| 353 matchRects[1]); | 379 matchRects[1]); |
| 354 EXPECT_EQ(findInPageRect(textInBElement, 0, textInBElement, 3), | 380 EXPECT_EQ(findInPageRect(textInBElement, 0, textInBElement, 3), |
| 355 matchRects[2]); | 381 matchRects[2]); |
| 356 } | 382 } |
| 357 | 383 |
| 358 TEST_F(TextFinderTest, ScopeRepeatPatternTextMatches) { | 384 TEST_F(TextFinderTest, ScopeRepeatPatternTextMatches) { |
| 359 document().body()->setInnerHTML("ab ab ab ab ab"); | 385 document().body()->setInnerHTML("ab ab ab ab ab"); |
| 360 document().updateStyleAndLayout(); | 386 document().updateStyleAndLayout(); |
| 361 | 387 |
| 362 Node* textNode = document().body()->firstChild(); | 388 Node* textNode = document().body()->firstChild(); |
| 363 | 389 |
| 364 int identifier = 0; | 390 int identifier = 0; |
| 365 WebString searchText(String("ab ab")); | 391 WebString searchText(String("ab ab")); |
| 366 WebFindOptions findOptions; // Default. | 392 WebFindOptions findOptions; // Default. |
| 367 | 393 |
| 368 textFinder().resetMatchCount(); | 394 textFinder().resetMatchCount(); |
| 369 textFinder().scopeStringMatches(identifier, searchText, findOptions, true); | 395 textFinder().startScopingStringMatches(identifier, searchText, findOptions); |
| 370 while (textFinder().scopingInProgress()) | 396 while (textFinder().scopingInProgress()) |
| 371 runPendingTasks(); | 397 runPendingTasks(); |
| 372 | 398 |
| 373 EXPECT_EQ(2, textFinder().totalMatchCount()); | 399 EXPECT_EQ(2, textFinder().totalMatchCount()); |
| 374 WebVector<WebFloatRect> matchRects; | 400 WebVector<WebFloatRect> matchRects; |
| 375 textFinder().findMatchRects(matchRects); | 401 textFinder().findMatchRects(matchRects); |
| 376 ASSERT_EQ(2u, matchRects.size()); | 402 ASSERT_EQ(2u, matchRects.size()); |
| 377 EXPECT_EQ(findInPageRect(textNode, 0, textNode, 5), matchRects[0]); | 403 EXPECT_EQ(findInPageRect(textNode, 0, textNode, 5), matchRects[0]); |
| 378 EXPECT_EQ(findInPageRect(textNode, 6, textNode, 11), matchRects[1]); | 404 EXPECT_EQ(findInPageRect(textNode, 6, textNode, 11), matchRects[1]); |
| 379 } | 405 } |
| 380 | 406 |
| 381 TEST_F(TextFinderTest, OverlappingMatches) { | 407 TEST_F(TextFinderTest, OverlappingMatches) { |
| 382 document().body()->setInnerHTML("aababaa"); | 408 document().body()->setInnerHTML("aababaa"); |
| 383 document().updateStyleAndLayout(); | 409 document().updateStyleAndLayout(); |
| 384 | 410 |
| 385 Node* textNode = document().body()->firstChild(); | 411 Node* textNode = document().body()->firstChild(); |
| 386 | 412 |
| 387 int identifier = 0; | 413 int identifier = 0; |
| 388 WebString searchText(String("aba")); | 414 WebString searchText(String("aba")); |
| 389 WebFindOptions findOptions; // Default. | 415 WebFindOptions findOptions; // Default. |
| 390 | 416 |
| 391 textFinder().resetMatchCount(); | 417 textFinder().resetMatchCount(); |
| 392 textFinder().scopeStringMatches(identifier, searchText, findOptions, true); | 418 textFinder().startScopingStringMatches(identifier, searchText, findOptions); |
| 393 while (textFinder().scopingInProgress()) | 419 while (textFinder().scopingInProgress()) |
| 394 runPendingTasks(); | 420 runPendingTasks(); |
| 395 | 421 |
| 396 // We shouldn't find overlapped matches. | 422 // We shouldn't find overlapped matches. |
| 397 EXPECT_EQ(1, textFinder().totalMatchCount()); | 423 EXPECT_EQ(1, textFinder().totalMatchCount()); |
| 398 WebVector<WebFloatRect> matchRects; | 424 WebVector<WebFloatRect> matchRects; |
| 399 textFinder().findMatchRects(matchRects); | 425 textFinder().findMatchRects(matchRects); |
| 400 ASSERT_EQ(1u, matchRects.size()); | 426 ASSERT_EQ(1u, matchRects.size()); |
| 401 EXPECT_EQ(findInPageRect(textNode, 1, textNode, 4), matchRects[0]); | 427 EXPECT_EQ(findInPageRect(textNode, 1, textNode, 4), matchRects[0]); |
| 402 } | 428 } |
| 403 | 429 |
| 404 TEST_F(TextFinderTest, SequentialMatches) { | 430 TEST_F(TextFinderTest, SequentialMatches) { |
| 405 document().body()->setInnerHTML("ababab"); | 431 document().body()->setInnerHTML("ababab"); |
| 406 document().updateStyleAndLayout(); | 432 document().updateStyleAndLayout(); |
| 407 | 433 |
| 408 Node* textNode = document().body()->firstChild(); | 434 Node* textNode = document().body()->firstChild(); |
| 409 | 435 |
| 410 int identifier = 0; | 436 int identifier = 0; |
| 411 WebString searchText(String("ab")); | 437 WebString searchText(String("ab")); |
| 412 WebFindOptions findOptions; // Default. | 438 WebFindOptions findOptions; // Default. |
| 413 | 439 |
| 414 textFinder().resetMatchCount(); | 440 textFinder().resetMatchCount(); |
| 415 textFinder().scopeStringMatches(identifier, searchText, findOptions, true); | 441 textFinder().startScopingStringMatches(identifier, searchText, findOptions); |
| 416 while (textFinder().scopingInProgress()) | 442 while (textFinder().scopingInProgress()) |
| 417 runPendingTasks(); | 443 runPendingTasks(); |
| 418 | 444 |
| 419 EXPECT_EQ(3, textFinder().totalMatchCount()); | 445 EXPECT_EQ(3, textFinder().totalMatchCount()); |
| 420 WebVector<WebFloatRect> matchRects; | 446 WebVector<WebFloatRect> matchRects; |
| 421 textFinder().findMatchRects(matchRects); | 447 textFinder().findMatchRects(matchRects); |
| 422 ASSERT_EQ(3u, matchRects.size()); | 448 ASSERT_EQ(3u, matchRects.size()); |
| 423 EXPECT_EQ(findInPageRect(textNode, 0, textNode, 2), matchRects[0]); | 449 EXPECT_EQ(findInPageRect(textNode, 0, textNode, 2), matchRects[0]); |
| 424 EXPECT_EQ(findInPageRect(textNode, 2, textNode, 4), matchRects[1]); | 450 EXPECT_EQ(findInPageRect(textNode, 2, textNode, 4), matchRects[1]); |
| 425 EXPECT_EQ(findInPageRect(textNode, 4, textNode, 6), matchRects[2]); | 451 EXPECT_EQ(findInPageRect(textNode, 4, textNode, 6), matchRects[2]); |
| 426 } | 452 } |
| 427 | 453 |
| 428 TEST_F(TextFinderTest, FindTextJavaScriptUpdatesDOM) { | 454 TEST_F(TextFinderTest, FindTextJavaScriptUpdatesDOM) { |
| 429 document().body()->setInnerHTML("<b>XXXXFindMeYYYY</b><i></i>"); | 455 document().body()->setInnerHTML("<b>XXXXFindMeYYYY</b><i></i>"); |
| 430 document().updateStyleAndLayout(); | 456 document().updateStyleAndLayout(); |
| 431 | 457 |
| 432 int identifier = 0; | 458 int identifier = 0; |
| 433 WebString searchText(String("FindMe")); | 459 WebString searchText(String("FindMe")); |
| 434 WebFindOptions findOptions; // Default. | 460 WebFindOptions findOptions; // Default. |
| 435 bool wrapWithinFrame = true; | 461 bool wrapWithinFrame = true; |
| 436 bool activeNow; | 462 bool activeNow; |
| 437 | 463 |
| 438 textFinder().resetMatchCount(); | 464 textFinder().resetMatchCount(); |
| 439 textFinder().scopeStringMatches(identifier, searchText, findOptions, true); | 465 textFinder().startScopingStringMatches(identifier, searchText, findOptions); |
| 440 while (textFinder().scopingInProgress()) | 466 while (textFinder().scopingInProgress()) |
| 441 runPendingTasks(); | 467 runPendingTasks(); |
| 442 | 468 |
| 443 findOptions.findNext = true; | 469 findOptions.findNext = true; |
| 444 ASSERT_TRUE(textFinder().find(identifier, searchText, findOptions, | 470 ASSERT_TRUE(textFinder().find(identifier, searchText, findOptions, |
| 445 wrapWithinFrame, &activeNow)); | 471 wrapWithinFrame, &activeNow)); |
| 446 EXPECT_TRUE(activeNow); | 472 EXPECT_TRUE(activeNow); |
| 447 ASSERT_TRUE(textFinder().find(identifier, searchText, findOptions, | 473 ASSERT_TRUE(textFinder().find(identifier, searchText, findOptions, |
| 448 wrapWithinFrame, &activeNow)); | 474 wrapWithinFrame, &activeNow)); |
| 449 EXPECT_TRUE(activeNow); | 475 EXPECT_TRUE(activeNow); |
| 450 | 476 |
| 451 // Add new text to DOM and try FindNext. | 477 // Add new text to DOM and try FindNext. |
| 452 Element* iElement = toElement(document().body()->lastChild()); | 478 Element* iElement = toElement(document().body()->lastChild()); |
| 453 ASSERT_TRUE(iElement); | 479 ASSERT_TRUE(iElement); |
| 454 iElement->setInnerHTML("ZZFindMe"); | 480 iElement->setInnerHTML("ZZFindMe"); |
| 455 document().updateStyleAndLayout(); | 481 document().updateStyleAndLayout(); |
| 456 | 482 |
| 457 ASSERT_TRUE(textFinder().find(identifier, searchText, findOptions, | 483 ASSERT_TRUE(textFinder().find(identifier, searchText, findOptions, |
| 458 wrapWithinFrame, &activeNow)); | 484 wrapWithinFrame, &activeNow)); |
| 459 Range* activeMatch = textFinder().activeMatch(); | 485 Range* activeMatch = textFinder().activeMatch(); |
| 460 ASSERT_TRUE(activeMatch); | 486 ASSERT_TRUE(activeMatch); |
| 461 EXPECT_FALSE(activeNow); | 487 EXPECT_FALSE(activeNow); |
| 462 EXPECT_EQ(2, activeMatch->startOffset()); | 488 EXPECT_EQ(2, activeMatch->startOffset()); |
| 463 EXPECT_EQ(8, activeMatch->endOffset()); | 489 EXPECT_EQ(8, activeMatch->endOffset()); |
| 464 | 490 |
| 465 // Restart full search and check that added text is found. | 491 // Restart full search and check that added text is found. |
| 466 findOptions.findNext = false; | 492 findOptions.findNext = false; |
| 467 textFinder().resetMatchCount(); | 493 textFinder().resetMatchCount(); |
| 468 textFinder().cancelPendingScopingEffort(); | 494 textFinder().cancelPendingScopingEffort(); |
| 469 textFinder().scopeStringMatches(identifier, searchText, findOptions, true); | 495 textFinder().startScopingStringMatches(identifier, searchText, findOptions); |
| 470 while (textFinder().scopingInProgress()) | 496 while (textFinder().scopingInProgress()) |
| 471 runPendingTasks(); | 497 runPendingTasks(); |
| 472 EXPECT_EQ(2, textFinder().totalMatchCount()); | 498 EXPECT_EQ(2, textFinder().totalMatchCount()); |
| 473 | 499 |
| 474 WebVector<WebFloatRect> matchRects; | 500 WebVector<WebFloatRect> matchRects; |
| 475 textFinder().findMatchRects(matchRects); | 501 textFinder().findMatchRects(matchRects); |
| 476 ASSERT_EQ(2u, matchRects.size()); | 502 ASSERT_EQ(2u, matchRects.size()); |
| 477 Node* textInBElement = document().body()->firstChild()->firstChild(); | 503 Node* textInBElement = document().body()->firstChild()->firstChild(); |
| 478 Node* textInIElement = document().body()->lastChild()->firstChild(); | 504 Node* textInIElement = document().body()->lastChild()->firstChild(); |
| 479 EXPECT_EQ(findInPageRect(textInBElement, 4, textInBElement, 10), | 505 EXPECT_EQ(findInPageRect(textInBElement, 4, textInBElement, 10), |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 519 document().body()->setInnerHTML(text); | 545 document().body()->setInnerHTML(text); |
| 520 document().updateStyleAndLayout(); | 546 document().updateStyleAndLayout(); |
| 521 | 547 |
| 522 int identifier = 0; | 548 int identifier = 0; |
| 523 WebFindOptions findOptions; // Default. | 549 WebFindOptions findOptions; // Default. |
| 524 | 550 |
| 525 textFinder().resetMatchCount(); | 551 textFinder().resetMatchCount(); |
| 526 | 552 |
| 527 // There will be only one iteration before timeout, because increment | 553 // There will be only one iteration before timeout, because increment |
| 528 // of the TimeProxyPlatform timer is greater than timeout threshold. | 554 // of the TimeProxyPlatform timer is greater than timeout threshold. |
| 529 textFinder().scopeStringMatches(identifier, searchPattern, findOptions, true); | 555 textFinder().startScopingStringMatches(identifier, searchPattern, |
| 556 findOptions); |
| 530 while (textFinder().scopingInProgress()) | 557 while (textFinder().scopingInProgress()) |
| 531 runPendingTasks(); | 558 runPendingTasks(); |
| 532 | 559 |
| 533 EXPECT_EQ(4, textFinder().totalMatchCount()); | 560 EXPECT_EQ(4, textFinder().totalMatchCount()); |
| 534 } | 561 } |
| 535 | 562 |
| 536 } // namespace blink | 563 } // namespace blink |
| OLD | NEW |