summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions
diff options
context:
space:
mode:
authorerikkay@google.com <erikkay@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-29 20:28:46 +0000
committererikkay@google.com <erikkay@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-29 20:28:46 +0000
commit309934c4ceea5086567f275cef17bbfefa29996b (patch)
treed8efe2e9b30e10d67bdacc8c0f4f28614a4a2eb3 /chrome/browser/extensions
parent36fe18f709825bc199f5eca66463a832e09638c5 (diff)
downloadchromium_src-309934c4ceea5086567f275cef17bbfefa29996b.zip
chromium_src-309934c4ceea5086567f275cef17bbfefa29996b.tar.gz
chromium_src-309934c4ceea5086567f275cef17bbfefa29996b.tar.bz2
more extensions bookmarks changes:* add schema verification* add unit tests for schema* add a few new methods (getTree, getChildren)* add events
Review URL: http://codereview.chromium.org/102009 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@14877 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/extensions')
-rw-r--r--chrome/browser/extensions/extension_bookmarks_module.cc177
-rw-r--r--chrome/browser/extensions/extension_bookmarks_module.h89
-rw-r--r--chrome/browser/extensions/extension_function_dispatcher.cc4
3 files changed, 259 insertions, 11 deletions
diff --git a/chrome/browser/extensions/extension_bookmarks_module.cc b/chrome/browser/extensions/extension_bookmarks_module.cc
index aa720ca..3a175ed 100644
--- a/chrome/browser/extensions/extension_bookmarks_module.cc
+++ b/chrome/browser/extensions/extension_bookmarks_module.cc
@@ -4,9 +4,12 @@
#include "chrome/browser/extensions/extension_bookmarks_module.h"
+#include "base/json_writer.h"
#include "chrome/browser/bookmarks/bookmark_codec.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/bookmarks/bookmark_utils.h"
+#include "chrome/browser/browser_list.h"
+#include "chrome/browser/extensions/extension_message_service.h"
#include "chrome/browser/profile.h"
namespace {
@@ -14,6 +17,8 @@ namespace {
const wchar_t* kIdKey = L"id";
const wchar_t* kIndexKey = L"index";
const wchar_t* kParentIdKey = L"parentId";
+const wchar_t* kOldIndexKey = L"oldIndex";
+const wchar_t* kOldParentIdKey = L"oldParentId";
const wchar_t* kUrlKey = L"url";
const wchar_t* kTitleKey = L"title";
const wchar_t* kChildrenIdsKey = L"childrenIds";
@@ -28,6 +33,13 @@ const char* kFolderNotEmptyError =
const char* kInvalidIndexError = "Index out of bounds.";
const char* kInvalidUrlError = "Invalid URL.";
const char* kModifySpecialError = "Can't modify the root bookmark folders.";
+
+// events
+const char* kOnBookmarkAdded = "bookmark-added";
+const char* kOnBookmarkRemoved = "bookmark-removed";
+const char* kOnBookmarkChanged = "bookmark-changed";
+const char* kOnBookmarkMoved = "bookmark-moved";
+const char* kOnBookmarkChildrenReordered = "bookmark-children-reordered";
};
// Helper functions.
@@ -76,7 +88,140 @@ class ExtensionBookmarks {
ExtensionBookmarks();
};
-// TODO(erikkay): add a recursive version
+void BookmarksFunction::Run() {
+ // TODO(erikkay) temporary hack until adding an event listener can notify the
+ // browser.
+ ExtensionBookmarkEventRouter* event_router =
+ ExtensionBookmarkEventRouter::GetSingleton();
+ BookmarkModel* model = profile()->GetBookmarkModel();
+ event_router->Observe(model);
+ SyncExtensionFunction::Run();
+}
+
+// static
+ExtensionBookmarkEventRouter* ExtensionBookmarkEventRouter::GetSingleton() {
+ return Singleton<ExtensionBookmarkEventRouter>::get();
+}
+
+ExtensionBookmarkEventRouter::ExtensionBookmarkEventRouter() {
+}
+
+ExtensionBookmarkEventRouter::~ExtensionBookmarkEventRouter() {
+}
+
+void ExtensionBookmarkEventRouter::Observe(BookmarkModel* model) {
+ if (models_.find(model) == models_.end()) {
+ model->AddObserver(this);
+ models_.insert(model);
+ }
+}
+
+void ExtensionBookmarkEventRouter::DispatchEvent(Profile *profile,
+ const char* event_name,
+ const std::string json_args) {
+ ExtensionMessageService::GetInstance(profile->GetRequestContext())->
+ DispatchEventToRenderers(event_name, json_args);
+}
+
+void ExtensionBookmarkEventRouter::Loaded(BookmarkModel* model) {
+ // TODO(erikkay): Do we need an event here? It seems unlikely that
+ // an extension would load before bookmarks loaded.
+}
+
+void ExtensionBookmarkEventRouter::BookmarkNodeMoved(BookmarkModel* model,
+ BookmarkNode* old_parent,
+ int old_index,
+ BookmarkNode* new_parent,
+ int new_index) {
+ ListValue args;
+ DictionaryValue* object_args = new DictionaryValue();
+ BookmarkNode* node = new_parent->GetChild(new_index);
+ object_args->SetInteger(kIdKey, node->id());
+ object_args->SetInteger(kParentIdKey, new_parent->id());
+ object_args->SetInteger(kIndexKey, new_index);
+ object_args->SetInteger(kOldParentIdKey, old_parent->id());
+ object_args->SetInteger(kOldIndexKey, old_index);
+ args.Append(object_args);
+
+ std::string json_args;
+ JSONWriter::Write(&args, false, &json_args);
+ DispatchEvent(model->profile(), kOnBookmarkMoved, json_args);
+}
+
+void ExtensionBookmarkEventRouter::BookmarkNodeAdded(BookmarkModel* model,
+ BookmarkNode* parent,
+ int index) {
+ ListValue args;
+ DictionaryValue* object_args = new DictionaryValue();
+ BookmarkNode* node = parent->GetChild(index);
+ object_args->SetInteger(kIdKey, node->id());
+ object_args->SetString(kTitleKey, node->GetTitle());
+ object_args->SetString(kUrlKey, node->GetURL().spec());
+ object_args->SetInteger(kParentIdKey, parent->id());
+ object_args->SetInteger(kIndexKey, index);
+ args.Append(object_args);
+
+ std::string json_args;
+ JSONWriter::Write(&args, false, &json_args);
+ DispatchEvent(model->profile(), kOnBookmarkAdded, json_args);
+}
+
+void ExtensionBookmarkEventRouter::BookmarkNodeRemoved(BookmarkModel* model,
+ BookmarkNode* parent,
+ int index) {
+ ListValue args;
+ DictionaryValue* object_args = new DictionaryValue();
+ object_args->SetInteger(kParentIdKey, parent->id());
+ object_args->SetInteger(kIndexKey, index);
+ args.Append(object_args);
+
+ std::string json_args;
+ JSONWriter::Write(&args, false, &json_args);
+ DispatchEvent(model->profile(), kOnBookmarkRemoved, json_args);
+}
+
+void ExtensionBookmarkEventRouter::BookmarkNodeChanged(BookmarkModel* model,
+ BookmarkNode* node) {
+ ListValue args;
+ args.Append(new FundamentalValue(node->id()));
+
+ // TODO(erikkay) The only two things that BookmarkModel sends this
+ // notification for are title and favicon. Since we're currently ignoring
+ // favicon and since the notification doesn't say which one anyway, for now
+ // we only include title. The ideal thing would be to change BookmarkModel
+ // to indicate what changed.
+ DictionaryValue* object_args = new DictionaryValue();
+ object_args->SetString(kTitleKey, node->GetTitle());
+ args.Append(object_args);
+
+ std::string json_args;
+ JSONWriter::Write(&args, false, &json_args);
+ DispatchEvent(model->profile(), kOnBookmarkChanged, json_args);
+}
+
+void ExtensionBookmarkEventRouter::BookmarkNodeFavIconLoaded(
+ BookmarkModel* model, BookmarkNode* node) {
+ // TODO(erikkay) anything we should do here?
+}
+
+void ExtensionBookmarkEventRouter::BookmarkNodeChildrenReordered(
+ BookmarkModel* model, BookmarkNode* node) {
+ ListValue args;
+ args.Append(new FundamentalValue(node->id()));
+ int childCount = node->GetChildCount();
+ ListValue* children = new ListValue();
+ for (int i = 0; i < childCount; ++i) {
+ BookmarkNode* child = node->GetChild(i);
+ Value* child_id = new FundamentalValue(child->id());
+ children->Append(child_id);
+ }
+ args.Append(children);
+
+ std::string json_args;
+ JSONWriter::Write(&args, false, &json_args);
+ DispatchEvent(model->profile(), kOnBookmarkChildrenReordered, json_args);
+}
+
bool GetBookmarksFunction::RunImpl() {
// TODO(erikkay): the JSON schema doesn't support the TYPE_INTEGER
// variant yet.
@@ -127,6 +272,35 @@ bool GetBookmarksFunction::RunImpl() {
return true;
}
+bool GetBookmarkChildrenFunction::RunImpl() {
+ int id;
+ EXTENSION_FUNCTION_VALIDATE(args_->GetAsInteger(&id));
+ BookmarkModel* model = profile()->GetBookmarkModel();
+ scoped_ptr<ListValue> json(new ListValue());
+ BookmarkNode* node = model->GetNodeByID(id);
+ if (!node) {
+ error_ = kNoNodeError;
+ return false;
+ }
+ int child_count = node->GetChildCount();
+ for (int i = 0; i < child_count; ++i) {
+ BookmarkNode* child = node->GetChild(i);
+ ExtensionBookmarks::AddNode(child, json.get(), false);
+ }
+
+ result_.reset(json.release());
+ return true;
+}
+
+bool GetBookmarkTreeFunction::RunImpl() {
+ BookmarkModel* model = profile()->GetBookmarkModel();
+ scoped_ptr<ListValue> json(new ListValue());
+ BookmarkNode* node = model->root_node();
+ ExtensionBookmarks::AddNode(node, json.get(), true);
+ result_.reset(json.release());
+ return true;
+}
+
bool SearchBookmarksFunction::RunImpl() {
EXTENSION_FUNCTION_VALIDATE(args_->IsType(Value::TYPE_STRING));
@@ -322,4 +496,3 @@ bool SetBookmarkTitleFunction::RunImpl() {
model->SetTitle(node, title);
return true;
}
-
diff --git a/chrome/browser/extensions/extension_bookmarks_module.h b/chrome/browser/extensions/extension_bookmarks_module.h
index b7b38d8..def5440 100644
--- a/chrome/browser/extensions/extension_bookmarks_module.h
+++ b/chrome/browser/extensions/extension_bookmarks_module.h
@@ -2,34 +2,105 @@
// 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_BOOKMARKS_MODULE_H__
-#define CHROME_BROWSER_EXTENSIONS_EXTENSION_BOOKMARKS_MODULE_H__
+#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_BOOKMARKS_MODULE_H_
+#define CHROME_BROWSER_EXTENSIONS_EXTENSION_BOOKMARKS_MODULE_H_
+#include <string>
+#include <vector>
+
+#include "base/singleton.h"
+#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/extensions/extension_function.h"
-class GetBookmarksFunction : public SyncExtensionFunction {
+// Observes BookmarkModel and then routes the notifications as events to
+// the extension system.
+class ExtensionBookmarkEventRouter : public BookmarkModelObserver {
+ public:
+ static ExtensionBookmarkEventRouter* GetSingleton();
+ virtual ~ExtensionBookmarkEventRouter();
+
+ // Call this for each model to observe. Safe to call multiple times per
+ // model.
+ void Observe(BookmarkModel* model);
+
+ // BookmarkModelObserver
+ virtual void Loaded(BookmarkModel* model);
+ virtual void BookmarkModelBeingDeleted(BookmarkModel* model) { }
+ virtual void BookmarkNodeMoved(BookmarkModel* model,
+ BookmarkNode* old_parent,
+ int old_index,
+ BookmarkNode* new_parent,
+ int new_index);
+ virtual void BookmarkNodeAdded(BookmarkModel* model,
+ BookmarkNode* parent,
+ int index);
+ virtual void BookmarkNodeRemoved(BookmarkModel* model,
+ BookmarkNode* parent,
+ int index);
+ virtual void BookmarkNodeRemoved(BookmarkModel* model,
+ BookmarkNode* parent,
+ int old_index,
+ BookmarkNode* node) {
+ BookmarkNodeRemoved(model, parent, old_index);
+ }
+ virtual void BookmarkNodeChanged(BookmarkModel* model,
+ BookmarkNode* node);
+ virtual void BookmarkNodeFavIconLoaded(BookmarkModel* model,
+ BookmarkNode* node);
+ virtual void BookmarkNodeChildrenReordered(BookmarkModel* model,
+ BookmarkNode* node);
+
+ private:
+ ExtensionBookmarkEventRouter();
+ friend struct DefaultSingletonTraits<ExtensionBookmarkEventRouter>;
+
+ // Helper to actually dispatch an event to extension listeners.
+ void DispatchEvent(Profile* profile,
+ const char* event_name,
+ const std::string json_args);
+
+ // These are stored so that Observe can be called multiple times safely.
+ // This way the caller doesn't have to know whether it's already observing
+ // a particular model or not. The pointers are not owned by this object.
+ std::set<BookmarkModel*> models_;
+
+ DISALLOW_COPY_AND_ASSIGN(ExtensionBookmarkEventRouter);
+};
+
+class BookmarksFunction : public SyncExtensionFunction {
+ virtual void Run();
+};
+
+class GetBookmarksFunction : public BookmarksFunction {
+ virtual bool RunImpl();
+};
+
+class GetBookmarkChildrenFunction : public BookmarksFunction {
virtual bool RunImpl();
};
-class SearchBookmarksFunction : public SyncExtensionFunction {
+class GetBookmarkTreeFunction : public BookmarksFunction {
virtual bool RunImpl();
};
-class RemoveBookmarkFunction : public SyncExtensionFunction {
+class SearchBookmarksFunction : public BookmarksFunction {
virtual bool RunImpl();
};
-class CreateBookmarkFunction : public SyncExtensionFunction {
+class RemoveBookmarkFunction : public BookmarksFunction {
virtual bool RunImpl();
};
-class MoveBookmarkFunction : public SyncExtensionFunction {
+class CreateBookmarkFunction : public BookmarksFunction {
virtual bool RunImpl();
};
-class SetBookmarkTitleFunction : public SyncExtensionFunction {
+class MoveBookmarkFunction : public BookmarksFunction {
virtual bool RunImpl();
};
-#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_BOOKMARKS_MODULE_H__
+class SetBookmarkTitleFunction : public BookmarksFunction {
+ virtual bool RunImpl();
+};
+#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_BOOKMARKS_MODULE_H_
diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc
index 5ca347b..7e6099f 100644
--- a/chrome/browser/extensions/extension_function_dispatcher.cc
+++ b/chrome/browser/extensions/extension_function_dispatcher.cc
@@ -63,6 +63,10 @@ FactoryRegistry::FactoryRegistry() {
// Bookmarks
factories_["GetBookmarks"] = &NewExtensionFunction<GetBookmarksFunction>;
+ factories_["GetBookmarkChildren"] =
+ &NewExtensionFunction<GetBookmarkChildrenFunction>;
+ factories_["GetBookmarkTree"] =
+ &NewExtensionFunction<GetBookmarkTreeFunction>;
factories_["SearchBookmarks"] =
&NewExtensionFunction<SearchBookmarksFunction>;
factories_["RemoveBookmark"] = &NewExtensionFunction<RemoveBookmarkFunction>;