| 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/ui/search/instant_controller.h" | 5 #include "chrome/browser/ui/search/instant_controller.h" |
| 6 | 6 |
| 7 #include "base/metrics/histogram.h" | 7 #include "base/metrics/histogram.h" |
| 8 #include "base/string_util.h" | 8 #include "base/string_util.h" |
| 9 #include "base/stringprintf.h" | 9 #include "base/stringprintf.h" |
| 10 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 233 | 233 |
| 234 } // namespace | 234 } // namespace |
| 235 | 235 |
| 236 InstantController::InstantController(BrowserInstantController* browser, | 236 InstantController::InstantController(BrowserInstantController* browser, |
| 237 bool extended_enabled) | 237 bool extended_enabled) |
| 238 : browser_(browser), | 238 : browser_(browser), |
| 239 extended_enabled_(extended_enabled), | 239 extended_enabled_(extended_enabled), |
| 240 instant_enabled_(false), | 240 instant_enabled_(false), |
| 241 use_local_page_only_(true), | 241 use_local_page_only_(true), |
| 242 model_(this), | 242 model_(this), |
| 243 use_tab_for_suggestions_(false), |
| 243 last_omnibox_text_has_inline_autocompletion_(false), | 244 last_omnibox_text_has_inline_autocompletion_(false), |
| 244 last_verbatim_(false), | 245 last_verbatim_(false), |
| 245 last_transition_type_(content::PAGE_TRANSITION_LINK), | 246 last_transition_type_(content::PAGE_TRANSITION_LINK), |
| 246 last_match_was_search_(false), | 247 last_match_was_search_(false), |
| 247 omnibox_focus_state_(OMNIBOX_FOCUS_NONE), | 248 omnibox_focus_state_(OMNIBOX_FOCUS_NONE), |
| 248 omnibox_bounds_(-1, -1, 0, 0), | 249 omnibox_bounds_(-1, -1, 0, 0), |
| 249 allow_overlay_to_show_search_suggestions_(false), | 250 allow_overlay_to_show_search_suggestions_(false), |
| 250 weak_ptr_factory_(this) { | 251 weak_ptr_factory_(this) { |
| 251 | 252 |
| 252 // When the InstantController lives, the InstantService should live. | 253 // When the InstantController lives, the InstantService should live. |
| 253 // InstantService sets up profile-level facilities such as the ThemeSource for | 254 // InstantService sets up profile-level facilities such as the ThemeSource for |
| 254 // the NTP. | 255 // the NTP. |
| 255 InstantServiceFactory::GetForProfile(browser_->profile()); | 256 InstantServiceFactory::GetForProfile(browser_->profile()); |
| 256 } | 257 } |
| 257 | 258 |
| 258 InstantController::~InstantController() { | 259 InstantController::~InstantController() { |
| 259 } | 260 } |
| 260 | 261 |
| 261 void InstantController::OnAutocompleteStart() { | 262 void InstantController::OnAutocompleteStart() { |
| 262 if (instant_tab_ && instant_tab_->supports_instant()) { | 263 if (instant_tab_ && instant_tab_->supports_instant()) { |
| 263 LOG_INSTANT_DEBUG_EVENT( | 264 LOG_INSTANT_DEBUG_EVENT( |
| 264 this, "OnAutocompleteStart: using InstantTab"); | 265 this, "OnAutocompleteStart: using InstantTab"); |
| 265 return; | 266 return; |
| 266 } | 267 } |
| 267 | 268 |
| 268 if (instant_tab_) { | 269 use_tab_for_suggestions_ = false; |
| 269 // If we have an |instant_tab_| but it doesn't support Instant yet, sever | |
| 270 // the connection to it so we use the overlay instead. This ensures that the | |
| 271 // user interaction will be responsive and handles cases where | |
| 272 // |instant_tab_| never responds about whether it supports Instant. | |
| 273 instant_tab_.reset(); | |
| 274 LOG_INSTANT_DEBUG_EVENT( | |
| 275 this, "OnAutocompleteStart: reset InstantTab"); | |
| 276 } | |
| 277 | 270 |
| 278 // Not using |instant_tab_|. Check if overlay is OK to use. | 271 // Not using |instant_tab_|. Check if overlay is OK to use. |
| 279 if (ShouldSwitchToLocalOverlay()) { | 272 if (ShouldSwitchToLocalOverlay()) { |
| 280 ResetOverlay(GetLocalInstantURL()); | 273 ResetOverlay(GetLocalInstantURL()); |
| 281 LOG_INSTANT_DEBUG_EVENT( | 274 LOG_INSTANT_DEBUG_EVENT( |
| 282 this, "OnAutocompleteStart: switching to local overlay"); | 275 this, "OnAutocompleteStart: switching to local overlay"); |
| 283 } else { | 276 } else { |
| 284 LOG_INSTANT_DEBUG_EVENT( | 277 LOG_INSTANT_DEBUG_EVENT( |
| 285 this, "OnAutocompleteStart: using existing overlay"); | 278 this, "OnAutocompleteStart: using existing overlay"); |
| 286 } | 279 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 307 UTF16ToUTF8(user_text).c_str(), UTF16ToUTF8(full_text).c_str(), | 300 UTF16ToUTF8(user_text).c_str(), UTF16ToUTF8(full_text).c_str(), |
| 308 static_cast<int>(selection_start), static_cast<int>(selection_end), | 301 static_cast<int>(selection_start), static_cast<int>(selection_end), |
| 309 verbatim, user_input_in_progress, omnibox_popup_is_open, escape_pressed, | 302 verbatim, user_input_in_progress, omnibox_popup_is_open, escape_pressed, |
| 310 is_keyword_search)); | 303 is_keyword_search)); |
| 311 | 304 |
| 312 // TODO(dhollowa): Complete keyword match UI. For now just hide suggestions. | 305 // TODO(dhollowa): Complete keyword match UI. For now just hide suggestions. |
| 313 // http://crbug.com/153932. Note, this early escape is happens prior to the | 306 // http://crbug.com/153932. Note, this early escape is happens prior to the |
| 314 // DCHECKs below because |user_text| and |full_text| have different semantics | 307 // DCHECKs below because |user_text| and |full_text| have different semantics |
| 315 // when keyword search is in effect. | 308 // when keyword search is in effect. |
| 316 if (is_keyword_search) { | 309 if (is_keyword_search) { |
| 317 if (instant_tab_) | 310 if (UseTabForSuggestions()) |
| 318 instant_tab_->Update(string16(), 0, 0, true); | 311 instant_tab_->Update(string16(), 0, 0, true); |
| 319 else | 312 else |
| 320 HideOverlay(); | 313 HideOverlay(); |
| 321 last_match_was_search_ = false; | 314 last_match_was_search_ = false; |
| 322 return false; | 315 return false; |
| 323 } | 316 } |
| 324 | 317 |
| 325 // Ignore spurious updates when the omnibox is blurred; otherwise click | 318 // Ignore spurious updates when the omnibox is blurred; otherwise click |
| 326 // targets on the page may vanish before a click event arrives. | 319 // targets on the page may vanish before a click event arrives. |
| 327 if (omnibox_focus_state_ == OMNIBOX_FOCUS_NONE) | 320 if (omnibox_focus_state_ == OMNIBOX_FOCUS_NONE) |
| (...skipping 30 matching lines...) Expand all Loading... |
| 358 !user_text.empty(); | 351 !user_text.empty(); |
| 359 | 352 |
| 360 // In non extended mode, Instant is disabled for URLs and keyword mode. | 353 // In non extended mode, Instant is disabled for URLs and keyword mode. |
| 361 if (!extended_enabled_ && | 354 if (!extended_enabled_ && |
| 362 (!last_match_was_search_ || | 355 (!last_match_was_search_ || |
| 363 match.type == AutocompleteMatch::SEARCH_OTHER_ENGINE)) { | 356 match.type == AutocompleteMatch::SEARCH_OTHER_ENGINE)) { |
| 364 HideOverlay(); | 357 HideOverlay(); |
| 365 return false; | 358 return false; |
| 366 } | 359 } |
| 367 | 360 |
| 368 if (!instant_tab_ && !overlay_) { | 361 if (!UseTabForSuggestions() && !overlay_) { |
| 369 HideOverlay(); | 362 HideOverlay(); |
| 370 return false; | 363 return false; |
| 371 } | 364 } |
| 372 | 365 |
| 373 if (extended_enabled_) { | 366 if (extended_enabled_) { |
| 374 if (!omnibox_popup_is_open) { | 367 if (!omnibox_popup_is_open) { |
| 375 if (!user_input_in_progress) { | 368 if (!user_input_in_progress) { |
| 376 // If the user isn't typing and the omnibox popup is closed, it means a | 369 // If the user isn't typing and the omnibox popup is closed, it means a |
| 377 // regular navigation, tab-switch or the user hitting Escape. | 370 // regular navigation, tab-switch or the user hitting Escape. |
| 378 if (instant_tab_) { | 371 if (UseTabForSuggestions()) { |
| 379 // The user is on a search results page. It may be showing results for | 372 // The user is on a search results page. It may be showing results for |
| 380 // a partial query the user typed before they hit Escape. Send the | 373 // a partial query the user typed before they hit Escape. Send the |
| 381 // omnibox text to the page to restore the original results. | 374 // omnibox text to the page to restore the original results. |
| 382 // | 375 // |
| 383 // In a tab switch, |instant_tab_| won't have updated yet, so it may | 376 // In a tab switch, |instant_tab_| won't have updated yet, so it may |
| 384 // be pointing to the previous tab (which was a search results page). | 377 // be pointing to the previous tab (which was a search results page). |
| 385 // Ensure we don't send the omnibox text to a random webpage (the new | 378 // Ensure we don't send the omnibox text to a random webpage (the new |
| 386 // tab), by comparing the old and new WebContents. | 379 // tab), by comparing the old and new WebContents. |
| 387 if (escape_pressed && | 380 if (escape_pressed && |
| 388 instant_tab_->contents() == browser_->GetActiveWebContents()) { | 381 instant_tab_->contents() == browser_->GetActiveWebContents()) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 401 // If |full_text| is empty, the user is on the NTP. The overlay may | 394 // If |full_text| is empty, the user is on the NTP. The overlay may |
| 402 // be showing custom NTP content; hide only if that's not the case. | 395 // be showing custom NTP content; hide only if that's not the case. |
| 403 HideOverlay(); | 396 HideOverlay(); |
| 404 } | 397 } |
| 405 } else if (full_text.empty()) { | 398 } else if (full_text.empty()) { |
| 406 // The user is typing, and backspaced away all omnibox text. Clear | 399 // The user is typing, and backspaced away all omnibox text. Clear |
| 407 // |last_omnibox_text_| so that we don't attempt to set suggestions. | 400 // |last_omnibox_text_| so that we don't attempt to set suggestions. |
| 408 last_omnibox_text_.clear(); | 401 last_omnibox_text_.clear(); |
| 409 last_user_text_.clear(); | 402 last_user_text_.clear(); |
| 410 last_suggestion_ = InstantSuggestion(); | 403 last_suggestion_ = InstantSuggestion(); |
| 411 if (instant_tab_) { | 404 if (UseTabForSuggestions()) { |
| 412 // On a search results page, tell it to clear old results. | 405 // On a search results page, tell it to clear old results. |
| 413 instant_tab_->Update(string16(), 0, 0, true); | 406 instant_tab_->Update(string16(), 0, 0, true); |
| 414 } else if (search_mode_.is_origin_ntp()) { | 407 } else if (search_mode_.is_origin_ntp()) { |
| 415 // On the NTP, tell the overlay to clear old results. Don't hide the | 408 // On the NTP, tell the overlay to clear old results. Don't hide the |
| 416 // overlay so it can show a blank page or logo if it wants. | 409 // overlay so it can show a blank page or logo if it wants. |
| 417 overlay_->Update(string16(), 0, 0, true); | 410 overlay_->Update(string16(), 0, 0, true); |
| 418 } else { | 411 } else { |
| 419 HideOverlay(); | 412 HideOverlay(); |
| 420 } | 413 } |
| 421 } else { | 414 } else { |
| 422 // The user switched to a tab with partial text already in the omnibox. | 415 // The user switched to a tab with partial text already in the omnibox. |
| 423 HideOverlay(); | 416 HideOverlay(); |
| 424 | 417 |
| 425 // The new tab may or may not be a search results page; we don't know | 418 // The new tab may or may not be a search results page; we don't know |
| 426 // since SearchModeChanged() hasn't been called yet. If it later turns | 419 // since SearchModeChanged() hasn't been called yet. If it later turns |
| 427 // out to be, we should store |full_text| now, so that if the user hits | 420 // out to be, we should store |full_text| now, so that if the user hits |
| 428 // Enter, we'll send the correct query to instant_tab_->Submit(). If the | 421 // Enter, we'll send the correct query to instant_tab_->Submit(). If the |
| 429 // partial text is not a query (|last_match_was_search_| is false), we | 422 // partial text is not a query (|last_match_was_search_| is false), we |
| 430 // won't Submit(), so no need to worry about that. | 423 // won't Submit(), so no need to worry about that. |
| 431 last_omnibox_text_ = full_text; | 424 last_omnibox_text_ = full_text; |
| 432 last_user_text_ = user_text; | 425 last_user_text_ = user_text; |
| 433 last_suggestion_ = InstantSuggestion(); | 426 last_suggestion_ = InstantSuggestion(); |
| 434 } | 427 } |
| 435 return false; | 428 return false; |
| 436 } else if (full_text.empty()) { | 429 } else if (full_text.empty()) { |
| 437 // The user typed a solitary "?". Same as the backspace case above. | 430 // The user typed a solitary "?". Same as the backspace case above. |
| 438 last_omnibox_text_.clear(); | 431 last_omnibox_text_.clear(); |
| 439 last_user_text_.clear(); | 432 last_user_text_.clear(); |
| 440 last_suggestion_ = InstantSuggestion(); | 433 last_suggestion_ = InstantSuggestion(); |
| 441 if (instant_tab_) | 434 if (UseTabForSuggestions()) |
| 442 instant_tab_->Update(string16(), 0, 0, true); | 435 instant_tab_->Update(string16(), 0, 0, true); |
| 443 else if (search_mode_.is_origin_ntp()) | 436 else if (search_mode_.is_origin_ntp()) |
| 444 overlay_->Update(string16(), 0, 0, true); | 437 overlay_->Update(string16(), 0, 0, true); |
| 445 else | 438 else |
| 446 HideOverlay(); | 439 HideOverlay(); |
| 447 return false; | 440 return false; |
| 448 } | 441 } |
| 449 } else if (!omnibox_popup_is_open || full_text.empty()) { | 442 } else if (!omnibox_popup_is_open || full_text.empty()) { |
| 450 // In the non-extended case, hide the overlay as long as the user isn't | 443 // In the non-extended case, hide the overlay as long as the user isn't |
| 451 // actively typing a non-empty query. | 444 // actively typing a non-empty query. |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 486 last_verbatim_ = verbatim; | 479 last_verbatim_ = verbatim; |
| 487 | 480 |
| 488 last_transition_type_ = match.transition; | 481 last_transition_type_ = match.transition; |
| 489 url_for_history_ = match.destination_url; | 482 url_for_history_ = match.destination_url; |
| 490 | 483 |
| 491 // Allow search suggestions. In extended mode, SearchModeChanged() will set | 484 // Allow search suggestions. In extended mode, SearchModeChanged() will set |
| 492 // this, but it's not called in non-extended mode, so fake it. | 485 // this, but it's not called in non-extended mode, so fake it. |
| 493 if (!extended_enabled_) | 486 if (!extended_enabled_) |
| 494 search_mode_.mode = SearchMode::MODE_SEARCH_SUGGESTIONS; | 487 search_mode_.mode = SearchMode::MODE_SEARCH_SUGGESTIONS; |
| 495 | 488 |
| 496 if (instant_tab_) { | 489 if (UseTabForSuggestions()) { |
| 497 instant_tab_->Update(user_text, selection_start, selection_end, verbatim); | 490 instant_tab_->Update(user_text, selection_start, selection_end, verbatim); |
| 498 } else { | 491 } else { |
| 499 if (first_interaction_time_.is_null()) | 492 if (first_interaction_time_.is_null()) |
| 500 first_interaction_time_ = base::Time::Now(); | 493 first_interaction_time_ = base::Time::Now(); |
| 501 allow_overlay_to_show_search_suggestions_ = true; | 494 allow_overlay_to_show_search_suggestions_ = true; |
| 502 | 495 |
| 503 overlay_->Update(extended_enabled_ ? user_text : full_text, | 496 overlay_->Update(extended_enabled_ ? user_text : full_text, |
| 504 selection_start, selection_end, verbatim); | 497 selection_start, selection_end, verbatim); |
| 505 } | 498 } |
| 506 | 499 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 576 ntp_->SetOmniboxBounds(omnibox_bounds_); | 569 ntp_->SetOmniboxBounds(omnibox_bounds_); |
| 577 if (instant_tab_) | 570 if (instant_tab_) |
| 578 instant_tab_->SetOmniboxBounds(omnibox_bounds_); | 571 instant_tab_->SetOmniboxBounds(omnibox_bounds_); |
| 579 } | 572 } |
| 580 | 573 |
| 581 void InstantController::HandleAutocompleteResults( | 574 void InstantController::HandleAutocompleteResults( |
| 582 const std::vector<AutocompleteProvider*>& providers) { | 575 const std::vector<AutocompleteProvider*>& providers) { |
| 583 if (!extended_enabled_) | 576 if (!extended_enabled_) |
| 584 return; | 577 return; |
| 585 | 578 |
| 586 if (!instant_tab_ && !overlay_) | 579 if (!UseTabForSuggestions() && !overlay_) |
| 587 return; | 580 return; |
| 588 | 581 |
| 589 // The omnibox sends suggestions when its possibly imaginary popup closes | 582 // The omnibox sends suggestions when its possibly imaginary popup closes |
| 590 // as it stops autocomplete. Ignore these. | 583 // as it stops autocomplete. Ignore these. |
| 591 if (omnibox_focus_state_ == OMNIBOX_FOCUS_NONE) | 584 if (omnibox_focus_state_ == OMNIBOX_FOCUS_NONE) |
| 592 return; | 585 return; |
| 593 | 586 |
| 594 DVLOG(1) << "AutocompleteResults:"; | 587 DVLOG(1) << "AutocompleteResults:"; |
| 595 std::vector<InstantAutocompleteResult> results; | 588 std::vector<InstantAutocompleteResult> results; |
| 596 for (ACProviders::const_iterator provider = providers.begin(); | 589 for (ACProviders::const_iterator provider = providers.begin(); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 628 << result.provider << " " << result.destination_url << " '" | 621 << result.provider << " " << result.destination_url << " '" |
| 629 << result.description << "' '" << result.search_query << "' " | 622 << result.description << "' '" << result.search_query << "' " |
| 630 << result.transition; | 623 << result.transition; |
| 631 results.push_back(result); | 624 results.push_back(result); |
| 632 } | 625 } |
| 633 } | 626 } |
| 634 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf( | 627 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf( |
| 635 "HandleAutocompleteResults: total_results=%d", | 628 "HandleAutocompleteResults: total_results=%d", |
| 636 static_cast<int>(results.size()))); | 629 static_cast<int>(results.size()))); |
| 637 | 630 |
| 638 if (instant_tab_) | 631 if (UseTabForSuggestions()) |
| 639 instant_tab_->SendAutocompleteResults(results); | 632 instant_tab_->SendAutocompleteResults(results); |
| 640 else | 633 else |
| 641 overlay_->SendAutocompleteResults(results); | 634 overlay_->SendAutocompleteResults(results); |
| 642 } | 635 } |
| 643 | 636 |
| 644 void InstantController::OnDefaultSearchProviderChanged() { | 637 void InstantController::OnDefaultSearchProviderChanged() { |
| 645 if (ntp_ && extended_enabled_) { | 638 if (ntp_ && extended_enabled_) { |
| 646 ntp_.reset(); | 639 ntp_.reset(); |
| 647 if (!use_local_page_only_) | 640 if (!use_local_page_only_) |
| 648 ResetNTP(GetInstantURL()); | 641 ResetNTP(GetInstantURL()); |
| 649 } | 642 } |
| 650 | 643 |
| 651 // Do not reload the overlay if it's actually the local overlay. | 644 // Do not reload the overlay if it's actually the local overlay. |
| 652 if (overlay_ && !overlay_->IsLocal()) { | 645 if (overlay_ && !overlay_->IsLocal()) { |
| 653 overlay_.reset(); | 646 overlay_.reset(); |
| 654 if (extended_enabled_ || instant_enabled_) { | 647 if (extended_enabled_ || instant_enabled_) { |
| 655 // Try to create another overlay immediately so that it is ready for the | 648 // Try to create another overlay immediately so that it is ready for the |
| 656 // next user interaction. | 649 // next user interaction. |
| 657 ResetOverlay(GetInstantURL()); | 650 ResetOverlay(GetInstantURL()); |
| 658 } | 651 } |
| 659 } | 652 } |
| 660 } | 653 } |
| 661 | 654 |
| 662 bool InstantController::OnUpOrDownKeyPressed(int count) { | 655 bool InstantController::OnUpOrDownKeyPressed(int count) { |
| 663 if (!extended_enabled_) | 656 if (!extended_enabled_) |
| 664 return false; | 657 return false; |
| 665 | 658 |
| 666 if (!instant_tab_ && !overlay_) | 659 if (!UseTabForSuggestions() && !overlay_) |
| 667 return false; | 660 return false; |
| 668 | 661 |
| 669 if (instant_tab_) | 662 if (UseTabForSuggestions()) |
| 670 instant_tab_->UpOrDownKeyPressed(count); | 663 instant_tab_->UpOrDownKeyPressed(count); |
| 671 else | 664 else |
| 672 overlay_->UpOrDownKeyPressed(count); | 665 overlay_->UpOrDownKeyPressed(count); |
| 673 | 666 |
| 674 return true; | 667 return true; |
| 675 } | 668 } |
| 676 | 669 |
| 677 void InstantController::OnCancel(const AutocompleteMatch& match, | 670 void InstantController::OnCancel(const AutocompleteMatch& match, |
| 678 const string16& user_text, | 671 const string16& user_text, |
| 679 const string16& full_text) { | 672 const string16& full_text) { |
| 680 if (!extended_enabled_) | 673 if (!extended_enabled_) |
| 681 return; | 674 return; |
| 682 | 675 |
| 683 if (!instant_tab_ && !overlay_) | 676 if (!UseTabForSuggestions() && !overlay_) |
| 684 return; | 677 return; |
| 685 | 678 |
| 686 // We manually reset the state here since the JS is not expected to do it. | 679 // We manually reset the state here since the JS is not expected to do it. |
| 687 // TODO(sreeram): Handle the case where user_text is now a URL | 680 // TODO(sreeram): Handle the case where user_text is now a URL |
| 688 last_match_was_search_ = AutocompleteMatch::IsSearchType(match.type) && | 681 last_match_was_search_ = AutocompleteMatch::IsSearchType(match.type) && |
| 689 !full_text.empty(); | 682 !full_text.empty(); |
| 690 last_omnibox_text_ = full_text; | 683 last_omnibox_text_ = full_text; |
| 691 last_user_text_ = user_text; | 684 last_user_text_ = user_text; |
| 692 last_suggestion_ = InstantSuggestion(); | 685 last_suggestion_ = InstantSuggestion(); |
| 693 | 686 |
| 694 // Say |full_text| is "amazon.com" and |user_text| is "ama". This means the | 687 // Say |full_text| is "amazon.com" and |user_text| is "ama". This means the |
| 695 // inline autocompletion is "zon.com"; so the selection should span from | 688 // inline autocompletion is "zon.com"; so the selection should span from |
| 696 // user_text.size() to full_text.size(). The selection bounds are inverted | 689 // user_text.size() to full_text.size(). The selection bounds are inverted |
| 697 // because the caret is at the end of |user_text|, not |full_text|. | 690 // because the caret is at the end of |user_text|, not |full_text|. |
| 698 if (instant_tab_) { | 691 if (UseTabForSuggestions()) { |
| 699 instant_tab_->CancelSelection(user_text, full_text.size(), user_text.size(), | 692 instant_tab_->CancelSelection(user_text, full_text.size(), user_text.size(), |
| 700 last_verbatim_); | 693 last_verbatim_); |
| 701 } else { | 694 } else { |
| 702 overlay_->CancelSelection(user_text, full_text.size(), user_text.size(), | 695 overlay_->CancelSelection(user_text, full_text.size(), user_text.size(), |
| 703 last_verbatim_); | 696 last_verbatim_); |
| 704 } | 697 } |
| 705 } | 698 } |
| 706 | 699 |
| 707 void InstantController::OmniboxNavigateToURL() { | 700 void InstantController::OmniboxNavigateToURL() { |
| 708 if (!extended_enabled_) | 701 if (!extended_enabled_) |
| 709 return; | 702 return; |
| 710 RecordNavigationHistogram(UsingLocalPage(), false); | 703 RecordNavigationHistogram(UsingLocalPage(), false); |
| 711 if (instant_tab_) | 704 if (UseTabForSuggestions()) |
| 712 instant_tab_->Submit(string16()); | 705 instant_tab_->Submit(string16()); |
| 713 } | 706 } |
| 714 | 707 |
| 715 content::WebContents* InstantController::GetOverlayContents() const { | 708 content::WebContents* InstantController::GetOverlayContents() const { |
| 716 return overlay_ ? overlay_->contents() : NULL; | 709 return overlay_ ? overlay_->contents() : NULL; |
| 717 } | 710 } |
| 718 | 711 |
| 719 bool InstantController::IsOverlayingSearchResults() const { | 712 bool InstantController::IsOverlayingSearchResults() const { |
| 720 return model_.mode().is_search_suggestions() && IsFullHeight(model_) && | 713 return model_.mode().is_search_suggestions() && IsFullHeight(model_) && |
| 721 (last_match_was_search_ || | 714 (last_match_was_search_ || |
| 722 last_suggestion_.behavior == INSTANT_COMPLETE_NEVER); | 715 last_suggestion_.behavior == INSTANT_COMPLETE_NEVER); |
| 723 } | 716 } |
| 724 | 717 |
| 725 bool InstantController::CommitIfPossible(InstantCommitType type) { | 718 bool InstantController::CommitIfPossible(InstantCommitType type) { |
| 726 if (!extended_enabled_ && !instant_enabled_) | 719 if (!extended_enabled_ && !instant_enabled_) |
| 727 return false; | 720 return false; |
| 728 | 721 |
| 729 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf( | 722 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf( |
| 730 "CommitIfPossible: type=%d last_omnibox_text_='%s' " | 723 "CommitIfPossible: type=%d last_omnibox_text_='%s' " |
| 731 "last_match_was_search_=%d instant_tab_=%d", type, | 724 "last_match_was_search_=%d use_tab_for_suggestions=%d", type, |
| 732 UTF16ToUTF8(last_omnibox_text_).c_str(), last_match_was_search_, | 725 UTF16ToUTF8(last_omnibox_text_).c_str(), last_match_was_search_, |
| 733 instant_tab_ != NULL)); | 726 UseTabForSuggestions())); |
| 734 | 727 |
| 735 // If we are on an already committed search results page, send a submit event | 728 // If we are on an already committed search results page, send a submit event |
| 736 // to the page, but otherwise, nothing else to do. | 729 // to the page, but otherwise, nothing else to do. |
| 737 if (instant_tab_) { | 730 if (UseTabForSuggestions()) { |
| 738 if (type == INSTANT_COMMIT_PRESSED_ENTER && | 731 if (type == INSTANT_COMMIT_PRESSED_ENTER && |
| 739 !instant_tab_->IsLocal() && | 732 !instant_tab_->IsLocal() && |
| 740 (last_match_was_search_ || | 733 (last_match_was_search_ || |
| 741 last_suggestion_.behavior == INSTANT_COMPLETE_NEVER)) { | 734 last_suggestion_.behavior == INSTANT_COMPLETE_NEVER)) { |
| 742 last_suggestion_.text.clear(); | 735 last_suggestion_.text.clear(); |
| 743 instant_tab_->Submit(last_omnibox_text_); | 736 instant_tab_->Submit(last_omnibox_text_); |
| 744 instant_tab_->contents()->GetView()->Focus(); | 737 instant_tab_->contents()->GetView()->Focus(); |
| 745 EnsureSearchTermsAreSet(instant_tab_->contents(), last_omnibox_text_); | 738 EnsureSearchTermsAreSet(instant_tab_->contents(), last_omnibox_text_); |
| 746 return true; | 739 return true; |
| 747 } | 740 } |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 852 // Hide explicitly. See comments in HideOverlay() for why. | 845 // Hide explicitly. See comments in HideOverlay() for why. |
| 853 model_.SetOverlayState(SearchMode(), 0, INSTANT_SIZE_PERCENT); | 846 model_.SetOverlayState(SearchMode(), 0, INSTANT_SIZE_PERCENT); |
| 854 | 847 |
| 855 // Delay deletion as we could've gotten here from an InstantOverlay method. | 848 // Delay deletion as we could've gotten here from an InstantOverlay method. |
| 856 DeletePageSoon(overlay_.Pass()); | 849 DeletePageSoon(overlay_.Pass()); |
| 857 | 850 |
| 858 // Try to create another overlay immediately so that it is ready for the next | 851 // Try to create another overlay immediately so that it is ready for the next |
| 859 // user interaction. | 852 // user interaction. |
| 860 ResetOverlay(GetInstantURL()); | 853 ResetOverlay(GetInstantURL()); |
| 861 | 854 |
| 855 if (instant_tab_) |
| 856 use_tab_for_suggestions_ = true; |
| 857 |
| 862 LOG_INSTANT_DEBUG_EVENT(this, "Committed"); | 858 LOG_INSTANT_DEBUG_EVENT(this, "Committed"); |
| 863 return true; | 859 return true; |
| 864 } | 860 } |
| 865 | 861 |
| 866 void InstantController::OmniboxFocusChanged( | 862 void InstantController::OmniboxFocusChanged( |
| 867 OmniboxFocusState state, | 863 OmniboxFocusState state, |
| 868 OmniboxFocusChangeReason reason, | 864 OmniboxFocusChangeReason reason, |
| 869 gfx::NativeView view_gaining_focus) { | 865 gfx::NativeView view_gaining_focus) { |
| 870 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf( | 866 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf( |
| 871 "OmniboxFocusChanged: %d to %d for reason %d", omnibox_focus_state_, | 867 "OmniboxFocusChanged: %d to %d for reason %d", omnibox_focus_state_, |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1199 } | 1195 } |
| 1200 | 1196 |
| 1201 void InstantController::SetSuggestions( | 1197 void InstantController::SetSuggestions( |
| 1202 const content::WebContents* contents, | 1198 const content::WebContents* contents, |
| 1203 const std::vector<InstantSuggestion>& suggestions) { | 1199 const std::vector<InstantSuggestion>& suggestions) { |
| 1204 LOG_INSTANT_DEBUG_EVENT(this, "SetSuggestions"); | 1200 LOG_INSTANT_DEBUG_EVENT(this, "SetSuggestions"); |
| 1205 | 1201 |
| 1206 // Ignore if the message is from an unexpected source. | 1202 // Ignore if the message is from an unexpected source. |
| 1207 if (IsContentsFrom(ntp(), contents)) | 1203 if (IsContentsFrom(ntp(), contents)) |
| 1208 return; | 1204 return; |
| 1209 if (instant_tab_ && !IsContentsFrom(instant_tab(), contents)) | 1205 if (UseTabForSuggestions() && !IsContentsFrom(instant_tab(), contents)) |
| 1210 return; | 1206 return; |
| 1211 if (IsContentsFrom(overlay(), contents) && | 1207 if (IsContentsFrom(overlay(), contents) && |
| 1212 !allow_overlay_to_show_search_suggestions_) | 1208 !allow_overlay_to_show_search_suggestions_) |
| 1213 return; | 1209 return; |
| 1214 | 1210 |
| 1215 InstantSuggestion suggestion; | 1211 InstantSuggestion suggestion; |
| 1216 if (!suggestions.empty()) | 1212 if (!suggestions.empty()) |
| 1217 suggestion = suggestions[0]; | 1213 suggestion = suggestions[0]; |
| 1218 | 1214 |
| 1219 // TODO(samarth): allow InstantTabs to call SetSuggestions() from the NTP once | 1215 // TODO(samarth): allow InstantTabs to call SetSuggestions() from the NTP once |
| 1220 // that is better supported. | 1216 // that is better supported. |
| 1221 bool can_use_instant_tab = instant_tab_ && search_mode_.is_search(); | 1217 bool can_use_instant_tab = UseTabForSuggestions() && |
| 1218 search_mode_.is_search(); |
| 1222 bool can_use_overlay = search_mode_.is_search_suggestions() && | 1219 bool can_use_overlay = search_mode_.is_search_suggestions() && |
| 1223 !last_omnibox_text_.empty(); | 1220 !last_omnibox_text_.empty(); |
| 1224 if (!can_use_instant_tab && !can_use_overlay) | 1221 if (!can_use_instant_tab && !can_use_overlay) |
| 1225 return; | 1222 return; |
| 1226 | 1223 |
| 1227 if (suggestion.behavior == INSTANT_COMPLETE_REPLACE) { | 1224 if (suggestion.behavior == INSTANT_COMPLETE_REPLACE) { |
| 1228 // We don't get an Update() when changing the omnibox due to a REPLACE | 1225 // We don't get an Update() when changing the omnibox due to a REPLACE |
| 1229 // suggestion (so that we don't inadvertently cause the overlay to change | 1226 // suggestion (so that we don't inadvertently cause the overlay to change |
| 1230 // what it's showing, as the user arrows up/down through the page-provided | 1227 // what it's showing, as the user arrows up/down through the page-provided |
| 1231 // suggestions). So, update these state variables here. | 1228 // suggestions). So, update these state variables here. |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1453 instant_tab_.reset(new InstantTab(this)); | 1450 instant_tab_.reset(new InstantTab(this)); |
| 1454 instant_tab_->Init(active_tab); | 1451 instant_tab_->Init(active_tab); |
| 1455 // Update theme info for this tab. | 1452 // Update theme info for this tab. |
| 1456 browser_->UpdateThemeInfo(); | 1453 browser_->UpdateThemeInfo(); |
| 1457 instant_tab_->SetDisplayInstantResults(instant_enabled_); | 1454 instant_tab_->SetDisplayInstantResults(instant_enabled_); |
| 1458 instant_tab_->SetOmniboxBounds(omnibox_bounds_); | 1455 instant_tab_->SetOmniboxBounds(omnibox_bounds_); |
| 1459 instant_tab_->InitializeFonts(); | 1456 instant_tab_->InitializeFonts(); |
| 1460 StartListeningToMostVisitedChanges(); | 1457 StartListeningToMostVisitedChanges(); |
| 1461 instant_tab_->KeyCaptureChanged( | 1458 instant_tab_->KeyCaptureChanged( |
| 1462 omnibox_focus_state_ == OMNIBOX_FOCUS_INVISIBLE); | 1459 omnibox_focus_state_ == OMNIBOX_FOCUS_INVISIBLE); |
| 1460 use_tab_for_suggestions_ = true; |
| 1463 } | 1461 } |
| 1464 | 1462 |
| 1465 // Hide the |overlay_| since we are now using |instant_tab_| instead. | 1463 // Hide the |overlay_| since we are now using |instant_tab_| instead. |
| 1466 HideOverlay(); | 1464 HideOverlay(); |
| 1467 } else { | 1465 } else { |
| 1468 instant_tab_.reset(); | 1466 instant_tab_.reset(); |
| 1469 } | 1467 } |
| 1470 } | 1468 } |
| 1471 | 1469 |
| 1472 void InstantController::HideOverlay() { | 1470 void InstantController::HideOverlay() { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1484 if (GetOverlayContents()) { | 1482 if (GetOverlayContents()) { |
| 1485 model_.SetOverlayState(SearchMode(), 0, INSTANT_SIZE_PERCENT); | 1483 model_.SetOverlayState(SearchMode(), 0, INSTANT_SIZE_PERCENT); |
| 1486 allow_overlay_to_show_search_suggestions_ = false; | 1484 allow_overlay_to_show_search_suggestions_ = false; |
| 1487 | 1485 |
| 1488 // Send a message asking the overlay to clear out old results. | 1486 // Send a message asking the overlay to clear out old results. |
| 1489 overlay_->Update(string16(), 0, 0, true); | 1487 overlay_->Update(string16(), 0, 0, true); |
| 1490 } | 1488 } |
| 1491 | 1489 |
| 1492 // Clear the first interaction timestamp for later use. | 1490 // Clear the first interaction timestamp for later use. |
| 1493 first_interaction_time_ = base::Time(); | 1491 first_interaction_time_ = base::Time(); |
| 1492 |
| 1493 if (instant_tab_) |
| 1494 use_tab_for_suggestions_ = true; |
| 1494 } | 1495 } |
| 1495 | 1496 |
| 1496 void InstantController::ShowOverlay(int height, InstantSizeUnits units) { | 1497 void InstantController::ShowOverlay(int height, InstantSizeUnits units) { |
| 1497 // If we are on a committed search results page, the |overlay_| is not in use. | 1498 // If we are on a committed search results page, the |overlay_| is not in use. |
| 1498 if (instant_tab_) | 1499 if (UseTabForSuggestions()) |
| 1499 return; | 1500 return; |
| 1500 | 1501 |
| 1501 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf( | 1502 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf( |
| 1502 "Show: height=%d units=%d", height, units)); | 1503 "Show: height=%d units=%d", height, units)); |
| 1503 | 1504 |
| 1504 // Must have updated omnibox after the last HideOverlay() to show suggestions. | 1505 // Must have updated omnibox after the last HideOverlay() to show suggestions. |
| 1505 if (!allow_overlay_to_show_search_suggestions_) | 1506 if (!allow_overlay_to_show_search_suggestions_) |
| 1506 return; | 1507 return; |
| 1507 | 1508 |
| 1508 // The page is trying to hide itself. Hide explicitly (i.e., don't use | 1509 // The page is trying to hide itself. Hide explicitly (i.e., don't use |
| 1509 // HideOverlay()) so that it can change its mind. | 1510 // HideOverlay()) so that it can change its mind. |
| 1510 if (height == 0) { | 1511 if (height == 0) { |
| 1511 model_.SetOverlayState(SearchMode(), 0, INSTANT_SIZE_PERCENT); | 1512 model_.SetOverlayState(SearchMode(), 0, INSTANT_SIZE_PERCENT); |
| 1513 if (instant_tab_) |
| 1514 use_tab_for_suggestions_ = true; |
| 1512 return; | 1515 return; |
| 1513 } | 1516 } |
| 1514 | 1517 |
| 1515 // If the overlay is being shown for the first time since the user started | 1518 // If the overlay is being shown for the first time since the user started |
| 1516 // typing, record a histogram value. | 1519 // typing, record a histogram value. |
| 1517 if (!first_interaction_time_.is_null() && model_.mode().is_default()) { | 1520 if (!first_interaction_time_.is_null() && model_.mode().is_default()) { |
| 1518 base::TimeDelta delta = base::Time::Now() - first_interaction_time_; | 1521 base::TimeDelta delta = base::Time::Now() - first_interaction_time_; |
| 1519 UMA_HISTOGRAM_TIMES("Instant.TimeToFirstShow", delta); | 1522 UMA_HISTOGRAM_TIMES("Instant.TimeToFirstShow", delta); |
| 1520 } | 1523 } |
| 1521 | 1524 |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1682 // suggest nothing. | 1685 // suggest nothing. |
| 1683 // TODO(samarth|jered): revisit this logic. http://crbug.com/196572. | 1686 // TODO(samarth|jered): revisit this logic. http://crbug.com/196572. |
| 1684 return true; | 1687 return true; |
| 1685 } | 1688 } |
| 1686 } | 1689 } |
| 1687 | 1690 |
| 1688 return false; | 1691 return false; |
| 1689 } | 1692 } |
| 1690 | 1693 |
| 1691 bool InstantController::UsingLocalPage() const { | 1694 bool InstantController::UsingLocalPage() const { |
| 1692 return (instant_tab_ && instant_tab_->IsLocal()) || | 1695 return (UseTabForSuggestions() && instant_tab_->IsLocal()) || |
| 1693 (!instant_tab_ && overlay_ && overlay_->IsLocal()); | 1696 (!UseTabForSuggestions() && overlay_ && overlay_->IsLocal()); |
| 1694 } | 1697 } |
| 1698 |
| 1699 bool InstantController::UseTabForSuggestions() const { |
| 1700 return instant_tab_ && use_tab_for_suggestions_; |
| 1701 } |
| OLD | NEW |