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_ntp.h" |
17 #include "chrome/browser/instant/instant_overlay.h" | |
17 #include "chrome/browser/instant/instant_tab.h" | 18 #include "chrome/browser/instant/instant_tab.h" |
18 #include "chrome/browser/platform_util.h" | 19 #include "chrome/browser/platform_util.h" |
19 #include "chrome/browser/search_engines/template_url_service.h" | 20 #include "chrome/browser/search_engines/template_url_service.h" |
20 #include "chrome/browser/search_engines/template_url_service_factory.h" | 21 #include "chrome/browser/search_engines/template_url_service_factory.h" |
21 #include "chrome/browser/ui/browser_instant_controller.h" | 22 #include "chrome/browser/ui/browser_instant_controller.h" |
22 #include "chrome/browser/ui/search/search_tab_helper.h" | 23 #include "chrome/browser/ui/search/search_tab_helper.h" |
23 #include "chrome/common/chrome_notification_types.h" | 24 #include "chrome/common/chrome_notification_types.h" |
24 #include "chrome/common/chrome_switches.h" | 25 #include "chrome/common/chrome_switches.h" |
25 #include "content/public/browser/navigation_entry.h" | 26 #include "content/public/browser/navigation_entry.h" |
26 #include "content/public/browser/notification_service.h" | 27 #include "content/public/browser/notification_service.h" |
(...skipping 12 matching lines...) Expand all Loading... | |
39 // page about the new omnibox bounds, in cases where the bounds shrink. This is | 40 // page about the new omnibox bounds, in cases where the bounds shrink. This is |
40 // to avoid the page jumping up/down very fast in response to bounds changes. | 41 // to avoid the page jumping up/down very fast in response to bounds changes. |
41 const int kUpdateBoundsDelayMS = 1000; | 42 const int kUpdateBoundsDelayMS = 1000; |
42 | 43 |
43 // The maximum number of times we'll load a non-Instant-supporting search engine | 44 // The maximum number of times we'll load a non-Instant-supporting search engine |
44 // before we give up and blacklist it for the rest of the browsing session. | 45 // before we give up and blacklist it for the rest of the browsing session. |
45 const int kMaxInstantSupportFailures = 10; | 46 const int kMaxInstantSupportFailures = 10; |
46 | 47 |
47 // If an Instant page has not been used in these many milliseconds, it is | 48 // If an Instant page has not been used in these many milliseconds, it is |
48 // reloaded so that the page does not become stale. | 49 // reloaded so that the page does not become stale. |
49 const int kStaleLoaderTimeoutMS = 3 * 3600 * 1000; | 50 const int kStalePageTimeoutMS = 3 * 3600 * 1000; |
50 | 51 |
51 // For reporting events of interest. | 52 // For reporting events of interest. |
52 enum InstantControllerEvent { | 53 enum InstantControllerEvent { |
53 INSTANT_CONTROLLER_EVENT_URL_ADDED_TO_BLACKLIST = 0, | 54 INSTANT_CONTROLLER_EVENT_URL_ADDED_TO_BLACKLIST = 0, |
54 INSTANT_CONTROLLER_EVENT_URL_REMOVED_FROM_BLACKLIST = 1, | 55 INSTANT_CONTROLLER_EVENT_URL_REMOVED_FROM_BLACKLIST = 1, |
55 INSTANT_CONTROLLER_EVENT_URL_BLOCKED_BY_BLACKLIST = 2, | 56 INSTANT_CONTROLLER_EVENT_URL_BLOCKED_BY_BLACKLIST = 2, |
56 INSTANT_CONTROLLER_EVENT_MAX = 3, | 57 INSTANT_CONTROLLER_EVENT_MAX = 3, |
57 }; | 58 }; |
58 | 59 |
59 void RecordEventHistogram(InstantControllerEvent event) { | 60 void RecordEventHistogram(InstantControllerEvent event) { |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
152 return true; | 153 return true; |
153 } | 154 } |
154 | 155 |
155 return false; | 156 return false; |
156 } | 157 } |
157 | 158 |
158 bool IsFullHeight(const InstantModel& model) { | 159 bool IsFullHeight(const InstantModel& model) { |
159 return model.height() == 100 && model.height_units() == INSTANT_SIZE_PERCENT; | 160 return model.height() == 100 && model.height_units() == INSTANT_SIZE_PERCENT; |
160 } | 161 } |
161 | 162 |
163 bool ContentsFrom(const InstantPage* page, | |
164 const content::WebContents* contents) { | |
165 return page && (page->contents() == contents); | |
166 } | |
167 | |
162 } // namespace | 168 } // namespace |
163 | 169 |
164 // static | 170 // static |
165 const char* InstantController::kLocalOmniboxPopupURL = | 171 const char* InstantController::kLocalOmniboxPopupURL = |
166 "chrome://local-omnibox-popup/local-omnibox-popup.html"; | 172 "chrome://local-omnibox-popup/local-omnibox-popup.html"; |
167 | 173 |
168 InstantController::InstantController(chrome::BrowserInstantController* browser, | 174 InstantController::InstantController(chrome::BrowserInstantController* browser, |
169 bool extended_enabled, | 175 bool extended_enabled, |
170 bool use_local_preview_only) | 176 bool use_local_preview_only) |
171 : browser_(browser), | 177 : browser_(browser), |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
208 << is_keyword_search; | 214 << is_keyword_search; |
209 | 215 |
210 // TODO(dhollowa): Complete keyword match UI. For now just hide suggestions. | 216 // TODO(dhollowa): Complete keyword match UI. For now just hide suggestions. |
211 // http://crbug.com/153932. Note, this early escape is happens prior to the | 217 // http://crbug.com/153932. Note, this early escape is happens prior to the |
212 // DCHECKs below because |user_text| and |full_text| have different semantics | 218 // DCHECKs below because |user_text| and |full_text| have different semantics |
213 // when keyword search is in effect. | 219 // when keyword search is in effect. |
214 if (is_keyword_search) { | 220 if (is_keyword_search) { |
215 if (instant_tab_) | 221 if (instant_tab_) |
216 instant_tab_->Update(string16(), 0, 0, true); | 222 instant_tab_->Update(string16(), 0, 0, true); |
217 else | 223 else |
218 HideLoader(); | 224 HideOverlay(); |
219 last_match_was_search_ = false; | 225 last_match_was_search_ = false; |
220 return false; | 226 return false; |
221 } | 227 } |
222 | 228 |
223 // If the popup is open, the user has to be typing. | 229 // If the popup is open, the user has to be typing. |
224 DCHECK(!omnibox_popup_is_open || user_input_in_progress); | 230 DCHECK(!omnibox_popup_is_open || user_input_in_progress); |
225 | 231 |
226 // If the popup is closed, there should be no inline autocompletion. | 232 // If the popup is closed, there should be no inline autocompletion. |
227 DCHECK(omnibox_popup_is_open || user_text.empty() || user_text == full_text) | 233 DCHECK(omnibox_popup_is_open || user_text.empty() || user_text == full_text) |
228 << user_text << "|" << full_text; | 234 << user_text << "|" << full_text; |
229 | 235 |
230 // If there's no text in the omnibox, the user can't have typed any. | 236 // If there's no text in the omnibox, the user can't have typed any. |
231 DCHECK(!full_text.empty() || user_text.empty()) << user_text; | 237 DCHECK(!full_text.empty() || user_text.empty()) << user_text; |
232 | 238 |
233 // If the user isn't typing, and the popup is closed, there can't be any | 239 // If the user isn't typing, and the popup is closed, there can't be any |
234 // user-typed text. | 240 // user-typed text. |
235 DCHECK(user_input_in_progress || omnibox_popup_is_open || user_text.empty()) | 241 DCHECK(user_input_in_progress || omnibox_popup_is_open || user_text.empty()) |
236 << user_text; | 242 << user_text; |
237 | 243 |
238 // The preview is being clicked and will commit soon. Don't change anything. | 244 // The preview is being clicked and will commit soon. Don't change anything. |
239 // TODO(sreeram): Add a browser test for this. | 245 // TODO(sreeram): Add a browser test for this. |
240 if (loader_ && loader_->is_pointer_down_from_activate()) | 246 if (overlay_ && overlay_->is_pointer_down_from_activate()) |
241 return false; | 247 return false; |
242 | 248 |
243 // In non-extended mode, SearchModeChanged() is never called, so fake it. The | 249 // In non-extended mode, SearchModeChanged() is never called, so fake it. The |
244 // mode is set to "disallow suggestions" here, so that if one of the early | 250 // mode is set to "disallow suggestions" here, so that if one of the early |
245 // "return false" conditions is hit, suggestions will be disallowed. If the | 251 // "return false" conditions is hit, suggestions will be disallowed. If the |
246 // query is sent to the loader, the mode is set to "allow" further below. | 252 // query is sent to the overlay, the mode is set to "allow" further below. |
247 if (!extended_enabled_) | 253 if (!extended_enabled_) |
248 search_mode_.mode = chrome::search::Mode::MODE_DEFAULT; | 254 search_mode_.mode = chrome::search::Mode::MODE_DEFAULT; |
249 | 255 |
250 last_match_was_search_ = AutocompleteMatch::IsSearchType(match.type) && | 256 last_match_was_search_ = AutocompleteMatch::IsSearchType(match.type) && |
251 !user_text.empty(); | 257 !user_text.empty(); |
252 | 258 |
253 if (!ResetLoaderForMatch(match)) { | 259 if (!ResetOverlayForMatch(match)) { |
254 HideLoader(); | 260 HideOverlay(); |
255 return false; | 261 return false; |
256 } | 262 } |
257 | 263 |
258 if (extended_enabled_) { | 264 if (extended_enabled_) { |
259 if (!omnibox_popup_is_open) { | 265 if (!omnibox_popup_is_open) { |
260 if (!user_input_in_progress) { | 266 if (!user_input_in_progress) { |
261 // If the user isn't typing and the omnibox popup is closed, it means a | 267 // If the user isn't typing and the omnibox popup is closed, it means a |
262 // regular navigation, tab-switch or the user hitting Escape. | 268 // regular navigation, tab-switch or the user hitting Escape. |
263 if (instant_tab_) { | 269 if (instant_tab_) { |
264 // The user is on a search results page. It may be showing results for | 270 // The user is on a search results page. It may be showing results for |
265 // a partial query the user typed before they hit Escape. Send the | 271 // a partial query the user typed before they hit Escape. Send the |
266 // omnibox text to the page to restore the original results. | 272 // omnibox text to the page to restore the original results. |
267 // | 273 // |
268 // In a tab switch, |instant_tab_| won't have updated yet, so it may | 274 // In a tab switch, |instant_tab_| won't have updated yet, so it may |
269 // be pointing to the previous tab (which was a search results page). | 275 // be pointing to the previous tab (which was a search results page). |
270 // Ensure we don't send the omnibox text to a random webpage (the new | 276 // Ensure we don't send the omnibox text to a random webpage (the new |
271 // tab), by comparing the old and new WebContents. | 277 // tab), by comparing the old and new WebContents. |
272 if (escape_pressed && | 278 if (escape_pressed && |
273 instant_tab_->contents() == browser_->GetActiveWebContents()) { | 279 instant_tab_->contents() == browser_->GetActiveWebContents()) { |
274 instant_tab_->Submit(full_text); | 280 instant_tab_->Submit(full_text); |
275 } | 281 } |
276 } else if (!full_text.empty()) { | 282 } else if (!full_text.empty()) { |
277 // If |full_text| is empty, the user is on the NTP. The preview may | 283 // If |full_text| is empty, the user is on the NTP. The preview may |
278 // be showing custom NTP content; hide only if that's not the case. | 284 // be showing custom NTP content; hide only if that's not the case. |
279 HideLoader(); | 285 HideOverlay(); |
280 } | 286 } |
281 } else if (full_text.empty()) { | 287 } else if (full_text.empty()) { |
282 // The user is typing, and backspaced away all omnibox text. Clear | 288 // The user is typing, and backspaced away all omnibox text. Clear |
283 // |last_omnibox_text_| so that we don't attempt to set suggestions. | 289 // |last_omnibox_text_| so that we don't attempt to set suggestions. |
284 last_omnibox_text_.clear(); | 290 last_omnibox_text_.clear(); |
285 last_suggestion_ = InstantSuggestion(); | 291 last_suggestion_ = InstantSuggestion(); |
286 if (instant_tab_) { | 292 if (instant_tab_) { |
287 // On a search results page, tell it to clear old results. | 293 // On a search results page, tell it to clear old results. |
288 instant_tab_->Update(string16(), 0, 0, true); | 294 instant_tab_->Update(string16(), 0, 0, true); |
289 } else if (search_mode_.is_origin_ntp()) { | 295 } else if (search_mode_.is_origin_ntp()) { |
290 // On the NTP, tell the preview to clear old results. Don't hide the | 296 // On the NTP, tell the preview to clear old results. Don't hide the |
291 // preview so it can show a blank page or logo if it wants. | 297 // preview so it can show a blank page or logo if it wants. |
292 loader_->Update(string16(), 0, 0, true); | 298 overlay_->Update(string16(), 0, 0, true); |
293 } else { | 299 } else { |
294 HideLoader(); | 300 HideOverlay(); |
295 } | 301 } |
296 } else { | 302 } else { |
297 // The user switched to a tab with partial text already in the omnibox. | 303 // The user switched to a tab with partial text already in the omnibox. |
298 HideLoader(); | 304 HideOverlay(); |
299 | 305 |
300 // The new tab may or may not be a search results page; we don't know | 306 // The new tab may or may not be a search results page; we don't know |
301 // since SearchModeChanged() hasn't been called yet. If it later turns | 307 // since SearchModeChanged() hasn't been called yet. If it later turns |
302 // out to be, we should store |full_text| now, so that if the user hits | 308 // out to be, we should store |full_text| now, so that if the user hits |
303 // Enter, we'll send the correct query to instant_tab_->Submit(). If the | 309 // Enter, we'll send the correct query to instant_tab_->Submit(). If the |
304 // partial text is not a query (|last_match_was_search_| is false), we | 310 // partial text is not a query (|last_match_was_search_| is false), we |
305 // won't Submit(), so no need to worry about that. | 311 // won't Submit(), so no need to worry about that. |
306 last_omnibox_text_ = full_text; | 312 last_omnibox_text_ = full_text; |
307 last_suggestion_ = InstantSuggestion(); | 313 last_suggestion_ = InstantSuggestion(); |
308 } | 314 } |
309 return false; | 315 return false; |
310 } else if (full_text.empty()) { | 316 } else if (full_text.empty()) { |
311 // The user typed a solitary "?". Same as the backspace case above. | 317 // The user typed a solitary "?". Same as the backspace case above. |
312 last_omnibox_text_.clear(); | 318 last_omnibox_text_.clear(); |
313 last_suggestion_ = InstantSuggestion(); | 319 last_suggestion_ = InstantSuggestion(); |
314 if (instant_tab_) | 320 if (instant_tab_) |
315 instant_tab_->Update(string16(), 0, 0, true); | 321 instant_tab_->Update(string16(), 0, 0, true); |
316 else if (search_mode_.is_origin_ntp()) | 322 else if (search_mode_.is_origin_ntp()) |
317 loader_->Update(string16(), 0, 0, true); | 323 overlay_->Update(string16(), 0, 0, true); |
318 else | 324 else |
319 HideLoader(); | 325 HideOverlay(); |
320 return false; | 326 return false; |
321 } | 327 } |
322 } else if (!omnibox_popup_is_open || full_text.empty()) { | 328 } else if (!omnibox_popup_is_open || full_text.empty()) { |
323 // In the non-extended case, hide the preview as long as the user isn't | 329 // In the non-extended case, hide the preview as long as the user isn't |
324 // actively typing a non-empty query. | 330 // actively typing a non-empty query. |
325 HideLoader(); | 331 HideOverlay(); |
326 return false; | 332 return false; |
327 } | 333 } |
328 | 334 |
329 last_omnibox_text_has_inline_autocompletion_ = user_text != full_text; | 335 last_omnibox_text_has_inline_autocompletion_ = user_text != full_text; |
330 | 336 |
331 // If the user continues typing the same query as the suggested text is | 337 // If the user continues typing the same query as the suggested text is |
332 // showing, reuse the suggestion (but only for INSTANT_COMPLETE_NEVER). | 338 // showing, reuse the suggestion (but only for INSTANT_COMPLETE_NEVER). |
333 bool reused_suggestion = false; | 339 bool reused_suggestion = false; |
334 if (last_suggestion_.behavior == INSTANT_COMPLETE_NEVER && | 340 if (last_suggestion_.behavior == INSTANT_COMPLETE_NEVER && |
335 !last_omnibox_text_has_inline_autocompletion_) { | 341 !last_omnibox_text_has_inline_autocompletion_) { |
(...skipping 23 matching lines...) Expand all Loading... | |
359 | 365 |
360 last_transition_type_ = match.transition; | 366 last_transition_type_ = match.transition; |
361 url_for_history_ = match.destination_url; | 367 url_for_history_ = match.destination_url; |
362 | 368 |
363 // Allow search suggestions. In extended mode, SearchModeChanged() will set | 369 // Allow search suggestions. In extended mode, SearchModeChanged() will set |
364 // this, but it's not called in non-extended mode, so fake it. | 370 // this, but it's not called in non-extended mode, so fake it. |
365 if (!extended_enabled_) | 371 if (!extended_enabled_) |
366 search_mode_.mode = chrome::search::Mode::MODE_SEARCH_SUGGESTIONS; | 372 search_mode_.mode = chrome::search::Mode::MODE_SEARCH_SUGGESTIONS; |
367 | 373 |
368 if (instant_tab_) { | 374 if (instant_tab_) { |
369 instant_tab_->Update(user_text, selection_start, selection_end, verbatim); | 375 instant_tab_->Update(user_text, selection_start, |
376 selection_end, verbatim); | |
370 } else { | 377 } else { |
371 if (first_interaction_time_.is_null()) | 378 if (first_interaction_time_.is_null()) |
372 first_interaction_time_ = base::Time::Now(); | 379 first_interaction_time_ = base::Time::Now(); |
373 allow_preview_to_show_search_suggestions_ = true; | 380 allow_preview_to_show_search_suggestions_ = true; |
374 loader_->Update(extended_enabled_ ? user_text : full_text, | 381 overlay_->Update(extended_enabled_ ? user_text : full_text, |
375 selection_start, selection_end, verbatim); | 382 selection_start, selection_end, verbatim); |
376 } | 383 } |
377 | 384 |
378 content::NotificationService::current()->Notify( | 385 content::NotificationService::current()->Notify( |
379 chrome::NOTIFICATION_INSTANT_CONTROLLER_UPDATED, | 386 chrome::NOTIFICATION_INSTANT_CONTROLLER_UPDATED, |
380 content::Source<InstantController>(this), | 387 content::Source<InstantController>(this), |
381 content::NotificationService::NoDetails()); | 388 content::NotificationService::NoDetails()); |
382 | 389 |
383 // We don't have new suggestions yet, but we can either reuse the existing | 390 // We don't have new suggestions yet, but we can either reuse the existing |
384 // suggestion or reset the existing "gray text". | 391 // suggestion or reset the existing "gray text". |
385 browser_->SetInstantSuggestion(last_suggestion_); | 392 browser_->SetInstantSuggestion(last_suggestion_); |
386 | 393 |
387 return true; | 394 return true; |
388 } | 395 } |
389 | 396 |
397 content::WebContents* InstantController::ReleaseNTPContents() { | |
398 if (!extended_enabled_ || !ntp_) | |
dhollowa
2013/01/22 22:34:58
Should this be a DCHECK? Should the caller be ask
samarth
2013/01/25 21:08:40
There are legitimate cases where this can happen (
| |
399 return NULL; | |
400 | |
401 content::WebContents* ntp_contents = ntp_->ReleaseContents(); | |
402 ntp_.reset(); | |
403 ResetNTP(); | |
404 return ntp_contents; | |
405 } | |
406 | |
390 // TODO(tonyg): This method only fires when the omnibox bounds change. It also | 407 // TODO(tonyg): This method only fires when the omnibox bounds change. It also |
391 // needs to fire when the preview bounds change (e.g.: open/close info bar). | 408 // needs to fire when the preview bounds change (e.g.: open/close info bar). |
392 void InstantController::SetPopupBounds(const gfx::Rect& bounds) { | 409 void InstantController::SetPopupBounds(const gfx::Rect& bounds) { |
393 if (!extended_enabled_ && !instant_enabled_) | 410 if (!extended_enabled_ && !instant_enabled_) |
394 return; | 411 return; |
395 | 412 |
396 if (popup_bounds_ == bounds) | 413 if (popup_bounds_ == bounds) |
397 return; | 414 return; |
398 | 415 |
399 popup_bounds_ = bounds; | 416 popup_bounds_ = bounds; |
400 if (popup_bounds_.height() > last_popup_bounds_.height()) { | 417 if (popup_bounds_.height() > last_popup_bounds_.height()) { |
401 update_bounds_timer_.Stop(); | 418 update_bounds_timer_.Stop(); |
402 SendPopupBoundsToPage(); | 419 SendPopupBoundsToPage(); |
403 } else if (!update_bounds_timer_.IsRunning()) { | 420 } else if (!update_bounds_timer_.IsRunning()) { |
404 update_bounds_timer_.Start(FROM_HERE, | 421 update_bounds_timer_.Start(FROM_HERE, |
405 base::TimeDelta::FromMilliseconds(kUpdateBoundsDelayMS), this, | 422 base::TimeDelta::FromMilliseconds(kUpdateBoundsDelayMS), this, |
406 &InstantController::SendPopupBoundsToPage); | 423 &InstantController::SendPopupBoundsToPage); |
407 } | 424 } |
408 } | 425 } |
409 | 426 |
410 void InstantController::SetMarginSize(int start, int end) { | 427 void InstantController::SetMarginSize(int start, int end) { |
411 if (!extended_enabled_ || (start_margin_ == start && end_margin_ == end)) | 428 if (!extended_enabled_ || (start_margin_ == start && end_margin_ == end)) |
412 return; | 429 return; |
413 | 430 |
414 start_margin_ = start; | 431 start_margin_ = start; |
415 end_margin_ = end; | 432 end_margin_ = end; |
416 if (loader_) | 433 if (overlay_) |
417 loader_->SetMarginSize(start_margin_, end_margin_); | 434 overlay_->SetMarginSize(start_margin_, end_margin_); |
435 if (ntp_) | |
436 ntp_->SetMarginSize(start_margin_, end_margin_); | |
418 if (instant_tab_) | 437 if (instant_tab_) |
419 instant_tab_->SetMarginSize(start_margin_, end_margin_); | 438 instant_tab_->SetMarginSize(start_margin_, end_margin_); |
420 } | 439 } |
421 | 440 |
422 void InstantController::HandleAutocompleteResults( | 441 void InstantController::HandleAutocompleteResults( |
423 const std::vector<AutocompleteProvider*>& providers) { | 442 const std::vector<AutocompleteProvider*>& providers) { |
424 if (!extended_enabled_) | 443 if (!extended_enabled_) |
425 return; | 444 return; |
426 | 445 |
427 if (!instant_tab_ && !loader_) | 446 if (!instant_tab_ && !overlay_) |
428 return; | 447 return; |
429 | 448 |
430 DVLOG(1) << "AutocompleteResults:"; | 449 DVLOG(1) << "AutocompleteResults:"; |
431 std::vector<InstantAutocompleteResult> results; | 450 std::vector<InstantAutocompleteResult> results; |
432 for (ACProviders::const_iterator provider = providers.begin(); | 451 for (ACProviders::const_iterator provider = providers.begin(); |
433 provider != providers.end(); ++provider) { | 452 provider != providers.end(); ++provider) { |
434 for (ACMatches::const_iterator match = (*provider)->matches().begin(); | 453 for (ACMatches::const_iterator match = (*provider)->matches().begin(); |
435 match != (*provider)->matches().end(); ++match) { | 454 match != (*provider)->matches().end(); ++match) { |
436 InstantAutocompleteResult result; | 455 InstantAutocompleteResult result; |
437 result.provider = UTF8ToUTF16((*provider)->GetName()); | 456 result.provider = UTF8ToUTF16((*provider)->GetName()); |
438 result.type = UTF8ToUTF16(AutocompleteMatch::TypeToString(match->type)); | 457 result.type = UTF8ToUTF16(AutocompleteMatch::TypeToString(match->type)); |
439 result.description = match->description; | 458 result.description = match->description; |
440 result.destination_url = UTF8ToUTF16(match->destination_url.spec()); | 459 result.destination_url = UTF8ToUTF16(match->destination_url.spec()); |
441 result.transition = match->transition; | 460 result.transition = match->transition; |
442 result.relevance = match->relevance; | 461 result.relevance = match->relevance; |
443 DVLOG(1) << " " << result.relevance << " " << result.type << " " | 462 DVLOG(1) << " " << result.relevance << " " << result.type << " " |
444 << result.provider << " " << result.destination_url << " '" | 463 << result.provider << " " << result.destination_url << " '" |
445 << result.description << "' " << result.transition; | 464 << result.description << "' " << result.transition; |
446 results.push_back(result); | 465 results.push_back(result); |
447 } | 466 } |
448 } | 467 } |
449 | 468 |
450 if (instant_tab_) | 469 if (instant_tab_) |
451 instant_tab_->SendAutocompleteResults(results); | 470 instant_tab_->SendAutocompleteResults(results); |
452 else | 471 else |
453 loader_->SendAutocompleteResults(results); | 472 overlay_->SendAutocompleteResults(results); |
454 } | 473 } |
455 | 474 |
456 bool InstantController::OnUpOrDownKeyPressed(int count) { | 475 bool InstantController::OnUpOrDownKeyPressed(int count) { |
457 if (!extended_enabled_) | 476 if (!extended_enabled_) |
458 return false; | 477 return false; |
459 | 478 |
460 if (!instant_tab_ && !loader_) | 479 if (!instant_tab_ && !overlay_) |
461 return false; | 480 return false; |
462 | 481 |
463 if (instant_tab_) | 482 if (instant_tab_) |
464 instant_tab_->UpOrDownKeyPressed(count); | 483 instant_tab_->UpOrDownKeyPressed(count); |
465 else | 484 else |
466 loader_->UpOrDownKeyPressed(count); | 485 overlay_->UpOrDownKeyPressed(count); |
467 | 486 |
468 return true; | 487 return true; |
469 } | 488 } |
470 | 489 |
471 content::WebContents* InstantController::GetPreviewContents() const { | 490 content::WebContents* InstantController::GetPreviewContents() const { |
472 return loader_ ? loader_->contents() : NULL; | 491 return overlay_ ? overlay_->contents() : NULL; |
473 } | 492 } |
474 | 493 |
475 bool InstantController::IsPreviewingSearchResults() const { | 494 bool InstantController::IsPreviewingSearchResults() const { |
476 return model_.mode().is_search_suggestions() && IsFullHeight(model_) && | 495 return model_.mode().is_search_suggestions() && IsFullHeight(model_) && |
477 (last_match_was_search_ || | 496 (last_match_was_search_ || |
478 last_suggestion_.behavior == INSTANT_COMPLETE_NEVER); | 497 last_suggestion_.behavior == INSTANT_COMPLETE_NEVER); |
479 } | 498 } |
480 | 499 |
481 bool InstantController::CommitIfPossible(InstantCommitType type) { | 500 bool InstantController::CommitIfPossible(InstantCommitType type) { |
482 if (!extended_enabled_ && !instant_enabled_) | 501 if (!extended_enabled_ && !instant_enabled_) |
(...skipping 14 matching lines...) Expand all Loading... | |
497 return true; | 516 return true; |
498 } | 517 } |
499 return false; | 518 return false; |
500 } | 519 } |
501 | 520 |
502 if (!IsPreviewingSearchResults() && type != INSTANT_COMMIT_NAVIGATED) | 521 if (!IsPreviewingSearchResults() && type != INSTANT_COMMIT_NAVIGATED) |
503 return false; | 522 return false; |
504 | 523 |
505 // There may re-entrance here, from the call to browser_->CommitInstant below, | 524 // There may re-entrance here, from the call to browser_->CommitInstant below, |
506 // which can cause a TabDeactivated notification which gets back here. | 525 // which can cause a TabDeactivated notification which gets back here. |
507 // In this case, loader_->ReleaseContents() was called already. | 526 // In this case, overlay_->ReleaseContents() was called already. |
508 if (!GetPreviewContents()) | 527 if (!GetPreviewContents()) |
509 return false; | 528 return false; |
510 | 529 |
511 // Never commit the local omnibox. | 530 // Never commit the local omnibox. |
512 if (loader_->IsUsingLocalPreview()) | 531 if (overlay_->IsUsingLocalPreview()) |
513 return false; | 532 return false; |
514 | 533 |
515 if (type == INSTANT_COMMIT_FOCUS_LOST) | 534 if (type == INSTANT_COMMIT_FOCUS_LOST) |
516 loader_->Cancel(last_omnibox_text_); | 535 overlay_->Cancel(last_omnibox_text_); |
517 else if (type != INSTANT_COMMIT_NAVIGATED && | 536 else if (type != INSTANT_COMMIT_NAVIGATED && |
518 type != INSTANT_COMMIT_CLICKED_QUERY_SUGGESTION) | 537 type != INSTANT_COMMIT_CLICKED_QUERY_SUGGESTION) |
519 loader_->Submit(last_omnibox_text_); | 538 overlay_->Submit(last_omnibox_text_); |
520 | 539 |
521 content::WebContents* preview = loader_->ReleaseContents(); | 540 content::WebContents* preview = overlay_->ReleaseContents(); |
522 | 541 |
523 if (extended_enabled_) { | 542 if (extended_enabled_) { |
524 // Consider what's happening: | 543 // Consider what's happening: |
525 // 1. The user has typed a query in the omnibox and committed it (either | 544 // 1. The user has typed a query in the omnibox and committed it (either |
526 // by pressing Enter or clicking on the preview). | 545 // by pressing Enter or clicking on the preview). |
527 // 2. We commit the preview to the tab strip, and tell the page. | 546 // 2. We commit the preview to the tab strip, and tell the page. |
528 // 3. The page will update the URL hash fragment with the query terms. | 547 // 3. The page will update the URL hash fragment with the query terms. |
529 // After steps 1 and 3, the omnibox will show the query terms. However, if | 548 // After steps 1 and 3, the omnibox will show the query terms. However, if |
530 // the URL we are committing at step 2 doesn't already have query terms, it | 549 // the URL we are committing at step 2 doesn't already have query terms, it |
531 // will flash for a brief moment as a plain URL. So, avoid that flicker by | 550 // will flash for a brief moment as a plain URL. So, avoid that flicker by |
(...skipping 17 matching lines...) Expand all Loading... | |
549 net::EscapeQueryParamValue(query, true))); | 568 net::EscapeQueryParamValue(query, true))); |
550 chrome::search::SearchTabHelper::FromWebContents(preview)-> | 569 chrome::search::SearchTabHelper::FromWebContents(preview)-> |
551 NavigationEntryUpdated(); | 570 NavigationEntryUpdated(); |
552 } | 571 } |
553 } | 572 } |
554 | 573 |
555 // If the preview page has navigated since the last Update(), we need to add | 574 // If the preview page has navigated since the last Update(), we need to add |
556 // the navigation to history ourselves. Else, the page will navigate after | 575 // the navigation to history ourselves. Else, the page will navigate after |
557 // commit, and it will be added to history in the usual manner. | 576 // commit, and it will be added to history in the usual manner. |
558 const history::HistoryAddPageArgs& last_navigation = | 577 const history::HistoryAddPageArgs& last_navigation = |
559 loader_->last_navigation(); | 578 overlay_->last_navigation(); |
560 if (!last_navigation.url.is_empty()) { | 579 if (!last_navigation.url.is_empty()) { |
561 content::NavigationEntry* entry = preview->GetController().GetActiveEntry(); | 580 content::NavigationEntry* entry = preview->GetController().GetActiveEntry(); |
562 | 581 |
563 // The last navigation should be the same as the active entry if the loader | 582 // The last navigation should be the same as the active entry if the overlay |
564 // is in search mode. During navigation, the active entry could have | 583 // is in search mode. During navigation, the active entry could have |
565 // changed since DidCommitProvisionalLoadForFrame is called after the entry | 584 // changed since DidCommitProvisionalLoadForFrame is called after the entry |
566 // is changed. | 585 // is changed. |
567 // TODO(shishir): Should we commit the last navigation for | 586 // TODO(shishir): Should we commit the last navigation for |
568 // INSTANT_COMMIT_NAVIGATED. | 587 // INSTANT_COMMIT_NAVIGATED. |
569 DCHECK(type == INSTANT_COMMIT_NAVIGATED || | 588 DCHECK(type == INSTANT_COMMIT_NAVIGATED || |
570 last_navigation.url == entry->GetURL()); | 589 last_navigation.url == entry->GetURL()); |
571 | 590 |
572 // Add the page to history. | 591 // Add the page to history. |
573 HistoryTabHelper* history_tab_helper = | 592 HistoryTabHelper* history_tab_helper = |
(...skipping 25 matching lines...) Expand all Loading... | |
599 } | 618 } |
600 | 619 |
601 // Browser takes ownership of the preview. | 620 // Browser takes ownership of the preview. |
602 browser_->CommitInstant(preview, type == INSTANT_COMMIT_PRESSED_ALT_ENTER); | 621 browser_->CommitInstant(preview, type == INSTANT_COMMIT_PRESSED_ALT_ENTER); |
603 | 622 |
604 content::NotificationService::current()->Notify( | 623 content::NotificationService::current()->Notify( |
605 chrome::NOTIFICATION_INSTANT_COMMITTED, | 624 chrome::NOTIFICATION_INSTANT_COMMITTED, |
606 content::Source<content::WebContents>(preview), | 625 content::Source<content::WebContents>(preview), |
607 content::NotificationService::NoDetails()); | 626 content::NotificationService::NoDetails()); |
608 | 627 |
609 // Hide explicitly. See comments in HideLoader() for why. | 628 // Hide explicitly. See comments in HideOverlay() for why. |
610 model_.SetPreviewState(chrome::search::Mode(), 0, INSTANT_SIZE_PERCENT); | 629 model_.SetPreviewState(chrome::search::Mode(), 0, INSTANT_SIZE_PERCENT); |
611 | 630 |
612 // Delay deletion as we could've gotten here from an InstantLoader method. | 631 // Delay deletion as we could've gotten here from an InstantOverlay method. |
613 MessageLoop::current()->DeleteSoon(FROM_HERE, loader_.release()); | 632 MessageLoop::current()->DeleteSoon(FROM_HERE, overlay_.release()); |
614 | 633 |
615 // Try to create another loader immediately so that it is ready for the next | 634 // Try to create another overlay immediately so that it is ready for the next |
616 // user interaction. | 635 // user interaction. |
617 CreateDefaultLoader(); | 636 CreateDefaultOverlay(); |
618 | 637 |
619 return true; | 638 return true; |
620 } | 639 } |
621 | 640 |
622 void InstantController::OmniboxFocusChanged( | 641 void InstantController::OmniboxFocusChanged( |
623 OmniboxFocusState state, | 642 OmniboxFocusState state, |
624 OmniboxFocusChangeReason reason, | 643 OmniboxFocusChangeReason reason, |
625 gfx::NativeView view_gaining_focus) { | 644 gfx::NativeView view_gaining_focus) { |
626 DVLOG(1) << "OmniboxFocusChanged: " << omnibox_focus_state_ << " to " | 645 DVLOG(1) << "OmniboxFocusChanged: " << omnibox_focus_state_ << " to " |
627 << state << " for reason " << reason; | 646 << state << " for reason " << reason; |
628 | 647 |
629 OmniboxFocusState old_focus_state = omnibox_focus_state_; | 648 OmniboxFocusState old_focus_state = omnibox_focus_state_; |
630 omnibox_focus_state_ = state; | 649 omnibox_focus_state_ = state; |
631 if (!extended_enabled_ && !instant_enabled_) | 650 if (!extended_enabled_ && !instant_enabled_) |
632 return; | 651 return; |
633 | 652 |
634 // Tell the page if the key capture mode changed unless the focus state | 653 // Tell the page if the key capture mode changed unless the focus state |
635 // changed because of TYPING. This is because in that case, the browser hasn't | 654 // changed because of TYPING. This is because in that case, the browser hasn't |
636 // really stopped capturing key strokes. | 655 // really stopped capturing key strokes. |
637 // | 656 // |
638 // (More practically, if we don't do this check, the page would receive | 657 // (More practically, if we don't do this check, the page would receive |
639 // onkeycapturechange before the corresponding onchange, and the page would | 658 // onkeycapturechange before the corresponding onchange, and the page would |
640 // have no way of telling whether the keycapturechange happened because of | 659 // have no way of telling whether the keycapturechange happened because of |
641 // some actual user action or just because they started typing.) | 660 // some actual user action or just because they started typing.) |
642 if (extended_enabled_ && GetPreviewContents() && | 661 if (extended_enabled_ && GetPreviewContents() && |
643 reason != OMNIBOX_FOCUS_CHANGE_TYPING) | 662 reason != OMNIBOX_FOCUS_CHANGE_TYPING) { |
644 loader_->KeyCaptureChanged(omnibox_focus_state_ == OMNIBOX_FOCUS_INVISIBLE); | 663 const bool is_key_capture_enabled = |
664 omnibox_focus_state_ == OMNIBOX_FOCUS_INVISIBLE; | |
665 if (overlay_) | |
666 overlay_->KeyCaptureChanged(is_key_capture_enabled); | |
667 if (instant_tab_) | |
668 instant_tab_->KeyCaptureChanged(is_key_capture_enabled); | |
669 } | |
645 | 670 |
646 // If focus went from outside the omnibox to the omnibox, preload the default | 671 // If focus went from outside the omnibox to the omnibox, preload the default |
647 // search engine, in anticipation of the user typing a query. If the reverse | 672 // search engine, in anticipation of the user typing a query. If the reverse |
648 // happened, commit or discard the preview. | 673 // happened, commit or discard the preview. |
649 if (state != OMNIBOX_FOCUS_NONE && old_focus_state == OMNIBOX_FOCUS_NONE) | 674 if (state != OMNIBOX_FOCUS_NONE && old_focus_state == OMNIBOX_FOCUS_NONE) |
650 CreateDefaultLoader(); | 675 CreateDefaultOverlay(); |
651 else if (state == OMNIBOX_FOCUS_NONE && old_focus_state != OMNIBOX_FOCUS_NONE) | 676 else if (state == OMNIBOX_FOCUS_NONE && old_focus_state != OMNIBOX_FOCUS_NONE) |
652 OmniboxLostFocus(view_gaining_focus); | 677 OmniboxLostFocus(view_gaining_focus); |
653 } | 678 } |
654 | 679 |
655 void InstantController::SearchModeChanged( | 680 void InstantController::SearchModeChanged( |
656 const chrome::search::Mode& old_mode, | 681 const chrome::search::Mode& old_mode, |
657 const chrome::search::Mode& new_mode) { | 682 const chrome::search::Mode& new_mode) { |
658 if (!extended_enabled_) | 683 if (!extended_enabled_) |
659 return; | 684 return; |
660 | 685 |
661 DVLOG(1) << "SearchModeChanged: [origin:mode] " << old_mode.origin << ":" | 686 DVLOG(1) << "SearchModeChanged: [origin:mode] " << old_mode.origin << ":" |
662 << old_mode.mode << " to " << new_mode.origin << ":" | 687 << old_mode.mode << " to " << new_mode.origin << ":" |
663 << new_mode.mode; | 688 << new_mode.mode; |
664 | 689 |
665 search_mode_ = new_mode; | 690 search_mode_ = new_mode; |
666 if (!new_mode.is_search_suggestions()) | 691 if (!new_mode.is_search_suggestions()) |
667 HideLoader(); | 692 HideOverlay(); |
668 | 693 |
669 if (loader_) | 694 if (overlay_) |
670 loader_->SearchModeChanged(new_mode); | 695 overlay_->SearchModeChanged(new_mode); |
671 | 696 |
672 ResetInstantTab(); | 697 ResetInstantTab(); |
673 } | 698 } |
674 | 699 |
675 void InstantController::ActiveTabChanged() { | 700 void InstantController::ActiveTabChanged() { |
676 if (!extended_enabled_ && !instant_enabled_) | 701 if (!extended_enabled_ && !instant_enabled_) |
677 return; | 702 return; |
678 | 703 |
679 DVLOG(1) << "ActiveTabChanged"; | 704 DVLOG(1) << "ActiveTabChanged"; |
680 | 705 |
681 // When switching tabs, always hide the preview, except if it's showing NTP | 706 // When switching tabs, always hide the preview. |
682 // content, and the new tab is also an NTP. | 707 HideOverlay(); |
683 if (!search_mode_.is_ntp() || !model_.mode().is_ntp()) | |
684 HideLoader(); | |
685 | 708 |
686 if (extended_enabled_) | 709 if (extended_enabled_) |
687 ResetInstantTab(); | 710 ResetInstantTab(); |
688 } | 711 } |
689 | 712 |
690 void InstantController::TabDeactivated(content::WebContents* contents) { | 713 void InstantController::TabDeactivated(content::WebContents* contents) { |
691 DVLOG(1) << "TabDeactivated"; | 714 DVLOG(1) << "TabDeactivated"; |
692 if (extended_enabled_ && !contents->IsBeingDestroyed()) | 715 if (extended_enabled_ && !contents->IsBeingDestroyed()) |
693 CommitIfPossible(INSTANT_COMMIT_FOCUS_LOST); | 716 CommitIfPossible(INSTANT_COMMIT_FOCUS_LOST); |
694 } | 717 } |
695 | 718 |
696 void InstantController::SetInstantEnabled(bool instant_enabled) { | 719 void InstantController::SetInstantEnabled(bool instant_enabled) { |
697 DVLOG(1) << "SetInstantEnabled: " << instant_enabled; | 720 DVLOG(1) << "SetInstantEnabled: " << instant_enabled; |
698 instant_enabled_ = instant_enabled; | 721 instant_enabled_ = instant_enabled; |
699 HideInternal(); | 722 HideInternal(); |
700 loader_.reset(); | 723 overlay_.reset(); |
701 if (extended_enabled_ || instant_enabled_) | 724 if (extended_enabled_ || instant_enabled_) |
702 CreateDefaultLoader(); | 725 CreateDefaultOverlay(); |
726 if (extended_enabled_) | |
727 ResetNTP(); | |
703 if (instant_tab_) | 728 if (instant_tab_) |
704 instant_tab_->SetDisplayInstantResults(instant_enabled_); | 729 instant_tab_->SetDisplayInstantResults(instant_enabled_); |
705 } | 730 } |
706 | 731 |
707 void InstantController::ThemeChanged(const ThemeBackgroundInfo& theme_info) { | 732 void InstantController::ThemeChanged(const ThemeBackgroundInfo& theme_info) { |
708 if (!extended_enabled_) | 733 if (!extended_enabled_) |
709 return; | 734 return; |
710 | 735 |
711 if (loader_) | 736 if (overlay_) |
712 loader_->SendThemeBackgroundInfo(theme_info); | 737 overlay_->SendThemeBackgroundInfo(theme_info); |
738 if (ntp_) | |
739 ntp_->SendThemeBackgroundInfo(theme_info); | |
713 } | 740 } |
714 | 741 |
715 void InstantController::ThemeAreaHeightChanged(int height) { | 742 void InstantController::ThemeAreaHeightChanged(int height) { |
716 if (!extended_enabled_) | 743 if (!extended_enabled_) |
717 return; | 744 return; |
718 | 745 |
719 if (loader_) | 746 if (overlay_) |
720 loader_->SendThemeAreaHeight(height); | 747 overlay_->SendThemeAreaHeight(height); |
748 if (ntp_) | |
749 ntp_->SendThemeAreaHeight(height); | |
750 } | |
751 | |
752 void InstantController::InstantSupportDetermined( | |
753 const content::WebContents* contents, | |
754 bool supports_instant) { | |
755 if (ContentsFrom(instant_tab_.get(), contents)) { | |
756 if (!supports_instant) | |
757 MessageLoop::current()->DeleteSoon(FROM_HERE, instant_tab_.release()); | |
758 } else if (ContentsFrom(ntp_.get(), contents)) { | |
759 if (supports_instant) { | |
760 RemoveFromBlacklist(ntp_->instant_url()); | |
761 } else { | |
762 AddToBlacklist(ntp_->instant_url()); | |
763 delete ntp_->ReleaseContents(); | |
dhollowa
2013/01/22 22:34:58
This deletion logic looks similar to :773, :789, :
samarth
2013/01/25 21:08:40
Done.
| |
764 ntp_.reset(); | |
765 ResetNTP(); | |
766 } | |
767 } else if (ContentsFrom(overlay_.get(), contents)) { | |
768 if (supports_instant) { | |
769 RemoveFromBlacklist(overlay_->instant_url()); | |
770 } else { | |
771 AddToBlacklist(overlay_->instant_url()); | |
772 HideInternal(); | |
773 delete overlay_->ReleaseContents(); | |
774 overlay_.reset(); | |
775 CreateDefaultOverlay(); | |
776 } | |
777 content::NotificationService::current()->Notify( | |
778 chrome::NOTIFICATION_INSTANT_SUPPORT_DETERMINED, | |
779 content::Source<InstantController>(this), | |
780 content::NotificationService::NoDetails()); | |
781 } | |
782 } | |
783 | |
784 void InstantController::InstantPageRenderViewGone( | |
785 const content::WebContents* contents) { | |
786 if (ContentsFrom(overlay_.get(), contents)) { | |
787 AddToBlacklist(overlay_->instant_url()); | |
788 HideInternal(); | |
789 delete overlay_->ReleaseContents(); | |
790 overlay_.reset(); | |
791 CreateDefaultOverlay(); | |
792 } else if (ContentsFrom(ntp_.get(), contents)) { | |
793 AddToBlacklist(ntp_->instant_url()); | |
794 delete ntp_->ReleaseContents(); | |
795 ntp_.reset(); | |
796 ResetNTP(); | |
797 } | |
798 } | |
799 | |
800 void InstantController::InstantPageAboutToNavigateMainFrame( | |
801 const content::WebContents* contents, | |
802 const GURL& url) { | |
803 if (!ContentsFrom(overlay_.get(), contents)) | |
804 return; | |
805 | |
806 // If the page does not yet support instant, we allow redirects and other | |
807 // navigations to go through since the instant URL can redirect - e.g. to | |
808 // country specific pages. | |
809 if (!overlay_->supports_instant()) | |
810 return; | |
811 | |
812 GURL instant_url(overlay_->instant_url()); | |
813 | |
814 // If we are navigating to the instant URL, do nothing. | |
815 if (url == instant_url) | |
816 return; | |
817 | |
818 // Commit the navigation if either: | |
819 // - The page is in NTP mode (so it could only navigate on a user click) or | |
820 // - The page is not in NTP mode and we are navigating to a URL with a | |
821 // different host or path than the instant URL. This enables the instant | |
822 // page when it is showing search results to change the query parameters | |
823 // and fragments of the URL without it navigating. | |
824 if (model_.mode().is_ntp() || | |
825 (url.host() != instant_url.host() || url.path() != instant_url.path())) { | |
826 CommitIfPossible(INSTANT_COMMIT_NAVIGATED); | |
827 } | |
721 } | 828 } |
722 | 829 |
723 void InstantController::SetSuggestions( | 830 void InstantController::SetSuggestions( |
724 const content::WebContents* contents, | 831 const content::WebContents* contents, |
725 const std::vector<InstantSuggestion>& suggestions) { | 832 const std::vector<InstantSuggestion>& suggestions) { |
726 DVLOG(1) << "SetSuggestions"; | 833 DVLOG(1) << "SetSuggestions"; |
727 | 834 |
728 // Ignore if the message is from an unexpected source. | 835 // Ignore if the message is from an unexpected source. |
729 if (instant_tab_) { | 836 if (ContentsFrom(ntp_.get(), contents)) |
730 if (instant_tab_->contents() != contents) | |
731 return; | |
732 } else if (!loader_ || loader_->contents() != contents || | |
733 !allow_preview_to_show_search_suggestions_) { | |
734 return; | 837 return; |
735 } | 838 if (instant_tab_ && !ContentsFrom(instant_tab_.get(), contents)) |
839 return; | |
840 if (ContentsFrom(overlay_.get(), contents) && | |
841 !allow_preview_to_show_search_suggestions_) | |
842 return; | |
736 | 843 |
737 InstantSuggestion suggestion; | 844 InstantSuggestion suggestion; |
738 if (!suggestions.empty()) | 845 if (!suggestions.empty()) |
739 suggestion = suggestions[0]; | 846 suggestion = suggestions[0]; |
740 | 847 |
741 if (instant_tab_ && search_mode_.is_search_results() && | 848 if (instant_tab_ && search_mode_.is_search_results() && |
742 suggestion.behavior == INSTANT_COMPLETE_REPLACE) { | 849 suggestion.behavior == INSTANT_COMPLETE_REPLACE) { |
743 // This means a committed page in state search called setValue(). We should | 850 // This means a committed page in state search called setValue(). We should |
744 // update the omnibox to reflect what the search page says. | 851 // update the omnibox to reflect what the search page says. |
745 browser_->SetInstantSuggestion(suggestion); | 852 browser_->SetInstantSuggestion(suggestion); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
802 last_suggestion_ = suggestion; | 909 last_suggestion_ = suggestion; |
803 DVLOG(1) << "SetInstantSuggestion: text='" << suggestion.text << "'" | 910 DVLOG(1) << "SetInstantSuggestion: text='" << suggestion.text << "'" |
804 << " behavior=" << suggestion.behavior << " type=" | 911 << " behavior=" << suggestion.behavior << " type=" |
805 << suggestion.type; | 912 << suggestion.type; |
806 browser_->SetInstantSuggestion(suggestion); | 913 browser_->SetInstantSuggestion(suggestion); |
807 } else { | 914 } else { |
808 last_suggestion_ = InstantSuggestion(); | 915 last_suggestion_ = InstantSuggestion(); |
809 } | 916 } |
810 } | 917 } |
811 | 918 |
812 // Extended mode pages will call ShowLoader() when they are ready. | 919 // Extended mode pages will call ShowOverlay() when they are ready. |
813 if (!extended_enabled_) | 920 if (!extended_enabled_) |
814 ShowLoader(INSTANT_SHOWN_QUERY_SUGGESTIONS, 100, INSTANT_SIZE_PERCENT); | 921 ShowOverlay(INSTANT_SHOWN_QUERY_SUGGESTIONS, 100, INSTANT_SIZE_PERCENT); |
815 } | 922 } |
816 | 923 |
817 void InstantController::InstantSupportDetermined( | 924 void InstantController::ShowInstantPreview(const content::WebContents* contents, |
818 const content::WebContents* contents, | 925 InstantShownReason reason, |
819 bool supports_instant) { | 926 int height, |
820 if (instant_tab_ && instant_tab_->contents() == contents) { | 927 InstantSizeUnits units) { |
821 if (!supports_instant) | 928 if (extended_enabled_ && ContentsFrom(overlay_.get(), contents)) |
822 MessageLoop::current()->DeleteSoon(FROM_HERE, instant_tab_.release()); | 929 ShowOverlay(reason, height, units); |
930 } | |
931 | |
932 void InstantController::StartCapturingKeyStrokes( | |
933 const content::WebContents* contents) { | |
934 if (!extended_enabled_) | |
823 return; | 935 return; |
824 } | |
825 | 936 |
826 if (loader_ && loader_->contents() == contents) { | 937 // Only honor the call if it comes from an active InstantTab or from an |
827 if (supports_instant) { | 938 // InstantOverlay that is being shown. |
828 if (blacklisted_urls_.erase(loader_->instant_url())) { | 939 if (ContentsFrom(instant_tab_.get(), contents) || |
829 RecordEventHistogram( | 940 (ContentsFrom(overlay_.get(), contents) && !model_.mode().is_default())) { |
830 INSTANT_CONTROLLER_EVENT_URL_REMOVED_FROM_BLACKLIST); | 941 browser_->FocusOmniboxInvisibly(); |
831 } | |
832 } else { | |
833 ++blacklisted_urls_[loader_->instant_url()]; | |
834 RecordEventHistogram(INSTANT_CONTROLLER_EVENT_URL_ADDED_TO_BLACKLIST); | |
835 HideInternal(); | |
836 delete loader_->ReleaseContents(); | |
837 MessageLoop::current()->DeleteSoon(FROM_HERE, loader_.release()); | |
838 CreateDefaultLoader(); | |
839 } | |
840 content::NotificationService::current()->Notify( | |
841 chrome::NOTIFICATION_INSTANT_SUPPORT_DETERMINED, | |
842 content::Source<InstantController>(this), | |
843 content::NotificationService::NoDetails()); | |
844 } | 942 } |
845 } | 943 } |
846 | 944 |
847 void InstantController::ShowInstantPreview(InstantShownReason reason, | 945 void InstantController::StopCapturingKeyStrokes( |
848 int height, | 946 content::WebContents* contents) { |
849 InstantSizeUnits units) { | 947 // Nothing to do if omnibox doesn't have invisible focus. |
850 if (extended_enabled_) | 948 if (!extended_enabled_ || omnibox_focus_state_ != OMNIBOX_FOCUS_INVISIBLE) |
851 ShowLoader(reason, height, units); | 949 return; |
950 | |
951 // Only honor the call if it comes from an active InstantTab or from an | |
952 // InstantOverlay that is being shown. | |
953 if (ContentsFrom(instant_tab_.get(), contents) || | |
954 (ContentsFrom(overlay_.get(), contents) && !model_.mode().is_default())) { | |
955 contents->Focus(); | |
956 } | |
852 } | 957 } |
853 | 958 |
854 void InstantController::StartCapturingKeyStrokes() { | 959 void InstantController::NavigateToURL(const content::WebContents* contents, |
855 // Ignore unless the loader is active and on the NTP. | 960 const GURL& url, |
856 if (extended_enabled_ && !instant_tab_ && model_.mode().is_ntp()) | 961 content::PageTransition transition) { |
857 browser_->FocusOmniboxInvisibly(); | 962 // TODO(samarth): handle case where contents are no longer "active" (e.g. user |
963 // has switched tabs). | |
964 if (!extended_enabled_) | |
965 return; | |
966 if (overlay_) | |
967 HideOverlay(); | |
968 browser_->OpenURLInCurrentTab(url, transition); | |
858 } | 969 } |
859 | 970 |
860 void InstantController::StopCapturingKeyStrokes() { | 971 void InstantController::OnStalePage(const content::WebContents* contents) { |
861 // Ignore unless the loader is active and on the NTP, and the omnibox has | 972 if (ContentsFrom(ntp_.get(), contents)) { |
862 // invisible focus. | 973 if (ntp_->is_stale()) { |
863 if (extended_enabled_ && !instant_tab_ && model_.mode().is_ntp() && | 974 ntp_.reset(); |
864 omnibox_focus_state_ == OMNIBOX_FOCUS_INVISIBLE) | 975 ResetNTP(); |
865 loader_->contents()->Focus(); | 976 } |
977 } else if (ContentsFrom(overlay_.get(), contents)) { | |
978 OnStaleOverlay(); | |
979 } | |
866 } | 980 } |
867 | 981 |
868 void InstantController::SwappedWebContents() { | 982 void InstantController::InstantPageSwappedContents( |
869 model_.SetPreviewContents(GetPreviewContents()); | 983 content::WebContents* new_contents) { |
984 if (ContentsFrom(overlay_.get(), new_contents)) | |
985 model_.SetPreviewContents(new_contents); | |
870 } | 986 } |
871 | 987 |
872 void InstantController::InstantLoaderContentsFocused() { | 988 void InstantController::InstantPageFocused( |
989 const content::WebContents* contents) { | |
873 #if defined(USE_AURA) | 990 #if defined(USE_AURA) |
874 // On aura the omnibox only receives a focus lost if we initiate the focus | 991 if (ContentsFrom(overlay_.get(), contents)) { |
875 // change. This does that. | 992 // On aura the omnibox only receives a focus lost if we initiate the focus |
876 if (!model_.mode().is_default()) | 993 // change. This does that. |
877 browser_->InstantPreviewFocused(); | 994 if (!model_.mode().is_default()) |
995 browser_->InstantPreviewFocused(); | |
996 } | |
878 #endif | 997 #endif |
879 } | 998 } |
880 | 999 |
881 void InstantController::InstantLoaderRenderViewGone() { | 1000 void InstantController::InstantPageClicked( |
882 ++blacklisted_urls_[loader_->instant_url()]; | 1001 const content::WebContents* contents) { |
883 HideInternal(); | 1002 if (ContentsFrom(overlay_.get(), contents)) |
884 delete loader_->ReleaseContents(); | 1003 CommitIfPossible(INSTANT_COMMIT_FOCUS_LOST); |
885 // Delay deletion as we have gotten here from an InstantLoader method. | |
886 MessageLoop::current()->DeleteSoon(FROM_HERE, loader_.release()); | |
887 CreateDefaultLoader(); | |
888 } | 1004 } |
889 | 1005 |
890 void InstantController::InstantLoaderAboutToNavigateMainFrame(const GURL& url) { | 1006 bool InstantController::InstantPageAboutToOpenURL( |
891 // If the page does not yet support instant, we allow redirects and other | 1007 const content::WebContents* contents) { |
892 // navigations to go through since the instant URL can redirect - e.g. to | 1008 // Allow navigation to continue if we can commit the overlay. |
893 // country specific pages. | 1009 return ContentsFrom(overlay_.get(), contents) && |
894 if (!loader_->supports_instant()) | 1010 CommitIfPossible(INSTANT_COMMIT_NAVIGATED); |
895 return; | |
896 | |
897 GURL instant_url(loader_->instant_url()); | |
898 | |
899 // If we are navigating to the instant URL, do nothing. | |
900 if (url == instant_url) | |
901 return; | |
902 | |
903 // Commit the navigation if either: | |
904 // - The page is in NTP mode (so it could only navigate on a user click) or | |
905 // - The page is not in NTP mode and we are navigating to a URL with a | |
906 // different host or path than the instant URL. This enables the instant | |
907 // page when it is showing search results to change the query parameters | |
908 // and fragments of the URL without it navigating. | |
909 if (model_.mode().is_ntp() || | |
910 (url.host() != instant_url.host() || url.path() != instant_url.path())) { | |
911 CommitIfPossible(INSTANT_COMMIT_NAVIGATED); | |
912 } | |
913 } | 1011 } |
914 | 1012 |
915 void InstantController::OmniboxLostFocus(gfx::NativeView view_gaining_focus) { | 1013 void InstantController::OmniboxLostFocus(gfx::NativeView view_gaining_focus) { |
916 // If the preview is showing custom NTP content, don't hide it, commit it | 1014 // If the preview is showing custom NTP content, don't hide it, commit it |
917 // (no matter where the user clicked) or try to recreate it. | 1015 // (no matter where the user clicked) or try to recreate it. |
918 if (model_.mode().is_ntp()) | 1016 if (model_.mode().is_ntp()) |
919 return; | 1017 return; |
920 | 1018 |
921 // If the preview is not showing at all, recreate it if it's stale. | 1019 // If the preview is not showing at all, recreate it if it's stale. |
922 if (model_.mode().is_default()) { | 1020 if (model_.mode().is_default()) { |
923 OnStaleLoader(); | 1021 OnStaleOverlay(); |
924 return; | 1022 return; |
925 } | 1023 } |
926 | 1024 |
927 // The preview is showing search suggestions. If GetPreviewContents() is NULL, | 1025 // The preview is showing search suggestions. If GetPreviewContents() is NULL, |
928 // we are in the commit path. Don't do anything. | 1026 // we are in the commit path. Don't do anything. |
929 if (!GetPreviewContents()) | 1027 if (!GetPreviewContents()) |
930 return; | 1028 return; |
931 | 1029 |
932 #if defined(OS_MACOSX) | 1030 #if defined(OS_MACOSX) |
933 // TODO(sreeram): See if Mac really needs this special treatment. | 1031 // TODO(sreeram): See if Mac really needs this special treatment. |
934 if (!loader_->is_pointer_down_from_activate()) | 1032 if (!overlay_->is_pointer_down_from_activate()) |
935 HideLoader(); | 1033 HideOverlay(); |
936 #else | 1034 #else |
937 if (IsViewInContents(GetViewGainingFocus(view_gaining_focus), | 1035 if (IsViewInContents(GetViewGainingFocus(view_gaining_focus), |
938 loader_->contents())) | 1036 overlay_->contents())) |
939 CommitIfPossible(INSTANT_COMMIT_FOCUS_LOST); | 1037 CommitIfPossible(INSTANT_COMMIT_FOCUS_LOST); |
940 else | 1038 else |
941 HideLoader(); | 1039 HideOverlay(); |
942 #endif | 1040 #endif |
943 } | 1041 } |
944 | 1042 |
945 void InstantController::NavigateToURL(const GURL& url, | 1043 void InstantController::OnStaleOverlay() { |
946 content::PageTransition transition) { | 1044 // The local popup is never stale. |
947 if (!extended_enabled_) | 1045 if (overlay_ && overlay_->IsUsingLocalPreview()) |
948 return; | 1046 return; |
949 if (loader_) | 1047 |
950 HideLoader(); | 1048 // If the preview is showing or the omnibox has focus, don't delete the |
951 browser_->OpenURLInCurrentTab(url, transition); | 1049 // overlay. It will get refreshed the next time the preview is hidden or the |
1050 // omnibox loses focus. | |
1051 if ((!overlay_ || overlay_->is_stale()) && | |
1052 omnibox_focus_state_ == OMNIBOX_FOCUS_NONE && | |
1053 model_.mode().is_default()) { | |
1054 overlay_.reset(); | |
1055 CreateDefaultOverlay(); | |
1056 } | |
952 } | 1057 } |
953 | 1058 |
954 bool InstantController::ResetLoader(const TemplateURL* template_url, | 1059 bool InstantController::ResetNTP() { |
955 const content::WebContents* active_tab, | 1060 const TemplateURL* template_url = TemplateURLServiceFactory::GetForProfile( |
956 bool fallback_to_local) { | 1061 browser_->profile())->GetDefaultSearchProvider(); |
1062 std::string instant_url; | |
1063 if (!GetInstantURL(template_url, &instant_url)) | |
1064 return false; | |
1065 | |
1066 ntp_.reset(new InstantNTP(this, instant_url)); | |
1067 ntp_->InitContents(browser_->profile(), browser_->GetActiveWebContents()); | |
1068 | |
1069 // Ensure the searchbox API has the correct initial state. | |
1070 if (extended_enabled_) { | |
1071 browser_->UpdateThemeInfoForPreview(); | |
1072 ntp_->SetDisplayInstantResults(instant_enabled_); | |
1073 ntp_->SetMarginSize(start_margin_, end_margin_); | |
1074 } | |
1075 return true; | |
1076 } | |
1077 | |
1078 bool InstantController::ResetOverlay(const TemplateURL* template_url, | |
1079 const content::WebContents* active_tab, | |
1080 bool fallback_to_local) { | |
957 std::string instant_url; | 1081 std::string instant_url; |
958 if (!GetInstantURL(template_url, &instant_url)) { | 1082 if (!GetInstantURL(template_url, &instant_url)) { |
959 if (!fallback_to_local || !extended_enabled_) | 1083 if (!fallback_to_local || !extended_enabled_) |
960 return false; | 1084 return false; |
961 | 1085 |
962 // If we are in extended mode, fallback to the local popup. | 1086 // If we are in extended mode, fallback to the local popup. |
963 instant_url = kLocalOmniboxPopupURL; | 1087 instant_url = kLocalOmniboxPopupURL; |
964 } | 1088 } |
965 | 1089 |
966 if (loader_ && loader_->instant_url() == instant_url) | 1090 if (overlay_ && overlay_->instant_url() == instant_url) |
967 return true; | 1091 return true; |
968 | 1092 |
969 HideInternal(); | 1093 HideInternal(); |
970 loader_.reset(new InstantLoader(this, instant_url)); | 1094 overlay_.reset(new InstantOverlay(this, instant_url)); |
971 loader_->InitContents(active_tab); | 1095 overlay_->InitContents(browser_->profile(), active_tab); |
972 | 1096 |
973 // Ensure the searchbox API has the correct initial state. | 1097 // Ensure the searchbox API has the correct initial state. |
974 if (extended_enabled_) { | 1098 if (extended_enabled_) { |
975 browser_->UpdateThemeInfoForPreview(); | 1099 browser_->UpdateThemeInfoForPreview(); |
976 loader_->SetDisplayInstantResults(instant_enabled_); | 1100 overlay_->SetDisplayInstantResults(instant_enabled_); |
977 loader_->SearchModeChanged(search_mode_); | 1101 overlay_->SearchModeChanged(search_mode_); |
978 loader_->KeyCaptureChanged(omnibox_focus_state_ == OMNIBOX_FOCUS_INVISIBLE); | 1102 overlay_->KeyCaptureChanged( |
979 loader_->SetMarginSize(start_margin_, end_margin_); | 1103 omnibox_focus_state_ == OMNIBOX_FOCUS_INVISIBLE); |
1104 overlay_->SetMarginSize(start_margin_, end_margin_); | |
980 } | 1105 } |
981 | 1106 |
982 // Restart the stale loader timer. | |
983 stale_loader_timer_.Start(FROM_HERE, | |
984 base::TimeDelta::FromMilliseconds(kStaleLoaderTimeoutMS), this, | |
985 &InstantController::OnStaleLoader); | |
986 | |
987 return true; | 1107 return true; |
988 } | 1108 } |
989 | 1109 |
990 bool InstantController::CreateDefaultLoader() { | 1110 bool InstantController::CreateDefaultOverlay() { |
991 // If there's no active tab, the browser is closing. | 1111 // If there's no active tab, the browser is opening or closing. |
992 const content::WebContents* active_tab = browser_->GetActiveWebContents(); | 1112 const content::WebContents* active_tab = browser_->GetActiveWebContents(); |
993 if (!active_tab) | 1113 if (!active_tab) |
994 return false; | 1114 return false; |
995 | 1115 |
996 const TemplateURL* template_url = TemplateURLServiceFactory::GetForProfile( | 1116 const TemplateURL* template_url = TemplateURLServiceFactory::GetForProfile( |
997 Profile::FromBrowserContext(active_tab->GetBrowserContext()))-> | 1117 Profile::FromBrowserContext(active_tab->GetBrowserContext()))-> |
998 GetDefaultSearchProvider(); | 1118 GetDefaultSearchProvider(); |
999 | 1119 |
1000 return ResetLoader(template_url, active_tab, true); | 1120 return ResetOverlay(template_url, active_tab, true); |
1001 } | 1121 } |
1002 | 1122 |
1003 void InstantController::OnStaleLoader() { | 1123 bool InstantController::ResetOverlayForMatch(const AutocompleteMatch& match) { |
1004 // The local popup is never stale. | 1124 // If we are on a search results page, we'll use that instead of a overlay. |
1005 if (loader_ && loader_->IsUsingLocalPreview()) | |
1006 return; | |
1007 | |
1008 // If the preview is showing or the omnibox has focus, don't delete the | |
1009 // loader. It will get refreshed the next time the preview is hidden or the | |
1010 // omnibox loses focus. | |
1011 if (!stale_loader_timer_.IsRunning() && | |
1012 omnibox_focus_state_ == OMNIBOX_FOCUS_NONE && | |
1013 model_.mode().is_default()) { | |
1014 loader_.reset(); | |
1015 CreateDefaultLoader(); | |
1016 } | |
1017 } | |
1018 | |
1019 void InstantController::ResetInstantTab() { | |
1020 // Do not wire up the InstantTab if instant should only use local previews, to | |
1021 // prevent it from sending data to the page. | |
1022 if (search_mode_.is_origin_search() && !use_local_preview_only_) { | |
1023 content::WebContents* active_tab = browser_->GetActiveWebContents(); | |
1024 if (!instant_tab_ || active_tab != instant_tab_->contents()) { | |
1025 instant_tab_.reset(new InstantTab(this, active_tab)); | |
1026 instant_tab_->Init(); | |
1027 instant_tab_->SetDisplayInstantResults(instant_enabled_); | |
1028 instant_tab_->SetMarginSize(start_margin_, end_margin_); | |
1029 } | |
1030 | |
1031 // Hide the |loader_| since we are now using |instant_tab_| instead. | |
1032 HideLoader(); | |
1033 } else { | |
1034 instant_tab_.reset(); | |
1035 } | |
1036 } | |
1037 | |
1038 bool InstantController::ResetLoaderForMatch(const AutocompleteMatch& match) { | |
1039 // If we are on a search results page, we'll use that instead of a loader. | |
1040 // TODO(sreeram): If |instant_tab_|'s URL is not the same as the instant_url | 1125 // TODO(sreeram): If |instant_tab_|'s URL is not the same as the instant_url |
1041 // of |match|, we shouldn't use the committed tab. | 1126 // of |match|, we shouldn't use the committed tab. |
1042 if (instant_tab_) | 1127 if (instant_tab_) |
1043 return true; | 1128 return true; |
1044 | 1129 |
1045 // If there's no active tab, the browser is closing. | 1130 // If there's no active tab, the browser is closing. |
1046 const content::WebContents* active_tab = browser_->GetActiveWebContents(); | 1131 const content::WebContents* active_tab = browser_->GetActiveWebContents(); |
1047 if (!active_tab) | 1132 if (!active_tab) |
1048 return false; | 1133 return false; |
1049 | 1134 |
1050 // Try to create a loader for the instant_url in the TemplateURL of |match|. | 1135 // Try to create a overlay for the instant_url in the TemplateURL of |match|. |
1051 // Do not fallback to the local preview because if the keyword specific | 1136 // Do not fallback to the local preview because if the keyword specific |
1052 // instant URL fails, we want to first try the default instant URL which | 1137 // instant URL fails, we want to first try the default instant URL which |
1053 // happens in the CreateDefaultLoader call below. | 1138 // happens in the CreateDefaultOverlay call below. |
1054 const TemplateURL* template_url = match.GetTemplateURL( | 1139 const TemplateURL* template_url = match.GetTemplateURL( |
1055 Profile::FromBrowserContext(active_tab->GetBrowserContext()), false); | 1140 Profile::FromBrowserContext(active_tab->GetBrowserContext()), false); |
1056 if (ResetLoader(template_url, active_tab, false)) | 1141 if (ResetOverlay(template_url, active_tab, false)) |
1057 return true; | 1142 return true; |
1058 | 1143 |
1059 // In non-extended mode, stop if we couldn't get a loader for the |match|. | 1144 // In non-extended mode, stop if we couldn't get a overlay for the |match|. |
1060 if (!extended_enabled_) | 1145 if (!extended_enabled_) |
1061 return false; | 1146 return false; |
1062 | 1147 |
1063 // If the match is a query, it is for a non-Instant search engine; stop. | 1148 // If the match is a query, it is for a non-Instant search engine; stop. |
1064 if (last_match_was_search_) | 1149 if (last_match_was_search_) |
1065 return false; | 1150 return false; |
1066 | 1151 |
1067 // The match is a URL, or a blank query. Try the default search engine. | 1152 // The match is a URL, or a blank query. Try the default search engine. |
1068 return CreateDefaultLoader(); | 1153 return CreateDefaultOverlay(); |
1069 } | 1154 } |
1070 | 1155 |
1071 void InstantController::HideLoader() { | 1156 void InstantController::ResetInstantTab() { |
1157 // Do not wire up the InstantTab if instant should only use local previews, to | |
1158 // prevent it from sending data to the page. | |
1159 if (!search_mode_.is_origin_default() && !use_local_preview_only_) { | |
1160 content::WebContents* active_tab = browser_->GetActiveWebContents(); | |
1161 if (!instant_tab_ || active_tab != instant_tab_->contents()) { | |
1162 instant_tab_.reset(new InstantTab(this)); | |
1163 instant_tab_->Init(active_tab); | |
1164 instant_tab_->SetDisplayInstantResults(instant_enabled_); | |
1165 instant_tab_->SetMarginSize(start_margin_, end_margin_); | |
1166 instant_tab_->KeyCaptureChanged( | |
1167 omnibox_focus_state_ == OMNIBOX_FOCUS_INVISIBLE); | |
1168 } | |
1169 | |
1170 // Hide the |overlay_| since we are now using |instant_tab_| instead. | |
1171 HideOverlay(); | |
1172 } else { | |
1173 instant_tab_.reset(); | |
1174 } | |
1175 } | |
1176 | |
1177 void InstantController::HideOverlay() { | |
1072 HideInternal(); | 1178 HideInternal(); |
1073 OnStaleLoader(); | 1179 OnStaleOverlay(); |
1074 } | 1180 } |
1075 | 1181 |
1076 void InstantController::HideInternal() { | 1182 void InstantController::HideInternal() { |
1077 DVLOG(1) << "Hide"; | 1183 DVLOG(1) << "Hide"; |
1078 | 1184 |
1079 // If GetPreviewContents() returns NULL, either we're already in the desired | 1185 // If GetPreviewContents() returns NULL, either we're already in the desired |
1080 // MODE_DEFAULT state, or we're in the commit path. For the latter, don't | 1186 // MODE_DEFAULT state, or we're in the commit path. For the latter, don't |
1081 // change the state just yet; else we may hide the preview unnecessarily. | 1187 // change the state just yet; else we may hide the preview unnecessarily. |
1082 // Instead, the state will be set correctly after the commit is done. | 1188 // Instead, the state will be set correctly after the commit is done. |
1083 if (GetPreviewContents()) { | 1189 if (GetPreviewContents()) { |
1084 model_.SetPreviewState(chrome::search::Mode(), 0, INSTANT_SIZE_PERCENT); | 1190 model_.SetPreviewState(chrome::search::Mode(), 0, INSTANT_SIZE_PERCENT); |
1085 allow_preview_to_show_search_suggestions_ = false; | 1191 allow_preview_to_show_search_suggestions_ = false; |
1086 | 1192 |
1087 // Send a message asking the preview to clear out old results. | 1193 // Send a message asking the preview to clear out old results. |
1088 loader_->Update(string16(), 0, 0, true); | 1194 overlay_->Update(string16(), 0, 0, true); |
1089 } | 1195 } |
1090 | 1196 |
1091 // Clear the first interaction timestamp for later use. | 1197 // Clear the first interaction timestamp for later use. |
1092 first_interaction_time_ = base::Time(); | 1198 first_interaction_time_ = base::Time(); |
1093 } | 1199 } |
1094 | 1200 |
1095 void InstantController::ShowLoader(InstantShownReason reason, | 1201 void InstantController::ShowOverlay(InstantShownReason reason, |
1096 int height, | 1202 int height, |
1097 InstantSizeUnits units) { | 1203 InstantSizeUnits units) { |
1098 // If we are on a committed search results page, the |loader_| is not in use. | 1204 // If we are on a committed search results page, the |overlay_| is not in use. |
1099 if (instant_tab_) | 1205 if (instant_tab_) |
1100 return; | 1206 return; |
1101 | 1207 |
1102 DVLOG(1) << "Show: reason=" << reason << " height=" << height << " units=" | 1208 DVLOG(1) << "Show: reason=" << reason << " height=" << height << " units=" |
1103 << units; | 1209 << units; |
1104 | 1210 |
1105 // Must be on NTP to show NTP content. | 1211 // INSTANT_SHOWN_CUSTOM_NTP_CONTENT is no longer supported. |
1106 if (reason == INSTANT_SHOWN_CUSTOM_NTP_CONTENT && !search_mode_.is_ntp()) | 1212 // TODO(samarth): remove once the server has been updated. |
1213 if (reason == INSTANT_SHOWN_CUSTOM_NTP_CONTENT) | |
1107 return; | 1214 return; |
1108 | 1215 |
1109 // Must have updated omnibox after the last HideLoader() to show suggestions. | 1216 // Must have updated omnibox after the last HideOverlay() to show suggestions. |
1110 if ((reason == INSTANT_SHOWN_QUERY_SUGGESTIONS || | 1217 if ((reason == INSTANT_SHOWN_QUERY_SUGGESTIONS || |
1111 reason == INSTANT_SHOWN_CLICKED_QUERY_SUGGESTION) && | 1218 reason == INSTANT_SHOWN_CLICKED_QUERY_SUGGESTION) && |
1112 !allow_preview_to_show_search_suggestions_) | 1219 !allow_preview_to_show_search_suggestions_) |
1113 return; | 1220 return; |
1114 | 1221 |
1115 // The page is trying to hide itself. Hide explicitly (i.e., don't use | 1222 // The page is trying to hide itself. Hide explicitly (i.e., don't use |
1116 // HideLoader()) so that it can change its mind. | 1223 // HideOverlay()) so that it can change its mind. |
1117 if (height == 0) { | 1224 if (height == 0) { |
1118 model_.SetPreviewState(chrome::search::Mode(), 0, INSTANT_SIZE_PERCENT); | 1225 model_.SetPreviewState(chrome::search::Mode(), 0, INSTANT_SIZE_PERCENT); |
1119 return; | 1226 return; |
1120 } | 1227 } |
1121 | 1228 |
1122 // If the preview is being shown for the first time since the user started | 1229 // If the preview is being shown for the first time since the user started |
1123 // typing, record a histogram value. | 1230 // typing, record a histogram value. |
1124 if (!first_interaction_time_.is_null() && model_.mode().is_default()) { | 1231 if (!first_interaction_time_.is_null() && model_.mode().is_default()) { |
1125 base::TimeDelta delta = base::Time::Now() - first_interaction_time_; | 1232 base::TimeDelta delta = base::Time::Now() - first_interaction_time_; |
1126 UMA_HISTOGRAM_TIMES("Instant.TimeToFirstShow", delta); | 1233 UMA_HISTOGRAM_TIMES("Instant.TimeToFirstShow", delta); |
1127 } | 1234 } |
1128 | 1235 |
1129 // Show at 100% height except in the following cases: | 1236 // Show at 100% height except in the following cases: |
1130 // - The local omnibox popup is being loaded. | 1237 // - The local omnibox popup is being loaded. |
1131 // - Instant is disabled. The page needs to be able to show only a dropdown. | 1238 // - Instant is disabled. The page needs to be able to show only a dropdown. |
1132 // - The page wants to show custom NTP content. | 1239 // - The page wants to show custom NTP content. |
1133 // - The page is over a website other than search or an NTP, and is not | 1240 // - The page is over a website other than search or an NTP, and is not |
1134 // already showing at 100% height. | 1241 // already showing at 100% height. |
1135 if (loader_->IsUsingLocalPreview() || !instant_enabled_ || | 1242 if (overlay_->IsUsingLocalPreview() || !instant_enabled_ || |
1136 reason == INSTANT_SHOWN_CUSTOM_NTP_CONTENT || | 1243 reason == INSTANT_SHOWN_CUSTOM_NTP_CONTENT || |
1137 (search_mode_.is_origin_default() && !IsFullHeight(model_))) | 1244 (search_mode_.is_origin_default() && !IsFullHeight(model_))) |
1138 model_.SetPreviewState(search_mode_, height, units); | 1245 model_.SetPreviewState(search_mode_, height, units); |
1139 else | 1246 else |
1140 model_.SetPreviewState(search_mode_, 100, INSTANT_SIZE_PERCENT); | 1247 model_.SetPreviewState(search_mode_, 100, INSTANT_SIZE_PERCENT); |
1141 | 1248 |
1142 // If the user clicked on a query suggestion, also go ahead and commit the | 1249 // If the user clicked on a query suggestion, also go ahead and commit the |
1143 // overlay. This is necessary because if the overlay was partially visible | 1250 // overlay. This is necessary because if the overlay was partially visible |
1144 // when the suggestion was clicked, the click itself would not commit the | 1251 // when the suggestion was clicked, the click itself would not commit the |
1145 // overlay (because we're not full height). | 1252 // overlay (because we're not full height). |
1146 if (reason == INSTANT_SHOWN_CLICKED_QUERY_SUGGESTION) | 1253 if (reason == INSTANT_SHOWN_CLICKED_QUERY_SUGGESTION) |
1147 CommitIfPossible(INSTANT_COMMIT_CLICKED_QUERY_SUGGESTION); | 1254 CommitIfPossible(INSTANT_COMMIT_CLICKED_QUERY_SUGGESTION); |
1148 } | 1255 } |
1149 | 1256 |
1150 void InstantController::SendPopupBoundsToPage() { | 1257 void InstantController::SendPopupBoundsToPage() { |
1151 if (last_popup_bounds_ == popup_bounds_ || !loader_ || | 1258 if (last_popup_bounds_ == popup_bounds_ || !overlay_ || |
1152 loader_->is_pointer_down_from_activate()) | 1259 overlay_->is_pointer_down_from_activate()) |
1153 return; | 1260 return; |
1154 | 1261 |
1155 last_popup_bounds_ = popup_bounds_; | 1262 last_popup_bounds_ = popup_bounds_; |
1156 gfx::Rect preview_bounds = browser_->GetInstantBounds(); | 1263 gfx::Rect preview_bounds = browser_->GetInstantBounds(); |
1157 gfx::Rect intersection = gfx::IntersectRects(popup_bounds_, preview_bounds); | 1264 gfx::Rect intersection = gfx::IntersectRects(popup_bounds_, preview_bounds); |
1158 | 1265 |
1159 // Translate into window coordinates. | 1266 // Translate into window coordinates. |
1160 if (!intersection.IsEmpty()) { | 1267 if (!intersection.IsEmpty()) { |
1161 intersection.Offset(-preview_bounds.origin().x(), | 1268 intersection.Offset(-preview_bounds.origin().x(), |
1162 -preview_bounds.origin().y()); | 1269 -preview_bounds.origin().y()); |
1163 } | 1270 } |
1164 | 1271 |
1165 // In the current Chrome UI, these must always be true so they sanity check | 1272 // In the current Chrome UI, these must always be true so they sanity check |
1166 // the above operations. In a future UI, these may be removed or adjusted. | 1273 // the above operations. In a future UI, these may be removed or adjusted. |
1167 // There is no point in sanity-checking |intersection.y()| because the omnibox | 1274 // There is no point in sanity-checking |intersection.y()| because the omnibox |
1168 // can be placed anywhere vertically relative to the preview (for example, in | 1275 // can be placed anywhere vertically relative to the preview (for example, in |
1169 // Mac fullscreen mode, the omnibox is fully enclosed by the preview bounds). | 1276 // Mac fullscreen mode, the omnibox is fully enclosed by the preview bounds). |
1170 DCHECK_LE(0, intersection.x()); | 1277 DCHECK_LE(0, intersection.x()); |
1171 DCHECK_LE(0, intersection.width()); | 1278 DCHECK_LE(0, intersection.width()); |
1172 DCHECK_LE(0, intersection.height()); | 1279 DCHECK_LE(0, intersection.height()); |
1173 | 1280 |
1174 loader_->SetPopupBounds(intersection); | 1281 overlay_->SetPopupBounds(intersection); |
1175 } | 1282 } |
1176 | 1283 |
1177 bool InstantController::GetInstantURL(const TemplateURL* template_url, | 1284 bool InstantController::GetInstantURL(const TemplateURL* template_url, |
1178 std::string* instant_url) const { | 1285 std::string* instant_url) const { |
1179 if (extended_enabled_ && use_local_preview_only_) { | 1286 if (extended_enabled_ && use_local_preview_only_) { |
1180 *instant_url = kLocalOmniboxPopupURL; | 1287 *instant_url = kLocalOmniboxPopupURL; |
1181 return true; | 1288 return true; |
1182 } | 1289 } |
1183 | 1290 |
1184 CommandLine* command_line = CommandLine::ForCurrentProcess(); | 1291 CommandLine* command_line = CommandLine::ForCurrentProcess(); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1236 std::map<std::string, int>::const_iterator iter = | 1343 std::map<std::string, int>::const_iterator iter = |
1237 blacklisted_urls_.find(*instant_url); | 1344 blacklisted_urls_.find(*instant_url); |
1238 if (iter != blacklisted_urls_.end() && | 1345 if (iter != blacklisted_urls_.end() && |
1239 iter->second > kMaxInstantSupportFailures) { | 1346 iter->second > kMaxInstantSupportFailures) { |
1240 RecordEventHistogram(INSTANT_CONTROLLER_EVENT_URL_BLOCKED_BY_BLACKLIST); | 1347 RecordEventHistogram(INSTANT_CONTROLLER_EVENT_URL_BLOCKED_BY_BLACKLIST); |
1241 return false; | 1348 return false; |
1242 } | 1349 } |
1243 | 1350 |
1244 return true; | 1351 return true; |
1245 } | 1352 } |
1353 | |
1354 void InstantController::AddToBlacklist(const std::string& url) { | |
1355 ++blacklisted_urls_[url]; | |
1356 RecordEventHistogram(INSTANT_CONTROLLER_EVENT_URL_ADDED_TO_BLACKLIST); | |
1357 } | |
1358 | |
1359 void InstantController::RemoveFromBlacklist(const std::string& url) { | |
1360 if (blacklisted_urls_.erase(url)) { | |
1361 RecordEventHistogram(INSTANT_CONTROLLER_EVENT_URL_REMOVED_FROM_BLACKLIST); | |
1362 } | |
1363 } | |
OLD | NEW |