summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-07 22:34:31 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-07 22:34:31 +0000
commite0360f2cca48cf72be469c936783c10d037af292 (patch)
treeb0fcb4f5a8de7a177af436df6bbfc7a87b6ab2d0
parentf891c9df37709735c6f188e163f57e6ee12cf25c (diff)
downloadchromium_src-e0360f2cca48cf72be469c936783c10d037af292.zip
chromium_src-e0360f2cca48cf72be469c936783c10d037af292.tar.gz
chromium_src-e0360f2cca48cf72be469c936783c10d037af292.tar.bz2
Extensions: create a simple model for the browser action buttons toolstrip and use it on Linux.
TODO: persist the order of buttons TODO: use the model on windows, mac TODO: let the view change the order of buttons My plan for persisting the order is just to write/read a simple text file to/from disk, one extension id per line. Similar to the bookmark model, except that is structured data (because they try to hold more information). BUG=26990 Review URL: http://codereview.chromium.org/462026 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@34005 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/extensions/extension_toolbar_model.cc79
-rw-r--r--chrome/browser/extensions/extension_toolbar_model.h64
-rw-r--r--chrome/browser/extensions/extensions_service.cc3
-rw-r--r--chrome/browser/extensions/extensions_service.h7
-rw-r--r--chrome/browser/gtk/browser_actions_toolbar_gtk.cc58
-rw-r--r--chrome/browser/gtk/browser_actions_toolbar_gtk.h16
-rwxr-xr-xchrome/chrome_browser.gypi2
7 files changed, 185 insertions, 44 deletions
diff --git a/chrome/browser/extensions/extension_toolbar_model.cc b/chrome/browser/extensions/extension_toolbar_model.cc
new file mode 100644
index 0000000..39856cf
--- /dev/null
+++ b/chrome/browser/extensions/extension_toolbar_model.cc
@@ -0,0 +1,79 @@
+// 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/extensions/extension_toolbar_model.h"
+
+#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/common/extensions/extension.h"
+#include "chrome/common/notification_service.h"
+
+ExtensionToolbarModel::ExtensionToolbarModel(ExtensionsService* service)
+ : service_(service) {
+ DCHECK(service_);
+
+ registrar_.Add(this, NotificationType::EXTENSION_LOADED,
+ Source<Profile>(service_->profile()));
+ registrar_.Add(this, NotificationType::EXTENSION_UNLOADED,
+ Source<Profile>(service_->profile()));
+ registrar_.Add(this, NotificationType::EXTENSION_UNLOADED_DISABLED,
+ Source<Profile>(service_->profile()));
+ registrar_.Add(this, NotificationType::EXTENSIONS_READY,
+ Source<Profile>(service_->profile()));
+}
+
+ExtensionToolbarModel::~ExtensionToolbarModel() {
+}
+
+void ExtensionToolbarModel::AddObserver(Observer* observer) {
+ observers_.AddObserver(observer);
+}
+
+void ExtensionToolbarModel::RemoveObserver(Observer* observer) {
+ observers_.RemoveObserver(observer);
+}
+
+void ExtensionToolbarModel::Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ if (type == NotificationType::EXTENSIONS_READY) {
+ for (size_t i = 0; i < service_->extensions()->size(); ++i) {
+ Extension* extension = service_->GetExtensionById(
+ service_->extensions()->at(i)->id(), false);
+ AddExtension(extension);
+ }
+ return;
+ }
+
+ if (!service_->is_ready())
+ return;
+
+ Extension* extension = Details<Extension>(details).ptr();
+ if (type == NotificationType::EXTENSION_LOADED) {
+ AddExtension(extension);
+ } else if (type == NotificationType::EXTENSION_UNLOADED ||
+ type == NotificationType::EXTENSION_UNLOADED_DISABLED) {
+ RemoveExtension(extension);
+ } else {
+ NOTREACHED() << "Received unexpected notification";
+ }
+}
+
+void ExtensionToolbarModel::AddExtension(Extension* extension) {
+ // We only care about extensions with browser actions.
+ if (!extension->browser_action())
+ return;
+
+ toolitems_.push_back(extension);
+ FOR_EACH_OBSERVER(Observer, observers_,
+ BrowserActionAdded(extension, toolitems_.size() - 1));
+}
+
+void ExtensionToolbarModel::RemoveExtension(Extension* extension) {
+ ExtensionList::iterator pos = std::find(begin(), end(), extension);
+ if (pos != end()) {
+ toolitems_.erase(pos);
+ FOR_EACH_OBSERVER(Observer, observers_,
+ BrowserActionRemoved(extension));
+ }
+}
diff --git a/chrome/browser/extensions/extension_toolbar_model.h b/chrome/browser/extensions/extension_toolbar_model.h
new file mode 100644
index 0000000..d02dc0f
--- /dev/null
+++ b/chrome/browser/extensions/extension_toolbar_model.h
@@ -0,0 +1,64 @@
+// 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_EXTENSIONS_EXTENSION_TOOLBAR_MODEL_H_
+#define CHROME_BROWSER_EXTENSIONS_EXTENSION_TOOLBAR_MODEL_H_
+
+#include "base/observer_list.h"
+#include "chrome/common/extensions/extension.h"
+#include "chrome/common/notification_observer.h"
+#include "chrome/common/notification_registrar.h"
+
+class ExtensionsService;
+
+// Model for the browser actions toolbar.
+class ExtensionToolbarModel : public NotificationObserver {
+ public:
+ explicit ExtensionToolbarModel(ExtensionsService* service);
+ ~ExtensionToolbarModel();
+
+ // A class which is informed of changes to the model; represents the view of
+ // MVC.
+ class Observer {
+ public:
+ // An extension with a browser action button has been added, and should go
+ // in the toolbar at |index|.
+ virtual void BrowserActionAdded(Extension* extension, int index) {}
+
+ // The browser action button for |extension| should no longer show.
+ virtual void BrowserActionRemoved(Extension* extension) {}
+ };
+
+ void AddObserver(Observer* observer);
+ void RemoveObserver(Observer* observer);
+
+ ExtensionList::iterator begin() {
+ return toolitems_.begin();
+ }
+
+ ExtensionList::iterator end() {
+ return toolitems_.end();
+ }
+
+ private:
+ // NotificationObserver implementation.
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ // Our observers.
+ ObserverList<Observer> observers_;
+
+ void AddExtension(Extension* extension);
+ void RemoveExtension(Extension* extension);
+
+ // Our ExtensionsService, guaranteed to outlive us.
+ ExtensionsService* service_;
+
+ // Ordered list of browser action buttons.
+ ExtensionList toolitems_;
+
+ NotificationRegistrar registrar_;
+};
+#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_TOOLBAR_MODEL_H_
diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc
index 7af9133..2ae7f5e 100644
--- a/chrome/browser/extensions/extensions_service.cc
+++ b/chrome/browser/extensions/extensions_service.cc
@@ -91,7 +91,8 @@ ExtensionsService::ExtensionsService(Profile* profile,
install_directory_(install_directory),
extensions_enabled_(true),
show_extensions_prompts_(true),
- ready_(false) {
+ ready_(false),
+ ALLOW_THIS_IN_INITIALIZER_LIST(toolbar_model_(this)) {
// Figure out if extension installation should be enabled.
if (command_line->HasSwitch(switches::kDisableExtensions)) {
extensions_enabled_ = false;
diff --git a/chrome/browser/extensions/extensions_service.h b/chrome/browser/extensions/extensions_service.h
index 79fdc10..0492538 100644
--- a/chrome/browser/extensions/extensions_service.h
+++ b/chrome/browser/extensions/extensions_service.h
@@ -20,6 +20,7 @@
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/extensions/extension_prefs.h"
#include "chrome/browser/extensions/extension_process_manager.h"
+#include "chrome/browser/extensions/extension_toolbar_model.h"
#include "chrome/browser/extensions/extensions_quota_service.h"
#include "chrome/browser/extensions/external_extension_provider.h"
#include "chrome/browser/extensions/sandboxed_extension_unpacker.h"
@@ -32,6 +33,7 @@ class Browser;
class DictionaryValue;
class Extension;
class ExtensionsServiceBackend;
+class ExtensionToolbarModel;
class ExtensionUpdater;
class GURL;
class PrefService;
@@ -213,6 +215,8 @@ class ExtensionsService
// Note that this may return NULL if autoupdate is not turned on.
ExtensionUpdater* updater() { return updater_.get(); }
+ ExtensionToolbarModel* toolbar_model() { return &toolbar_model_; }
+
ExtensionsQuotaService* quota_service() { return &quota_service_; }
// Notify the frontend that there was an error loading an extension.
@@ -292,6 +296,9 @@ class ExtensionsService
// Our extension updater, if updates are turned on.
scoped_refptr<ExtensionUpdater> updater_;
+ // The model that tracks extensions with BrowserAction buttons.
+ ExtensionToolbarModel toolbar_model_;
+
// Map of inspector cookies that are detached, waiting for an extension to be
// reloaded.
typedef std::map<std::string, int> OrphanedDevTools;
diff --git a/chrome/browser/gtk/browser_actions_toolbar_gtk.cc b/chrome/browser/gtk/browser_actions_toolbar_gtk.cc
index 4399923..91ea423 100644
--- a/chrome/browser/gtk/browser_actions_toolbar_gtk.cc
+++ b/chrome/browser/gtk/browser_actions_toolbar_gtk.cc
@@ -203,18 +203,20 @@ class BrowserActionButton : public NotificationObserver,
BrowserActionsToolbarGtk::BrowserActionsToolbarGtk(Browser* browser)
: browser_(browser),
profile_(browser->profile()),
+ model_(NULL),
hbox_(gtk_hbox_new(FALSE, kBrowserActionButtonPadding)) {
- registrar_.Add(this, NotificationType::EXTENSION_LOADED,
- Source<Profile>(profile_));
- registrar_.Add(this, NotificationType::EXTENSION_UNLOADED,
- Source<Profile>(profile_));
- registrar_.Add(this, NotificationType::EXTENSION_UNLOADED_DISABLED,
- Source<Profile>(profile_));
-
- CreateAllButtons();
+ ExtensionsService* extension_service = profile_->GetExtensionsService();
+ // The |extension_service| can be NULL in Incognito.
+ if (extension_service) {
+ model_ = extension_service->toolbar_model();
+ model_->AddObserver(this);
+ CreateAllButtons();
+ }
}
BrowserActionsToolbarGtk::~BrowserActionsToolbarGtk() {
+ if (model_)
+ model_->RemoveObserver(this);
hbox_.Destroy();
}
@@ -233,38 +235,14 @@ void BrowserActionsToolbarGtk::Update() {
}
}
-void BrowserActionsToolbarGtk::Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details) {
- Extension* extension = Details<Extension>(details).ptr();
-
- if (type == NotificationType::EXTENSION_LOADED) {
- CreateButtonForExtension(extension);
- } else if (type == NotificationType::EXTENSION_UNLOADED ||
- type == NotificationType::EXTENSION_UNLOADED_DISABLED) {
- RemoveButtonForExtension(extension);
- } else {
- NOTREACHED() << "Received unexpected notification";
- }
-}
-
void BrowserActionsToolbarGtk::CreateAllButtons() {
- ExtensionsService* extension_service = profile_->GetExtensionsService();
- if (!extension_service) // The |extension_service| can be NULL in Incognito.
- return;
-
- for (size_t i = 0; i < extension_service->extensions()->size(); ++i) {
- Extension* extension = extension_service->GetExtensionById(
- extension_service->extensions()->at(i)->id(), false);
- CreateButtonForExtension(extension);
+ for (ExtensionList::iterator iter = model_->begin();
+ iter != model_->end(); ++iter) {
+ CreateButtonForExtension(*iter);
}
}
void BrowserActionsToolbarGtk::CreateButtonForExtension(Extension* extension) {
- // Only show extensions with browser actions.
- if (!extension->browser_action())
- return;
-
RemoveButtonForExtension(extension);
linked_ptr<BrowserActionButton> button(
new BrowserActionButton(this, extension));
@@ -286,3 +264,13 @@ void BrowserActionsToolbarGtk::UpdateVisibility() {
else
gtk_widget_show(widget());
}
+
+void BrowserActionsToolbarGtk::BrowserActionAdded(Extension* extension,
+ int index) {
+ // TODO(estade): respect |index|.
+ CreateButtonForExtension(extension);
+}
+
+void BrowserActionsToolbarGtk::BrowserActionRemoved(Extension* extension) {
+ RemoveButtonForExtension(extension);
+}
diff --git a/chrome/browser/gtk/browser_actions_toolbar_gtk.h b/chrome/browser/gtk/browser_actions_toolbar_gtk.h
index 015b5c9..ceee599b 100644
--- a/chrome/browser/gtk/browser_actions_toolbar_gtk.h
+++ b/chrome/browser/gtk/browser_actions_toolbar_gtk.h
@@ -9,6 +9,7 @@
#include <string>
#include "base/linked_ptr.h"
+#include "chrome/browser/extensions/extension_toolbar_model.h"
#include "chrome/common/notification_observer.h"
#include "chrome/common/notification_registrar.h"
#include "chrome/common/owned_widget_gtk.h"
@@ -20,7 +21,7 @@ class Profile;
typedef struct _GtkWidget GtkWidget;
-class BrowserActionsToolbarGtk : public NotificationObserver {
+class BrowserActionsToolbarGtk : public ExtensionToolbarModel::Observer {
public:
explicit BrowserActionsToolbarGtk(Browser* browser);
~BrowserActionsToolbarGtk();
@@ -37,11 +38,6 @@ class BrowserActionsToolbarGtk : public NotificationObserver {
// Update the display of all buttons.
void Update();
- // NotificationObserver implementation.
- void Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details);
-
private:
// Query the extensions service for all extensions with browser actions,
// and create the UI for them.
@@ -60,13 +56,17 @@ class BrowserActionsToolbarGtk : public NotificationObserver {
// to show.
void UpdateVisibility();
+ // ExtensionToolbarModel::Observer implementation.
+ virtual void BrowserActionAdded(Extension* extension, int index);
+ virtual void BrowserActionRemoved(Extension* extension);
+
Browser* browser_;
Profile* profile_;
- OwnedWidgetGtk hbox_;
+ ExtensionToolbarModel* model_;
- NotificationRegistrar registrar_;
+ OwnedWidgetGtk hbox_;
// Map from extension ID to BrowserActionButton, which is a wrapper for
// a chrome button and related functionality. There should be one entry
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 5999495..8a88319 100755
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -686,6 +686,8 @@
'browser/extensions/extension_tabs_module_constants.h',
'browser/extensions/extension_test_api.cc',
'browser/extensions/extension_test_api.h',
+ 'browser/extensions/extension_toolbar_model.cc',
+ 'browser/extensions/extension_toolbar_model.h',
'browser/extensions/extension_toolstrip_api.cc',
'browser/extensions/extension_toolstrip_api.h',
'browser/extensions/extension_updater.cc',