diff options
author | dcblack@chromium.org <dcblack@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-20 00:53:56 +0000 |
---|---|---|
committer | dcblack@chromium.org <dcblack@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-20 00:53:56 +0000 |
commit | 5e63aededfd66dd694e68619051153439f0016b1 (patch) | |
tree | 0fdf857dfbb557acb9d888ee6fdf67a6c1d266ba | |
parent | ae3dfe9c43613d5257c818316e8a0cca35118afa (diff) | |
download | chromium_src-5e63aededfd66dd694e68619051153439f0016b1.zip chromium_src-5e63aededfd66dd694e68619051153439f0016b1.tar.gz chromium_src-5e63aededfd66dd694e68619051153439f0016b1.tar.bz2 |
Add support for the NavigateContentWindow function to the extended Instant API and reduce the number of autocomplete providers that trigger when extended Instant is enabled.
BUG=150045
Review URL: https://chromiumcodereview.appspot.com/10918288
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@157677 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/autocomplete/autocomplete_classifier.cc | 10 | ||||
-rw-r--r-- | chrome/browser/autocomplete/autocomplete_classifier.h | 5 | ||||
-rw-r--r-- | chrome/browser/ui/omnibox/omnibox_edit_model.cc | 12 | ||||
-rw-r--r-- | chrome/renderer/resources/extensions/searchbox_api.js | 4 | ||||
-rw-r--r-- | chrome/renderer/searchbox/searchbox.cc | 18 | ||||
-rw-r--r-- | chrome/renderer/searchbox/searchbox.h | 12 | ||||
-rw-r--r-- | chrome/renderer/searchbox/searchbox_extension.cc | 80 |
7 files changed, 105 insertions, 36 deletions
diff --git a/chrome/browser/autocomplete/autocomplete_classifier.cc b/chrome/browser/autocomplete/autocomplete_classifier.cc index 28f870e..110d4ad 100644 --- a/chrome/browser/autocomplete/autocomplete_classifier.cc +++ b/chrome/browser/autocomplete/autocomplete_classifier.cc @@ -23,6 +23,16 @@ const int AutocompleteClassifier::kDefaultOmniboxProviders = AutocompleteProvider::TYPE_SHORTCUTS | AutocompleteProvider::TYPE_ZERO_SUGGEST; +// static +const int AutocompleteClassifier::kInstantExtendedOmniboxProviders = + AutocompleteProvider::TYPE_BUILTIN | + AutocompleteProvider::TYPE_HISTORY_QUICK | + AutocompleteProvider::TYPE_HISTORY_URL | + // TODO: remove TYPE_SEARCH once it's no longer needed to pass + // the Instant suggestion through via FinalizeInstantQuery. + AutocompleteProvider::TYPE_SEARCH | + AutocompleteProvider::TYPE_ZERO_SUGGEST; + AutocompleteClassifier::AutocompleteClassifier(Profile* profile) : controller_(new AutocompleteController(profile, NULL, kDefaultOmniboxProviders)), diff --git a/chrome/browser/autocomplete/autocomplete_classifier.h b/chrome/browser/autocomplete/autocomplete_classifier.h index 17e6474..cf37b3c 100644 --- a/chrome/browser/autocomplete/autocomplete_classifier.h +++ b/chrome/browser/autocomplete/autocomplete_classifier.h @@ -23,6 +23,11 @@ class AutocompleteClassifier : public ProfileKeyedService { // AutocompleteController(). static const int kDefaultOmniboxProviders; + // Bitmap of AutocompleteProvider::Type values describing the set of providers + // that have been whitelisted as working properly with the Instant Extended + // API. Intended to be passed to AutocompleteController(). + static const int kInstantExtendedOmniboxProviders; + explicit AutocompleteClassifier(Profile* profile); virtual ~AutocompleteClassifier(); diff --git a/chrome/browser/ui/omnibox/omnibox_edit_model.cc b/chrome/browser/ui/omnibox/omnibox_edit_model.cc index bdfe05b..8232aae 100644 --- a/chrome/browser/ui/omnibox/omnibox_edit_model.cc +++ b/chrome/browser/ui/omnibox/omnibox_edit_model.cc @@ -44,6 +44,7 @@ #include "chrome/browser/ui/omnibox/omnibox_popup_model.h" #include "chrome/browser/ui/omnibox/omnibox_popup_view.h" #include "chrome/browser/ui/omnibox/omnibox_view.h" +#include "chrome/browser/ui/search/search.h" #include "chrome/browser/ui/search/search_tab_helper.h" #include "chrome/browser/ui/tab_contents/tab_contents.h" #include "chrome/common/chrome_notification_types.h" @@ -84,10 +85,7 @@ OmniboxEditModel::State::~State() { OmniboxEditModel::OmniboxEditModel(OmniboxView* view, OmniboxEditController* controller, Profile* profile) - : ALLOW_THIS_IN_INITIALIZER_LIST( - autocomplete_controller_(new AutocompleteController(profile, this, - AutocompleteClassifier::kDefaultOmniboxProviders))), - view_(view), + : view_(view), popup_(NULL), controller_(controller), has_focus_(false), @@ -101,6 +99,12 @@ OmniboxEditModel::OmniboxEditModel(OmniboxView* view, profile_(profile), in_revert_(false), allow_exact_keyword_match_(false) { + // Use a restricted subset of the autocomplete providers if we're using the + // Instant Extended API, as it doesn't support them all. + autocomplete_controller_.reset(new AutocompleteController(profile, this, + chrome::search::IsInstantExtendedAPIEnabled(profile) ? + AutocompleteClassifier::kInstantExtendedOmniboxProviders : + AutocompleteClassifier::kDefaultOmniboxProviders)); } OmniboxEditModel::~OmniboxEditModel() { diff --git a/chrome/renderer/resources/extensions/searchbox_api.js b/chrome/renderer/resources/extensions/searchbox_api.js index d17ee17..ae18282 100644 --- a/chrome/renderer/resources/extensions/searchbox_api.js +++ b/chrome/renderer/resources/extensions/searchbox_api.js @@ -29,6 +29,7 @@ if (!chrome.searchBox) { native function GetWidth(); native function GetHeight(); native function GetAutocompleteResults(); + native function NavigateContentWindow(); native function SetSuggestions(); native function SetQuerySuggestion(); native function SetQuerySuggestionFromAutocompleteResult(); @@ -176,6 +177,9 @@ if (!chrome.searchBox) { this.markDuplicateSuggestions = function(clientSuggestions) { return DedupeClientSuggestions(clientSuggestions); }; + this.navigateContentWindow = function(destination) { + return NavigateContentWindow(destination); + }; this.onchange = null; this.onsubmit = null; this.oncancel = null; diff --git a/chrome/renderer/searchbox/searchbox.cc b/chrome/renderer/searchbox/searchbox.cc index 88e88bb..778e1ef 100644 --- a/chrome/renderer/searchbox/searchbox.cc +++ b/chrome/renderer/searchbox/searchbox.cc @@ -56,6 +56,24 @@ gfx::Rect SearchBox::GetRect() { static_cast<int>(static_cast<float>(rect_.height()) / zoom)); } +const std::vector<InstantAutocompleteResult>& + SearchBox::GetAutocompleteResults() { + // Remember the last requested autocomplete_results to account for race + // conditions between autocomplete providers returning new data and the user + // clicking on a suggestion. + last_autocomplete_results_ = autocomplete_results_; + last_results_base_ = results_base_; + return autocomplete_results_; +} + +const InstantAutocompleteResult* SearchBox::GetAutocompleteResultWithId( + size_t restricted_id) const { + if (restricted_id < last_results_base_ || + restricted_id >= last_results_base_ + last_autocomplete_results_.size()) + return NULL; + return &last_autocomplete_results_[restricted_id - last_results_base_]; +} + bool SearchBox::OnMessageReceived(const IPC::Message& message) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(SearchBox, message) diff --git a/chrome/renderer/searchbox/searchbox.h b/chrome/renderer/searchbox/searchbox.h index c568d13..c1d655a 100644 --- a/chrome/renderer/searchbox/searchbox.h +++ b/chrome/renderer/searchbox/searchbox.h @@ -39,10 +39,12 @@ class SearchBox : public content::RenderViewObserver, size_t selection_start() const { return selection_start_; } size_t selection_end() const { return selection_end_; } int results_base() const { return results_base_; } + gfx::Rect GetRect(); - const std::vector<InstantAutocompleteResult>& autocomplete_results() const { - return autocomplete_results_; - } + const std::vector<InstantAutocompleteResult>& GetAutocompleteResults(); + // Searchbox retains ownership of this object. + const InstantAutocompleteResult* + GetAutocompleteResultWithId(size_t restricted_id) const; private: // RenderViewObserver implementation. @@ -67,9 +69,11 @@ class SearchBox : public content::RenderViewObserver, bool verbatim_; size_t selection_start_; size_t selection_end_; - int results_base_; + size_t results_base_; gfx::Rect rect_; std::vector<InstantAutocompleteResult> autocomplete_results_; + size_t last_results_base_; + std::vector<InstantAutocompleteResult> last_autocomplete_results_; DISALLOW_COPY_AND_ASSIGN(SearchBox); }; diff --git a/chrome/renderer/searchbox/searchbox_extension.cc b/chrome/renderer/searchbox/searchbox_extension.cc index d68eb99..e8ff07d 100644 --- a/chrome/renderer/searchbox/searchbox_extension.cc +++ b/chrome/renderer/searchbox/searchbox_extension.cc @@ -14,6 +14,8 @@ #include "grit/renderer_resources.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebScriptSource.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURLRequest.h" #include "ui/base/keycodes/keyboard_codes.h" #include "ui/base/resource/resource_bundle.h" #include "v8/include/v8.h" @@ -163,6 +165,10 @@ class SearchBoxExtensionWrapper : public v8::Extension { static v8::Handle<v8::Value> GetAutocompleteResults( const v8::Arguments& args); + // Navigates the window to a URL represented by either a URL string or a + // restricted ID. + static v8::Handle<v8::Value> NavigateContentWindow(const v8::Arguments& args); + // Sets ordered suggestions. Valid for current |value|. static v8::Handle<v8::Value> SetSuggestions(const v8::Arguments& args); @@ -212,6 +218,8 @@ v8::Handle<v8::FunctionTemplate> SearchBoxExtensionWrapper::GetNativeFunction( return v8::FunctionTemplate::New(GetHeight); } else if (name->Equals(v8::String::New("GetAutocompleteResults"))) { return v8::FunctionTemplate::New(GetAutocompleteResults); + } else if (name->Equals(v8::String::New("NavigateContentWindow"))) { + return v8::FunctionTemplate::New(NavigateContentWindow); } else if (name->Equals(v8::String::New("SetSuggestions"))) { return v8::FunctionTemplate::New(SetSuggestions); } else if (name->Equals(v8::String::New("SetQuerySuggestion"))) { @@ -312,8 +320,8 @@ v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetAutocompleteResults( content::RenderView* render_view = GetRenderView(); if (!render_view) return v8::Undefined(); const std::vector<InstantAutocompleteResult>& results = - SearchBox::Get(render_view)->autocomplete_results(); - const int results_base = SearchBox::Get(render_view)->results_base(); + SearchBox::Get(render_view)->GetAutocompleteResults(); + const size_t results_base = SearchBox::Get(render_view)->results_base(); v8::Handle<v8::Array> results_array = v8::Array::New(results.size()); for (size_t i = 0; i < results.size(); ++i) { v8::Handle<v8::Object> result = v8::Object::New(); @@ -337,6 +345,31 @@ v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetAutocompleteResults( } // static +v8::Handle<v8::Value> SearchBoxExtensionWrapper::NavigateContentWindow( + const v8::Arguments& args) { + content::RenderView* render_view = GetRenderView(); + if (!render_view || !args.Length()) return v8::Undefined(); + + GURL destination_url; + if (args[0]->IsString()) { + destination_url = GURL(*v8::String::Utf8Value(args[0])); + } else if (args[0]->IsNumber()) { + // Get the restricted_id. + const size_t restricted_id = args[0]->Uint32Value(); + const InstantAutocompleteResult* result = + SearchBox::Get(render_view)->GetAutocompleteResultWithId(restricted_id); + if (result) + destination_url = result->destination_url; + } + // Navigate the main frame. + if (destination_url.is_valid()) { + WebKit::WebURLRequest request(destination_url); + render_view->GetWebView()->mainFrame()->loadRequest(request); + } + return v8::Undefined(); +} + +// static v8::Handle<v8::Value> SearchBoxExtensionWrapper::SetSuggestions( const v8::Arguments& args) { std::vector<InstantSuggestion> suggestions; @@ -418,23 +451,20 @@ v8::Handle<v8::Value> content::RenderView* render_view = GetRenderView(); if (1 <= args.Length() && args.Length() <= 2 && args[0]->IsNumber() && render_view) { - const int results_id = args[0]->Uint32Value(); - const int results_base = SearchBox::Get(render_view)->results_base(); - // Note that stale results_ids, less than the current results_base, will - // wrap. - const size_t index = results_id - results_base; - const std::vector<InstantAutocompleteResult>& suggestions = - SearchBox::Get(render_view)->autocomplete_results(); - if (index < suggestions.size()) { - string16 text = UTF8ToUTF16(suggestions[index].destination_url.spec()); + const size_t results_id = args[0]->Uint32Value(); + + const InstantAutocompleteResult* result = + SearchBox::Get(render_view)->GetAutocompleteResultWithId(results_id); + if (result) { + string16 text = UTF8ToUTF16(result->destination_url.spec()); InstantCompleteBehavior behavior = INSTANT_COMPLETE_NOW; InstantSuggestionType type = INSTANT_SUGGESTION_URL; if (args.Length() >= 2 && args[1]->Uint32Value() == 2) behavior = INSTANT_COMPLETE_NEVER; - if (suggestions[index].is_search) { - text = suggestions[index].contents; + if (result->is_search) { + text = result->contents; type = INSTANT_SUGGESTION_SEARCH; } @@ -442,8 +472,7 @@ v8::Handle<v8::Value> suggestions.push_back(InstantSuggestion(text, behavior, type)); SearchBox::Get(render_view)->SetSuggestions(suggestions); } else { - VLOG(1) << "Invalid results_id " << results_id << "; " - << "results_base is " << results_base << "."; + VLOG(1) << "Invalid results_id " << results_id; } } return v8::Undefined(); @@ -475,21 +504,17 @@ v8::Handle<v8::Value> content::RenderView* render_view = GetRenderView(); if (1 <= args.Length() && args.Length() <= 2 && args[0]->IsNumber() && render_view) { - const int results_id = args[0]->Uint32Value(); - const int results_base = SearchBox::Get(render_view)->results_base(); - // Note that stale results_ids, less than the current results_base, will - // wrap. - const size_t index = results_id - results_base; - const std::vector<InstantAutocompleteResult>& suggestions = - SearchBox::Get(render_view)->autocomplete_results(); - if (index < suggestions.size()) { - string16 text = UTF8ToUTF16(suggestions[index].destination_url.spec()); + const size_t results_id = args[0]->Uint32Value(); + const InstantAutocompleteResult* result = + SearchBox::Get(render_view)->GetAutocompleteResultWithId(results_id); + if (result) { + string16 text = UTF8ToUTF16(result->destination_url.spec()); InstantCompleteBehavior behavior = INSTANT_COMPLETE_REPLACE; InstantSuggestionType type = INSTANT_SUGGESTION_URL; if ((args.Length() >= 2 && args[1]->Uint32Value() == 0) || - (args.Length() < 2 && suggestions[index].is_search)) { - text = suggestions[index].contents; + (args.Length() < 2 && result->is_search)) { + text = result->contents; type = INSTANT_SUGGESTION_SEARCH; } @@ -497,8 +522,7 @@ v8::Handle<v8::Value> suggestions.push_back(InstantSuggestion(text, behavior, type)); SearchBox::Get(render_view)->SetSuggestions(suggestions); } else { - VLOG(1) << "Invalid results_id " << results_id << "; " - << "results_base is " << results_base << "."; + VLOG(1) << "Invalid results_id " << results_id; } } return v8::Undefined(); |