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

Unified Diff: content/renderer/render_frame_impl.cc

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 | « content/renderer/render_frame_impl.h ('k') | content/test/data/find_in_hidden_frame.html » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/renderer/render_frame_impl.cc
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index e01306b0e421bdcee5d147f4d81dbb7d464c3fd0..5904543ef2c7cea1eb2c12b134b9b405fe448d80 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -301,6 +301,10 @@ using blink::WebFloatPoint;
using blink::WebFloatRect;
#endif
+#define STATIC_ASSERT_ENUM(a, b) \
+ static_assert(static_cast<int>(a) == static_cast<int>(b), \
+ "mismatching enums: " #a)
+
namespace content {
namespace {
@@ -1496,13 +1500,16 @@ bool RenderFrameImpl::OnMessageReceived(const IPC::Message& msg) {
OnGetSerializedHtmlWithLocalLinks)
IPC_MESSAGE_HANDLER(FrameMsg_SerializeAsMHTML, OnSerializeAsMHTML)
IPC_MESSAGE_HANDLER(FrameMsg_Find, OnFind)
+ IPC_MESSAGE_HANDLER(FrameMsg_ClearActiveFindMatch, OnClearActiveFindMatch)
IPC_MESSAGE_HANDLER(FrameMsg_StopFinding, OnStopFinding)
IPC_MESSAGE_HANDLER(FrameMsg_EnableViewSourceMode, OnEnableViewSourceMode)
IPC_MESSAGE_HANDLER(FrameMsg_SuppressFurtherDialogs,
OnSuppressFurtherDialogs)
#if defined(OS_ANDROID)
- IPC_MESSAGE_HANDLER(InputMsg_ActivateNearestFindResult,
+ IPC_MESSAGE_HANDLER(FrameMsg_ActivateNearestFindResult,
OnActivateNearestFindResult)
+ IPC_MESSAGE_HANDLER(FrameMsg_GetNearestFindResult,
+ OnGetNearestFindResult)
IPC_MESSAGE_HANDLER(FrameMsg_FindMatchRects, OnFindMatchRects)
IPC_MESSAGE_HANDLER(FrameMsg_SelectPopupMenuItems, OnSelectPopupMenuItems)
#elif defined(OS_MACOSX)
@@ -4099,20 +4106,19 @@ void RenderFrameImpl::willInsertBody(blink::WebLocalFrame* frame) {
void RenderFrameImpl::reportFindInPageMatchCount(int request_id,
int count,
bool final_update) {
- int active_match_ordinal = -1; // -1 = don't update active match ordinal
- if (!count)
- active_match_ordinal = 0;
+ // -1 here means don't update the active match ordinal.
+ int active_match_ordinal = count ? -1 : 0;
- Send(new FrameHostMsg_Find_Reply(routing_id_, request_id, count, gfx::Rect(),
- active_match_ordinal, final_update));
+ SendFindReply(request_id, count, active_match_ordinal, gfx::Rect(),
+ final_update);
}
void RenderFrameImpl::reportFindInPageSelection(
int request_id,
int active_match_ordinal,
const blink::WebRect& selection_rect) {
- Send(new FrameHostMsg_Find_Reply(routing_id_, request_id, -1, selection_rect,
- active_match_ordinal, false));
+ SendFindReply(request_id, -1 /* match_count */, active_match_ordinal,
+ selection_rect, false /* final_status_update */);
}
void RenderFrameImpl::requestStorageQuota(
@@ -5018,13 +5024,6 @@ void RenderFrameImpl::OnSerializeAsMHTML(
void RenderFrameImpl::OnFind(int request_id,
const base::string16& search_text,
const WebFindOptions& options) {
- // This should only be received on the main frame, since find-in-page is
- // currently orchestrated by the main frame.
- if (!is_main_frame_) {
- NOTREACHED();
- return;
- }
-
DCHECK(!search_text.empty());
blink::WebPlugin* plugin = GetWebPluginForFind();
@@ -5036,152 +5035,78 @@ void RenderFrameImpl::OnFind(int request_id,
} else {
if (!plugin->startFind(search_text, options.matchCase, request_id)) {
// Send "no results".
- SendFindReply(request_id, 0, 0, gfx::Rect(), true);
+ SendFindReply(request_id, 0 /* match_count */, 0 /* ordinal */,
+ gfx::Rect(), true /* final_status_update */ );
}
}
return;
}
- WebLocalFrame* main_frame = GetWebFrame();
- WebLocalFrame* focused_frame =
- render_view_->webview()->focusedFrame()->toWebLocalFrame();
- // Start searching in the focused frame.
- WebLocalFrame* search_frame = focused_frame;
-
- // Check for multiple searchable frames.
- bool multi_frame = (main_frame->traverseNextLocal(true) != main_frame);
-
- // If we have multiple frames, we don't want to wrap the search within the
- // frame, so we check here if we only have |main_frame| in the chain.
- bool wrap_within_frame = !multi_frame;
+ // Send "no results" if this frame has no visible content.
+ if (!frame_->hasVisibleContent()) {
+ SendFindReply(request_id, 0 /* match_count */, 0 /* ordinal */,
+ gfx::Rect(), true /* final_status_update */ );
+ return;
+ }
WebRect selection_rect;
- bool result = false;
bool active_now = false;
// If something is selected when we start searching it means we cannot just
// increment the current match ordinal; we need to re-generate it.
- WebRange current_selection = focused_frame->selectionRange();
-
- do {
- result =
- search_frame->find(request_id, search_text, options, wrap_within_frame,
- &selection_rect, &active_now);
-
- if (!result) {
- // Don't leave text selected as you move to the next frame.
- search_frame->executeCommand(WebString::fromUTF8("Unselect"));
-
- // Find the next frame, but skip the invisible ones.
- do {
- // What is the next frame to search (we might be going backwards)? Note
- // that we specify wrap=true so that search_frame never becomes NULL.
- search_frame = options.forward
- ? search_frame->traverseNextLocal(true)
- : search_frame->traversePreviousLocal(true);
- } while (!search_frame->hasVisibleContent() &&
- search_frame != focused_frame);
-
- // Make sure selection doesn't affect the search operation in new frame.
- search_frame->executeCommand(WebString::fromUTF8("Unselect"));
-
- // If we have multiple frames and we have wrapped back around to the
- // focused frame, we need to search it once more allowing wrap within
- // the frame, otherwise it will report 'no match' if the focused frame has
- // reported matches, but no frames after the focused_frame contain a
- // match for the search word(s).
- if (multi_frame && search_frame == focused_frame) {
- result = search_frame->find(request_id, search_text, options,
- true, // Force wrapping.
- &selection_rect, &active_now);
- }
- }
+ WebRange current_selection = frame_->selectionRange();
- render_view_->webview()->setFocusedFrame(search_frame);
- } while (!result && search_frame != focused_frame);
+ if (frame_->find(request_id, search_text, options,
+ false /* wrapWithinFrame */, &selection_rect, &active_now)) {
+ // Indicate that at least one match has been found. 1 here means possibly
+ // more matches could be coming. -1 here means that the exact active match
+ // ordinal is not yet known.
+ SendFindReply(request_id, 1 /* match_count */, -1 /* ordinal */,
+ gfx::Rect(), false /* final_status_update */ );
+ }
if (options.findNext && current_selection.isNull() && active_now) {
- // Force the main_frame to report the actual count.
- main_frame->increaseMatchCount(0, request_id);
- } else {
- // If nothing is found, set result to "0 of 0", otherwise, set it to
- // "-1 of 1" to indicate that we found at least one item, but we don't know
- // yet what is active.
- int ordinal = result ? -1 : 0; // -1 here means we might know more later.
- int match_count = result ? 1 : 0; // 1 here means possibly more coming.
-
- // If we find no matches then this will be our last status update.
- // Otherwise the scoping effort will send more results.
- bool final_status_update = !result;
-
- SendFindReply(request_id, match_count, ordinal, selection_rect,
- final_status_update);
-
- // Scoping effort begins, starting with the main frame.
- search_frame = main_frame;
-
- main_frame->resetMatchCount();
-
- do {
- // Cancel all old scoping requests before starting a new one.
- search_frame->cancelPendingScopingEffort();
-
- // We don't start another scoping effort unless at least one match has
- // been found.
- if (result) {
- // Start new scoping request. If the scoping function determines that it
- // needs to scope, it will defer until later.
- search_frame->scopeStringMatches(request_id, search_text, options,
- true); // reset the tickmarks
- }
-
- // Iterate to the next frame. The frame will not necessarily scope, for
- // example if it is not visible.
- search_frame = search_frame->traverseNextLocal(true);
- } while (search_frame != main_frame);
+ // Force report of the actual count.
+ frame_->increaseMatchCount(0, request_id);
+ return;
}
+
+ // Scoping effort begins.
+ frame_->resetMatchCount();
+
+ // Cancel all old scoping requests before starting a new one.
+ frame_->cancelPendingScopingEffort();
+
+ // Start new scoping request. If the scoping function determines that it
+ // needs to scope, it will defer until later.
+ frame_->scopeStringMatches(request_id,
+ search_text,
+ options,
+ true); // reset the tickmarks
}
-void RenderFrameImpl::OnStopFinding(StopFindAction action) {
- // This should only be received on the main frame, since find-in-page is
- // currently orchestrated by the main frame.
- if (!is_main_frame_) {
- NOTREACHED();
- return;
- }
+void RenderFrameImpl::OnClearActiveFindMatch() {
+ frame_->executeCommand(WebString::fromUTF8("Unselect"));
+ frame_->clearActiveFindMatch();
+}
- WebView* view = render_view_->webview();
- if (!view)
- return;
+// Ensure that content::StopFindAction and blink::WebLocalFrame::StopFindAction
+// are kept in sync.
+STATIC_ASSERT_ENUM(STOP_FIND_ACTION_CLEAR_SELECTION,
+ WebLocalFrame::StopFindActionClearSelection);
+STATIC_ASSERT_ENUM(STOP_FIND_ACTION_KEEP_SELECTION,
+ WebLocalFrame::StopFindActionKeepSelection);
+STATIC_ASSERT_ENUM(STOP_FIND_ACTION_ACTIVATE_SELECTION,
+ WebLocalFrame::StopFindActionActivateSelection);
+void RenderFrameImpl::OnStopFinding(StopFindAction action) {
blink::WebPlugin* plugin = GetWebPluginForFind();
if (plugin) {
plugin->stopFind();
return;
}
- bool clear_selection = action == STOP_FIND_ACTION_CLEAR_SELECTION;
- if (clear_selection) {
- view->focusedFrame()->executeCommand(WebString::fromUTF8("Unselect"));
- }
-
- WebLocalFrame* frame = GetWebFrame();
- while (frame) {
- frame->stopFinding(clear_selection);
- frame = frame->traverseNextLocal(false);
- }
-
- if (action == STOP_FIND_ACTION_ACTIVATE_SELECTION) {
- WebFrame* focused_frame = view->focusedFrame();
- if (focused_frame) {
- WebDocument doc = focused_frame->document();
- if (!doc.isNull()) {
- WebElement element = doc.focusedElement();
- if (!element.isNull())
- element.simulateClick();
- }
- }
- }
+ frame_->stopFinding(static_cast<WebLocalFrame::StopFindAction>(action));
}
void RenderFrameImpl::OnEnableViewSourceMode() {
@@ -5213,6 +5138,14 @@ void RenderFrameImpl::OnActivateNearestFindResult(int request_id,
true /* final_update */);
}
+void RenderFrameImpl::OnGetNearestFindResult(int nfr_request_id,
+ float x,
+ float y) {
+ float distance = frame_->distanceToNearestFindMatch(WebFloatPoint(x, y));
+ Send(new FrameHostMsg_GetNearestFindResult_Reply(
+ routing_id_, nfr_request_id, distance));
+}
+
void RenderFrameImpl::OnFindMatchRects(int current_version) {
std::vector<gfx::RectF> match_rects;
@@ -6078,9 +6011,6 @@ blink::ServiceRegistry* RenderFrameImpl::serviceRegistry() {
}
blink::WebPlugin* RenderFrameImpl::GetWebPluginForFind() {
- if (!is_main_frame_)
- return nullptr;
-
if (frame_->document().isPluginDocument())
return frame_->document().to<WebPluginDocument>().plugin();
@@ -6097,8 +6027,15 @@ void RenderFrameImpl::SendFindReply(int request_id,
int ordinal,
const WebRect& selection_rect,
bool final_status_update) {
- Send(new FrameHostMsg_Find_Reply(routing_id_, request_id, match_count,
- selection_rect, ordinal,
+ if (final_status_update && !ordinal)
+ frame_->executeCommand(WebString::fromUTF8("Unselect"));
+ DCHECK(ordinal >= -1);
+
+ Send(new FrameHostMsg_Find_Reply(routing_id_,
+ request_id,
+ match_count,
+ selection_rect,
+ ordinal,
final_status_update));
}
« no previous file with comments | « content/renderer/render_frame_impl.h ('k') | content/test/data/find_in_hidden_frame.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698