| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/instant/instant_controller.h" | 5 #include "chrome/browser/instant/instant_controller.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
| 9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
| 10 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 150 bool extended_enabled) | 150 bool extended_enabled) |
| 151 : browser_(browser), | 151 : browser_(browser), |
| 152 extended_enabled_(extended_enabled), | 152 extended_enabled_(extended_enabled), |
| 153 instant_enabled_(false), | 153 instant_enabled_(false), |
| 154 model_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 154 model_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
| 155 last_omnibox_text_has_inline_autocompletion_(false), | 155 last_omnibox_text_has_inline_autocompletion_(false), |
| 156 last_verbatim_(false), | 156 last_verbatim_(false), |
| 157 last_transition_type_(content::PAGE_TRANSITION_LINK), | 157 last_transition_type_(content::PAGE_TRANSITION_LINK), |
| 158 last_match_was_search_(false), | 158 last_match_was_search_(false), |
| 159 omnibox_focus_state_(OMNIBOX_FOCUS_NONE), | 159 omnibox_focus_state_(OMNIBOX_FOCUS_NONE), |
| 160 start_margin_(0), |
| 161 end_margin_(0), |
| 160 allow_preview_to_show_search_suggestions_(false) { | 162 allow_preview_to_show_search_suggestions_(false) { |
| 161 } | 163 } |
| 162 | 164 |
| 163 InstantController::~InstantController() { | 165 InstantController::~InstantController() { |
| 164 } | 166 } |
| 165 | 167 |
| 166 bool InstantController::Update(const AutocompleteMatch& match, | 168 bool InstantController::Update(const AutocompleteMatch& match, |
| 167 const string16& user_text, | 169 const string16& user_text, |
| 168 const string16& full_text, | 170 const string16& full_text, |
| 169 size_t selection_start, | 171 size_t selection_start, |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 347 browser_->SetInstantSuggestion(last_suggestion_); | 349 browser_->SetInstantSuggestion(last_suggestion_); |
| 348 | 350 |
| 349 // Though we may have handled a URL match above, we return false here, so that | 351 // Though we may have handled a URL match above, we return false here, so that |
| 350 // omnibox prerendering can kick in. TODO(sreeram): Remove this (and always | 352 // omnibox prerendering can kick in. TODO(sreeram): Remove this (and always |
| 351 // return true) once we are able to commit URLs as well. | 353 // return true) once we are able to commit URLs as well. |
| 352 return last_match_was_search_; | 354 return last_match_was_search_; |
| 353 } | 355 } |
| 354 | 356 |
| 355 // TODO(tonyg): This method only fires when the omnibox bounds change. It also | 357 // TODO(tonyg): This method only fires when the omnibox bounds change. It also |
| 356 // needs to fire when the preview bounds change (e.g.: open/close info bar). | 358 // needs to fire when the preview bounds change (e.g.: open/close info bar). |
| 357 void InstantController::SetOmniboxBounds(const gfx::Rect& bounds) { | 359 void InstantController::SetPopupBounds(const gfx::Rect& bounds) { |
| 358 if (!extended_enabled_ && !instant_enabled_) | 360 if (!extended_enabled_ && !instant_enabled_) |
| 359 return; | 361 return; |
| 360 | 362 |
| 361 if (omnibox_bounds_ == bounds) | 363 if (popup_bounds_ == bounds) |
| 362 return; | 364 return; |
| 363 | 365 |
| 364 omnibox_bounds_ = bounds; | 366 popup_bounds_ = bounds; |
| 365 if (omnibox_bounds_.height() > last_omnibox_bounds_.height()) { | 367 if (popup_bounds_.height() > last_popup_bounds_.height()) { |
| 366 update_bounds_timer_.Stop(); | 368 update_bounds_timer_.Stop(); |
| 367 SendBoundsToPage(); | 369 SendPopupBoundsToPage(); |
| 368 } else if (!update_bounds_timer_.IsRunning()) { | 370 } else if (!update_bounds_timer_.IsRunning()) { |
| 369 update_bounds_timer_.Start(FROM_HERE, | 371 update_bounds_timer_.Start(FROM_HERE, |
| 370 base::TimeDelta::FromMilliseconds(kUpdateBoundsDelayMS), this, | 372 base::TimeDelta::FromMilliseconds(kUpdateBoundsDelayMS), this, |
| 371 &InstantController::SendBoundsToPage); | 373 &InstantController::SendPopupBoundsToPage); |
| 372 } | 374 } |
| 373 } | 375 } |
| 374 | 376 |
| 377 void InstantController::SetMarginSize(int start, int end) { |
| 378 if (!extended_enabled_ || (start_margin_ == start && end_margin_ == end)) |
| 379 return; |
| 380 |
| 381 start_margin_ = start; |
| 382 end_margin_ = end; |
| 383 if (loader_) |
| 384 loader_->SetMarginSize(start_margin_, end_margin_); |
| 385 if (instant_tab_) |
| 386 instant_tab_->SetMarginSize(start_margin_, end_margin_); |
| 387 } |
| 388 |
| 375 void InstantController::HandleAutocompleteResults( | 389 void InstantController::HandleAutocompleteResults( |
| 376 const std::vector<AutocompleteProvider*>& providers) { | 390 const std::vector<AutocompleteProvider*>& providers) { |
| 377 if (!extended_enabled_) | 391 if (!extended_enabled_) |
| 378 return; | 392 return; |
| 379 | 393 |
| 380 if (!instant_tab_ && !loader_) | 394 if (!instant_tab_ && !loader_) |
| 381 return; | 395 return; |
| 382 | 396 |
| 383 DVLOG(1) << "AutocompleteResults:"; | 397 DVLOG(1) << "AutocompleteResults:"; |
| 384 std::vector<InstantAutocompleteResult> results; | 398 std::vector<InstantAutocompleteResult> results; |
| (...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 852 HideInternal(); | 866 HideInternal(); |
| 853 loader_.reset(new InstantLoader(this, instant_url)); | 867 loader_.reset(new InstantLoader(this, instant_url)); |
| 854 loader_->InitContents(active_tab); | 868 loader_->InitContents(active_tab); |
| 855 | 869 |
| 856 // Ensure the searchbox API has the correct initial state. | 870 // Ensure the searchbox API has the correct initial state. |
| 857 if (extended_enabled_) { | 871 if (extended_enabled_) { |
| 858 browser_->UpdateThemeInfoForPreview(); | 872 browser_->UpdateThemeInfoForPreview(); |
| 859 loader_->SetDisplayInstantResults(instant_enabled_); | 873 loader_->SetDisplayInstantResults(instant_enabled_); |
| 860 loader_->SearchModeChanged(search_mode_); | 874 loader_->SearchModeChanged(search_mode_); |
| 861 loader_->KeyCaptureChanged(omnibox_focus_state_ == OMNIBOX_FOCUS_INVISIBLE); | 875 loader_->KeyCaptureChanged(omnibox_focus_state_ == OMNIBOX_FOCUS_INVISIBLE); |
| 876 loader_->SetMarginSize(start_margin_, end_margin_); |
| 862 } | 877 } |
| 863 | 878 |
| 864 // Restart the stale loader timer. | 879 // Restart the stale loader timer. |
| 865 stale_loader_timer_.Start(FROM_HERE, | 880 stale_loader_timer_.Start(FROM_HERE, |
| 866 base::TimeDelta::FromMilliseconds(kStaleLoaderTimeoutMS), this, | 881 base::TimeDelta::FromMilliseconds(kStaleLoaderTimeoutMS), this, |
| 867 &InstantController::OnStaleLoader); | 882 &InstantController::OnStaleLoader); |
| 868 | 883 |
| 869 return true; | 884 return true; |
| 870 } | 885 } |
| 871 | 886 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 894 } | 909 } |
| 895 } | 910 } |
| 896 | 911 |
| 897 void InstantController::ResetInstantTab() { | 912 void InstantController::ResetInstantTab() { |
| 898 if (search_mode_.is_origin_search()) { | 913 if (search_mode_.is_origin_search()) { |
| 899 content::WebContents* active_tab = browser_->GetActiveWebContents(); | 914 content::WebContents* active_tab = browser_->GetActiveWebContents(); |
| 900 if (!instant_tab_ || active_tab != instant_tab_->contents()) { | 915 if (!instant_tab_ || active_tab != instant_tab_->contents()) { |
| 901 instant_tab_.reset(new InstantTab(this, active_tab)); | 916 instant_tab_.reset(new InstantTab(this, active_tab)); |
| 902 instant_tab_->Init(); | 917 instant_tab_->Init(); |
| 903 instant_tab_->SetDisplayInstantResults(instant_enabled_); | 918 instant_tab_->SetDisplayInstantResults(instant_enabled_); |
| 919 instant_tab_->SetMarginSize(start_margin_, end_margin_); |
| 904 } | 920 } |
| 905 | 921 |
| 906 // Hide the |loader_| since we are now using |instant_tab_| instead. | 922 // Hide the |loader_| since we are now using |instant_tab_| instead. |
| 907 HideLoader(); | 923 HideLoader(); |
| 908 } else { | 924 } else { |
| 909 instant_tab_.reset(); | 925 instant_tab_.reset(); |
| 910 } | 926 } |
| 911 } | 927 } |
| 912 | 928 |
| 913 bool InstantController::ResetLoaderForMatch(const AutocompleteMatch& match) { | 929 bool InstantController::ResetLoaderForMatch(const AutocompleteMatch& match) { |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1010 model_.SetPreviewState(search_mode_, 100, INSTANT_SIZE_PERCENT); | 1026 model_.SetPreviewState(search_mode_, 100, INSTANT_SIZE_PERCENT); |
| 1011 | 1027 |
| 1012 // If the user clicked on a query suggestion, also go ahead and commit the | 1028 // If the user clicked on a query suggestion, also go ahead and commit the |
| 1013 // overlay. This is necessary because if the overlay was partially visible | 1029 // overlay. This is necessary because if the overlay was partially visible |
| 1014 // when the suggestion was clicked, the click itself would not commit the | 1030 // when the suggestion was clicked, the click itself would not commit the |
| 1015 // overlay (because we're not full height). | 1031 // overlay (because we're not full height). |
| 1016 if (reason == INSTANT_SHOWN_CLICKED_QUERY_SUGGESTION) | 1032 if (reason == INSTANT_SHOWN_CLICKED_QUERY_SUGGESTION) |
| 1017 CommitIfPossible(INSTANT_COMMIT_CLICKED_QUERY_SUGGESTION); | 1033 CommitIfPossible(INSTANT_COMMIT_CLICKED_QUERY_SUGGESTION); |
| 1018 } | 1034 } |
| 1019 | 1035 |
| 1020 void InstantController::SendBoundsToPage() { | 1036 void InstantController::SendPopupBoundsToPage() { |
| 1021 if (last_omnibox_bounds_ == omnibox_bounds_ || !loader_ || | 1037 if (last_popup_bounds_ == popup_bounds_ || !loader_ || |
| 1022 loader_->is_pointer_down_from_activate()) | 1038 loader_->is_pointer_down_from_activate()) |
| 1023 return; | 1039 return; |
| 1024 | 1040 |
| 1025 last_omnibox_bounds_ = omnibox_bounds_; | 1041 last_popup_bounds_ = popup_bounds_; |
| 1026 gfx::Rect preview_bounds = browser_->GetInstantBounds(); | 1042 gfx::Rect preview_bounds = browser_->GetInstantBounds(); |
| 1027 gfx::Rect intersection = gfx::IntersectRects(omnibox_bounds_, preview_bounds); | 1043 gfx::Rect intersection = gfx::IntersectRects(popup_bounds_, preview_bounds); |
| 1028 | 1044 |
| 1029 // Translate into window coordinates. | 1045 // Translate into window coordinates. |
| 1030 if (!intersection.IsEmpty()) { | 1046 if (!intersection.IsEmpty()) { |
| 1031 intersection.Offset(-preview_bounds.origin().x(), | 1047 intersection.Offset(-preview_bounds.origin().x(), |
| 1032 -preview_bounds.origin().y()); | 1048 -preview_bounds.origin().y()); |
| 1033 } | 1049 } |
| 1034 | 1050 |
| 1035 // In the current Chrome UI, these must always be true so they sanity check | 1051 // In the current Chrome UI, these must always be true so they sanity check |
| 1036 // the above operations. In a future UI, these may be removed or adjusted. | 1052 // the above operations. In a future UI, these may be removed or adjusted. |
| 1037 // There is no point in sanity-checking |intersection.y()| because the omnibox | 1053 // There is no point in sanity-checking |intersection.y()| because the omnibox |
| 1038 // can be placed anywhere vertically relative to the preview (for example, in | 1054 // can be placed anywhere vertically relative to the preview (for example, in |
| 1039 // Mac fullscreen mode, the omnibox is fully enclosed by the preview bounds). | 1055 // Mac fullscreen mode, the omnibox is fully enclosed by the preview bounds). |
| 1040 DCHECK_LE(0, intersection.x()); | 1056 DCHECK_LE(0, intersection.x()); |
| 1041 DCHECK_LE(0, intersection.width()); | 1057 DCHECK_LE(0, intersection.width()); |
| 1042 DCHECK_LE(0, intersection.height()); | 1058 DCHECK_LE(0, intersection.height()); |
| 1043 | 1059 |
| 1044 loader_->SetOmniboxBounds(intersection); | 1060 loader_->SetPopupBounds(intersection); |
| 1045 } | 1061 } |
| 1046 | 1062 |
| 1047 bool InstantController::GetInstantURL(const TemplateURL* template_url, | 1063 bool InstantController::GetInstantURL(const TemplateURL* template_url, |
| 1048 std::string* instant_url) const { | 1064 std::string* instant_url) const { |
| 1049 CommandLine* command_line = CommandLine::ForCurrentProcess(); | 1065 CommandLine* command_line = CommandLine::ForCurrentProcess(); |
| 1050 if (command_line->HasSwitch(switches::kInstantURL)) { | 1066 if (command_line->HasSwitch(switches::kInstantURL)) { |
| 1051 *instant_url = command_line->GetSwitchValueASCII(switches::kInstantURL); | 1067 *instant_url = command_line->GetSwitchValueASCII(switches::kInstantURL); |
| 1052 return template_url != NULL; | 1068 return template_url != NULL; |
| 1053 } | 1069 } |
| 1054 | 1070 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1088 } | 1104 } |
| 1089 | 1105 |
| 1090 std::map<std::string, int>::const_iterator iter = | 1106 std::map<std::string, int>::const_iterator iter = |
| 1091 blacklisted_urls_.find(*instant_url); | 1107 blacklisted_urls_.find(*instant_url); |
| 1092 if (iter != blacklisted_urls_.end() && | 1108 if (iter != blacklisted_urls_.end() && |
| 1093 iter->second > kMaxInstantSupportFailures) | 1109 iter->second > kMaxInstantSupportFailures) |
| 1094 return false; | 1110 return false; |
| 1095 | 1111 |
| 1096 return true; | 1112 return true; |
| 1097 } | 1113 } |
| OLD | NEW |