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