OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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/i18n/case_conversion.h" | 8 #include "base/i18n/case_conversion.h" |
9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
(...skipping 24 matching lines...) Expand all Loading... | |
35 #include "net/base/escape.h" | 35 #include "net/base/escape.h" |
36 #include "unicode/normalizer2.h" | 36 #include "unicode/normalizer2.h" |
37 #include "unicode/unistr.h" | 37 #include "unicode/unistr.h" |
38 | 38 |
39 #if defined(TOOLKIT_VIEWS) | 39 #if defined(TOOLKIT_VIEWS) |
40 #include "ui/views/widget/widget.h" | 40 #include "ui/views/widget/widget.h" |
41 #endif | 41 #endif |
42 | 42 |
43 namespace { | 43 namespace { |
44 | 44 |
45 // An artificial delay (in milliseconds) we introduce before telling the Instant | 45 // An artificial delay (in milliseconds) we introduce before telling the Instant |
samarth
2012/11/16 22:08:26
I suspect this was necessary because the height of
melevin
2012/11/16 22:34:43
We'll have to test once the JavaScript is wired.
| |
46 // page about the new omnibox bounds, in cases where the bounds shrink. This is | 46 // page about the new omnibox bounds, in cases where the bounds shrink. This is |
47 // to avoid the page jumping up/down very fast in response to bounds changes. | 47 // to avoid the page jumping up/down very fast in response to bounds changes. |
48 const int kUpdateBoundsDelayMS = 1000; | 48 const int kUpdateBoundsDelayMS = 1000; |
49 | 49 |
50 // The maximum number of times we'll load a non-Instant-supporting search engine | 50 // The maximum number of times we'll load a non-Instant-supporting search engine |
51 // before we give up and blacklist it for the rest of the browsing session. | 51 // before we give up and blacklist it for the rest of the browsing session. |
52 const int kMaxInstantSupportFailures = 10; | 52 const int kMaxInstantSupportFailures = 10; |
53 | 53 |
54 // If an Instant page has not been used in these many milliseconds, it is | 54 // If an Instant page has not been used in these many milliseconds, it is |
55 // reloaded so that the page does not become stale. | 55 // reloaded so that the page does not become stale. |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
252 browser_->SetInstantSuggestion(last_suggestion_); | 252 browser_->SetInstantSuggestion(last_suggestion_); |
253 | 253 |
254 // Though we may have handled a URL match above, we return false here, so that | 254 // Though we may have handled a URL match above, we return false here, so that |
255 // omnibox prerendering can kick in. TODO(sreeram): Remove this (and always | 255 // omnibox prerendering can kick in. TODO(sreeram): Remove this (and always |
256 // return true) once we are able to commit URLs as well. | 256 // return true) once we are able to commit URLs as well. |
257 return last_match_was_search_; | 257 return last_match_was_search_; |
258 } | 258 } |
259 | 259 |
260 // TODO(tonyg): This method only fires when the omnibox bounds change. It also | 260 // TODO(tonyg): This method only fires when the omnibox bounds change. It also |
261 // needs to fire when the preview bounds change (e.g.: open/close info bar). | 261 // needs to fire when the preview bounds change (e.g.: open/close info bar). |
262 void InstantController::SetOmniboxBounds(const gfx::Rect& bounds) { | 262 void InstantController::SetPopupBounds(const gfx::Rect& bounds) { |
263 if (omnibox_bounds_ == bounds) | 263 if (popup_bounds_ == bounds) |
264 return; | 264 return; |
265 | 265 |
266 omnibox_bounds_ = bounds; | 266 popup_bounds_ = bounds; |
267 if (omnibox_bounds_.height() > last_omnibox_bounds_.height()) { | 267 if (popup_bounds_.height() > last_popup_bounds_.height()) { |
268 update_bounds_timer_.Stop(); | 268 update_bounds_timer_.Stop(); |
269 SendBoundsToPage(); | 269 SendBoundsToPage(); |
270 } else if (!update_bounds_timer_.IsRunning()) { | 270 } else if (!update_bounds_timer_.IsRunning()) { |
271 update_bounds_timer_.Start(FROM_HERE, | 271 update_bounds_timer_.Start(FROM_HERE, |
272 base::TimeDelta::FromMilliseconds(kUpdateBoundsDelayMS), this, | 272 base::TimeDelta::FromMilliseconds(kUpdateBoundsDelayMS), this, |
273 &InstantController::SendBoundsToPage); | 273 &InstantController::SendBoundsToPage); |
274 } | 274 } |
275 } | 275 } |
276 | 276 |
277 void InstantController::SetMarginSize(int start, int end) { | |
278 if ((start_margin_ == start && end_margin_ == end) || | |
279 model_.preview_state() == InstantModel::NOT_READY || | |
280 !GetPreviewContents() || loader_->IsPointerDownFromActivate()) | |
281 return; | |
282 | |
283 start_margin_ = start; | |
284 end_margin_ = end; | |
285 loader_->SetMarginSize(start_margin_, end_margin_); | |
286 } | |
287 | |
277 void InstantController::HandleAutocompleteResults( | 288 void InstantController::HandleAutocompleteResults( |
278 const std::vector<AutocompleteProvider*>& providers) { | 289 const std::vector<AutocompleteProvider*>& providers) { |
279 if (mode_ != EXTENDED || !GetPreviewContents()) | 290 if (mode_ != EXTENDED || !GetPreviewContents()) |
280 return; | 291 return; |
281 | 292 |
282 std::vector<InstantAutocompleteResult> results; | 293 std::vector<InstantAutocompleteResult> results; |
283 for (ACProviders::const_iterator provider = providers.begin(); | 294 for (ACProviders::const_iterator provider = providers.begin(); |
284 provider != providers.end(); ++provider) { | 295 provider != providers.end(); ++provider) { |
285 for (ACMatches::const_iterator match = (*provider)->matches().begin(); | 296 for (ACMatches::const_iterator match = (*provider)->matches().begin(); |
286 match != (*provider)->matches().end(); ++match) { | 297 match != (*provider)->matches().end(); ++match) { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
322 // correctly after the commit is done. | 333 // correctly after the commit is done. |
323 if (GetPreviewContents()) | 334 if (GetPreviewContents()) |
324 model_.SetPreviewState(InstantModel::NOT_READY, 0, INSTANT_SIZE_PERCENT); | 335 model_.SetPreviewState(InstantModel::NOT_READY, 0, INSTANT_SIZE_PERCENT); |
325 | 336 |
326 if (GetPreviewContents() && !last_full_text_.empty()) { | 337 if (GetPreviewContents() && !last_full_text_.empty()) { |
327 // Send a blank query to ask the preview to clear out old results. | 338 // Send a blank query to ask the preview to clear out old results. |
328 last_full_text_.clear(); | 339 last_full_text_.clear(); |
329 last_user_text_.clear(); | 340 last_user_text_.clear(); |
330 loader_->Update(last_full_text_, true); | 341 loader_->Update(last_full_text_, true); |
331 } | 342 } |
343 | |
344 // Clear the margins so they are set when the preview is shown again. | |
samarth
2012/11/16 22:08:26
Why is this necessary?
melevin
2012/11/16 22:34:43
When the SearchBox object is created it does not h
samarth
2012/11/19 21:42:44
Take a look at ResetLoader. Whenever we load a new
melevin
2012/11/20 22:32:20
I only see the instant URL being communicated to t
samarth
2012/11/20 22:47:37
I meant something like https://cs.corp.google.com/
| |
345 start_margin_ = 0; | |
346 end_margin_ = 0; | |
332 } | 347 } |
333 | 348 |
334 bool InstantController::IsCurrent() const { | 349 bool InstantController::IsCurrent() const { |
335 return model_.preview_state() == InstantModel::QUERY_RESULTS && | 350 return model_.preview_state() == InstantModel::QUERY_RESULTS && |
336 GetPreviewContents() && | 351 GetPreviewContents() && |
337 loader_->supports_instant() && last_match_was_search_; | 352 loader_->supports_instant() && last_match_was_search_; |
338 } | 353 } |
339 | 354 |
340 void InstantController::CommitCurrentPreview(InstantCommitType type) { | 355 void InstantController::CommitCurrentPreview(InstantCommitType type) { |
341 TabContents* preview = loader_->ReleasePreviewContents(type, last_full_text_); | 356 TabContents* preview = loader_->ReleasePreviewContents(type, last_full_text_); |
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
709 if (!stale_loader_timer_.IsRunning()) | 724 if (!stale_loader_timer_.IsRunning()) |
710 OnStaleLoader(); | 725 OnStaleLoader(); |
711 } | 726 } |
712 | 727 |
713 void InstantController::DeleteLoader() { | 728 void InstantController::DeleteLoader() { |
714 last_full_text_.clear(); | 729 last_full_text_.clear(); |
715 last_user_text_.clear(); | 730 last_user_text_.clear(); |
716 last_verbatim_ = false; | 731 last_verbatim_ = false; |
717 last_suggestion_ = InstantSuggestion(); | 732 last_suggestion_ = InstantSuggestion(); |
718 last_match_was_search_ = false; | 733 last_match_was_search_ = false; |
719 last_omnibox_bounds_ = gfx::Rect(); | 734 last_popup_bounds_ = gfx::Rect(); |
720 url_for_history_ = GURL(); | 735 url_for_history_ = GURL(); |
721 if (GetPreviewContents()) | 736 if (GetPreviewContents()) |
722 model_.SetPreviewState(InstantModel::NOT_READY, 0, INSTANT_SIZE_PERCENT); | 737 model_.SetPreviewState(InstantModel::NOT_READY, 0, INSTANT_SIZE_PERCENT); |
723 | 738 |
724 // Schedule the deletion for later, since we may have gotten here from a call | 739 // Schedule the deletion for later, since we may have gotten here from a call |
725 // within a |loader_| method (i.e., it's still on the stack). If we deleted | 740 // within a |loader_| method (i.e., it's still on the stack). If we deleted |
726 // the loader immediately, things would still be fine so long as the caller | 741 // the loader immediately, things would still be fine so long as the caller |
727 // doesn't access any instance members after we return, but why rely on that? | 742 // doesn't access any instance members after we return, but why rely on that? |
728 MessageLoop::current()->DeleteSoon(FROM_HERE, loader_.release()); | 743 MessageLoop::current()->DeleteSoon(FROM_HERE, loader_.release()); |
729 } | 744 } |
730 | 745 |
731 void InstantController::Show(InstantShownReason reason, | 746 void InstantController::Show(InstantShownReason reason, |
732 int height, | 747 int height, |
733 InstantSizeUnits units) { | 748 InstantSizeUnits units) { |
734 // Must be on NTP to show NTP content. | 749 // Must be on NTP to show NTP content. |
735 if (reason == INSTANT_SHOWN_CUSTOM_NTP_CONTENT && !active_tab_is_ntp_) | 750 if (reason == INSTANT_SHOWN_CUSTOM_NTP_CONTENT && !active_tab_is_ntp_) |
736 return; | 751 return; |
737 | 752 |
738 // Must have updated omnibox after most recent Hide() to show suggestions. | 753 // Must have updated omnibox after most recent Hide() to show suggestions. |
739 if (reason == INSTANT_SHOWN_QUERY_SUGGESTIONS && | 754 if (reason == INSTANT_SHOWN_QUERY_SUGGESTIONS && |
740 model_.preview_state() == InstantModel::NOT_READY) | 755 model_.preview_state() == InstantModel::NOT_READY) |
741 return; | 756 return; |
742 | 757 |
743 model_.SetPreviewState(GetNewPreviewState(reason), height, units); | 758 model_.SetPreviewState(GetNewPreviewState(reason), height, units); |
744 } | 759 } |
745 | 760 |
746 void InstantController::SendBoundsToPage() { | 761 void InstantController::SendBoundsToPage() { |
747 if (last_omnibox_bounds_ == omnibox_bounds_ || | 762 if (last_popup_bounds_ == popup_bounds_ || |
748 model_.preview_state() == InstantModel::NOT_READY || | 763 model_.preview_state() == InstantModel::NOT_READY || |
749 !GetPreviewContents() || loader_->IsPointerDownFromActivate()) | 764 !GetPreviewContents() || loader_->IsPointerDownFromActivate()) |
750 return; | 765 return; |
751 | 766 |
752 last_omnibox_bounds_ = omnibox_bounds_; | 767 last_popup_bounds_ = popup_bounds_; |
753 gfx::Rect preview_bounds = browser_->GetInstantBounds(); | 768 gfx::Rect preview_bounds = browser_->GetInstantBounds(); |
754 gfx::Rect intersection = gfx::IntersectRects(omnibox_bounds_, preview_bounds); | 769 gfx::Rect intersection = gfx::IntersectRects(popup_bounds_, preview_bounds); |
755 | 770 |
756 // Translate into window coordinates. | 771 // Translate into window coordinates. |
757 if (!intersection.IsEmpty()) { | 772 if (!intersection.IsEmpty()) { |
758 intersection.Offset(-preview_bounds.origin().x(), | 773 intersection.Offset(-preview_bounds.origin().x(), |
759 -preview_bounds.origin().y()); | 774 -preview_bounds.origin().y()); |
760 } | 775 } |
761 | 776 |
762 // In the current Chrome UI, these must always be true so they sanity check | 777 // In the current Chrome UI, these must always be true so they sanity check |
763 // the above operations. In a future UI, these may be removed or adjusted. | 778 // the above operations. In a future UI, these may be removed or adjusted. |
764 // There is no point in sanity-checking |intersection.y()| because the omnibox | 779 // There is no point in sanity-checking |intersection.y()| because the omnibox |
765 // can be placed anywhere vertically relative to the preview (for example, in | 780 // can be placed anywhere vertically relative to the preview (for example, in |
766 // Mac fullscreen mode, the omnibox is fully enclosed by the preview bounds). | 781 // Mac fullscreen mode, the omnibox is fully enclosed by the preview bounds). |
767 DCHECK_LE(0, intersection.x()); | 782 DCHECK_LE(0, intersection.x()); |
768 DCHECK_LE(0, intersection.width()); | 783 DCHECK_LE(0, intersection.width()); |
769 DCHECK_LE(0, intersection.height()); | 784 DCHECK_LE(0, intersection.height()); |
770 | 785 |
771 loader_->SetOmniboxBounds(intersection); | 786 loader_->SetPopupBounds(intersection); |
772 } | 787 } |
773 | 788 |
774 bool InstantController::GetInstantURL(const TemplateURL* template_url, | 789 bool InstantController::GetInstantURL(const TemplateURL* template_url, |
775 const GURL& tab_url, | 790 const GURL& tab_url, |
776 std::string* instant_url) const { | 791 std::string* instant_url) const { |
777 CommandLine* command_line = CommandLine::ForCurrentProcess(); | 792 CommandLine* command_line = CommandLine::ForCurrentProcess(); |
778 if (command_line->HasSwitch(switches::kInstantURL)) { | 793 if (command_line->HasSwitch(switches::kInstantURL)) { |
779 *instant_url = command_line->GetSwitchValueASCII(switches::kInstantURL); | 794 *instant_url = command_line->GetSwitchValueASCII(switches::kInstantURL); |
780 return template_url != NULL; | 795 return template_url != NULL; |
781 } | 796 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
816 } | 831 } |
817 | 832 |
818 std::map<std::string, int>::const_iterator iter = | 833 std::map<std::string, int>::const_iterator iter = |
819 blacklisted_urls_.find(*instant_url); | 834 blacklisted_urls_.find(*instant_url); |
820 if (iter != blacklisted_urls_.end() && | 835 if (iter != blacklisted_urls_.end() && |
821 iter->second > kMaxInstantSupportFailures) | 836 iter->second > kMaxInstantSupportFailures) |
822 return false; | 837 return false; |
823 | 838 |
824 return true; | 839 return true; |
825 } | 840 } |
OLD | NEW |