1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// found in the LICENSE file.
4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/guest_view/web_view/web_view_find_helper.h"
6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <utility>
8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/api/web_view/web_view_internal_api.h"
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/guest_view/web_view/web_view_constants.h"
11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)namespace extensions {
136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
14116680a4aac90f2aa7413d9095a592090648e557Ben MurdochWebViewFindHelper::WebViewFindHelper(WebViewGuest* webview_guest)
15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    : webview_guest_(webview_guest), current_find_request_id_(0) {
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
18116680a4aac90f2aa7413d9095a592090648e557Ben MurdochWebViewFindHelper::~WebViewFindHelper() {
19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
21116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid WebViewFindHelper::CancelAllFindSessions() {
22116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  current_find_session_ = linked_ptr<WebViewFindHelper::FindInfo>();
23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  while (!find_info_map_.empty()) {
24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    find_info_map_.begin()->second->SendResponse(true /* canceled */);
25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    find_info_map_.erase(find_info_map_.begin());
26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (find_update_event_.get())
28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DispatchFindUpdateEvent(true /* canceled */, true /* final_update */);
29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  find_update_event_.reset();
30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
32116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid WebViewFindHelper::DispatchFindUpdateEvent(bool canceled,
33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                                bool final_update) {
34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(find_update_event_.get());
35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  find_update_event_->PrepareResults(args.get());
37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  args->SetBoolean(webview::kFindCanceled, canceled);
38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  args->SetBoolean(webview::kFindFinalUpdate, final_update);
39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(webview_guest_);
40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  webview_guest_->DispatchEventToEmbedder(
415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      new GuestViewBase::Event(webview::kEventFindReply, args.Pass()));
42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
44116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid WebViewFindHelper::EndFindSession(int session_request_id, bool canceled) {
45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  FindInfoMap::iterator session_iterator =
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      find_info_map_.find(session_request_id);
47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(session_iterator != find_info_map_.end());
48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  FindInfo* find_info = session_iterator->second.get();
49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Call the callback function of the first request of the find session.
51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  find_info->SendResponse(canceled);
52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // For every subsequent find request of the find session.
54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  for (std::vector<base::WeakPtr<WebViewFindHelper::FindInfo> >::iterator i =
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)           find_info->find_next_requests_.begin();
56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch       i != find_info->find_next_requests_.end();
57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch       ++i) {
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK(i->get());
59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Do not call callbacks for subsequent find requests that have not been
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // replied to yet. These requests will get their own final updates in the
62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // same order as they appear in |find_next_requests_|, i.e. the order that
63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // the requests were made in. Once one request is found that has not been
64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // replied to, none that follow will be replied to either, and do not need
65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // to be checked.
66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (!(*i)->replied_)
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      break;
68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Update the request's number of matches (if not canceled).
70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (!canceled) {
71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      (*i)->find_results_.number_of_matches_ =
72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          find_info->find_results_.number_of_matches_;
73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Call the request's callback function with the find results, and then
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // delete its map entry to free the WebViewInternalFindFunction object.
77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    (*i)->SendResponse(canceled);
78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    find_info_map_.erase((*i)->request_id_);
79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Erase the first find request's map entry to free the
82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // WebViewInternalFindFunction
83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // object.
84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  find_info_map_.erase(session_request_id);
85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
87116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid WebViewFindHelper::Find(
88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    content::WebContents* guest_web_contents,
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const base::string16& search_text,
90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const blink::WebFindOptions& options,
916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    scoped_refptr<WebViewInternalFindFunction> find_function) {
92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Need a new request_id for each new find request.
93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ++current_find_request_id_;
94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Stores the find request information by request_id so that its callback
96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // function can be called when the find results are available.
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::pair<FindInfoMap::iterator, bool> insert_result =
98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      find_info_map_.insert(std::make_pair(
99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          current_find_request_id_,
100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          linked_ptr<
101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch              WebViewFindHelper::FindInfo>(new WebViewFindHelper::FindInfo(
102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch              current_find_request_id_, search_text, options, find_function))));
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // No duplicate insertions.
104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(insert_result.second);
105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Find options including the implicit |findNext| field.
107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  blink::WebFindOptions* full_options = insert_result.first->second->options();
108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Set |findNext| implicitly.
110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (current_find_session_.get()) {
111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const base::string16& current_search_text =
112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        current_find_session_->search_text();
113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    bool current_match_case = current_find_session_->options()->matchCase;
114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    full_options->findNext = !current_search_text.empty() &&
115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        current_search_text == search_text &&
116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        current_match_case == options.matchCase;
117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  } else {
118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    full_options->findNext = false;
119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Link find requests that are a part of the same find session.
122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (full_options->findNext && current_find_session_.get()) {
123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK(current_find_request_id_ != current_find_session_->request_id());
124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    current_find_session_->AddFindNextRequest(
125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        insert_result.first->second->AsWeakPtr());
126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Update the current find session, if necessary.
129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!full_options->findNext)
130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    current_find_session_ = insert_result.first->second;
131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  guest_web_contents->Find(current_find_request_id_,
133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                           search_text, *full_options);
134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
136116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid WebViewFindHelper::FindReply(int request_id,
137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                  int number_of_matches,
138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                  const gfx::Rect& selection_rect,
139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                  int active_match_ordinal,
140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                  bool final_update) {
141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  FindInfoMap::iterator find_iterator = find_info_map_.find(request_id);
142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Ignore slow replies to canceled find requests.
144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (find_iterator == find_info_map_.end())
145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // This find request must be a part of an existing find session.
148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(current_find_session_.get());
149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
150116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  WebViewFindHelper::FindInfo* find_info = find_iterator->second.get();
151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Handle canceled find requests.
153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!find_info->options()->findNext &&
154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      find_info_map_.begin()->first < request_id) {
155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK_NE(current_find_session_->request_id(),
156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)              find_info_map_.begin()->first);
157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DispatchFindUpdateEvent(true /* canceled */, true /* final_update */);
158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EndFindSession(find_info_map_.begin()->first, true /* canceled */);
159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Clears the results for |findupdate| for a new find session.
162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!find_info->replied() && !find_info->options()->findNext)
163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    find_update_event_.reset(new FindUpdateEvent(find_info->search_text()));
164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Aggregate the find results.
166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  find_info->AggregateResults(number_of_matches, selection_rect,
167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                              active_match_ordinal, final_update);
168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  find_update_event_->AggregateResults(number_of_matches, selection_rect,
169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                      active_match_ordinal, final_update);
170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Propagate incremental results to the |findupdate| event.
172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DispatchFindUpdateEvent(false /* canceled */, final_update);
173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Call the callback functions of completed find requests.
175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (final_update)
176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EndFindSession(request_id, false /* canceled */);
177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
179116680a4aac90f2aa7413d9095a592090648e557Ben MurdochWebViewFindHelper::FindResults::FindResults()
180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    : number_of_matches_(0), active_match_ordinal_(0) {
181116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
183116680a4aac90f2aa7413d9095a592090648e557Ben MurdochWebViewFindHelper::FindResults::~FindResults() {
184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
185a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
186116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid WebViewFindHelper::FindResults::AggregateResults(
187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    int number_of_matches,
188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const gfx::Rect& selection_rect,
189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    int active_match_ordinal,
190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    bool final_update) {
191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (number_of_matches != -1)
192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    number_of_matches_ = number_of_matches;
193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (active_match_ordinal != -1)
195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    active_match_ordinal_ = active_match_ordinal;
196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (final_update && active_match_ordinal_ == 0) {
198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // No match found, so the selection rectangle is empty.
199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    selection_rect_ = gfx::Rect();
200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  } else if (!selection_rect.IsEmpty()) {
201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    selection_rect_ = selection_rect;
202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
203a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
205116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid WebViewFindHelper::FindResults::PrepareResults(
206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::DictionaryValue* results) {
207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  results->SetInteger(webview::kFindNumberOfMatches, number_of_matches_);
208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  results->SetInteger(webview::kFindActiveMatchOrdinal, active_match_ordinal_);
209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::DictionaryValue rect;
210a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  rect.SetInteger(webview::kFindRectLeft, selection_rect_.x());
211a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  rect.SetInteger(webview::kFindRectTop, selection_rect_.y());
212a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  rect.SetInteger(webview::kFindRectWidth, selection_rect_.width());
213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  rect.SetInteger(webview::kFindRectHeight, selection_rect_.height());
214a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  results->Set(webview::kFindSelectionRect, rect.DeepCopy());
215a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
216a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
217116680a4aac90f2aa7413d9095a592090648e557Ben MurdochWebViewFindHelper::FindUpdateEvent::FindUpdateEvent(
218116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const base::string16& search_text)
219116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    : search_text_(search_text) {
220a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
222116680a4aac90f2aa7413d9095a592090648e557Ben MurdochWebViewFindHelper::FindUpdateEvent::~FindUpdateEvent() {
223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
224a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
225116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid WebViewFindHelper::FindUpdateEvent::AggregateResults(
226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    int number_of_matches,
227a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const gfx::Rect& selection_rect,
228a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    int active_match_ordinal,
229a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    bool final_update) {
230a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  find_results_.AggregateResults(number_of_matches, selection_rect,
231a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                 active_match_ordinal, final_update);
232a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
233a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
234116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid WebViewFindHelper::FindUpdateEvent::PrepareResults(
235a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::DictionaryValue* results) {
236a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  results->SetString(webview::kFindSearchText, search_text_);
237a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  find_results_.PrepareResults(results);
238a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
240116680a4aac90f2aa7413d9095a592090648e557Ben MurdochWebViewFindHelper::FindInfo::FindInfo(
241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    int request_id,
242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const base::string16& search_text,
243a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const blink::WebFindOptions& options,
2446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    scoped_refptr<WebViewInternalFindFunction> find_function)
245a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : request_id_(request_id),
246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      search_text_(search_text),
247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      options_(options),
248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      find_function_(find_function),
249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      replied_(false),
250a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      weak_ptr_factory_(this) {
251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
253116680a4aac90f2aa7413d9095a592090648e557Ben MurdochWebViewFindHelper::FindInfo::~FindInfo() {
254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
255a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
256116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid WebViewFindHelper::FindInfo::AggregateResults(
257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    int number_of_matches,
258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const gfx::Rect& selection_rect,
259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    int active_match_ordinal,
260a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    bool final_update) {
261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  replied_ = true;
262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  find_results_.AggregateResults(number_of_matches, selection_rect,
263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                 active_match_ordinal, final_update);
264a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
266116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbase::WeakPtr<WebViewFindHelper::FindInfo>
267116680a4aac90f2aa7413d9095a592090648e557Ben MurdochWebViewFindHelper::FindInfo::AsWeakPtr() {
268a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return weak_ptr_factory_.GetWeakPtr();
269a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
270a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
271116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid WebViewFindHelper::FindInfo::SendResponse(bool canceled) {
272a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Prepare the find results to pass to the callback function.
273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::DictionaryValue results;
274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  find_results_.PrepareResults(&results);
275a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  results.SetBoolean(webview::kFindCanceled, canceled);
276a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
277a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Call the callback.
278a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  find_function_->SetResult(results.DeepCopy());
279a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  find_function_->SendResponse(true);
280a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
2816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}  // namespace extensions
283