summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-14 20:51:29 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-14 20:51:29 +0000
commit216e0bc0a053fe5939f829c877959f9a26a91e11 (patch)
tree3c9036938d87ee68ba69acc7ca0a9529a19202dd /chrome/browser/extensions
parenta4ed6281fe6d6aad1366a8f6b03e35f6e1eadaa6 (diff)
downloadchromium_src-216e0bc0a053fe5939f829c877959f9a26a91e11.zip
chromium_src-216e0bc0a053fe5939f829c877959f9a26a91e11.tar.gz
chromium_src-216e0bc0a053fe5939f829c877959f9a26a91e11.tar.bz2
Persist the order of extensions in the browser action toolbar across sessions.
Very similar to what we did with the extension shelf. BUG=26990 Review URL: http://codereview.chromium.org/487021 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@34490 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/extensions')
-rw-r--r--chrome/browser/extensions/extension_prefs.cc31
-rw-r--r--chrome/browser/extensions/extension_prefs.h6
-rw-r--r--chrome/browser/extensions/extension_toolbar_model.cc86
-rw-r--r--chrome/browser/extensions/extension_toolbar_model.h8
4 files changed, 122 insertions, 9 deletions
diff --git a/chrome/browser/extensions/extension_prefs.cc b/chrome/browser/extensions/extension_prefs.cc
index c793fb3b..aef47ac 100644
--- a/chrome/browser/extensions/extension_prefs.cc
+++ b/chrome/browser/extensions/extension_prefs.cc
@@ -36,6 +36,11 @@ const wchar_t kPrefBlacklist[] = L"blacklist";
// A preference that tracks extension shelf configuration. This is a list
// object read from the Preferences file, containing a list of toolstrip URLs.
const wchar_t kExtensionShelf[] = L"extensions.shelf";
+
+// A preference that tracks browser action toolbar configuration. This is a list
+// object stored in the Preferences file. The extensions are stored by ID.
+const wchar_t kExtensionToolbar[] = L"extensions.toolbar";
+
}
////////////////////////////////////////////////////////////////////////////////
@@ -105,6 +110,8 @@ ExtensionPrefs::ExtensionPrefs(PrefService* prefs, const FilePath& root_dir)
prefs_->RegisterDictionaryPref(kExtensionsPref);
if (!prefs->FindPreference(kExtensionShelf))
prefs->RegisterListPref(kExtensionShelf);
+ if (!prefs->FindPreference(kExtensionToolbar))
+ prefs->RegisterListPref(kExtensionToolbar);
MakePathsRelative();
}
@@ -314,6 +321,30 @@ void ExtensionPrefs::SetShelfToolstripOrder(const URLList& urls) {
prefs_->ScheduleSavePersistentPrefs();
}
+std::vector<std::string> ExtensionPrefs::GetToolbarOrder() {
+ std::vector<std::string> extension_ids;
+ const ListValue* toolbar_order = prefs_->GetList(kExtensionToolbar);
+ if (toolbar_order) {
+ for (size_t i = 0; i < toolbar_order->GetSize(); ++i) {
+ std::string extension_id;
+ if (toolbar_order->GetString(i, &extension_id))
+ extension_ids.push_back(extension_id);
+ }
+ }
+ return extension_ids;
+}
+
+void ExtensionPrefs::SetToolbarOrder(
+ const std::vector<std::string>& extension_ids) {
+ ListValue* toolbar_order = prefs_->GetMutableList(kExtensionToolbar);
+ toolbar_order->Clear();
+ for (std::vector<std::string>::const_iterator iter = extension_ids.begin();
+ iter != extension_ids.end(); ++iter) {
+ toolbar_order->Append(new StringValue(*iter));
+ }
+ prefs_->ScheduleSavePersistentPrefs();
+}
+
void ExtensionPrefs::OnExtensionInstalled(Extension* extension) {
const std::string& id = extension->id();
// Make sure we don't enable a disabled extension.
diff --git a/chrome/browser/extensions/extension_prefs.h b/chrome/browser/extensions/extension_prefs.h
index 2bbd239..86ad883 100644
--- a/chrome/browser/extensions/extension_prefs.h
+++ b/chrome/browser/extensions/extension_prefs.h
@@ -36,6 +36,12 @@ class ExtensionPrefs {
// Sets the order that toolstrip URLs appear in the shelf.
void SetShelfToolstripOrder(const URLList& urls);
+ // Get the order that the browser actions appear in the toolbar.
+ std::vector<std::string> GetToolbarOrder();
+
+ // Set the order that the browser actions appear in the toolbar.
+ void SetToolbarOrder(const std::vector<std::string>& extension_ids);
+
// Called when an extension is installed, so that prefs get created.
void OnExtensionInstalled(Extension* extension);
diff --git a/chrome/browser/extensions/extension_toolbar_model.cc b/chrome/browser/extensions/extension_toolbar_model.cc
index 5a9f2a8..d561120 100644
--- a/chrome/browser/extensions/extension_toolbar_model.cc
+++ b/chrome/browser/extensions/extension_toolbar_model.cc
@@ -4,6 +4,7 @@
#include "chrome/browser/extensions/extension_toolbar_model.h"
+#include "chrome/browser/extensions/extension_prefs.h"
#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/notification_service.h"
@@ -46,7 +47,7 @@ void ExtensionToolbarModel::MoveBrowserAction(Extension* extension,
bool inserted = false;
for (ExtensionList::iterator iter = begin(); iter != end(); ++iter, ++i) {
if (i == index) {
- toolitems_.insert(pos, extension);
+ toolitems_.insert(iter, extension);
inserted = true;
break;
}
@@ -60,17 +61,15 @@ void ExtensionToolbarModel::MoveBrowserAction(Extension* extension,
}
FOR_EACH_OBSERVER(Observer, observers_, BrowserActionMoved(extension, index));
+
+ UpdatePrefs();
}
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);
- }
+ InitializeExtensionList();
return;
}
@@ -96,13 +95,82 @@ void ExtensionToolbarModel::AddExtension(Extension* extension) {
toolitems_.push_back(extension);
FOR_EACH_OBSERVER(Observer, observers_,
BrowserActionAdded(extension, toolitems_.size() - 1));
+
+ UpdatePrefs();
}
void ExtensionToolbarModel::RemoveExtension(Extension* extension) {
ExtensionList::iterator pos = std::find(begin(), end(), extension);
- if (pos != end()) {
- toolitems_.erase(pos);
+ if (pos == end()) {
+ return;
+ }
+
+ toolitems_.erase(pos);
+ FOR_EACH_OBSERVER(Observer, observers_,
+ BrowserActionRemoved(extension));
+
+ UpdatePrefs();
+}
+
+// Combine the currently enabled extensions that have browser actions (which
+// we get from the ExtensionsService) with the ordering we get from the
+// pref service. For robustness we use a somewhat inefficient process:
+// 1. Create a vector of extensions sorted by their pref values. This vector may
+// have holes.
+// 2. Create a vector of extensions that did not have a pref value.
+// 3. Remove holes from the sorted vector and append the unsorted vector.
+void ExtensionToolbarModel::InitializeExtensionList() {
+ DCHECK(service_->is_ready());
+
+ std::vector<std::string> pref_order = service_->extension_prefs()->
+ GetToolbarOrder();
+ // Items that have a pref for their position.
+ ExtensionList sorted;
+ sorted.resize(pref_order.size(), NULL);
+ // The items that don't have a pref for their position.
+ ExtensionList unsorted;
+
+ // Create the lists.
+ for (size_t i = 0; i < service_->extensions()->size(); ++i) {
+ Extension* extension = service_->extensions()->at(i);
+ if (!extension->browser_action())
+ continue;
+
+ std::vector<std::string>::iterator pos =
+ std::find(pref_order.begin(), pref_order.end(), extension->id());
+ if (pos != pref_order.end()) {
+ int index = std::distance(pref_order.begin(), pos);
+ sorted[index] = extension;
+ } else {
+ unsorted.push_back(extension);
+ }
+ }
+
+ // Merge the lists.
+ toolitems_.reserve(sorted.size() + unsorted.size());
+ for (ExtensionList::iterator iter = sorted.begin();
+ iter != sorted.end(); ++iter) {
+ if (*iter != NULL)
+ toolitems_.push_back(*iter);
+ }
+ toolitems_.insert(toolitems_.end(), unsorted.begin(), unsorted.end());
+
+ // Inform observers.
+ for (size_t i = 0; i < toolitems_.size(); i++) {
FOR_EACH_OBSERVER(Observer, observers_,
- BrowserActionRemoved(extension));
+ BrowserActionAdded(toolitems_[i], i));
}
+
+ UpdatePrefs();
+}
+
+void ExtensionToolbarModel::UpdatePrefs() {
+ if (!service_->extension_prefs())
+ return;
+
+ std::vector<std::string> ids;
+ ids.reserve(toolitems_.size());
+ for (ExtensionList::iterator iter = begin(); iter != end(); ++iter)
+ ids.push_back((*iter)->id());
+ service_->extension_prefs()->SetToolbarOrder(ids);
}
diff --git a/chrome/browser/extensions/extension_toolbar_model.h b/chrome/browser/extensions/extension_toolbar_model.h
index 54977eb..5b6a8a4 100644
--- a/chrome/browser/extensions/extension_toolbar_model.h
+++ b/chrome/browser/extensions/extension_toolbar_model.h
@@ -52,6 +52,14 @@ class ExtensionToolbarModel : public NotificationObserver {
const NotificationSource& source,
const NotificationDetails& details);
+ // To be called after the extension service is ready; gets loaded extensions
+ // from the extension service and their saved order from the pref service
+ // and constructs |toolitems_| from these data.
+ void InitializeExtensionList();
+
+ // Save the model to prefs.
+ void UpdatePrefs();
+
// Our observers.
ObserverList<Observer> observers_;