| 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 |