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/omnibox_search_hint.h" | 5 #include "chrome/browser/omnibox_search_hint.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/memory/weak_ptr.h" | 9 #include "base/memory/weak_ptr.h" |
10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
(...skipping 25 matching lines...) Expand all Loading... |
36 #include "grit/generated_resources.h" | 36 #include "grit/generated_resources.h" |
37 #include "grit/theme_resources.h" | 37 #include "grit/theme_resources.h" |
38 #include "ui/base/l10n/l10n_util.h" | 38 #include "ui/base/l10n/l10n_util.h" |
39 #include "ui/base/resource/resource_bundle.h" | 39 #include "ui/base/resource/resource_bundle.h" |
40 | 40 |
41 using content::NavigationController; | 41 using content::NavigationController; |
42 using content::NavigationEntry; | 42 using content::NavigationEntry; |
43 | 43 |
44 DEFINE_WEB_CONTENTS_USER_DATA_KEY(OmniboxSearchHint); | 44 DEFINE_WEB_CONTENTS_USER_DATA_KEY(OmniboxSearchHint); |
45 | 45 |
46 // The URLs of search engines for which we want to trigger the infobar. | |
47 const char* const kSearchEngineURLs[] = { | |
48 "http://www.google.com/", | |
49 "http://www.yahoo.com/", | |
50 "http://www.bing.com/", | |
51 "http://www.altavista.com/", | |
52 "http://www.ask.com/", | |
53 "http://www.wolframalpha.com/", | |
54 }; | |
55 | |
56 | 46 |
57 // HintInfoBar ---------------------------------------------------------------- | 47 // HintInfoBar ---------------------------------------------------------------- |
58 | 48 |
59 class HintInfoBar : public ConfirmInfoBarDelegate { | 49 class HintInfoBar : public ConfirmInfoBarDelegate { |
60 public: | 50 public: |
| 51 // If the active entry for |web_contents| is a navigation to the user's |
| 52 // default search engine, and the engine is on a small whitelist, creates a |
| 53 // "you can search from the omnibox" hint delegate and adds it to the |
| 54 // InfoBarService for |web_contents|. |
| 55 static void Create(content::WebContents* web_contents, |
| 56 OmniboxSearchHint* omnibox_hint); |
| 57 |
| 58 private: |
61 HintInfoBar(OmniboxSearchHint* omnibox_hint, | 59 HintInfoBar(OmniboxSearchHint* omnibox_hint, |
62 InfoBarService* infobar_service); | 60 InfoBarService* infobar_service); |
63 | |
64 private: | |
65 virtual ~HintInfoBar(); | 61 virtual ~HintInfoBar(); |
66 | 62 |
67 void AllowExpiry() { should_expire_ = true; } | 63 void AllowExpiry() { should_expire_ = true; } |
68 | 64 |
69 // ConfirmInfoBarDelegate: | 65 // ConfirmInfoBarDelegate: |
70 virtual void InfoBarDismissed() OVERRIDE; | 66 virtual void InfoBarDismissed() OVERRIDE; |
71 virtual gfx::Image* GetIcon() const OVERRIDE; | 67 virtual gfx::Image* GetIcon() const OVERRIDE; |
72 virtual Type GetInfoBarType() const OVERRIDE; | 68 virtual Type GetInfoBarType() const OVERRIDE; |
73 virtual string16 GetMessageText() const OVERRIDE; | 69 virtual string16 GetMessageText() const OVERRIDE; |
74 virtual int GetButtons() const OVERRIDE; | 70 virtual int GetButtons() const OVERRIDE; |
(...skipping 10 matching lines...) Expand all Loading... |
85 | 81 |
86 // Whether the info-bar should be dismissed on the next navigation. | 82 // Whether the info-bar should be dismissed on the next navigation. |
87 bool should_expire_; | 83 bool should_expire_; |
88 | 84 |
89 // Used to delay the expiration of the info-bar. | 85 // Used to delay the expiration of the info-bar. |
90 base::WeakPtrFactory<HintInfoBar> weak_factory_; | 86 base::WeakPtrFactory<HintInfoBar> weak_factory_; |
91 | 87 |
92 DISALLOW_COPY_AND_ASSIGN(HintInfoBar); | 88 DISALLOW_COPY_AND_ASSIGN(HintInfoBar); |
93 }; | 89 }; |
94 | 90 |
| 91 // static |
| 92 void HintInfoBar::Create(content::WebContents* web_contents, |
| 93 OmniboxSearchHint* omnibox_hint) { |
| 94 // The URLs of search engines for which we want to trigger the infobar. |
| 95 const char* const kSearchEngineURLs[] = { |
| 96 "http://www.google.com/", |
| 97 "http://www.yahoo.com/", |
| 98 "http://www.bing.com/", |
| 99 "http://www.altavista.com/", |
| 100 "http://www.ask.com/", |
| 101 "http://www.wolframalpha.com/", |
| 102 }; |
| 103 CR_DEFINE_STATIC_LOCAL(std::set<std::string>, search_engine_urls, ()); |
| 104 if (search_engine_urls.empty()) { |
| 105 for (size_t i = 0; i < arraysize(kSearchEngineURLs); ++i) |
| 106 search_engine_urls.insert(kSearchEngineURLs[i]); |
| 107 } |
| 108 |
| 109 content::NavigationEntry* entry = |
| 110 web_contents->GetController().GetActiveEntry(); |
| 111 if (search_engine_urls.find(entry->GetURL().spec()) == |
| 112 search_engine_urls.end()) { |
| 113 // The search engine is not in our white-list, bail. |
| 114 return; |
| 115 } |
| 116 |
| 117 Profile* profile = |
| 118 Profile::FromBrowserContext(web_contents->GetBrowserContext()); |
| 119 const TemplateURL* const default_provider = |
| 120 TemplateURLServiceFactory::GetForProfile(profile)-> |
| 121 GetDefaultSearchProvider(); |
| 122 if (!default_provider) |
| 123 return; |
| 124 |
| 125 if (default_provider->url_ref().GetHost() == entry->GetURL().host()) { |
| 126 InfoBarService* infobar_service = |
| 127 InfoBarService::FromWebContents(web_contents); |
| 128 infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>( |
| 129 new HintInfoBar(omnibox_hint, infobar_service))); |
| 130 } |
| 131 } |
| 132 |
95 HintInfoBar::HintInfoBar(OmniboxSearchHint* omnibox_hint, | 133 HintInfoBar::HintInfoBar(OmniboxSearchHint* omnibox_hint, |
96 InfoBarService* infobar_service) | 134 InfoBarService* infobar_service) |
97 : ConfirmInfoBarDelegate(infobar_service), | 135 : ConfirmInfoBarDelegate(infobar_service), |
98 omnibox_hint_(omnibox_hint), | 136 omnibox_hint_(omnibox_hint), |
99 action_taken_(false), | 137 action_taken_(false), |
100 should_expire_(false), | 138 should_expire_(false), |
101 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { | 139 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { |
102 // We want the info-bar to stick-around for few seconds and then be hidden | 140 // We want the info-bar to stick-around for few seconds and then be hidden |
103 // on the next navigation after that. | 141 // on the next navigation after that. |
104 MessageLoop::current()->PostDelayedTask( | 142 MessageLoop::current()->PostDelayedTask( |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 | 196 |
159 // OmniboxSearchHint ---------------------------------------------------------- | 197 // OmniboxSearchHint ---------------------------------------------------------- |
160 | 198 |
161 OmniboxSearchHint::OmniboxSearchHint(content::WebContents* web_contents) | 199 OmniboxSearchHint::OmniboxSearchHint(content::WebContents* web_contents) |
162 : web_contents_(web_contents) { | 200 : web_contents_(web_contents) { |
163 NavigationController* controller = &(web_contents->GetController()); | 201 NavigationController* controller = &(web_contents->GetController()); |
164 notification_registrar_.Add( | 202 notification_registrar_.Add( |
165 this, | 203 this, |
166 content::NOTIFICATION_NAV_ENTRY_COMMITTED, | 204 content::NOTIFICATION_NAV_ENTRY_COMMITTED, |
167 content::Source<NavigationController>(controller)); | 205 content::Source<NavigationController>(controller)); |
168 // Fill the search_engine_urls_ map, used for faster look-up (overkill?). | |
169 for (size_t i = 0; i < arraysize(kSearchEngineURLs); ++i) | |
170 search_engine_urls_[kSearchEngineURLs[i]] = 1; | |
171 | 206 |
172 Profile* profile = | 207 Profile* profile = |
173 Profile::FromBrowserContext(web_contents->GetBrowserContext()); | 208 Profile::FromBrowserContext(web_contents->GetBrowserContext()); |
174 // Listen for omnibox to figure-out when the user searches from the omnibox. | 209 // Listen for omnibox to figure-out when the user searches from the omnibox. |
175 notification_registrar_.Add(this, | 210 notification_registrar_.Add(this, |
176 chrome::NOTIFICATION_OMNIBOX_OPENED_URL, | 211 chrome::NOTIFICATION_OMNIBOX_OPENED_URL, |
177 content::Source<Profile>(profile)); | 212 content::Source<Profile>(profile)); |
178 } | 213 } |
179 | 214 |
180 OmniboxSearchHint::~OmniboxSearchHint() { | 215 OmniboxSearchHint::~OmniboxSearchHint() { |
181 } | 216 } |
182 | 217 |
183 void OmniboxSearchHint::Observe(int type, | 218 void OmniboxSearchHint::Observe(int type, |
184 const content::NotificationSource& source, | 219 const content::NotificationSource& source, |
185 const content::NotificationDetails& details) { | 220 const content::NotificationDetails& details) { |
186 if (type == content::NOTIFICATION_NAV_ENTRY_COMMITTED) { | 221 if (type == content::NOTIFICATION_NAV_ENTRY_COMMITTED) { |
187 content::NavigationEntry* entry = | 222 HintInfoBar::Create(web_contents_, this); |
188 web_contents_->GetController().GetActiveEntry(); | |
189 if (search_engine_urls_.find(entry->GetURL().spec()) == | |
190 search_engine_urls_.end()) { | |
191 // The search engine is not in our white-list, bail. | |
192 return; | |
193 } | |
194 Profile* profile = | |
195 Profile::FromBrowserContext(web_contents_->GetBrowserContext()); | |
196 const TemplateURL* const default_provider = | |
197 TemplateURLServiceFactory::GetForProfile(profile)-> | |
198 GetDefaultSearchProvider(); | |
199 if (!default_provider) | |
200 return; | |
201 | |
202 if (default_provider->url_ref().GetHost() == entry->GetURL().host()) | |
203 ShowInfoBar(); | |
204 } else if (type == chrome::NOTIFICATION_OMNIBOX_OPENED_URL) { | 223 } else if (type == chrome::NOTIFICATION_OMNIBOX_OPENED_URL) { |
205 AutocompleteLog* log = content::Details<AutocompleteLog>(details).ptr(); | 224 AutocompleteLog* log = content::Details<AutocompleteLog>(details).ptr(); |
206 AutocompleteMatch::Type type = | 225 AutocompleteMatch::Type type = |
207 log->result.match_at(log->selected_index).type; | 226 log->result.match_at(log->selected_index).type; |
208 if (AutocompleteMatch::IsSearchType(type)) { | 227 if (AutocompleteMatch::IsSearchType(type)) { |
209 // The user performed a search from the omnibox, don't show the infobar | 228 // The user performed a search from the omnibox, don't show the infobar |
210 // again. | 229 // again. |
211 DisableHint(); | 230 DisableHint(); |
212 } | 231 } |
213 } | 232 } |
214 } | 233 } |
215 | 234 |
216 void OmniboxSearchHint::ShowInfoBar() { | |
217 InfoBarService* infobar_service = | |
218 InfoBarService::FromWebContents(web_contents_); | |
219 infobar_service->AddInfoBar(new HintInfoBar(this, infobar_service)); | |
220 } | |
221 | |
222 void OmniboxSearchHint::ShowEnteringQuery() { | 235 void OmniboxSearchHint::ShowEnteringQuery() { |
223 LocationBar* location_bar = chrome::FindBrowserWithWebContents( | 236 LocationBar* location_bar = chrome::FindBrowserWithWebContents( |
224 web_contents_)->window()->GetLocationBar(); | 237 web_contents_)->window()->GetLocationBar(); |
225 OmniboxView* omnibox_view = location_bar->GetLocationEntry(); | 238 OmniboxView* omnibox_view = location_bar->GetLocationEntry(); |
226 location_bar->FocusLocation(true); | 239 location_bar->FocusLocation(true); |
227 omnibox_view->SetUserText( | 240 omnibox_view->SetUserText( |
228 l10n_util::GetStringUTF16(IDS_OMNIBOX_SEARCH_HINT_OMNIBOX_TEXT)); | 241 l10n_util::GetStringUTF16(IDS_OMNIBOX_SEARCH_HINT_OMNIBOX_TEXT)); |
229 omnibox_view->SelectAll(false); | 242 omnibox_view->SelectAll(false); |
230 // Entering text in the omnibox view triggers the suggestion popup that we | 243 // Entering text in the omnibox view triggers the suggestion popup that we |
231 // don't want to show in this case. | 244 // don't want to show in this case. |
(...skipping 11 matching lines...) Expand all Loading... |
243 } | 256 } |
244 | 257 |
245 // static | 258 // static |
246 bool OmniboxSearchHint::IsEnabled(Profile* profile) { | 259 bool OmniboxSearchHint::IsEnabled(Profile* profile) { |
247 // The infobar can only be shown if the correct switch has been provided and | 260 // The infobar can only be shown if the correct switch has been provided and |
248 // the user did not dismiss the infobar before. | 261 // the user did not dismiss the infobar before. |
249 return profile->GetPrefs()->GetBoolean(prefs::kShowOmniboxSearchHint) && | 262 return profile->GetPrefs()->GetBoolean(prefs::kShowOmniboxSearchHint) && |
250 CommandLine::ForCurrentProcess()->HasSwitch( | 263 CommandLine::ForCurrentProcess()->HasSwitch( |
251 switches::kSearchInOmniboxHint); | 264 switches::kSearchInOmniboxHint); |
252 } | 265 } |
OLD | NEW |