diff options
author | feldstein@chromium.org <feldstein@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-02 06:45:31 +0000 |
---|---|---|
committer | feldstein@chromium.org <feldstein@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-02 06:45:31 +0000 |
commit | 9b0718510886b13ee0ff6a2248285cbba2f08d1c (patch) | |
tree | 83295ada4204fd086a76ba869868b957214fac20 | |
parent | 4b6bcfac8cd147db4650b7a88f6bc1fe17342e5b (diff) | |
download | chromium_src-9b0718510886b13ee0ff6a2248285cbba2f08d1c.zip chromium_src-9b0718510886b13ee0ff6a2248285cbba2f08d1c.tar.gz chromium_src-9b0718510886b13ee0ff6a2248285cbba2f08d1c.tar.bz2 |
Add a folders_only and subtree api to bookmark manager
Adds a new API to the experimental.bookmarkManager namespace
getSubtree(id, foldersOnly, callback)
Which returns any subtree, and if foldersOnly is true, only returns the folders.
At this point, only the bookmark tree is using the new call.
BUG=39877
TEST=ExtensionBookmarksTest.*
Review URL: http://codereview.chromium.org/1611001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@43461 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/extensions/extension_bookmark_helpers.cc | 107 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_bookmark_helpers.h | 34 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_bookmark_manager_api.cc | 30 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_bookmark_manager_api.h | 10 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_bookmarks_module.cc | 107 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_bookmarks_unittest.cc | 80 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_function_dispatcher.cc | 1 | ||||
-rw-r--r-- | chrome/browser/resources/bookmark_manager/js/bmm/bookmarktree.js | 2 | ||||
-rwxr-xr-x | chrome/chrome_browser.gypi | 2 | ||||
-rw-r--r-- | chrome/chrome_tests.gypi | 1 | ||||
-rwxr-xr-x | chrome/common/extensions/api/extension_api.json | 25 |
11 files changed, 307 insertions, 92 deletions
diff --git a/chrome/browser/extensions/extension_bookmark_helpers.cc b/chrome/browser/extensions/extension_bookmark_helpers.cc new file mode 100644 index 0000000..f648a5e --- /dev/null +++ b/chrome/browser/extensions/extension_bookmark_helpers.cc @@ -0,0 +1,107 @@ +// Copyright (c) 2010 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_bookmark_helpers.h" + +#include "base/string_util.h" +#include "chrome/browser/extensions/extension_bookmarks_module_constants.h" + +namespace keys = extension_bookmarks_module_constants; + +// Helper functions. +namespace extension_bookmark_helpers { + +DictionaryValue* GetNodeDictionary(const BookmarkNode* node, + bool recurse, + bool only_folders) { + DictionaryValue* dict = new DictionaryValue(); + dict->SetString(keys::kIdKey, Int64ToString(node->id())); + + const BookmarkNode* parent = node->GetParent(); + if (parent) { + dict->SetString(keys::kParentIdKey, Int64ToString(parent->id())); + dict->SetInteger(keys::kIndexKey, parent->IndexOfChild(node)); + } + + if (!node->is_folder()) { + dict->SetString(keys::kUrlKey, node->GetURL().spec()); + } else { + // Javascript Date wants milliseconds since the epoch, ToDoubleT is + // seconds. + base::Time t = node->date_group_modified(); + if (!t.is_null()) + dict->SetReal(keys::kDateGroupModifiedKey, floor(t.ToDoubleT() * 1000)); + } + + dict->SetString(keys::kTitleKey, node->GetTitle()); + if (!node->date_added().is_null()) { + // Javascript Date wants milliseconds since the epoch, ToDoubleT is + // seconds. + dict->SetReal(keys::kDateAddedKey, + floor(node->date_added().ToDoubleT() * 1000)); + } + + if (recurse && node->is_folder()) { + int childCount = node->GetChildCount(); + ListValue* children = new ListValue(); + for (int i = 0; i < childCount; ++i) { + const BookmarkNode* child = node->GetChild(i); + if (!only_folders || child->is_folder()) { + DictionaryValue* dict = GetNodeDictionary(child, true, only_folders); + children->Append(dict); + } + } + dict->Set(keys::kChildrenKey, children); + } + return dict; +} + +void AddNode(const BookmarkNode* node, + ListValue* list, + bool recurse, + bool only_folders) { + DictionaryValue* dict = GetNodeDictionary(node, recurse, only_folders); + list->Append(dict); +} + +// Add a JSON representation of |node| to the JSON |list|. +void AddNode(const BookmarkNode* node, + ListValue* list, + bool recurse) { + return AddNode(node, list, recurse, false); +} + +void AddNodeFoldersOnly(const BookmarkNode* node, + ListValue* list, + bool recurse) { + return AddNode(node, list, recurse, true); +} + +bool RemoveNode(BookmarkModel* model, + int64 id, + bool recursive, + std::string* error) { + const BookmarkNode* node = model->GetNodeByID(id); + if (!node) { + *error = keys::kNoNodeError; + return false; + } + if (node == model->root_node() || + node == model->other_node() || + node == model->GetBookmarkBarNode()) { + *error = keys::kModifySpecialError; + return false; + } + if (node->is_folder() && node->GetChildCount() > 0 && !recursive) { + *error = keys::kFolderNotEmptyError; + return false; + } + + const BookmarkNode* parent = node->GetParent(); + int index = parent->IndexOfChild(node); + model->Remove(parent, index); + return true; +} + +} diff --git a/chrome/browser/extensions/extension_bookmark_helpers.h b/chrome/browser/extensions/extension_bookmark_helpers.h new file mode 100644 index 0000000..f58db22 --- /dev/null +++ b/chrome/browser/extensions/extension_bookmark_helpers.h @@ -0,0 +1,34 @@ +// Copyright (c) 2010 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_BOOKMARK_HELPERS_H_ +#define CHROME_BROWSER_EXTENSIONS_EXTENSION_BOOKMARK_HELPERS_H_ + +#include "base/values.h" +#include "chrome/browser/bookmarks/bookmark_model.h" + +// Helper functions. +namespace extension_bookmark_helpers { + +DictionaryValue* GetNodeDictionary(const BookmarkNode* node, + bool recurse, + bool only_folders); + +// Add a JSON representation of |node| to the JSON |list|. +void AddNode(const BookmarkNode* node, + ListValue* list, + bool recurse); + +void AddNodeFoldersOnly(const BookmarkNode* node, + ListValue* list, + bool recurse); + +bool RemoveNode(BookmarkModel* model, + int64 id, + bool recursive, + std::string* error); + +} + +#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_BOOKMARKS_HELPERS_H_ diff --git a/chrome/browser/extensions/extension_bookmark_manager_api.cc b/chrome/browser/extensions/extension_bookmark_manager_api.cc index def7eeb..d057731 100644 --- a/chrome/browser/extensions/extension_bookmark_manager_api.cc +++ b/chrome/browser/extensions/extension_bookmark_manager_api.cc @@ -14,6 +14,7 @@ #include "chrome/browser/bookmarks/bookmark_model.h" #include "chrome/browser/bookmarks/bookmark_utils.h" #include "chrome/browser/dom_ui/chrome_url_data_manager.h" +#include "chrome/browser/extensions/extension_bookmark_helpers.h" #include "chrome/browser/extensions/extension_bookmarks_module_constants.h" #include "chrome/browser/extensions/extension_dom_ui.h" #include "chrome/browser/extensions/extension_message_service.h" @@ -398,3 +399,32 @@ bool DropBookmarkManagerFunction::RunImpl() { return false; } } + +bool GetSubtreeBookmarkManagerFunction::RunImpl() { + BookmarkModel* model = profile()->GetBookmarkModel(); + const BookmarkNode* node; + int64 id; + std::string id_string; + EXTENSION_FUNCTION_VALIDATE(args_as_list()->GetString(0, &id_string)); + bool folders_only; + EXTENSION_FUNCTION_VALIDATE(args_as_list()->GetBoolean(1, &folders_only)); + if (id_string == "") { + node = model->root_node(); + } else { + if (!StringToInt64(id_string, &id)) { + error_ = keys::kInvalidIdError; + return false; + } + node = model->GetNodeByID(id); + } + scoped_ptr<ListValue> json(new ListValue()); + if (folders_only) { + extension_bookmark_helpers::AddNodeFoldersOnly(node, + json.get(), + true); + } else { + extension_bookmark_helpers::AddNode(node, json.get(), true); + } + result_.reset(json.release()); + return true; +} diff --git a/chrome/browser/extensions/extension_bookmark_manager_api.h b/chrome/browser/extensions/extension_bookmark_manager_api.h index 5baad91..ace9124 100644 --- a/chrome/browser/extensions/extension_bookmark_manager_api.h +++ b/chrome/browser/extensions/extension_bookmark_manager_api.h @@ -130,4 +130,14 @@ class DropBookmarkManagerFunction : public BookmarksFunction { DECLARE_EXTENSION_FUNCTION_NAME("experimental.bookmarkManager.drop"); }; + +class GetSubtreeBookmarkManagerFunction : public BookmarksFunction { + public: + // Override BookmarksFunction + virtual bool RunImpl(); + + private: + DECLARE_EXTENSION_FUNCTION_NAME("experimental.bookmarkManager.getSubtree"); +}; + #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_BOOKMARK_MANAGER_API_H_ diff --git a/chrome/browser/extensions/extension_bookmarks_module.cc b/chrome/browser/extensions/extension_bookmarks_module.cc index 2d09ef9..6a8cd08 100644 --- a/chrome/browser/extensions/extension_bookmarks_module.cc +++ b/chrome/browser/extensions/extension_bookmarks_module.cc @@ -13,6 +13,7 @@ #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_bookmark_helpers.h" #include "chrome/browser/extensions/extension_bookmarks_module_constants.h" #include "chrome/browser/extensions/extension_message_service.h" #include "chrome/browser/extensions/extensions_quota_service.h" @@ -33,86 +34,6 @@ typedef ExtensionsQuotaService::TimedLimit TimedLimit; typedef ExtensionsQuotaService::SustainedLimit SustainedLimit; typedef QuotaLimitHeuristic::BucketMapper BucketMapper; -// Helper functions. -class ExtensionBookmarks { - public: - // Convert |node| into a JSON value. - static DictionaryValue* GetNodeDictionary(const BookmarkNode* node, - bool recurse) { - DictionaryValue* dict = new DictionaryValue(); - dict->SetString(keys::kIdKey, Int64ToString(node->id())); - - const BookmarkNode* parent = node->GetParent(); - if (parent) { - dict->SetString(keys::kParentIdKey, Int64ToString(parent->id())); - dict->SetInteger(keys::kIndexKey, parent->IndexOfChild(node)); - } - - if (!node->is_folder()) { - dict->SetString(keys::kUrlKey, node->GetURL().spec()); - } else { - // Javascript Date wants milliseconds since the epoch, ToDoubleT is - // seconds. - base::Time t = node->date_group_modified(); - if (!t.is_null()) - dict->SetReal(keys::kDateGroupModifiedKey, floor(t.ToDoubleT() * 1000)); - } - - dict->SetString(keys::kTitleKey, node->GetTitle()); - if (!node->date_added().is_null()) { - // Javascript Date wants milliseconds since the epoch, ToDoubleT is - // seconds. - dict->SetReal(keys::kDateAddedKey, - floor(node->date_added().ToDoubleT() * 1000)); - } - - if (recurse && node->is_folder()) { - int childCount = node->GetChildCount(); - ListValue* children = new ListValue(); - for (int i = 0; i < childCount; ++i) { - const BookmarkNode* child = node->GetChild(i); - DictionaryValue* dict = GetNodeDictionary(child, true); - children->Append(dict); - } - dict->Set(keys::kChildrenKey, children); - } - return dict; - } - - // Add a JSON representation of |node| to the JSON |list|. - static void AddNode(const BookmarkNode* node, ListValue* list, bool recurse) { - DictionaryValue* dict = GetNodeDictionary(node, recurse); - list->Append(dict); - } - - static bool RemoveNode(BookmarkModel* model, int64 id, bool recursive, - std::string* error) { - const BookmarkNode* node = model->GetNodeByID(id); - if (!node) { - *error = keys::kNoNodeError; - return false; - } - if (node == model->root_node() || - node == model->other_node() || - node == model->GetBookmarkBarNode()) { - *error = keys::kModifySpecialError; - return false; - } - if (node->is_folder() && node->GetChildCount() > 0 && !recursive) { - *error = keys::kFolderNotEmptyError; - return false; - } - - const BookmarkNode* parent = node->GetParent(); - int index = parent->IndexOfChild(node); - model->Remove(parent, index); - return true; - } - - private: - ExtensionBookmarks(); -}; - void BookmarksFunction::Run() { BookmarkModel* model = profile()->GetBookmarkModel(); if (!model->IsLoaded()) { @@ -211,7 +132,8 @@ void ExtensionBookmarkEventRouter::BookmarkNodeAdded(BookmarkModel* model, ListValue args; const BookmarkNode* node = parent->GetChild(index); args.Append(new StringValue(Int64ToString(node->id()))); - DictionaryValue* obj = ExtensionBookmarks::GetNodeDictionary(node, false); + DictionaryValue* obj = + extension_bookmark_helpers::GetNodeDictionary(node, false, false); args.Append(obj); std::string json_args; @@ -321,7 +243,7 @@ bool GetBookmarksFunction::RunImpl() { error_ = keys::kNoNodeError; return false; } else { - ExtensionBookmarks::AddNode(node, json.get(), false); + extension_bookmark_helpers::AddNode(node, json.get(), false); } } } else { @@ -335,7 +257,7 @@ bool GetBookmarksFunction::RunImpl() { error_ = keys::kNoNodeError; return false; } - ExtensionBookmarks::AddNode(node, json.get(), false); + extension_bookmark_helpers::AddNode(node, json.get(), false); } result_.reset(json.release()); @@ -358,7 +280,7 @@ bool GetBookmarkChildrenFunction::RunImpl() { int child_count = node->GetChildCount(); for (int i = 0; i < child_count; ++i) { const BookmarkNode* child = node->GetChild(i); - ExtensionBookmarks::AddNode(child, json.get(), false); + extension_bookmark_helpers::AddNode(child, json.get(), false); } result_.reset(json.release()); @@ -379,7 +301,7 @@ bool GetBookmarkRecentFunction::RunImpl() { std::vector<const BookmarkNode*>::iterator i = nodes.begin(); for (; i != nodes.end(); ++i) { const BookmarkNode* node = *i; - ExtensionBookmarks::AddNode(node, json, false); + extension_bookmark_helpers::AddNode(node, json, false); } result_.reset(json); return true; @@ -389,7 +311,7 @@ bool GetBookmarkTreeFunction::RunImpl() { BookmarkModel* model = profile()->GetBookmarkModel(); scoped_ptr<ListValue> json(new ListValue()); const BookmarkNode* node = model->root_node(); - ExtensionBookmarks::AddNode(node, json.get(), true); + extension_bookmark_helpers::AddNode(node, json.get(), true); result_.reset(json.release()); return true; } @@ -410,7 +332,7 @@ bool SearchBookmarksFunction::RunImpl() { std::vector<const BookmarkNode*>::iterator i = nodes.begin(); for (; i != nodes.end(); ++i) { const BookmarkNode* node = *i; - ExtensionBookmarks::AddNode(node, json, false); + extension_bookmark_helpers::AddNode(node, json, false); } result_.reset(json); @@ -466,7 +388,7 @@ bool RemoveBookmarkFunction::RunImpl() { size_t count = ids.size(); EXTENSION_FUNCTION_VALIDATE(count > 0); for (std::list<int64>::iterator it = ids.begin(); it != ids.end(); ++it) { - if (!ExtensionBookmarks::RemoveNode(model, *it, recursive, &error_)) + if (!extension_bookmark_helpers::RemoveNode(model, *it, recursive, &error_)) return false; } return true; @@ -530,7 +452,8 @@ bool CreateBookmarkFunction::RunImpl() { return false; } - DictionaryValue* ret = ExtensionBookmarks::GetNodeDictionary(node, false); + DictionaryValue* ret = + extension_bookmark_helpers::GetNodeDictionary(node, false, false); result_.reset(ret); return true; @@ -609,7 +532,8 @@ bool MoveBookmarkFunction::RunImpl() { model->Move(node, parent, index); - DictionaryValue* ret = ExtensionBookmarks::GetNodeDictionary(node, false); + DictionaryValue* ret = + extension_bookmark_helpers::GetNodeDictionary(node, false, false); result_.reset(ret); return true; @@ -680,7 +604,8 @@ bool UpdateBookmarkFunction::RunImpl() { if (!url.is_empty()) model->SetURL(node, url); - DictionaryValue* ret = ExtensionBookmarks::GetNodeDictionary(node, false); + DictionaryValue* ret = + extension_bookmark_helpers::GetNodeDictionary(node, false, false); result_.reset(ret); return true; diff --git a/chrome/browser/extensions/extension_bookmarks_unittest.cc b/chrome/browser/extensions/extension_bookmarks_unittest.cc new file mode 100644 index 0000000..4b1070e --- /dev/null +++ b/chrome/browser/extensions/extension_bookmarks_unittest.cc @@ -0,0 +1,80 @@ +// Copyright (c) 2010 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 "testing/gtest/include/gtest/gtest.h" + +#include "base/values.h" +#include "chrome/browser/bookmarks/bookmark_model.h" +#include "chrome/browser/extensions/extension_bookmark_helpers.h" +#include "chrome/browser/extensions/extension_bookmarks_module_constants.h" +namespace keys = extension_bookmarks_module_constants; + +class ExtensionBookmarksTest : public testing::Test { + public: + virtual void SetUp() { + model_.reset(new BookmarkModel(NULL)); + model_->AddURL(model_->other_node(), 0, L"Digg", + GURL("http://www.reddit.com")); + model_->AddURL(model_->other_node(), 0, L"News", + GURL("http://www.foxnews.com")); + folder = + model_->AddGroup(model_->other_node(), 0, L"outer folder"); + model_->AddGroup(folder, 0, L"inner folder 1"); + model_->AddGroup(folder, 0, L"inner folder 2"); + model_->AddURL(folder, 0, L"Digg", GURL("http://reddit.com")); + model_->AddURL(folder, 0, L"CNet", GURL("http://cnet.com")); + } + + scoped_ptr<BookmarkModel> model_; + const BookmarkNode* folder; +}; +TEST_F(ExtensionBookmarksTest, GetFullTreeFromRoot) { + DictionaryValue* tree = + extension_bookmark_helpers::GetNodeDictionary(model_->other_node(), + true, // recurse + false); // not only folders + ListValue* children; + tree->GetList(keys::kChildrenKey, &children); + ASSERT_EQ(3U, children->GetSize()); +} + +TEST_F(ExtensionBookmarksTest, GetFoldersOnlyFromRoot) { + DictionaryValue* tree = + extension_bookmark_helpers::GetNodeDictionary(model_->other_node(), + true, // recurse + true); // only folders + ListValue* children; + tree->GetList(keys::kChildrenKey, &children); + ASSERT_EQ(1U, children->GetSize()); +} + +TEST_F(ExtensionBookmarksTest, GetSubtree) { + DictionaryValue* tree = + extension_bookmark_helpers::GetNodeDictionary(folder, + true, // recurse + false); // not only folders + ListValue* children; + tree->GetList(keys::kChildrenKey, &children); + ASSERT_EQ(4U, children->GetSize()); + DictionaryValue* digg; + children->GetDictionary(1,&digg); + std::string title; + digg->GetString(keys::kTitleKey, &title); + ASSERT_EQ("Digg", title); +} + +TEST_F(ExtensionBookmarksTest, GetSubtreeFoldersOnly) { + DictionaryValue* tree = + extension_bookmark_helpers::GetNodeDictionary(folder, + true, // recurse + true); // only folders + ListValue* children; + tree->GetList(keys::kChildrenKey, &children); + ASSERT_EQ(2U, children->GetSize()); + DictionaryValue* inner_folder; + children->GetDictionary(1,&inner_folder); + std::string title; + inner_folder->GetString(keys::kTitleKey, &title); + ASSERT_EQ("inner folder 1", title); +} diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc index 03889ee..78a2c032 100644 --- a/chrome/browser/extensions/extension_function_dispatcher.cc +++ b/chrome/browser/extensions/extension_function_dispatcher.cc @@ -156,6 +156,7 @@ void FactoryRegistry::ResetFunctions() { RegisterFunction<BookmarkManagerGetStringsFunction>(); RegisterFunction<StartDragBookmarkManagerFunction>(); RegisterFunction<DropBookmarkManagerFunction>(); + RegisterFunction<GetSubtreeBookmarkManagerFunction>(); // History RegisterFunction<AddUrlHistoryFunction>(); diff --git a/chrome/browser/resources/bookmark_manager/js/bmm/bookmarktree.js b/chrome/browser/resources/bookmark_manager/js/bmm/bookmarktree.js index 8acfa28..42e0a10 100644 --- a/chrome/browser/resources/bookmark_manager/js/bmm/bookmarktree.js +++ b/chrome/browser/resources/bookmark_manager/js/bmm/bookmarktree.js @@ -174,7 +174,7 @@ cr.define('bmm', function() { } var self = this; - chrome.bookmarks.getTree(function(root) { + chrome.experimental.bookmarkManager.getSubtree('', true, function(root) { buildTreeItems(self, root[0].children); cr.dispatchSimpleEvent(self, 'load'); }); diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index cc5111a..b748432 100755 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -931,6 +931,8 @@ 'browser/extensions/extension_accessibility_api.h', 'browser/extensions/extension_accessibility_api_constants.cc', 'browser/extensions/extension_accessibility_api_constants.h', + 'browser/extensions/extension_bookmark_helpers.cc', + 'browser/extensions/extension_bookmark_helpers.h', 'browser/extensions/extension_bookmarks_module.cc', 'browser/extensions/extension_bookmarks_module.h', 'browser/extensions/extension_bookmarks_module_constants.cc', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index cf435b1..a51d76e 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1231,6 +1231,7 @@ 'browser/extensions/extension_apitest.cc', 'browser/extensions/extension_apitest.h', 'browser/extensions/extension_bookmarks_apitest.cc', + 'browser/extensions/extension_bookmarks_unittest.cc', 'browser/extensions/extension_bookmark_manager_apitest.cc', 'browser/extensions/extension_browsertest.cc', 'browser/extensions/extension_browsertest.h', diff --git a/chrome/common/extensions/api/extension_api.json b/chrome/common/extensions/api/extension_api.json index f9a8b3b..b554298 100755 --- a/chrome/common/extensions/api/extension_api.json +++ b/chrome/common/extensions/api/extension_api.json @@ -2285,6 +2285,31 @@ "optional": true } ] + }, + { + "name": "getSubtree", + "type": "function", + "description": "Retrieves a bookmark hierarchy from the given node. If the node id is empty, it is the full tree. If foldersOnly is true, it will only return folders, not actual bookmarks.", + "nodoc": "true", + "parameters": [ + { + "name": "id", + "type": "string", + "description": "ID of the root of the tree to pull. If empty, the entire tree will be returned." + }, + { + "name": "foldersOnly", + "type": "boolean", + "description": "Pass true to only return folders." + }, + { + "name": "callback", + "type": "function", + "parameters": [ + {"name": "results", "type": "array", "items": { "$ref": "BookmarkTreeNode"} } + ] + } + ] } ], "events": [ |