diff options
author | erikkay@google.com <erikkay@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-04-29 20:28:46 +0000 |
---|---|---|
committer | erikkay@google.com <erikkay@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-04-29 20:28:46 +0000 |
commit | 309934c4ceea5086567f275cef17bbfefa29996b (patch) | |
tree | d8efe2e9b30e10d67bdacc8c0f4f28614a4a2eb3 /chrome/browser/extensions | |
parent | 36fe18f709825bc199f5eca66463a832e09638c5 (diff) | |
download | chromium_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')
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>; |