summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/app/generated_resources.grd10
-rw-r--r--chrome/browser/browser.cc1
-rw-r--r--chrome/browser/gtk/infobar_gtk.cc2
-rw-r--r--chrome/browser/omnibox_search_hint.cc204
-rw-r--r--chrome/browser/omnibox_search_hint.h61
-rw-r--r--chrome/browser/tab_contents/infobar_delegate.h17
-rw-r--r--chrome/browser/tab_contents/tab_contents.cc5
-rw-r--r--chrome/browser/tab_contents/tab_contents.h5
-rw-r--r--chrome/browser/views/infobars/infobars.cc44
-rw-r--r--chrome/chrome.gyp2
-rw-r--r--chrome/common/chrome_switches.cc4
-rw-r--r--chrome/common/chrome_switches.h2
-rw-r--r--chrome/common/pref_names.cc4
-rw-r--r--chrome/common/pref_names.h1
14 files changed, 355 insertions, 7 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 84508d4..1a4ffa5 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -4058,6 +4058,16 @@ each locale. -->
Created new window in existing browser session.
</message>
+ <message name="IDS_OMNIBOX_SEARCH_HINT_INFOBAR_TEXT" desc="The text displayed in the info-bar to tell users they can type their search queries directly in the location bar.">
+ Did you know you can search directly from the box above?
+ </message>
+ <message name="IDS_OMNIBOX_SEARCH_HINT_INFOBAR_BUTTON_LABEL" desc="The label of the 'Show Me' button on the omnibox search hint infobar.">
+ Show Me
+ </message>
+ <message name="IDS_OMNIBOX_SEARCH_HINT_OMNIBOX_TEXT" desc="The text displayed selected in the omnibox once the user clicked the 'Show Me' button on the omnibox search hint infobar.">
+ Type your search query here
+ </message>
+
<!-- Mac Menubar Menus -->
<if expr="os == 'darwin'">
<!-- Menubar Menu Titles -->
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc
index 6df7a48..b373b4f 100644
--- a/chrome/browser/browser.cc
+++ b/chrome/browser/browser.cc
@@ -1207,6 +1207,7 @@ void Browser::RegisterUserPrefs(PrefService* prefs) {
prefs->RegisterIntegerPref(prefs::kDeleteTimePeriod, 0);
prefs->RegisterBooleanPref(prefs::kCheckDefaultBrowser, true);
prefs->RegisterBooleanPref(prefs::kUseCustomChromeFrame, false);
+ prefs->RegisterBooleanPref(prefs::kShowOmniboxSearchHint, true);
}
// static
diff --git a/chrome/browser/gtk/infobar_gtk.cc b/chrome/browser/gtk/infobar_gtk.cc
index 06c549c..4acc96f 100644
--- a/chrome/browser/gtk/infobar_gtk.cc
+++ b/chrome/browser/gtk/infobar_gtk.cc
@@ -150,6 +150,8 @@ void InfoBar::Closed() {
// static
void InfoBar::OnCloseButton(GtkWidget* button, InfoBar* info_bar) {
+ if (info_bar->delegate_)
+ info_bar->delegate_->InfoBarDismissed();
info_bar->RemoveInfoBar();
}
diff --git a/chrome/browser/omnibox_search_hint.cc b/chrome/browser/omnibox_search_hint.cc
new file mode 100644
index 0000000..9d36690
--- /dev/null
+++ b/chrome/browser/omnibox_search_hint.cc
@@ -0,0 +1,204 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/omnibox_search_hint.h"
+
+#include "app/animation.h"
+#include "app/l10n_util.h"
+#include "app/resource_bundle.h"
+#include "base/command_line.h"
+#include "base/task.h"
+#include "chrome/browser/browser_list.h"
+#include "chrome/browser/browser_window.h"
+#include "chrome/browser/location_bar.h"
+#include "chrome/browser/autocomplete/autocomplete_edit_view.h"
+#include "chrome/browser/profile.h"
+#include "chrome/browser/search_engines/template_url_model.h"
+#include "chrome/browser/tab_contents/infobar_delegate.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/notification_service.h"
+#include "chrome/common/notification_type.h"
+#include "chrome/common/pref_names.h"
+#include "grit/generated_resources.h"
+
+// The URLs of search engines for which we want to trigger the infobar.
+const char* kSearchEngineURLs[] = {
+ "http://www.google.com/",
+ "http://www.yahoo.com/",
+ "http://www.bing.com/",
+ "http://www.altavista.com/",
+ "http://www.ask.com/",
+ "http://www.wolframalpha.com/",
+};
+
+class HintInfoBar : public ConfirmInfoBarDelegate {
+ public:
+ explicit HintInfoBar(OmniboxSearchHint* omnibox_hint)
+ : ConfirmInfoBarDelegate(omnibox_hint->tab()),
+ omnibox_hint_(omnibox_hint),
+ action_taken_(false),
+ should_expire_(false),
+ ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
+ // We want the info-bar to stick-around for few seconds and then be hidden
+ // on the next navigation after that.
+ MessageLoop::current()->PostDelayedTask(FROM_HERE,
+ method_factory_.NewRunnableMethod(&HintInfoBar::Expire),
+ 8000); // 8 seconds.
+ }
+
+ virtual bool ShouldExpire(
+ const NavigationController::LoadCommittedDetails& details) const {
+ return should_expire_;
+ }
+
+ // Overridden from ConfirmInfoBarDelegate:
+ virtual void InfoBarClosed() {
+ if (!action_taken_)
+ UMA_HISTOGRAM_COUNTS("OmniboxSearchHint.Ignored", 1);
+ delete this;
+ }
+
+ virtual void InfoBarDismissed() {
+ action_taken_ = true;
+ UMA_HISTOGRAM_COUNTS("OmniboxSearchHint.Closed", 1);
+ // User closed the infobar, let's not bug him again with this in the future.
+ omnibox_hint_->DisableHint();
+ }
+
+ virtual std::wstring GetMessageText() const {
+ return l10n_util::GetString(IDS_OMNIBOX_SEARCH_HINT_INFOBAR_TEXT);
+ }
+
+ virtual SkBitmap* GetIcon() const {
+ return ResourceBundle::GetSharedInstance().GetBitmapNamed(
+ IDR_INFOBAR_QUESTION_MARK);
+ }
+
+ virtual int GetButtons() const {
+ return BUTTON_OK;
+ }
+
+ virtual std::wstring GetButtonLabel(InfoBarButton button) const {
+ return l10n_util::GetString(IDS_OMNIBOX_SEARCH_HINT_INFOBAR_BUTTON_LABEL);
+ }
+
+ virtual Type GetInfoBarType() {
+ return INFO_TYPE;
+ }
+
+ virtual bool Accept() {
+ action_taken_ = true;
+ UMA_HISTOGRAM_COUNTS("OmniboxSearchHint.ShowMe", 1);
+ omnibox_hint_->DisableHint();
+ omnibox_hint_->ShowEnteringQuery();
+ return true;
+ }
+
+ void Expire() {
+ should_expire_ = true;
+ }
+
+ private:
+ // The omnibox hint that shows us.
+ OmniboxSearchHint* omnibox_hint_;
+
+ // Whether the user clicked one of the buttons.
+ bool action_taken_;
+
+ // Whether the info-bar should be dismissed on the next navigation.
+ bool should_expire_;
+
+ // Used to delay the expiration of the info-bar.
+ ScopedRunnableMethodFactory<HintInfoBar> method_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(HintInfoBar);
+};
+
+OmniboxSearchHint::OmniboxSearchHint(TabContents* tab) : tab_(tab) {
+ NavigationController* controller = &(tab->controller());
+ notification_registrar_.Add(this,
+ NotificationType::NAV_ENTRY_COMMITTED,
+ Source<NavigationController>(controller));
+ // Fill the search_engine_urls_ map, used for faster look-up (overkill?).
+ for (size_t i = 0;
+ i < sizeof(kSearchEngineURLs) / sizeof(kSearchEngineURLs[0]); ++i) {
+ search_engine_urls_[kSearchEngineURLs[i]] = 1;
+ }
+
+ // Listen for omnibox to figure-out when the user searches from the omnibox.
+ notification_registrar_.Add(this,
+ NotificationType::OMNIBOX_OPENED_URL,
+ Source<Profile>(tab->profile()));
+}
+
+OmniboxSearchHint::~OmniboxSearchHint() {
+}
+
+void OmniboxSearchHint::Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ if (type == NotificationType::NAV_ENTRY_COMMITTED) {
+ NavigationEntry* entry = tab_->controller().GetActiveEntry();
+ if (search_engine_urls_.find(entry->url().spec()) ==
+ search_engine_urls_.end()) {
+ // The search engine is not in our white-list, bail.
+ return;
+ }
+ const TemplateURL* const default_provider =
+ tab_->profile()->GetTemplateURLModel()->GetDefaultSearchProvider();
+ if (!default_provider)
+ return;
+
+ const TemplateURLRef* const search_url = default_provider->url();
+ if (search_url->GetHost() == entry->url().host())
+ ShowInfoBar();
+ } else if (type == NotificationType::OMNIBOX_OPENED_URL) {
+ AutocompleteLog* log = Details<AutocompleteLog>(details).ptr();
+ AutocompleteMatch::Type type =
+ log->result.match_at(log->selected_index).type;
+ if (type == AutocompleteMatch::SEARCH_WHAT_YOU_TYPED ||
+ type == AutocompleteMatch::SEARCH_HISTORY ||
+ type == AutocompleteMatch::SEARCH_SUGGEST) {
+ // The user performed a search from the omnibox, don't show the infobar
+ // again.
+ DisableHint();
+ }
+ }
+}
+
+void OmniboxSearchHint::ShowInfoBar() {
+ tab_->AddInfoBar(new HintInfoBar(this));
+}
+
+void OmniboxSearchHint::ShowEnteringQuery() {
+ LocationBar* location_bar = BrowserList::GetLastActive()->window()->
+ GetLocationBar();
+ AutocompleteEditView* edit_view = location_bar->location_entry();
+ location_bar->FocusLocation();
+ edit_view->SetUserText(
+ l10n_util::GetString(IDS_OMNIBOX_SEARCH_HINT_OMNIBOX_TEXT));
+ edit_view->SelectAll(false);
+ // Entering text in the autocomplete edit view triggers the suggestion popup
+ // that we don't want to show in this case.
+ edit_view->ClosePopup();
+}
+
+void OmniboxSearchHint::DisableHint() {
+ // The NAV_ENTRY_COMMITTED notification was needed to show the infobar, the
+ // OMNIBOX_OPENED_URL notification was there to set the kShowOmniboxSearchHint
+ // prefs to false, none of them are needed anymore.
+ notification_registrar_.RemoveAll();
+ tab_->profile()->GetPrefs()->SetBoolean(prefs::kShowOmniboxSearchHint,
+ false);
+}
+
+// static
+bool OmniboxSearchHint::IsEnabled(Profile* profile) {
+ // The infobar can only be shown if the correct switch has been provided and
+ // the user did not dismiss the infobar before.
+ return profile->GetPrefs()->GetBoolean(prefs::kShowOmniboxSearchHint) &&
+ CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kSearchInOmniboxHint);
+}
diff --git a/chrome/browser/omnibox_search_hint.h b/chrome/browser/omnibox_search_hint.h
new file mode 100644
index 0000000..3d92011
--- /dev/null
+++ b/chrome/browser/omnibox_search_hint.h
@@ -0,0 +1,61 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_OMNIBOX_SEARCH_HINT_
+#define CHROME_BROWSER_OMNIBOX_SEARCH_HINT_
+
+#include <map>
+#include <string>
+
+#include "base/scoped_ptr.h"
+#include "chrome/common/notification_observer.h"
+#include "chrome/common/notification_registrar.h"
+
+class Profile;
+class TabContents;
+
+// This class is responsible for showing an info-bar that tells the user she
+// can type her search query directly in the omnibox.
+// It is displayed when the user visits a known search engine URL and has not
+// searched from the omnibox before, or has not previously dismissed a similar
+// info-bar.
+class OmniboxSearchHint : public NotificationObserver {
+ public:
+ explicit OmniboxSearchHint(TabContents* tab);
+ ~OmniboxSearchHint();
+
+ // NotificationObserver method:
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ // Focus the location bar and displays a message instructing that search
+ // queries can be typed directly in there.
+ void ShowEnteringQuery();
+
+ TabContents* tab() { return tab_; }
+
+ // Disables the hint infobar permanently, so that it does not show ever again.
+ void DisableHint();
+
+ // Returns true if the profile and current environment make the showing of the
+ // hint infobar possible.
+ static bool IsEnabled(Profile* profile);
+
+ private:
+ void ShowInfoBar();
+
+ NotificationRegistrar notification_registrar_;
+
+ // The tab we are associated with.
+ TabContents* tab_;
+
+ // A map containing the URLs of the search engine for which we want to
+ // trigger the hint.
+ std::map<std::string, int> search_engine_urls_;
+
+ DISALLOW_COPY_AND_ASSIGN(OmniboxSearchHint);
+};
+
+#endif // CHROME_BROWSER_OMNIBOX_SEARCH_HINT_
diff --git a/chrome/browser/tab_contents/infobar_delegate.h b/chrome/browser/tab_contents/infobar_delegate.h
index 6f44dd2..f8ce253 100644
--- a/chrome/browser/tab_contents/infobar_delegate.h
+++ b/chrome/browser/tab_contents/infobar_delegate.h
@@ -41,6 +41,14 @@ class LinkInfoBarDelegate;
// AddInfoBar!
class InfoBarDelegate {
public:
+ // The type of the infobar. It controls its appearence, such as its background
+ // color.
+ enum Type {
+ INFO_TYPE,
+ WARNING_TYPE,
+ ERROR_TYPE
+ };
+
// Returns true if the supplied |delegate| is equal to this one. Equality is
// left to the implementation to define. This function is called by the
// TabContents when determining whether or not a delegate should be added
@@ -57,6 +65,9 @@ class InfoBarDelegate {
virtual bool ShouldExpire(
const NavigationController::LoadCommittedDetails& details) const;
+ // Called when the user clicks on the close button to dismiss the infobar.
+ virtual void InfoBarDismissed() {}
+
// Called after the InfoBar is closed. The delegate is free to delete itself
// at this point.
virtual void InfoBarClosed() {}
@@ -84,6 +95,12 @@ class InfoBarDelegate {
return NULL;
}
+ // Returns the type of the infobar. The type determines the appearance (such
+ // as background color) of the infobar.
+ virtual Type GetInfoBarType() {
+ return WARNING_TYPE;
+ }
+
protected:
// Provided to subclasses as a convenience to initialize the state of this
// object. If |contents| is non-NULL, its active entry's unique ID will be
diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc
index e91f188..3678335 100644
--- a/chrome/browser/tab_contents/tab_contents.cc
+++ b/chrome/browser/tab_contents/tab_contents.cc
@@ -28,6 +28,7 @@
#include "chrome/browser/jsmessage_box_handler.h"
#include "chrome/browser/load_from_memory_cache_details.h"
#include "chrome/browser/load_notification_details.h"
+#include "chrome/browser/omnibox_search_hint.h"
#include "chrome/browser/password_manager/password_manager.h"
#include "chrome/browser/plugin_installer.h"
#include "chrome/browser/profile.h"
@@ -285,6 +286,10 @@ TabContents::TabContents(Profile* profile,
static string16 global_last_search = string16();
last_search_prepopulate_text_ = &global_last_search;
+ // Set-up the showing of the omnibox search infobar if applicable.
+ if (OmniboxSearchHint::IsEnabled(profile))
+ omnibox_search_hint_.reset(new OmniboxSearchHint(this));
+
view_->InitRendererPrefs(&renderer_preferences_);
}
diff --git a/chrome/browser/tab_contents/tab_contents.h b/chrome/browser/tab_contents/tab_contents.h
index e0bb482..fc6f76f 100644
--- a/chrome/browser/tab_contents/tab_contents.h
+++ b/chrome/browser/tab_contents/tab_contents.h
@@ -74,6 +74,7 @@ class DOMUI;
class DOMUIContents;
class DownloadItem;
class LoadNotificationDetails;
+class OmniboxSearchHint;
class PageAction;
class PasswordManager;
class PluginInstaller;
@@ -1089,6 +1090,10 @@ class TabContents : public PageNavigator,
// reset on navigations to false on navigations.
bool suppress_javascript_messages_;
+ // Shows an info-bar to users when they search from a known search engine and
+ // have never used the monibox for search before.
+ scoped_ptr<OmniboxSearchHint> omnibox_search_hint_;
+
// Settings that get passed to the renderer process.
RendererPreferences renderer_preferences_;
diff --git a/chrome/browser/views/infobars/infobars.cc b/chrome/browser/views/infobars/infobars.cc
index 8c67150..c404d0e 100644
--- a/chrome/browser/views/infobars/infobars.cc
+++ b/chrome/browser/views/infobars/infobars.cc
@@ -30,8 +30,16 @@ static const int kIconLabelSpacing = 5;
static const int kButtonSpacing = 5;
static const int kWordSpacing = 2;
-static const SkColor kBackgroundColorTop = SkColorSetRGB(255, 242, 183);
-static const SkColor kBackgroundColorBottom = SkColorSetRGB(250, 230, 145);
+static const SkColor kInfoBackgroundColorTop = SkColorSetRGB(170, 214, 112);
+static const SkColor kInfoBackgroundColorBottom = SkColorSetRGB(146, 205, 114);
+
+static const SkColor kWarningBackgroundColorTop = SkColorSetRGB(255, 242, 183);
+static const SkColor kWarningBackgroundColorBottom =
+ SkColorSetRGB(250, 230, 145);
+
+static const SkColor kErrorBackgroundColorTop = kWarningBackgroundColorTop;
+static const SkColor kErrorBackgroundColorBottom =
+ kWarningBackgroundColorBottom;
static const int kSeparatorLineHeight = 1;
@@ -57,10 +65,29 @@ int OffsetY(views::View* parent, const gfx::Size prefsize) {
class InfoBarBackground : public views::Background {
public:
- InfoBarBackground() {
+ InfoBarBackground(InfoBarDelegate::Type infobar_type) {
+ SkColor top_color;
+ SkColor bottom_color;
+ switch (infobar_type) {
+ case InfoBarDelegate::INFO_TYPE:
+ top_color = kInfoBackgroundColorTop;
+ bottom_color = kInfoBackgroundColorBottom;
+ break;
+ case InfoBarDelegate::WARNING_TYPE:
+ top_color = kWarningBackgroundColorTop;
+ bottom_color = kWarningBackgroundColorBottom;
+ break;
+ case InfoBarDelegate::ERROR_TYPE:
+ top_color = kErrorBackgroundColorTop;
+ bottom_color = kErrorBackgroundColorBottom;
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
gradient_background_.reset(
- views::Background::CreateVerticalGradientBackground(
- kBackgroundColorTop, kBackgroundColorBottom));
+ views::Background::CreateVerticalGradientBackground(top_color,
+ bottom_color));
}
// Overridden from views::View:
@@ -90,7 +117,7 @@ InfoBar::InfoBar(InfoBarDelegate* delegate)
// We delete ourselves when we're removed from the view hierarchy.
SetParentOwned(false);
- set_background(new InfoBarBackground);
+ set_background(new InfoBarBackground(delegate->GetInfoBarType()));
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
close_button_->SetImage(views::CustomButton::BS_NORMAL,
@@ -172,8 +199,11 @@ void InfoBar::RemoveInfoBar() const {
// InfoBar, views::ButtonListener implementation: ------------------
void InfoBar::ButtonPressed(views::Button* sender) {
- if (sender == close_button_)
+ if (sender == close_button_) {
+ if (delegate_)
+ delegate_->InfoBarDismissed();
RemoveInfoBar();
+ }
}
// InfoBar, AnimationDelegate implementation: ----------------------------------
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index ae71889..ca3b3c3 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -1294,6 +1294,8 @@
'browser/net/url_fetcher_protect.h',
'browser/net/url_fixer_upper.cc',
'browser/net/url_fixer_upper.h',
+ 'browser/omnibox_search_hint.cc',
+ 'browser/omnibox_search_hint.h',
'browser/options_page_base.cc',
'browser/options_page_base.h',
'browser/options_util.cc',
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index 99bcd33..ee617fd 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -538,6 +538,10 @@ const wchar_t kEnableTabtastic2[] = L"enable-tabtastic2";
// enabled.
const wchar_t kPinnedTabCount[] = L"pinned-tab-count";
+// Enables the showing of an info-bar instructing user they can search directly
+// from the omnibox.
+const wchar_t kSearchInOmniboxHint[] = L"search-in-omnibox-hint";
+
// Enable local storage. Still buggy.
const wchar_t kEnableLocalStorage[] = L"enable-local-storage";
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index 038a630..ea089e8 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -207,6 +207,8 @@ extern const wchar_t kEnableTabtastic2[];
extern const wchar_t kPinnedTabCount[];
+extern const wchar_t kSearchInOmniboxHint[];
+
extern const wchar_t kEnableLocalStorage[];
extern const wchar_t kEnableSessionStorage[];
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index 14176e4..ed4c086 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -268,6 +268,10 @@ const wchar_t kCheckDefaultBrowser[] = L"browser.check_default_browser";
// true, we draw a custom chrome frame (thicker title bar and blue border).
const wchar_t kUseCustomChromeFrame[] = L"browser.custom_chrome_frame";
+// Boolean that indicates whether the infobar explaining that search can be done
+// directly from the omnibox should be shown.
+const wchar_t kShowOmniboxSearchHint[] = L"browser.show_omnibox_search_hint";
+
// *************** LOCAL STATE ***************
// These are attached to the machine/installation
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index 96b2caf..a33ca22 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -101,6 +101,7 @@ extern const wchar_t kCurrentThemeTints[];
extern const wchar_t kCurrentThemeDisplayProperties[];
extern const wchar_t kCheckDefaultBrowser[];
extern const wchar_t kUseCustomChromeFrame[];
+extern const wchar_t kShowOmniboxSearchHint[];
// Local state
extern const wchar_t kAvailableProfiles[];