diff options
author | pkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-01 16:59:11 +0000 |
---|---|---|
committer | pkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-01 16:59:11 +0000 |
commit | df772cbfe7a1b17dd7bb179c1e25780201d0b0ce (patch) | |
tree | bb2c277deb1b3ef07d04b5908e362c0ef7556478 /chrome/browser | |
parent | 8e0dca871966c15a08c23bfd890aad73ee3b8aa5 (diff) | |
download | chromium_src-df772cbfe7a1b17dd7bb179c1e25780201d0b0ce.zip chromium_src-df772cbfe7a1b17dd7bb179c1e25780201d0b0ce.tar.gz chromium_src-df772cbfe7a1b17dd7bb179c1e25780201d0b0ce.tar.bz2 |
More work fixing miscellaneous issues in the autocomplete code, probably none of which will help my crasher :(
* Force the query to stop if the user deletes a match. This makes more sense from a UI perspective and allows some code to be simpler.
* Prevent us from potentially doing a "minimal changes" match in a different profile (hard to trigger, likely no practical effects)
* Remove unneeded Reset() call on a repeating timer (which will auto-reset itself)
* Rename one of the notifications and move its listener to the edit, since that's who really cares about it anyway.
* Make the controller's Stop(true) notify the popup via the normal observer pipeline rather than coding something special into the popup's StopAutocomplete().
* Rename |paste_and_go_controller| |synchronous_controller| and use it instead of using the main popup controller to do the synchronous query when calling URLsForDefaultMatch(). This makes things both simpler and safer.
BUG=none
TEST=Using the omnibox still works fine
Review URL: http://codereview.chromium.org/178049
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@25044 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
11 files changed, 182 insertions, 185 deletions
diff --git a/chrome/browser/autocomplete/autocomplete.cc b/chrome/browser/autocomplete/autocomplete.cc index 6c18880..6a2989e 100644 --- a/chrome/browser/autocomplete/autocomplete.cc +++ b/chrome/browser/autocomplete/autocomplete.cc @@ -646,6 +646,8 @@ AutocompleteController::~AutocompleteController() { void AutocompleteController::SetProfile(Profile* profile) { for (ACProviders::iterator i(providers_.begin()); i != providers_.end(); ++i) (*i)->SetProfile(profile); + input_.Clear(); // Ensure we don't try to do a "minimal_changes" query on a + // different profile. } void AutocompleteController::Start(const std::wstring& text, @@ -710,19 +712,26 @@ void AutocompleteController::Stop(bool clear_result) { updated_latest_result_ = false; delay_interval_has_passed_ = false; done_ = true; - if (clear_result) + if (clear_result) { result_.Reset(); + NotificationService::current()->Notify( + NotificationType::AUTOCOMPLETE_CONTROLLER_RESULT_UPDATED, + Source<AutocompleteController>(this), + Details<const AutocompleteResult>(&result_)); + // NOTE: We don't notify AUTOCOMPLETE_CONTROLLER_DEFAULT_MATCH_UPDATED since + // we're trying to only clear the popup, not touch the edit... this is all + // a mess and should be cleaned up :( + } latest_result_.CopyFrom(result_); } void AutocompleteController::DeleteMatch(const AutocompleteMatch& match) { DCHECK(match.deletable); - match.provider->DeleteMatch(match); // This will synchronously call back to + match.provider->DeleteMatch(match); // This may synchronously call back to // OnProviderUpdate(). - - // Notify observers of this change immediately, so the UI feels responsive to - // the user's action. - CommitResult(); + CommitResult(); // Ensure any new result gets committed immediately. If it + // was committed already or hasn't been modified, this is + // harmless. } void AutocompleteController::OnProviderUpdate(bool updated_matches) { @@ -759,7 +768,7 @@ void AutocompleteController::UpdateLatestResult(bool is_synchronous_pass) { } NotificationService::current()->Notify( - NotificationType::AUTOCOMPLETE_CONTROLLER_SYNCHRONOUS_MATCHES_AVAILABLE, + NotificationType::AUTOCOMPLETE_CONTROLLER_DEFAULT_MATCH_UPDATED, Source<AutocompleteController>(this), Details<const AutocompleteResult>(&latest_result_)); } @@ -776,7 +785,6 @@ void AutocompleteController::UpdateLatestResult(bool is_synchronous_pass) { void AutocompleteController::DelayTimerFired() { delay_interval_has_passed_ = true; - update_delay_timer_.Reset(); CommitResult(); } @@ -798,6 +806,13 @@ void AutocompleteController::CommitResult() { NotificationType::AUTOCOMPLETE_CONTROLLER_RESULT_UPDATED, Source<AutocompleteController>(this), Details<const AutocompleteResult>(&result_)); + // This notification must be sent after the other so the popup has time to + // update its state before the edit calls into it. + // TODO(pkasting): Eliminate this ordering requirement. + NotificationService::current()->Notify( + NotificationType::AUTOCOMPLETE_CONTROLLER_DEFAULT_MATCH_UPDATED, + Source<AutocompleteController>(this), + Details<const AutocompleteResult>(&result_)); if (!done_) update_delay_timer_.Reset(); } diff --git a/chrome/browser/autocomplete/autocomplete.h b/chrome/browser/autocomplete/autocomplete.h index 6002596..20697b8 100644 --- a/chrome/browser/autocomplete/autocomplete.h +++ b/chrome/browser/autocomplete/autocomplete.h @@ -518,7 +518,8 @@ class AutocompleteProvider // Called to delete a match and the backing data that produced it. This // match should not appear again in this or future queries. This can only be - // called for matches the provider marks as deletable. + // called for matches the provider marks as deletable. This should only be + // called when no query is running. // NOTE: Remember to call OnProviderUpdate() if matches_ is updated. virtual void DeleteMatch(const AutocompleteMatch& match) {} @@ -749,12 +750,11 @@ class AutocompleteController : public ACProviderListener { // fired, they will be discarded. // // If |clear_result| is true, the controller will also erase the result set. - // TODO(pkasting): This is temporary. Instead, we should keep a separate - // result set that tracks the displayed matches. void Stop(bool clear_result); // Asks the relevant provider to delete |match|, and ensures observers are - // notified of resulting changes immediately. + // notified of resulting changes immediately. This should only be called when + // no query is running. void DeleteMatch(const AutocompleteMatch& match); // Getters diff --git a/chrome/browser/autocomplete/autocomplete_edit.cc b/chrome/browser/autocomplete/autocomplete_edit.cc index ce78f0f..174f23c 100644 --- a/chrome/browser/autocomplete/autocomplete_edit.cc +++ b/chrome/browser/autocomplete/autocomplete_edit.cc @@ -10,6 +10,7 @@ #include "chrome/browser/autocomplete/autocomplete_popup_model.h" #include "chrome/browser/autocomplete/keyword_provider.h" #include "chrome/browser/metrics/user_metrics.h" +#include "chrome/browser/net/dns_global.h" #include "chrome/browser/net/url_fixer_upper.h" #include "chrome/browser/profile.h" #include "chrome/browser/search_engines/template_url.h" @@ -22,15 +23,13 @@ /////////////////////////////////////////////////////////////////////////////// // AutocompleteEditModel -// A single AutocompleteController used solely for making synchronous calls to -// determine how to deal with the clipboard contents for Paste And Go -// functionality. We avoid using the popup's controller here because we don't -// want to interrupt in-progress queries or modify the popup state just -// because the user right-clicked the edit. We don't need a controller for -// every edit because this will always be accessed on the main thread, so we +// A single AutocompleteController used solely for making synchronous calls. We +// avoid using the popup's controller here because we don't want to interrupt +// in-progress queries or modify the popup state. We don't need a controller +// for every edit because this will always be accessed on the main thread, so we // won't have thread-safety problems. -static AutocompleteController* paste_and_go_controller = NULL; -static int paste_and_go_controller_refcount = 0; +static AutocompleteController* synchronous_controller = NULL; +static int synchronous_controller_refcount = 0; AutocompleteEditModel::AutocompleteEditModel( AutocompleteEditView* view, @@ -48,16 +47,32 @@ AutocompleteEditModel::AutocompleteEditModel( keyword_ui_state_(NORMAL), show_search_hint_(true), profile_(profile) { - if (++paste_and_go_controller_refcount == 1) { + if (++synchronous_controller_refcount == 1) { // We don't have a controller yet, so create one. No profile is set since // we'll set this before each call to the controller. - paste_and_go_controller = new AutocompleteController(NULL); + synchronous_controller = new AutocompleteController(NULL); } } AutocompleteEditModel::~AutocompleteEditModel() { - if (--paste_and_go_controller_refcount == 0) - delete paste_and_go_controller; + if (--synchronous_controller_refcount == 0) { + delete synchronous_controller; + } else { + // This isn't really necessary, but it ensures safety if someday any + // provider does some kind of cleanup on the old profile when it gets a + // SetProfile() call. The current profile could be deleted after we return, + // so if we don't do this, the providers will be referencing a deleted + // object, and if they accessed it on the next SetProfile() call, bad things + // would happen. + synchronous_controller->SetProfile(NULL); + } +} + +void AutocompleteEditModel::SetPopupModel(AutocompletePopupModel* popup_model) { + popup_ = popup_model; + registrar_.Add(this, + NotificationType::AUTOCOMPLETE_CONTROLLER_DEFAULT_MATCH_UPDATED, + Source<AutocompleteController>(popup_->autocomplete_controller())); } void AutocompleteEditModel::SetProfile(Profile* profile) { @@ -198,13 +213,13 @@ bool AutocompleteEditModel::CanPasteAndGo(const std::wstring& text) const { paste_and_go_alternate_nav_url_ = GURL(); // Ask the controller what do do with this input. - // Setting the profile is cheap, and since there's one paste_and_go_controller + // Setting the profile is cheap, and since there's one synchronous_controller // for many tabs which may all have different profiles, it ensures we're // always using the right one. - paste_and_go_controller->SetProfile(profile_); - paste_and_go_controller->Start(text, std::wstring(), true, false, true); - DCHECK(paste_and_go_controller->done()); - const AutocompleteResult& result = paste_and_go_controller->result(); + synchronous_controller->SetProfile(profile_); + synchronous_controller->Start(text, std::wstring(), true, false, true); + DCHECK(synchronous_controller->done()); + const AutocompleteResult& result = synchronous_controller->result(); if (result.empty()) return false; @@ -527,6 +542,39 @@ bool AutocompleteEditModel::OnAfterPossibleChange(const std::wstring& new_text, return true; } +void AutocompleteEditModel::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + DCHECK_EQ(NotificationType::AUTOCOMPLETE_CONTROLLER_DEFAULT_MATCH_UPDATED, + type.value); + + std::wstring inline_autocomplete_text; + std::wstring keyword; + bool is_keyword_hint = false; + AutocompleteMatch::Type match_type = AutocompleteMatch::SEARCH_WHAT_YOU_TYPED; + const AutocompleteResult* result = + Details<const AutocompleteResult>(details).ptr(); + const AutocompleteResult::const_iterator match(result->default_match()); + if (match != result->end()) { + if ((match->inline_autocomplete_offset != std::wstring::npos) && + (match->inline_autocomplete_offset < match->fill_into_edit.length())) { + inline_autocomplete_text = + match->fill_into_edit.substr(match->inline_autocomplete_offset); + } + // Warm up DNS Prefetch Cache. + chrome_browser_net::DnsPrefetchUrl(match->destination_url); + // 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. + + is_keyword_hint = popup_->GetKeywordForMatch(*match, &keyword); + match_type = match->type; + } + + OnPopupDataChanged(inline_autocomplete_text, false, keyword, is_keyword_hint, + match_type); +} + void AutocompleteEditModel::InternalSetUserText(const std::wstring& text) { user_text_ = text; just_deleted_text_ = false; @@ -550,13 +598,39 @@ std::wstring AutocompleteEditModel::UserTextFromDisplayText( GURL AutocompleteEditModel::GetURLForCurrentText( PageTransition::Type* transition, bool* is_history_what_you_typed_match, - GURL* alternate_nav_url) { + GURL* alternate_nav_url) const { return (popup_->IsOpen() || query_in_progress()) ? popup_->URLsForCurrentSelection(transition, is_history_what_you_typed_match, alternate_nav_url) : - popup_->URLsForDefaultMatch(UserTextFromDisplayText(view_->GetText()), - GetDesiredTLD(), transition, - is_history_what_you_typed_match, - alternate_nav_url); + URLsForDefaultMatch(transition, is_history_what_you_typed_match, + alternate_nav_url); +} + +GURL AutocompleteEditModel::URLsForDefaultMatch( + PageTransition::Type* transition, + bool* is_history_what_you_typed_match, + GURL* alternate_nav_url) const { + // Ask the controller what do do with this input. + // Setting the profile is cheap, and since there's one synchronous_controller + // for many tabs which may all have different profiles, it ensures we're + // always using the right one. + synchronous_controller->SetProfile(profile_); + synchronous_controller->Start(UserTextFromDisplayText(view_->GetText()), + GetDesiredTLD(), true, false, true); + CHECK(synchronous_controller->done()); + + const AutocompleteResult& result = synchronous_controller->result(); + if (result.empty()) + return GURL(); + + // Get the URLs for the default match. + const AutocompleteResult::const_iterator match = result.default_match(); + if (transition) + *transition = match->transition; + if (is_history_what_you_typed_match) + *is_history_what_you_typed_match = match->is_history_what_you_typed_match; + if (alternate_nav_url) + *alternate_nav_url = result.alternate_nav_url(); + return match->destination_url; } diff --git a/chrome/browser/autocomplete/autocomplete_edit.h b/chrome/browser/autocomplete/autocomplete_edit.h index efe5c9a..4d6c4a7 100644 --- a/chrome/browser/autocomplete/autocomplete_edit.h +++ b/chrome/browser/autocomplete/autocomplete_edit.h @@ -6,6 +6,7 @@ #define CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_EDIT_H_ #include "chrome/browser/autocomplete/autocomplete.h" +#include "chrome/common/notification_registrar.h" #include "chrome/common/page_transition_types.h" #include "googleurl/src/gurl.h" #include "webkit/glue/window_open_disposition.h" @@ -53,7 +54,7 @@ class AutocompleteEditController { virtual std::wstring GetTitle() const = 0; }; -class AutocompleteEditModel { +class AutocompleteEditModel : public NotificationObserver { public: enum KeywordUIState { // The user is typing normally. @@ -96,9 +97,7 @@ class AutocompleteEditModel { Profile* profile); ~AutocompleteEditModel(); - void set_popup_model(AutocompletePopupModel* popup_model) { - popup_ = popup_model; - } + void SetPopupModel(AutocompletePopupModel* popup_model); // Invoked when the profile has changed. void SetProfile(Profile* profile); @@ -241,9 +240,9 @@ class AutocompleteEditModel { // negative for moving up, positive for moving down. void OnUpOrDownKeyPressed(int count); - // Called back by the AutocompletePopupModel when any relevant data changes. - // This rolls together several separate pieces of data into one call so we can - // update all the UI efficiently: + // Called when any relevant data changes. This rolls together several + // separate pieces of data into one call so we can update all the UI + // efficiently: // |text| is either the new temporary text (if |is_temporary_text| is true) // from the user manually selecting a different match, or the inline // autocomplete text (if |is_temporary_text| is false). @@ -296,6 +295,11 @@ class AutocompleteEditModel { // he intended to hit "ctrl-enter". }; + // NotificationObserver + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + // Called whenever user_text_ should change. void InternalSetUserText(const std::wstring& text); @@ -314,7 +318,19 @@ class AutocompleteEditModel { // not needed). GURL GetURLForCurrentText(PageTransition::Type* transition, bool* is_history_what_you_typed_match, - GURL* alternate_nav_url); + GURL* alternate_nav_url) const; + + // Performs a query for only the synchronously available matches for the + // current input, sets |transition|, |is_history_what_you_typed_match|, and + // |alternate_nav_url| (if applicable) based on the default match, and returns + // its url. |transition|, |is_history_what_you_typed_match| and/or + // |alternate_nav_url| may be null, in which case they are not updated. + // + // If there are no matches for the input, leaves the outparams unset and + // returns the empty string. + GURL URLsForDefaultMatch(PageTransition::Type* transition, + bool* is_history_what_you_typed_match, + GURL* alternate_nav_url) const; AutocompleteEditView* view_; @@ -322,6 +338,8 @@ class AutocompleteEditModel { AutocompleteEditController* controller_; + NotificationRegistrar registrar_; + // Whether the edit has focus. bool has_focus_; diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc b/chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc index b9ae999..0d47780f 100644 --- a/chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc +++ b/chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc @@ -105,7 +105,7 @@ AutocompleteEditViewGtk::AutocompleteEditViewGtk( #endif tab_was_pressed_(false), paste_clipboard_requested_(false) { - model_->set_popup_model(popup_view_->GetModel()); + model_->SetPopupModel(popup_view_->GetModel()); } AutocompleteEditViewGtk::~AutocompleteEditViewGtk() { diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_win.cc b/chrome/browser/autocomplete/autocomplete_edit_view_win.cc index 59d6a9e..1e0b3b6 100644 --- a/chrome/browser/autocomplete/autocomplete_edit_view_win.cc +++ b/chrome/browser/autocomplete/autocomplete_edit_view_win.cc @@ -426,7 +426,7 @@ AutocompleteEditViewWin::AutocompleteEditViewWin( drop_highlight_position_(-1), background_color_(0), scheme_security_level_(ToolbarModel::NORMAL) { - model_->set_popup_model(popup_view_->GetModel()); + model_->SetPopupModel(popup_view_->GetModel()); saved_selection_for_focus_change_.cpMin = -1; diff --git a/chrome/browser/autocomplete/autocomplete_popup_model.cc b/chrome/browser/autocomplete/autocomplete_popup_model.cc index d54c385..44c14c2 100644 --- a/chrome/browser/autocomplete/autocomplete_popup_model.cc +++ b/chrome/browser/autocomplete/autocomplete_popup_model.cc @@ -7,13 +7,15 @@ #include "base/string_util.h" #include "chrome/browser/autocomplete/autocomplete_edit.h" #include "chrome/browser/autocomplete/autocomplete_popup_view.h" -#include "chrome/browser/net/dns_global.h" #include "chrome/browser/profile.h" #include "chrome/browser/search_engines/template_url.h" #include "chrome/browser/search_engines/template_url_model.h" #include "chrome/common/notification_service.h" #include "third_party/icu38/public/common/unicode/ubidi.h" +/////////////////////////////////////////////////////////////////////////////// +// AutocompletePopupModel + AutocompletePopupModel::AutocompletePopupModel( AutocompletePopupView* popup_view, AutocompleteEditModel* edit_model, @@ -23,16 +25,9 @@ AutocompletePopupModel::AutocompletePopupModel( controller_(new AutocompleteController(profile)), profile_(profile), hovered_line_(kNoMatch), - selected_line_(kNoMatch), - inside_synchronous_query_(false) { - registrar_.Add( - this, - NotificationType::AUTOCOMPLETE_CONTROLLER_RESULT_UPDATED, - Source<AutocompleteController>(controller_.get())); - registrar_.Add( - this, - NotificationType::AUTOCOMPLETE_CONTROLLER_SYNCHRONOUS_MATCHES_AVAILABLE, - Source<AutocompleteController>(controller_.get())); + selected_line_(kNoMatch) { + registrar_.Add(this, NotificationType::AUTOCOMPLETE_CONTROLLER_RESULT_UPDATED, + Source<AutocompleteController>(controller_.get())); } AutocompletePopupModel::~AutocompletePopupModel() { @@ -61,9 +56,6 @@ void AutocompletePopupModel::StartAutocomplete( void AutocompletePopupModel::StopAutocomplete() { controller_->Stop(true); - SetHoveredLine(kNoMatch); - selected_line_ = kNoMatch; - view_->UpdatePopupAppearance(); } bool AutocompletePopupModel::IsOpen() const { @@ -117,6 +109,8 @@ void AutocompletePopupModel::SetSelectedLine(size_t line, return; // Nothing else to do. // Update the edit with the new data for this match. + // TODO(pkasting): If |selected_line_| moves to the controller, this can be + // eliminated and just become a call to the observer on the edit. std::wstring keyword; const bool is_keyword_hint = GetKeywordForMatch(match, &keyword); edit_model_->OnPopupDataChanged( @@ -187,42 +181,6 @@ GURL AutocompletePopupModel::URLsForCurrentSelection( return match->destination_url; } -GURL AutocompletePopupModel::URLsForDefaultMatch( - const std::wstring& text, - const std::wstring& desired_tld, - PageTransition::Type* transition, - bool* is_history_what_you_typed_match, - GURL* alternate_nav_url) { - // We had better not already be doing anything, or this call will blow it - // away. - CHECK(!IsOpen()); - CHECK(controller_->done()); - - // Run the new query and get only the synchronously available matches. - inside_synchronous_query_ = true; // Tell Observe() not to notify the edit or - // update our appearance. - controller_->Start(text, desired_tld, true, false, true); - inside_synchronous_query_ = false; - CHECK(controller_->done()); - - const AutocompleteResult& result = controller_->result(); - GURL destination_url; - if (!result.empty()) { - // Get the URLs for the default match. - const AutocompleteResult::const_iterator match = result.default_match(); - if (transition) - *transition = match->transition; - if (is_history_what_you_typed_match) - *is_history_what_you_typed_match = match->is_history_what_you_typed_match; - if (alternate_nav_url) - *alternate_nav_url = result.alternate_nav_url(); - destination_url = match->destination_url; - } - - controller_->Stop(true); // Keeps our state consistent. - return destination_url; -} - bool AutocompletePopupModel::GetKeywordForMatch(const AutocompleteMatch& match, std::wstring* keyword) const { // Assume we have no keyword until we find otherwise. @@ -279,11 +237,15 @@ void AutocompletePopupModel::TryDeletingCurrentItem() { // yet visible" one. if (selected_line_ == kNoMatch) return; + + // Cancel the query so the matches don't change on the user. + controller_->Stop(false); + const AutocompleteMatch& match = controller_->result().match_at(selected_line_); if (match.deletable) { const size_t selected_line = selected_line_; - controller_->DeleteMatch(match); // This will synchronously notify us that + controller_->DeleteMatch(match); // This may synchronously notify us that // the results have changed. const AutocompleteResult& result = controller_->result(); if (!result.empty()) { @@ -299,60 +261,20 @@ void AutocompletePopupModel::TryDeletingCurrentItem() { void AutocompletePopupModel::Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details) { - if (inside_synchronous_query_) - return; + DCHECK_EQ(NotificationType::AUTOCOMPLETE_CONTROLLER_RESULT_UPDATED, + type.value); const AutocompleteResult* result = Details<const AutocompleteResult>(details).ptr(); - switch (type.value) { - case NotificationType::AUTOCOMPLETE_CONTROLLER_RESULT_UPDATED: { - selected_line_ = (result->default_match() == result->end()) ? - kNoMatch : (result->default_match() - result->begin()); - // There had better not be a nonempty result set with no default match. - CHECK((selected_line_ != kNoMatch) || result->empty()); - // If we're going to trim the window size to no longer include the hovered - // line, turn hover off. Practically, this shouldn't happen, but it - // doesn't hurt to be defensive. - if ((hovered_line_ != kNoMatch) && (result->size() <= hovered_line_)) - SetHoveredLine(kNoMatch); - - view_->UpdatePopupAppearance(); - } - // FALL THROUGH - - case NotificationType:: - AUTOCOMPLETE_CONTROLLER_SYNCHRONOUS_MATCHES_AVAILABLE: { - // Update the edit with the possibly new data for this match. - // NOTE: This must be done after the code above, so that our internal - // state will be consistent when the edit calls back to - // URLsForCurrentSelection(). - std::wstring inline_autocomplete_text; - std::wstring keyword; - bool is_keyword_hint = false; - AutocompleteMatch::Type type = AutocompleteMatch::SEARCH_WHAT_YOU_TYPED; - const AutocompleteResult::const_iterator match(result->default_match()); - if (match != result->end()) { - if ((match->inline_autocomplete_offset != std::wstring::npos) && - (match->inline_autocomplete_offset < - match->fill_into_edit.length())) { - inline_autocomplete_text = - match->fill_into_edit.substr(match->inline_autocomplete_offset); - } - // Warm up DNS Prefetch Cache. - chrome_browser_net::DnsPrefetchUrl(match->destination_url); - // 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. - - is_keyword_hint = GetKeywordForMatch(*match, &keyword); - type = match->type; - } - edit_model_->OnPopupDataChanged(inline_autocomplete_text, false, keyword, - is_keyword_hint, type); - return; - } + selected_line_ = (result->default_match() == result->end()) ? + kNoMatch : (result->default_match() - result->begin()); + // There had better not be a nonempty result set with no default match. + CHECK((selected_line_ != kNoMatch) || result->empty()); + // If we're going to trim the window size to no longer include the hovered + // line, turn hover off. Practically, this shouldn't happen, but it + // doesn't hurt to be defensive. + if ((hovered_line_ != kNoMatch) && (result->size() <= hovered_line_)) + SetHoveredLine(kNoMatch); - default: - NOTREACHED(); - } + view_->UpdatePopupAppearance(); } diff --git a/chrome/browser/autocomplete/autocomplete_popup_model.h b/chrome/browser/autocomplete/autocomplete_popup_model.h index c0c6185..166a238 100644 --- a/chrome/browser/autocomplete/autocomplete_popup_model.h +++ b/chrome/browser/autocomplete/autocomplete_popup_model.h @@ -94,25 +94,6 @@ class AutocompletePopupModel : public NotificationObserver { bool* is_history_what_you_typed_match, GURL* alternate_nav_url) const; - // This is sort of a hybrid between StartAutocomplete() and - // URLForCurrentSelection(). When the popup isn't open and the user hits - // enter, we want to get the default match for the user's input immediately, - // and not open the popup, continue running autocomplete, etc. Therefore, - // this does a query for only the synchronously available matches for the - // provided input parameters, sets |transition|, - // |is_history_what_you_typed_match|, and |alternate_nav_url| (if applicable) - // based on the default match, and returns its url. |transition|, - // |is_history_what_you_typed_match| and/or |alternate_nav_url| may be null, - // in which case they are not updated. - // - // If there are no matches for |text|, leaves the outparams unset and returns - // the empty string. - GURL URLsForDefaultMatch(const std::wstring& text, - const std::wstring& desired_tld, - PageTransition::Type* transition, - bool* is_history_what_you_typed_match, - GURL* alternate_nav_url); - // Gets the selected keyword or keyword hint for the given match. Returns // true if |keyword| represents a keyword hint, or false if |keyword| // represents a selected keyword. (|keyword| will always be set [though @@ -168,10 +149,6 @@ class AutocompletePopupModel : public NotificationObserver { // The match the user has manually chosen, if any. AutocompleteResult::Selection manually_selected_match_; - // A hack for URLsForDefaultMatch() that makes the code in Observe() do - // nothing. - bool inside_synchronous_query_; - DISALLOW_COPY_AND_ASSIGN(AutocompletePopupModel); }; diff --git a/chrome/browser/autocomplete/autocomplete_popup_view_mac.mm b/chrome/browser/autocomplete/autocomplete_popup_view_mac.mm index 3553072..6cc2206 100644 --- a/chrome/browser/autocomplete/autocomplete_popup_view_mac.mm +++ b/chrome/browser/autocomplete/autocomplete_popup_view_mac.mm @@ -267,7 +267,7 @@ AutocompletePopupViewMac::AutocompletePopupViewMac( DCHECK(edit_view); DCHECK(edit_model); DCHECK(profile); - edit_model->set_popup_model(model_.get()); + edit_model->SetPopupModel(model_.get()); } AutocompletePopupViewMac::~AutocompletePopupViewMac() { diff --git a/chrome/browser/autocomplete/autocomplete_unittest.cc b/chrome/browser/autocomplete/autocomplete_unittest.cc index 5115e2f..40e6ecf 100644 --- a/chrome/browser/autocomplete/autocomplete_unittest.cc +++ b/chrome/browser/autocomplete/autocomplete_unittest.cc @@ -116,12 +116,10 @@ class AutocompleteProviderTest : public testing::Test, }; void AutocompleteProviderTest::SetUp() { - registrar_.Add(this, - NotificationType::AUTOCOMPLETE_CONTROLLER_RESULT_UPDATED, + registrar_.Add(this, NotificationType::AUTOCOMPLETE_CONTROLLER_RESULT_UPDATED, NotificationService::AllSources()); - registrar_.Add( - this, - NotificationType::AUTOCOMPLETE_CONTROLLER_SYNCHRONOUS_MATCHES_AVAILABLE, + registrar_.Add(this, + NotificationType::AUTOCOMPLETE_CONTROLLER_DEFAULT_MATCH_UPDATED, NotificationService::AllSources()); ResetController(false); } diff --git a/chrome/browser/autocomplete/history_url_provider.cc b/chrome/browser/autocomplete/history_url_provider.cc index fb819d2..714e311 100644 --- a/chrome/browser/autocomplete/history_url_provider.cc +++ b/chrome/browser/autocomplete/history_url_provider.cc @@ -64,6 +64,8 @@ void HistoryURLProvider::Stop() { } void HistoryURLProvider::DeleteMatch(const AutocompleteMatch& match) { + DCHECK(done_); + // Delete the match from the history DB. HistoryService* history_service = profile_ ? profile_->GetHistoryService(Profile::EXPLICIT_ACCESS) : @@ -94,15 +96,6 @@ void HistoryURLProvider::DeleteMatch(const AutocompleteMatch& match) { } DCHECK(found) << "Asked to delete a URL that isn't in our set of matches"; listener_->OnProviderUpdate(true); - - // Cancel any current pass 2 and rerun it, so we get correct history data. - if (!done_) { - // Copy params_->input to avoid a race condition where params_ gets deleted - // out from under us on the other thread after we set params_->cancel here. - AutocompleteInput input(params_->input); - params_->cancel = true; - RunAutocompletePasses(input, false); - } } // Called on the history thread. |