bool InPageSearchManager::findNextString(const String& text, FindOptions findOptions, bool wrap, bool highlightAllMatches, bool selectActiveMatchOnClear) { bool highlightAllMatchesStateChanged = m_highlightAllMatches != highlightAllMatches; m_highlightAllMatches = highlightAllMatches; if (!text.length()) { clearTextMatches(selectActiveMatchOnClear); cancelPendingScopingEffort(); m_activeSearchString = String(); m_webPage->m_client->updateFindStringResult(m_activeMatchCount, m_activeMatchIndex); return false; } if (!shouldSearchForText(text)) { m_activeSearchString = text; m_webPage->m_client->updateFindStringResult(m_activeMatchCount, m_activeMatchIndex); return false; } // Validate the range in case any node has been removed since last search. if (m_activeMatch && !m_activeMatch->boundaryPointsValid()) m_activeMatch = 0; ExceptionCode ec = 0; RefPtr<Range> searchStartingPoint = m_activeMatch ? m_activeMatch->cloneRange(ec) : 0; bool newSearch = highlightAllMatchesStateChanged || (m_activeSearchString != text); bool forward = !(findOptions & WebCore::Backwards); if (newSearch) { // Start a new search. m_activeSearchString = text; cancelPendingScopingEffort(); m_scopingCaseInsensitive = findOptions & CaseInsensitive; m_webPage->m_page->unmarkAllTextMatches(); } else { // Searching for same string should start from the end of last match. if (m_activeMatch) { if (forward) searchStartingPoint->setStart(searchStartingPoint->endPosition()); else searchStartingPoint->setEnd(searchStartingPoint->startPosition()); } } // If there is any active selection, new search should start from the beginning of it. bool startFromSelection = false; VisibleSelection selection = m_webPage->focusedOrMainFrame()->selection().selection(); if (!selection.isNone()) { searchStartingPoint = selection.firstRange().get(); m_webPage->focusedOrMainFrame()->selection().clear(); startFromSelection = true; } Frame* currentActiveMatchFrame = selection.isNone() && m_activeMatch ? m_activeMatch->ownerDocument().frame() : m_webPage->focusedOrMainFrame(); if (findAndMarkText(text, searchStartingPoint.get(), currentActiveMatchFrame, findOptions, newSearch, startFromSelection)) return true; Frame* startFrame = currentActiveMatchFrame; do { currentActiveMatchFrame = DOMSupport::incrementFrame(currentActiveMatchFrame, forward, wrap); if (!currentActiveMatchFrame) { // We should only ever have a null frame if we haven't found any // matches and we're not wrapping. We have searched every frame. ASSERT(!wrap); m_webPage->m_client->updateFindStringResult(m_activeMatchCount, m_activeMatchIndex); return false; } if (findAndMarkText(text, 0, currentActiveMatchFrame, findOptions, newSearch, startFromSelection)) return true; } while (startFrame != currentActiveMatchFrame); clearTextMatches(); m_webPage->m_client->updateFindStringResult(m_activeMatchCount, m_activeMatchIndex); return false; }
bool InPageSearchManager::findNextString(const String& text, bool forward) { if (!text.length()) { clearTextMatches(); cancelPendingScopingEffort(); m_activeSearchString = String(); return false; } if (!shouldSearchForText(text)) { m_activeSearchString = text; return false; } // Validate the range in case any node has been removed since last search. if (m_activeMatch && !m_activeMatch->boundaryPointsValid()) m_activeMatch = 0; RefPtr<Range> searchStartingPoint(m_activeMatch); bool newSearch = m_activeSearchString != text; if (newSearch) { // Start a new search. m_activeSearchString = text; cancelPendingScopingEffort(); m_webPage->m_page->unmarkAllTextMatches(); } else { // Search same string for next occurrence. setMarkerActive(m_activeMatch.get(), false /* active */); // Searching for same string should start from the end of last match. if (m_activeMatch) { if (forward) searchStartingPoint->setStart(searchStartingPoint->endPosition()); else searchStartingPoint->setEnd(searchStartingPoint->startPosition()); } } // If there is any active selection, new search should start from the beginning of it. VisibleSelection selection = m_webPage->focusedOrMainFrame()->selection()->selection(); if (!selection.isNone()) { searchStartingPoint = selection.firstRange().get(); m_webPage->focusedOrMainFrame()->selection()->clear(); } Frame* currentActiveMatchFrame = selection.isNone() && m_activeMatch ? m_activeMatch->ownerDocument()->frame() : m_webPage->focusedOrMainFrame(); const FindOptions findOptions = (forward ? 0 : Backwards) | CaseInsensitive | StartInSelection; if (findAndMarkText(text, searchStartingPoint.get(), currentActiveMatchFrame, findOptions, newSearch)) return true; Frame* startFrame = currentActiveMatchFrame; do { currentActiveMatchFrame = DOMSupport::incrementFrame(currentActiveMatchFrame, forward, true /* wrapFlag */); if (findAndMarkText(text, 0, currentActiveMatchFrame, findOptions, newSearch)) return true; } while (currentActiveMatchFrame && startFrame != currentActiveMatchFrame); clearTextMatches(); // FIXME: We need to notify client here. return false; }