| Index: chrome/browser/android/contextualsearch/contextual_search_delegate.cc
|
| diff --git a/chrome/browser/android/contextualsearch/contextual_search_delegate.cc b/chrome/browser/android/contextualsearch/contextual_search_delegate.cc
|
| index dd465e4f837b68e083f669c8fbfafbad32eee19c..99902c52dabe7ac5814d3b84b9ff2fbfe18816bf 100644
|
| --- a/chrome/browser/android/contextualsearch/contextual_search_delegate.cc
|
| +++ b/chrome/browser/android/contextualsearch/contextual_search_delegate.cc
|
| @@ -41,6 +41,7 @@ const char kContextualSearchResponseSelectedTextParam[] = "selected_text";
|
| const char kContextualSearchResponseSearchTermParam[] = "search_term";
|
| const char kContextualSearchResponseResolvedTermParam[] = "resolved_term";
|
| const char kContextualSearchPreventPreload[] = "prevent_preload";
|
| +const char kContextualSearchMentions[] = "mentions";
|
| const char kContextualSearchServerEndpoint[] = "_/contextualsearch?";
|
| const int kContextualSearchRequestVersion = 2;
|
| const char kContextualSearchResolverUrl[] =
|
| @@ -49,6 +50,7 @@ const char kContextualSearchResolverUrl[] =
|
| // room for other parameters.
|
| const int kContextualSearchDefaultContentSize = 1536;
|
| const int kContextualSearchDefaultIcingSurroundingSize = 400;
|
| +const int kContextualSearchMaxSelection = 100;
|
| // The maximum length of a URL to build.
|
| const int kMaxURLSize = 2048;
|
| const char kXssiEscape[] = ")]}'\n";
|
| @@ -142,6 +144,10 @@ void ContextualSearchDelegate::OnURLFetchComplete(
|
| std::string display_text;
|
| std::string alternate_term;
|
| std::string prevent_preload;
|
| + int mention_start = 0;
|
| + int mention_end = 0;
|
| + int start_adjust = 0;
|
| + int end_adjust = 0;
|
|
|
| if (source->GetStatus().is_success() && response_code == 200) {
|
| std::string response;
|
| @@ -149,13 +155,30 @@ void ContextualSearchDelegate::OnURLFetchComplete(
|
| DCHECK(has_string_response);
|
| if (has_string_response) {
|
| DecodeSearchTermsFromJsonResponse(response, &search_term, &display_text,
|
| - &alternate_term, &prevent_preload);
|
| + &alternate_term, &prevent_preload,
|
| + &mention_start, &mention_end);
|
| + if (mention_start != 0 || mention_end != 0) {
|
| + // Sanity check that our selection is non-zero and it is less than
|
| + // 100 characters as that would make contextual search bar hide.
|
| + // We also check that there is at least one character overlap between
|
| + // the new and old selection.
|
| + if (mention_start >= mention_end
|
| + || (mention_end - mention_start) > kContextualSearchMaxSelection
|
| + || mention_end <= context_->start_offset
|
| + || mention_start >= context_->end_offset) {
|
| + start_adjust = 0;
|
| + end_adjust = 0;
|
| + } else {
|
| + start_adjust = mention_start - context_->start_offset;
|
| + end_adjust = mention_end - context_->end_offset;
|
| + }
|
| + }
|
| }
|
| }
|
| bool is_invalid = response_code == net::URLFetcher::RESPONSE_CODE_INVALID;
|
| search_term_callback_.Run(
|
| is_invalid, response_code, search_term, display_text, alternate_term,
|
| - prevent_preload == kDoPreventPreloadValue);
|
| + prevent_preload == kDoPreventPreloadValue, start_adjust, end_adjust);
|
|
|
| // The ContextualSearchContext is consumed once the request has completed.
|
| context_.reset();
|
| @@ -399,7 +422,9 @@ void ContextualSearchDelegate::DecodeSearchTermsFromJsonResponse(
|
| std::string* search_term,
|
| std::string* display_text,
|
| std::string* alternate_term,
|
| - std::string* prevent_preload) {
|
| + std::string* prevent_preload,
|
| + int* mention_start,
|
| + int* mention_end) {
|
| bool contains_xssi_escape = response.find(kXssiEscape) == 0;
|
| const std::string& proper_json =
|
| contains_xssi_escape ? response.substr(strlen(kXssiEscape)) : response;
|
| @@ -416,6 +441,11 @@ void ContextualSearchDelegate::DecodeSearchTermsFromJsonResponse(
|
| display_text)) {
|
| *display_text = *search_term;
|
| }
|
| + // Extract mentions for selection expansion.
|
| + base::ListValue* mentions_list;
|
| + dict->GetList(kContextualSearchMentions, &mentions_list);
|
| + if (mentions_list != NULL && mentions_list->GetSize() >= 2)
|
| + ExtractMentionsStartEnd(*mentions_list, mention_start, mention_end);
|
| // If either the selected text or the resolved term is not the search term,
|
| // use it as the alternate term.
|
| std::string selected_text;
|
| @@ -445,6 +475,19 @@ int ContextualSearchDelegate::GetSearchTermSurroundingSize() {
|
| return kContextualSearchDefaultContentSize;
|
| }
|
|
|
| +// Extract the Start/End of the mentions in the surrounding text
|
| +// for selection-expansion.
|
| +void ContextualSearchDelegate::ExtractMentionsStartEnd(
|
| + const base::ListValue& mentions_list,
|
| + int* startResult,
|
| + int* endResult) {
|
| + int int_value;
|
| + if (mentions_list.GetInteger(0, &int_value))
|
| + *startResult = std::max(0, int_value);
|
| + if (mentions_list.GetInteger(1, &int_value))
|
| + *endResult = std::max(0, int_value);
|
| +}
|
| +
|
| // Returns the size of the surroundings to be sent to Icing.
|
| int ContextualSearchDelegate::GetIcingSurroundingSize() {
|
| std::string param_string = variations::GetVariationParamValue(
|
|
|