| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/instant/instant_controller.h" | 5 #include "chrome/browser/instant/instant_controller.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/i18n/case_conversion.h" | 8 #include "base/i18n/case_conversion.h" |
| 9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
| 10 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 } | 137 } |
| 138 | 138 |
| 139 // static | 139 // static |
| 140 bool InstantController::IsEnabled(Profile* profile) { | 140 bool InstantController::IsEnabled(Profile* profile) { |
| 141 const PrefService* prefs = profile ? profile->GetPrefs() : NULL; | 141 const PrefService* prefs = profile ? profile->GetPrefs() : NULL; |
| 142 return prefs && prefs->GetBoolean(prefs::kInstantEnabled); | 142 return prefs && prefs->GetBoolean(prefs::kInstantEnabled); |
| 143 } | 143 } |
| 144 | 144 |
| 145 bool InstantController::Update(const AutocompleteMatch& match, | 145 bool InstantController::Update(const AutocompleteMatch& match, |
| 146 const string16& user_text, | 146 const string16& user_text, |
| 147 bool verbatim, | 147 const string16& full_text, |
| 148 string16* suggested_text, | 148 bool verbatim) { |
| 149 InstantCompleteBehavior* complete_behavior) { | |
| 150 const TabContents* active_tab = delegate_->GetActiveTabContents(); | 149 const TabContents* active_tab = delegate_->GetActiveTabContents(); |
| 151 | 150 |
| 152 // We could get here with no active tab if the Browser is closing. | 151 // We could get here with no active tab if the Browser is closing. |
| 153 if (!active_tab) { | 152 if (!active_tab) { |
| 154 Hide(); | 153 Hide(); |
| 155 return false; | 154 return false; |
| 156 } | 155 } |
| 157 | 156 |
| 158 std::string instant_url; | 157 std::string instant_url; |
| 159 Profile* profile = active_tab->profile(); | 158 Profile* profile = active_tab->profile(); |
| 160 | 159 |
| 161 // If the match's TemplateURL isn't valid, it is likely not a query. | 160 // If the match's TemplateURL isn't valid, it is likely not a query. |
| 162 if (!GetInstantURL(match.GetTemplateURL(profile), &instant_url)) { | 161 if (!GetInstantURL(match.GetTemplateURL(profile), &instant_url)) { |
| 163 Hide(); | 162 Hide(); |
| 164 return false; | 163 return false; |
| 165 } | 164 } |
| 166 | 165 |
| 167 string16 full_text = user_text + *suggested_text; | |
| 168 | |
| 169 if (full_text.empty()) { | 166 if (full_text.empty()) { |
| 170 Hide(); | 167 Hide(); |
| 171 return false; | 168 return false; |
| 172 } | 169 } |
| 173 | 170 |
| 174 // The presence of any suggested_text implies verbatim. | |
| 175 DCHECK(suggested_text->empty() || verbatim) | |
| 176 << user_text << "|" << *suggested_text; | |
| 177 | |
| 178 ResetLoader(instant_url, active_tab); | 171 ResetLoader(instant_url, active_tab); |
| 179 last_active_tab_ = active_tab; | 172 last_active_tab_ = active_tab; |
| 180 | 173 |
| 181 // Track the non-Instant search URL for this query. | 174 // Track the non-Instant search URL for this query. |
| 182 url_for_history_ = match.destination_url; | 175 url_for_history_ = match.destination_url; |
| 183 last_transition_type_ = match.transition; | 176 last_transition_type_ = match.transition; |
| 184 | 177 |
| 178 // In EXTENDED mode, we send only |user_text| as the query text. In all other |
| 179 // modes, we use the entire |full_text|. |
| 180 const string16& query_text = mode_ == EXTENDED ? user_text : full_text; |
| 181 string16 last_query_text = |
| 182 mode_ == EXTENDED ? last_user_text_ : last_full_text_; |
| 185 last_user_text_ = user_text; | 183 last_user_text_ = user_text; |
| 184 last_full_text_ = full_text; |
| 186 | 185 |
| 187 // Don't send an update to the loader if the query text hasn't changed. | 186 // Don't send an update to the loader if the query text hasn't changed. |
| 188 if (full_text == last_full_text_ && verbatim == last_verbatim_) { | 187 if (query_text == last_query_text && verbatim == last_verbatim_) { |
| 189 // Since we are updating |suggested_text|, shouldn't we also update | 188 // Reuse the last suggestion, as it's still valid. |
| 190 // |last_full_text_|? No. There's no guarantee that our suggestion will | 189 delegate_->SetSuggestedText(last_suggestion_.text, |
| 191 // actually be inline autocompleted. For example, it may get trumped by | 190 last_suggestion_.behavior); |
| 192 // a history suggestion. If our suggestion does make it, the omnibox will | |
| 193 // call Update() again, at which time we'll update |last_full_text_|. | |
| 194 *suggested_text = last_suggestion_.text; | |
| 195 *complete_behavior = last_suggestion_.behavior; | |
| 196 | 191 |
| 197 // We need to call Show() here because of this: | 192 // We need to call Show() here because of this: |
| 198 // 1. User has typed a query (say Q). Instant overlay is showing results. | 193 // 1. User has typed a query (say Q). Instant overlay is showing results. |
| 199 // 2. User arrows-down to a URL entry or erases all omnibox text. Both of | 194 // 2. User arrows-down to a URL entry or erases all omnibox text. Both of |
| 200 // these cause the overlay to Hide(). | 195 // these cause the overlay to Hide(). |
| 201 // 3. User arrows-up to Q or types Q again. The last text we processed is | 196 // 3. User arrows-up to Q or types Q again. The last text we processed is |
| 202 // still Q, so we don't Update() the loader, but we do need to Show(). | 197 // still Q, so we don't Update() the loader, but we do need to Show(). |
| 203 if (loader_processed_last_update_ && | 198 if (loader_processed_last_update_ && |
| 204 (mode_ == INSTANT || mode_ == EXTENDED)) { | 199 (mode_ == INSTANT || mode_ == EXTENDED)) { |
| 205 Show(); | 200 Show(); |
| 206 } | 201 } |
| 207 return true; | 202 return true; |
| 208 } | 203 } |
| 209 | 204 |
| 210 last_full_text_ = full_text; | |
| 211 last_verbatim_ = verbatim; | 205 last_verbatim_ = verbatim; |
| 212 loader_processed_last_update_ = false; | 206 loader_processed_last_update_ = false; |
| 213 | |
| 214 // Reset the last suggestion, as it's no longer valid. | |
| 215 suggested_text->clear(); | |
| 216 last_suggestion_ = InstantSuggestion(); | 207 last_suggestion_ = InstantSuggestion(); |
| 217 *complete_behavior = INSTANT_COMPLETE_NOW; | |
| 218 | 208 |
| 219 if (mode_ != SILENT) { | 209 if (mode_ != SILENT) { |
| 220 loader_->Update(last_full_text_, last_verbatim_); | 210 loader_->Update(query_text, verbatim); |
| 221 | 211 |
| 222 content::NotificationService::current()->Notify( | 212 content::NotificationService::current()->Notify( |
| 223 chrome::NOTIFICATION_INSTANT_CONTROLLER_UPDATED, | 213 chrome::NOTIFICATION_INSTANT_CONTROLLER_UPDATED, |
| 224 content::Source<InstantController>(this), | 214 content::Source<InstantController>(this), |
| 225 content::NotificationService::NoDetails()); | 215 content::NotificationService::NoDetails()); |
| 226 } | 216 } |
| 227 | 217 |
| 218 // We don't have suggestions yet, but need to reset any existing "gray text". |
| 219 delegate_->SetSuggestedText(string16(), INSTANT_COMPLETE_NOW); |
| 220 |
| 228 return true; | 221 return true; |
| 229 } | 222 } |
| 230 | 223 |
| 231 // TODO(tonyg): This method only fires when the omnibox bounds change. It also | 224 // TODO(tonyg): This method only fires when the omnibox bounds change. It also |
| 232 // needs to fire when the preview bounds change (e.g.: open/close info bar). | 225 // needs to fire when the preview bounds change (e.g.: open/close info bar). |
| 233 void InstantController::SetOmniboxBounds(const gfx::Rect& bounds) { | 226 void InstantController::SetOmniboxBounds(const gfx::Rect& bounds) { |
| 234 if (omnibox_bounds_ == bounds || (mode_ != INSTANT && mode_ != EXTENDED)) | 227 if (omnibox_bounds_ == bounds || (mode_ != INSTANT && mode_ != EXTENDED)) |
| 235 return; | 228 return; |
| 236 | 229 |
| 237 omnibox_bounds_ = bounds; | 230 omnibox_bounds_ = bounds; |
| (...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 648 return false; | 641 return false; |
| 649 } | 642 } |
| 650 | 643 |
| 651 return true; | 644 return true; |
| 652 } | 645 } |
| 653 | 646 |
| 654 bool InstantController::IsOutOfDate() const { | 647 bool InstantController::IsOutOfDate() const { |
| 655 return !last_active_tab_ || | 648 return !last_active_tab_ || |
| 656 last_active_tab_ != delegate_->GetActiveTabContents(); | 649 last_active_tab_ != delegate_->GetActiveTabContents(); |
| 657 } | 650 } |
| OLD | NEW |