| 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 |