| 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 | 
|---|