1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 cr
.define('bmm', function() {
7 * Whether a node contains another node.
8 * TODO(yosin): Once JavaScript style guide is updated and linter follows
9 * that, we'll remove useless documentations for |parent| and |descendant|.
10 * TODO(yosin): bmm.contains() should be method of BookmarkTreeNode.
11 * @param {!BookmarkTreeNode} parent .
12 * @param {!BookmarkTreeNode} descendant .
13 * @return {boolean} Whether the parent contains the descendant.
15 function contains(parent
, descendant
) {
16 if (descendant
.parentId
== parent
.id
)
18 // the bmm.treeLookup contains all folders
19 var parentTreeItem
= bmm
.treeLookup
[descendant
.parentId
];
20 if (!parentTreeItem
|| !parentTreeItem
.bookmarkNode
)
22 return this.contains(parent
, parentTreeItem
.bookmarkNode
);
26 * @param {!BookmarkTreeNode} node The node to test.
27 * @return {boolean} Whether a bookmark node is a folder.
29 function isFolder(node
) {
30 return !('url' in node
);
33 var loadingPromises
= {};
36 * Promise version of chrome.bookmarkManagerPrivate.getSubtree.
37 * @param {string} id .
38 * @param {boolean} foldersOnly .
39 * @return {!Promise.<!Array.<!BookmarkTreeNode>>} .
41 function getSubtreePromise(id
, foldersOnly
) {
42 return new Promise(function(resolve
) {
43 chrome
.bookmarkManagerPrivate
.getSubtree(id
, foldersOnly
, resolve
);
48 * Loads a subtree of the bookmark tree and returns a {@code Promise} that
49 * will be fulfilled when done. This reuses multiple loads so that we do not
50 * load the same subtree more than once at the same time.
51 * @return {!Promise.<!BookmarkTreeNode>} The future promise for the load.
53 function loadSubtree(id
) {
54 if (!loadingPromises
[id
]) {
55 loadingPromises
[id
] = getSubtreePromise(id
, false).then(function(nodes
) {
56 delete loadingPromises
[id
];
57 return nodes
&& nodes
[0];
60 return loadingPromises
[id
];
64 * Loads the entire bookmark tree and returns a {@code Promise} that will
65 * be fulfilled when done. This reuses multiple loads so that we do not load
66 * the same tree more than once at the same time.
67 * @return {!Promise.<Node>} The future promise for the load.
70 return loadSubtree('');
75 * Removes the cached item from both the list and tree lookups.
77 remove: function(id
) {
78 var treeItem
= bmm
.treeLookup
[id
];
80 var items
= treeItem
.items
; // is an HTMLCollection
81 for (var i
= 0; i
< items
.length
; ++i
) {
83 var bookmarkNode
= item
.bookmarkNode
;
84 delete bmm
.treeLookup
[bookmarkNode
.id
];
86 delete bmm
.treeLookup
[id
];
91 * Updates the underlying bookmark node for the tree items and list items by
92 * querying the bookmark backend.
93 * @param {string} id The id of the node to update the children for.
94 * @param {Function=} opt_f A funciton to call when done.
96 updateChildren: function(id
, opt_f
) {
97 function updateItem(bookmarkNode
) {
98 var treeItem
= bmm
.treeLookup
[bookmarkNode
.id
];
100 treeItem
.bookmarkNode
= bookmarkNode
;
104 chrome
.bookmarks
.getChildren(id
, function(children
) {
106 children
.forEach(updateItem
);
115 * Called when the title of a bookmark changes.
116 * @param {string} id The id of changed bookmark node.
117 * @param {!Object} changeInfo The information about how the node changed.
119 function handleBookmarkChanged(id
, changeInfo
) {
121 bmm
.tree
.handleBookmarkChanged(id
, changeInfo
);
123 bmm
.list
.handleBookmarkChanged(id
, changeInfo
);
127 * Callback for when the user reorders by title.
128 * @param {string} id The id of the bookmark folder that was reordered.
129 * @param {!Object} reorderInfo The information about how the items where
132 function handleChildrenReordered(id
, reorderInfo
) {
134 bmm
.tree
.handleChildrenReordered(id
, reorderInfo
);
136 bmm
.list
.handleChildrenReordered(id
, reorderInfo
);
137 bookmarkCache
.updateChildren(id
);
141 * Callback for when a bookmark node is created.
142 * @param {string} id The id of the newly created bookmark node.
143 * @param {!Object} bookmarkNode The new bookmark node.
145 function handleCreated(id
, bookmarkNode
) {
147 bmm
.list
.handleCreated(id
, bookmarkNode
);
149 bmm
.tree
.handleCreated(id
, bookmarkNode
);
150 bookmarkCache
.updateChildren(bookmarkNode
.parentId
);
154 * Callback for when a bookmark node is moved.
155 * @param {string} id The id of the moved bookmark node.
156 * @param {!Object} moveInfo The information about move.
158 function handleMoved(id
, moveInfo
) {
160 bmm
.list
.handleMoved(id
, moveInfo
);
162 bmm
.tree
.handleMoved(id
, moveInfo
);
164 bookmarkCache
.updateChildren(moveInfo
.parentId
);
165 if (moveInfo
.parentId
!= moveInfo
.oldParentId
)
166 bookmarkCache
.updateChildren(moveInfo
.oldParentId
);
170 * Callback for when a bookmark node is removed.
171 * @param {string} id The id of the removed bookmark node.
172 * @param {!Object} bookmarkNode The information about removed.
174 function handleRemoved(id
, removeInfo
) {
176 bmm
.list
.handleRemoved(id
, removeInfo
);
178 bmm
.tree
.handleRemoved(id
, removeInfo
);
180 bookmarkCache
.updateChildren(removeInfo
.parentId
);
181 bookmarkCache
.remove(id
);
185 * Callback for when all bookmark nodes have been deleted.
187 function handleRemoveAll() {
188 // Reload the list and the tree.
196 * Callback for when importing bookmark is started.
198 function handleImportBegan() {
199 chrome
.bookmarks
.onCreated
.removeListener(handleCreated
);
200 chrome
.bookmarks
.onChanged
.removeListener(handleBookmarkChanged
);
204 * Callback for when importing bookmark node is finished.
206 function handleImportEnded() {
207 // When importing is done we reload the tree and the list.
210 bmm
.tree
.removeEventListener('load', f
);
212 chrome
.bookmarks
.onCreated
.addListener(handleCreated
);
213 chrome
.bookmarks
.onChanged
.addListener(handleBookmarkChanged
);
218 // TODO(estade): this should navigate to the newly imported folder, which
219 // may be the bookmark bar if there were no previous bookmarks.
224 bmm
.tree
.addEventListener('load', f
);
230 * Adds the listeners for the bookmark model change events.
232 function addBookmarkModelListeners() {
233 chrome
.bookmarks
.onChanged
.addListener(handleBookmarkChanged
);
234 chrome
.bookmarks
.onChildrenReordered
.addListener(handleChildrenReordered
);
235 chrome
.bookmarks
.onCreated
.addListener(handleCreated
);
236 chrome
.bookmarks
.onMoved
.addListener(handleMoved
);
237 chrome
.bookmarks
.onRemoved
.addListener(handleRemoved
);
238 chrome
.bookmarks
.onImportBegan
.addListener(handleImportBegan
);
239 chrome
.bookmarks
.onImportEnded
.addListener(handleImportEnded
);
245 loadSubtree
: loadSubtree
,
247 addBookmarkModelListeners
: addBookmarkModelListeners