TEST_F(TextFinderTest, ScopeTextMatchesWithShadowDOM) { document().body()->setInnerHTML("<b>FOO</b><i>foo</i>", ASSERT_NO_EXCEPTION); RefPtrWillBeRawPtr<ShadowRoot> shadowRoot = document().body()->createShadowRootInternal(ShadowRootType::V0, ASSERT_NO_EXCEPTION); shadowRoot->setInnerHTML("<content select=\"i\"></content><u>Foo</u><content></content>", ASSERT_NO_EXCEPTION); Node* textInBElement = document().body()->firstChild()->firstChild(); Node* textInIElement = document().body()->lastChild()->firstChild(); Node* textInUElement = shadowRoot->childNodes()->item(1)->firstChild(); int identifier = 0; WebString searchText(String("fOO")); WebFindOptions findOptions; // Default. textFinder().resetMatchCount(); textFinder().scopeStringMatches(identifier, searchText, findOptions, true); while (textFinder().scopingInProgress()) runPendingTasks(); // TextIterator currently returns the matches in the composed tree order, // so in this case the matches will be returned in the order of // <i> -> <u> -> <b>. EXPECT_EQ(3, textFinder().totalMatchCount()); WebVector<WebFloatRect> matchRects; textFinder().findMatchRects(matchRects); ASSERT_EQ(3u, matchRects.size()); EXPECT_EQ(findInPageRect(textInIElement, 0, textInIElement, 3), matchRects[0]); EXPECT_EQ(findInPageRect(textInUElement, 0, textInUElement, 3), matchRects[1]); EXPECT_EQ(findInPageRect(textInBElement, 0, textInBElement, 3), matchRects[2]); }
TEST_F(TextFinderFakeTimerTest, ScopeWithTimeouts) { // Make a long string. String text(Vector<UChar>(100)); text.fill('a'); String searchPattern("abc"); // Make 4 substrings "abc" in text. text.insert(searchPattern, 1); text.insert(searchPattern, 10); text.insert(searchPattern, 50); text.insert(searchPattern, 90); document().body()->setInnerHTML(text, ASSERT_NO_EXCEPTION); int identifier = 0; WebFindOptions findOptions; // Default. textFinder().resetMatchCount(); // There will be only one iteration before timeout, because increment // of the TimeProxyPlatform timer is greater than timeout threshold. textFinder().scopeStringMatches(identifier, searchPattern, findOptions, true); while (textFinder().scopingInProgress()) runPendingTasks(); EXPECT_EQ(4, textFinder().totalMatchCount()); }
TEST_F(TextFinderTest, FindTextAutosizing) { document().body()->setInnerHTML("XXXXFindMeYYYYfindmeZZZZ", ASSERT_NO_EXCEPTION); int identifier = 0; WebString searchText(String("FindMe")); WebFindOptions findOptions; // Default. bool wrapWithinFrame = true; WebRect* selectionRect = nullptr; // Set viewport scale to 20 in order to simulate zoom-in VisualViewport& visualViewport = document().page()->frameHost().visualViewport(); visualViewport.setScale(20); // Enforce autosizing document().settings()->setTextAutosizingEnabled(true); document().settings()->setTextAutosizingWindowSizeOverride(IntSize(20, 20)); document().textAutosizer()->updatePageInfo(); // In case of autosizing, scale _should_ change ASSERT_TRUE(textFinder().find(identifier, searchText, findOptions, wrapWithinFrame, selectionRect)); ASSERT_TRUE(textFinder().activeMatch()); ASSERT_EQ(1, visualViewport.scale()); // in this case to 1 // Disable autosizing and reset scale to 20 visualViewport.setScale(20); document().settings()->setTextAutosizingEnabled(false); document().textAutosizer()->updatePageInfo(); ASSERT_TRUE(textFinder().find(identifier, searchText, findOptions, wrapWithinFrame, selectionRect)); ASSERT_TRUE(textFinder().activeMatch()); ASSERT_EQ(20, visualViewport.scale()); }
TEST_F(TextFinderTest, FindTextNotFound) { document().body()->setInnerHTML("XXXXFindMeYYYYfindmeZZZZ", ASSERT_NO_EXCEPTION); int identifier = 0; WebString searchText(String("Boo")); WebFindOptions findOptions; // Default. bool wrapWithinFrame = true; WebRect* selectionRect = nullptr; EXPECT_FALSE(textFinder().find(identifier, searchText, findOptions, wrapWithinFrame, selectionRect)); EXPECT_FALSE(textFinder().activeMatch()); }
TEST_F(TextFinderTest, FindTextNotFound) { document().body()->setInnerHTML("XXXXFindMeYYYYfindmeZZZZ"); document().updateStyleAndLayout(); int identifier = 0; WebString searchText(String("Boo")); WebFindOptions findOptions; // Default. bool wrapWithinFrame = true; EXPECT_FALSE( textFinder().find(identifier, searchText, findOptions, wrapWithinFrame)); EXPECT_FALSE(textFinder().activeMatch()); }
TEST_F(TextFinderTest, OverlappingMatches) { document().body()->setInnerHTML("aababaa", ASSERT_NO_EXCEPTION); Node* textNode = document().body()->firstChild(); int identifier = 0; WebString searchText(String("aba")); WebFindOptions findOptions; // Default. textFinder().resetMatchCount(); textFinder().scopeStringMatches(identifier, searchText, findOptions, true); while (textFinder().scopingInProgress()) runPendingTasks(); // We shouldn't find overlapped matches. EXPECT_EQ(1, textFinder().totalMatchCount()); WebVector<WebFloatRect> matchRects; textFinder().findMatchRects(matchRects); ASSERT_EQ(1u, matchRects.size()); EXPECT_EQ(findInPageRect(textNode, 1, textNode, 4), matchRects[0]); }
TEST_F(TextFinderTest, ScopeRepeatPatternTextMatches) { document().body()->setInnerHTML("ab ab ab ab ab", ASSERT_NO_EXCEPTION); Node* textNode = document().body()->firstChild(); int identifier = 0; WebString searchText(String("ab ab")); WebFindOptions findOptions; // Default. textFinder().resetMatchCount(); textFinder().scopeStringMatches(identifier, searchText, findOptions, true); while (textFinder().scopingInProgress()) runPendingTasks(); EXPECT_EQ(2, textFinder().totalMatchCount()); WebVector<WebFloatRect> matchRects; textFinder().findMatchRects(matchRects); ASSERT_EQ(2u, matchRects.size()); EXPECT_EQ(findInPageRect(textNode, 0, textNode, 5), matchRects[0]); EXPECT_EQ(findInPageRect(textNode, 6, textNode, 11), matchRects[1]); }
TEST_F(TextFinderTest, ScopeTextMatchesRepeated) { document().body()->setInnerHTML("XXXXFindMeYYYYfindmeZZZZ"); document().updateStyleAndLayout(); Node* textNode = document().body()->firstChild(); int identifier = 0; WebString searchText1(String("XFindMe")); WebString searchText2(String("FindMe")); WebFindOptions findOptions; // Default. textFinder().resetMatchCount(); textFinder().startScopingStringMatches(identifier, searchText1, findOptions); textFinder().startScopingStringMatches(identifier, searchText2, findOptions); while (textFinder().scopingInProgress()) runPendingTasks(); // Only searchText2 should be highlighted. EXPECT_EQ(2, textFinder().totalMatchCount()); WebVector<WebFloatRect> matchRects; textFinder().findMatchRects(matchRects); ASSERT_EQ(2u, matchRects.size()); EXPECT_EQ(findInPageRect(textNode, 4, textNode, 10), matchRects[0]); EXPECT_EQ(findInPageRect(textNode, 14, textNode, 20), matchRects[1]); }
TEST_F(TextFinderTest, SequentialMatches) { document().body()->setInnerHTML("ababab"); document().updateStyleAndLayout(); Node* textNode = document().body()->firstChild(); int identifier = 0; WebString searchText(String("ab")); WebFindOptions findOptions; // Default. textFinder().resetMatchCount(); textFinder().startScopingStringMatches(identifier, searchText, findOptions); while (textFinder().scopingInProgress()) runPendingTasks(); EXPECT_EQ(3, textFinder().totalMatchCount()); WebVector<WebFloatRect> matchRects; textFinder().findMatchRects(matchRects); ASSERT_EQ(3u, matchRects.size()); EXPECT_EQ(findInPageRect(textNode, 0, textNode, 2), matchRects[0]); EXPECT_EQ(findInPageRect(textNode, 2, textNode, 4), matchRects[1]); EXPECT_EQ(findInPageRect(textNode, 4, textNode, 6), matchRects[2]); }
TEST_F(TextFinderTest, FindTextSimple) { document().body()->setInnerHTML("XXXXFindMeYYYYfindmeZZZZ", ASSERT_NO_EXCEPTION); Node* textNode = document().body()->firstChild(); int identifier = 0; WebString searchText(String("FindMe")); WebFindOptions findOptions; // Default. bool wrapWithinFrame = true; WebRect* selectionRect = nullptr; ASSERT_TRUE(textFinder().find(identifier, searchText, findOptions, wrapWithinFrame, selectionRect)); Range* activeMatch = textFinder().activeMatch(); ASSERT_TRUE(activeMatch); EXPECT_EQ(textNode, activeMatch->startContainer()); EXPECT_EQ(4, activeMatch->startOffset()); EXPECT_EQ(textNode, activeMatch->endContainer()); EXPECT_EQ(10, activeMatch->endOffset()); findOptions.findNext = true; ASSERT_TRUE(textFinder().find(identifier, searchText, findOptions, wrapWithinFrame, selectionRect)); activeMatch = textFinder().activeMatch(); ASSERT_TRUE(activeMatch); EXPECT_EQ(textNode, activeMatch->startContainer()); EXPECT_EQ(14, activeMatch->startOffset()); EXPECT_EQ(textNode, activeMatch->endContainer()); EXPECT_EQ(20, activeMatch->endOffset()); // Should wrap to the first match. ASSERT_TRUE(textFinder().find(identifier, searchText, findOptions, wrapWithinFrame, selectionRect)); activeMatch = textFinder().activeMatch(); ASSERT_TRUE(activeMatch); EXPECT_EQ(textNode, activeMatch->startContainer()); EXPECT_EQ(4, activeMatch->startOffset()); EXPECT_EQ(textNode, activeMatch->endContainer()); EXPECT_EQ(10, activeMatch->endOffset()); // Search in the reverse order. identifier = 1; findOptions = WebFindOptions(); findOptions.forward = false; ASSERT_TRUE(textFinder().find(identifier, searchText, findOptions, wrapWithinFrame, selectionRect)); activeMatch = textFinder().activeMatch(); ASSERT_TRUE(activeMatch); EXPECT_EQ(textNode, activeMatch->startContainer()); EXPECT_EQ(14, activeMatch->startOffset()); EXPECT_EQ(textNode, activeMatch->endContainer()); EXPECT_EQ(20, activeMatch->endOffset()); findOptions.findNext = true; ASSERT_TRUE(textFinder().find(identifier, searchText, findOptions, wrapWithinFrame, selectionRect)); activeMatch = textFinder().activeMatch(); ASSERT_TRUE(activeMatch); EXPECT_EQ(textNode, activeMatch->startContainer()); EXPECT_EQ(4, activeMatch->startOffset()); EXPECT_EQ(textNode, activeMatch->endContainer()); EXPECT_EQ(10, activeMatch->endOffset()); // Wrap to the first match (last occurence in the document). ASSERT_TRUE(textFinder().find(identifier, searchText, findOptions, wrapWithinFrame, selectionRect)); activeMatch = textFinder().activeMatch(); ASSERT_TRUE(activeMatch); EXPECT_EQ(textNode, activeMatch->startContainer()); EXPECT_EQ(14, activeMatch->startOffset()); EXPECT_EQ(textNode, activeMatch->endContainer()); EXPECT_EQ(20, activeMatch->endOffset()); }
TEST_F(TextFinderTest, FindTextInShadowDOM) { document().body()->setInnerHTML("<b>FOO</b><i>foo</i>", ASSERT_NO_EXCEPTION); RefPtrWillBeRawPtr<ShadowRoot> shadowRoot = document().body()->createShadowRootInternal(ShadowRootType::V0, ASSERT_NO_EXCEPTION); shadowRoot->setInnerHTML("<content select=\"i\"></content><u>Foo</u><content></content>", ASSERT_NO_EXCEPTION); Node* textInBElement = document().body()->firstChild()->firstChild(); Node* textInIElement = document().body()->lastChild()->firstChild(); Node* textInUElement = shadowRoot->childNodes()->item(1)->firstChild(); int identifier = 0; WebString searchText(String("foo")); WebFindOptions findOptions; // Default. bool wrapWithinFrame = true; WebRect* selectionRect = nullptr; // TextIterator currently returns the matches in the composed treeorder, so // in this case the matches will be returned in the order of // <i> -> <u> -> <b>. ASSERT_TRUE(textFinder().find(identifier, searchText, findOptions, wrapWithinFrame, selectionRect)); Range* activeMatch = textFinder().activeMatch(); ASSERT_TRUE(activeMatch); EXPECT_EQ(textInIElement, activeMatch->startContainer()); EXPECT_EQ(0, activeMatch->startOffset()); EXPECT_EQ(textInIElement, activeMatch->endContainer()); EXPECT_EQ(3, activeMatch->endOffset()); findOptions.findNext = true; ASSERT_TRUE(textFinder().find(identifier, searchText, findOptions, wrapWithinFrame, selectionRect)); activeMatch = textFinder().activeMatch(); ASSERT_TRUE(activeMatch); EXPECT_EQ(textInUElement, activeMatch->startContainer()); EXPECT_EQ(0, activeMatch->startOffset()); EXPECT_EQ(textInUElement, activeMatch->endContainer()); EXPECT_EQ(3, activeMatch->endOffset()); ASSERT_TRUE(textFinder().find(identifier, searchText, findOptions, wrapWithinFrame, selectionRect)); activeMatch = textFinder().activeMatch(); ASSERT_TRUE(activeMatch); EXPECT_EQ(textInBElement, activeMatch->startContainer()); EXPECT_EQ(0, activeMatch->startOffset()); EXPECT_EQ(textInBElement, activeMatch->endContainer()); EXPECT_EQ(3, activeMatch->endOffset()); // Should wrap to the first match. ASSERT_TRUE(textFinder().find(identifier, searchText, findOptions, wrapWithinFrame, selectionRect)); activeMatch = textFinder().activeMatch(); ASSERT_TRUE(activeMatch); EXPECT_EQ(textInIElement, activeMatch->startContainer()); EXPECT_EQ(0, activeMatch->startOffset()); EXPECT_EQ(textInIElement, activeMatch->endContainer()); EXPECT_EQ(3, activeMatch->endOffset()); // Fresh search in the reverse order. identifier = 1; findOptions = WebFindOptions(); findOptions.forward = false; ASSERT_TRUE(textFinder().find(identifier, searchText, findOptions, wrapWithinFrame, selectionRect)); activeMatch = textFinder().activeMatch(); ASSERT_TRUE(activeMatch); EXPECT_EQ(textInBElement, activeMatch->startContainer()); EXPECT_EQ(0, activeMatch->startOffset()); EXPECT_EQ(textInBElement, activeMatch->endContainer()); EXPECT_EQ(3, activeMatch->endOffset()); findOptions.findNext = true; ASSERT_TRUE(textFinder().find(identifier, searchText, findOptions, wrapWithinFrame, selectionRect)); activeMatch = textFinder().activeMatch(); ASSERT_TRUE(activeMatch); EXPECT_EQ(textInUElement, activeMatch->startContainer()); EXPECT_EQ(0, activeMatch->startOffset()); EXPECT_EQ(textInUElement, activeMatch->endContainer()); EXPECT_EQ(3, activeMatch->endOffset()); ASSERT_TRUE(textFinder().find(identifier, searchText, findOptions, wrapWithinFrame, selectionRect)); activeMatch = textFinder().activeMatch(); ASSERT_TRUE(activeMatch); EXPECT_EQ(textInIElement, activeMatch->startContainer()); EXPECT_EQ(0, activeMatch->startOffset()); EXPECT_EQ(textInIElement, activeMatch->endContainer()); EXPECT_EQ(3, activeMatch->endOffset()); // And wrap. ASSERT_TRUE(textFinder().find(identifier, searchText, findOptions, wrapWithinFrame, selectionRect)); activeMatch = textFinder().activeMatch(); ASSERT_TRUE(activeMatch); EXPECT_EQ(textInBElement, activeMatch->startContainer()); EXPECT_EQ(0, activeMatch->startOffset()); EXPECT_EQ(textInBElement, activeMatch->endContainer()); EXPECT_EQ(3, activeMatch->endOffset()); }
TEST_F(TextFinderTest, FindTextJavaScriptUpdatesDOMAfterNoMatches) { document().body()->setInnerHTML("<b>XXXXYYYY</b><i></i>"); document().updateStyleAndLayout(); int identifier = 0; WebString searchText(String("FindMe")); WebFindOptions findOptions; // Default. bool wrapWithinFrame = true; bool activeNow = false; textFinder().resetMatchCount(); textFinder().startScopingStringMatches(identifier, searchText, findOptions); while (textFinder().scopingInProgress()) runPendingTasks(); findOptions.findNext = true; ASSERT_FALSE(textFinder().find(identifier, searchText, findOptions, wrapWithinFrame, &activeNow)); EXPECT_FALSE(activeNow); // Add new text to DOM and try FindNext. Element* iElement = toElement(document().body()->lastChild()); ASSERT_TRUE(iElement); iElement->setInnerHTML("ZZFindMe"); document().updateStyleAndLayout(); ASSERT_TRUE(textFinder().find(identifier, searchText, findOptions, wrapWithinFrame, &activeNow)); Range* activeMatch = textFinder().activeMatch(); ASSERT_TRUE(activeMatch); EXPECT_FALSE(activeNow); EXPECT_EQ(2, activeMatch->startOffset()); EXPECT_EQ(8, activeMatch->endOffset()); // Restart full search and check that added text is found. findOptions.findNext = false; textFinder().resetMatchCount(); textFinder().cancelPendingScopingEffort(); textFinder().startScopingStringMatches(identifier, searchText, findOptions); while (textFinder().scopingInProgress()) runPendingTasks(); EXPECT_EQ(1, textFinder().totalMatchCount()); WebVector<WebFloatRect> matchRects; textFinder().findMatchRects(matchRects); ASSERT_EQ(1u, matchRects.size()); Node* textInIElement = document().body()->lastChild()->firstChild(); EXPECT_EQ(findInPageRect(textInIElement, 2, textInIElement, 8), matchRects[0]); }