TEST_F(SurroundingTextTest, BasicRangeSelection) { setHTML(String("<p id='selection'>Lorem ipsum dolor sit amet</p>")); { VisibleSelection selection = select(0, 5); SurroundingText surroundingText(*firstRangeOf(selection), 1); EXPECT_EQ("Lorem ", surroundingText.content()); EXPECT_EQ(0u, surroundingText.startOffsetInContent()); EXPECT_EQ(5u, surroundingText.endOffsetInContent()); } { VisibleSelection selection = select(0, 5); SurroundingText surroundingText(*firstRangeOf(selection), 5); EXPECT_EQ("Lorem ip", surroundingText.content().simplifyWhiteSpace()); EXPECT_EQ(1u, surroundingText.startOffsetInContent()); EXPECT_EQ(6u, surroundingText.endOffsetInContent()); } { VisibleSelection selection = select(0, 5); SurroundingText surroundingText(*firstRangeOf(selection), 42); EXPECT_EQ("Lorem ipsum dolor sit amet", surroundingText.content().simplifyWhiteSpace()); EXPECT_EQ(1u, surroundingText.startOffsetInContent()); EXPECT_EQ(6u, surroundingText.endOffsetInContent()); } { VisibleSelection selection = select(6, 11); SurroundingText surroundingText(*firstRangeOf(selection), 2); EXPECT_EQ(" ipsum ", surroundingText.content()); EXPECT_EQ(1u, surroundingText.startOffsetInContent()); EXPECT_EQ(6u, surroundingText.endOffsetInContent()); } { VisibleSelection selection = select(6, 11); SurroundingText surroundingText(*firstRangeOf(selection), 42); EXPECT_EQ("Lorem ipsum dolor sit amet", surroundingText.content().simplifyWhiteSpace()); EXPECT_EQ(7u, surroundingText.startOffsetInContent()); EXPECT_EQ(12u, surroundingText.endOffsetInContent()); } }
TEST_F(SurroundingTextTest, TreeRangeSelection) { setHTML(String("<div>This is outside of <p id='selection'>foo bar</p> the selected node</div>")); { VisibleSelection selection = select(0, 1); SurroundingText surroundingText(*firstRangeOf(selection), 1); EXPECT_EQ("fo", surroundingText.content().simplifyWhiteSpace()); EXPECT_EQ(0u, surroundingText.startOffsetInContent()); EXPECT_EQ(1u, surroundingText.endOffsetInContent()); } { VisibleSelection selection = select(0, 3); SurroundingText surroundingText(*firstRangeOf(selection), 12); EXPECT_EQ("e of foo bar", surroundingText.content().simplifyWhiteSpace()); EXPECT_EQ(5u, surroundingText.startOffsetInContent()); EXPECT_EQ(8u, surroundingText.endOffsetInContent()); } { VisibleSelection selection = select(0, 3); SurroundingText surroundingText(*firstRangeOf(selection), 1337); EXPECT_EQ("This is outside of foo bar the selected node", surroundingText.content().simplifyWhiteSpace()); EXPECT_EQ(20u, surroundingText.startOffsetInContent()); EXPECT_EQ(23u, surroundingText.endOffsetInContent()); } { VisibleSelection selection = select(4, 7); SurroundingText surroundingText(*firstRangeOf(selection), 12); EXPECT_EQ("foo bar the se", surroundingText.content().simplifyWhiteSpace()); EXPECT_EQ(5u, surroundingText.startOffsetInContent()); EXPECT_EQ(8u, surroundingText.endOffsetInContent()); } { VisibleSelection selection = select(0, 7); SurroundingText surroundingText(*firstRangeOf(selection), 1337); EXPECT_EQ("This is outside of foo bar the selected node", surroundingText.content().simplifyWhiteSpace()); EXPECT_EQ(20u, surroundingText.startOffsetInContent()); EXPECT_EQ(27u, surroundingText.endOffsetInContent()); } }
bool TextFinder::find(int identifier, const WebString& searchText, const WebFindOptions& options, bool wrapWithinFrame, bool* activeNow) { if (!options.findNext) unmarkAllTextMatches(); else setMarkerActive(m_activeMatch.get(), false); if (m_activeMatch && &m_activeMatch->ownerDocument() != ownerFrame().frame()->document()) m_activeMatch = nullptr; // If the user has selected something since the last Find operation we want // to start from there. Otherwise, we start searching from where the last Find // operation left off (either a Find or a FindNext operation). VisibleSelection selection(ownerFrame().frame()->selection().selection()); bool activeSelection = !selection.isNone(); if (activeSelection) { m_activeMatch = firstRangeOf(selection); ownerFrame().frame()->selection().clear(); } DCHECK(ownerFrame().frame()); DCHECK(ownerFrame().frame()->view()); const FindOptions findOptions = (options.forward ? 0 : Backwards) | (options.matchCase ? 0 : CaseInsensitive) | (wrapWithinFrame ? WrapAround : 0) | (options.wordStart ? AtWordStarts : 0) | (options.medialCapitalAsWordStart ? TreatMedialCapitalAsWordStart : 0) | (options.findNext ? 0 : StartInSelection); m_activeMatch = ownerFrame().frame()->editor().findStringAndScrollToVisible( searchText, m_activeMatch.get(), findOptions); if (!m_activeMatch) { // If we're finding next the next active match might not be in the current // frame. In this case we don't want to clear the matches cache. if (!options.findNext) clearFindMatchesCache(); ownerFrame().frameView()->invalidatePaintForTickmarks(); return false; } // If the user is browsing a page with autosizing, adjust the zoom to the // column where the next hit has been found. Doing this when autosizing is // not set will result in a zoom reset on small devices. if (ownerFrame() .frame() ->document() ->textAutosizer() ->pageNeedsAutosizing()) { ownerFrame().viewImpl()->zoomToFindInPageRect( ownerFrame().frameView()->contentsToRootFrame( enclosingIntRect(LayoutObject::absoluteBoundingBoxRectForRange( m_activeMatch.get())))); } bool wasActiveFrame = m_currentActiveMatchFrame; m_currentActiveMatchFrame = true; bool isActive = setMarkerActive(m_activeMatch.get(), true); if (activeNow) *activeNow = isActive; // Make sure no node is focused. See http://crbug.com/38700. ownerFrame().frame()->document()->clearFocusedElement(); // Set this frame as focused. ownerFrame().viewImpl()->setFocusedFrame(&ownerFrame()); if (!options.findNext || activeSelection || !isActive) { // This is either an initial Find operation, a Find-next from a new // start point due to a selection, or new matches were found during // Find-next due to DOM alteration (that couldn't be set as active), so // we set the flag to ask the scoping effort to find the active rect for // us and report it back to the UI. m_locatingActiveRect = true; } else { if (!wasActiveFrame) { if (options.forward) m_activeMatchIndex = 0; else m_activeMatchIndex = m_lastMatchCount - 1; } else { if (options.forward) ++m_activeMatchIndex; else --m_activeMatchIndex; if (m_activeMatchIndex + 1 > m_lastMatchCount) m_activeMatchIndex = 0; else if (m_activeMatchIndex < 0) m_activeMatchIndex = m_lastMatchCount - 1; } WebRect selectionRect = ownerFrame().frameView()->contentsToRootFrame( m_activeMatch->boundingBox()); reportFindInPageSelection(selectionRect, m_activeMatchIndex + 1, identifier); } return true; }
PassRefPtrWillBeRawPtr<Range> SelectionEditor::firstRange() const { if (m_logicalRange) return m_logicalRange->cloneRange(); return firstRangeOf(m_selection); }