Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 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/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
| 9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
| 10 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
| 11 #include "chrome/browser/autocomplete/autocomplete_provider.h" | 11 #include "chrome/browser/autocomplete/autocomplete_provider.h" |
| 12 #include "chrome/browser/google/google_util.h" | 12 #include "chrome/browser/google/google_util.h" |
| 13 #include "chrome/browser/history/history.h" | 13 #include "chrome/browser/history/history.h" |
| 14 #include "chrome/browser/history/history_service_factory.h" | 14 #include "chrome/browser/history/history_service_factory.h" |
| 15 #include "chrome/browser/history/history_tab_helper.h" | 15 #include "chrome/browser/history/history_tab_helper.h" |
| 16 #include "chrome/browser/instant/instant_loader.h" | 16 #include "chrome/browser/instant/instant_loader.h" |
| 17 #include "chrome/browser/instant/instant_tab.h" | |
| 17 #include "chrome/browser/platform_util.h" | 18 #include "chrome/browser/platform_util.h" |
| 18 #include "chrome/browser/search_engines/template_url_service.h" | 19 #include "chrome/browser/search_engines/template_url_service.h" |
| 19 #include "chrome/browser/search_engines/template_url_service_factory.h" | 20 #include "chrome/browser/search_engines/template_url_service_factory.h" |
| 20 #include "chrome/browser/ui/browser_instant_controller.h" | 21 #include "chrome/browser/ui/browser_instant_controller.h" |
| 21 #include "chrome/browser/ui/search/search_tab_helper.h" | 22 #include "chrome/browser/ui/search/search_tab_helper.h" |
| 22 #include "chrome/browser/ui/tab_contents/tab_contents.h" | |
| 23 #include "chrome/common/chrome_notification_types.h" | 23 #include "chrome/common/chrome_notification_types.h" |
| 24 #include "chrome/common/chrome_switches.h" | 24 #include "chrome/common/chrome_switches.h" |
| 25 #include "content/public/browser/navigation_entry.h" | 25 #include "content/public/browser/navigation_entry.h" |
| 26 #include "content/public/browser/notification_service.h" | 26 #include "content/public/browser/notification_service.h" |
| 27 #include "content/public/browser/render_widget_host_view.h" | 27 #include "content/public/browser/render_widget_host_view.h" |
| 28 #include "net/base/escape.h" | 28 #include "net/base/escape.h" |
| 29 #include "unicode/normalizer2.h" | 29 #include "unicode/normalizer2.h" |
| 30 | 30 |
| 31 #if defined(TOOLKIT_VIEWS) | 31 #if defined(TOOLKIT_VIEWS) |
| 32 #include "ui/views/widget/widget.h" | 32 #include "ui/views/widget/widget.h" |
| 33 #endif | 33 #endif |
| 34 | 34 |
| 35 namespace { | 35 namespace { |
| 36 | 36 |
| 37 // An artificial delay (in milliseconds) we introduce before telling the Instant | 37 // An artificial delay (in milliseconds) we introduce before telling the Instant |
| 38 // page about the new omnibox bounds, in cases where the bounds shrink. This is | 38 // page about the new omnibox bounds, in cases where the bounds shrink. This is |
| 39 // to avoid the page jumping up/down very fast in response to bounds changes. | 39 // to avoid the page jumping up/down very fast in response to bounds changes. |
| 40 const int kUpdateBoundsDelayMS = 1000; | 40 const int kUpdateBoundsDelayMS = 1000; |
| 41 | 41 |
| 42 // The maximum number of times we'll load a non-Instant-supporting search engine | 42 // The maximum number of times we'll load a non-Instant-supporting search engine |
| 43 // before we give up and blacklist it for the rest of the browsing session. | 43 // before we give up and blacklist it for the rest of the browsing session. |
| 44 const int kMaxInstantSupportFailures = 10; | 44 const int kMaxInstantSupportFailures = 10; |
| 45 | 45 |
| 46 // If an Instant page has not been used in these many milliseconds, it is | 46 // If an Instant page has not been used in these many milliseconds, it is |
| 47 // reloaded so that the page does not become stale. | 47 // reloaded so that the page does not become stale. |
| 48 const int kStaleLoaderTimeoutMS = 3 * 3600 * 1000; | 48 const int kStaleLoaderTimeoutMS = 3 * 3600 * 1000; |
| 49 | 49 |
| 50 void AddSessionStorageHistogram(bool extended_enabled, | 50 void AddSessionStorageHistogram(bool extended_enabled, |
| 51 const TabContents* tab1, | 51 const content::WebContents* tab1, |
| 52 const TabContents* tab2) { | 52 const content::WebContents* tab2) { |
| 53 base::Histogram* histogram = base::BooleanHistogram::FactoryGet( | 53 base::Histogram* histogram = base::BooleanHistogram::FactoryGet( |
| 54 std::string("Instant.SessionStorageNamespace") + | 54 std::string("Instant.SessionStorageNamespace") + |
| 55 (extended_enabled ? "_Extended" : "_Instant"), | 55 (extended_enabled ? "_Extended" : "_Instant"), |
| 56 base::Histogram::kUmaTargetedHistogramFlag); | 56 base::Histogram::kUmaTargetedHistogramFlag); |
| 57 const content::SessionStorageNamespaceMap& session_storage_map1 = | 57 const content::SessionStorageNamespaceMap& session_storage_map1 = |
| 58 tab1->web_contents()->GetController().GetSessionStorageNamespaceMap(); | 58 tab1->GetController().GetSessionStorageNamespaceMap(); |
| 59 const content::SessionStorageNamespaceMap& session_storage_map2 = | 59 const content::SessionStorageNamespaceMap& session_storage_map2 = |
| 60 tab2->web_contents()->GetController().GetSessionStorageNamespaceMap(); | 60 tab2->GetController().GetSessionStorageNamespaceMap(); |
| 61 bool is_session_storage_the_same = | 61 bool is_session_storage_the_same = |
| 62 session_storage_map1.size() == session_storage_map2.size(); | 62 session_storage_map1.size() == session_storage_map2.size(); |
| 63 if (is_session_storage_the_same) { | 63 if (is_session_storage_the_same) { |
| 64 // The size is the same, so let's check that all entries match. | 64 // The size is the same, so let's check that all entries match. |
| 65 for (content::SessionStorageNamespaceMap::const_iterator | 65 for (content::SessionStorageNamespaceMap::const_iterator |
| 66 it1 = session_storage_map1.begin(), | 66 it1 = session_storage_map1.begin(), |
| 67 it2 = session_storage_map2.begin(); | 67 it2 = session_storage_map2.begin(); |
| 68 it1 != session_storage_map1.end() && it2 != session_storage_map2.end(); | 68 it1 != session_storage_map1.end() && it2 != session_storage_map2.end(); |
| 69 ++it1, ++it2) { | 69 ++it1, ++it2) { |
| 70 if (it1->first != it2->first || it1->second != it2->second) { | 70 if (it1->first != it2->first || it1->second != it2->second) { |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 83 if (normalizer == NULL || U_FAILURE(status)) | 83 if (normalizer == NULL || U_FAILURE(status)) |
| 84 return str; | 84 return str; |
| 85 icu::UnicodeString norm_str(normalizer->normalize( | 85 icu::UnicodeString norm_str(normalizer->normalize( |
| 86 icu::UnicodeString(FALSE, str.c_str(), str.size()), status)); | 86 icu::UnicodeString(FALSE, str.c_str(), str.size()), status)); |
| 87 if (U_FAILURE(status)) | 87 if (U_FAILURE(status)) |
| 88 return str; | 88 return str; |
| 89 return string16(norm_str.getBuffer(), norm_str.length()); | 89 return string16(norm_str.getBuffer(), norm_str.length()); |
| 90 } | 90 } |
| 91 | 91 |
| 92 bool NormalizeAndStripPrefix(string16* text, const string16& prefix) { | 92 bool NormalizeAndStripPrefix(string16* text, const string16& prefix) { |
| 93 const string16 norm_prefix = Normalize(prefix); | 93 string16 norm_prefix = Normalize(prefix); |
|
samarth
2012/12/03 19:46:03
FWIW, I find this kind of const usage useful (as o
sreeram
2012/12/04 08:10:52
Ack. I do vacillate between too much and too littl
| |
| 94 string16 norm_text = Normalize(*text); | 94 string16 norm_text = Normalize(*text); |
| 95 if (norm_prefix.size() <= norm_text.size() && | 95 if (norm_prefix.size() <= norm_text.size() && |
| 96 norm_text.compare(0, norm_prefix.size(), norm_prefix) == 0) { | 96 norm_text.compare(0, norm_prefix.size(), norm_prefix) == 0) { |
| 97 *text = norm_text.erase(0, norm_prefix.size()); | 97 *text = norm_text.erase(0, norm_prefix.size()); |
| 98 return true; | 98 return true; |
| 99 } | 99 } |
| 100 return false; | 100 return false; |
| 101 } | 101 } |
| 102 | 102 |
| 103 // For TOOLKIT_VIEWS, the top level widget is always focused. If the focus | 103 // For TOOLKIT_VIEWS, the top level widget is always focused. If the focus |
| 104 // change originated in views determine the child Widget from the view that is | 104 // change originated in views determine the child Widget from the view that is |
| 105 // being focused. | 105 // being focused. |
| 106 gfx::NativeView GetViewGainingFocus(gfx::NativeView view_gaining_focus) { | 106 gfx::NativeView GetViewGainingFocus(gfx::NativeView view_gaining_focus) { |
| 107 #if defined(TOOLKIT_VIEWS) | 107 #if defined(TOOLKIT_VIEWS) |
| 108 views::Widget* widget = view_gaining_focus ? | 108 views::Widget* widget = view_gaining_focus ? |
| 109 views::Widget::GetWidgetForNativeView(view_gaining_focus) : NULL; | 109 views::Widget::GetWidgetForNativeView(view_gaining_focus) : NULL; |
| 110 if (widget) { | 110 if (widget) { |
| 111 views::FocusManager* focus_manager = widget->GetFocusManager(); | 111 views::FocusManager* focus_manager = widget->GetFocusManager(); |
| 112 if (focus_manager && focus_manager->is_changing_focus() && | 112 if (focus_manager && focus_manager->is_changing_focus() && |
| 113 focus_manager->GetFocusedView() && | 113 focus_manager->GetFocusedView() && |
| 114 focus_manager->GetFocusedView()->GetWidget()) { | 114 focus_manager->GetFocusedView()->GetWidget()) |
| 115 return focus_manager->GetFocusedView()->GetWidget()->GetNativeView(); | 115 return focus_manager->GetFocusedView()->GetWidget()->GetNativeView(); |
| 116 } | |
| 117 } | 116 } |
| 118 #endif | 117 #endif |
| 119 return view_gaining_focus; | 118 return view_gaining_focus; |
| 120 } | 119 } |
| 121 | 120 |
| 122 // Returns true if |view| is the top-level contents view or a child view in the | 121 // Returns true if |view| is the top-level contents view or a child view in the |
| 123 // view hierarchy of |contents|. | 122 // view hierarchy of |contents|. |
| 124 bool IsViewInContents(gfx::NativeView view, content::WebContents* contents) { | 123 bool IsViewInContents(gfx::NativeView view, content::WebContents* contents) { |
| 125 content::RenderWidgetHostView* rwhv = contents->GetRenderWidgetHostView(); | 124 content::RenderWidgetHostView* rwhv = contents->GetRenderWidgetHostView(); |
| 126 if (!view || !rwhv) | 125 if (!view || !rwhv) |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 154 last_match_was_search_(false), | 153 last_match_was_search_(false), |
| 155 is_omnibox_focused_(false) { | 154 is_omnibox_focused_(false) { |
| 156 } | 155 } |
| 157 | 156 |
| 158 InstantController::~InstantController() { | 157 InstantController::~InstantController() { |
| 159 } | 158 } |
| 160 | 159 |
| 161 bool InstantController::Update(const AutocompleteMatch& match, | 160 bool InstantController::Update(const AutocompleteMatch& match, |
| 162 const string16& user_text, | 161 const string16& user_text, |
| 163 const string16& full_text, | 162 const string16& full_text, |
| 164 const bool verbatim, | 163 bool verbatim, |
| 165 const bool user_input_in_progress, | 164 bool user_input_in_progress, |
| 166 const bool omnibox_popup_is_open) { | 165 bool omnibox_popup_is_open) { |
| 167 if (!extended_enabled_ && !instant_enabled_) | 166 if (!extended_enabled_ && !instant_enabled_) |
| 168 return false; | 167 return false; |
| 169 | 168 |
| 170 DVLOG(1) << "Update: " << AutocompleteMatch::TypeToString(match.type) | 169 DVLOG(1) << "Update: " << AutocompleteMatch::TypeToString(match.type) |
| 171 << " user_text='" << user_text << "' full_text='" << full_text << "'" | 170 << " user_text='" << user_text << "' full_text='" << full_text << "'" |
| 172 << " verbatim=" << verbatim << " typing=" << user_input_in_progress | 171 << " verbatim=" << verbatim << " typing=" << user_input_in_progress |
| 173 << " popup=" << omnibox_popup_is_open; | 172 << " popup=" << omnibox_popup_is_open; |
| 174 | 173 |
| 175 // If the popup is open, the user has to be typing. | 174 // If the popup is open, the user has to be typing. |
| 176 DCHECK(!omnibox_popup_is_open || user_input_in_progress); | 175 DCHECK(!omnibox_popup_is_open || user_input_in_progress); |
| 177 | 176 |
| 178 // If the popup is closed, there should be no inline autocompletion. | 177 // If the popup is closed, there should be no inline autocompletion. |
| 179 DCHECK(omnibox_popup_is_open || user_text == full_text) << user_text << "|" | 178 DCHECK(omnibox_popup_is_open || user_text.empty() || user_text == full_text) |
| 180 << full_text; | 179 << user_text << "|" << full_text; |
| 181 | 180 |
| 182 // If there's inline autocompletion, the query has to be verbatim. | 181 // If there's inline autocompletion, the query has to be verbatim. |
| 183 DCHECK(user_text == full_text || verbatim) << user_text << "|" << full_text; | 182 DCHECK(user_text.empty() || user_text == full_text || verbatim) |
| 183 << user_text << "|" << full_text; | |
| 184 | 184 |
| 185 // If there's no text in the omnibox, the user can't have typed any. | 185 // If there's no text in the omnibox, the user can't have typed any. |
| 186 DCHECK(!full_text.empty() || user_text.empty()) << user_text; | 186 DCHECK(!full_text.empty() || user_text.empty()) << user_text; |
| 187 | 187 |
| 188 // If the user isn't typing, and the popup is closed, there can't be any | 188 // If the user isn't typing, and the popup is closed, there can't be any |
| 189 // user-typed text. | 189 // user-typed text. |
| 190 DCHECK(user_input_in_progress || omnibox_popup_is_open || user_text.empty()) | 190 DCHECK(user_input_in_progress || omnibox_popup_is_open || user_text.empty()) |
| 191 << user_text; | 191 << user_text; |
| 192 | 192 |
| 193 // In non-extended mode, SearchModeChanged() is never called, so fake it. The | 193 // In non-extended mode, SearchModeChanged() is never called, so fake it. The |
| 194 // mode is set to "disallow suggestions" here, so that if one of the early | 194 // mode is set to "disallow suggestions" here, so that if one of the early |
| 195 // "return false" conditions is hit, suggestions will be disallowed. If the | 195 // "return false" conditions is hit, suggestions will be disallowed. If the |
| 196 // query is sent to the loader, the mode is set to "allow" further below. | 196 // query is sent to the loader, the mode is set to "allow" further below. |
| 197 if (!extended_enabled_) | 197 if (!extended_enabled_) |
| 198 search_mode_.mode = chrome::search::Mode::MODE_DEFAULT; | 198 search_mode_.mode = chrome::search::Mode::MODE_DEFAULT; |
| 199 | 199 |
| 200 // If there's no active tab, the browser is closing. | 200 // If there's no active tab, the browser is closing. |
| 201 const TabContents* const active_tab = browser_->GetActiveTabContents(); | 201 const content::WebContents* active_tab = browser_->GetActiveWebContents(); |
| 202 if (!active_tab) { | 202 if (!active_tab) { |
| 203 Hide(true); | 203 Hide(); |
| 204 return false; | 204 return false; |
| 205 } | 205 } |
| 206 | 206 |
| 207 const TemplateURL* template_url = match.GetTemplateURL( | |
| 208 Profile::FromBrowserContext(active_tab->GetBrowserContext()), false); | |
| 209 bool match_is_search = AutocompleteMatch::IsSearchType(match.type); | |
| 210 | |
| 211 // Ensure we have a loader or tab that can process this |match|. | |
| 212 if (extended_enabled_) { | |
| 213 // In extended mode, use the first among the following that succeeds: | |
| 214 // 1. A committed search results page. | |
| 215 // 2. An Instant loader for |template_url|. | |
| 216 // 3. If the |match| is a URL or a blank search query, the Instant loader | |
| 217 // for the default search engine. | |
| 218 // TODO(sreeram): If |template_url| doesn't match the |instant_tab_| URL, | |
| 219 // we shouldn't blindly use the committed tab. | |
| 220 if (!instant_tab_ && !ResetLoader(template_url, active_tab) && | |
| 221 ((match_is_search && !user_text.empty()) || !CreateDefaultLoader())) { | |
|
Jered
2012/11/29 19:57:05
Should this check full_text.empty() as it used to?
Jered
2012/11/29 19:57:05
It took me a second to unwind this if. Maybe
bool
sreeram
2012/12/04 08:10:52
No, user_text is the right thing here. If we are i
sreeram
2012/12/04 08:10:52
Done.
| |
| 222 Hide(); | |
| 223 return false; | |
| 224 } | |
| 225 } else if (!ResetLoader(template_url, active_tab)) { | |
| 226 // In non-extended mode, if the TemplateURL of the |match| doesn't have a | |
| 227 // valid Instant URL, do not proceed. | |
| 228 Hide(); | |
| 229 return false; | |
| 230 } | |
| 231 | |
| 207 // Legend: OPIO == |omnibox_popup_is_open|, UIIP = |user_input_in_progress|. | 232 // Legend: OPIO == |omnibox_popup_is_open|, UIIP = |user_input_in_progress|. |
|
Jered
2012/11/29 19:57:05
I'd love to extract everything from this table dow
sreeram
2012/12/04 08:10:52
I've removed the table and made the section much b
| |
| 208 // | 233 // |
| 209 // # OPIO UIIP full_text Notes | 234 // # OPIO UIIP full_text Notes |
| 210 // - ---- ---- --------- ----- | 235 // - ---- ---- --------- ----- |
| 211 // 1 no no blank } Navigation, or user hit Escape. |full_text| is | 236 // 1 no no blank } Navigation, tab-switch or Escape. |full_text| is |
| 212 // 2 no no non-blank } blank if the page is NTP, non-blank otherwise. | 237 // 2 no no non-blank } blank if the page is NTP, non-blank otherwise. |
| 213 // | 238 // |
| 214 // 3 no yes blank User backspaced away all omnibox text. | 239 // 3 no yes blank User backspaced away all omnibox text. |
| 215 // | 240 // |
| 216 // 4 no yes non-blank User switched to a tab with a partial query. | 241 // 4 no yes non-blank User switched to a tab with a partial query. |
| 217 // | 242 // |
| 218 // 5 yes no blank } Impossible. DCHECK()ed above. | 243 // 5 yes no blank } Impossible. DCHECK()ed above. |
| 219 // 6 yes no non-blank } | 244 // 6 yes no non-blank } |
| 220 // | 245 // |
| 221 // 7 yes yes blank User typed a "?" into the omnibox. | 246 // 7 yes yes blank User typed a "?" into the omnibox. |
| 222 // | 247 // |
| 223 // 8 yes yes non-blank User typed text into the omnibox. | 248 // 8 yes yes non-blank User typed text into the omnibox. |
| 224 // | 249 // |
| 225 // In non-extended mode, #1 to #7 call Hide(). #8 calls loader_->Update(). | 250 // In non-extended mode, #1 to #7 call Hide(). #8 calls loader_->Update(). |
| 226 // | 251 // |
| 227 // In extended mode, #2 and #4 call Hide(). #1 doesn't Hide() as the preview | 252 // In extended mode, #2 and #4 call Hide(). #1 doesn't Hide() as the preview |
| 228 // may be showing custom NTP content, but doesn't Update() either. #3 and #7 | 253 // may be showing custom NTP content, but doesn't Update() either. #3 and #7 |
| 229 // don't Hide(), but send a blank query to Update(). #8 calls Update(). | 254 // don't Hide(), and send a blank query to Update(). #8 calls Update(). |
| 230 | 255 |
| 231 if (extended_enabled_) { | 256 if (extended_enabled_) { |
| 232 if (!omnibox_popup_is_open) { | 257 if (!omnibox_popup_is_open) { |
| 233 if (!full_text.empty()) { | 258 if (!user_input_in_progress) { |
| 234 Hide(true); | 259 if (!full_text.empty()) { |
| 235 return false; | 260 Hide(); // #2 |
| 261 // If the user hit Escape when on a search results page, restore the | |
| 262 // original results by resending the query. If the user was not on a | |
|
Jered
2012/11/29 19:57:05
What "original" results? Do you mean the committed
sreeram
2012/12/04 08:10:52
I've tried to explain this better in the new patch
| |
| 263 // search results page, SearchModeChanged() would've caught it, and | |
| 264 // |instant_tab_| will be NULL, so we won't accidentally send a URL | |
| 265 // to |instant_tab_|. Except if the user just switched tabs. Hence the | |
| 266 // comparison of WebContents, to catch that case as well. | |
| 267 if (instant_tab_ && instant_tab_->contents() == active_tab) | |
| 268 instant_tab_->Update(full_text, true); | |
| 269 } | |
| 270 return false; // #1 | |
|
Jered
2012/11/29 19:57:05
Note this is both #1 and #2.
sreeram
2012/12/04 08:10:52
Ack. See new patch.
| |
| 271 } else { | |
| 272 if (!full_text.empty()) { | |
| 273 Hide(); // #4 | |
| 274 if (match_is_search) { | |
| 275 // The user just switched to a tab with a partial query already in | |
| 276 // the omnibox. This tab may or may not be a search results page | |
| 277 // (SearchModeChanged() hasn't been called yet). So, assume that it | |
| 278 // could be, and store |full_text| so that if the user then hits | |
| 279 // Enter, we'll send the correct query in instant_tab_->Submit(). | |
| 280 last_full_text_ = full_text; | |
| 281 last_match_was_search_ = true; | |
| 282 } | |
| 283 return false; | |
| 284 } | |
| 236 } | 285 } |
| 237 if (!user_input_in_progress && full_text.empty()) | |
| 238 return false; | |
| 239 } | 286 } |
| 240 } else if (!omnibox_popup_is_open || full_text.empty()) { | 287 } else if (!omnibox_popup_is_open || full_text.empty()) { |
| 241 // Update() can be called if the user clicks the preview while composing | 288 // Update() can be called if the user clicks the preview while composing |
| 242 // text with an IME. If so, we should commit on mouse up, so don't Hide(). | 289 // text with an IME. If so, we should commit on mouse up, so don't Hide(). |
| 243 if (!GetPreviewContents() || !loader_->IsPointerDownFromActivate()) | 290 if (!loader_ || !loader_->is_pointer_down_from_activate()) |
| 244 Hide(true); | 291 Hide(); |
| 245 return false; | 292 return false; |
| 246 } | 293 } |
| 247 | 294 |
| 248 // Ensure we have a loader that can process this match. First, try to use the | |
| 249 // TemplateURL of the |match|. If that's invalid, in non-extended mode, stop. | |
| 250 // In extended mode, try using the default search engine, but only when the | |
| 251 // match is for a URL (i.e., not some other kind of non-Instant search). | |
| 252 // A completely blank query shows up as a search, and we do want to allow | |
| 253 // that, hence the "!full_text.empty()" clause. | |
| 254 Profile* const profile = active_tab->profile(); | |
| 255 const bool match_is_search = AutocompleteMatch::IsSearchType(match.type); | |
| 256 if (!ResetLoader(match.GetTemplateURL(profile, false), active_tab) && | |
| 257 (!extended_enabled_ || (match_is_search && !full_text.empty()) || | |
| 258 !CreateDefaultLoader())) { | |
| 259 Hide(true); | |
| 260 return false; | |
| 261 } | |
| 262 | |
| 263 // If the user continues typing the same query as the suggested text is | 295 // If the user continues typing the same query as the suggested text is |
| 264 // showing, reuse the suggestion (but only for INSTANT_COMPLETE_NEVER). | 296 // showing, reuse the suggestion (but only for INSTANT_COMPLETE_NEVER). |
| 265 bool reused_suggestion = false; | 297 bool reused_suggestion = false; |
| 266 if (last_suggestion_.behavior == INSTANT_COMPLETE_NEVER) { | 298 if (last_suggestion_.behavior == INSTANT_COMPLETE_NEVER) { |
| 267 if (StartsWith(last_user_text_, user_text, false) && !user_text.empty()) { | 299 if (StartsWith(last_user_text_, user_text, false) && !user_text.empty()) { |
| 268 // The user is backspacing away characters. | 300 // The user is backspacing away characters. |
| 269 last_suggestion_.text.insert(0, last_user_text_, user_text.size(), | 301 last_suggestion_.text.insert(0, last_user_text_, user_text.size(), |
| 270 last_user_text_.size() - user_text.size()); | 302 last_user_text_.size() - user_text.size()); |
| 271 reused_suggestion = true; | 303 reused_suggestion = true; |
| 272 } else if (StartsWith(user_text, last_user_text_, false)) { | 304 } else if (StartsWith(user_text, last_user_text_, false)) { |
| 273 // The user is typing forward. Normalize any added characters. | 305 // The user is typing forward. Normalize any added characters. |
| 274 reused_suggestion = NormalizeAndStripPrefix(&last_suggestion_.text, | 306 reused_suggestion = NormalizeAndStripPrefix(&last_suggestion_.text, |
| 275 string16(user_text, last_user_text_.size())); | 307 string16(user_text, last_user_text_.size())); |
| 276 } | 308 } |
| 277 } | 309 } |
| 278 | 310 |
| 279 last_user_text_ = user_text; | 311 last_user_text_ = user_text; |
| 280 last_full_text_ = full_text; | 312 last_full_text_ = full_text; |
| 281 last_verbatim_ = verbatim; | 313 last_verbatim_ = verbatim; |
| 282 | 314 |
| 283 if (!reused_suggestion) | 315 if (!reused_suggestion) |
| 284 last_suggestion_ = InstantSuggestion(); | 316 last_suggestion_ = InstantSuggestion(); |
| 285 | 317 |
| 286 last_transition_type_ = match.transition; | 318 last_transition_type_ = match.transition; |
| 287 last_match_was_search_ = match_is_search; | 319 last_match_was_search_ = match_is_search; |
| 288 url_for_history_ = match.destination_url; | 320 url_for_history_ = match.destination_url; |
| 289 | 321 |
| 290 // Store the first interaction time for use with latency histograms. | 322 // Store the first interaction time for use with latency histograms (but only |
| 291 if (first_interaction_time_.is_null()) | 323 // if we are talking to the |loader_| and not a committed tab). |
| 324 if (!instant_tab_ && first_interaction_time_.is_null()) | |
| 292 first_interaction_time_ = base::Time::Now(); | 325 first_interaction_time_ = base::Time::Now(); |
| 293 | 326 |
| 294 // Allow search suggestions. In extended mode, SearchModeChanged() will set | 327 // Allow search suggestions. In extended mode, SearchModeChanged() will set |
| 295 // this, but it's not called in non-extended mode, so fake it. | 328 // this, but it's not called in non-extended mode, so fake it. |
| 296 if (!extended_enabled_) | 329 if (!extended_enabled_) |
| 297 search_mode_.mode = chrome::search::Mode::MODE_SEARCH_SUGGESTIONS; | 330 search_mode_.mode = chrome::search::Mode::MODE_SEARCH_SUGGESTIONS; |
| 298 | 331 |
| 299 loader_->Update(extended_enabled_ ? user_text : full_text, verbatim); | 332 if (instant_tab_) |
| 333 instant_tab_->Update(user_text, verbatim); | |
| 334 else | |
| 335 loader_->Update(extended_enabled_ ? user_text : full_text, verbatim); | |
| 300 | 336 |
| 301 content::NotificationService::current()->Notify( | 337 content::NotificationService::current()->Notify( |
| 302 chrome::NOTIFICATION_INSTANT_CONTROLLER_UPDATED, | 338 chrome::NOTIFICATION_INSTANT_CONTROLLER_UPDATED, |
| 303 content::Source<InstantController>(this), | 339 content::Source<InstantController>(this), |
| 304 content::NotificationService::NoDetails()); | 340 content::NotificationService::NoDetails()); |
| 305 | 341 |
| 306 // We don't have new suggestions yet, but we can either reuse the existing | 342 // We don't have new suggestions yet, but we can either reuse the existing |
| 307 // suggestion or reset the existing "gray text". | 343 // suggestion or reset the existing "gray text". |
| 308 browser_->SetInstantSuggestion(last_suggestion_); | 344 browser_->SetInstantSuggestion(last_suggestion_); |
| 309 | 345 |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 331 base::TimeDelta::FromMilliseconds(kUpdateBoundsDelayMS), this, | 367 base::TimeDelta::FromMilliseconds(kUpdateBoundsDelayMS), this, |
| 332 &InstantController::SendBoundsToPage); | 368 &InstantController::SendBoundsToPage); |
| 333 } | 369 } |
| 334 } | 370 } |
| 335 | 371 |
| 336 void InstantController::HandleAutocompleteResults( | 372 void InstantController::HandleAutocompleteResults( |
| 337 const std::vector<AutocompleteProvider*>& providers) { | 373 const std::vector<AutocompleteProvider*>& providers) { |
| 338 if (!extended_enabled_) | 374 if (!extended_enabled_) |
| 339 return; | 375 return; |
| 340 | 376 |
| 341 if (!GetPreviewContents()) | 377 if (!instant_tab_ && !loader_) |
| 342 return; | 378 return; |
| 343 | 379 |
| 344 DVLOG(1) << "AutocompleteResults:"; | 380 DVLOG(1) << "AutocompleteResults:"; |
| 345 std::vector<InstantAutocompleteResult> results; | 381 std::vector<InstantAutocompleteResult> results; |
| 346 for (ACProviders::const_iterator provider = providers.begin(); | 382 for (ACProviders::const_iterator provider = providers.begin(); |
| 347 provider != providers.end(); ++provider) { | 383 provider != providers.end(); ++provider) { |
| 348 for (ACMatches::const_iterator match = (*provider)->matches().begin(); | 384 for (ACMatches::const_iterator match = (*provider)->matches().begin(); |
| 349 match != (*provider)->matches().end(); ++match) { | 385 match != (*provider)->matches().end(); ++match) { |
| 350 InstantAutocompleteResult result; | 386 InstantAutocompleteResult result; |
| 351 result.provider = UTF8ToUTF16((*provider)->GetName()); | 387 result.provider = UTF8ToUTF16((*provider)->GetName()); |
| 352 result.type = UTF8ToUTF16(AutocompleteMatch::TypeToString(match->type)); | 388 result.type = UTF8ToUTF16(AutocompleteMatch::TypeToString(match->type)); |
| 353 result.description = match->description; | 389 result.description = match->description; |
| 354 result.destination_url = UTF8ToUTF16(match->destination_url.spec()); | 390 result.destination_url = UTF8ToUTF16(match->destination_url.spec()); |
| 355 result.relevance = match->relevance; | 391 result.relevance = match->relevance; |
| 356 DVLOG(1) << " " << result.relevance << " " << result.type << " " | 392 DVLOG(1) << " " << result.relevance << " " << result.type << " " |
| 357 << result.provider << " " << result.destination_url << " '" | 393 << result.provider << " " << result.destination_url << " '" |
| 358 << result.description << "'"; | 394 << result.description << "'"; |
| 359 results.push_back(result); | 395 results.push_back(result); |
| 360 } | 396 } |
| 361 } | 397 } |
| 362 | 398 |
| 363 loader_->SendAutocompleteResults(results); | 399 if (instant_tab_) |
| 400 instant_tab_->SendAutocompleteResults(results); | |
| 401 else | |
| 402 loader_->SendAutocompleteResults(results); | |
| 364 } | 403 } |
| 365 | 404 |
| 366 bool InstantController::OnUpOrDownKeyPressed(int count) { | 405 bool InstantController::OnUpOrDownKeyPressed(int count) { |
| 367 if (!extended_enabled_) | 406 if (!extended_enabled_) |
| 368 return false; | 407 return false; |
| 369 | 408 |
| 370 if (!GetPreviewContents()) | 409 if (!instant_tab_ && !loader_) |
| 371 return false; | 410 return false; |
| 372 | 411 |
| 373 loader_->OnUpOrDownKeyPressed(count); | 412 if (instant_tab_) |
| 374 return true; | 413 instant_tab_->UpOrDownKeyPressed(count); |
| 414 else | |
| 415 loader_->UpOrDownKeyPressed(count); | |
| 416 | |
| 417 return false; | |
|
Jered
2012/11/29 19:57:05
Should this be return true;?
sreeram
2012/12/04 08:10:52
Indeed. Done. ('Twas a typo.)
| |
| 375 } | 418 } |
| 376 | 419 |
| 377 TabContents* InstantController::GetPreviewContents() const { | 420 content::WebContents* InstantController::GetPreviewContents() const { |
| 378 return loader_ ? loader_->preview_contents() : NULL; | 421 return loader_ ? loader_->contents() : NULL; |
| 379 } | 422 } |
| 380 | 423 |
| 381 bool InstantController::IsCurrent() const { | 424 bool InstantController::IsCurrent() const { |
| 382 return model_.mode().is_search_suggestions() && last_match_was_search_; | 425 return model_.mode().is_search_suggestions() && last_match_was_search_; |
| 383 } | 426 } |
| 384 | 427 |
| 385 bool InstantController::CommitIfCurrent(InstantCommitType type) { | 428 bool InstantController::CommitIfCurrent(InstantCommitType type) { |
| 386 if (!extended_enabled_ && !instant_enabled_) | 429 if (!extended_enabled_ && !instant_enabled_) |
| 387 return false; | 430 return false; |
| 388 | 431 |
| 432 // If we are on a committed search results page, send a submit event to the | |
| 433 // page, but otherwise, nothing else to do. | |
|
Jered
2012/11/29 19:57:05
From the "nothing else to do" part, I would expect
sreeram
2012/12/04 08:10:52
Done. It worked the way it was before, since IsCur
| |
| 434 if (instant_tab_ && last_match_was_search_ && | |
| 435 type == INSTANT_COMMIT_PRESSED_ENTER) { | |
| 436 instant_tab_->Submit(last_full_text_); | |
| 437 return true; | |
| 438 } | |
| 439 | |
| 389 if (!IsCurrent()) | 440 if (!IsCurrent()) |
| 390 return false; | 441 return false; |
| 391 | 442 |
| 392 DVLOG(1) << "CommitIfCurrent"; | 443 DVLOG(1) << "CommitIfCurrent"; |
| 393 TabContents* preview = loader_->ReleasePreviewContents(type, last_full_text_); | 444 |
| 445 if (type == INSTANT_COMMIT_FOCUS_LOST) | |
| 446 loader_->Cancel(last_full_text_); | |
| 447 else | |
| 448 loader_->Submit(last_full_text_); | |
| 449 | |
| 450 content::WebContents* preview = loader_->ReleaseContents(); | |
| 394 | 451 |
| 395 if (extended_enabled_) { | 452 if (extended_enabled_) { |
| 396 // Consider what's happening: | 453 // Consider what's happening: |
| 397 // 1. The user has typed a query in the omnibox and committed it (either | 454 // 1. The user has typed a query in the omnibox and committed it (either |
| 398 // by pressing Enter or clicking on the preview). | 455 // by pressing Enter or clicking on the preview). |
| 399 // 2. We commit the preview to the tab strip, and tell the page. | 456 // 2. We commit the preview to the tab strip, and tell the page. |
| 400 // 3. The page will update the URL hash fragment with the query terms. | 457 // 3. The page will update the URL hash fragment with the query terms. |
| 401 // After steps 1 and 3, the omnibox will show the query terms. However, if | 458 // After steps 1 and 3, the omnibox will show the query terms. However, if |
| 402 // the URL we are committing at step 2 doesn't already have query terms, it | 459 // the URL we are committing at step 2 doesn't already have query terms, it |
| 403 // will flash for a brief moment as a plain URL. So, avoid that flicker by | 460 // will flash for a brief moment as a plain URL. So, avoid that flicker by |
| 404 // pretending that the plain URL is actually the typed query terms. | 461 // pretending that the plain URL is actually the typed query terms. |
| 405 // TODO(samarth,beaudoin): Instead of this hack, we should add a new field | 462 // TODO(samarth,beaudoin): Instead of this hack, we should add a new field |
| 406 // to NavigationEntry to keep track of what the correct query, if any, is. | 463 // to NavigationEntry to keep track of what the correct query, if any, is. |
| 407 content::NavigationEntry* entry = | 464 content::NavigationEntry* entry = |
| 408 preview->web_contents()->GetController().GetVisibleEntry(); | 465 preview->GetController().GetVisibleEntry(); |
| 409 std::string url = entry->GetVirtualURL().spec(); | 466 std::string url = entry->GetVirtualURL().spec(); |
| 410 if (!google_util::IsInstantExtendedAPIGoogleSearchUrl(url) && | 467 if (!google_util::IsInstantExtendedAPIGoogleSearchUrl(url) && |
| 411 google_util::IsGoogleDomainUrl(url, google_util::ALLOW_SUBDOMAIN, | 468 google_util::IsGoogleDomainUrl(url, google_util::ALLOW_SUBDOMAIN, |
| 412 google_util::ALLOW_NON_STANDARD_PORTS)) { | 469 google_util::ALLOW_NON_STANDARD_PORTS)) { |
| 413 entry->SetVirtualURL(GURL( | 470 entry->SetVirtualURL(GURL( |
| 414 url + "#q=" + | 471 url + "#q=" + |
| 415 net::EscapeQueryParamValue(UTF16ToUTF8(last_full_text_), true))); | 472 net::EscapeQueryParamValue(UTF16ToUTF8(last_full_text_), true))); |
| 416 chrome::search::SearchTabHelper::FromWebContents( | 473 chrome::search::SearchTabHelper::FromWebContents(preview)-> |
| 417 preview->web_contents())->NavigationEntryUpdated(); | 474 NavigationEntryUpdated(); |
| 418 } | 475 } |
| 419 } | 476 } |
| 420 | 477 |
| 421 // If the preview page has navigated since the last Update(), we need to add | 478 // If the preview page has navigated since the last Update(), we need to add |
| 422 // the navigation to history ourselves. Else, the page will navigate after | 479 // the navigation to history ourselves. Else, the page will navigate after |
| 423 // commit, and it will be added to history in the usual manner. | 480 // commit, and it will be added to history in the usual manner. |
| 424 const history::HistoryAddPageArgs& last_navigation = | 481 const history::HistoryAddPageArgs& last_navigation = |
| 425 loader_->last_navigation(); | 482 loader_->last_navigation(); |
| 426 if (!last_navigation.url.is_empty()) { | 483 if (!last_navigation.url.is_empty()) { |
| 427 content::NavigationEntry* entry = | 484 content::NavigationEntry* entry = preview->GetController().GetActiveEntry(); |
| 428 preview->web_contents()->GetController().GetActiveEntry(); | |
| 429 DCHECK_EQ(last_navigation.url, entry->GetURL()); | 485 DCHECK_EQ(last_navigation.url, entry->GetURL()); |
| 430 | 486 |
| 431 // Add the page to history. | 487 // Add the page to history. |
| 432 HistoryTabHelper* history_tab_helper = | 488 HistoryTabHelper* history_tab_helper = |
| 433 HistoryTabHelper::FromWebContents(preview->web_contents()); | 489 HistoryTabHelper::FromWebContents(preview); |
| 434 history_tab_helper->UpdateHistoryForNavigation(last_navigation); | 490 history_tab_helper->UpdateHistoryForNavigation(last_navigation); |
| 435 | 491 |
| 436 // Update the page title. | 492 // Update the page title. |
| 437 history_tab_helper->UpdateHistoryPageTitle(*entry); | 493 history_tab_helper->UpdateHistoryPageTitle(*entry); |
| 438 } | 494 } |
| 439 | 495 |
| 440 // Add a fake history entry with a non-Instant search URL, so that search | 496 // Add a fake history entry with a non-Instant search URL, so that search |
| 441 // terms extraction (for autocomplete history matches) works. | 497 // terms extraction (for autocomplete history matches) works. |
| 442 if (HistoryService* history = HistoryServiceFactory::GetForProfile( | 498 HistoryService* history = HistoryServiceFactory::GetForProfile( |
| 443 preview->profile(), Profile::EXPLICIT_ACCESS)) { | 499 Profile::FromBrowserContext(preview->GetBrowserContext()), |
| 500 Profile::EXPLICIT_ACCESS); | |
| 501 if (history) { | |
| 444 history->AddPage(url_for_history_, base::Time::Now(), NULL, 0, GURL(), | 502 history->AddPage(url_for_history_, base::Time::Now(), NULL, 0, GURL(), |
| 445 history::RedirectList(), last_transition_type_, | 503 history::RedirectList(), last_transition_type_, |
| 446 history::SOURCE_BROWSED, false); | 504 history::SOURCE_BROWSED, false); |
| 447 } | 505 } |
| 448 | 506 |
| 449 preview->web_contents()->GetController().PruneAllButActive(); | 507 preview->GetController().PruneAllButActive(); |
| 450 | 508 |
| 451 if (type != INSTANT_COMMIT_PRESSED_ALT_ENTER) { | 509 if (type != INSTANT_COMMIT_PRESSED_ALT_ENTER) { |
| 452 const TabContents* active_tab = browser_->GetActiveTabContents(); | 510 content::WebContents* active_tab = browser_->GetActiveWebContents(); |
| 453 AddSessionStorageHistogram(extended_enabled_, active_tab, preview); | 511 AddSessionStorageHistogram(extended_enabled_, active_tab, preview); |
| 454 preview->web_contents()->GetController().CopyStateFromAndPrune( | 512 preview->GetController().CopyStateFromAndPrune( |
| 455 &active_tab->web_contents()->GetController()); | 513 &active_tab->GetController()); |
| 456 } | 514 } |
| 457 | 515 |
| 458 DeleteLoader(); | |
| 459 | |
| 460 // Browser takes ownership of the preview. | 516 // Browser takes ownership of the preview. |
| 461 browser_->CommitInstant(preview, type == INSTANT_COMMIT_PRESSED_ALT_ENTER); | 517 browser_->CommitInstant(preview, type == INSTANT_COMMIT_PRESSED_ALT_ENTER); |
| 462 | 518 |
| 463 content::NotificationService::current()->Notify( | 519 content::NotificationService::current()->Notify( |
| 464 chrome::NOTIFICATION_INSTANT_COMMITTED, | 520 chrome::NOTIFICATION_INSTANT_COMMITTED, |
| 465 content::Source<content::WebContents>(preview->web_contents()), | 521 content::Source<content::WebContents>(preview), |
| 466 content::NotificationService::NoDetails()); | 522 content::NotificationService::NoDetails()); |
| 467 | 523 |
| 524 // Hide explicitly. See comments in Hide() for why calling it won't work. | |
| 468 model_.SetPreviewState(chrome::search::Mode(), 0, INSTANT_SIZE_PERCENT); | 525 model_.SetPreviewState(chrome::search::Mode(), 0, INSTANT_SIZE_PERCENT); |
| 469 | 526 |
| 527 // Delay deletion as we could've gotten here from an InstantLoader method. | |
| 528 MessageLoop::current()->DeleteSoon(FROM_HERE, loader_.release()); | |
| 529 | |
| 470 // Try to create another loader immediately so that it is ready for the next | 530 // Try to create another loader immediately so that it is ready for the next |
| 471 // user interaction. | 531 // user interaction. |
| 472 CreateDefaultLoader(); | 532 CreateDefaultLoader(); |
| 473 | 533 |
| 474 return true; | 534 return true; |
| 475 } | 535 } |
| 476 | 536 |
| 477 void InstantController::OmniboxLostFocus(gfx::NativeView view_gaining_focus) { | 537 void InstantController::OmniboxLostFocus(gfx::NativeView view_gaining_focus) { |
| 478 DVLOG(1) << "OmniboxLostFocus"; | 538 DVLOG(1) << "OmniboxLostFocus"; |
| 479 is_omnibox_focused_ = false; | 539 is_omnibox_focused_ = false; |
| 480 | 540 |
| 481 if (!extended_enabled_ && !instant_enabled_) | 541 if (!extended_enabled_ && !instant_enabled_) |
| 482 return; | 542 return; |
| 483 | 543 |
| 484 // If the preview isn't showing search suggestions, nothing to do. The check | 544 // If the preview isn't showing search suggestions, nothing to do. The check |
| 485 // for GetPreviewContents() (which normally is redundant, given IsCurrent()) | 545 // for GetPreviewContents() (which normally is redundant, given IsCurrent()) |
| 486 // is to handle the case when we get here during a commit. | 546 // is to handle the case when we get here during a commit. |
| 487 if (!IsCurrent() || !GetPreviewContents()) { | 547 if (!IsCurrent() || !GetPreviewContents()) { |
| 488 OnStaleLoader(); | 548 OnStaleLoader(); |
| 489 return; | 549 return; |
| 490 } | 550 } |
| 491 | 551 |
| 492 #if defined(OS_MACOSX) | 552 #if defined(OS_MACOSX) |
| 493 if (!loader_->IsPointerDownFromActivate()) | 553 if (!loader_->is_pointer_down_from_activate()) |
| 494 Hide(true); | 554 Hide(); |
| 495 #else | 555 #else |
| 496 if (IsViewInContents(GetViewGainingFocus(view_gaining_focus), | 556 if (IsViewInContents(GetViewGainingFocus(view_gaining_focus), |
| 497 GetPreviewContents()->web_contents())) | 557 loader_->contents())) |
| 498 CommitIfCurrent(INSTANT_COMMIT_FOCUS_LOST); | 558 CommitIfCurrent(INSTANT_COMMIT_FOCUS_LOST); |
| 499 else | 559 else |
| 500 Hide(true); | 560 Hide(); |
| 501 #endif | 561 #endif |
| 502 } | 562 } |
| 503 | 563 |
| 504 void InstantController::OmniboxGotFocus() { | 564 void InstantController::OmniboxGotFocus() { |
| 505 DVLOG(1) << "OmniboxGotFocus"; | 565 DVLOG(1) << "OmniboxGotFocus"; |
| 506 is_omnibox_focused_ = true; | 566 is_omnibox_focused_ = true; |
| 507 | 567 |
| 508 if (!extended_enabled_ && !instant_enabled_) | 568 if (!extended_enabled_ && !instant_enabled_) |
| 509 return; | 569 return; |
| 510 | 570 |
| 511 if (!GetPreviewContents()) | 571 CreateDefaultLoader(); |
| 512 CreateDefaultLoader(); | |
| 513 } | 572 } |
| 514 | 573 |
| 515 void InstantController::SearchModeChanged( | 574 void InstantController::SearchModeChanged( |
| 516 const chrome::search::Mode& old_mode, | 575 const chrome::search::Mode& old_mode, |
| 517 const chrome::search::Mode& new_mode) { | 576 const chrome::search::Mode& new_mode) { |
| 518 if (!extended_enabled_) | 577 if (!extended_enabled_) |
| 519 return; | 578 return; |
| 520 | 579 |
| 521 DVLOG(1) << "SearchModeChanged: [origin:mode] " << old_mode.origin << ":" | 580 DVLOG(1) << "SearchModeChanged: [origin:mode] " << old_mode.origin << ":" |
| 522 << old_mode.mode << " to " << new_mode.origin << ":" | 581 << old_mode.mode << " to " << new_mode.origin << ":" |
| 523 << new_mode.mode; | 582 << new_mode.mode; |
| 524 search_mode_ = new_mode; | 583 search_mode_ = new_mode; |
| 525 | 584 |
| 526 if (new_mode.is_search_suggestions()) { | 585 if (new_mode.is_search_suggestions()) { |
| 527 // The preview is showing NTP content, but it's not appropriate anymore. | 586 // The preview is showing NTP content, but it's not appropriate anymore. |
| 528 if (model_.mode().is_ntp() && !new_mode.is_origin_ntp()) | 587 if (model_.mode().is_ntp() && !new_mode.is_origin_ntp()) { |
| 529 Hide(false); | 588 // Hide() clears |last_full_text_|. Restore it so that if the user just |
| 589 // switched to a tab with a partial query, we don't lose it. | |
| 590 string16 text = last_full_text_; | |
| 591 Hide(); | |
| 592 last_full_text_ = text; | |
| 593 } | |
| 530 } else { | 594 } else { |
| 531 Hide(true); | 595 Hide(); |
| 532 } | 596 } |
| 533 | 597 |
| 534 if (GetPreviewContents()) | 598 if (loader_) |
| 535 loader_->SearchModeChanged(new_mode); | 599 loader_->SearchModeChanged(new_mode); |
| 600 | |
| 601 ResetInstantTab(); | |
| 536 } | 602 } |
| 537 | 603 |
| 538 void InstantController::ActiveTabChanged() { | 604 void InstantController::ActiveTabChanged() { |
| 539 if (!extended_enabled_ && !instant_enabled_) | 605 if (!extended_enabled_ && !instant_enabled_) |
| 540 return; | 606 return; |
| 541 | 607 |
| 542 DVLOG(1) << "ActiveTabChanged"; | 608 DVLOG(1) << "ActiveTabChanged"; |
| 543 | 609 |
| 544 // By this time, SearchModeChanged() should've been called, so we only need to | 610 // By this time, SearchModeChanged() should've been called, so we only need to |
| 545 // handle the case when the search mode does NOT change, as in the case of | 611 // handle the case when the search mode does NOT change, as in the case of |
| 546 // going from search_suggestions to search_suggestions (i.e., partial queries | 612 // going from search_suggestions to search_suggestions (i.e., partial queries |
| 547 // on both old and new tabs). | 613 // on both old and new tabs). |
| 548 if (search_mode_.is_search_suggestions() && | 614 if (search_mode_.is_search_suggestions() && |
| 549 model_.mode().is_search_suggestions()) | 615 model_.mode().is_search_suggestions()) { |
| 550 Hide(false); | 616 // Hide() clears |last_full_text_|. Restore it so that if the user just |
| 617 // switched to a tab with a partial query, we don't lose it. | |
| 618 string16 text = last_full_text_; | |
| 619 Hide(); | |
| 620 last_full_text_ = text; | |
| 621 } | |
| 622 | |
| 623 if (extended_enabled_) | |
| 624 ResetInstantTab(); | |
| 551 } | 625 } |
| 552 | 626 |
| 553 void InstantController::SetInstantEnabled(bool instant_enabled) { | 627 void InstantController::SetInstantEnabled(bool instant_enabled) { |
| 554 instant_enabled_ = instant_enabled; | 628 instant_enabled_ = instant_enabled; |
| 555 if (!extended_enabled_ && !instant_enabled_) | 629 HideInternal(); |
| 556 DeleteLoader(); | 630 loader_.reset(); |
| 631 if (extended_enabled_ || instant_enabled_) | |
| 632 CreateDefaultLoader(); | |
| 557 } | 633 } |
| 558 | 634 |
| 559 void InstantController::ThemeChanged(const ThemeBackgroundInfo& theme_info) { | 635 void InstantController::ThemeChanged(const ThemeBackgroundInfo& theme_info) { |
| 560 if (!extended_enabled_) | 636 if (!extended_enabled_) |
| 561 return; | 637 return; |
| 562 | 638 |
| 563 if (GetPreviewContents()) | 639 if (loader_) |
| 564 loader_->SendThemeBackgroundInfo(theme_info); | 640 loader_->SendThemeBackgroundInfo(theme_info); |
| 565 } | 641 } |
| 566 | 642 |
| 567 void InstantController::ThemeAreaHeightChanged(int height) { | 643 void InstantController::ThemeAreaHeightChanged(int height) { |
| 568 if (!extended_enabled_) | 644 if (!extended_enabled_) |
| 569 return; | 645 return; |
| 570 | 646 |
| 571 if (GetPreviewContents()) | 647 if (loader_) |
| 572 loader_->SendThemeAreaHeight(height); | 648 loader_->SendThemeAreaHeight(height); |
| 573 } | 649 } |
| 574 | 650 |
| 575 void InstantController::SetSuggestions( | 651 void InstantController::SetSuggestions( |
| 576 InstantLoader* loader, | 652 const content::WebContents* contents, |
| 577 const std::vector<InstantSuggestion>& suggestions) { | 653 const std::vector<InstantSuggestion>& suggestions) { |
| 578 DVLOG(1) << "SetSuggestions"; | 654 DVLOG(1) << "SetSuggestions"; |
| 579 if (loader_ != loader || !search_mode_.is_search_suggestions()) | 655 |
| 656 // Ignore if we are not currently accepting search suggestions, or if they are | |
| 657 // coming from the wrong loader. | |
| 658 if (!search_mode_.is_search_suggestions() || | |
| 659 (instant_tab_ && instant_tab_->contents() != contents) || | |
| 660 (!instant_tab_ && loader_ && loader_->contents() != contents)) | |
|
samarth
2012/12/03 19:46:03
Yikes! The last two clauses appear all over the pl
sreeram
2012/12/04 08:10:52
Actually, it's just in two places - the only two c
| |
| 580 return; | 661 return; |
| 581 | 662 |
| 582 InstantSuggestion suggestion; | 663 InstantSuggestion suggestion; |
| 583 if (!suggestions.empty()) | 664 if (!suggestions.empty()) |
| 584 suggestion = suggestions[0]; | 665 suggestion = suggestions[0]; |
| 585 | 666 |
| 586 if (suggestion.behavior == INSTANT_COMPLETE_REPLACE) { | 667 if (suggestion.behavior == INSTANT_COMPLETE_REPLACE) { |
| 587 // We don't get an Update() when changing the omnibox due to a REPLACE | 668 // We don't get an Update() when changing the omnibox due to a REPLACE |
| 588 // suggestion (so that we don't inadvertently cause the preview to change | 669 // suggestion (so that we don't inadvertently cause the preview to change |
| 589 // what it's showing, as the user arrows up/down through the page-provided | 670 // what it's showing, as the user arrows up/down through the page-provided |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 639 DVLOG(1) << "SetInstantSuggestion: text='" << suggestion.text << "'" | 720 DVLOG(1) << "SetInstantSuggestion: text='" << suggestion.text << "'" |
| 640 << " behavior=" << suggestion.behavior << " type=" | 721 << " behavior=" << suggestion.behavior << " type=" |
| 641 << suggestion.type; | 722 << suggestion.type; |
| 642 browser_->SetInstantSuggestion(suggestion); | 723 browser_->SetInstantSuggestion(suggestion); |
| 643 } | 724 } |
| 644 } | 725 } |
| 645 | 726 |
| 646 Show(INSTANT_SHOWN_QUERY_SUGGESTIONS, 100, INSTANT_SIZE_PERCENT); | 727 Show(INSTANT_SHOWN_QUERY_SUGGESTIONS, 100, INSTANT_SIZE_PERCENT); |
| 647 } | 728 } |
| 648 | 729 |
| 649 void InstantController::CommitInstantLoader(InstantLoader* loader) { | 730 void InstantController::InstantSupportDetermined( |
| 650 if (loader_ == loader) | 731 const content::WebContents* contents, |
| 651 CommitIfCurrent(INSTANT_COMMIT_FOCUS_LOST); | 732 bool supports_instant) { |
| 733 if (instant_tab_ && instant_tab_->contents() == contents) { | |
| 734 if (!supports_instant) | |
|
Jered
2012/11/29 19:57:05
Wow, I hope not. Do we not want to update the blac
sreeram
2012/12/04 08:10:52
No. The blacklist is to make sure that we are not
| |
| 735 MessageLoop::current()->DeleteSoon(FROM_HERE, instant_tab_.release()); | |
| 736 return; | |
| 737 } | |
| 738 | |
| 739 if (loader_ && loader_->contents() == contents) { | |
| 740 if (supports_instant) { | |
| 741 blacklisted_urls_.erase(loader_->instant_url()); | |
| 742 } else { | |
| 743 ++blacklisted_urls_[loader_->instant_url()]; | |
| 744 HideInternal(); | |
| 745 delete loader_->ReleaseContents(); | |
| 746 MessageLoop::current()->DeleteSoon(FROM_HERE, loader_.release()); | |
| 747 CreateDefaultLoader(); | |
|
Jered
2012/11/29 19:57:05
Is this CreateDefaultLoader() call new? I think th
sreeram
2012/12/04 08:10:52
Yeah, the call is new. The infinite loop can't hap
| |
| 748 } | |
| 749 content::NotificationService::current()->Notify( | |
| 750 chrome::NOTIFICATION_INSTANT_SUPPORT_DETERMINED, | |
| 751 content::Source<InstantController>(this), | |
| 752 content::NotificationService::NoDetails()); | |
| 753 } | |
| 652 } | 754 } |
| 653 | 755 |
| 654 void InstantController::ShowInstantPreview(InstantLoader* loader, | 756 void InstantController::ShowInstantPreview(InstantShownReason reason, |
| 655 InstantShownReason reason, | |
| 656 int height, | 757 int height, |
| 657 InstantSizeUnits units) { | 758 InstantSizeUnits units) { |
| 658 if (loader_ == loader && extended_enabled_) | 759 if (extended_enabled_) |
| 659 Show(reason, height, units); | 760 Show(reason, height, units); |
| 660 } | 761 } |
| 661 | 762 |
| 662 void InstantController::InstantSupportDetermined(InstantLoader* loader, | 763 void InstantController::SwappedWebContents() { |
| 663 bool supports_instant) { | 764 model_.SetPreviewContents(GetPreviewContents()); |
| 664 if (supports_instant) { | |
| 665 blacklisted_urls_.erase(loader->instant_url()); | |
| 666 } else { | |
| 667 ++blacklisted_urls_[loader->instant_url()]; | |
| 668 if (loader_ == loader) | |
| 669 DeleteLoader(); | |
| 670 } | |
| 671 | |
| 672 content::NotificationService::current()->Notify( | |
| 673 chrome::NOTIFICATION_INSTANT_SUPPORT_DETERMINED, | |
| 674 content::Source<InstantController>(this), | |
| 675 content::NotificationService::NoDetails()); | |
| 676 } | 765 } |
| 677 | 766 |
| 678 void InstantController::SwappedTabContents(InstantLoader* loader) { | 767 void InstantController::InstantLoaderContentsFocused() { |
| 679 if (loader_ == loader) | |
| 680 model_.SetPreviewContents(GetPreviewContents()); | |
| 681 } | |
| 682 | |
| 683 void InstantController::InstantLoaderContentsFocused(InstantLoader* loader) { | |
| 684 #if defined(USE_AURA) | 768 #if defined(USE_AURA) |
| 685 // On aura the omnibox only receives a focus lost if we initiate the focus | 769 // On aura the omnibox only receives a focus lost if we initiate the focus |
| 686 // change. This does that. | 770 // change. This does that. |
| 687 if (loader_ == loader && !model_.mode().is_default()) | 771 if (!model_.mode().is_default()) |
| 688 browser_->InstantPreviewFocused(); | 772 browser_->InstantPreviewFocused(); |
| 689 #endif | 773 #endif |
| 690 } | 774 } |
| 691 | 775 |
| 692 bool InstantController::ResetLoader(const TemplateURL* template_url, | 776 bool InstantController::ResetLoader(const TemplateURL* template_url, |
| 693 const TabContents* active_tab) { | 777 const content::WebContents* active_tab) { |
| 694 std::string instant_url; | 778 std::string instant_url; |
| 695 if (!GetInstantURL(template_url, &instant_url)) | 779 if (!GetInstantURL(template_url, &instant_url)) |
| 696 return false; | 780 return false; |
| 697 | 781 |
| 698 if (GetPreviewContents() && loader_->instant_url() != instant_url) | 782 if (loader_ && loader_->instant_url() == instant_url) |
| 699 DeleteLoader(); | 783 return true; |
| 700 | 784 |
| 701 if (!GetPreviewContents()) { | 785 HideInternal(); |
| 702 loader_.reset(new InstantLoader(this, instant_url, active_tab)); | 786 loader_.reset(new InstantLoader(this, instant_url)); |
| 703 loader_->Init(); | 787 loader_->InitContents(active_tab); |
| 704 | 788 |
| 705 // Ensure the searchbox API has the correct theme-related info and context. | 789 // Ensure the searchbox API has the correct theme-related info and context. |
| 706 if (extended_enabled_) { | 790 if (extended_enabled_) { |
| 707 browser_->UpdateThemeInfoForPreview(); | 791 browser_->UpdateThemeInfoForPreview(); |
| 708 loader_->SearchModeChanged(search_mode_); | 792 loader_->SearchModeChanged(search_mode_); |
| 709 } | 793 } |
| 710 | 794 |
| 711 // Reset the loader timer. | 795 // Restart the stale loader timer. |
| 712 stale_loader_timer_.Start( | 796 stale_loader_timer_.Start(FROM_HERE, |
| 713 FROM_HERE, | 797 base::TimeDelta::FromMilliseconds(kStaleLoaderTimeoutMS), this, |
| 714 base::TimeDelta::FromMilliseconds(kStaleLoaderTimeoutMS), this, | 798 &InstantController::OnStaleLoader); |
| 715 &InstantController::OnStaleLoader); | |
| 716 } | |
| 717 | 799 |
| 718 return true; | 800 return true; |
| 719 } | 801 } |
| 720 | 802 |
| 721 bool InstantController::CreateDefaultLoader() { | 803 bool InstantController::CreateDefaultLoader() { |
| 722 // If there's no active tab, the browser is closing. | 804 // If there's no active tab, the browser is closing. |
| 723 const TabContents* active_tab = browser_->GetActiveTabContents(); | 805 const content::WebContents* active_tab = browser_->GetActiveWebContents(); |
| 724 if (!active_tab) | 806 if (!active_tab) |
| 725 return false; | 807 return false; |
| 726 | 808 |
| 727 const TemplateURL* template_url = | 809 const TemplateURL* template_url = TemplateURLServiceFactory::GetForProfile( |
| 728 TemplateURLServiceFactory::GetForProfile(active_tab->profile())-> | 810 Profile::FromBrowserContext(active_tab->GetBrowserContext()))-> |
| 729 GetDefaultSearchProvider(); | 811 GetDefaultSearchProvider(); |
| 730 | 812 |
| 731 return ResetLoader(template_url, active_tab); | 813 return ResetLoader(template_url, active_tab); |
| 732 } | 814 } |
| 733 | 815 |
| 734 void InstantController::OnStaleLoader() { | 816 void InstantController::OnStaleLoader() { |
| 735 // If the preview is showing or the omnibox has focus, don't delete the | 817 // If the preview is showing or the omnibox has focus, don't delete the |
| 736 // loader. It will get refreshed the next time the preview is hidden or the | 818 // loader. It will get refreshed the next time the preview is hidden or the |
| 737 // omnibox loses focus. | 819 // omnibox loses focus. |
| 738 if (!stale_loader_timer_.IsRunning() && !is_omnibox_focused_ && | 820 if (!stale_loader_timer_.IsRunning() && !is_omnibox_focused_ && |
| 739 model_.mode().is_default()) { | 821 model_.mode().is_default()) { |
| 740 DeleteLoader(); | 822 loader_.reset(); |
| 741 CreateDefaultLoader(); | 823 CreateDefaultLoader(); |
| 742 } | 824 } |
| 743 } | 825 } |
| 744 | 826 |
| 745 void InstantController::DeleteLoader() { | 827 void InstantController::ResetInstantTab() { |
| 746 // Clear all state, except |last_transition_type_| as it's used during commit. | 828 if (search_mode_.is_origin_search()) { |
| 747 last_user_text_.clear(); | 829 content::WebContents* active_tab = browser_->GetActiveWebContents(); |
| 748 last_full_text_.clear(); | 830 if (!instant_tab_ || active_tab != instant_tab_->contents()) |
| 749 last_verbatim_ = false; | 831 instant_tab_.reset(new InstantTab(this, active_tab)); |
| 750 last_suggestion_ = InstantSuggestion(); | 832 |
| 751 last_match_was_search_ = false; | 833 // We are now using |instant_tab_| instead of |loader_|, so Hide() the |
| 752 if (!extended_enabled_) | 834 // latter, but preserve |last_full_text_|. |
|
Jered
2012/11/29 19:57:05
This happens in 3 places. Perhaps extract a method
sreeram
2012/12/04 08:10:52
Ack. No longer repeated in the new patch.
| |
| 753 search_mode_.mode = chrome::search::Mode::MODE_DEFAULT; | 835 string16 text = last_full_text_; |
| 754 omnibox_bounds_ = gfx::Rect(); | 836 Hide(); |
| 755 last_omnibox_bounds_ = gfx::Rect(); | 837 last_full_text_ = text; |
| 756 update_bounds_timer_.Stop(); | 838 } else { |
| 757 stale_loader_timer_.Stop(); | 839 instant_tab_.reset(); |
| 758 url_for_history_ = GURL(); | 840 } |
| 759 first_interaction_time_ = base::Time(); | 841 } |
| 842 | |
| 843 void InstantController::Hide() { | |
| 844 HideInternal(); | |
| 845 OnStaleLoader(); | |
| 846 } | |
| 847 | |
| 848 void InstantController::HideInternal() { | |
| 849 DVLOG(1) << "Hide"; | |
| 850 | |
| 851 // If GetPreviewContents() returns NULL, either we're already in the desired | |
| 852 // MODE_DEFAULT state, or we're in the commit path. For the latter, don't | |
| 853 // change the state just yet; else we may hide the preview unnecessarily. | |
| 854 // Instead, the state will be set correctly after the commit is done. | |
| 760 if (GetPreviewContents()) { | 855 if (GetPreviewContents()) { |
| 761 model_.SetPreviewState(chrome::search::Mode(), 0, INSTANT_SIZE_PERCENT); | 856 model_.SetPreviewState(chrome::search::Mode(), 0, INSTANT_SIZE_PERCENT); |
| 762 loader_->CleanupPreviewContents(); | 857 |
| 858 // Send a message asking the preview to clear out old results. | |
| 859 if (!last_full_text_.empty()) { | |
| 860 last_full_text_.clear(); | |
| 861 loader_->Update(last_full_text_, true); | |
| 862 } | |
| 763 } | 863 } |
| 764 | 864 |
| 765 // Schedule the deletion for later, since we may have gotten here from a call | |
| 766 // within a |loader_| method (i.e., it's still on the stack). If we deleted | |
| 767 // the loader immediately, things would still be fine so long as the caller | |
| 768 // doesn't access any instance members after we return, but why rely on that? | |
| 769 MessageLoop::current()->DeleteSoon(FROM_HERE, loader_.release()); | |
| 770 } | |
| 771 | |
| 772 void InstantController::Hide(bool clear_query) { | |
| 773 DVLOG(1) << "Hide: clear_query=" << clear_query; | |
| 774 | |
| 775 // The only time when the preview is not already in the desired MODE_DEFAULT | |
| 776 // state and GetPreviewContents() returns NULL is when we are in the commit | |
| 777 // path. In that case, don't change the state just yet; otherwise we may | |
| 778 // cause the preview to hide unnecessarily. Instead, the state will be set | |
| 779 // correctly after the commit is done. | |
| 780 if (GetPreviewContents()) | |
| 781 model_.SetPreviewState(chrome::search::Mode(), 0, INSTANT_SIZE_PERCENT); | |
| 782 | |
| 783 // Clear the first interaction timestamp for later use. | 865 // Clear the first interaction timestamp for later use. |
| 784 first_interaction_time_ = base::Time(); | 866 first_interaction_time_ = base::Time(); |
| 785 | |
| 786 if (clear_query) { | |
| 787 if (GetPreviewContents() && !last_full_text_.empty()) | |
| 788 loader_->Update(string16(), true); | |
| 789 last_user_text_.clear(); | |
| 790 last_full_text_.clear(); | |
| 791 } | |
| 792 | |
| 793 OnStaleLoader(); | |
| 794 } | 867 } |
| 795 | 868 |
| 796 void InstantController::Show(InstantShownReason reason, | 869 void InstantController::Show(InstantShownReason reason, |
| 797 int height, | 870 int height, |
| 798 InstantSizeUnits units) { | 871 InstantSizeUnits units) { |
| 872 if (instant_tab_) | |
| 873 return; | |
| 874 | |
| 799 DVLOG(1) << "Show: reason=" << reason << " height=" << height << " units=" | 875 DVLOG(1) << "Show: reason=" << reason << " height=" << height << " units=" |
| 800 << units; | 876 << units; |
| 801 | 877 |
| 802 // Must be on NTP to show NTP content. | 878 // Must be on NTP to show NTP content. |
| 803 if (reason == INSTANT_SHOWN_CUSTOM_NTP_CONTENT && !search_mode_.is_ntp()) | 879 if (reason == INSTANT_SHOWN_CUSTOM_NTP_CONTENT && !search_mode_.is_ntp()) |
| 804 return; | 880 return; |
| 805 | 881 |
| 806 // Must have updated omnibox after most recent Hide() to show suggestions. | 882 // Must have updated omnibox after most recent Hide() to show suggestions. |
| 807 if (reason == INSTANT_SHOWN_QUERY_SUGGESTIONS && | 883 if (reason == INSTANT_SHOWN_QUERY_SUGGESTIONS && |
| 808 !search_mode_.is_search_suggestions()) | 884 !search_mode_.is_search_suggestions()) |
| 809 return; | 885 return; |
| 810 | 886 |
| 811 // If the preview is being shown because of the first set of suggestions to | 887 // If the preview is being shown for the first time since the user started |
| 812 // arrive for this query editing session, record a histogram value. | 888 // typing, record a histogram value. |
| 813 if (!first_interaction_time_.is_null() && model_.mode().is_default()) { | 889 if (!first_interaction_time_.is_null() && model_.mode().is_default()) { |
| 814 base::TimeDelta delta = base::Time::Now() - first_interaction_time_; | 890 base::TimeDelta delta = base::Time::Now() - first_interaction_time_; |
| 815 UMA_HISTOGRAM_TIMES("Instant.TimeToFirstShow", delta); | 891 UMA_HISTOGRAM_TIMES("Instant.TimeToFirstShow", delta); |
| 816 } | 892 } |
| 817 | 893 |
| 818 // Show at 100% height except in the following cases: | 894 // Show at 100% height except in the following cases: |
| 819 // - The page wants to hide (height=0). | 895 // - The page wants to hide (height=0). |
| 820 // - The page wants to show custom NTP content. | 896 // - The page wants to show custom NTP content. |
| 821 // - The page is over a website other than search or an NTP, and is not | 897 // - The page is over a website other than search or an NTP, and is not |
| 822 // already showing at 100% height. | 898 // already showing at 100% height. |
| 823 const bool is_full_height = | 899 bool is_full_height = model_.height() == 100 && |
| 824 model_.height() == 100 && model_.height_units() == INSTANT_SIZE_PERCENT; | 900 model_.height_units() == INSTANT_SIZE_PERCENT; |
| 825 if (height == 0 || | 901 if (height == 0 || |
| 826 reason == INSTANT_SHOWN_CUSTOM_NTP_CONTENT || | 902 reason == INSTANT_SHOWN_CUSTOM_NTP_CONTENT || |
| 827 (search_mode_.is_origin_default() && !is_full_height)) | 903 (search_mode_.is_origin_default() && !is_full_height)) |
| 828 model_.SetPreviewState(search_mode_, height, units); | 904 model_.SetPreviewState(search_mode_, height, units); |
| 829 else | 905 else |
| 830 model_.SetPreviewState(search_mode_, 100, INSTANT_SIZE_PERCENT); | 906 model_.SetPreviewState(search_mode_, 100, INSTANT_SIZE_PERCENT); |
| 831 } | 907 } |
| 832 | 908 |
| 833 void InstantController::SendBoundsToPage() { | 909 void InstantController::SendBoundsToPage() { |
| 834 if (last_omnibox_bounds_ == omnibox_bounds_ || | 910 if (last_omnibox_bounds_ == omnibox_bounds_ || !loader_ || |
| 835 !GetPreviewContents() || loader_->IsPointerDownFromActivate()) | 911 loader_->is_pointer_down_from_activate()) |
| 836 return; | 912 return; |
| 837 | 913 |
| 838 last_omnibox_bounds_ = omnibox_bounds_; | 914 last_omnibox_bounds_ = omnibox_bounds_; |
| 839 gfx::Rect preview_bounds = browser_->GetInstantBounds(); | 915 gfx::Rect preview_bounds = browser_->GetInstantBounds(); |
| 840 gfx::Rect intersection = gfx::IntersectRects(omnibox_bounds_, preview_bounds); | 916 gfx::Rect intersection = gfx::IntersectRects(omnibox_bounds_, preview_bounds); |
| 841 | 917 |
| 842 // Translate into window coordinates. | 918 // Translate into window coordinates. |
| 843 if (!intersection.IsEmpty()) { | 919 if (!intersection.IsEmpty()) { |
| 844 intersection.Offset(-preview_bounds.origin().x(), | 920 intersection.Offset(-preview_bounds.origin().x(), |
| 845 -preview_bounds.origin().y()); | 921 -preview_bounds.origin().y()); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 879 | 955 |
| 880 // Extended mode should always use HTTPS. TODO(sreeram): This section can be | 956 // Extended mode should always use HTTPS. TODO(sreeram): This section can be |
| 881 // removed if TemplateURLs supported "https://{google:host}/..." instead of | 957 // removed if TemplateURLs supported "https://{google:host}/..." instead of |
| 882 // only supporting "{google:baseURL}...". | 958 // only supporting "{google:baseURL}...". |
| 883 if (extended_enabled_) { | 959 if (extended_enabled_) { |
| 884 GURL url_obj(*instant_url); | 960 GURL url_obj(*instant_url); |
| 885 if (!url_obj.is_valid()) | 961 if (!url_obj.is_valid()) |
| 886 return false; | 962 return false; |
| 887 | 963 |
| 888 if (!url_obj.SchemeIsSecure()) { | 964 if (!url_obj.SchemeIsSecure()) { |
| 889 const std::string new_scheme = "https"; | 965 std::string new_scheme = "https"; |
|
Jered
2012/11/29 19:57:05
There is probably a constant for this somewhere.
sreeram
2012/12/04 08:10:52
I'd think so too, but I couldn't find one!
| |
| 890 const std::string new_port = "443"; | 966 std::string new_port = "443"; |
|
Jered
2012/11/29 19:57:05
This too I'd expect.
sreeram
2012/12/04 08:10:52
Likewise. (Note that this is worse, since it needs
| |
| 891 GURL::Replacements secure; | 967 GURL::Replacements secure; |
| 892 secure.SetSchemeStr(new_scheme); | 968 secure.SetSchemeStr(new_scheme); |
| 893 secure.SetPortStr(new_port); | 969 secure.SetPortStr(new_port); |
| 894 url_obj = url_obj.ReplaceComponents(secure); | 970 url_obj = url_obj.ReplaceComponents(secure); |
| 895 | 971 |
| 896 if (!url_obj.is_valid()) | 972 if (!url_obj.is_valid()) |
| 897 return false; | 973 return false; |
| 898 | 974 |
| 899 *instant_url = url_obj.spec(); | 975 *instant_url = url_obj.spec(); |
| 900 } | 976 } |
| 901 } | 977 } |
| 902 | 978 |
| 903 std::map<std::string, int>::const_iterator iter = | 979 std::map<std::string, int>::const_iterator iter = |
| 904 blacklisted_urls_.find(*instant_url); | 980 blacklisted_urls_.find(*instant_url); |
| 905 if (iter != blacklisted_urls_.end() && | 981 if (iter != blacklisted_urls_.end() && |
| 906 iter->second > kMaxInstantSupportFailures) | 982 iter->second > kMaxInstantSupportFailures) |
| 907 return false; | 983 return false; |
| 908 | 984 |
| 909 return true; | 985 return true; |
| 910 } | 986 } |
| OLD | NEW |