Remove unused parameter.
[chromium-blink-merge.git] / extensions / browser / guest_view / web_view / web_view_find_helper.cc
blob8539b257b7baa16330ac1fe721c0878cfc33a311
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "extensions/browser/guest_view/web_view/web_view_find_helper.h"
7 #include <utility>
9 #include "extensions/browser/api/guest_view/web_view/web_view_internal_api.h"
10 #include "extensions/browser/guest_view/web_view/web_view_constants.h"
12 namespace extensions {
14 WebViewFindHelper::WebViewFindHelper(WebViewGuest* webview_guest)
15 : webview_guest_(webview_guest), current_find_request_id_(0) {
18 WebViewFindHelper::~WebViewFindHelper() {
21 void WebViewFindHelper::CancelAllFindSessions() {
22 current_find_session_ = linked_ptr<WebViewFindHelper::FindInfo>();
23 while (!find_info_map_.empty()) {
24 find_info_map_.begin()->second->SendResponse(true /* canceled */);
25 find_info_map_.erase(find_info_map_.begin());
27 if (find_update_event_.get())
28 DispatchFindUpdateEvent(true /* canceled */, true /* final_update */);
29 find_update_event_.reset();
32 void WebViewFindHelper::DispatchFindUpdateEvent(bool canceled,
33 bool final_update) {
34 DCHECK(find_update_event_.get());
35 scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
36 find_update_event_->PrepareResults(args.get());
37 args->SetBoolean(webview::kFindCanceled, canceled);
38 args->SetBoolean(webview::kFindFinalUpdate, final_update);
39 DCHECK(webview_guest_);
40 webview_guest_->DispatchEventToView(
41 new GuestViewBase::Event(webview::kEventFindReply, args.Pass()));
44 void WebViewFindHelper::EndFindSession(int session_request_id, bool canceled) {
45 FindInfoMap::iterator session_iterator =
46 find_info_map_.find(session_request_id);
47 DCHECK(session_iterator != find_info_map_.end());
48 FindInfo* find_info = session_iterator->second.get();
50 // Call the callback function of the first request of the find session.
51 find_info->SendResponse(canceled);
53 // For every subsequent find request of the find session.
54 for (std::vector<base::WeakPtr<WebViewFindHelper::FindInfo> >::iterator i =
55 find_info->find_next_requests_.begin();
56 i != find_info->find_next_requests_.end();
57 ++i) {
58 DCHECK(i->get());
60 // Do not call callbacks for subsequent find requests that have not been
61 // replied to yet. These requests will get their own final updates in the
62 // same order as they appear in |find_next_requests_|, i.e. the order that
63 // the requests were made in. Once one request is found that has not been
64 // replied to, none that follow will be replied to either, and do not need
65 // to be checked.
66 if (!(*i)->replied_)
67 break;
69 // Update the request's number of matches (if not canceled).
70 if (!canceled) {
71 (*i)->find_results_.number_of_matches_ =
72 find_info->find_results_.number_of_matches_;
75 // Call the request's callback function with the find results, and then
76 // delete its map entry to free the WebViewInternalFindFunction object.
77 (*i)->SendResponse(canceled);
78 find_info_map_.erase((*i)->request_id_);
81 // Erase the first find request's map entry to free the
82 // WebViewInternalFindFunction
83 // object.
84 find_info_map_.erase(session_request_id);
87 void WebViewFindHelper::Find(
88 content::WebContents* guest_web_contents,
89 const base::string16& search_text,
90 const blink::WebFindOptions& options,
91 scoped_refptr<WebViewInternalFindFunction> find_function) {
92 // Need a new request_id for each new find request.
93 ++current_find_request_id_;
95 // Stores the find request information by request_id so that its callback
96 // function can be called when the find results are available.
97 std::pair<FindInfoMap::iterator, bool> insert_result =
98 find_info_map_.insert(std::make_pair(
99 current_find_request_id_,
100 linked_ptr<
101 WebViewFindHelper::FindInfo>(new WebViewFindHelper::FindInfo(
102 current_find_request_id_, search_text, options, find_function))));
103 // No duplicate insertions.
104 DCHECK(insert_result.second);
106 // Find options including the implicit |findNext| field.
107 blink::WebFindOptions* full_options = insert_result.first->second->options();
109 // Set |findNext| implicitly.
110 if (current_find_session_.get()) {
111 const base::string16& current_search_text =
112 current_find_session_->search_text();
113 bool current_match_case = current_find_session_->options()->matchCase;
114 full_options->findNext = !current_search_text.empty() &&
115 current_search_text == search_text &&
116 current_match_case == options.matchCase;
117 } else {
118 full_options->findNext = false;
121 // Link find requests that are a part of the same find session.
122 if (full_options->findNext && current_find_session_.get()) {
123 DCHECK(current_find_request_id_ != current_find_session_->request_id());
124 current_find_session_->AddFindNextRequest(
125 insert_result.first->second->AsWeakPtr());
128 // Update the current find session, if necessary.
129 if (!full_options->findNext)
130 current_find_session_ = insert_result.first->second;
132 guest_web_contents->Find(current_find_request_id_,
133 search_text, *full_options);
136 void WebViewFindHelper::FindReply(int request_id,
137 int number_of_matches,
138 const gfx::Rect& selection_rect,
139 int active_match_ordinal,
140 bool final_update) {
141 FindInfoMap::iterator find_iterator = find_info_map_.find(request_id);
143 // Ignore slow replies to canceled find requests.
144 if (find_iterator == find_info_map_.end())
145 return;
147 // This find request must be a part of an existing find session.
148 DCHECK(current_find_session_.get());
150 WebViewFindHelper::FindInfo* find_info = find_iterator->second.get();
152 // Handle canceled find requests.
153 if (!find_info->options()->findNext &&
154 find_info_map_.begin()->first < request_id) {
155 DCHECK_NE(current_find_session_->request_id(),
156 find_info_map_.begin()->first);
157 DispatchFindUpdateEvent(true /* canceled */, true /* final_update */);
158 EndFindSession(find_info_map_.begin()->first, true /* canceled */);
161 // Clears the results for |findupdate| for a new find session.
162 if (!find_info->replied() && !find_info->options()->findNext)
163 find_update_event_.reset(new FindUpdateEvent(find_info->search_text()));
165 // Aggregate the find results.
166 find_info->AggregateResults(number_of_matches, selection_rect,
167 active_match_ordinal, final_update);
168 find_update_event_->AggregateResults(number_of_matches, selection_rect,
169 active_match_ordinal, final_update);
171 // Propagate incremental results to the |findupdate| event.
172 DispatchFindUpdateEvent(false /* canceled */, final_update);
174 // Call the callback functions of completed find requests.
175 if (final_update)
176 EndFindSession(request_id, false /* canceled */);
179 WebViewFindHelper::FindResults::FindResults()
180 : number_of_matches_(0), active_match_ordinal_(0) {
183 WebViewFindHelper::FindResults::~FindResults() {
186 void WebViewFindHelper::FindResults::AggregateResults(
187 int number_of_matches,
188 const gfx::Rect& selection_rect,
189 int active_match_ordinal,
190 bool final_update) {
191 if (number_of_matches != -1)
192 number_of_matches_ = number_of_matches;
194 if (active_match_ordinal != -1)
195 active_match_ordinal_ = active_match_ordinal;
197 if (final_update && active_match_ordinal_ == 0) {
198 // No match found, so the selection rectangle is empty.
199 selection_rect_ = gfx::Rect();
200 } else if (!selection_rect.IsEmpty()) {
201 selection_rect_ = selection_rect;
205 void WebViewFindHelper::FindResults::PrepareResults(
206 base::DictionaryValue* results) {
207 results->SetInteger(webview::kFindNumberOfMatches, number_of_matches_);
208 results->SetInteger(webview::kFindActiveMatchOrdinal, active_match_ordinal_);
209 base::DictionaryValue rect;
210 rect.SetInteger(webview::kFindRectLeft, selection_rect_.x());
211 rect.SetInteger(webview::kFindRectTop, selection_rect_.y());
212 rect.SetInteger(webview::kFindRectWidth, selection_rect_.width());
213 rect.SetInteger(webview::kFindRectHeight, selection_rect_.height());
214 results->Set(webview::kFindSelectionRect, rect.DeepCopy());
217 WebViewFindHelper::FindUpdateEvent::FindUpdateEvent(
218 const base::string16& search_text)
219 : search_text_(search_text) {
222 WebViewFindHelper::FindUpdateEvent::~FindUpdateEvent() {
225 void WebViewFindHelper::FindUpdateEvent::AggregateResults(
226 int number_of_matches,
227 const gfx::Rect& selection_rect,
228 int active_match_ordinal,
229 bool final_update) {
230 find_results_.AggregateResults(number_of_matches, selection_rect,
231 active_match_ordinal, final_update);
234 void WebViewFindHelper::FindUpdateEvent::PrepareResults(
235 base::DictionaryValue* results) {
236 results->SetString(webview::kFindSearchText, search_text_);
237 find_results_.PrepareResults(results);
240 WebViewFindHelper::FindInfo::FindInfo(
241 int request_id,
242 const base::string16& search_text,
243 const blink::WebFindOptions& options,
244 scoped_refptr<WebViewInternalFindFunction> find_function)
245 : request_id_(request_id),
246 search_text_(search_text),
247 options_(options),
248 find_function_(find_function),
249 replied_(false),
250 weak_ptr_factory_(this) {
253 WebViewFindHelper::FindInfo::~FindInfo() {
256 void WebViewFindHelper::FindInfo::AggregateResults(
257 int number_of_matches,
258 const gfx::Rect& selection_rect,
259 int active_match_ordinal,
260 bool final_update) {
261 replied_ = true;
262 find_results_.AggregateResults(number_of_matches, selection_rect,
263 active_match_ordinal, final_update);
266 base::WeakPtr<WebViewFindHelper::FindInfo>
267 WebViewFindHelper::FindInfo::AsWeakPtr() {
268 return weak_ptr_factory_.GetWeakPtr();
271 void WebViewFindHelper::FindInfo::SendResponse(bool canceled) {
272 // Prepare the find results to pass to the callback function.
273 base::DictionaryValue results;
274 find_results_.PrepareResults(&results);
275 results.SetBoolean(webview::kFindCanceled, canceled);
277 // Call the callback.
278 find_function_->SetResult(results.DeepCopy());
279 find_function_->SendResponse(true);
282 } // namespace extensions