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

Unified Diff: third_party/WebKit/Source/web/TextFinder.cpp

Issue 1959183002: Multi-Process Find-in-Page. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Disabled tests on Android Release because of crbug.com/615291. Created 4 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/WebKit/Source/web/TextFinder.h ('k') | third_party/WebKit/Source/web/WebLocalFrameImpl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/WebKit/Source/web/TextFinder.cpp
diff --git a/third_party/WebKit/Source/web/TextFinder.cpp b/third_party/WebKit/Source/web/TextFinder.cpp
index 4f6ea4071f41fc591a29e4b1a71e0d3519dde50c..407dc0d75e6b7698703d9de4ac15f24d8a189790 100644
--- a/third_party/WebKit/Source/web/TextFinder.cpp
+++ b/third_party/WebKit/Source/web/TextFinder.cpp
@@ -117,8 +117,6 @@ bool TextFinder::find(int identifier, const WebString& searchText, const WebFind
if (!ownerFrame().frame() || !ownerFrame().frame()->page())
return false;
- WebLocalFrameImpl* mainFrameImpl = ownerFrame().viewImpl()->mainFrameImpl();
-
if (!options.findNext)
unmarkAllTextMatches();
else
@@ -164,49 +162,58 @@ bool TextFinder::find(int identifier, const WebString& searchText, const WebFind
ownerFrame().viewImpl()->zoomToFindInPageRect(ownerFrame().frameView()->contentsToRootFrame(enclosingIntRect(LayoutObject::absoluteBoundingBoxRectForRange(m_activeMatch.get()))));
}
- WebLocalFrameImpl* oldActiveFrame = mainFrameImpl->ensureTextFinder().m_currentActiveMatchFrame;
- mainFrameImpl->ensureTextFinder().m_currentActiveMatchFrame = &ownerFrame();
-
- // Make sure no node is focused. See http://crbug.com/38700.
- ownerFrame().frame()->document()->clearFocusedElement();
+ 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 a 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.
+ // 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 (oldActiveFrame != &ownerFrame()) {
+ if (!wasActiveFrame) {
if (options.forward)
- m_activeMatchIndexInCurrentFrame = 0;
+ m_activeMatchIndex = 0;
else
- m_activeMatchIndexInCurrentFrame = m_lastMatchCount - 1;
+ m_activeMatchIndex = m_lastMatchCount - 1;
} else {
if (options.forward)
- ++m_activeMatchIndexInCurrentFrame;
+ ++m_activeMatchIndex;
else
- --m_activeMatchIndexInCurrentFrame;
+ --m_activeMatchIndex;
- if (m_activeMatchIndexInCurrentFrame + 1 > m_lastMatchCount)
- m_activeMatchIndexInCurrentFrame = 0;
- if (m_activeMatchIndexInCurrentFrame == -1)
- m_activeMatchIndexInCurrentFrame = m_lastMatchCount - 1;
+ if (m_activeMatchIndex + 1 > m_lastMatchCount)
+ m_activeMatchIndex = 0;
+ else if (m_activeMatchIndex < 0)
+ m_activeMatchIndex = m_lastMatchCount - 1;
}
if (selectionRect) {
*selectionRect = ownerFrame().frameView()->contentsToRootFrame(m_activeMatch->boundingBox());
- reportFindInPageSelection(*selectionRect, m_activeMatchIndexInCurrentFrame + 1, identifier);
+ reportFindInPageSelection(*selectionRect, m_activeMatchIndex + 1, identifier);
}
}
return true;
}
+void TextFinder::clearActiveFindMatch()
+{
+ m_currentActiveMatchFrame = false;
+ setMarkerActive(m_activeMatch.get(), false);
+}
+
void TextFinder::stopFindingAndClearSelection()
{
cancelPendingScopingEffort();
@@ -232,10 +239,9 @@ void TextFinder::reportFindInPageResultToAccessibility(int identifier)
if (!startObject || !endObject)
return;
- WebLocalFrameImpl* mainFrameImpl = ownerFrame().viewImpl()->mainFrameImpl();
- if (mainFrameImpl && mainFrameImpl->client()) {
- mainFrameImpl->client()->handleAccessibilityFindInPageResult(
- identifier, m_activeMatchIndexInCurrentFrame + 1,
+ if (ownerFrame().client()) {
+ ownerFrame().client()->handleAccessibilityFindInPageResult(
+ identifier, m_activeMatchIndex + 1,
WebAXObject(startObject), m_activeMatch->startOffset(),
WebAXObject(endObject), m_activeMatch->endOffset());
}
@@ -266,7 +272,7 @@ void TextFinder::scopeStringMatches(int identifier, const WebString& searchText,
// The view might be null on detached frames.
LocalFrame* frame = ownerFrame().frame();
if (frame && frame->page())
- ownerFrame().viewImpl()->mainFrameImpl()->ensureTextFinder().m_framesScopingCount++;
+ m_frameScoping = true;
// Now, defer scoping until later to allow find operation to finish quickly.
scopeStringMatchesSoon(identifier, searchText, options, false); // false means just reset, so don't do it again.
@@ -274,14 +280,10 @@ void TextFinder::scopeStringMatches(int identifier, const WebString& searchText,
}
if (!shouldScopeMatches(searchText)) {
- // Note that we want to defer the final update when resetting even if shouldScopeMatches returns false.
- // This is done in order to prevent sending a final message based only on the results of the first frame
- // since m_framesScopingCount would be 0 as other frames have yet to reset.
finishCurrentScopingEffort(identifier);
return;
}
- WebLocalFrameImpl* mainFrameImpl = ownerFrame().viewImpl()->mainFrameImpl();
PositionInFlatTree searchStart = PositionInFlatTree::firstPositionInNode(ownerFrame().frame()->document());
PositionInFlatTree searchEnd = PositionInFlatTree::lastPositionInNode(ownerFrame().frame()->document());
DCHECK_EQ(searchStart.document(), searchEnd.document());
@@ -341,17 +343,17 @@ void TextFinder::scopeStringMatches(int identifier, const WebString& searchText,
bool foundActiveMatch = false;
if (m_locatingActiveRect && (activeSelectionRect == resultBounds)) {
// We have found the active tickmark frame.
- mainFrameImpl->ensureTextFinder().m_currentActiveMatchFrame = &ownerFrame();
+ m_currentActiveMatchFrame = true;
foundActiveMatch = true;
// We also know which tickmark is active now.
- m_activeMatchIndexInCurrentFrame = matchCount - 1;
+ m_activeMatchIndex = matchCount - 1;
// To stop looking for the active tickmark, we set this flag.
m_locatingActiveRect = false;
// Notify browser of new location for the selected rectangle.
reportFindInPageSelection(
ownerFrame().frameView()->contentsToRootFrame(resultBounds),
- m_activeMatchIndexInCurrentFrame + 1,
+ m_activeMatchIndex + 1,
identifier);
}
@@ -380,8 +382,8 @@ void TextFinder::scopeStringMatches(int identifier, const WebString& searchText,
ownerFrame().client()->reportFindInFrameMatchCount(identifier, m_lastMatchCount, false);
- // Let the mainframe know how much we found during this pass.
- mainFrameImpl->increaseMatchCount(matchCount, identifier);
+ // Let the frame know how many matches we found during this pass.
+ ownerFrame().increaseMatchCount(matchCount, identifier);
}
if (timedOut) {
@@ -408,8 +410,8 @@ void TextFinder::flushCurrentScopingEffort(int identifier)
if (!ownerFrame().frame() || !ownerFrame().frame()->page())
return;
- WebLocalFrameImpl* mainFrameImpl = ownerFrame().viewImpl()->mainFrameImpl();
- mainFrameImpl->ensureTextFinder().decrementFramesScopingCount(identifier);
+ m_frameScoping = false;
+ ownerFrame().increaseMatchCount(0, identifier);
}
void TextFinder::finishCurrentScopingEffort(int identifier)
@@ -431,7 +433,7 @@ void TextFinder::cancelPendingScopingEffort()
deferredWork->dispose();
m_deferredScopingWork.clear();
- m_activeMatchIndexInCurrentFrame = -1;
+ m_activeMatchIndex = -1;
// Last request didn't complete.
if (m_scopingInProgress)
@@ -449,14 +451,14 @@ void TextFinder::increaseMatchCount(int identifier, int count)
// Update the UI with the latest findings.
if (ownerFrame().client())
- ownerFrame().client()->reportFindInPageMatchCount(identifier, m_totalMatchCount, !m_framesScopingCount);
+ ownerFrame().client()->reportFindInPageMatchCount(identifier, m_totalMatchCount, !m_frameScoping);
}
void TextFinder::reportFindInPageSelection(const WebRect& selectionRect, int activeMatchOrdinal, int identifier)
{
// Update the UI with the latest selection rect.
if (ownerFrame().client())
- ownerFrame().client()->reportFindInPageSelection(identifier, ordinalOfFirstMatch() + activeMatchOrdinal, selectionRect);
+ ownerFrame().client()->reportFindInPageSelection(identifier, activeMatchOrdinal, selectionRect);
// Update accessibility too, so if the user commits to this query
// we can move accessibility focus to this result.
@@ -469,29 +471,18 @@ void TextFinder::resetMatchCount()
++m_findMatchMarkersVersion;
m_totalMatchCount = 0;
- m_framesScopingCount = 0;
+ m_frameScoping = false;
}
void TextFinder::clearFindMatchesCache()
{
if (!m_findMatchesCache.isEmpty())
- ownerFrame().viewImpl()->mainFrameImpl()->ensureTextFinder().m_findMatchMarkersVersion++;
+ ++m_findMatchMarkersVersion;
m_findMatchesCache.clear();
m_findMatchRectsAreValid = false;
}
-bool TextFinder::isActiveMatchFrameValid() const
-{
- WebLocalFrameImpl* mainFrameImpl = ownerFrame().viewImpl()->mainFrameImpl();
- if (!mainFrameImpl->textFinder())
- return false;
-
- if (WebLocalFrameImpl* activeMatchFrame = mainFrameImpl->textFinder()->activeMatchFrame())
- return activeMatchFrame->textFinder()->activeMatch() && activeMatchFrame->frame()->tree().isDescendantOf(mainFrameImpl->frame());
- return false;
-}
-
void TextFinder::updateFindMatchRects()
{
IntSize currentContentsSize = ownerFrame().contentsSize();
@@ -534,71 +525,56 @@ void TextFinder::updateFindMatchRects()
WebFloatRect TextFinder::activeFindMatchRect()
{
- if (!isActiveMatchFrameValid())
+ if (!m_currentActiveMatchFrame || !m_activeMatch)
return WebFloatRect();
- return WebFloatRect(findInPageRectFromRange(m_currentActiveMatchFrame->textFinder()->activeMatch()));
+ return WebFloatRect(findInPageRectFromRange(activeMatch()));
}
void TextFinder::findMatchRects(WebVector<WebFloatRect>& outputRects)
{
- Vector<WebFloatRect> matchRects;
- for (WebLocalFrameImpl* frame = &ownerFrame(); frame; frame = toWebLocalFrameImpl(frame->traverseNextLocal(false)))
- frame->ensureTextFinder().appendFindMatchRects(matchRects);
-
- outputRects = matchRects;
-}
-
-void TextFinder::appendFindMatchRects(Vector<WebFloatRect>& frameRects)
-{
updateFindMatchRects();
- frameRects.reserveCapacity(frameRects.size() + m_findMatchesCache.size());
+
+ Vector<WebFloatRect> matchRects;
+ matchRects.reserveCapacity(matchRects.size() + m_findMatchesCache.size());
for (const FindMatch& match : m_findMatchesCache) {
DCHECK(!match.m_rect.isEmpty());
- frameRects.append(match.m_rect);
+ matchRects.append(match.m_rect);
}
+
+ outputRects = matchRects;
}
int TextFinder::selectNearestFindMatch(const WebFloatPoint& point, WebRect* selectionRect)
{
- TextFinder* bestFinder = nullptr;
- int indexInBestFrame = -1;
- float distanceInBestFrame = FLT_MAX;
-
- for (WebLocalFrameImpl* frame = &ownerFrame(); frame; frame = toWebLocalFrameImpl(frame->traverseNextLocal(false))) {
- float distanceInFrame;
- TextFinder& finder = frame->ensureTextFinder();
- int indexInFrame = finder.nearestFindMatch(point, distanceInFrame);
- if (distanceInFrame < distanceInBestFrame) {
- bestFinder = &finder;
- indexInBestFrame = indexInFrame;
- distanceInBestFrame = distanceInFrame;
- }
- }
-
- if (indexInBestFrame != -1)
- return bestFinder->selectFindMatch(static_cast<unsigned>(indexInBestFrame), selectionRect);
+ int index = nearestFindMatch(point, nullptr);
+ if (index != -1)
+ return selectFindMatch(static_cast<unsigned>(index), selectionRect);
return -1;
}
-int TextFinder::nearestFindMatch(const FloatPoint& point, float& distanceSquared)
+int TextFinder::nearestFindMatch(const FloatPoint& point, float* distanceSquared)
{
updateFindMatchRects();
int nearest = -1;
- distanceSquared = FLT_MAX;
+ float nearestDistanceSquared = FLT_MAX;
for (size_t i = 0; i < m_findMatchesCache.size(); ++i) {
DCHECK(!m_findMatchesCache[i].m_rect.isEmpty());
FloatSize offset = point - m_findMatchesCache[i].m_rect.center();
float width = offset.width();
float height = offset.height();
float currentDistanceSquared = width * width + height * height;
- if (currentDistanceSquared < distanceSquared) {
+ if (currentDistanceSquared < nearestDistanceSquared) {
nearest = i;
- distanceSquared = currentDistanceSquared;
+ nearestDistanceSquared = currentDistanceSquared;
}
}
+
+ if (distanceSquared)
+ *distanceSquared = nearestDistanceSquared;
+
return nearest;
}
@@ -611,18 +587,15 @@ int TextFinder::selectFindMatch(unsigned index, WebRect* selectionRect)
return -1;
// Check if the match is already selected.
- TextFinder& mainFrameTextFinder = ownerFrame().viewImpl()->mainFrameImpl()->ensureTextFinder();
- WebLocalFrameImpl* activeMatchFrame = mainFrameTextFinder.m_currentActiveMatchFrame;
- if (&ownerFrame() != activeMatchFrame || !m_activeMatch || !areRangesEqual(m_activeMatch.get(), range)) {
- if (isActiveMatchFrameValid())
- activeMatchFrame->ensureTextFinder().setMatchMarkerActive(false);
-
- m_activeMatchIndexInCurrentFrame = m_findMatchesCache[index].m_ordinal - 1;
+ if (!m_currentActiveMatchFrame || !m_activeMatch || !areRangesEqual(m_activeMatch.get(), range)) {
+ m_activeMatchIndex = m_findMatchesCache[index].m_ordinal - 1;
// Set this frame as the active frame (the one with the active highlight).
- mainFrameTextFinder.m_currentActiveMatchFrame = &ownerFrame();
+ m_currentActiveMatchFrame = true;
ownerFrame().viewImpl()->setFocusedFrame(&ownerFrame());
+ if (m_activeMatch)
+ setMarkerActive(m_activeMatch.get(), false);
m_activeMatch = range;
setMarkerActive(m_activeMatch.get(), true);
@@ -650,7 +623,7 @@ int TextFinder::selectFindMatch(unsigned index, WebRect* selectionRect)
if (selectionRect)
*selectionRect = activeMatchRect;
- return ordinalOfFirstMatch() + m_activeMatchIndexInCurrentFrame + 1;
+ return m_activeMatchIndex + 1;
}
TextFinder* TextFinder::create(WebLocalFrameImpl& ownerFrame)
@@ -660,12 +633,12 @@ TextFinder* TextFinder::create(WebLocalFrameImpl& ownerFrame)
TextFinder::TextFinder(WebLocalFrameImpl& ownerFrame)
: m_ownerFrame(&ownerFrame)
- , m_currentActiveMatchFrame(nullptr)
- , m_activeMatchIndexInCurrentFrame(-1)
+ , m_currentActiveMatchFrame(false)
+ , m_activeMatchIndex(-1)
, m_resumeScopingFromRange(nullptr)
, m_lastMatchCount(-1)
, m_totalMatchCount(-1)
- , m_framesScopingCount(-1)
+ , m_frameScoping(false)
, m_findRequestIdentifier(-1)
, m_nextInvalidateAfter(0)
, m_findMatchMarkersVersion(0)
@@ -695,33 +668,14 @@ bool TextFinder::setMarkerActive(Range* range, bool active)
void TextFinder::unmarkAllTextMatches()
{
LocalFrame* frame = ownerFrame().frame();
- if (frame && frame->page() && frame->editor().markedTextMatchesAreHighlighted()) {
- if (ownerFrame().client() && ownerFrame().client()->shouldSearchSingleFrame())
- frame->document()->markers().removeMarkers(DocumentMarker::TextMatch);
- else
- frame->page()->unmarkAllTextMatches();
- }
-}
-
-int TextFinder::ordinalOfFirstMatchForFrame(WebLocalFrameImpl* frame) const
-{
- int ordinal = 0;
- WebLocalFrameImpl* mainFrameImpl = ownerFrame().viewImpl()->mainFrameImpl();
- // Iterate from the main frame up to (but not including) |frame| and
- // add up the number of matches found so far.
- for (WebLocalFrameImpl* it = mainFrameImpl; it != frame; it = toWebLocalFrameImpl(it->traverseNextLocal(true))) {
- TextFinder& finder = it->ensureTextFinder();
- if (finder.m_lastMatchCount > 0)
- ordinal += finder.m_lastMatchCount;
- }
- return ordinal;
+ if (frame && frame->page() && frame->editor().markedTextMatchesAreHighlighted())
+ frame->document()->markers().removeMarkers(DocumentMarker::TextMatch);
}
bool TextFinder::shouldScopeMatches(const String& searchText)
{
// Don't scope if we can't find a frame or a view.
// The user may have closed the tab/application, so abort.
- // Also ignore detached frames, as many find operations report to the main frame.
LocalFrame* frame = ownerFrame().frame();
if (!frame || !frame->view() || !frame->page() || !ownerFrame().hasVisibleContent())
return false;
@@ -782,32 +736,9 @@ void TextFinder::flushCurrentScoping()
flushCurrentScopingEffort(m_findRequestIdentifier);
}
-void TextFinder::setMatchMarkerActive(bool active)
-{
- setMarkerActive(m_activeMatch.get(), active);
-}
-
-void TextFinder::decrementFramesScopingCount(int identifier)
-{
- // This frame has no further scoping left, so it is done. Other frames might,
- // of course, continue to scope matches.
- --m_framesScopingCount;
-
- // If this is the last frame to finish scoping we need to trigger the final
- // update to be sent.
- if (!m_framesScopingCount)
- ownerFrame().increaseMatchCount(0, identifier);
-}
-
-int TextFinder::ordinalOfFirstMatch() const
-{
- return ordinalOfFirstMatchForFrame(m_ownerFrame.get());
-}
-
DEFINE_TRACE(TextFinder)
{
visitor->trace(m_ownerFrame);
- visitor->trace(m_currentActiveMatchFrame);
visitor->trace(m_activeMatch);
visitor->trace(m_resumeScopingFromRange);
visitor->trace(m_deferredScopingWork);
« no previous file with comments | « third_party/WebKit/Source/web/TextFinder.h ('k') | third_party/WebKit/Source/web/WebLocalFrameImpl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698