| 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));
|
| }
|
|
|
|
|