OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 (function() { | 5 (function() { |
6 /** @const */ var BookmarkList = bmm.BookmarkList; | 6 /** @const */ var BookmarkList = bmm.BookmarkList; |
7 /** @const */ var BookmarkTree = bmm.BookmarkTree; | 7 /** @const */ var BookmarkTree = bmm.BookmarkTree; |
8 /** @const */ var Command = cr.ui.Command; | 8 /** @const */ var Command = cr.ui.Command; |
9 /** @const */ var CommandBinding = cr.ui.CommandBinding; | |
10 /** @const */ var LinkKind = cr.LinkKind; | 9 /** @const */ var LinkKind = cr.LinkKind; |
11 /** @const */ var ListItem = cr.ui.ListItem; | 10 /** @const */ var ListItem = cr.ui.ListItem; |
12 /** @const */ var Menu = cr.ui.Menu; | 11 /** @const */ var Menu = cr.ui.Menu; |
13 /** @const */ var MenuButton = cr.ui.MenuButton; | 12 /** @const */ var MenuButton = cr.ui.MenuButton; |
14 /** @const */ var Splitter = cr.ui.Splitter; | 13 /** @const */ var Splitter = cr.ui.Splitter; |
15 /** @const */ var TreeItem = cr.ui.TreeItem; | 14 /** @const */ var TreeItem = cr.ui.TreeItem; |
16 | 15 |
17 /** | 16 /** |
18 * An array containing the BookmarkTreeNodes that were deleted in the last | 17 * An array containing the BookmarkTreeNodes that were deleted in the last |
19 * deletion action. This is used for implementing undo. | 18 * deletion action. This is used for implementing undo. |
20 * @type {Array.<BookmarkTreeNode>} | 19 * @type {Array.<Array.<BookmarkTreeNode>>} |
21 */ | 20 */ |
22 var lastDeletedNodes; | 21 var lastDeletedNodes; |
23 | 22 |
24 /** | 23 /** |
25 * | 24 * |
26 * Holds the last DOMTimeStamp when mouse pointer hovers on folder in tree | 25 * Holds the last DOMTimeStamp when mouse pointer hovers on folder in tree |
27 * view. Zero means pointer doesn't hover on folder. | 26 * view. Zero means pointer doesn't hover on folder. |
28 * @type {number} | 27 * @type {number} |
29 */ | 28 */ |
30 var lastHoverOnFolderTimeStamp = 0; | 29 var lastHoverOnFolderTimeStamp = 0; |
31 | 30 |
32 /** | 31 /** |
33 * Holds a function that will undo that last action, if global undo is enabled. | 32 * Holds a function that will undo that last action, if global undo is enabled. |
34 * @type {Function} | 33 * @type {Function} |
35 */ | 34 */ |
36 var performGlobalUndo; | 35 var performGlobalUndo; |
37 | 36 |
38 /** | 37 /** |
39 * Holds a link controller singleton. Use getLinkController() rarther than | 38 * Holds a link controller singleton. Use getLinkController() rarther than |
40 * accessing this variabie. | 39 * accessing this variabie. |
41 * @type {LinkController} | 40 * @type {cr.LinkController} |
42 */ | 41 */ |
43 var linkController; | 42 var linkController; |
44 | 43 |
45 /** | 44 /** |
46 * New Windows are not allowed in Windows 8 metro mode. | 45 * New Windows are not allowed in Windows 8 metro mode. |
47 */ | 46 */ |
48 var canOpenNewWindows = true; | 47 var canOpenNewWindows = true; |
49 | 48 |
50 /** | 49 /** |
51 * Incognito mode availability can take the following values: , | 50 * Incognito mode availability can take the following values: , |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 | 134 |
136 searchTreeItem.label = loadTimeData.getString('search'); | 135 searchTreeItem.label = loadTimeData.getString('search'); |
137 searchTreeItem.icon = isRTL() ? 'images/bookmark_manager_search_rtl.png' : | 136 searchTreeItem.icon = isRTL() ? 'images/bookmark_manager_search_rtl.png' : |
138 'images/bookmark_manager_search.png'; | 137 'images/bookmark_manager_search.png'; |
139 } | 138 } |
140 | 139 |
141 /** | 140 /** |
142 * Updates the location hash to reflect the current state of the application. | 141 * Updates the location hash to reflect the current state of the application. |
143 */ | 142 */ |
144 function updateHash() { | 143 function updateHash() { |
145 window.location.hash = tree.selectedItem.bookmarkId; | 144 window.location.hash = bmm.tree.selectedItem.bookmarkId; |
146 updateAllCommands(); | 145 updateAllCommands(); |
147 } | 146 } |
148 | 147 |
149 /** | 148 /** |
150 * Navigates to a bookmark ID. | 149 * Navigates to a bookmark ID. |
151 * @param {string} id The ID to navigate to. | 150 * @param {string} id The ID to navigate to. |
152 * @param {function()=} opt_callback Function called when list view loaded or | 151 * @param {function()=} opt_callback Function called when list view loaded or |
153 * displayed specified folder. | 152 * displayed specified folder. |
154 */ | 153 */ |
155 function navigateTo(id, opt_callback) { | 154 function navigateTo(id, opt_callback) { |
156 window.location.hash = id; | 155 window.location.hash = id; |
157 updateAllCommands(); | 156 updateAllCommands(); |
158 | 157 |
159 var metricsId = folderMetricsNameMap[id.replace(/^q=.*/, 'q=')] || | 158 var metricsId = folderMetricsNameMap[id.replace(/^q=.*/, 'q=')] || |
160 folderMetricsNameMap['subfolder']; | 159 folderMetricsNameMap['subfolder']; |
161 chrome.metricsPrivate.recordUserAction( | 160 chrome.metricsPrivate.recordUserAction( |
162 'BookmarkManager_NavigateTo_' + metricsId); | 161 'BookmarkManager_NavigateTo_' + metricsId); |
163 | 162 |
164 if (opt_callback) { | 163 if (opt_callback) { |
| 164 var list = getRequiredElement('list'); |
165 if (list.parentId == id) | 165 if (list.parentId == id) |
166 opt_callback(); | 166 opt_callback(); |
167 else | 167 else |
168 addOneShotEventListener(list, 'load', opt_callback); | 168 addOneShotEventListener(list, 'load', opt_callback); |
169 } | 169 } |
170 } | 170 } |
171 | 171 |
172 /** | 172 /** |
173 * Updates the parent ID of the bookmark list and selects the correct tree item. | 173 * Updates the parent ID of the bookmark list and selects the correct tree item. |
174 * @param {string} id The id. | 174 * @param {string} id The id. |
175 */ | 175 */ |
176 function updateParentId(id) { | 176 function updateParentId(id) { |
177 // Setting list.parentId fires 'load' event. | 177 // Setting list.parentId fires 'load' event. |
178 list.parentId = id; | 178 bmm.list.parentId = id; |
179 | 179 |
180 // When tree.selectedItem changed, tree view calls navigatTo() then it | 180 // When tree.selectedItem changed, tree view calls navigatTo() then it |
181 // calls updateHash() when list view displayed specified folder. | 181 // calls updateHash() when list view displayed specified folder. |
182 tree.selectedItem = bmm.treeLookup[id] || tree.selectedItem; | 182 bmm.tree.selectedItem = bmm.treeLookup[id] || bmm.tree.selectedItem; |
183 } | 183 } |
184 | 184 |
185 // Process the location hash. This is called by onhashchange and when the page | 185 // Process the location hash. This is called by onhashchange and when the page |
186 // is first loaded. | 186 // is first loaded. |
187 function processHash() { | 187 function processHash() { |
188 var id = window.location.hash.slice(1); | 188 var id = window.location.hash.slice(1); |
189 if (!id) { | 189 if (!id) { |
190 // If we do not have a hash, select first item in the tree. | 190 // If we do not have a hash, select first item in the tree. |
191 id = tree.items[0].bookmarkId; | 191 id = bmm.tree.items[0].bookmarkId; |
192 } | 192 } |
193 | 193 |
194 var valid = false; | 194 var valid = false; |
195 if (/^e=/.test(id)) { | 195 if (/^e=/.test(id)) { |
196 id = id.slice(2); | 196 id = id.slice(2); |
197 | 197 |
198 // If hash contains e=, edit the item specified. | 198 // If hash contains e=, edit the item specified. |
199 chrome.bookmarks.get(id, function(bookmarkNodes) { | 199 chrome.bookmarks.get(id, function(bookmarkNodes) { |
200 // Verify the node to edit is a valid node. | 200 // Verify the node to edit is a valid node. |
201 if (!bookmarkNodes || bookmarkNodes.length != 1) | 201 if (!bookmarkNodes || bookmarkNodes.length != 1) |
202 return; | 202 return; |
203 var bookmarkNode = bookmarkNodes[0]; | 203 var bookmarkNode = bookmarkNodes[0]; |
204 | 204 |
205 // After the list reloads, edit the desired bookmark. | 205 // After the list reloads, edit the desired bookmark. |
206 var editBookmark = function(e) { | 206 var editBookmark = function() { |
207 var index = list.dataModel.findIndexById(bookmarkNode.id); | 207 var index = bmm.list.dataModel.findIndexById(bookmarkNode.id); |
208 if (index != -1) { | 208 if (index != -1) { |
209 var sm = list.selectionModel; | 209 var sm = bmm.list.selectionModel; |
210 sm.anchorIndex = sm.leadIndex = sm.selectedIndex = index; | 210 sm.anchorIndex = sm.leadIndex = sm.selectedIndex = index; |
211 scrollIntoViewAndMakeEditable(index); | 211 scrollIntoViewAndMakeEditable(index); |
212 } | 212 } |
213 }; | 213 }; |
214 | 214 |
215 navigateTo(bookmarkNode.parentId, editBookmark); | 215 var parentId = assert(bookmarkNode.parentId); |
| 216 navigateTo(parentId, editBookmark); |
216 }); | 217 }); |
217 | 218 |
218 // We handle the two cases of navigating to the bookmark to be edited | 219 // We handle the two cases of navigating to the bookmark to be edited |
219 // above. Don't run the standard navigation code below. | 220 // above. Don't run the standard navigation code below. |
220 return; | 221 return; |
221 } else if (/^q=/.test(id)) { | 222 } else if (/^q=/.test(id)) { |
222 // In case we got a search hash, update the text input and the | 223 // In case we got a search hash, update the text input and the |
223 // bmm.treeLookup to use the new id. | 224 // bmm.treeLookup to use the new id. |
224 setSearch(id.slice(2)); | 225 setSearch(id.slice(2)); |
225 valid = true; | 226 valid = true; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 var id = searchTreeItem.bookmarkId = 'q=' + searchText; | 267 var id = searchTreeItem.bookmarkId = 'q=' + searchText; |
267 bmm.treeLookup[searchTreeItem.bookmarkId] = searchTreeItem; | 268 bmm.treeLookup[searchTreeItem.bookmarkId] = searchTreeItem; |
268 } | 269 } |
269 | 270 |
270 var input = $('term'); | 271 var input = $('term'); |
271 // Do not update the input if the user is actively using the text input. | 272 // Do not update the input if the user is actively using the text input. |
272 if (document.activeElement != input) | 273 if (document.activeElement != input) |
273 input.value = searchText; | 274 input.value = searchText; |
274 | 275 |
275 if (searchText) { | 276 if (searchText) { |
276 tree.add(searchTreeItem); | 277 bmm.tree.add(searchTreeItem); |
277 tree.selectedItem = searchTreeItem; | 278 bmm.tree.selectedItem = searchTreeItem; |
278 } else { | 279 } else { |
279 // Go "home". | 280 // Go "home". |
280 tree.selectedItem = tree.items[0]; | 281 bmm.tree.selectedItem = bmm.tree.items[0]; |
281 id = tree.selectedItem.bookmarkId; | 282 id = bmm.tree.selectedItem.bookmarkId; |
282 } | 283 } |
283 | 284 |
284 navigateTo(id); | 285 navigateTo(id); |
285 } | 286 } |
286 | 287 |
287 /** | 288 /** |
288 * This returns the user visible path to the folder where the bookmark is | 289 * This returns the user visible path to the folder where the bookmark is |
289 * located. | 290 * located. |
290 * @param {number} parentId The ID of the parent folder. | 291 * @param {number} parentId The ID of the parent folder. |
291 * @return {string} The path to the the bookmark, | 292 * @return {string} The path to the the bookmark, |
292 */ | 293 */ |
293 function getFolder(parentId) { | 294 function getFolder(parentId) { |
294 var parentNode = tree.getBookmarkNodeById(parentId); | 295 var parentNode = bmm.tree.getBookmarkNodeById(parentId); |
295 if (parentNode) { | 296 if (parentNode) { |
296 var s = parentNode.title; | 297 var s = parentNode.title; |
297 if (parentNode.parentId != bmm.ROOT_ID) { | 298 if (parentNode.parentId != bmm.ROOT_ID) { |
298 return getFolder(parentNode.parentId) + '/' + s; | 299 return getFolder(parentNode.parentId) + '/' + s; |
299 } | 300 } |
300 return s; | 301 return s; |
301 } | 302 } |
302 } | 303 } |
303 | 304 |
304 function handleLoadForTree(e) { | 305 function handleLoadForTree(e) { |
(...skipping 19 matching lines...) Expand all Loading... |
324 if (!bmm.isFolder(child)) | 325 if (!bmm.isFolder(child)) |
325 urls.push(child.url); | 326 urls.push(child.url); |
326 }); | 327 }); |
327 } else { | 328 } else { |
328 urls.push(node.url); | 329 urls.push(node.url); |
329 } | 330 } |
330 } | 331 } |
331 | 332 |
332 // Get a future promise for the nodes. | 333 // Get a future promise for the nodes. |
333 var promises = nodes.map(function(node) { | 334 var promises = nodes.map(function(node) { |
334 if (bmm.isFolder(node)) | 335 if (bmm.isFolder(assert(node))) |
335 return bmm.loadSubtree(node.id); | 336 return bmm.loadSubtree(node.id); |
336 // Not a folder so we already have all the data we need. | 337 // Not a folder so we already have all the data we need. |
337 return Promise.resolve(node); | 338 return Promise.resolve(node); |
338 }); | 339 }); |
339 | 340 |
340 return Promise.all(promises).then(function(nodes) { | 341 return Promise.all(promises).then(function(nodes) { |
341 nodes.forEach(addNodes); | 342 nodes.forEach(addNodes); |
342 return urls; | 343 return urls; |
343 }); | 344 }); |
344 } | 345 } |
345 | 346 |
346 /** | 347 /** |
347 * Returns the nodes (non recursive) to use for the open commands. | 348 * Returns the nodes (non recursive) to use for the open commands. |
348 * @param {HTMLElement} target . | 349 * @param {HTMLElement} target |
349 * @return {Array.<BookmarkTreeNode>} . | 350 * @return {!Array.<BookmarkTreeNode>} |
350 */ | 351 */ |
351 function getNodesForOpen(target) { | 352 function getNodesForOpen(target) { |
352 if (target == tree) { | 353 if (target == bmm.tree) { |
353 if (tree.selectedItem != searchTreeItem) | 354 if (bmm.tree.selectedItem != searchTreeItem) |
354 return tree.selectedFolders; | 355 return bmm.tree.selectedFolders; |
355 // Fall through to use all nodes in the list. | 356 // Fall through to use all nodes in the list. |
356 } else { | 357 } else { |
357 var items = list.selectedItems; | 358 var items = bmm.list.selectedItems; |
358 if (items.length) | 359 if (items.length) |
359 return items; | 360 return items; |
360 } | 361 } |
361 | 362 |
362 // The list starts off with a null dataModel. We can get here during startup. | 363 // The list starts off with a null dataModel. We can get here during startup. |
363 if (!list.dataModel) | 364 if (!bmm.list.dataModel) |
364 return []; | 365 return []; |
365 | 366 |
366 // Return an array based on the dataModel. | 367 // Return an array based on the dataModel. |
367 return list.dataModel.slice(); | 368 return bmm.list.dataModel.slice(); |
368 } | 369 } |
369 | 370 |
370 /** | 371 /** |
371 * Returns a promise that will contain all URLs of all the selected bookmarks | 372 * Returns a promise that will contain all URLs of all the selected bookmarks |
372 * and the nested bookmarks for use with the open commands. | 373 * and the nested bookmarks for use with the open commands. |
373 * @param {HTMLElement} target The target list or tree. | 374 * @param {HTMLElement} target The target list or tree. |
374 * @return {Promise.<Array.<string>>} . | 375 * @return {Promise.<Array.<string>>} . |
375 */ | 376 */ |
376 function getUrlsForOpenCommands(target) { | 377 function getUrlsForOpenCommands(target) { |
377 return getAllUrls(getNodesForOpen(target)); | 378 return getAllUrls(getNodesForOpen(target)); |
(...skipping 12 matching lines...) Expand all Loading... |
390 * @param {string} pluralId The string id of menu label if the singular form is | 391 * @param {string} pluralId The string id of menu label if the singular form is |
391 not used. | 392 not used. |
392 * @param {boolean} commandDisabled Whether the menu item should be disabled | 393 * @param {boolean} commandDisabled Whether the menu item should be disabled |
393 no matter what bookmarks are selected. | 394 no matter what bookmarks are selected. |
394 */ | 395 */ |
395 function updateOpenCommand(e, command, singularId, pluralId, commandDisabled) { | 396 function updateOpenCommand(e, command, singularId, pluralId, commandDisabled) { |
396 if (singularId) { | 397 if (singularId) { |
397 // The command label reflects the selection which might not reflect | 398 // The command label reflects the selection which might not reflect |
398 // how many bookmarks will be opened. For example if you right click an | 399 // how many bookmarks will be opened. For example if you right click an |
399 // empty area in a folder with 1 bookmark the text should still say "all". | 400 // empty area in a folder with 1 bookmark the text should still say "all". |
| 401 assert(!e.target || e.target instanceof BookmarkList || |
| 402 e.target instanceof BookmarkTree); |
400 var selectedNodes = getSelectedBookmarkNodes(e.target).filter(notNewNode); | 403 var selectedNodes = getSelectedBookmarkNodes(e.target).filter(notNewNode); |
401 var singular = selectedNodes.length == 1 && !bmm.isFolder(selectedNodes[0]); | 404 var singular = selectedNodes.length == 1 && !bmm.isFolder(selectedNodes[0]); |
402 command.label = loadTimeData.getString(singular ? singularId : pluralId); | 405 command.label = loadTimeData.getString(singular ? singularId : pluralId); |
403 } | 406 } |
404 | 407 |
405 if (commandDisabled) { | 408 if (commandDisabled) { |
406 command.disabled = true; | 409 command.disabled = true; |
407 e.canExecute = false; | 410 e.canExecute = false; |
408 return; | 411 return; |
409 } | 412 } |
410 | 413 |
411 getUrlsForOpenCommands(e.target).then(function(urls) { | 414 getUrlsForOpenCommands(assertInstanceof(e.target, HTMLElement)).then( |
| 415 function(urls) { |
412 var disabled = !urls.length; | 416 var disabled = !urls.length; |
413 command.disabled = disabled; | 417 command.disabled = disabled; |
414 e.canExecute = !disabled; | 418 e.canExecute = !disabled; |
415 }); | 419 }); |
416 } | 420 } |
417 | 421 |
418 /** | 422 /** |
419 * Calls the backend to figure out if we can paste the clipboard into the active | 423 * Calls the backend to figure out if we can paste the clipboard into the active |
420 * folder. | 424 * folder. |
421 * @param {Function=} opt_f Function to call after the state has been updated. | 425 * @param {Function=} opt_f Function to call after the state has been updated. |
422 */ | 426 */ |
423 function updatePasteCommand(opt_f) { | 427 function updatePasteCommand(opt_f) { |
424 function update(canPaste) { | 428 function update(canPaste) { |
425 var organizeMenuCommand = $('paste-from-organize-menu-command'); | 429 var organizeMenuCommand = $('paste-from-organize-menu-command'); |
426 var contextMenuCommand = $('paste-from-context-menu-command'); | 430 var contextMenuCommand = $('paste-from-context-menu-command'); |
427 organizeMenuCommand.disabled = !canPaste; | 431 organizeMenuCommand.disabled = !canPaste; |
428 contextMenuCommand.disabled = !canPaste; | 432 contextMenuCommand.disabled = !canPaste; |
429 if (opt_f) | 433 if (opt_f) |
430 opt_f(); | 434 opt_f(); |
431 } | 435 } |
432 // We cannot paste into search view. | 436 // We cannot paste into search view. |
433 if (list.isSearch()) | 437 if (bmm.list.isSearch()) |
434 update(false); | 438 update(false); |
435 else | 439 else |
436 chrome.bookmarkManagerPrivate.canPaste(list.parentId, update); | 440 chrome.bookmarkManagerPrivate.canPaste(bmm.list.parentId, update); |
437 } | 441 } |
438 | 442 |
439 function handleCanExecuteForDocument(e) { | 443 function handleCanExecuteForDocument(e) { |
440 var command = e.command; | 444 var command = e.command; |
441 switch (command.id) { | 445 switch (command.id) { |
442 case 'import-menu-command': | 446 case 'import-menu-command': |
443 e.canExecute = canEdit; | 447 e.canExecute = canEdit; |
444 break; | 448 break; |
445 case 'export-menu-command': | 449 case 'export-menu-command': |
446 // We can always execute the export-menu command. | 450 // We can always execute the export-menu command. |
447 e.canExecute = true; | 451 e.canExecute = true; |
448 break; | 452 break; |
449 case 'sort-command': | 453 case 'sort-command': |
450 e.canExecute = !list.isSearch() && | 454 e.canExecute = !bmm.list.isSearch() && |
451 list.dataModel && list.dataModel.length > 1 && | 455 bmm.list.dataModel && bmm.list.dataModel.length > 1 && |
452 !isUnmodifiable(tree.getBookmarkNodeById(list.parentId)); | 456 !isUnmodifiable(bmm.tree.getBookmarkNodeById(bmm.list.parentId)); |
453 break; | 457 break; |
454 case 'undo-command': | 458 case 'undo-command': |
455 // If the search box is active, pass the undo command through | 459 // If the search box is active, pass the undo command through |
456 // (fixes http://crbug.com/278112). Otherwise, because | 460 // (fixes http://crbug.com/278112). Otherwise, because |
457 // the global undo command has no visible UI, always enable it, and | 461 // the global undo command has no visible UI, always enable it, and |
458 // just make it a no-op if undo is not possible. | 462 // just make it a no-op if undo is not possible. |
459 e.canExecute = e.currentTarget.activeElement !== $('term'); | 463 e.canExecute = e.currentTarget.activeElement !== $('term'); |
460 break; | 464 break; |
461 default: | 465 default: |
462 canExecuteForList(e); | 466 canExecuteForList(e); |
463 break; | 467 break; |
464 } | 468 } |
465 } | 469 } |
466 | 470 |
467 /** | 471 /** |
468 * Helper function for handling canExecute for the list and the tree. | 472 * Helper function for handling canExecute for the list and the tree. |
469 * @param {!Event} e Can execute event object. | 473 * @param {!cr.ui.CanExecuteEvent} e Can execute event object. |
470 * @param {boolean} isSearch Whether the user is trying to do a command on | 474 * @param {boolean} isSearch Whether the user is trying to do a command on |
471 * search. | 475 * search. |
472 */ | 476 */ |
473 function canExecuteShared(e, isSearch) { | 477 function canExecuteShared(e, isSearch) { |
474 var command = e.command; | 478 var command = e.command; |
475 var commandId = command.id; | 479 var commandId = command.id; |
476 switch (commandId) { | 480 switch (commandId) { |
477 case 'paste-from-organize-menu-command': | 481 case 'paste-from-organize-menu-command': |
478 case 'paste-from-context-menu-command': | 482 case 'paste-from-context-menu-command': |
479 updatePasteCommand(); | 483 updatePasteCommand(); |
480 break; | 484 break; |
481 | 485 |
482 case 'add-new-bookmark-command': | 486 case 'add-new-bookmark-command': |
483 case 'new-folder-command': | 487 case 'new-folder-command': |
484 var parentId = computeParentFolderForNewItem(); | 488 var parentId = computeParentFolderForNewItem(); |
485 var unmodifiable = isUnmodifiable(tree.getBookmarkNodeById(parentId)); | 489 var unmodifiable = isUnmodifiable( |
| 490 bmm.tree.getBookmarkNodeById(parentId)); |
486 e.canExecute = !isSearch && canEdit && !unmodifiable; | 491 e.canExecute = !isSearch && canEdit && !unmodifiable; |
487 break; | 492 break; |
488 | 493 |
489 case 'open-in-new-tab-command': | 494 case 'open-in-new-tab-command': |
490 updateOpenCommand(e, command, 'open_in_new_tab', 'open_all', false); | 495 updateOpenCommand(e, command, 'open_in_new_tab', 'open_all', false); |
491 break; | 496 break; |
492 case 'open-in-background-tab-command': | 497 case 'open-in-background-tab-command': |
493 updateOpenCommand(e, command, '', '', false); | 498 updateOpenCommand(e, command, '', '', false); |
494 break; | 499 break; |
495 case 'open-in-new-window-command': | 500 case 'open-in-new-window-command': |
(...skipping 10 matching lines...) Expand all Loading... |
506 break; | 511 break; |
507 | 512 |
508 case 'undo-delete-command': | 513 case 'undo-delete-command': |
509 e.canExecute = !!lastDeletedNodes; | 514 e.canExecute = !!lastDeletedNodes; |
510 break; | 515 break; |
511 } | 516 } |
512 } | 517 } |
513 | 518 |
514 /** | 519 /** |
515 * Helper function for handling canExecute for the list and document. | 520 * Helper function for handling canExecute for the list and document. |
516 * @param {!Event} e Can execute event object. | 521 * @param {!cr.ui.CanExecuteEvent} e Can execute event object. |
517 */ | 522 */ |
518 function canExecuteForList(e) { | 523 function canExecuteForList(e) { |
519 var command = e.command; | 524 var command = e.command; |
520 var commandId = command.id; | 525 var commandId = command.id; |
521 | 526 |
522 function hasSelected() { | 527 function hasSelected() { |
523 return !!list.selectedItem; | 528 return !!bmm.list.selectedItem; |
524 } | 529 } |
525 | 530 |
526 function hasSingleSelected() { | 531 function hasSingleSelected() { |
527 return list.selectedItems.length == 1; | 532 return bmm.list.selectedItems.length == 1; |
528 } | 533 } |
529 | 534 |
530 function canCopyItem(item) { | 535 function canCopyItem(item) { |
531 return item.id != 'new'; | 536 return item.id != 'new'; |
532 } | 537 } |
533 | 538 |
534 function canCopyItems() { | 539 function canCopyItems() { |
535 var selectedItems = list.selectedItems; | 540 var selectedItems = bmm.list.selectedItems; |
536 return selectedItems && selectedItems.some(canCopyItem); | 541 return selectedItems && selectedItems.some(canCopyItem); |
537 } | 542 } |
538 | 543 |
539 function isSearch() { | 544 function isSearch() { |
540 return list.isSearch(); | 545 return bmm.list.isSearch(); |
541 } | 546 } |
542 | 547 |
543 switch (commandId) { | 548 switch (commandId) { |
544 case 'rename-folder-command': | 549 case 'rename-folder-command': |
545 // Show rename if a single folder is selected. | 550 // Show rename if a single folder is selected. |
546 var items = list.selectedItems; | 551 var items = bmm.list.selectedItems; |
547 if (items.length != 1) { | 552 if (items.length != 1) { |
548 e.canExecute = false; | 553 e.canExecute = false; |
549 command.hidden = true; | 554 command.hidden = true; |
550 } else { | 555 } else { |
551 var isFolder = bmm.isFolder(items[0]); | 556 var isFolder = bmm.isFolder(items[0]); |
552 e.canExecute = isFolder && canEdit && !hasUnmodifiable(items); | 557 e.canExecute = isFolder && canEdit && !hasUnmodifiable(items); |
553 command.hidden = !isFolder; | 558 command.hidden = !isFolder; |
554 } | 559 } |
555 break; | 560 break; |
556 | 561 |
557 case 'edit-command': | 562 case 'edit-command': |
558 // Show the edit command if not a folder. | 563 // Show the edit command if not a folder. |
559 var items = list.selectedItems; | 564 var items = bmm.list.selectedItems; |
560 if (items.length != 1) { | 565 if (items.length != 1) { |
561 e.canExecute = false; | 566 e.canExecute = false; |
562 command.hidden = false; | 567 command.hidden = false; |
563 } else { | 568 } else { |
564 var isFolder = bmm.isFolder(items[0]); | 569 var isFolder = bmm.isFolder(items[0]); |
565 e.canExecute = !isFolder && canEdit && !hasUnmodifiable(items); | 570 e.canExecute = !isFolder && canEdit && !hasUnmodifiable(items); |
566 command.hidden = isFolder; | 571 command.hidden = isFolder; |
567 } | 572 } |
568 break; | 573 break; |
569 | 574 |
570 case 'show-in-folder-command': | 575 case 'show-in-folder-command': |
571 e.canExecute = isSearch() && hasSingleSelected(); | 576 e.canExecute = isSearch() && hasSingleSelected(); |
572 break; | 577 break; |
573 | 578 |
574 case 'delete-command': | 579 case 'delete-command': |
575 case 'cut-command': | 580 case 'cut-command': |
576 e.canExecute = canCopyItems() && canEdit && | 581 e.canExecute = canCopyItems() && canEdit && |
577 !hasUnmodifiable(list.selectedItems); | 582 !hasUnmodifiable(bmm.list.selectedItems); |
578 break; | 583 break; |
579 | 584 |
580 case 'copy-command': | 585 case 'copy-command': |
581 e.canExecute = canCopyItems(); | 586 e.canExecute = canCopyItems(); |
582 break; | 587 break; |
583 | 588 |
584 case 'open-in-same-window-command': | 589 case 'open-in-same-window-command': |
585 e.canExecute = hasSelected(); | 590 e.canExecute = hasSelected(); |
586 break; | 591 break; |
587 | 592 |
588 default: | 593 default: |
589 canExecuteShared(e, isSearch()); | 594 canExecuteShared(e, isSearch()); |
590 } | 595 } |
591 } | 596 } |
592 | 597 |
593 // Update canExecute for the commands when the list is the active element. | 598 // Update canExecute for the commands when the list is the active element. |
594 function handleCanExecuteForList(e) { | 599 function handleCanExecuteForList(e) { |
595 if (e.target != list) return; | 600 if (e.target != bmm.list) return; |
596 canExecuteForList(e); | 601 canExecuteForList(e); |
597 } | 602 } |
598 | 603 |
599 // Update canExecute for the commands when the tree is the active element. | 604 // Update canExecute for the commands when the tree is the active element. |
600 function handleCanExecuteForTree(e) { | 605 function handleCanExecuteForTree(e) { |
601 if (e.target != tree) return; | 606 if (e.target != bmm.tree) return; |
602 | 607 |
603 var command = e.command; | 608 var command = e.command; |
604 var commandId = command.id; | 609 var commandId = command.id; |
605 | 610 |
606 function hasSelected() { | 611 function hasSelected() { |
607 return !!e.target.selectedItem; | 612 return !!e.target.selectedItem; |
608 } | 613 } |
609 | 614 |
610 function isSearch() { | 615 function isSearch() { |
611 var item = e.target.selectedItem; | 616 var item = e.target.selectedItem; |
612 return item == searchTreeItem; | 617 return item == searchTreeItem; |
613 } | 618 } |
614 | 619 |
615 function isTopLevelItem() { | 620 function isTopLevelItem() { |
616 return e.target.selectedItem.parentNode == tree; | 621 return e.target.selectedItem.parentNode == bmm.tree; |
617 } | 622 } |
618 | 623 |
619 switch (commandId) { | 624 switch (commandId) { |
620 case 'rename-folder-command': | 625 case 'rename-folder-command': |
621 command.hidden = false; | 626 command.hidden = false; |
622 e.canExecute = hasSelected() && !isTopLevelItem() && canEdit && | 627 e.canExecute = hasSelected() && !isTopLevelItem() && canEdit && |
623 !hasUnmodifiable(tree.selectedFolders); | 628 !hasUnmodifiable(bmm.tree.selectedFolders); |
624 break; | 629 break; |
625 | 630 |
626 case 'edit-command': | 631 case 'edit-command': |
627 command.hidden = true; | 632 command.hidden = true; |
628 e.canExecute = false; | 633 e.canExecute = false; |
629 break; | 634 break; |
630 | 635 |
631 case 'delete-command': | 636 case 'delete-command': |
632 case 'cut-command': | 637 case 'cut-command': |
633 e.canExecute = hasSelected() && !isTopLevelItem() && canEdit && | 638 e.canExecute = hasSelected() && !isTopLevelItem() && canEdit && |
634 !hasUnmodifiable(tree.selectedFolders); | 639 !hasUnmodifiable(bmm.tree.selectedFolders); |
635 break; | 640 break; |
636 | 641 |
637 case 'copy-command': | 642 case 'copy-command': |
638 e.canExecute = hasSelected() && !isTopLevelItem(); | 643 e.canExecute = hasSelected() && !isTopLevelItem(); |
639 break; | 644 break; |
640 | 645 |
641 default: | 646 default: |
642 canExecuteShared(e, isSearch()); | 647 canExecuteShared(e, isSearch()); |
643 } | 648 } |
644 } | 649 } |
(...skipping 17 matching lines...) Expand all Loading... |
662 if (result != canEdit) { | 667 if (result != canEdit) { |
663 canEdit = result; | 668 canEdit = result; |
664 editingCommands.forEach(function(baseId) { | 669 editingCommands.forEach(function(baseId) { |
665 $(baseId + '-command').canExecuteChange(); | 670 $(baseId + '-command').canExecuteChange(); |
666 }); | 671 }); |
667 } | 672 } |
668 }); | 673 }); |
669 } | 674 } |
670 | 675 |
671 function handleChangeForTree(e) { | 676 function handleChangeForTree(e) { |
672 navigateTo(tree.selectedItem.bookmarkId); | 677 navigateTo(bmm.tree.selectedItem.bookmarkId); |
673 } | 678 } |
674 | 679 |
675 function handleOrganizeButtonClick(e) { | 680 function handleOrganizeButtonClick(e) { |
676 updateEditingCommands(); | 681 updateEditingCommands(); |
677 $('add-new-bookmark-command').canExecuteChange(); | 682 $('add-new-bookmark-command').canExecuteChange(); |
678 $('new-folder-command').canExecuteChange(); | 683 $('new-folder-command').canExecuteChange(); |
679 $('sort-command').canExecuteChange(); | 684 $('sort-command').canExecuteChange(); |
680 } | 685 } |
681 | 686 |
682 function handleRename(e) { | 687 function handleRename(e) { |
683 var item = e.target; | 688 var item = e.target; |
684 var bookmarkNode = item.bookmarkNode; | 689 var bookmarkNode = item.bookmarkNode; |
685 chrome.bookmarks.update(bookmarkNode.id, {title: item.label}); | 690 chrome.bookmarks.update(bookmarkNode.id, {title: item.label}); |
686 performGlobalUndo = null; // This can't be undone, so disable global undo. | 691 performGlobalUndo = null; // This can't be undone, so disable global undo. |
687 } | 692 } |
688 | 693 |
689 function handleEdit(e) { | 694 function handleEdit(e) { |
690 var item = e.target; | 695 var item = e.target; |
691 var bookmarkNode = item.bookmarkNode; | 696 var bookmarkNode = item.bookmarkNode; |
692 var context = { | 697 var context = { |
693 title: bookmarkNode.title | 698 title: bookmarkNode.title |
694 }; | 699 }; |
695 if (!bmm.isFolder(bookmarkNode)) | 700 if (!bmm.isFolder(bookmarkNode)) |
696 context.url = bookmarkNode.url; | 701 context.url = bookmarkNode.url; |
697 | 702 |
698 if (bookmarkNode.id == 'new') { | 703 if (bookmarkNode.id == 'new') { |
699 selectItemsAfterUserAction(list); | 704 selectItemsAfterUserAction(/** @type {BookmarkList} */(bmm.list)); |
700 | 705 |
701 // New page | 706 // New page |
702 context.parentId = bookmarkNode.parentId; | 707 context.parentId = bookmarkNode.parentId; |
703 chrome.bookmarks.create(context, function(node) { | 708 chrome.bookmarks.create(context, function(node) { |
704 // A new node was created and will get added to the list due to the | 709 // A new node was created and will get added to the list due to the |
705 // handler. | 710 // handler. |
706 var dataModel = list.dataModel; | 711 var dataModel = bmm.list.dataModel; |
707 var index = dataModel.indexOf(bookmarkNode); | 712 var index = dataModel.indexOf(bookmarkNode); |
708 dataModel.splice(index, 1); | 713 dataModel.splice(index, 1); |
709 | 714 |
710 // Select new item. | 715 // Select new item. |
711 var newIndex = dataModel.findIndexById(node.id); | 716 var newIndex = dataModel.findIndexById(node.id); |
712 if (newIndex != -1) { | 717 if (newIndex != -1) { |
713 var sm = list.selectionModel; | 718 var sm = bmm.list.selectionModel; |
714 list.scrollIndexIntoView(newIndex); | 719 bmm.list.scrollIndexIntoView(newIndex); |
715 sm.leadIndex = sm.anchorIndex = sm.selectedIndex = newIndex; | 720 sm.leadIndex = sm.anchorIndex = sm.selectedIndex = newIndex; |
716 } | 721 } |
717 }); | 722 }); |
718 } else { | 723 } else { |
719 // Edit | 724 // Edit |
720 chrome.bookmarks.update(bookmarkNode.id, context); | 725 chrome.bookmarks.update(bookmarkNode.id, context); |
721 } | 726 } |
722 performGlobalUndo = null; // This can't be undone, so disable global undo. | 727 performGlobalUndo = null; // This can't be undone, so disable global undo. |
723 } | 728 } |
724 | 729 |
725 function handleCancelEdit(e) { | 730 function handleCancelEdit(e) { |
726 var item = e.target; | 731 var item = e.target; |
727 var bookmarkNode = item.bookmarkNode; | 732 var bookmarkNode = item.bookmarkNode; |
728 if (bookmarkNode.id == 'new') { | 733 if (bookmarkNode.id == 'new') { |
729 var dataModel = list.dataModel; | 734 var dataModel = bmm.list.dataModel; |
730 var index = dataModel.findIndexById('new'); | 735 var index = dataModel.findIndexById('new'); |
731 dataModel.splice(index, 1); | 736 dataModel.splice(index, 1); |
732 } | 737 } |
733 } | 738 } |
734 | 739 |
735 /** | 740 /** |
736 * Navigates to the folder that the selected item is in and selects it. This is | 741 * Navigates to the folder that the selected item is in and selects it. This is |
737 * used for the show-in-folder command. | 742 * used for the show-in-folder command. |
738 */ | 743 */ |
739 function showInFolder() { | 744 function showInFolder() { |
740 var bookmarkNode = list.selectedItem; | 745 var bookmarkNode = bmm.list.selectedItem; |
741 if (!bookmarkNode) | 746 if (!bookmarkNode) |
742 return; | 747 return; |
743 var parentId = bookmarkNode.parentId; | 748 var parentId = bookmarkNode.parentId; |
744 | 749 |
745 // After the list is loaded we should select the revealed item. | 750 // After the list is loaded we should select the revealed item. |
746 function selectItem() { | 751 function selectItem() { |
747 var index = list.dataModel.findIndexById(bookmarkNode.id); | 752 var index = bmm.list.dataModel.findIndexById(bookmarkNode.id); |
748 if (index == -1) | 753 if (index == -1) |
749 return; | 754 return; |
750 var sm = list.selectionModel; | 755 var sm = bmm.list.selectionModel; |
751 sm.anchorIndex = sm.leadIndex = sm.selectedIndex = index; | 756 sm.anchorIndex = sm.leadIndex = sm.selectedIndex = index; |
752 list.scrollIndexIntoView(index); | 757 bmm.list.scrollIndexIntoView(index); |
753 } | 758 } |
754 | 759 |
755 var treeItem = bmm.treeLookup[parentId]; | 760 var treeItem = bmm.treeLookup[parentId]; |
756 treeItem.reveal(); | 761 treeItem.reveal(); |
757 | 762 |
758 navigateTo(parentId, selectItem); | 763 navigateTo(parentId, selectItem); |
759 } | 764 } |
760 | 765 |
761 /** | 766 /** |
762 * @return {!cr.LinkController} The link controller used to open links based on | 767 * @return {!cr.LinkController} The link controller used to open links based on |
763 * user clicks and keyboard actions. | 768 * user clicks and keyboard actions. |
764 */ | 769 */ |
765 function getLinkController() { | 770 function getLinkController() { |
766 return linkController || | 771 return linkController || |
767 (linkController = new cr.LinkController(loadTimeData)); | 772 (linkController = new cr.LinkController(loadTimeData)); |
768 } | 773 } |
769 | 774 |
770 /** | 775 /** |
771 * Returns the selected bookmark nodes of the provided tree or list. | 776 * Returns the selected bookmark nodes of the provided tree or list. |
772 * If |opt_target| is not provided or null the active element is used. | 777 * If |opt_target| is not provided or null the active element is used. |
773 * Only call this if the list or the tree is focused. | 778 * Only call this if the list or the tree is focused. |
774 * @param {BookmarkList|BookmarkTree} opt_target The target list or tree. | 779 * @param {(BookmarkList|BookmarkTree)=} opt_target The target list or tree. |
775 * @return {!Array} Array of bookmark nodes. | 780 * @return {!Array} Array of bookmark nodes. |
776 */ | 781 */ |
777 function getSelectedBookmarkNodes(opt_target) { | 782 function getSelectedBookmarkNodes(opt_target) { |
778 return (opt_target || document.activeElement) == tree ? | 783 return (opt_target || document.activeElement) == bmm.tree ? |
779 tree.selectedFolders : list.selectedItems; | 784 bmm.tree.selectedFolders : bmm.list.selectedItems; |
780 } | 785 } |
781 | 786 |
782 /** | 787 /** |
783 * @return {!Array.<string>} An array of the selected bookmark IDs. | 788 * @return {!Array.<string>} An array of the selected bookmark IDs. |
784 */ | 789 */ |
785 function getSelectedBookmarkIds() { | 790 function getSelectedBookmarkIds() { |
786 var selectedNodes = getSelectedBookmarkNodes(); | 791 var selectedNodes = getSelectedBookmarkNodes(); |
787 selectedNodes.sort(function(a, b) { return a.index - b.index }); | 792 selectedNodes.sort(function(a, b) { return a.index - b.index }); |
788 return selectedNodes.map(function(node) { | 793 return selectedNodes.map(function(node) { |
789 return node.id; | 794 return node.id; |
790 }); | 795 }); |
791 } | 796 } |
792 | 797 |
793 /** | 798 /** |
794 * @param {BookmarkTreeNode} node The node to test. | 799 * @param {BookmarkTreeNode} node The node to test. |
795 * @return {boolean} Whether the given node is unmodifiable. | 800 * @return {boolean} Whether the given node is unmodifiable. |
796 */ | 801 */ |
797 function isUnmodifiable(node) { | 802 function isUnmodifiable(node) { |
798 return node && node.unmodifiable; | 803 return !!(node && node.unmodifiable); |
799 } | 804 } |
800 | 805 |
801 /** | 806 /** |
802 * @param {BookmarkList} A list of BookmarkNodes. | 807 * @param {Array.<BookmarkTreeNode>} nodes A list of BookmarkTreeNodes. |
803 * @return {boolean} Whether any of the nodes is managed. | 808 * @return {boolean} Whether any of the nodes is managed. |
804 */ | 809 */ |
805 function hasUnmodifiable(nodes) { | 810 function hasUnmodifiable(nodes) { |
806 return nodes.some(isUnmodifiable); | 811 return nodes.some(isUnmodifiable); |
807 } | 812 } |
808 | 813 |
809 /** | 814 /** |
810 * Opens the selected bookmarks. | 815 * Opens the selected bookmarks. |
811 * @param {LinkKind} kind The kind of link we want to open. | 816 * @param {cr.LinkKind} kind The kind of link we want to open. |
812 * @param {HTMLElement} opt_eventTarget The target of the user initiated event. | 817 * @param {HTMLElement=} opt_eventTarget The target of the user initiated event. |
813 */ | 818 */ |
814 function openBookmarks(kind, opt_eventTarget) { | 819 function openBookmarks(kind, opt_eventTarget) { |
815 // If we have selected any folders, we need to find all the bookmarks one | 820 // If we have selected any folders, we need to find all the bookmarks one |
816 // level down. We use multiple async calls to getSubtree instead of getting | 821 // level down. We use multiple async calls to getSubtree instead of getting |
817 // the whole tree since we would like to minimize the amount of data sent. | 822 // the whole tree since we would like to minimize the amount of data sent. |
818 | 823 |
819 var urlsP = getUrlsForOpenCommands(opt_eventTarget); | 824 var urlsP = getUrlsForOpenCommands(opt_eventTarget ? opt_eventTarget : null); |
820 urlsP.then(function(urls) { | 825 urlsP.then(function(urls) { |
821 getLinkController().openUrls(urls, kind); | 826 getLinkController().openUrls(assert(urls), kind); |
822 chrome.bookmarkManagerPrivate.recordLaunch(); | 827 chrome.bookmarkManagerPrivate.recordLaunch(); |
823 }); | 828 }); |
824 } | 829 } |
825 | 830 |
826 /** | 831 /** |
827 * Opens an item in the list. | 832 * Opens an item in the list. |
828 */ | 833 */ |
829 function openItem() { | 834 function openItem() { |
830 var bookmarkNodes = getSelectedBookmarkNodes(); | 835 var bookmarkNodes = getSelectedBookmarkNodes(); |
831 // If we double clicked or pressed enter on a single folder, navigate to it. | 836 // If we double clicked or pressed enter on a single folder, navigate to it. |
832 if (bookmarkNodes.length == 1 && bmm.isFolder(bookmarkNodes[0])) | 837 if (bookmarkNodes.length == 1 && bmm.isFolder(bookmarkNodes[0])) |
833 navigateTo(bookmarkNodes[0].id); | 838 navigateTo(bookmarkNodes[0].id); |
834 else | 839 else |
835 openBookmarks(LinkKind.FOREGROUND_TAB); | 840 openBookmarks(LinkKind.FOREGROUND_TAB); |
836 } | 841 } |
837 | 842 |
838 /** | 843 /** |
839 * Refreshes search results after delete or undo-delete. | 844 * Refreshes search results after delete or undo-delete. |
840 * This ensures children of deleted folders do not remain in results | 845 * This ensures children of deleted folders do not remain in results |
841 */ | 846 */ |
842 function updateSearchResults() { | 847 function updateSearchResults() { |
843 if (list.isSearch()) { | 848 if (bmm.list.isSearch()) |
844 list.reload(); | 849 bmm.list.reload(); |
845 } | |
846 } | 850 } |
847 | 851 |
848 /** | 852 /** |
849 * Deletes the selected bookmarks. The bookmarks are saved in memory in case | 853 * Deletes the selected bookmarks. The bookmarks are saved in memory in case |
850 * the user needs to undo the deletion. | 854 * the user needs to undo the deletion. |
851 */ | 855 */ |
852 function deleteBookmarks() { | 856 function deleteBookmarks() { |
853 var selectedIds = getSelectedBookmarkIds(); | 857 var selectedIds = getSelectedBookmarkIds(); |
854 var filteredIds = getFilteredSelectedBookmarkIds(); | 858 var filteredIds = getFilteredSelectedBookmarkIds(); |
855 lastDeletedNodes = []; | 859 lastDeletedNodes = []; |
(...skipping 16 matching lines...) Expand all Loading... |
872 performDelete(); | 876 performDelete(); |
873 updateSearchResults(); | 877 updateSearchResults(); |
874 } | 878 } |
875 }); | 879 }); |
876 }); | 880 }); |
877 } | 881 } |
878 | 882 |
879 /** | 883 /** |
880 * Restores a tree of bookmarks under a specified folder. | 884 * Restores a tree of bookmarks under a specified folder. |
881 * @param {BookmarkTreeNode} node The node to restore. | 885 * @param {BookmarkTreeNode} node The node to restore. |
882 * @param {=string} parentId The ID of the folder to restore under. If not | 886 * @param {(string|number)=} opt_parentId If a string is passed, it's the ID of |
883 * specified, the original parentId of the node will be used. | 887 * the folder to restore under. If not specified or a number is passed, the |
| 888 * original parentId of the node will be used. |
884 */ | 889 */ |
885 function restoreTree(node, parentId) { | 890 function restoreTree(node, opt_parentId) { |
886 var bookmarkInfo = { | 891 var bookmarkInfo = { |
887 parentId: parentId || node.parentId, | 892 parentId: typeof opt_parentId == 'string' ? opt_parentId : node.parentId, |
888 title: node.title, | 893 title: node.title, |
889 index: node.index, | 894 index: node.index, |
890 url: node.url | 895 url: node.url |
891 }; | 896 }; |
892 | 897 |
893 chrome.bookmarks.create(bookmarkInfo, function(result) { | 898 chrome.bookmarks.create(bookmarkInfo, function(result) { |
894 if (!result) { | 899 if (!result) { |
895 console.error('Failed to restore bookmark.'); | 900 console.error('Failed to restore bookmark.'); |
896 return; | 901 return; |
897 } | 902 } |
(...skipping 21 matching lines...) Expand all Loading... |
919 | 924 |
920 // Only a single level of undo is supported, so disable global undo now. | 925 // Only a single level of undo is supported, so disable global undo now. |
921 performGlobalUndo = null; | 926 performGlobalUndo = null; |
922 } | 927 } |
923 | 928 |
924 /** | 929 /** |
925 * Computes folder for "Add Page" and "Add Folder". | 930 * Computes folder for "Add Page" and "Add Folder". |
926 * @return {string} The id of folder node where we'll create new page/folder. | 931 * @return {string} The id of folder node where we'll create new page/folder. |
927 */ | 932 */ |
928 function computeParentFolderForNewItem() { | 933 function computeParentFolderForNewItem() { |
929 if (document.activeElement == tree) | 934 if (document.activeElement == bmm.tree) |
930 return list.parentId; | 935 return bmm.list.parentId; |
931 var selectedItem = list.selectedItem; | 936 var selectedItem = bmm.list.selectedItem; |
932 return selectedItem && bmm.isFolder(selectedItem) ? | 937 return selectedItem && bmm.isFolder(selectedItem) ? |
933 selectedItem.id : list.parentId; | 938 selectedItem.id : bmm.list.parentId; |
934 } | 939 } |
935 | 940 |
936 /** | 941 /** |
937 * Callback for rename folder and edit command. This starts editing for | 942 * Callback for rename folder and edit command. This starts editing for |
938 * selected item. | 943 * selected item. |
939 */ | 944 */ |
940 function editSelectedItem() { | 945 function editSelectedItem() { |
941 if (document.activeElement == tree) { | 946 if (document.activeElement == bmm.tree) { |
942 tree.selectedItem.editing = true; | 947 bmm.tree.selectedItem.editing = true; |
943 } else { | 948 } else { |
944 var li = list.getListItem(list.selectedItem); | 949 var li = bmm.list.getListItem(bmm.list.selectedItem); |
945 if (li) | 950 if (li) |
946 li.editing = true; | 951 li.editing = true; |
947 } | 952 } |
948 } | 953 } |
949 | 954 |
950 /** | 955 /** |
951 * Callback for the new folder command. This creates a new folder and starts | 956 * Callback for the new folder command. This creates a new folder and starts |
952 * a rename of it. | 957 * a rename of it. |
953 */ | 958 */ |
954 function newFolder() { | 959 function newFolder() { |
955 performGlobalUndo = null; // This can't be undone, so disable global undo. | 960 performGlobalUndo = null; // This can't be undone, so disable global undo. |
956 | 961 |
957 var parentId = computeParentFolderForNewItem(); | 962 var parentId = computeParentFolderForNewItem(); |
958 | 963 |
959 // Callback is called after tree and list data model updated. | 964 // Callback is called after tree and list data model updated. |
960 function createFolder(callback) { | 965 function createFolder(callback) { |
961 chrome.bookmarks.create({ | 966 chrome.bookmarks.create({ |
962 title: loadTimeData.getString('new_folder_name'), | 967 title: loadTimeData.getString('new_folder_name'), |
963 parentId: parentId | 968 parentId: parentId |
964 }, callback); | 969 }, callback); |
965 } | 970 } |
966 | 971 |
967 if (document.activeElement == tree) { | 972 if (document.activeElement == bmm.tree) { |
968 createFolder(function(newNode) { | 973 createFolder(function(newNode) { |
969 navigateTo(newNode.id, function() { | 974 navigateTo(newNode.id, function() { |
970 bmm.treeLookup[newNode.id].editing = true; | 975 bmm.treeLookup[newNode.id].editing = true; |
971 }); | 976 }); |
972 }); | 977 }); |
973 return; | 978 return; |
974 } | 979 } |
975 | 980 |
976 function editNewFolderInList() { | 981 function editNewFolderInList() { |
977 createFolder(function() { | 982 createFolder(function() { |
978 var index = list.dataModel.length - 1; | 983 var index = bmm.list.dataModel.length - 1; |
979 var sm = list.selectionModel; | 984 var sm = bmm.list.selectionModel; |
980 sm.anchorIndex = sm.leadIndex = sm.selectedIndex = index; | 985 sm.anchorIndex = sm.leadIndex = sm.selectedIndex = index; |
981 scrollIntoViewAndMakeEditable(index); | 986 scrollIntoViewAndMakeEditable(index); |
982 }); | 987 }); |
983 } | 988 } |
984 | 989 |
985 navigateTo(parentId, editNewFolderInList); | 990 navigateTo(parentId, editNewFolderInList); |
986 } | 991 } |
987 | 992 |
988 /** | 993 /** |
989 * Scrolls the list item into view and makes it editable. | 994 * Scrolls the list item into view and makes it editable. |
990 * @param {number} index The index of the item to make editable. | 995 * @param {number} index The index of the item to make editable. |
991 */ | 996 */ |
992 function scrollIntoViewAndMakeEditable(index) { | 997 function scrollIntoViewAndMakeEditable(index) { |
993 list.scrollIndexIntoView(index); | 998 bmm.list.scrollIndexIntoView(index); |
994 // onscroll is now dispatched asynchronously so we have to postpone | 999 // onscroll is now dispatched asynchronously so we have to postpone |
995 // the rest. | 1000 // the rest. |
996 setTimeout(function() { | 1001 setTimeout(function() { |
997 var item = list.getListItemByIndex(index); | 1002 var item = bmm.list.getListItemByIndex(index); |
998 if (item) | 1003 if (item) |
999 item.editing = true; | 1004 item.editing = true; |
1000 }); | 1005 }, 0); |
1001 } | 1006 } |
1002 | 1007 |
1003 /** | 1008 /** |
1004 * Adds a page to the current folder. This is called by the | 1009 * Adds a page to the current folder. This is called by the |
1005 * add-new-bookmark-command handler. | 1010 * add-new-bookmark-command handler. |
1006 */ | 1011 */ |
1007 function addPage() { | 1012 function addPage() { |
1008 var parentId = computeParentFolderForNewItem(); | 1013 var parentId = computeParentFolderForNewItem(); |
1009 | 1014 |
1010 function editNewBookmark() { | 1015 function editNewBookmark() { |
1011 var fakeNode = { | 1016 var fakeNode = { |
1012 title: '', | 1017 title: '', |
1013 url: '', | 1018 url: '', |
1014 parentId: parentId, | 1019 parentId: parentId, |
1015 id: 'new' | 1020 id: 'new' |
1016 }; | 1021 }; |
1017 var dataModel = list.dataModel; | 1022 var dataModel = bmm.list.dataModel; |
1018 var length = dataModel.length; | 1023 var length = dataModel.length; |
1019 dataModel.splice(length, 0, fakeNode); | 1024 dataModel.splice(length, 0, fakeNode); |
1020 var sm = list.selectionModel; | 1025 var sm = bmm.list.selectionModel; |
1021 sm.anchorIndex = sm.leadIndex = sm.selectedIndex = length; | 1026 sm.anchorIndex = sm.leadIndex = sm.selectedIndex = length; |
1022 scrollIntoViewAndMakeEditable(length); | 1027 scrollIntoViewAndMakeEditable(length); |
1023 }; | 1028 }; |
1024 | 1029 |
1025 navigateTo(parentId, editNewBookmark); | 1030 navigateTo(parentId, editNewBookmark); |
1026 } | 1031 } |
1027 | 1032 |
1028 /** | 1033 /** |
1029 * This function is used to select items after a user action such as paste, drop | 1034 * This function is used to select items after a user action such as paste, drop |
1030 * add page etc. | 1035 * add page etc. |
1031 * @param {BookmarkList|BookmarkTree} target The target of the user action. | 1036 * @param {BookmarkList|BookmarkTree} target The target of the user action. |
1032 * @param {=string} opt_selectedTreeId If provided, then select that tree id. | 1037 * @param {string=} opt_selectedTreeId If provided, then select that tree id. |
1033 */ | 1038 */ |
1034 function selectItemsAfterUserAction(target, opt_selectedTreeId) { | 1039 function selectItemsAfterUserAction(target, opt_selectedTreeId) { |
1035 // We get one onCreated event per item so we delay the handling until we get | 1040 // We get one onCreated event per item so we delay the handling until we get |
1036 // no more events coming. | 1041 // no more events coming. |
1037 | 1042 |
1038 var ids = []; | 1043 var ids = []; |
1039 var timer; | 1044 var timer; |
1040 | 1045 |
1041 function handle(id, bookmarkNode) { | 1046 function handle(id, bookmarkNode) { |
1042 clearTimeout(timer); | 1047 clearTimeout(timer); |
1043 if (opt_selectedTreeId || list.parentId == bookmarkNode.parentId) | 1048 if (opt_selectedTreeId || bmm.list.parentId == bookmarkNode.parentId) |
1044 ids.push(id); | 1049 ids.push(id); |
1045 timer = setTimeout(handleTimeout, 50); | 1050 timer = setTimeout(handleTimeout, 50); |
1046 } | 1051 } |
1047 | 1052 |
1048 function handleTimeout() { | 1053 function handleTimeout() { |
1049 chrome.bookmarks.onCreated.removeListener(handle); | 1054 chrome.bookmarks.onCreated.removeListener(handle); |
1050 chrome.bookmarks.onMoved.removeListener(handle); | 1055 chrome.bookmarks.onMoved.removeListener(handle); |
1051 | 1056 |
1052 if (opt_selectedTreeId && ids.indexOf(opt_selectedTreeId) != -1) { | 1057 if (opt_selectedTreeId && ids.indexOf(opt_selectedTreeId) != -1) { |
1053 var index = ids.indexOf(opt_selectedTreeId); | 1058 var index = ids.indexOf(opt_selectedTreeId); |
1054 if (index != -1 && opt_selectedTreeId in bmm.treeLookup) { | 1059 if (index != -1 && opt_selectedTreeId in bmm.treeLookup) { |
1055 tree.selectedItem = bmm.treeLookup[opt_selectedTreeId]; | 1060 bmm.tree.selectedItem = bmm.treeLookup[opt_selectedTreeId]; |
1056 } | 1061 } |
1057 } else if (target == list) { | 1062 } else if (target == bmm.list) { |
1058 var dataModel = list.dataModel; | 1063 var dataModel = bmm.list.dataModel; |
1059 var firstIndex = dataModel.findIndexById(ids[0]); | 1064 var firstIndex = dataModel.findIndexById(ids[0]); |
1060 var lastIndex = dataModel.findIndexById(ids[ids.length - 1]); | 1065 var lastIndex = dataModel.findIndexById(ids[ids.length - 1]); |
1061 if (firstIndex != -1 && lastIndex != -1) { | 1066 if (firstIndex != -1 && lastIndex != -1) { |
1062 var selectionModel = list.selectionModel; | 1067 var selectionModel = bmm.list.selectionModel; |
1063 selectionModel.selectedIndex = -1; | 1068 selectionModel.selectedIndex = -1; |
1064 selectionModel.selectRange(firstIndex, lastIndex); | 1069 selectionModel.selectRange(firstIndex, lastIndex); |
1065 selectionModel.anchorIndex = selectionModel.leadIndex = lastIndex; | 1070 selectionModel.anchorIndex = selectionModel.leadIndex = lastIndex; |
1066 list.focus(); | 1071 bmm.list.focus(); |
1067 } | 1072 } |
1068 } | 1073 } |
1069 | 1074 |
1070 list.endBatchUpdates(); | 1075 bmm.list.endBatchUpdates(); |
1071 } | 1076 } |
1072 | 1077 |
1073 list.startBatchUpdates(); | 1078 bmm.list.startBatchUpdates(); |
1074 | 1079 |
1075 chrome.bookmarks.onCreated.addListener(handle); | 1080 chrome.bookmarks.onCreated.addListener(handle); |
1076 chrome.bookmarks.onMoved.addListener(handle); | 1081 chrome.bookmarks.onMoved.addListener(handle); |
1077 timer = setTimeout(handleTimeout, 300); | 1082 timer = setTimeout(handleTimeout, 300); |
1078 } | 1083 } |
1079 | 1084 |
1080 /** | 1085 /** |
1081 * Record user action. | 1086 * Record user action. |
1082 * @param {string} name An user action name. | 1087 * @param {string} name An user action name. |
1083 */ | 1088 */ |
1084 function recordUserAction(name) { | 1089 function recordUserAction(name) { |
1085 chrome.metricsPrivate.recordUserAction('BookmarkManager_Command_' + name); | 1090 chrome.metricsPrivate.recordUserAction('BookmarkManager_Command_' + name); |
1086 } | 1091 } |
1087 | 1092 |
1088 /** | 1093 /** |
1089 * The currently selected bookmark, based on where the user is clicking. | 1094 * The currently selected bookmark, based on where the user is clicking. |
1090 * @return {string} The ID of the currently selected bookmark (could be from | 1095 * @return {string} The ID of the currently selected bookmark (could be from |
1091 * tree view or list view). | 1096 * tree view or list view). |
1092 */ | 1097 */ |
1093 function getSelectedId() { | 1098 function getSelectedId() { |
1094 if (document.activeElement == tree) | 1099 if (document.activeElement == bmm.tree) |
1095 return tree.selectedItem.bookmarkId; | 1100 return bmm.tree.selectedItem.bookmarkId; |
1096 var selectedItem = list.selectedItem; | 1101 var selectedItem = bmm.list.selectedItem; |
1097 return selectedItem && bmm.isFolder(selectedItem) ? | 1102 return selectedItem && bmm.isFolder(selectedItem) ? |
1098 selectedItem.id : tree.selectedItem.bookmarkId; | 1103 selectedItem.id : bmm.tree.selectedItem.bookmarkId; |
1099 } | 1104 } |
1100 | 1105 |
1101 /** | 1106 /** |
1102 * Pastes the copied/cutted bookmark into the right location depending whether | 1107 * Pastes the copied/cutted bookmark into the right location depending whether |
1103 * if it was called from Organize Menu or from Context Menu. | 1108 * if it was called from Organize Menu or from Context Menu. |
1104 * @param {string} id The id of the element being pasted from. | 1109 * @param {string} id The id of the element being pasted from. |
1105 */ | 1110 */ |
1106 function pasteBookmark(id) { | 1111 function pasteBookmark(id) { |
1107 recordUserAction('Paste'); | 1112 recordUserAction('Paste'); |
1108 selectItemsAfterUserAction(list); | 1113 selectItemsAfterUserAction(/** @type {BookmarkList} */(bmm.list)); |
1109 chrome.bookmarkManagerPrivate.paste(id, getSelectedBookmarkIds()); | 1114 chrome.bookmarkManagerPrivate.paste(id, getSelectedBookmarkIds()); |
1110 } | 1115 } |
1111 | 1116 |
1112 /** | 1117 /** |
1113 * Returns true if child is contained in another selected folder. | 1118 * Returns true if child is contained in another selected folder. |
1114 * Traces parent nodes up the tree until a selected ancestor or root is found. | 1119 * Traces parent nodes up the tree until a selected ancestor or root is found. |
1115 */ | 1120 */ |
1116 function hasSelectedAncestor(parentNode) { | 1121 function hasSelectedAncestor(parentNode) { |
1117 function contains(arr, item) { | 1122 function contains(arr, item) { |
1118 for (var i = 0; i < arr.length; i++) | 1123 for (var i = 0; i < arr.length; i++) |
1119 if (arr[i] === item) | 1124 if (arr[i] === item) |
1120 return true; | 1125 return true; |
1121 return false; | 1126 return false; |
1122 } | 1127 } |
1123 | 1128 |
1124 // Don't search top level, cannot select permanent nodes in search. | 1129 // Don't search top level, cannot select permanent nodes in search. |
1125 if (parentNode == null || parentNode.id <= 2) | 1130 if (parentNode == null || parentNode.id <= 2) |
1126 return false; | 1131 return false; |
1127 | 1132 |
1128 // Found selected ancestor. | 1133 // Found selected ancestor. |
1129 if (contains(getSelectedBookmarkNodes(), parentNode)) | 1134 if (contains(getSelectedBookmarkNodes(), parentNode)) |
1130 return true; | 1135 return true; |
1131 | 1136 |
1132 // Keep digging. | 1137 // Keep digging. |
1133 return hasSelectedAncestor(tree.getBookmarkNodeById(parentNode.parentId)); | 1138 return hasSelectedAncestor( |
| 1139 bmm.tree.getBookmarkNodeById(parentNode.parentId)); |
1134 } | 1140 } |
1135 | 1141 |
1136 function getFilteredSelectedBookmarkIds() { | 1142 function getFilteredSelectedBookmarkIds() { |
1137 // Remove duplicates from filteredIds and return. | 1143 // Remove duplicates from filteredIds and return. |
1138 var filteredIds = new Array(); | 1144 var filteredIds = new Array(); |
1139 // Selected nodes to iterate through for matches. | 1145 // Selected nodes to iterate through for matches. |
1140 var nodes = getSelectedBookmarkNodes(); | 1146 var nodes = getSelectedBookmarkNodes(); |
1141 | 1147 |
1142 for (var i = 0; i < nodes.length; i++) | 1148 for (var i = 0; i < nodes.length; i++) |
1143 if (!hasSelectedAncestor(tree.getBookmarkNodeById(nodes[i].parentId))) | 1149 if (!hasSelectedAncestor(bmm.tree.getBookmarkNodeById(nodes[i].parentId))) |
1144 filteredIds.splice(0, 0, nodes[i].id); | 1150 filteredIds.splice(0, 0, nodes[i].id); |
1145 | 1151 |
1146 return filteredIds; | 1152 return filteredIds; |
1147 } | 1153 } |
1148 | 1154 |
1149 /** | 1155 /** |
1150 * Handler for the command event. This is used for context menu of list/tree | 1156 * Handler for the command event. This is used for context menu of list/tree |
1151 * and organized menu. | 1157 * and organized menu. |
1152 * @param {!Event} e The event object. | 1158 * @param {!Event} e The event object. |
1153 */ | 1159 */ |
(...skipping 17 matching lines...) Expand all Loading... |
1171 recordUserAction('UndoNone'); | 1177 recordUserAction('UndoNone'); |
1172 } | 1178 } |
1173 break; | 1179 break; |
1174 case 'show-in-folder-command': | 1180 case 'show-in-folder-command': |
1175 recordUserAction('ShowInFolder'); | 1181 recordUserAction('ShowInFolder'); |
1176 showInFolder(); | 1182 showInFolder(); |
1177 break; | 1183 break; |
1178 case 'open-in-new-tab-command': | 1184 case 'open-in-new-tab-command': |
1179 case 'open-in-background-tab-command': | 1185 case 'open-in-background-tab-command': |
1180 recordUserAction('OpenInNewTab'); | 1186 recordUserAction('OpenInNewTab'); |
1181 openBookmarks(LinkKind.BACKGROUND_TAB, e.target); | 1187 openBookmarks(LinkKind.BACKGROUND_TAB, |
| 1188 assertInstanceof(e.target, HTMLElement)); |
1182 break; | 1189 break; |
1183 case 'open-in-new-window-command': | 1190 case 'open-in-new-window-command': |
1184 recordUserAction('OpenInNewWindow'); | 1191 recordUserAction('OpenInNewWindow'); |
1185 openBookmarks(LinkKind.WINDOW, e.target); | 1192 openBookmarks(LinkKind.WINDOW, |
| 1193 assertInstanceof(e.target, HTMLElement)); |
1186 break; | 1194 break; |
1187 case 'open-incognito-window-command': | 1195 case 'open-incognito-window-command': |
1188 recordUserAction('OpenIncognito'); | 1196 recordUserAction('OpenIncognito'); |
1189 openBookmarks(LinkKind.INCOGNITO, e.target); | 1197 openBookmarks(LinkKind.INCOGNITO, |
| 1198 assertInstanceof(e.target, HTMLElement)); |
1190 break; | 1199 break; |
1191 case 'delete-command': | 1200 case 'delete-command': |
1192 recordUserAction('Delete'); | 1201 recordUserAction('Delete'); |
1193 deleteBookmarks(); | 1202 deleteBookmarks(); |
1194 break; | 1203 break; |
1195 case 'copy-command': | 1204 case 'copy-command': |
1196 recordUserAction('Copy'); | 1205 recordUserAction('Copy'); |
1197 chrome.bookmarkManagerPrivate.copy(getSelectedBookmarkIds(), | 1206 chrome.bookmarkManagerPrivate.copy(getSelectedBookmarkIds(), |
1198 updatePasteCommand); | 1207 updatePasteCommand); |
1199 break; | 1208 break; |
1200 case 'cut-command': | 1209 case 'cut-command': |
1201 recordUserAction('Cut'); | 1210 recordUserAction('Cut'); |
1202 chrome.bookmarkManagerPrivate.cut(getSelectedBookmarkIds(), | 1211 chrome.bookmarkManagerPrivate.cut(getSelectedBookmarkIds(), |
1203 function() { | 1212 function() { |
1204 updatePasteCommand(); | 1213 updatePasteCommand(); |
1205 updateSearchResults(); | 1214 updateSearchResults(); |
1206 }); | 1215 }); |
1207 break; | 1216 break; |
1208 case 'paste-from-organize-menu-command': | 1217 case 'paste-from-organize-menu-command': |
1209 pasteBookmark(list.parentId); | 1218 pasteBookmark(bmm.list.parentId); |
1210 break; | 1219 break; |
1211 case 'paste-from-context-menu-command': | 1220 case 'paste-from-context-menu-command': |
1212 pasteBookmark(getSelectedId()); | 1221 pasteBookmark(getSelectedId()); |
1213 break; | 1222 break; |
1214 case 'sort-command': | 1223 case 'sort-command': |
1215 recordUserAction('Sort'); | 1224 recordUserAction('Sort'); |
1216 chrome.bookmarkManagerPrivate.sortChildren(list.parentId); | 1225 chrome.bookmarkManagerPrivate.sortChildren(bmm.list.parentId); |
1217 break; | 1226 break; |
1218 case 'rename-folder-command': | 1227 case 'rename-folder-command': |
1219 editSelectedItem(); | 1228 editSelectedItem(); |
1220 break; | 1229 break; |
1221 case 'edit-command': | 1230 case 'edit-command': |
1222 recordUserAction('Edit'); | 1231 recordUserAction('Edit'); |
1223 editSelectedItem(); | 1232 editSelectedItem(); |
1224 break; | 1233 break; |
1225 case 'new-folder-command': | 1234 case 'new-folder-command': |
1226 recordUserAction('NewFolder'); | 1235 recordUserAction('NewFolder'); |
(...skipping 12 matching lines...) Expand all Loading... |
1239 undoDelete(); | 1248 undoDelete(); |
1240 break; | 1249 break; |
1241 } | 1250 } |
1242 } | 1251 } |
1243 | 1252 |
1244 // Execute the copy, cut and paste commands when those events are dispatched by | 1253 // Execute the copy, cut and paste commands when those events are dispatched by |
1245 // the browser. This allows us to rely on the browser to handle the keyboard | 1254 // the browser. This allows us to rely on the browser to handle the keyboard |
1246 // shortcuts for these commands. | 1255 // shortcuts for these commands. |
1247 function installEventHandlerForCommand(eventName, commandId) { | 1256 function installEventHandlerForCommand(eventName, commandId) { |
1248 function handle(e) { | 1257 function handle(e) { |
1249 if (document.activeElement != list && document.activeElement != tree) | 1258 if (document.activeElement != bmm.list && |
| 1259 document.activeElement != bmm.tree) |
1250 return; | 1260 return; |
1251 var command = $(commandId); | 1261 var command = $(commandId); |
1252 if (!command.disabled) { | 1262 if (!command.disabled) { |
1253 command.execute(); | 1263 command.execute(); |
1254 if (e) | 1264 if (e) |
1255 e.preventDefault(); // Prevent the system beep. | 1265 e.preventDefault(); // Prevent the system beep. |
1256 } | 1266 } |
1257 } | 1267 } |
1258 if (eventName == 'paste') { | 1268 if (eventName == 'paste') { |
1259 // Paste is a bit special since we need to do an async call to see if we | 1269 // Paste is a bit special since we need to do an async call to see if we |
1260 // can paste because the paste command might not be up to date. | 1270 // can paste because the paste command might not be up to date. |
1261 document.addEventListener(eventName, function(e) { | 1271 document.addEventListener(eventName, function(e) { |
1262 updatePasteCommand(handle); | 1272 updatePasteCommand(handle); |
1263 }); | 1273 }); |
1264 } else { | 1274 } else { |
1265 document.addEventListener(eventName, handle); | 1275 document.addEventListener(eventName, handle); |
1266 } | 1276 } |
1267 } | 1277 } |
1268 | 1278 |
1269 function initializeSplitter() { | 1279 function initializeSplitter() { |
1270 var splitter = document.querySelector('.main > .splitter'); | 1280 var splitter = document.querySelector('.main > .splitter'); |
1271 Splitter.decorate(splitter); | 1281 Splitter.decorate(splitter); |
1272 | 1282 |
1273 // The splitter persists the size of the left component in the local store. | 1283 // The splitter persists the size of the left component in the local store. |
1274 if ('treeWidth' in localStorage) | 1284 if ('treeWidth' in window.localStorage) |
1275 splitter.previousElementSibling.style.width = localStorage['treeWidth']; | 1285 splitter.previousElementSibling.style.width = |
| 1286 window.localStorage['treeWidth']; |
1276 | 1287 |
1277 splitter.addEventListener('resize', function(e) { | 1288 splitter.addEventListener('resize', function(e) { |
1278 localStorage['treeWidth'] = splitter.previousElementSibling.style.width; | 1289 window.localStorage['treeWidth'] = |
| 1290 splitter.previousElementSibling.style.width; |
1279 }); | 1291 }); |
1280 } | 1292 } |
1281 | 1293 |
1282 function initializeBookmarkManager() { | 1294 function initializeBookmarkManager() { |
1283 // Sometimes the extension API is not initialized. | 1295 // Sometimes the extension API is not initialized. |
1284 if (!chrome.bookmarks) | 1296 if (!chrome.bookmarks) |
1285 console.error('Bookmarks extension API is not available'); | 1297 console.error('Bookmarks extension API is not available'); |
1286 | 1298 |
1287 chrome.bookmarkManagerPrivate.getStrings(continueInitializeBookmarkManager); | 1299 chrome.bookmarkManagerPrivate.getStrings(continueInitializeBookmarkManager); |
1288 } | 1300 } |
1289 | 1301 |
1290 function continueInitializeBookmarkManager(localizedStrings) { | 1302 function continueInitializeBookmarkManager(localizedStrings) { |
1291 loadLocalizedStrings(localizedStrings); | 1303 loadLocalizedStrings(localizedStrings); |
1292 | 1304 |
1293 bmm.treeLookup[searchTreeItem.bookmarkId] = searchTreeItem; | 1305 bmm.treeLookup[searchTreeItem.bookmarkId] = searchTreeItem; |
1294 | 1306 |
1295 cr.ui.decorate('menu', Menu); | 1307 cr.ui.decorate('menu', Menu); |
1296 cr.ui.decorate('button[menu]', MenuButton); | 1308 cr.ui.decorate('button[menu]', MenuButton); |
1297 cr.ui.decorate('command', Command); | 1309 cr.ui.decorate('command', Command); |
1298 BookmarkList.decorate(list); | 1310 BookmarkList.decorate($('list')); |
1299 BookmarkTree.decorate(tree); | 1311 BookmarkTree.decorate($('tree')); |
1300 | 1312 |
1301 list.addEventListener('canceledit', handleCancelEdit); | 1313 bmm.list.addEventListener('canceledit', handleCancelEdit); |
1302 list.addEventListener('canExecute', handleCanExecuteForList); | 1314 bmm.list.addEventListener('canExecute', handleCanExecuteForList); |
1303 list.addEventListener('change', updateAllCommands); | 1315 bmm.list.addEventListener('change', updateAllCommands); |
1304 list.addEventListener('contextmenu', updateEditingCommands); | 1316 bmm.list.addEventListener('contextmenu', updateEditingCommands); |
1305 list.addEventListener('dblclick', handleDoubleClickForList); | 1317 bmm.list.addEventListener('dblclick', handleDoubleClickForList); |
1306 list.addEventListener('edit', handleEdit); | 1318 bmm.list.addEventListener('edit', handleEdit); |
1307 list.addEventListener('rename', handleRename); | 1319 bmm.list.addEventListener('rename', handleRename); |
1308 list.addEventListener('urlClicked', handleUrlClickedForList); | 1320 bmm.list.addEventListener('urlClicked', handleUrlClickedForList); |
1309 | 1321 |
1310 tree.addEventListener('canExecute', handleCanExecuteForTree); | 1322 bmm.tree.addEventListener('canExecute', handleCanExecuteForTree); |
1311 tree.addEventListener('change', handleChangeForTree); | 1323 bmm.tree.addEventListener('change', handleChangeForTree); |
1312 tree.addEventListener('contextmenu', updateEditingCommands); | 1324 bmm.tree.addEventListener('contextmenu', updateEditingCommands); |
1313 tree.addEventListener('rename', handleRename); | 1325 bmm.tree.addEventListener('rename', handleRename); |
1314 tree.addEventListener('load', handleLoadForTree); | 1326 bmm.tree.addEventListener('load', handleLoadForTree); |
1315 | 1327 |
1316 cr.ui.contextMenuHandler.addContextMenuProperty(tree); | 1328 cr.ui.contextMenuHandler.addContextMenuProperty( |
1317 list.contextMenu = $('context-menu'); | 1329 /** @type {!Element} */(bmm.tree)); |
1318 tree.contextMenu = $('context-menu'); | 1330 bmm.list.contextMenu = $('context-menu'); |
| 1331 bmm.tree.contextMenu = $('context-menu'); |
1319 | 1332 |
1320 // We listen to hashchange so that we can update the currently shown folder | 1333 // We listen to hashchange so that we can update the currently shown folder |
1321 // when // the user goes back and forward in the history. | 1334 // when // the user goes back and forward in the history. |
1322 window.addEventListener('hashchange', processHash); | 1335 window.addEventListener('hashchange', processHash); |
1323 | 1336 |
1324 document.querySelector('header form').onsubmit = function(e) { | 1337 document.querySelector('header form').onsubmit = |
| 1338 /** @type {function(Event=)} */(function(e) { |
1325 setSearch($('term').value); | 1339 setSearch($('term').value); |
1326 e.preventDefault(); | 1340 e.preventDefault(); |
1327 }; | 1341 }); |
1328 | 1342 |
1329 $('term').addEventListener('search', handleSearch); | 1343 $('term').addEventListener('search', handleSearch); |
1330 | 1344 |
1331 document.querySelector('.summary button').addEventListener( | 1345 document.querySelector('.summary button').addEventListener( |
1332 'click', handleOrganizeButtonClick); | 1346 'click', handleOrganizeButtonClick); |
1333 | 1347 |
1334 document.addEventListener('canExecute', handleCanExecuteForDocument); | 1348 document.addEventListener('canExecute', handleCanExecuteForDocument); |
1335 document.addEventListener('command', handleCommand); | 1349 document.addEventListener('command', handleCommand); |
1336 | 1350 |
1337 // Listen to copy, cut and paste events and execute the associated commands. | 1351 // Listen to copy, cut and paste events and execute the associated commands. |
(...skipping 26 matching lines...) Expand all Loading... |
1364 }); | 1378 }); |
1365 | 1379 |
1366 chrome.bookmarkManagerPrivate.canOpenNewWindows(function(result) { | 1380 chrome.bookmarkManagerPrivate.canOpenNewWindows(function(result) { |
1367 canOpenNewWindows = result; | 1381 canOpenNewWindows = result; |
1368 }); | 1382 }); |
1369 | 1383 |
1370 cr.ui.FocusOutlineManager.forDocument(document); | 1384 cr.ui.FocusOutlineManager.forDocument(document); |
1371 initializeSplitter(); | 1385 initializeSplitter(); |
1372 bmm.addBookmarkModelListeners(); | 1386 bmm.addBookmarkModelListeners(); |
1373 dnd.init(selectItemsAfterUserAction); | 1387 dnd.init(selectItemsAfterUserAction); |
1374 tree.reload(); | 1388 bmm.tree.reload(); |
1375 } | 1389 } |
1376 | 1390 |
1377 initializeBookmarkManager(); | 1391 initializeBookmarkManager(); |
1378 })(); | 1392 })(); |
OLD | NEW |