Index: chrome/browser/ui/omnibox/omnibox_controller.cc |
diff --git a/chrome/browser/ui/omnibox/omnibox_controller.cc b/chrome/browser/ui/omnibox/omnibox_controller.cc |
index d99214ce4e9fac77fd31b52233060409a05564be..ee4f27d2b7802a5b569641b7957b2daaea8ad183 100644 |
--- a/chrome/browser/ui/omnibox/omnibox_controller.cc |
+++ b/chrome/browser/ui/omnibox/omnibox_controller.cc |
@@ -4,15 +4,32 @@ |
#include "chrome/browser/ui/omnibox/omnibox_controller.h" |
+#include "base/metrics/histogram.h" |
#include "chrome/browser/autocomplete/autocomplete_classifier.h" |
#include "chrome/browser/autocomplete/autocomplete_controller.h" |
+#include "chrome/browser/autocomplete/autocomplete_match.h" |
+#include "chrome/browser/net/predictor.h" |
+#include "chrome/browser/predictors/autocomplete_action_predictor.h" |
+#include "chrome/browser/prerender/prerender_field_trial.h" |
+#include "chrome/browser/prerender/prerender_manager.h" |
+#include "chrome/browser/prerender/prerender_manager_factory.h" |
+#include "chrome/browser/profiles/profile.h" |
#include "chrome/browser/search/search.h" |
+#include "chrome/browser/ui/omnibox/omnibox_edit_controller.h" |
#include "chrome/browser/ui/omnibox/omnibox_edit_model.h" |
+#include "chrome/browser/ui/omnibox/omnibox_popup_model.h" |
+#include "chrome/browser/ui/omnibox/omnibox_popup_view.h" |
+#include "chrome/browser/ui/search/instant_controller.h" |
+#include "extensions/common/constants.h" |
+#include "ui/gfx/rect.h" |
+ |
+using predictors::AutocompleteActionPredictor; |
OmniboxController::OmniboxController(OmniboxEditModel* omnibox_edit_model, |
Profile* profile) |
- : omnibox_edit_model_(omnibox_edit_model) { |
+ : omnibox_edit_model_(omnibox_edit_model), |
+ profile_(profile) { |
autocomplete_controller_.reset(new AutocompleteController(profile, this, |
chrome::IsInstantExtendedAPIEnabled() ? |
AutocompleteClassifier::kInstantExtendedOmniboxProviders : |
@@ -23,5 +40,90 @@ OmniboxController::~OmniboxController() { |
} |
void OmniboxController::OnResultChanged(bool default_match_changed) { |
- omnibox_edit_model_->OnResultChanged(default_match_changed); |
+ // TODO(beaudoin): There should be no need to access the popup when using |
+ // instant extended, remove this reference. |
+ const bool was_open = popup_->IsOpen(); |
+ if (default_match_changed) { |
+ // The default match has changed, we need to let the OmniboxEditModel know |
+ // about new inline autocomplete text (blue highlight). |
+ string16 inline_autocomplete_text; |
+ string16 keyword; |
+ bool is_keyword_hint = false; |
+ const AutocompleteResult& result = this->result(); |
+ const AutocompleteResult::const_iterator match(result.default_match()); |
+ if (match != result.end()) { |
+ if ((match->inline_autocomplete_offset != string16::npos) && |
+ (match->inline_autocomplete_offset < |
+ match->fill_into_edit.length())) { |
+ inline_autocomplete_text = |
+ match->fill_into_edit.substr(match->inline_autocomplete_offset); |
+ } |
+ |
+ if (!prerender::IsOmniboxEnabled(profile_)) |
+ DoPreconnect(*match); |
+ |
+ // We could prefetch the alternate nav URL, if any, but because there |
+ // can be many of these as a user types an initial series of characters, |
+ // the OS DNS cache could suffer eviction problems for minimal gain. |
+ |
+ match->GetKeywordUIState(profile_, &keyword, &is_keyword_hint); |
+ } |
+ |
+ popup_->OnResultChanged(); |
+ omnibox_edit_model_->OnPopupDataChanged(inline_autocomplete_text, NULL, |
+ keyword, is_keyword_hint); |
+ } else { |
+ popup_->OnResultChanged(); |
+ } |
+ |
+ if (popup_->IsOpen()) { |
+ // The popup size may have changed, let instant know. |
+ OnPopupBoundsChanged(popup_->view()->GetTargetBounds()); |
+ |
+ InstantController* instant = |
+ omnibox_edit_model_->controller()->GetInstant(); |
+ if (instant && !omnibox_edit_model_->in_revert()) { |
+ instant->HandleAutocompleteResults( |
+ *autocomplete_controller()->providers(), |
+ autocomplete_controller()->result()); |
+ } |
+ } else if (was_open) { |
+ // Accepts the temporary text as the user text, because it makes little |
+ // sense to have temporary text when the popup is closed. |
+ omnibox_edit_model_->AcceptTemporaryTextAsUserText(); |
+ // The popup has been closed, let instant know. |
+ OnPopupBoundsChanged(gfx::Rect()); |
+ } |
+} |
+ |
+void OmniboxController::ClearPopupKeywordMode() const { |
+ if (popup_->IsOpen() && |
+ popup_->selected_line_state() == OmniboxPopupModel::KEYWORD) |
+ popup_->SetSelectedLineState(OmniboxPopupModel::NORMAL); |
+} |
+ |
+const AutocompleteResult& OmniboxController::result() const { |
+ return autocomplete_controller_->result(); |
+} |
+ |
+void OmniboxController::DoPreconnect(const AutocompleteMatch& match) { |
+ if (!match.destination_url.SchemeIs(extensions::kExtensionScheme)) { |
+ // Warm up DNS Prefetch cache, or preconnect to a search service. |
+ UMA_HISTOGRAM_ENUMERATION("Autocomplete.MatchType", match.type, |
+ AutocompleteMatchType::NUM_TYPES); |
+ if (profile_->GetNetworkPredictor()) { |
+ profile_->GetNetworkPredictor()->AnticipateOmniboxUrl( |
+ match.destination_url, |
+ AutocompleteActionPredictor::IsPreconnectable(match)); |
+ } |
+ // We could prefetch the alternate nav URL, if any, but because there |
+ // can be many of these as a user types an initial series of characters, |
+ // the OS DNS cache could suffer eviction problems for minimal gain. |
+ } |
+} |
+ |
+void OmniboxController::OnPopupBoundsChanged(const gfx::Rect& bounds) { |
+ InstantController* instant = omnibox_edit_model_->controller()->GetInstant(); |
+ if (instant) |
+ instant->SetPopupBounds(bounds); |
} |