OLD | NEW |
| (Empty) |
1 // Copyright 2013 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. | |
4 | |
5 cr.define('bmm', function() { | |
6 var Promise = cr.Promise; | |
7 | |
8 /** | |
9 * Whether a node contains another node. | |
10 * TODO(yosin): Once JavaScript style guide is updated and linter follows | |
11 * that, we'll remove useless documentations for |parent| and |descendant|. | |
12 * TODO(yosin): bmm.contains() should be method of BookmarkTreeNode. | |
13 * @param {!BookmarkTreeNode} parent . | |
14 * @param {!BookmarkTreeNode} descendant . | |
15 * @return {boolean} Whether the parent contains the descendant. | |
16 */ | |
17 function contains(parent, descendant) { | |
18 if (descendant.parentId == parent.id) | |
19 return true; | |
20 // the bmm.treeLookup contains all folders | |
21 var parentTreeItem = bmm.treeLookup[descendant.parentId]; | |
22 if (!parentTreeItem || !parentTreeItem.bookmarkNode) | |
23 return false; | |
24 return this.contains(parent, parentTreeItem.bookmarkNode); | |
25 } | |
26 | |
27 /** | |
28 * @param {!BookmarkTreeNode} node The node to test. | |
29 * @return {boolean} Whether a bookmark node is a folder. | |
30 */ | |
31 function isFolder(node) { | |
32 return !('url' in node); | |
33 } | |
34 | |
35 var loadingPromises = {}; | |
36 | |
37 /** | |
38 * Loads a subtree of the bookmark tree and returns a {@code cr.Promise} that | |
39 * will be fulfilled when done. This reuses multiple loads so that we do not | |
40 * load the same subtree more than once at the same time. | |
41 * @return {!cr.Promise} The future promise for the load. | |
42 */ | |
43 function loadSubtree(id) { | |
44 var p = new Promise; | |
45 if (!(id in loadingPromises)) { | |
46 loadingPromises[id] = new Promise; | |
47 loadingPromises[id].addListener(function(n) { | |
48 p.value = n; | |
49 }); | |
50 chrome.bookmarkManagerPrivate.getSubtree(id, false, function(nodes) { | |
51 loadingPromises[id].value = nodes && nodes[0]; | |
52 delete loadingPromises[id]; | |
53 }); | |
54 } else { | |
55 loadingPromises[id].addListener(function(n) { | |
56 p.value = n; | |
57 }); | |
58 } | |
59 return p; | |
60 } | |
61 | |
62 /** | |
63 * Loads the entire bookmark tree and returns a {@code cr.Promise} that will | |
64 * be fulfilled when done. This reuses multiple loads so that we do not load | |
65 * the same tree more than once at the same time. | |
66 * @return {!cr.Promise} The future promise for the load. | |
67 */ | |
68 function loadTree() { | |
69 return loadSubtree(''); | |
70 } | |
71 | |
72 var bookmarkCache = { | |
73 /** | |
74 * Removes the cached item from both the list and tree lookups. | |
75 */ | |
76 remove: function(id) { | |
77 var treeItem = bmm.treeLookup[id]; | |
78 if (treeItem) { | |
79 var items = treeItem.items; // is an HTMLCollection | |
80 for (var i = 0; i < items.length; ++i) { | |
81 var item = items[i]; | |
82 var bookmarkNode = item.bookmarkNode; | |
83 delete bmm.treeLookup[bookmarkNode.id]; | |
84 } | |
85 delete bmm.treeLookup[id]; | |
86 } | |
87 }, | |
88 | |
89 /** | |
90 * Updates the underlying bookmark node for the tree items and list items by | |
91 * querying the bookmark backend. | |
92 * @param {string} id The id of the node to update the children for. | |
93 * @param {Function=} opt_f A funciton to call when done. | |
94 */ | |
95 updateChildren: function(id, opt_f) { | |
96 function updateItem(bookmarkNode) { | |
97 var treeItem = bmm.treeLookup[bookmarkNode.id]; | |
98 if (treeItem) { | |
99 treeItem.bookmarkNode = bookmarkNode; | |
100 } | |
101 } | |
102 | |
103 chrome.bookmarks.getChildren(id, function(children) { | |
104 if (children) | |
105 children.forEach(updateItem); | |
106 | |
107 if (opt_f) | |
108 opt_f(children); | |
109 }); | |
110 } | |
111 }; | |
112 | |
113 /** | |
114 * Called when the title of a bookmark changes. | |
115 * @param {string} id The id of changed bookmark node. | |
116 * @param {!Object} changeInfo The information about how the node changed. | |
117 */ | |
118 function handleBookmarkChanged(id, changeInfo) { | |
119 if (bmm.tree) | |
120 bmm.tree.handleBookmarkChanged(id, changeInfo); | |
121 if (bmm.list) | |
122 bmm.list.handleBookmarkChanged(id, changeInfo); | |
123 } | |
124 | |
125 /** | |
126 * Callback for when the user reorders by title. | |
127 * @param {string} id The id of the bookmark folder that was reordered. | |
128 * @param {!Object} reorderInfo The information about how the items where | |
129 * reordered. | |
130 */ | |
131 function handleChildrenReordered(id, reorderInfo) { | |
132 if (bmm.tree) | |
133 bmm.tree.handleChildrenReordered(id, reorderInfo); | |
134 if (bmm.list) | |
135 bmm.list.handleChildrenReordered(id, reorderInfo); | |
136 bookmarkCache.updateChildren(id); | |
137 } | |
138 | |
139 /** | |
140 * Callback for when a bookmark node is created. | |
141 * @param {string} id The id of the newly created bookmark node. | |
142 * @param {!Object} bookmarkNode The new bookmark node. | |
143 */ | |
144 function handleCreated(id, bookmarkNode) { | |
145 if (bmm.list) | |
146 bmm.list.handleCreated(id, bookmarkNode); | |
147 if (bmm.tree) | |
148 bmm.tree.handleCreated(id, bookmarkNode); | |
149 bookmarkCache.updateChildren(bookmarkNode.parentId); | |
150 } | |
151 | |
152 /** | |
153 * Callback for when a bookmark node is moved. | |
154 * @param {string} id The id of the moved bookmark node. | |
155 * @param {!Object} moveInfo The information about move. | |
156 */ | |
157 function handleMoved(id, moveInfo) { | |
158 if (bmm.list) | |
159 bmm.list.handleMoved(id, moveInfo); | |
160 if (bmm.tree) | |
161 bmm.tree.handleMoved(id, moveInfo); | |
162 | |
163 bookmarkCache.updateChildren(moveInfo.parentId); | |
164 if (moveInfo.parentId != moveInfo.oldParentId) | |
165 bookmarkCache.updateChildren(moveInfo.oldParentId); | |
166 } | |
167 | |
168 /** | |
169 * Callback for when a bookmark node is removed. | |
170 * @param {string} id The id of the removed bookmark node. | |
171 * @param {!Object} bookmarkNode The information about removed. | |
172 */ | |
173 function handleRemoved(id, removeInfo) { | |
174 if (bmm.list) | |
175 bmm.list.handleRemoved(id, removeInfo); | |
176 if (bmm.tree) | |
177 bmm.tree.handleRemoved(id, removeInfo); | |
178 | |
179 bookmarkCache.updateChildren(removeInfo.parentId); | |
180 bookmarkCache.remove(id); | |
181 } | |
182 | |
183 /** | |
184 * Callback for when all bookmark nodes have been deleted. | |
185 */ | |
186 function handleRemoveAll() { | |
187 // Reload the list and the tree. | |
188 if (bmm.list) | |
189 bmm.list.reload(); | |
190 if (bmm.tree) | |
191 bmm.tree.reload(); | |
192 } | |
193 | |
194 /** | |
195 * Callback for when importing bookmark is started. | |
196 */ | |
197 function handleImportBegan() { | |
198 chrome.bookmarks.onCreated.removeListener(handleCreated); | |
199 chrome.bookmarks.onChanged.removeListener(handleBookmarkChanged); | |
200 } | |
201 | |
202 /** | |
203 * Callback for when importing bookmark node is finished. | |
204 */ | |
205 function handleImportEnded() { | |
206 // When importing is done we reload the tree and the list. | |
207 | |
208 function f() { | |
209 bmm.tree.removeEventListener('load', f); | |
210 | |
211 chrome.bookmarks.onCreated.addListener(handleCreated); | |
212 chrome.bookmarks.onChanged.addListener(handleBookmarkChanged); | |
213 | |
214 if (!bmm.list) | |
215 return; | |
216 | |
217 // TODO(estade): this should navigate to the newly imported folder, which | |
218 // may be the bookmark bar if there were no previous bookmarks. | |
219 bmm.list.reload(); | |
220 } | |
221 | |
222 if (bmm.tree) { | |
223 bmm.tree.addEventListener('load', f); | |
224 bmm.tree.reload(); | |
225 } | |
226 } | |
227 | |
228 /** | |
229 * Adds the listeners for the bookmark model change events. | |
230 */ | |
231 function addBookmarkModelListeners() { | |
232 chrome.bookmarks.onChanged.addListener(handleBookmarkChanged); | |
233 chrome.bookmarks.onChildrenReordered.addListener(handleChildrenReordered); | |
234 chrome.bookmarks.onCreated.addListener(handleCreated); | |
235 chrome.bookmarks.onMoved.addListener(handleMoved); | |
236 chrome.bookmarks.onRemoved.addListener(handleRemoved); | |
237 chrome.bookmarks.onImportBegan.addListener(handleImportBegan); | |
238 chrome.bookmarks.onImportEnded.addListener(handleImportEnded); | |
239 }; | |
240 | |
241 return { | |
242 contains: contains, | |
243 isFolder: isFolder, | |
244 loadSubtree: loadSubtree, | |
245 loadTree: loadTree, | |
246 addBookmarkModelListeners: addBookmarkModelListeners | |
247 }; | |
248 }); | |
OLD | NEW |