Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(446)

Side by Side Diff: chrome/browser/resources/enhanced_bookmark_manager/js/bmm/bookmark_tree.js

Issue 200063003: Remove enhanced bookmarks extension (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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
6 cr.define('bmm', function() {
7 /**
8 * The id of the bookmark root.
9 * @type {string}
10 * @const
11 */
12 var ROOT_ID = '0';
13
14 /** @const */ var Tree = cr.ui.Tree;
15 /** @const */ var TreeItem = cr.ui.TreeItem;
16
17 var treeLookup = {};
18 var tree;
19
20 // Manager for persisting the expanded state.
21 var expandedManager = {
22 /**
23 * A map of the collapsed IDs.
24 * @type {Object}
25 */
26 map: 'bookmarkTreeState' in localStorage ?
27 JSON.parse(localStorage['bookmarkTreeState']) : {},
28
29 /**
30 * Set the collapsed state for an ID.
31 * @param {string} The bookmark ID of the tree item that was expanded or
32 * collapsed.
33 * @param {boolean} expanded Whether the tree item was expanded.
34 */
35 set: function(id, expanded) {
36 if (expanded)
37 delete this.map[id];
38 else
39 this.map[id] = 1;
40
41 this.save();
42 },
43
44 /**
45 * @param {string} id The bookmark ID.
46 * @return {boolean} Whether the tree item should be expanded.
47 */
48 get: function(id) {
49 return !(id in this.map);
50 },
51
52 /**
53 * Callback for the expand and collapse events from the tree.
54 * @param {!Event} e The collapse or expand event.
55 */
56 handleEvent: function(e) {
57 this.set(e.target.bookmarkId, e.type == 'expand');
58 },
59
60 /**
61 * Cleans up old bookmark IDs.
62 */
63 cleanUp: function() {
64 for (var id in this.map) {
65 // If the id is no longer in the treeLookup the bookmark no longer
66 // exists.
67 if (!(id in treeLookup))
68 delete this.map[id];
69 }
70 this.save();
71 },
72
73 timer: null,
74
75 /**
76 * Saves the expanded state to the localStorage.
77 */
78 save: function() {
79 clearTimeout(this.timer);
80 var map = this.map;
81 // Save in a timeout so that we can coalesce multiple changes.
82 this.timer = setTimeout(function() {
83 localStorage['bookmarkTreeState'] = JSON.stringify(map);
84 }, 100);
85 }
86 };
87
88 // Clean up once per session but wait until things settle down a bit.
89 setTimeout(expandedManager.cleanUp.bind(expandedManager), 1e4);
90
91 /**
92 * Creates a new tree item for a bookmark node.
93 * @param {!Object} bookmarkNode The bookmark node.
94 * @constructor
95 * @extends {TreeItem}
96 */
97 function BookmarkTreeItem(bookmarkNode) {
98 var ti = new TreeItem({
99 label: bookmarkNode.title,
100 bookmarkNode: bookmarkNode,
101 // Bookmark toolbar and Other bookmarks are not draggable.
102 draggable: bookmarkNode.parentId != ROOT_ID
103 });
104 ti.__proto__ = BookmarkTreeItem.prototype;
105 treeLookup[bookmarkNode.id] = ti;
106 return ti;
107 }
108
109 BookmarkTreeItem.prototype = {
110 __proto__: TreeItem.prototype,
111
112 /**
113 * The ID of the bookmark this tree item represents.
114 * @type {string}
115 */
116 get bookmarkId() {
117 return this.bookmarkNode.id;
118 }
119 };
120
121 /**
122 * Asynchronousy adds a tree item at the correct index based on the bookmark
123 * backend.
124 *
125 * Since the bookmark tree only contains folders the index we get from certain
126 * callbacks is not very useful so we therefore have this async call which
127 * gets the children of the parent and adds the tree item at the desired
128 * index.
129 *
130 * This also exoands the parent so that newly added children are revealed.
131 *
132 * @param {!cr.ui.TreeItem} parent The parent tree item.
133 * @param {!cr.ui.TreeItem} treeItem The tree item to add.
134 * @param {Function=} f A function which gets called after the item has been
135 * added at the right index.
136 */
137 function addTreeItem(parent, treeItem, opt_f) {
138 chrome.bookmarks.getChildren(parent.bookmarkNode.id, function(children) {
139 var index = children.filter(bmm.isFolder).map(function(item) {
140 return item.id;
141 }).indexOf(treeItem.bookmarkNode.id);
142 parent.addAt(treeItem, index);
143 parent.expanded = true;
144 if (opt_f)
145 opt_f();
146 });
147 }
148
149
150 /**
151 * Creates a new bookmark list.
152 * @param {Object=} opt_propertyBag Optional properties.
153 * @constructor
154 * @extends {HTMLButtonElement}
155 */
156 var BookmarkTree = cr.ui.define('tree');
157
158 BookmarkTree.prototype = {
159 __proto__: Tree.prototype,
160
161 decorate: function() {
162 Tree.prototype.decorate.call(this);
163 this.addEventListener('expand', expandedManager);
164 this.addEventListener('collapse', expandedManager);
165
166 bmm.tree = this;
167 },
168
169 handleBookmarkChanged: function(id, changeInfo) {
170 var treeItem = treeLookup[id];
171 if (treeItem)
172 treeItem.label = treeItem.bookmarkNode.title = changeInfo.title;
173 },
174
175 handleChildrenReordered: function(id, reorderInfo) {
176 var parentItem = treeLookup[id];
177 // The tree only contains folders.
178 var dirIds = reorderInfo.childIds.filter(function(id) {
179 return id in treeLookup;
180 }).forEach(function(id, i) {
181 parentItem.addAt(treeLookup[id], i);
182 });
183 },
184
185 handleCreated: function(id, bookmarkNode) {
186 if (bmm.isFolder(bookmarkNode)) {
187 var parentItem = treeLookup[bookmarkNode.parentId];
188 var newItem = new BookmarkTreeItem(bookmarkNode);
189 addTreeItem(parentItem, newItem);
190 }
191 },
192
193 handleMoved: function(id, moveInfo) {
194 var treeItem = treeLookup[id];
195 if (treeItem) {
196 var oldParentItem = treeLookup[moveInfo.oldParentId];
197 oldParentItem.remove(treeItem);
198 var newParentItem = treeLookup[moveInfo.parentId];
199 // The tree only shows folders so the index is not the index we want. We
200 // therefore get the children need to adjust the index.
201 addTreeItem(newParentItem, treeItem);
202 }
203 },
204
205 handleRemoved: function(id, removeInfo) {
206 var parentItem = treeLookup[removeInfo.parentId];
207 var itemToRemove = treeLookup[id];
208 if (parentItem && itemToRemove)
209 parentItem.remove(itemToRemove);
210 },
211
212 insertSubtree: function(folder) {
213 if (!bmm.isFolder(folder))
214 return;
215 var children = folder.children;
216 this.handleCreated(folder.id, folder);
217 for (var i = 0; i < children.length; i++) {
218 var child = children[i];
219 this.insertSubtree(child);
220 }
221 },
222
223 /**
224 * Returns the bookmark node with the given ID. The tree only maintains
225 * folder nodes.
226 * @param {string} id The ID of the node to find.
227 * @return {BookmarkTreeNode} The bookmark tree node or null if not found.
228 */
229 getBookmarkNodeById: function(id) {
230 var treeItem = treeLookup[id];
231 if (treeItem)
232 return treeItem.bookmarkNode;
233 return null;
234 },
235
236 /**
237 * Returns the selected bookmark folder node as an array.
238 * @type {!Array} Array of bookmark nodes.
239 */
240 get selectedFolders() {
241 return this.selectedItem && this.selectedItem.bookmarkNode ?
242 [this.selectedItem.bookmarkNode] : [];
243 },
244
245 /**
246 * Fetches the bookmark items and builds the tree control.
247 */
248 reload: function() {
249 /**
250 * Recursive helper function that adds all the directories to the
251 * parentTreeItem.
252 * @param {!cr.ui.Tree|!cr.ui.TreeItem} parentTreeItem The parent tree
253 * element to append to.
254 * @param {!Array.<BookmarkTreeNode>} bookmarkNodes A list of bookmark
255 * nodes to be added.
256 * @return {boolean} Whether any directories where added.
257 */
258 function buildTreeItems(parentTreeItem, bookmarkNodes) {
259 var hasDirectories = false;
260 for (var i = 0, bookmarkNode; bookmarkNode = bookmarkNodes[i]; i++) {
261 if (bmm.isFolder(bookmarkNode)) {
262 hasDirectories = true;
263 var item = new BookmarkTreeItem(bookmarkNode);
264 parentTreeItem.add(item);
265 var anyChildren = buildTreeItems(item, bookmarkNode.children);
266 item.expanded = anyChildren && expandedManager.get(bookmarkNode.id);
267 }
268 }
269 return hasDirectories;
270 }
271
272 var self = this;
273 chrome.bookmarkManagerPrivate.getSubtree('', true, function(root) {
274 self.clear();
275 buildTreeItems(self, root[0].children);
276 cr.dispatchSimpleEvent(self, 'load');
277 });
278 },
279
280 /**
281 * Clears the tree.
282 */
283 clear: function() {
284 // Remove all fields without recreating the object since other code
285 // references it.
286 for (var id in treeLookup) {
287 delete treeLookup[id];
288 }
289 this.textContent = '';
290 },
291
292 /** @override */
293 remove: function(child) {
294 Tree.prototype.remove.call(this, child);
295 if (child.bookmarkNode)
296 delete treeLookup[child.bookmarkNode.id];
297 }
298 };
299
300 return {
301 BookmarkTree: BookmarkTree,
302 BookmarkTreeItem: BookmarkTreeItem,
303 treeLookup: treeLookup,
304 tree: tree,
305 ROOT_ID: ROOT_ID
306 };
307 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698