Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / ui / search / instant_search_prerenderer.cc
blob4199a2b6ebb7375426f13901beab93e4c0324639
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/search/instant_search_prerenderer.h"
7 #include "chrome/browser/autocomplete/autocomplete_match.h"
8 #include "chrome/browser/prerender/prerender_handle.h"
9 #include "chrome/browser/prerender/prerender_manager.h"
10 #include "chrome/browser/prerender/prerender_manager_factory.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/browser/search/instant_service.h"
13 #include "chrome/browser/search/instant_service_factory.h"
14 #include "chrome/browser/search/search.h"
15 #include "chrome/browser/ui/browser_navigator.h"
16 #include "chrome/browser/ui/search/search_tab_helper.h"
18 namespace {
20 // Returns true if the underlying page supports Instant search.
21 bool PageSupportsInstantSearch(content::WebContents* contents) {
22 // Search results page supports Instant search.
23 return SearchTabHelper::FromWebContents(contents)->IsSearchResultsPage();
26 } // namespace
28 InstantSearchPrerenderer::InstantSearchPrerenderer(Profile* profile,
29 const GURL& url)
30 : profile_(profile),
31 prerender_url_(url) {
34 InstantSearchPrerenderer::~InstantSearchPrerenderer() {
35 if (prerender_handle_)
36 prerender_handle_->OnCancel();
39 // static
40 InstantSearchPrerenderer* InstantSearchPrerenderer::GetForProfile(
41 Profile* profile) {
42 DCHECK(profile);
43 InstantService* instant_service =
44 InstantServiceFactory::GetForProfile(profile);
45 return instant_service ? instant_service->instant_search_prerenderer() : NULL;
48 void InstantSearchPrerenderer::Init(
49 const content::SessionStorageNamespaceMap& session_storage_namespace_map,
50 const gfx::Size& size) {
51 // TODO(kmadhusu): Enable Instant for Incognito profile.
52 if (profile_->IsOffTheRecord())
53 return;
55 // Only cancel the old prerender after starting the new one, so if the URLs
56 // are the same, the underlying prerender will be reused.
57 scoped_ptr<prerender::PrerenderHandle> old_prerender_handle(
58 prerender_handle_.release());
59 prerender::PrerenderManager* prerender_manager =
60 prerender::PrerenderManagerFactory::GetForProfile(profile_);
61 if (prerender_manager) {
62 content::SessionStorageNamespace* session_storage_namespace = NULL;
63 content::SessionStorageNamespaceMap::const_iterator it =
64 session_storage_namespace_map.find(std::string());
65 if (it != session_storage_namespace_map.end())
66 session_storage_namespace = it->second.get();
68 prerender_handle_.reset(prerender_manager->AddPrerenderForInstant(
69 prerender_url_, session_storage_namespace, size));
71 if (old_prerender_handle)
72 old_prerender_handle->OnCancel();
75 void InstantSearchPrerenderer::Cancel() {
76 if (!prerender_handle_)
77 return;
79 last_instant_suggestion_ = InstantSuggestion();
80 prerender_handle_->OnCancel();
81 prerender_handle_.reset();
84 void InstantSearchPrerenderer::Prerender(const InstantSuggestion& suggestion) {
85 if (!prerender_handle_)
86 return;
88 if (last_instant_suggestion_.text == suggestion.text)
89 return;
91 if (last_instant_suggestion_.text.empty() &&
92 !prerender_handle_->IsFinishedLoading())
93 return;
95 if (!prerender_contents())
96 return;
98 last_instant_suggestion_ = suggestion;
99 SearchTabHelper::FromWebContents(prerender_contents())->
100 SetSuggestionToPrefetch(suggestion);
103 void InstantSearchPrerenderer::Commit(const base::string16& query) {
104 DCHECK(prerender_handle_);
105 DCHECK(prerender_contents());
106 SearchTabHelper::FromWebContents(prerender_contents())->Submit(query);
109 bool InstantSearchPrerenderer::CanCommitQuery(
110 content::WebContents* source,
111 const base::string16& query) const {
112 if (!source || query.empty())
113 return false;
115 if (last_instant_suggestion_.text != query)
116 return false;
118 if (!prerender_handle_ || !prerender_contents())
119 return false;
121 // InstantSearchPrerenderer can commit query to the prerendered page only if
122 // the underlying |source| page doesn't support Instant search.
123 return !PageSupportsInstantSearch(source);
126 bool InstantSearchPrerenderer::UsePrerenderedPage(
127 const GURL& url,
128 chrome::NavigateParams* params) {
129 base::string16 search_terms = chrome::GetSearchTermsFromURL(profile_, url);
130 prerender::PrerenderManager* prerender_manager =
131 prerender::PrerenderManagerFactory::GetForProfile(profile_);
132 if (search_terms.empty() ||
133 !params->target_contents ||
134 last_instant_suggestion_.text != search_terms ||
135 !prerender_contents() ||
136 !prerender_manager) {
137 Cancel();
138 return false;
141 bool success = prerender_manager->MaybeUsePrerenderedPage(
142 prerender_contents()->GetURL(), params);
143 prerender_handle_.reset();
144 return success;
147 bool InstantSearchPrerenderer::IsAllowed(const AutocompleteMatch& match,
148 content::WebContents* source) const {
149 return source && AutocompleteMatch::IsSearchType(match.type) &&
150 !PageSupportsInstantSearch(source);
153 content::WebContents* InstantSearchPrerenderer::prerender_contents() const {
154 return (prerender_handle_ && prerender_handle_->contents()) ?
155 prerender_handle_->contents()->prerender_contents() : NULL;