This source file includes following definitions.
- current_find_request_id_
- CancelAllFindSessions
- DispatchFindUpdateEvent
- EndFindSession
- FindReply
- active_match_ordinal_
- AggregateResults
- PrepareResults
- AggregateResults
- PrepareResults
- weak_ptr_factory_
- AggregateResults
- AsWeakPtr
- SendResponse
#include "chrome/browser/guestview/webview/webview_find_helper.h"
#include <utility>
#include "chrome/browser/extensions/api/webview/webview_api.h"
#include "chrome/browser/guestview/webview/webview_constants.h"
WebviewFindHelper::WebviewFindHelper(WebViewGuest* webview_guest)
: webview_guest_(webview_guest),
current_find_request_id_(0) {
}
WebviewFindHelper::~WebviewFindHelper() {
}
void WebviewFindHelper::CancelAllFindSessions() {
current_find_session_ = linked_ptr<WebviewFindHelper::FindInfo>();
while (!find_info_map_.empty()) {
find_info_map_.begin()->second->SendResponse(true );
find_info_map_.erase(find_info_map_.begin());
}
if (find_update_event_.get())
DispatchFindUpdateEvent(true , true );
find_update_event_.reset();
}
void WebviewFindHelper::DispatchFindUpdateEvent(bool canceled,
bool final_update) {
DCHECK(find_update_event_.get());
scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
find_update_event_->PrepareResults(args.get());
args->SetBoolean(webview::kFindCanceled, canceled);
args->SetBoolean(webview::kFindFinalUpdate, final_update);
DCHECK(webview_guest_);
webview_guest_->DispatchEvent(new GuestView::Event(webview::kEventFindReply,
args.Pass()));
}
void WebviewFindHelper::EndFindSession(int session_request_id, bool canceled) {
FindInfoMap::iterator session_iterator =
find_info_map_.find(session_request_id);
DCHECK(session_iterator != find_info_map_.end());
FindInfo* find_info = session_iterator->second.get();
find_info->SendResponse(canceled);
for (std::vector<base::WeakPtr<WebviewFindHelper::FindInfo> >::iterator i =
find_info->find_next_requests_.begin();
i != find_info->find_next_requests_.end(); ++i) {
DCHECK(i->get());
if (!(*i)->replied_)
break;
if (!canceled) {
(*i)->find_results_.number_of_matches_ =
find_info->find_results_.number_of_matches_;
}
(*i)->SendResponse(canceled);
find_info_map_.erase((*i)->request_id_);
}
find_info_map_.erase(session_request_id);
}
void WebviewFindHelper::Find(
content::WebContents* guest_web_contents,
const base::string16& search_text,
const blink::WebFindOptions& options,
scoped_refptr<extensions::WebviewFindFunction> find_function) {
++current_find_request_id_;
std::pair<FindInfoMap::iterator, bool> insert_result =
find_info_map_.insert(
std::make_pair(current_find_request_id_,
linked_ptr<WebviewFindHelper::FindInfo>(
new WebviewFindHelper::FindInfo(
current_find_request_id_,
search_text,
options,
find_function))));
DCHECK(insert_result.second);
blink::WebFindOptions* full_options = insert_result.first->second->options();
if (current_find_session_.get()) {
const base::string16& current_search_text =
current_find_session_->search_text();
bool current_match_case = current_find_session_->options()->matchCase;
full_options->findNext = !current_search_text.empty() &&
current_search_text == search_text &&
current_match_case == options.matchCase;
} else {
full_options->findNext = false;
}
if (full_options->findNext && current_find_session_.get()) {
DCHECK(current_find_request_id_ != current_find_session_->request_id());
current_find_session_->AddFindNextRequest(
insert_result.first->second->AsWeakPtr());
}
if (!full_options->findNext)
current_find_session_ = insert_result.first->second;
guest_web_contents->Find(current_find_request_id_,
search_text, *full_options);
}
void WebviewFindHelper::FindReply(int request_id,
int number_of_matches,
const gfx::Rect& selection_rect,
int active_match_ordinal,
bool final_update) {
FindInfoMap::iterator find_iterator = find_info_map_.find(request_id);
if (find_iterator == find_info_map_.end())
return;
DCHECK(current_find_session_.get());
WebviewFindHelper::FindInfo* find_info = find_iterator->second.get();
if (!find_info->options()->findNext &&
find_info_map_.begin()->first < request_id) {
DCHECK_NE(current_find_session_->request_id(),
find_info_map_.begin()->first);
DispatchFindUpdateEvent(true , true );
EndFindSession(find_info_map_.begin()->first, true );
}
if (!find_info->replied() && !find_info->options()->findNext)
find_update_event_.reset(new FindUpdateEvent(find_info->search_text()));
find_info->AggregateResults(number_of_matches, selection_rect,
active_match_ordinal, final_update);
find_update_event_->AggregateResults(number_of_matches, selection_rect,
active_match_ordinal, final_update);
DispatchFindUpdateEvent(false , final_update);
if (final_update)
EndFindSession(request_id, false );
}
WebviewFindHelper::FindResults::FindResults()
: number_of_matches_(0),
active_match_ordinal_(0) {}
WebviewFindHelper::FindResults::~FindResults() {
}
void WebviewFindHelper::FindResults::AggregateResults(
int number_of_matches,
const gfx::Rect& selection_rect,
int active_match_ordinal,
bool final_update) {
if (number_of_matches != -1)
number_of_matches_ = number_of_matches;
if (active_match_ordinal != -1)
active_match_ordinal_ = active_match_ordinal;
if (final_update && active_match_ordinal_ == 0) {
selection_rect_ = gfx::Rect();
} else if (!selection_rect.IsEmpty()) {
selection_rect_ = selection_rect;
}
}
void WebviewFindHelper::FindResults::PrepareResults(
base::DictionaryValue* results) {
results->SetInteger(webview::kFindNumberOfMatches, number_of_matches_);
results->SetInteger(webview::kFindActiveMatchOrdinal, active_match_ordinal_);
base::DictionaryValue rect;
rect.SetInteger(webview::kFindRectLeft, selection_rect_.x());
rect.SetInteger(webview::kFindRectTop, selection_rect_.y());
rect.SetInteger(webview::kFindRectWidth, selection_rect_.width());
rect.SetInteger(webview::kFindRectHeight, selection_rect_.height());
results->Set(webview::kFindSelectionRect, rect.DeepCopy());
}
WebviewFindHelper::FindUpdateEvent::FindUpdateEvent(
const base::string16& search_text) : search_text_(search_text) {
}
WebviewFindHelper::FindUpdateEvent::~FindUpdateEvent() {
}
void WebviewFindHelper::FindUpdateEvent::AggregateResults(
int number_of_matches,
const gfx::Rect& selection_rect,
int active_match_ordinal,
bool final_update) {
find_results_.AggregateResults(number_of_matches, selection_rect,
active_match_ordinal, final_update);
}
void WebviewFindHelper::FindUpdateEvent::PrepareResults(
base::DictionaryValue* results) {
results->SetString(webview::kFindSearchText, search_text_);
find_results_.PrepareResults(results);
}
WebviewFindHelper::FindInfo::FindInfo(
int request_id,
const base::string16& search_text,
const blink::WebFindOptions& options,
scoped_refptr<extensions::WebviewFindFunction> find_function)
: request_id_(request_id),
search_text_(search_text),
options_(options),
find_function_(find_function),
replied_(false),
weak_ptr_factory_(this) {
}
WebviewFindHelper::FindInfo::~FindInfo() {
}
void WebviewFindHelper::FindInfo::AggregateResults(
int number_of_matches,
const gfx::Rect& selection_rect,
int active_match_ordinal,
bool final_update) {
replied_ = true;
find_results_.AggregateResults(number_of_matches, selection_rect,
active_match_ordinal, final_update);
}
base::WeakPtr<WebviewFindHelper::FindInfo>
WebviewFindHelper::FindInfo::AsWeakPtr() {
return weak_ptr_factory_.GetWeakPtr();
}
void WebviewFindHelper::FindInfo::SendResponse(bool canceled) {
base::DictionaryValue results;
find_results_.PrepareResults(&results);
results.SetBoolean(webview::kFindCanceled, canceled);
find_function_->SetResult(results.DeepCopy());
find_function_->SendResponse(true);
}