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 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
261 UTF16ToUTF8(user_text).c_str(), UTF16ToUTF8(full_text).c_str(), | 261 UTF16ToUTF8(user_text).c_str(), UTF16ToUTF8(full_text).c_str(), |
262 static_cast<int>(selection_start), static_cast<int>(selection_end), | 262 static_cast<int>(selection_start), static_cast<int>(selection_end), |
263 verbatim, user_input_in_progress, omnibox_popup_is_open, escape_pressed, | 263 verbatim, user_input_in_progress, omnibox_popup_is_open, escape_pressed, |
264 is_keyword_search)); | 264 is_keyword_search)); |
265 | 265 |
266 // TODO(dhollowa): Complete keyword match UI. For now just hide suggestions. | 266 // TODO(dhollowa): Complete keyword match UI. For now just hide suggestions. |
267 // http://crbug.com/153932. Note, this early escape is happens prior to the | 267 // http://crbug.com/153932. Note, this early escape is happens prior to the |
268 // DCHECKs below because |user_text| and |full_text| have different semantics | 268 // DCHECKs below because |user_text| and |full_text| have different semantics |
269 // when keyword search is in effect. | 269 // when keyword search is in effect. |
270 if (is_keyword_search) { | 270 if (is_keyword_search) { |
271 if (UseInstantTabToShowSuggestions()) | 271 if (instant_tab_) |
272 instant_tab_->Update(string16(), 0, 0, true); | 272 instant_tab_->Update(string16(), 0, 0, true); |
273 else | 273 else |
274 HideOverlay(); | 274 HideOverlay(); |
275 last_match_was_search_ = false; | 275 last_match_was_search_ = false; |
276 return false; | 276 return false; |
277 } | 277 } |
278 | 278 |
279 // Ignore spurious updates when the omnibox is blurred; otherwise click | 279 // Ignore spurious updates when the omnibox is blurred; otherwise click |
280 // targets on the page may vanish before a click event arrives. | 280 // targets on the page may vanish before a click event arrives. |
281 if (omnibox_focus_state_ == OMNIBOX_FOCUS_NONE) | 281 if (omnibox_focus_state_ == OMNIBOX_FOCUS_NONE) |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
314 // In non extended mode, Instant is disabled for URLs and keyword mode. | 314 // In non extended mode, Instant is disabled for URLs and keyword mode. |
315 if (!extended_enabled_ && | 315 if (!extended_enabled_ && |
316 (!last_match_was_search_ || | 316 (!last_match_was_search_ || |
317 match.type == AutocompleteMatch::SEARCH_OTHER_ENGINE)) { | 317 match.type == AutocompleteMatch::SEARCH_OTHER_ENGINE)) { |
318 HideOverlay(); | 318 HideOverlay(); |
319 return false; | 319 return false; |
320 } | 320 } |
321 | 321 |
322 // If we have an |instant_tab_| use it, else ensure we have an overlay that is | 322 // If we have an |instant_tab_| use it, else ensure we have an overlay that is |
323 // current or is using the local overlay. | 323 // current or is using the local overlay. |
324 if (!UseInstantTabToShowSuggestions() && | 324 if (!instant_tab_ && !(overlay_ && overlay_->IsLocal()) && |
325 !(overlay_ && overlay_->IsLocalOverlay()) && | |
326 !EnsureOverlayIsCurrent(false)) { | 325 !EnsureOverlayIsCurrent(false)) { |
327 HideOverlay(); | 326 HideOverlay(); |
328 return false; | 327 return false; |
329 } | 328 } |
330 | 329 |
331 if (extended_enabled_) { | 330 if (extended_enabled_) { |
332 if (!omnibox_popup_is_open) { | 331 if (!omnibox_popup_is_open) { |
333 if (!user_input_in_progress) { | 332 if (!user_input_in_progress) { |
334 // If the user isn't typing and the omnibox popup is closed, it means a | 333 // If the user isn't typing and the omnibox popup is closed, it means a |
335 // regular navigation, tab-switch or the user hitting Escape. | 334 // regular navigation, tab-switch or the user hitting Escape. |
336 if (UseInstantTabToShowSuggestions()) { | 335 if (instant_tab_) { |
337 // The user is on a search results page. It may be showing results for | 336 // The user is on a search results page. It may be showing results for |
338 // a partial query the user typed before they hit Escape. Send the | 337 // a partial query the user typed before they hit Escape. Send the |
339 // omnibox text to the page to restore the original results. | 338 // omnibox text to the page to restore the original results. |
340 // | 339 // |
341 // In a tab switch, |instant_tab_| won't have updated yet, so it may | 340 // In a tab switch, |instant_tab_| won't have updated yet, so it may |
342 // be pointing to the previous tab (which was a search results page). | 341 // be pointing to the previous tab (which was a search results page). |
343 // Ensure we don't send the omnibox text to a random webpage (the new | 342 // Ensure we don't send the omnibox text to a random webpage (the new |
344 // tab), by comparing the old and new WebContents. | 343 // tab), by comparing the old and new WebContents. |
345 if (escape_pressed && | 344 if (escape_pressed && |
346 instant_tab_->contents() == browser_->GetActiveWebContents()) { | 345 instant_tab_->contents() == browser_->GetActiveWebContents()) { |
347 instant_tab_->Submit(full_text); | 346 instant_tab_->Submit(full_text); |
348 } | 347 } |
349 } else if (!full_text.empty()) { | 348 } else if (!full_text.empty()) { |
350 // If |full_text| is empty, the user is on the NTP. The overlay may | 349 // If |full_text| is empty, the user is on the NTP. The overlay may |
351 // be showing custom NTP content; hide only if that's not the case. | 350 // be showing custom NTP content; hide only if that's not the case. |
352 HideOverlay(); | 351 HideOverlay(); |
353 } | 352 } |
354 } else if (full_text.empty()) { | 353 } else if (full_text.empty()) { |
355 // The user is typing, and backspaced away all omnibox text. Clear | 354 // The user is typing, and backspaced away all omnibox text. Clear |
356 // |last_omnibox_text_| so that we don't attempt to set suggestions. | 355 // |last_omnibox_text_| so that we don't attempt to set suggestions. |
357 last_omnibox_text_.clear(); | 356 last_omnibox_text_.clear(); |
358 last_user_text_.clear(); | 357 last_user_text_.clear(); |
359 last_suggestion_ = InstantSuggestion(); | 358 last_suggestion_ = InstantSuggestion(); |
360 if (UseInstantTabToShowSuggestions()) { | 359 if (instant_tab_) { |
361 // On a search results page, tell it to clear old results. | 360 // On a search results page, tell it to clear old results. |
362 instant_tab_->Update(string16(), 0, 0, true); | 361 instant_tab_->Update(string16(), 0, 0, true); |
363 } else if (search_mode_.is_origin_ntp()) { | 362 } else if (search_mode_.is_origin_ntp()) { |
364 // On the NTP, tell the overlay to clear old results. Don't hide the | 363 // On the NTP, tell the overlay to clear old results. Don't hide the |
365 // overlay so it can show a blank page or logo if it wants. | 364 // overlay so it can show a blank page or logo if it wants. |
366 overlay_->Update(string16(), 0, 0, true); | 365 overlay_->Update(string16(), 0, 0, true); |
367 } else { | 366 } else { |
368 HideOverlay(); | 367 HideOverlay(); |
369 } | 368 } |
370 } else { | 369 } else { |
371 // The user switched to a tab with partial text already in the omnibox. | 370 // The user switched to a tab with partial text already in the omnibox. |
372 HideOverlay(); | 371 HideOverlay(); |
373 | 372 |
374 // The new tab may or may not be a search results page; we don't know | 373 // The new tab may or may not be a search results page; we don't know |
375 // since SearchModeChanged() hasn't been called yet. If it later turns | 374 // since SearchModeChanged() hasn't been called yet. If it later turns |
376 // out to be, we should store |full_text| now, so that if the user hits | 375 // out to be, we should store |full_text| now, so that if the user hits |
377 // Enter, we'll send the correct query to instant_tab_->Submit(). If the | 376 // Enter, we'll send the correct query to instant_tab_->Submit(). If the |
378 // partial text is not a query (|last_match_was_search_| is false), we | 377 // partial text is not a query (|last_match_was_search_| is false), we |
379 // won't Submit(), so no need to worry about that. | 378 // won't Submit(), so no need to worry about that. |
380 last_omnibox_text_ = full_text; | 379 last_omnibox_text_ = full_text; |
381 last_user_text_ = user_text; | 380 last_user_text_ = user_text; |
382 last_suggestion_ = InstantSuggestion(); | 381 last_suggestion_ = InstantSuggestion(); |
383 } | 382 } |
384 return false; | 383 return false; |
385 } else if (full_text.empty()) { | 384 } else if (full_text.empty()) { |
386 // The user typed a solitary "?". Same as the backspace case above. | 385 // The user typed a solitary "?". Same as the backspace case above. |
387 last_omnibox_text_.clear(); | 386 last_omnibox_text_.clear(); |
388 last_user_text_.clear(); | 387 last_user_text_.clear(); |
389 last_suggestion_ = InstantSuggestion(); | 388 last_suggestion_ = InstantSuggestion(); |
390 if (UseInstantTabToShowSuggestions()) | 389 if (instant_tab_) |
391 instant_tab_->Update(string16(), 0, 0, true); | 390 instant_tab_->Update(string16(), 0, 0, true); |
392 else if (search_mode_.is_origin_ntp()) | 391 else if (search_mode_.is_origin_ntp()) |
393 overlay_->Update(string16(), 0, 0, true); | 392 overlay_->Update(string16(), 0, 0, true); |
394 else | 393 else |
395 HideOverlay(); | 394 HideOverlay(); |
396 return false; | 395 return false; |
397 } | 396 } |
398 } else if (!omnibox_popup_is_open || full_text.empty()) { | 397 } else if (!omnibox_popup_is_open || full_text.empty()) { |
399 // In the non-extended case, hide the overlay as long as the user isn't | 398 // In the non-extended case, hide the overlay as long as the user isn't |
400 // actively typing a non-empty query. | 399 // actively typing a non-empty query. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
435 last_verbatim_ = verbatim; | 434 last_verbatim_ = verbatim; |
436 | 435 |
437 last_transition_type_ = match.transition; | 436 last_transition_type_ = match.transition; |
438 url_for_history_ = match.destination_url; | 437 url_for_history_ = match.destination_url; |
439 | 438 |
440 // Allow search suggestions. In extended mode, SearchModeChanged() will set | 439 // Allow search suggestions. In extended mode, SearchModeChanged() will set |
441 // this, but it's not called in non-extended mode, so fake it. | 440 // this, but it's not called in non-extended mode, so fake it. |
442 if (!extended_enabled_) | 441 if (!extended_enabled_) |
443 search_mode_.mode = SearchMode::MODE_SEARCH_SUGGESTIONS; | 442 search_mode_.mode = SearchMode::MODE_SEARCH_SUGGESTIONS; |
444 | 443 |
445 if (UseInstantTabToShowSuggestions()) { | 444 if (instant_tab_) { |
446 // If we have an |instant_tab_| but it doesn't support Instant yet, sever | 445 // If we have an |instant_tab_| but it doesn't support Instant yet, sever |
447 // the connection to it so we use the overlay instead. This ensures that the | 446 // the connection to it so we use the overlay instead. This ensures that the |
448 // user interaction will be responsive and handles cases where | 447 // user interaction will be responsive and handles cases where |
449 // |instant_tab_| never responds about whether it supports Instant. | 448 // |instant_tab_| never responds about whether it supports Instant. |
450 if (instant_tab_->supports_instant()) | 449 if (instant_tab_->supports_instant()) |
451 instant_tab_->Update(user_text, selection_start, selection_end, verbatim); | 450 instant_tab_->Update(user_text, selection_start, selection_end, verbatim); |
452 else | 451 else |
453 instant_tab_.reset(); | 452 instant_tab_.reset(); |
454 } | 453 } |
455 | 454 |
456 if (!UseInstantTabToShowSuggestions()) { | 455 if (!instant_tab_) { |
457 if (first_interaction_time_.is_null()) | 456 if (first_interaction_time_.is_null()) |
458 first_interaction_time_ = base::Time::Now(); | 457 first_interaction_time_ = base::Time::Now(); |
459 allow_overlay_to_show_search_suggestions_ = true; | 458 allow_overlay_to_show_search_suggestions_ = true; |
460 | 459 |
461 // For extended mode, if the loader is not ready at this point, switch over | 460 // For extended mode, if the loader is not ready at this point, switch over |
462 // to a backup loader. | 461 // to a backup loader. |
463 if (extended_enabled_ && !overlay_->supports_instant() && | 462 if (extended_enabled_ && !overlay_->supports_instant() && |
464 !overlay_->IsLocalOverlay() && browser_->GetActiveWebContents()) { | 463 !overlay_->IsLocal() && browser_->GetActiveWebContents()) { |
465 CreateOverlay(chrome::kChromeSearchLocalOmniboxPopupURL, | 464 CreateOverlay(chrome::GetLocalInstantURL(browser_->profile()).spec(), |
466 browser_->GetActiveWebContents()); | 465 browser_->GetActiveWebContents()); |
467 } | 466 } |
468 | 467 |
469 overlay_->Update(extended_enabled_ ? user_text : full_text, | 468 overlay_->Update(extended_enabled_ ? user_text : full_text, |
470 selection_start, selection_end, verbatim); | 469 selection_start, selection_end, verbatim); |
471 } | 470 } |
472 | 471 |
473 content::NotificationService::current()->Notify( | 472 content::NotificationService::current()->Notify( |
474 chrome::NOTIFICATION_INSTANT_CONTROLLER_UPDATED, | 473 chrome::NOTIFICATION_INSTANT_CONTROLLER_UPDATED, |
475 content::Source<InstantController>(this), | 474 content::Source<InstantController>(this), |
476 content::NotificationService::NoDetails()); | 475 content::NotificationService::NoDetails()); |
477 | 476 |
478 // We don't have new suggestions yet, but we can either reuse the existing | 477 // We don't have new suggestions yet, but we can either reuse the existing |
479 // suggestion or reset the existing "gray text". | 478 // suggestion or reset the existing "gray text". |
480 browser_->SetInstantSuggestion(last_suggestion_); | 479 browser_->SetInstantSuggestion(last_suggestion_); |
481 | 480 |
482 return true; | 481 return true; |
483 } | 482 } |
484 | 483 |
485 scoped_ptr<content::WebContents> InstantController::ReleaseNTPContents() { | 484 scoped_ptr<content::WebContents> InstantController::ReleaseNTPContents() { |
486 if (!extended_enabled_ || !browser_->profile() || | 485 if (!extended_enabled_ || !browser_->profile() || |
487 browser_->profile()->IsOffTheRecord()) | 486 browser_->profile()->IsOffTheRecord()) |
488 return scoped_ptr<content::WebContents>(NULL); | 487 return scoped_ptr<content::WebContents>(NULL); |
489 | 488 |
490 LOG_INSTANT_DEBUG_EVENT(this, "ReleaseNTPContents"); | 489 LOG_INSTANT_DEBUG_EVENT(this, "ReleaseNTPContents"); |
491 | 490 |
492 // Switch to the local NTP unless we're already using one. | 491 // Switch to the local NTP unless its URL hasn't changed. |
493 if (!ntp_ || (ShouldSwitchToLocalNTP() && !ntp_->IsLocalNTP())) | 492 if (!ntp_ || ShouldSwitchToLocalNTP()) |
samarth
2013/04/17 17:24:59
A few more comments here actually:
1) Please also
jeremycho
2013/04/17 20:14:33
Done. Left a TODO for the test.
| |
494 ResetNTP(false, true); | 493 ResetNTP(false, true); |
495 | 494 |
496 scoped_ptr<content::WebContents> ntp_contents = ntp_->ReleaseContents(); | 495 scoped_ptr<content::WebContents> ntp_contents = ntp_->ReleaseContents(); |
497 | 496 |
498 // Override the blacklist on an explicit user action. | 497 // Override the blacklist on an explicit user action. |
499 ResetNTP(true, false); | 498 ResetNTP(true, false); |
500 return ntp_contents.Pass(); | 499 return ntp_contents.Pass(); |
501 } | 500 } |
502 | 501 |
503 // TODO(tonyg): This method only fires when the omnibox bounds change. It also | 502 // TODO(tonyg): This method only fires when the omnibox bounds change. It also |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
545 // as it stops autocomplete. Ignore these. | 544 // as it stops autocomplete. Ignore these. |
546 if (omnibox_focus_state_ == OMNIBOX_FOCUS_NONE) | 545 if (omnibox_focus_state_ == OMNIBOX_FOCUS_NONE) |
547 return; | 546 return; |
548 | 547 |
549 DVLOG(1) << "AutocompleteResults:"; | 548 DVLOG(1) << "AutocompleteResults:"; |
550 std::vector<InstantAutocompleteResult> results; | 549 std::vector<InstantAutocompleteResult> results; |
551 for (ACProviders::const_iterator provider = providers.begin(); | 550 for (ACProviders::const_iterator provider = providers.begin(); |
552 provider != providers.end(); ++provider) { | 551 provider != providers.end(); ++provider) { |
553 const bool from_search_provider = | 552 const bool from_search_provider = |
554 (*provider)->type() == AutocompleteProvider::TYPE_SEARCH; | 553 (*provider)->type() == AutocompleteProvider::TYPE_SEARCH; |
555 // Unless we are talking to the local overlay, skip SearchProvider, since | 554 const bool using_local_page = |
556 // it only echoes suggestions. | 555 (instant_tab_ && instant_tab_->IsLocal()) || overlay_->IsLocal(); |
557 if (from_search_provider && | 556 // Unless we are talking to a local page, skip SearchProvider, since it only |
558 (UseInstantTabToShowSuggestions() || !overlay_->IsLocalOverlay())) | 557 // echoes suggestions. |
558 if (from_search_provider && !using_local_page) | |
559 continue; | 559 continue; |
560 // Only send autocomplete results when all the providers are done. Skip | 560 // Only send autocomplete results when all the providers are done. Skip |
561 // this check for the SearchProvider, since it isn't done until the page | 561 // this check for the SearchProvider, since it isn't done until the page |
562 // calls SetSuggestions (causing SearchProvider::FinalizeInstantQuery() to | 562 // calls SetSuggestions (causing SearchProvider::FinalizeInstantQuery() to |
563 // be called), which makes it a chicken-and-egg thing. | 563 // be called), which makes it a chicken-and-egg thing. |
564 if (!from_search_provider && !(*provider)->done()) { | 564 if (!from_search_provider && !(*provider)->done()) { |
565 DVLOG(1) << "Waiting for " << (*provider)->GetName(); | 565 DVLOG(1) << "Waiting for " << (*provider)->GetName(); |
566 return; | 566 return; |
567 } | 567 } |
568 for (ACMatches::const_iterator match = (*provider)->matches().begin(); | 568 for (ACMatches::const_iterator match = (*provider)->matches().begin(); |
(...skipping 11 matching lines...) Expand all Loading... | |
580 << result.provider << " " << result.destination_url << " '" | 580 << result.provider << " " << result.destination_url << " '" |
581 << result.description << "' '" << result.search_query << "' " | 581 << result.description << "' '" << result.search_query << "' " |
582 << result.transition; | 582 << result.transition; |
583 results.push_back(result); | 583 results.push_back(result); |
584 } | 584 } |
585 } | 585 } |
586 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf( | 586 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf( |
587 "HandleAutocompleteResults: total_results=%d", | 587 "HandleAutocompleteResults: total_results=%d", |
588 static_cast<int>(results.size()))); | 588 static_cast<int>(results.size()))); |
589 | 589 |
590 if (UseInstantTabToShowSuggestions()) | 590 if (instant_tab_) |
591 instant_tab_->SendAutocompleteResults(results); | 591 instant_tab_->SendAutocompleteResults(results); |
592 else | 592 else |
593 overlay_->SendAutocompleteResults(results); | 593 overlay_->SendAutocompleteResults(results); |
594 } | 594 } |
595 | 595 |
596 bool InstantController::OnUpOrDownKeyPressed(int count) { | 596 bool InstantController::OnUpOrDownKeyPressed(int count) { |
597 if (!extended_enabled_) | 597 if (!extended_enabled_) |
598 return false; | 598 return false; |
599 | 599 |
600 if (!instant_tab_ && !overlay_) | 600 if (!instant_tab_ && !overlay_) |
601 return false; | 601 return false; |
602 | 602 |
603 if (UseInstantTabToShowSuggestions()) | 603 if (instant_tab_) |
604 instant_tab_->UpOrDownKeyPressed(count); | 604 instant_tab_->UpOrDownKeyPressed(count); |
605 else | 605 else |
606 overlay_->UpOrDownKeyPressed(count); | 606 overlay_->UpOrDownKeyPressed(count); |
607 | 607 |
608 return true; | 608 return true; |
609 } | 609 } |
610 | 610 |
611 void InstantController::OnCancel(const AutocompleteMatch& match, | 611 void InstantController::OnCancel(const AutocompleteMatch& match, |
612 const string16& user_text, | 612 const string16& user_text, |
613 const string16& full_text) { | 613 const string16& full_text) { |
614 if (!extended_enabled_) | 614 if (!extended_enabled_) |
615 return; | 615 return; |
616 | 616 |
617 if (!instant_tab_ && !overlay_) | 617 if (!instant_tab_ && !overlay_) |
618 return; | 618 return; |
619 | 619 |
620 // We manually reset the state here since the JS is not expected to do it. | 620 // We manually reset the state here since the JS is not expected to do it. |
621 // TODO(sreeram): Handle the case where user_text is now a URL | 621 // TODO(sreeram): Handle the case where user_text is now a URL |
622 last_match_was_search_ = AutocompleteMatch::IsSearchType(match.type) && | 622 last_match_was_search_ = AutocompleteMatch::IsSearchType(match.type) && |
623 !full_text.empty(); | 623 !full_text.empty(); |
624 last_omnibox_text_ = full_text; | 624 last_omnibox_text_ = full_text; |
625 last_user_text_ = user_text; | 625 last_user_text_ = user_text; |
626 last_suggestion_ = InstantSuggestion(); | 626 last_suggestion_ = InstantSuggestion(); |
627 | 627 |
628 // Say |full_text| is "amazon.com" and |user_text| is "ama". This means the | 628 // Say |full_text| is "amazon.com" and |user_text| is "ama". This means the |
629 // inline autocompletion is "zon.com"; so the selection should span from | 629 // inline autocompletion is "zon.com"; so the selection should span from |
630 // user_text.size() to full_text.size(). The selection bounds are inverted | 630 // user_text.size() to full_text.size(). The selection bounds are inverted |
631 // because the caret is at the end of |user_text|, not |full_text|. | 631 // because the caret is at the end of |user_text|, not |full_text|. |
632 if (UseInstantTabToShowSuggestions()) { | 632 if (instant_tab_) { |
633 instant_tab_->CancelSelection(user_text, full_text.size(), user_text.size(), | 633 instant_tab_->CancelSelection(user_text, full_text.size(), user_text.size(), |
634 last_verbatim_); | 634 last_verbatim_); |
635 } else { | 635 } else { |
636 overlay_->CancelSelection(user_text, full_text.size(), user_text.size(), | 636 overlay_->CancelSelection(user_text, full_text.size(), user_text.size(), |
637 last_verbatim_); | 637 last_verbatim_); |
638 } | 638 } |
639 } | 639 } |
640 | 640 |
641 void InstantController::OmniboxNavigateToURL() { | 641 void InstantController::OmniboxNavigateToURL() { |
642 if (!extended_enabled_) | 642 if (!extended_enabled_) |
(...skipping 18 matching lines...) Expand all Loading... | |
661 return false; | 661 return false; |
662 | 662 |
663 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf( | 663 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf( |
664 "CommitIfPossible: type=%d last_omnibox_text_='%s' " | 664 "CommitIfPossible: type=%d last_omnibox_text_='%s' " |
665 "last_match_was_search_=%d instant_tab_=%d", type, | 665 "last_match_was_search_=%d instant_tab_=%d", type, |
666 UTF16ToUTF8(last_omnibox_text_).c_str(), last_match_was_search_, | 666 UTF16ToUTF8(last_omnibox_text_).c_str(), last_match_was_search_, |
667 instant_tab_ != NULL)); | 667 instant_tab_ != NULL)); |
668 | 668 |
669 // If we are on an already committed search results page, send a submit event | 669 // If we are on an already committed search results page, send a submit event |
670 // to the page, but otherwise, nothing else to do. | 670 // to the page, but otherwise, nothing else to do. |
671 if (UseInstantTabToShowSuggestions()) { | 671 if (instant_tab_) { |
672 if (type == INSTANT_COMMIT_PRESSED_ENTER && | 672 if (type == INSTANT_COMMIT_PRESSED_ENTER && |
673 !instant_tab_->IsLocal() && | |
673 (last_match_was_search_ || | 674 (last_match_was_search_ || |
674 last_suggestion_.behavior == INSTANT_COMPLETE_NEVER)) { | 675 last_suggestion_.behavior == INSTANT_COMPLETE_NEVER)) { |
675 last_suggestion_.text.clear(); | 676 last_suggestion_.text.clear(); |
676 instant_tab_->Submit(last_omnibox_text_); | 677 instant_tab_->Submit(last_omnibox_text_); |
677 instant_tab_->contents()->GetView()->Focus(); | 678 instant_tab_->contents()->GetView()->Focus(); |
678 EnsureSearchTermsAreSet(instant_tab_->contents(), last_omnibox_text_); | 679 EnsureSearchTermsAreSet(instant_tab_->contents(), last_omnibox_text_); |
679 return true; | 680 return true; |
680 } | 681 } |
681 return false; | 682 return false; |
682 } | 683 } |
683 | 684 |
684 // If the overlay is not showing at all, don't commit it. | 685 // If the overlay is not showing at all, don't commit it. |
685 if (!model_.mode().is_search_suggestions()) | 686 if (!model_.mode().is_search_suggestions()) |
686 return false; | 687 return false; |
687 | 688 |
688 // If the overlay is showing at full height (with results), commit it. | 689 // If the overlay is showing at full height (with results), commit it. |
689 // If it's showing at parial height, commit if it's navigating. | 690 // If it's showing at parial height, commit if it's navigating. |
690 if (!IsOverlayingSearchResults() && type != INSTANT_COMMIT_NAVIGATED) | 691 if (!IsOverlayingSearchResults() && type != INSTANT_COMMIT_NAVIGATED) |
691 return false; | 692 return false; |
692 | 693 |
693 // There may re-entrance here, from the call to browser_->CommitInstant below, | 694 // There may re-entrance here, from the call to browser_->CommitInstant below, |
694 // which can cause a TabDeactivated notification which gets back here. | 695 // which can cause a TabDeactivated notification which gets back here. |
695 // In this case, overlay_->ReleaseContents() was called already. | 696 // In this case, overlay_->ReleaseContents() was called already. |
696 if (!GetOverlayContents()) | 697 if (!GetOverlayContents()) |
697 return false; | 698 return false; |
698 | 699 |
699 // Never commit the local overlay. | 700 // Never commit the local overlay. |
700 if (overlay_->IsLocalOverlay()) | 701 if (overlay_->IsLocal()) |
701 return false; | 702 return false; |
702 | 703 |
703 if (type == INSTANT_COMMIT_FOCUS_LOST) { | 704 if (type == INSTANT_COMMIT_FOCUS_LOST) { |
704 // Extended mode doesn't need or use the Cancel message. | 705 // Extended mode doesn't need or use the Cancel message. |
705 if (!extended_enabled_) | 706 if (!extended_enabled_) |
706 overlay_->Cancel(last_omnibox_text_); | 707 overlay_->Cancel(last_omnibox_text_); |
707 } else if (type != INSTANT_COMMIT_NAVIGATED) { | 708 } else if (type != INSTANT_COMMIT_NAVIGATED) { |
708 overlay_->Submit(last_omnibox_text_); | 709 overlay_->Submit(last_omnibox_text_); |
709 } | 710 } |
710 | 711 |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
922 #if defined(USE_AURA) | 923 #if defined(USE_AURA) |
923 // On aura the omnibox only receives a focus lost if we initiate the focus | 924 // On aura the omnibox only receives a focus lost if we initiate the focus |
924 // change. This does that. | 925 // change. This does that. |
925 if (!model_.mode().is_default()) | 926 if (!model_.mode().is_default()) |
926 browser_->InstantOverlayFocused(); | 927 browser_->InstantOverlayFocused(); |
927 #endif | 928 #endif |
928 } | 929 } |
929 | 930 |
930 void InstantController::ReloadOverlayIfStale() { | 931 void InstantController::ReloadOverlayIfStale() { |
931 // The local overlay is never stale. | 932 // The local overlay is never stale. |
932 if (overlay_ && overlay_->IsLocalOverlay()) | 933 if (overlay_ && overlay_->IsLocal()) |
933 return; | 934 return; |
934 | 935 |
935 // If the overlay is showing or the omnibox has focus, don't delete the | 936 // If the overlay is showing or the omnibox has focus, don't delete the |
936 // overlay. It will get refreshed the next time the overlay is hidden or the | 937 // overlay. It will get refreshed the next time the overlay is hidden or the |
937 // omnibox loses focus. | 938 // omnibox loses focus. |
938 if ((!overlay_ || overlay_->is_stale()) && | 939 if ((!overlay_ || overlay_->is_stale()) && |
939 omnibox_focus_state_ == OMNIBOX_FOCUS_NONE && | 940 omnibox_focus_state_ == OMNIBOX_FOCUS_NONE && |
940 model_.mode().is_default()) { | 941 model_.mode().is_default()) { |
941 overlay_.reset(); | 942 overlay_.reset(); |
942 EnsureOverlayIsCurrent(false); | 943 EnsureOverlayIsCurrent(false); |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1112 } | 1113 } |
1113 | 1114 |
1114 void InstantController::SetSuggestions( | 1115 void InstantController::SetSuggestions( |
1115 const content::WebContents* contents, | 1116 const content::WebContents* contents, |
1116 const std::vector<InstantSuggestion>& suggestions) { | 1117 const std::vector<InstantSuggestion>& suggestions) { |
1117 LOG_INSTANT_DEBUG_EVENT(this, "SetSuggestions"); | 1118 LOG_INSTANT_DEBUG_EVENT(this, "SetSuggestions"); |
1118 | 1119 |
1119 // Ignore if the message is from an unexpected source. | 1120 // Ignore if the message is from an unexpected source. |
1120 if (IsContentsFrom(ntp(), contents)) | 1121 if (IsContentsFrom(ntp(), contents)) |
1121 return; | 1122 return; |
1122 if (UseInstantTabToShowSuggestions() && | 1123 if (instant_tab_ && !IsContentsFrom(instant_tab(), contents)) |
1123 !IsContentsFrom(instant_tab(), contents)) | |
1124 return; | 1124 return; |
1125 if (IsContentsFrom(overlay(), contents) && | 1125 if (IsContentsFrom(overlay(), contents) && |
1126 !allow_overlay_to_show_search_suggestions_) | 1126 !allow_overlay_to_show_search_suggestions_) |
1127 return; | 1127 return; |
1128 | 1128 |
1129 InstantSuggestion suggestion; | 1129 InstantSuggestion suggestion; |
1130 if (!suggestions.empty()) | 1130 if (!suggestions.empty()) |
1131 suggestion = suggestions[0]; | 1131 suggestion = suggestions[0]; |
1132 | 1132 |
1133 // TODO(samarth): allow InstantTabs to call SetSuggestions() from the NTP once | 1133 // TODO(samarth): allow InstantTabs to call SetSuggestions() from the NTP once |
1134 // that is better supported. | 1134 // that is better supported. |
1135 bool can_use_instant_tab = UseInstantTabToShowSuggestions() && | 1135 bool can_use_instant_tab = instant_tab_ && search_mode_.is_search(); |
1136 search_mode_.is_search(); | |
1137 bool can_use_overlay = search_mode_.is_search_suggestions() && | 1136 bool can_use_overlay = search_mode_.is_search_suggestions() && |
1138 !last_omnibox_text_.empty(); | 1137 !last_omnibox_text_.empty(); |
1139 if (!can_use_instant_tab && !can_use_overlay) | 1138 if (!can_use_instant_tab && !can_use_overlay) |
1140 return; | 1139 return; |
1141 | 1140 |
1142 if (suggestion.behavior == INSTANT_COMPLETE_REPLACE) { | 1141 if (suggestion.behavior == INSTANT_COMPLETE_REPLACE) { |
1143 // We don't get an Update() when changing the omnibox due to a REPLACE | 1142 // We don't get an Update() when changing the omnibox due to a REPLACE |
1144 // suggestion (so that we don't inadvertently cause the overlay to change | 1143 // suggestion (so that we don't inadvertently cause the overlay to change |
1145 // what it's showing, as the user arrows up/down through the page-provided | 1144 // what it's showing, as the user arrows up/down through the page-provided |
1146 // suggestions). So, update these state variables here. | 1145 // suggestions). So, update these state variables here. |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1261 else if (!IsViewInContents(GetViewGainingFocus(view_gaining_focus), | 1260 else if (!IsViewInContents(GetViewGainingFocus(view_gaining_focus), |
1262 overlay_->contents())) | 1261 overlay_->contents())) |
1263 HideOverlay(); | 1262 HideOverlay(); |
1264 #endif | 1263 #endif |
1265 } | 1264 } |
1266 | 1265 |
1267 void InstantController::ResetNTP(bool ignore_blacklist, bool use_local_ntp) { | 1266 void InstantController::ResetNTP(bool ignore_blacklist, bool use_local_ntp) { |
1268 std::string instant_url; | 1267 std::string instant_url; |
1269 if (use_local_ntp || | 1268 if (use_local_ntp || |
1270 !GetInstantURL(browser_->profile(), ignore_blacklist, &instant_url)) | 1269 !GetInstantURL(browser_->profile(), ignore_blacklist, &instant_url)) |
1271 instant_url = chrome::kChromeSearchLocalNtpUrl; | 1270 instant_url = chrome::GetLocalInstantURL(browser_->profile()).spec(); |
1272 ntp_.reset(new InstantNTP(this, instant_url)); | 1271 ntp_.reset(new InstantNTP(this, instant_url)); |
1273 ntp_->InitContents(browser_->profile(), browser_->GetActiveWebContents(), | 1272 ntp_->InitContents(browser_->profile(), browser_->GetActiveWebContents(), |
1274 base::Bind(&InstantController::ResetNTP, | 1273 base::Bind(&InstantController::ResetNTP, |
1275 base::Unretained(this), false, false)); | 1274 base::Unretained(this), false, false)); |
1276 } | 1275 } |
1277 | 1276 |
1278 bool InstantController::EnsureOverlayIsCurrent(bool ignore_blacklist) { | 1277 bool InstantController::EnsureOverlayIsCurrent(bool ignore_blacklist) { |
1279 // If there's no active tab, the browser is closing. | 1278 // If there's no active tab, the browser is closing. |
1280 const content::WebContents* active_tab = browser_->GetActiveWebContents(); | 1279 const content::WebContents* active_tab = browser_->GetActiveWebContents(); |
1281 if (!active_tab) | 1280 if (!active_tab) |
1282 return false; | 1281 return false; |
1283 | 1282 |
1284 Profile* profile = Profile::FromBrowserContext( | 1283 Profile* profile = Profile::FromBrowserContext( |
1285 active_tab->GetBrowserContext()); | 1284 active_tab->GetBrowserContext()); |
1286 std::string instant_url; | 1285 std::string instant_url; |
1287 if (!GetInstantURL(profile, ignore_blacklist, &instant_url)) { | 1286 if (!GetInstantURL(profile, ignore_blacklist, &instant_url)) { |
1288 // If we are in extended mode, fallback to the local overlay. | 1287 // If we are in extended mode, fallback to the local overlay. |
1289 if (extended_enabled_) | 1288 if (extended_enabled_) |
1290 instant_url = chrome::kChromeSearchLocalOmniboxPopupURL; | 1289 instant_url = chrome::GetLocalInstantURL(browser_->profile()).spec(); |
1291 else | 1290 else |
1292 return false; | 1291 return false; |
1293 } | 1292 } |
1294 | 1293 |
1295 if (!overlay_ || overlay_->instant_url() != instant_url) | 1294 if (!overlay_ || overlay_->instant_url() != instant_url) |
1296 CreateOverlay(instant_url, active_tab); | 1295 CreateOverlay(instant_url, active_tab); |
1297 | 1296 |
1298 return true; | 1297 return true; |
1299 } | 1298 } |
1300 | 1299 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1362 // Send a message asking the overlay to clear out old results. | 1361 // Send a message asking the overlay to clear out old results. |
1363 overlay_->Update(string16(), 0, 0, true); | 1362 overlay_->Update(string16(), 0, 0, true); |
1364 } | 1363 } |
1365 | 1364 |
1366 // Clear the first interaction timestamp for later use. | 1365 // Clear the first interaction timestamp for later use. |
1367 first_interaction_time_ = base::Time(); | 1366 first_interaction_time_ = base::Time(); |
1368 } | 1367 } |
1369 | 1368 |
1370 void InstantController::ShowOverlay(int height, InstantSizeUnits units) { | 1369 void InstantController::ShowOverlay(int height, InstantSizeUnits units) { |
1371 // If we are on a committed search results page, the |overlay_| is not in use. | 1370 // If we are on a committed search results page, the |overlay_| is not in use. |
1372 if (UseInstantTabToShowSuggestions()) | 1371 if (instant_tab_) |
1373 return; | 1372 return; |
1374 | 1373 |
1375 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf( | 1374 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf( |
1376 "Show: height=%d units=%d", height, units)); | 1375 "Show: height=%d units=%d", height, units)); |
1377 | 1376 |
1378 // Must have updated omnibox after the last HideOverlay() to show suggestions. | 1377 // Must have updated omnibox after the last HideOverlay() to show suggestions. |
1379 if (!allow_overlay_to_show_search_suggestions_) | 1378 if (!allow_overlay_to_show_search_suggestions_) |
1380 return; | 1379 return; |
1381 | 1380 |
1382 // The page is trying to hide itself. Hide explicitly (i.e., don't use | 1381 // The page is trying to hide itself. Hide explicitly (i.e., don't use |
1383 // HideOverlay()) so that it can change its mind. | 1382 // HideOverlay()) so that it can change its mind. |
1384 if (height == 0) { | 1383 if (height == 0) { |
1385 model_.SetOverlayState(SearchMode(), 0, INSTANT_SIZE_PERCENT); | 1384 model_.SetOverlayState(SearchMode(), 0, INSTANT_SIZE_PERCENT); |
1386 return; | 1385 return; |
1387 } | 1386 } |
1388 | 1387 |
1389 // If the overlay is being shown for the first time since the user started | 1388 // If the overlay is being shown for the first time since the user started |
1390 // typing, record a histogram value. | 1389 // typing, record a histogram value. |
1391 if (!first_interaction_time_.is_null() && model_.mode().is_default()) { | 1390 if (!first_interaction_time_.is_null() && model_.mode().is_default()) { |
1392 base::TimeDelta delta = base::Time::Now() - first_interaction_time_; | 1391 base::TimeDelta delta = base::Time::Now() - first_interaction_time_; |
1393 UMA_HISTOGRAM_TIMES("Instant.TimeToFirstShow", delta); | 1392 UMA_HISTOGRAM_TIMES("Instant.TimeToFirstShow", delta); |
1394 } | 1393 } |
1395 | 1394 |
1396 // Show at 100% height except in the following cases: | 1395 // Show at 100% height except in the following cases: |
1397 // - The local overlay (omnibox popup) is being loaded. | 1396 // - The local overlay (omnibox popup) is being loaded. |
1398 // - Instant is disabled. The page needs to be able to show only a dropdown. | 1397 // - Instant is disabled. The page needs to be able to show only a dropdown. |
1399 // - The page is over a website other than search or an NTP, and is not | 1398 // - The page is over a website other than search or an NTP, and is not |
1400 // already showing at 100% height. | 1399 // already showing at 100% height. |
1401 if (overlay_->IsLocalOverlay() || !instant_enabled_ || | 1400 if (overlay_->IsLocal() || !instant_enabled_ || |
1402 (search_mode_.is_origin_default() && !IsFullHeight(model_))) | 1401 (search_mode_.is_origin_default() && !IsFullHeight(model_))) |
1403 model_.SetOverlayState(search_mode_, height, units); | 1402 model_.SetOverlayState(search_mode_, height, units); |
1404 else | 1403 else |
1405 model_.SetOverlayState(search_mode_, 100, INSTANT_SIZE_PERCENT); | 1404 model_.SetOverlayState(search_mode_, 100, INSTANT_SIZE_PERCENT); |
1406 | 1405 |
1407 // If the overlay is being shown at full height and the omnibox is not | 1406 // If the overlay is being shown at full height and the omnibox is not |
1408 // focused, commit right away. | 1407 // focused, commit right away. |
1409 if (IsFullHeight(model_) && omnibox_focus_state_ == OMNIBOX_FOCUS_NONE) | 1408 if (IsFullHeight(model_) && omnibox_focus_state_ == OMNIBOX_FOCUS_NONE) |
1410 CommitIfPossible(INSTANT_COMMIT_FOCUS_LOST); | 1409 CommitIfPossible(INSTANT_COMMIT_FOCUS_LOST); |
1411 } | 1410 } |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1607 // suggest 'nstant'. Otherwise, the user text really isn't a prefix, so | 1606 // suggest 'nstant'. Otherwise, the user text really isn't a prefix, so |
1608 // suggest nothing. | 1607 // suggest nothing. |
1609 // TODO(samarth|jered): revisit this logic. http://crbug.com/196572. | 1608 // TODO(samarth|jered): revisit this logic. http://crbug.com/196572. |
1610 return true; | 1609 return true; |
1611 } | 1610 } |
1612 } | 1611 } |
1613 | 1612 |
1614 return false; | 1613 return false; |
1615 } | 1614 } |
1616 | 1615 |
1617 bool InstantController::UseInstantTabToShowSuggestions() const { | 1616 bool InstantController::ShouldSwitchToLocalNTP() const { |
1618 return instant_tab_ && !instant_tab_->IsLocalNTP(); | 1617 bool localNtpUrlChanged = |
samarth
2013/04/17 16:24:11
This was really confusing for me to reason about.
jeremycho
2013/04/17 20:14:33
Done.
| |
1619 } | 1618 (ntp_->instant_url() != chrome::GetLocalInstantURL( |
1619 browser_->profile()).spec()); | |
1620 | 1620 |
1621 bool InstantController::ShouldSwitchToLocalNTP() const { | |
1622 // If there is no Instant URL or the NTP is stale, switch. | 1621 // If there is no Instant URL or the NTP is stale, switch. |
1623 std::string instant_url; | 1622 std::string instant_url; |
1624 if (!GetInstantURL(browser_->profile(), false, &instant_url) || | 1623 if (!GetInstantURL(browser_->profile(), false, &instant_url) || |
1625 !chrome::MatchesOriginAndPath(GURL(ntp_->instant_url()), | 1624 !chrome::MatchesOriginAndPath(GURL(ntp_->instant_url()), |
1626 GURL(instant_url))) { | 1625 GURL(instant_url))) { |
1627 return true; | 1626 return localNtpUrlChanged; |
1628 } | 1627 } |
1629 | 1628 |
1630 if (ntp_->supports_instant()) | 1629 if (ntp_->supports_instant()) |
1631 return false; | 1630 return false; |
1632 | 1631 |
1633 // If this is not window startup, switch. | 1632 // If this is not window startup, switch. |
1634 // TODO(shishir): This is not completely reliable. Find a better way to detect | 1633 // TODO(shishir): This is not completely reliable. Find a better way to detect |
1635 // startup time. | 1634 // startup time. |
1636 if (browser_->GetActiveWebContents()) | 1635 if (browser_->GetActiveWebContents()) |
1637 return true; | 1636 return localNtpUrlChanged; |
1638 | 1637 |
1639 return chrome::IsAggressiveLocalNTPFallbackEnabled(); | 1638 return chrome::IsAggressiveLocalNTPFallbackEnabled() && localNtpUrlChanged; |
1640 } | 1639 } |
OLD | NEW |