diff options
6 files changed, 196 insertions, 26 deletions
diff --git a/chrome/browser/extensions/extension_bookmark_manager_api.cc b/chrome/browser/extensions/extension_bookmark_manager_api.cc index a6b3e08..11fd56d 100644 --- a/chrome/browser/extensions/extension_bookmark_manager_api.cc +++ b/chrome/browser/extensions/extension_bookmark_manager_api.cc @@ -6,28 +6,78 @@ #include "app/l10n_util.h" #include "base/values.h" -#include "grit/generated_resources.h" -#include "chrome/browser/profile.h" +#include "chrome/browser/bookmarks/bookmark_model.h" #include "chrome/browser/bookmarks/bookmark_html_writer.h" +#include "chrome/browser/bookmarks/bookmark_utils.h" +#include "chrome/browser/extensions/extension_bookmarks_module_constants.h" #include "chrome/browser/importer/importer.h" +#include "chrome/browser/profile.h" +#include "grit/generated_resources.h" + +namespace keys = extension_bookmarks_module_constants; + +bool ClipboardBookmarkManagerFunction::CopyOrCut(bool cut) { + EXTENSION_FUNCTION_VALIDATE(args_->IsType(Value::TYPE_LIST)); + const ListValue* ids = args_as_list(); + size_t count = ids->GetSize(); + EXTENSION_FUNCTION_VALIDATE(count > 0); + + BookmarkModel* model = profile()->GetBookmarkModel(); + std::vector<const BookmarkNode*> nodes; + + for (size_t i = 0; i < count; ++i) { + int64 id; + std::string id_string; + EXTENSION_FUNCTION_VALIDATE(ids->GetString(i, &id_string)); + if (!GetBookmarkIdAsInt64(id_string, &id)) + return false; + const BookmarkNode* node = model->GetNodeByID(id); + if (!node) { + error_ = keys::kNoNodeError; + return false; + } else { + nodes.push_back(node); + } + } + + bookmark_utils::CopyToClipboard(model, nodes, cut); -bool CopyBookmarkManagerFunction::RunImpl() { - NOTIMPLEMENTED(); return true; } +const BookmarkNode* ClipboardBookmarkManagerFunction::GetNodeFromArguments() { + std::string id_string; + EXTENSION_FUNCTION_VALIDATE(args_->GetAsString(&id_string)); + int64 id; + EXTENSION_FUNCTION_VALIDATE(StringToInt64(id_string, &id)); + BookmarkModel* model = profile()->GetBookmarkModel(); + const BookmarkNode* node = model->GetNodeByID(id); + EXTENSION_FUNCTION_VALIDATE(node); + return node; +} -bool CutBookmarkManagerFunction::RunImpl() { - NOTIMPLEMENTED(); - return true; +bool CopyBookmarkManagerFunction::RunImpl() { + return CopyOrCut(false); } +bool CutBookmarkManagerFunction::RunImpl() { + return CopyOrCut(true); +} bool PasteBookmarkManagerFunction::RunImpl() { - NOTIMPLEMENTED(); + BookmarkModel* model = profile()->GetBookmarkModel(); + const BookmarkNode* parent_node = GetNodeFromArguments(); + bookmark_utils::PasteFromClipboard(model, parent_node, -1); return true; } +bool CanPasteBookmarkManagerFunction::RunImpl() { + const BookmarkNode* parent_node = GetNodeFromArguments(); + bool can_paste = bookmark_utils::CanPasteFromClipboard(parent_node); + result_.reset(Value::CreateBooleanValue(can_paste)); + SendResponse(true); + return true; +} void BookmarkManagerIOFunction::SelectFile(SelectFileDialog::Type type) { // Balanced in one of the three callbacks of SelectFileDialog: // either FileSelectionCanceled, MultiFilesSelected, or FileSelected diff --git a/chrome/browser/extensions/extension_bookmark_manager_api.h b/chrome/browser/extensions/extension_bookmark_manager_api.h index f0bf1a3..72f1bf0 100644 --- a/chrome/browser/extensions/extension_bookmark_manager_api.h +++ b/chrome/browser/extensions/extension_bookmark_manager_api.h @@ -5,39 +5,58 @@ #ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_BOOKMARK_MANAGER_API_H_ #define CHROME_BROWSER_EXTENSIONS_EXTENSION_BOOKMARK_MANAGER_API_H_ +#include "chrome/browser/extensions/extension_bookmarks_module.h" #include "chrome/browser/extensions/extension_function.h" #include "chrome/browser/shell_dialogs.h" -#include "chrome/browser/extensions/extension_bookmarks_module.h" -class CopyBookmarkManagerFunction : public AsyncExtensionFunction { +class BookmarkNode; + +class ClipboardBookmarkManagerFunction : public BookmarksFunction { + protected: + bool CopyOrCut(bool cut); + // Returns a single bookmark node from the ID passed as the first argument. + const BookmarkNode* GetNodeFromArguments(); +}; + +class CopyBookmarkManagerFunction : public ClipboardBookmarkManagerFunction { public: - // Override BookmarkManagerFunction. + // Override ClipboardBookmarkManagerFunction. virtual bool RunImpl(); private: DECLARE_EXTENSION_FUNCTION_NAME("experimental.bookmarkManager.copy"); }; -class CutBookmarkManagerFunction : public AsyncExtensionFunction { +class CutBookmarkManagerFunction : public ClipboardBookmarkManagerFunction { public: - // Override BookmarkManagerFunction. + // Override ClipboardBookmarkManagerFunction. virtual bool RunImpl(); private: DECLARE_EXTENSION_FUNCTION_NAME("experimental.bookmarkManager.cut"); }; -class PasteBookmarkManagerFunction : public AsyncExtensionFunction { +class PasteBookmarkManagerFunction : public ClipboardBookmarkManagerFunction { public: - // Override BookmarkManagerFunction. + // Override ClipboardBookmarkManagerFunction. virtual bool RunImpl(); private: DECLARE_EXTENSION_FUNCTION_NAME("experimental.bookmarkManager.paste"); }; +class CanPasteBookmarkManagerFunction + : public ClipboardBookmarkManagerFunction { + public: + // Override ClipboardBookmarkManagerFunction. + virtual bool RunImpl(); + + private: + DECLARE_EXTENSION_FUNCTION_NAME("experimental.bookmarkManager.canPaste"); +}; + class BookmarkManagerIOFunction : public BookmarksFunction, - public SelectFileDialog::Listener { + public SelectFileDialog::Listener { public: // Overridden from SelectFileDialog::Listener: virtual void FileSelected(const FilePath& path, int index, void* params) = 0; @@ -51,7 +70,7 @@ class BookmarkManagerIOFunction : public BookmarksFunction, class ImportBookmarksFunction : public BookmarkManagerIOFunction { public: - // Override BookmarkManagerFunction. + // Override BookmarkManagerIOFunction. bool RunImpl(); void FileSelected(const FilePath& path, int index, void* params); @@ -61,7 +80,7 @@ class ImportBookmarksFunction : public BookmarkManagerIOFunction { class ExportBookmarksFunction : public BookmarkManagerIOFunction { public: - // Override BookmarkManagerFunction. + // Override BookmarkManagerIOFunction. bool RunImpl(); void FileSelected(const FilePath& path, int index, void* params); @@ -71,7 +90,7 @@ class ExportBookmarksFunction : public BookmarkManagerIOFunction { class BookmarkManagerGetStringsFunction : public AsyncExtensionFunction { public: - // Override BookmarkManagerFunction. + // Override AsyncExtensionFunction. virtual bool RunImpl(); private: diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc index ba85956..bdba709 100644 --- a/chrome/browser/extensions/extension_function_dispatcher.cc +++ b/chrome/browser/extensions/extension_function_dispatcher.cc @@ -138,6 +138,7 @@ void FactoryRegistry::ResetFunctions() { RegisterFunction<CopyBookmarkManagerFunction>(); RegisterFunction<CutBookmarkManagerFunction>(); RegisterFunction<PasteBookmarkManagerFunction>(); + RegisterFunction<CanPasteBookmarkManagerFunction>(); RegisterFunction<ImportBookmarksFunction>(); RegisterFunction<ExportBookmarksFunction>(); RegisterFunction<BookmarkManagerGetStringsFunction>(); diff --git a/chrome/common/extensions/api/extension_api.json b/chrome/common/extensions/api/extension_api.json index ab9de52..0b3f764 100755 --- a/chrome/common/extensions/api/extension_api.json +++ b/chrome/common/extensions/api/extension_api.json @@ -1794,6 +1794,18 @@ ] }, { + "name": "canPaste", + "type": "function", + "description": "Whether there are any bookmarks that can be pasted", + "nodoc": "true", + "parameters": [ + {"type": "string", "name": "parentId", "description": "The ID of the folder to paste into"}, + {"type": "function", "name": "callback", "parameters": [ + {"type": "boolean"} + ]} + ] + }, + { "name": "import", "type": "function", "description": "Imports bookmarks from a chrome html bookmark file", diff --git a/chrome/test/data/extensions/api_test/bookmark_manager/manifest.json b/chrome/test/data/extensions/api_test/bookmark_manager/manifest.json index 6625282..ce4e407 100644 --- a/chrome/test/data/extensions/api_test/bookmark_manager/manifest.json +++ b/chrome/test/data/extensions/api_test/bookmark_manager/manifest.json @@ -3,5 +3,5 @@ "version": "0.1", "description": "end-to-end browser test for chrome.experimental.bookmarkManager API", "background_page": "test.html", - "permissions": ["experimental"] + "permissions": ["bookmarks", "experimental"] } diff --git a/chrome/test/data/extensions/api_test/bookmark_manager/test.js b/chrome/test/data/extensions/api_test/bookmark_manager/test.js index 33f928d..e0f596e 100644 --- a/chrome/test/data/extensions/api_test/bookmark_manager/test.js +++ b/chrome/test/data/extensions/api_test/bookmark_manager/test.js @@ -1,15 +1,103 @@ // Bookmark Manager API test for Chrome. // browser_tests.exe --gtest_filter=ExtensionApiTest.BookmarkManager -var pass = chrome.test.callbackPass; -var fail = chrome.test.callbackFail; -var assertEq = chrome.test.assertEq; +const pass = chrome.test.callbackPass; +const fail = chrome.test.callbackFail; +const assertEq = chrome.test.assertEq; +const assertTrue = chrome.test.assertTrue; +const bookmarks = chrome.bookmarks; +const bookmarkManager = chrome.experimental.bookmarkManager; +const MAC = /Mac/.test(navigator.platform); +var node, node2, count; -chrome.test.runTests([ +var tests = [ function getStrings() { - chrome.experimental.bookmarkManager.getStrings(pass(function(strings) { + bookmarkManager.getStrings(pass(function(strings) { assertEq('string', typeof strings['title']); assertEq('string', typeof strings['search_button']); })); } -]); +]; + +// Mac does not yet support the clipboard API. +if (!MAC) { + tests.push( + + // The clipboard test is split into different parts to allow asynchronous + // operations to finish. + function clipboard() { + // Create a new bookmark. + node = { + parentId: '1', + title: 'Foo', + url: 'http://www.example.com/foo' + }; + + bookmarks.create(node, pass(function(result) { + node.id = result.id; + node.index = result.index; + count = result.index + 1; + })); + }, + + function clipboard2() { + // Copy it. + bookmarkManager.copy([node.id]); + + // Ensure canPaste is now true. + bookmarkManager.canPaste('1', pass(function(result) { + assertTrue(result, 'Should be able to paste now'); + })); + + // Paste it. + bookmarkManager.paste('1'); + + // Ensure it got added. + bookmarks.getChildren('1', pass(function(result) { + count++; + assertEq(count, result.length); + + node2 = result[result.length - 1]; + + assertEq(node.title, node2.title); + assertEq(node.url, node2.url); + assertEq(node.parentId, node2.parentId); + })); + }, + + function clipboard3() { + // Cut this and the previous bookmark. + bookmarkManager.cut([node.id, node2.id]); + + // Ensure count decreased by 2. + bookmarks.getChildren('1', pass(function(result) { + count -= 2; + assertEq(count, result.length); + })); + + // Ensure canPaste is still true. + bookmarkManager.canPaste('1', pass(function(result) { + assertTrue(result, 'Should be able to paste now'); + })); + }, + + function clipboard4() { + // Paste. + bookmarkManager.paste('1'); + + // Check the last two bookmarks. + bookmarks.getChildren('1', pass(function(result) { + count += 2; + assertEq(count, result.length); + + var last = result[result.length - 2]; + var last2 = result[result.length - 1]; + assertEq(last.title, last2.title); + assertEq(last.url, last2.url); + assertEq(last.parentId, last2.parentId); + })); + } + ); +} + +chrome.test.runTests(tests); |