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 = $('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) { |
165 if (list.parentId == id) | 164 if ($('list').parentId == id) |
Dan Beam
2014/09/23 02:46:56
cast to !Element here as you're already doing mayb
Vitaly Pavlenko
2014/09/23 22:20:55
Done.
| |
166 opt_callback(); | 165 opt_callback(); |
167 else | 166 else |
168 addOneShotEventListener(list, 'load', opt_callback); | 167 addOneShotEventListener(/** @type {!Element} */($('list')), 'load', |
168 opt_callback); | |
Dan Beam
2014/09/23 02:46:56
if () needs curlies
Vitaly Pavlenko
2014/09/23 22:20:55
Done.
| |
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 $('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 $('tree').selectedItem = bmm.treeLookup[id] || $('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 = $('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 = $('list').dataModel.findIndexById(bookmarkNode.id); |
208 if (index != -1) { | 208 if (index != -1) { |
209 var sm = list.selectionModel; | 209 var sm = $('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 navigateTo(bookmarkNode.parentId, editBookmark); |
216 }); | 216 }); |
217 | 217 |
218 // We handle the two cases of navigating to the bookmark to be edited | 218 // We handle the two cases of navigating to the bookmark to be edited |
219 // above. Don't run the standard navigation code below. | 219 // above. Don't run the standard navigation code below. |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
266 var id = searchTreeItem.bookmarkId = 'q=' + searchText; | 266 var id = searchTreeItem.bookmarkId = 'q=' + searchText; |
267 bmm.treeLookup[searchTreeItem.bookmarkId] = searchTreeItem; | 267 bmm.treeLookup[searchTreeItem.bookmarkId] = searchTreeItem; |
268 } | 268 } |
269 | 269 |
270 var input = $('term'); | 270 var input = $('term'); |
271 // Do not update the input if the user is actively using the text input. | 271 // Do not update the input if the user is actively using the text input. |
272 if (document.activeElement != input) | 272 if (document.activeElement != input) |
273 input.value = searchText; | 273 input.value = searchText; |
274 | 274 |
275 if (searchText) { | 275 if (searchText) { |
276 tree.add(searchTreeItem); | 276 $('tree').add(searchTreeItem); |
277 tree.selectedItem = searchTreeItem; | 277 $('tree').selectedItem = searchTreeItem; |
278 } else { | 278 } else { |
279 // Go "home". | 279 // Go "home". |
280 tree.selectedItem = tree.items[0]; | 280 $('tree').selectedItem = $('tree').items[0]; |
281 id = tree.selectedItem.bookmarkId; | 281 id = $('tree').selectedItem.bookmarkId; |
282 } | 282 } |
283 | 283 |
284 navigateTo(id); | 284 navigateTo(id); |
285 } | 285 } |
286 | 286 |
287 /** | 287 /** |
288 * This returns the user visible path to the folder where the bookmark is | 288 * This returns the user visible path to the folder where the bookmark is |
289 * located. | 289 * located. |
290 * @param {number} parentId The ID of the parent folder. | 290 * @param {number} parentId The ID of the parent folder. |
291 * @return {string} The path to the the bookmark, | 291 * @return {string} The path to the the bookmark, |
292 */ | 292 */ |
293 function getFolder(parentId) { | 293 function getFolder(parentId) { |
294 var parentNode = tree.getBookmarkNodeById(parentId); | 294 var parentNode = $('tree').getBookmarkNodeById(parentId); |
295 if (parentNode) { | 295 if (parentNode) { |
296 var s = parentNode.title; | 296 var s = parentNode.title; |
297 if (parentNode.parentId != bmm.ROOT_ID) { | 297 if (parentNode.parentId != bmm.ROOT_ID) { |
298 return getFolder(parentNode.parentId) + '/' + s; | 298 return getFolder(parentNode.parentId) + '/' + s; |
299 } | 299 } |
300 return s; | 300 return s; |
301 } | 301 } |
302 } | 302 } |
303 | 303 |
304 function handleLoadForTree(e) { | 304 function handleLoadForTree(e) { |
(...skipping 19 matching lines...) Expand all Loading... | |
324 if (!bmm.isFolder(child)) | 324 if (!bmm.isFolder(child)) |
325 urls.push(child.url); | 325 urls.push(child.url); |
326 }); | 326 }); |
327 } else { | 327 } else { |
328 urls.push(node.url); | 328 urls.push(node.url); |
329 } | 329 } |
330 } | 330 } |
331 | 331 |
332 // Get a future promise for the nodes. | 332 // Get a future promise for the nodes. |
333 var promises = nodes.map(function(node) { | 333 var promises = nodes.map(function(node) { |
334 if (bmm.isFolder(node)) | 334 if (bmm.isFolder(assert(node))) |
335 return bmm.loadSubtree(node.id); | 335 return bmm.loadSubtree(node.id); |
336 // Not a folder so we already have all the data we need. | 336 // Not a folder so we already have all the data we need. |
337 return Promise.resolve(node); | 337 return Promise.resolve(node); |
338 }); | 338 }); |
339 | 339 |
340 return Promise.all(promises).then(function(nodes) { | 340 return Promise.all(promises).then(function(nodes) { |
341 nodes.forEach(addNodes); | 341 nodes.forEach(addNodes); |
342 return urls; | 342 return urls; |
343 }); | 343 }); |
344 } | 344 } |
345 | 345 |
346 /** | 346 /** |
347 * Returns the nodes (non recursive) to use for the open commands. | 347 * Returns the nodes (non recursive) to use for the open commands. |
348 * @param {HTMLElement} target . | 348 * @param {HTMLElement} target |
349 * @return {Array.<BookmarkTreeNode>} . | 349 * @return {!Array.<BookmarkTreeNode>} |
350 */ | 350 */ |
351 function getNodesForOpen(target) { | 351 function getNodesForOpen(target) { |
352 if (target == tree) { | 352 if (target == $('tree')) { |
353 if (tree.selectedItem != searchTreeItem) | 353 if ($('tree').selectedItem != searchTreeItem) |
354 return tree.selectedFolders; | 354 return $('tree').selectedFolders; |
355 // Fall through to use all nodes in the list. | 355 // Fall through to use all nodes in the list. |
356 } else { | 356 } else { |
357 var items = list.selectedItems; | 357 var items = $('list').selectedItems; |
358 if (items.length) | 358 if (items.length) |
359 return items; | 359 return items; |
360 } | 360 } |
361 | 361 |
362 // The list starts off with a null dataModel. We can get here during startup. | 362 // The list starts off with a null dataModel. We can get here during startup. |
363 if (!list.dataModel) | 363 if (!$('list').dataModel) |
364 return []; | 364 return []; |
365 | 365 |
366 // Return an array based on the dataModel. | 366 // Return an array based on the dataModel. |
367 return list.dataModel.slice(); | 367 return $('list').dataModel.slice(); |
368 } | 368 } |
369 | 369 |
370 /** | 370 /** |
371 * Returns a promise that will contain all URLs of all the selected bookmarks | 371 * Returns a promise that will contain all URLs of all the selected bookmarks |
372 * and the nested bookmarks for use with the open commands. | 372 * and the nested bookmarks for use with the open commands. |
373 * @param {HTMLElement} target The target list or tree. | 373 * @param {HTMLElement} target The target list or tree. |
374 * @return {Promise.<Array.<string>>} . | 374 * @return {Promise.<Array.<string>>} . |
375 */ | 375 */ |
376 function getUrlsForOpenCommands(target) { | 376 function getUrlsForOpenCommands(target) { |
377 return getAllUrls(getNodesForOpen(target)); | 377 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 | 390 * @param {string} pluralId The string id of menu label if the singular form is |
391 not used. | 391 not used. |
392 * @param {boolean} commandDisabled Whether the menu item should be disabled | 392 * @param {boolean} commandDisabled Whether the menu item should be disabled |
393 no matter what bookmarks are selected. | 393 no matter what bookmarks are selected. |
394 */ | 394 */ |
395 function updateOpenCommand(e, command, singularId, pluralId, commandDisabled) { | 395 function updateOpenCommand(e, command, singularId, pluralId, commandDisabled) { |
396 if (singularId) { | 396 if (singularId) { |
397 // The command label reflects the selection which might not reflect | 397 // The command label reflects the selection which might not reflect |
398 // how many bookmarks will be opened. For example if you right click an | 398 // 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". | 399 // empty area in a folder with 1 bookmark the text should still say "all". |
400 assert(!e.target || e.target instanceof BookmarkList || | |
401 e.target instanceof BookmarkTree); | |
400 var selectedNodes = getSelectedBookmarkNodes(e.target).filter(notNewNode); | 402 var selectedNodes = getSelectedBookmarkNodes(e.target).filter(notNewNode); |
401 var singular = selectedNodes.length == 1 && !bmm.isFolder(selectedNodes[0]); | 403 var singular = selectedNodes.length == 1 && !bmm.isFolder(selectedNodes[0]); |
402 command.label = loadTimeData.getString(singular ? singularId : pluralId); | 404 command.label = loadTimeData.getString(singular ? singularId : pluralId); |
403 } | 405 } |
404 | 406 |
405 if (commandDisabled) { | 407 if (commandDisabled) { |
406 command.disabled = true; | 408 command.disabled = true; |
407 e.canExecute = false; | 409 e.canExecute = false; |
408 return; | 410 return; |
409 } | 411 } |
410 | 412 |
411 getUrlsForOpenCommands(e.target).then(function(urls) { | 413 getUrlsForOpenCommands(assertInstanceof(e.target, HTMLElement)).then( |
414 function(urls) { | |
412 var disabled = !urls.length; | 415 var disabled = !urls.length; |
413 command.disabled = disabled; | 416 command.disabled = disabled; |
414 e.canExecute = !disabled; | 417 e.canExecute = !disabled; |
415 }); | 418 }); |
416 } | 419 } |
417 | 420 |
418 /** | 421 /** |
419 * Calls the backend to figure out if we can paste the clipboard into the active | 422 * Calls the backend to figure out if we can paste the clipboard into the active |
420 * folder. | 423 * folder. |
421 * @param {Function=} opt_f Function to call after the state has been updated. | 424 * @param {Function=} opt_f Function to call after the state has been updated. |
422 */ | 425 */ |
423 function updatePasteCommand(opt_f) { | 426 function updatePasteCommand(opt_f) { |
424 function update(canPaste) { | 427 function update(canPaste) { |
425 var organizeMenuCommand = $('paste-from-organize-menu-command'); | 428 var organizeMenuCommand = $('paste-from-organize-menu-command'); |
426 var contextMenuCommand = $('paste-from-context-menu-command'); | 429 var contextMenuCommand = $('paste-from-context-menu-command'); |
427 organizeMenuCommand.disabled = !canPaste; | 430 organizeMenuCommand.disabled = !canPaste; |
428 contextMenuCommand.disabled = !canPaste; | 431 contextMenuCommand.disabled = !canPaste; |
429 if (opt_f) | 432 if (opt_f) |
430 opt_f(); | 433 opt_f(); |
431 } | 434 } |
432 // We cannot paste into search view. | 435 // We cannot paste into search view. |
433 if (list.isSearch()) | 436 if ($('list').isSearch()) |
434 update(false); | 437 update(false); |
435 else | 438 else |
436 chrome.bookmarkManagerPrivate.canPaste(list.parentId, update); | 439 chrome.bookmarkManagerPrivate.canPaste($('list').parentId, update); |
437 } | 440 } |
438 | 441 |
439 function handleCanExecuteForDocument(e) { | 442 function handleCanExecuteForDocument(e) { |
440 var command = e.command; | 443 var command = e.command; |
441 switch (command.id) { | 444 switch (command.id) { |
442 case 'import-menu-command': | 445 case 'import-menu-command': |
443 e.canExecute = canEdit; | 446 e.canExecute = canEdit; |
444 break; | 447 break; |
445 case 'export-menu-command': | 448 case 'export-menu-command': |
446 // We can always execute the export-menu command. | 449 // We can always execute the export-menu command. |
447 e.canExecute = true; | 450 e.canExecute = true; |
448 break; | 451 break; |
449 case 'sort-command': | 452 case 'sort-command': |
450 e.canExecute = !list.isSearch() && | 453 e.canExecute = !$('list').isSearch() && |
451 list.dataModel && list.dataModel.length > 1 && | 454 $('list').dataModel && $('list').dataModel.length > 1 && |
452 !isUnmodifiable(tree.getBookmarkNodeById(list.parentId)); | 455 !isUnmodifiable($('tree').getBookmarkNodeById($('list').parentId)); |
453 break; | 456 break; |
454 case 'undo-command': | 457 case 'undo-command': |
455 // If the search box is active, pass the undo command through | 458 // If the search box is active, pass the undo command through |
456 // (fixes http://crbug.com/278112). Otherwise, because | 459 // (fixes http://crbug.com/278112). Otherwise, because |
457 // the global undo command has no visible UI, always enable it, and | 460 // the global undo command has no visible UI, always enable it, and |
458 // just make it a no-op if undo is not possible. | 461 // just make it a no-op if undo is not possible. |
459 e.canExecute = e.currentTarget.activeElement !== $('term'); | 462 e.canExecute = e.currentTarget.activeElement !== $('term'); |
460 break; | 463 break; |
461 default: | 464 default: |
462 canExecuteForList(e); | 465 canExecuteForList(e); |
463 break; | 466 break; |
464 } | 467 } |
465 } | 468 } |
466 | 469 |
467 /** | 470 /** |
468 * Helper function for handling canExecute for the list and the tree. | 471 * Helper function for handling canExecute for the list and the tree. |
469 * @param {!Event} e Can execute event object. | 472 * @param {!cr.ui.CanExecuteEvent} e Can execute event object. |
470 * @param {boolean} isSearch Whether the user is trying to do a command on | 473 * @param {boolean} isSearch Whether the user is trying to do a command on |
471 * search. | 474 * search. |
472 */ | 475 */ |
473 function canExecuteShared(e, isSearch) { | 476 function canExecuteShared(e, isSearch) { |
474 var command = e.command; | 477 var command = e.command; |
475 var commandId = command.id; | 478 var commandId = command.id; |
476 switch (commandId) { | 479 switch (commandId) { |
477 case 'paste-from-organize-menu-command': | 480 case 'paste-from-organize-menu-command': |
478 case 'paste-from-context-menu-command': | 481 case 'paste-from-context-menu-command': |
479 updatePasteCommand(); | 482 updatePasteCommand(); |
480 break; | 483 break; |
481 | 484 |
482 case 'add-new-bookmark-command': | 485 case 'add-new-bookmark-command': |
483 case 'new-folder-command': | 486 case 'new-folder-command': |
484 var parentId = computeParentFolderForNewItem(); | 487 var parentId = computeParentFolderForNewItem(); |
485 var unmodifiable = isUnmodifiable(tree.getBookmarkNodeById(parentId)); | 488 var unmodifiable = isUnmodifiable( |
489 $('tree').getBookmarkNodeById(parentId)); | |
486 e.canExecute = !isSearch && canEdit && !unmodifiable; | 490 e.canExecute = !isSearch && canEdit && !unmodifiable; |
487 break; | 491 break; |
488 | 492 |
489 case 'open-in-new-tab-command': | 493 case 'open-in-new-tab-command': |
490 updateOpenCommand(e, command, 'open_in_new_tab', 'open_all', false); | 494 updateOpenCommand(e, command, 'open_in_new_tab', 'open_all', false); |
491 break; | 495 break; |
492 case 'open-in-background-tab-command': | 496 case 'open-in-background-tab-command': |
493 updateOpenCommand(e, command, '', '', false); | 497 updateOpenCommand(e, command, '', '', false); |
494 break; | 498 break; |
495 case 'open-in-new-window-command': | 499 case 'open-in-new-window-command': |
(...skipping 10 matching lines...) Expand all Loading... | |
506 break; | 510 break; |
507 | 511 |
508 case 'undo-delete-command': | 512 case 'undo-delete-command': |
509 e.canExecute = !!lastDeletedNodes; | 513 e.canExecute = !!lastDeletedNodes; |
510 break; | 514 break; |
511 } | 515 } |
512 } | 516 } |
513 | 517 |
514 /** | 518 /** |
515 * Helper function for handling canExecute for the list and document. | 519 * Helper function for handling canExecute for the list and document. |
516 * @param {!Event} e Can execute event object. | 520 * @param {!cr.ui.CanExecuteEvent} e Can execute event object. |
517 */ | 521 */ |
518 function canExecuteForList(e) { | 522 function canExecuteForList(e) { |
519 var command = e.command; | 523 var command = e.command; |
520 var commandId = command.id; | 524 var commandId = command.id; |
521 | 525 |
522 function hasSelected() { | 526 function hasSelected() { |
523 return !!list.selectedItem; | 527 return !!$('list').selectedItem; |
524 } | 528 } |
525 | 529 |
526 function hasSingleSelected() { | 530 function hasSingleSelected() { |
527 return list.selectedItems.length == 1; | 531 return $('list').selectedItems.length == 1; |
528 } | 532 } |
529 | 533 |
530 function canCopyItem(item) { | 534 function canCopyItem(item) { |
531 return item.id != 'new'; | 535 return item.id != 'new'; |
532 } | 536 } |
533 | 537 |
534 function canCopyItems() { | 538 function canCopyItems() { |
535 var selectedItems = list.selectedItems; | 539 var selectedItems = $('list').selectedItems; |
536 return selectedItems && selectedItems.some(canCopyItem); | 540 return selectedItems && selectedItems.some(canCopyItem); |
537 } | 541 } |
538 | 542 |
539 function isSearch() { | 543 function isSearch() { |
540 return list.isSearch(); | 544 return $('list').isSearch(); |
541 } | 545 } |
542 | 546 |
543 switch (commandId) { | 547 switch (commandId) { |
544 case 'rename-folder-command': | 548 case 'rename-folder-command': |
545 // Show rename if a single folder is selected. | 549 // Show rename if a single folder is selected. |
546 var items = list.selectedItems; | 550 var items = $('list').selectedItems; |
547 if (items.length != 1) { | 551 if (items.length != 1) { |
548 e.canExecute = false; | 552 e.canExecute = false; |
549 command.hidden = true; | 553 command.hidden = true; |
550 } else { | 554 } else { |
551 var isFolder = bmm.isFolder(items[0]); | 555 var isFolder = bmm.isFolder(items[0]); |
552 e.canExecute = isFolder && canEdit && !hasUnmodifiable(items); | 556 e.canExecute = isFolder && canEdit && !hasUnmodifiable(items); |
553 command.hidden = !isFolder; | 557 command.hidden = !isFolder; |
554 } | 558 } |
555 break; | 559 break; |
556 | 560 |
557 case 'edit-command': | 561 case 'edit-command': |
558 // Show the edit command if not a folder. | 562 // Show the edit command if not a folder. |
559 var items = list.selectedItems; | 563 var items = $('list').selectedItems; |
560 if (items.length != 1) { | 564 if (items.length != 1) { |
561 e.canExecute = false; | 565 e.canExecute = false; |
562 command.hidden = false; | 566 command.hidden = false; |
563 } else { | 567 } else { |
564 var isFolder = bmm.isFolder(items[0]); | 568 var isFolder = bmm.isFolder(items[0]); |
565 e.canExecute = !isFolder && canEdit && !hasUnmodifiable(items); | 569 e.canExecute = !isFolder && canEdit && !hasUnmodifiable(items); |
566 command.hidden = isFolder; | 570 command.hidden = isFolder; |
567 } | 571 } |
568 break; | 572 break; |
569 | 573 |
570 case 'show-in-folder-command': | 574 case 'show-in-folder-command': |
571 e.canExecute = isSearch() && hasSingleSelected(); | 575 e.canExecute = isSearch() && hasSingleSelected(); |
572 break; | 576 break; |
573 | 577 |
574 case 'delete-command': | 578 case 'delete-command': |
575 case 'cut-command': | 579 case 'cut-command': |
576 e.canExecute = canCopyItems() && canEdit && | 580 e.canExecute = canCopyItems() && canEdit && |
577 !hasUnmodifiable(list.selectedItems); | 581 !hasUnmodifiable($('list').selectedItems); |
578 break; | 582 break; |
579 | 583 |
580 case 'copy-command': | 584 case 'copy-command': |
581 e.canExecute = canCopyItems(); | 585 e.canExecute = canCopyItems(); |
582 break; | 586 break; |
583 | 587 |
584 case 'open-in-same-window-command': | 588 case 'open-in-same-window-command': |
585 e.canExecute = hasSelected(); | 589 e.canExecute = hasSelected(); |
586 break; | 590 break; |
587 | 591 |
588 default: | 592 default: |
589 canExecuteShared(e, isSearch()); | 593 canExecuteShared(e, isSearch()); |
590 } | 594 } |
591 } | 595 } |
592 | 596 |
593 // Update canExecute for the commands when the list is the active element. | 597 // Update canExecute for the commands when the list is the active element. |
594 function handleCanExecuteForList(e) { | 598 function handleCanExecuteForList(e) { |
595 if (e.target != list) return; | 599 if (e.target != $('list')) return; |
596 canExecuteForList(e); | 600 canExecuteForList(e); |
597 } | 601 } |
598 | 602 |
599 // Update canExecute for the commands when the tree is the active element. | 603 // Update canExecute for the commands when the tree is the active element. |
600 function handleCanExecuteForTree(e) { | 604 function handleCanExecuteForTree(e) { |
601 if (e.target != tree) return; | 605 if (e.target != $('tree')) return; |
602 | 606 |
603 var command = e.command; | 607 var command = e.command; |
604 var commandId = command.id; | 608 var commandId = command.id; |
605 | 609 |
606 function hasSelected() { | 610 function hasSelected() { |
607 return !!e.target.selectedItem; | 611 return !!e.target.selectedItem; |
608 } | 612 } |
609 | 613 |
610 function isSearch() { | 614 function isSearch() { |
611 var item = e.target.selectedItem; | 615 var item = e.target.selectedItem; |
612 return item == searchTreeItem; | 616 return item == searchTreeItem; |
613 } | 617 } |
614 | 618 |
615 function isTopLevelItem() { | 619 function isTopLevelItem() { |
616 return e.target.selectedItem.parentNode == tree; | 620 return e.target.selectedItem.parentNode == $('tree'); |
617 } | 621 } |
618 | 622 |
619 switch (commandId) { | 623 switch (commandId) { |
620 case 'rename-folder-command': | 624 case 'rename-folder-command': |
621 command.hidden = false; | 625 command.hidden = false; |
622 e.canExecute = hasSelected() && !isTopLevelItem() && canEdit && | 626 e.canExecute = hasSelected() && !isTopLevelItem() && canEdit && |
623 !hasUnmodifiable(tree.selectedFolders); | 627 !hasUnmodifiable($('tree').selectedFolders); |
624 break; | 628 break; |
625 | 629 |
626 case 'edit-command': | 630 case 'edit-command': |
627 command.hidden = true; | 631 command.hidden = true; |
628 e.canExecute = false; | 632 e.canExecute = false; |
629 break; | 633 break; |
630 | 634 |
631 case 'delete-command': | 635 case 'delete-command': |
632 case 'cut-command': | 636 case 'cut-command': |
633 e.canExecute = hasSelected() && !isTopLevelItem() && canEdit && | 637 e.canExecute = hasSelected() && !isTopLevelItem() && canEdit && |
634 !hasUnmodifiable(tree.selectedFolders); | 638 !hasUnmodifiable($('tree').selectedFolders); |
635 break; | 639 break; |
636 | 640 |
637 case 'copy-command': | 641 case 'copy-command': |
638 e.canExecute = hasSelected() && !isTopLevelItem(); | 642 e.canExecute = hasSelected() && !isTopLevelItem(); |
639 break; | 643 break; |
640 | 644 |
641 default: | 645 default: |
642 canExecuteShared(e, isSearch()); | 646 canExecuteShared(e, isSearch()); |
643 } | 647 } |
644 } | 648 } |
(...skipping 17 matching lines...) Expand all Loading... | |
662 if (result != canEdit) { | 666 if (result != canEdit) { |
663 canEdit = result; | 667 canEdit = result; |
664 editingCommands.forEach(function(baseId) { | 668 editingCommands.forEach(function(baseId) { |
665 $(baseId + '-command').canExecuteChange(); | 669 $(baseId + '-command').canExecuteChange(); |
666 }); | 670 }); |
667 } | 671 } |
668 }); | 672 }); |
669 } | 673 } |
670 | 674 |
671 function handleChangeForTree(e) { | 675 function handleChangeForTree(e) { |
672 navigateTo(tree.selectedItem.bookmarkId); | 676 navigateTo($('tree').selectedItem.bookmarkId); |
673 } | 677 } |
674 | 678 |
675 function handleOrganizeButtonClick(e) { | 679 function handleOrganizeButtonClick(e) { |
676 updateEditingCommands(); | 680 updateEditingCommands(); |
677 $('add-new-bookmark-command').canExecuteChange(); | 681 $('add-new-bookmark-command').canExecuteChange(); |
678 $('new-folder-command').canExecuteChange(); | 682 $('new-folder-command').canExecuteChange(); |
679 $('sort-command').canExecuteChange(); | 683 $('sort-command').canExecuteChange(); |
680 } | 684 } |
681 | 685 |
682 function handleRename(e) { | 686 function handleRename(e) { |
683 var item = e.target; | 687 var item = e.target; |
684 var bookmarkNode = item.bookmarkNode; | 688 var bookmarkNode = item.bookmarkNode; |
685 chrome.bookmarks.update(bookmarkNode.id, {title: item.label}); | 689 chrome.bookmarks.update(bookmarkNode.id, {title: item.label}); |
686 performGlobalUndo = null; // This can't be undone, so disable global undo. | 690 performGlobalUndo = null; // This can't be undone, so disable global undo. |
687 } | 691 } |
688 | 692 |
689 function handleEdit(e) { | 693 function handleEdit(e) { |
690 var item = e.target; | 694 var item = e.target; |
691 var bookmarkNode = item.bookmarkNode; | 695 var bookmarkNode = item.bookmarkNode; |
692 var context = { | 696 var context = { |
693 title: bookmarkNode.title | 697 title: bookmarkNode.title |
694 }; | 698 }; |
695 if (!bmm.isFolder(bookmarkNode)) | 699 if (!bmm.isFolder(bookmarkNode)) |
696 context.url = bookmarkNode.url; | 700 context.url = bookmarkNode.url; |
697 | 701 |
698 if (bookmarkNode.id == 'new') { | 702 if (bookmarkNode.id == 'new') { |
699 selectItemsAfterUserAction(list); | 703 selectItemsAfterUserAction(/** @type {BookmarkList} */($('list'))); |
700 | 704 |
701 // New page | 705 // New page |
702 context.parentId = bookmarkNode.parentId; | 706 context.parentId = bookmarkNode.parentId; |
703 chrome.bookmarks.create(context, function(node) { | 707 chrome.bookmarks.create(context, function(node) { |
704 // A new node was created and will get added to the list due to the | 708 // A new node was created and will get added to the list due to the |
705 // handler. | 709 // handler. |
706 var dataModel = list.dataModel; | 710 var dataModel = $('list').dataModel; |
707 var index = dataModel.indexOf(bookmarkNode); | 711 var index = dataModel.indexOf(bookmarkNode); |
708 dataModel.splice(index, 1); | 712 dataModel.splice(index, 1); |
709 | 713 |
710 // Select new item. | 714 // Select new item. |
711 var newIndex = dataModel.findIndexById(node.id); | 715 var newIndex = dataModel.findIndexById(node.id); |
712 if (newIndex != -1) { | 716 if (newIndex != -1) { |
713 var sm = list.selectionModel; | 717 var sm = $('list').selectionModel; |
714 list.scrollIndexIntoView(newIndex); | 718 $('list').scrollIndexIntoView(newIndex); |
715 sm.leadIndex = sm.anchorIndex = sm.selectedIndex = newIndex; | 719 sm.leadIndex = sm.anchorIndex = sm.selectedIndex = newIndex; |
716 } | 720 } |
717 }); | 721 }); |
718 } else { | 722 } else { |
719 // Edit | 723 // Edit |
720 chrome.bookmarks.update(bookmarkNode.id, context); | 724 chrome.bookmarks.update(bookmarkNode.id, context); |
721 } | 725 } |
722 performGlobalUndo = null; // This can't be undone, so disable global undo. | 726 performGlobalUndo = null; // This can't be undone, so disable global undo. |
723 } | 727 } |
724 | 728 |
725 function handleCancelEdit(e) { | 729 function handleCancelEdit(e) { |
726 var item = e.target; | 730 var item = e.target; |
727 var bookmarkNode = item.bookmarkNode; | 731 var bookmarkNode = item.bookmarkNode; |
728 if (bookmarkNode.id == 'new') { | 732 if (bookmarkNode.id == 'new') { |
729 var dataModel = list.dataModel; | 733 var dataModel = $('list').dataModel; |
730 var index = dataModel.findIndexById('new'); | 734 var index = dataModel.findIndexById('new'); |
731 dataModel.splice(index, 1); | 735 dataModel.splice(index, 1); |
732 } | 736 } |
733 } | 737 } |
734 | 738 |
735 /** | 739 /** |
736 * Navigates to the folder that the selected item is in and selects it. This is | 740 * Navigates to the folder that the selected item is in and selects it. This is |
737 * used for the show-in-folder command. | 741 * used for the show-in-folder command. |
738 */ | 742 */ |
739 function showInFolder() { | 743 function showInFolder() { |
740 var bookmarkNode = list.selectedItem; | 744 var bookmarkNode = $('list').selectedItem; |
741 if (!bookmarkNode) | 745 if (!bookmarkNode) |
742 return; | 746 return; |
743 var parentId = bookmarkNode.parentId; | 747 var parentId = bookmarkNode.parentId; |
744 | 748 |
745 // After the list is loaded we should select the revealed item. | 749 // After the list is loaded we should select the revealed item. |
746 function selectItem() { | 750 function selectItem() { |
747 var index = list.dataModel.findIndexById(bookmarkNode.id); | 751 var index = $('list').dataModel.findIndexById(bookmarkNode.id); |
748 if (index == -1) | 752 if (index == -1) |
749 return; | 753 return; |
750 var sm = list.selectionModel; | 754 var sm = $('list').selectionModel; |
751 sm.anchorIndex = sm.leadIndex = sm.selectedIndex = index; | 755 sm.anchorIndex = sm.leadIndex = sm.selectedIndex = index; |
752 list.scrollIndexIntoView(index); | 756 $('list').scrollIndexIntoView(index); |
753 } | 757 } |
754 | 758 |
755 var treeItem = bmm.treeLookup[parentId]; | 759 var treeItem = bmm.treeLookup[parentId]; |
756 treeItem.reveal(); | 760 treeItem.reveal(); |
757 | 761 |
758 navigateTo(parentId, selectItem); | 762 navigateTo(parentId, selectItem); |
759 } | 763 } |
760 | 764 |
761 /** | 765 /** |
762 * @return {!cr.LinkController} The link controller used to open links based on | 766 * @return {!cr.LinkController} The link controller used to open links based on |
763 * user clicks and keyboard actions. | 767 * user clicks and keyboard actions. |
764 */ | 768 */ |
765 function getLinkController() { | 769 function getLinkController() { |
766 return linkController || | 770 return linkController || |
767 (linkController = new cr.LinkController(loadTimeData)); | 771 (linkController = new cr.LinkController(loadTimeData)); |
768 } | 772 } |
769 | 773 |
770 /** | 774 /** |
771 * Returns the selected bookmark nodes of the provided tree or list. | 775 * 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. | 776 * 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. | 777 * Only call this if the list or the tree is focused. |
774 * @param {BookmarkList|BookmarkTree} opt_target The target list or tree. | 778 * @param {(BookmarkList|BookmarkTree)=} opt_target The target list or tree. |
775 * @return {!Array} Array of bookmark nodes. | 779 * @return {!Array} Array of bookmark nodes. |
776 */ | 780 */ |
777 function getSelectedBookmarkNodes(opt_target) { | 781 function getSelectedBookmarkNodes(opt_target) { |
778 return (opt_target || document.activeElement) == tree ? | 782 return (opt_target || document.activeElement) == $('tree') ? |
779 tree.selectedFolders : list.selectedItems; | 783 $('tree').selectedFolders : $('list').selectedItems; |
780 } | 784 } |
781 | 785 |
782 /** | 786 /** |
783 * @return {!Array.<string>} An array of the selected bookmark IDs. | 787 * @return {!Array.<string>} An array of the selected bookmark IDs. |
784 */ | 788 */ |
785 function getSelectedBookmarkIds() { | 789 function getSelectedBookmarkIds() { |
786 var selectedNodes = getSelectedBookmarkNodes(); | 790 var selectedNodes = getSelectedBookmarkNodes(); |
787 selectedNodes.sort(function(a, b) { return a.index - b.index }); | 791 selectedNodes.sort(function(a, b) { return a.index - b.index }); |
788 return selectedNodes.map(function(node) { | 792 return selectedNodes.map(function(node) { |
789 return node.id; | 793 return node.id; |
790 }); | 794 }); |
791 } | 795 } |
792 | 796 |
793 /** | 797 /** |
794 * @param {BookmarkTreeNode} node The node to test. | 798 * @param {BookmarkTreeNode} node The node to test. |
795 * @return {boolean} Whether the given node is unmodifiable. | 799 * @return {boolean} Whether the given node is unmodifiable. |
796 */ | 800 */ |
797 function isUnmodifiable(node) { | 801 function isUnmodifiable(node) { |
798 return node && node.unmodifiable; | 802 return node && node.unmodifiable; |
799 } | 803 } |
800 | 804 |
801 /** | 805 /** |
802 * @param {BookmarkList} A list of BookmarkNodes. | 806 * @param {Array.<BookmarkTreeNode>} nodes A list of BookmarkTreeNodes. |
803 * @return {boolean} Whether any of the nodes is managed. | 807 * @return {boolean} Whether any of the nodes is managed. |
804 */ | 808 */ |
805 function hasUnmodifiable(nodes) { | 809 function hasUnmodifiable(nodes) { |
806 return nodes.some(isUnmodifiable); | 810 return nodes.some(isUnmodifiable); |
807 } | 811 } |
808 | 812 |
809 /** | 813 /** |
810 * Opens the selected bookmarks. | 814 * Opens the selected bookmarks. |
811 * @param {LinkKind} kind The kind of link we want to open. | 815 * @param {cr.LinkKind} kind The kind of link we want to open. |
812 * @param {HTMLElement} opt_eventTarget The target of the user initiated event. | 816 * @param {HTMLElement=} opt_eventTarget The target of the user initiated event. |
813 */ | 817 */ |
814 function openBookmarks(kind, opt_eventTarget) { | 818 function openBookmarks(kind, opt_eventTarget) { |
815 // If we have selected any folders, we need to find all the bookmarks one | 819 // 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 | 820 // 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. | 821 // the whole tree since we would like to minimize the amount of data sent. |
818 | 822 |
819 var urlsP = getUrlsForOpenCommands(opt_eventTarget); | 823 var urlsP = getUrlsForOpenCommands(opt_eventTarget ? opt_eventTarget : null); |
820 urlsP.then(function(urls) { | 824 urlsP.then(function(urls) { |
821 getLinkController().openUrls(urls, kind); | 825 getLinkController().openUrls(assert(urls), kind); |
822 chrome.bookmarkManagerPrivate.recordLaunch(); | 826 chrome.bookmarkManagerPrivate.recordLaunch(); |
823 }); | 827 }); |
824 } | 828 } |
825 | 829 |
826 /** | 830 /** |
827 * Opens an item in the list. | 831 * Opens an item in the list. |
828 */ | 832 */ |
829 function openItem() { | 833 function openItem() { |
830 var bookmarkNodes = getSelectedBookmarkNodes(); | 834 var bookmarkNodes = getSelectedBookmarkNodes(); |
831 // If we double clicked or pressed enter on a single folder, navigate to it. | 835 // If we double clicked or pressed enter on a single folder, navigate to it. |
832 if (bookmarkNodes.length == 1 && bmm.isFolder(bookmarkNodes[0])) | 836 if (bookmarkNodes.length == 1 && bmm.isFolder(bookmarkNodes[0])) |
833 navigateTo(bookmarkNodes[0].id); | 837 navigateTo(bookmarkNodes[0].id); |
834 else | 838 else |
835 openBookmarks(LinkKind.FOREGROUND_TAB); | 839 openBookmarks(LinkKind.FOREGROUND_TAB); |
836 } | 840 } |
837 | 841 |
838 /** | 842 /** |
839 * Refreshes search results after delete or undo-delete. | 843 * Refreshes search results after delete or undo-delete. |
840 * This ensures children of deleted folders do not remain in results | 844 * This ensures children of deleted folders do not remain in results |
841 */ | 845 */ |
842 function updateSearchResults() { | 846 function updateSearchResults() { |
843 if (list.isSearch()) { | 847 if ($('list').isSearch()) { |
844 list.reload(); | 848 $('list').reload(); |
845 } | 849 } |
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(); |
(...skipping 17 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 (when |
888 * called by forEach), the 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 == $('tree')) |
930 return list.parentId; | 935 return $('list').parentId; |
931 var selectedItem = list.selectedItem; | 936 var selectedItem = $('list').selectedItem; |
932 return selectedItem && bmm.isFolder(selectedItem) ? | 937 return selectedItem && bmm.isFolder(selectedItem) ? |
933 selectedItem.id : list.parentId; | 938 selectedItem.id : $('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 == $('tree')) { |
942 tree.selectedItem.editing = true; | 947 $('tree').selectedItem.editing = true; |
943 } else { | 948 } else { |
944 var li = list.getListItem(list.selectedItem); | 949 var li = $('list').getListItem($('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 == $('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 = $('list').dataModel.length - 1; |
979 var sm = list.selectionModel; | 984 var sm = $('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 $('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 = $('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 = $('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 = $('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 || $('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 $('tree').selectedItem = bmm.treeLookup[opt_selectedTreeId]; |
1056 } | 1061 } |
1057 } else if (target == list) { | 1062 } else if (target == $('list')) { |
1058 var dataModel = list.dataModel; | 1063 var dataModel = $('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 = $('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 $('list').focus(); |
1067 } | 1072 } |
1068 } | 1073 } |
1069 | 1074 |
1070 list.endBatchUpdates(); | 1075 $('list').endBatchUpdates(); |
1071 } | 1076 } |
1072 | 1077 |
1073 list.startBatchUpdates(); | 1078 $('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 == $('tree')) |
1095 return tree.selectedItem.bookmarkId; | 1100 return $('tree').selectedItem.bookmarkId; |
1096 var selectedItem = list.selectedItem; | 1101 var selectedItem = $('list').selectedItem; |
1097 return selectedItem && bmm.isFolder(selectedItem) ? | 1102 return selectedItem && bmm.isFolder(selectedItem) ? |
1098 selectedItem.id : tree.selectedItem.bookmarkId; | 1103 selectedItem.id : $('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} */($('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 $('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($('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($('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($('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 != $('list') && |
1259 document.activeElement != $('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 $('list').addEventListener('canceledit', handleCancelEdit); |
1302 list.addEventListener('canExecute', handleCanExecuteForList); | 1314 $('list').addEventListener('canExecute', handleCanExecuteForList); |
1303 list.addEventListener('change', updateAllCommands); | 1315 $('list').addEventListener('change', updateAllCommands); |
1304 list.addEventListener('contextmenu', updateEditingCommands); | 1316 $('list').addEventListener('contextmenu', updateEditingCommands); |
1305 list.addEventListener('dblclick', handleDoubleClickForList); | 1317 $('list').addEventListener('dblclick', handleDoubleClickForList); |
1306 list.addEventListener('edit', handleEdit); | 1318 $('list').addEventListener('edit', handleEdit); |
1307 list.addEventListener('rename', handleRename); | 1319 $('list').addEventListener('rename', handleRename); |
1308 list.addEventListener('urlClicked', handleUrlClickedForList); | 1320 $('list').addEventListener('urlClicked', handleUrlClickedForList); |
1309 | 1321 |
1310 tree.addEventListener('canExecute', handleCanExecuteForTree); | 1322 $('tree').addEventListener('canExecute', handleCanExecuteForTree); |
1311 tree.addEventListener('change', handleChangeForTree); | 1323 $('tree').addEventListener('change', handleChangeForTree); |
1312 tree.addEventListener('contextmenu', updateEditingCommands); | 1324 $('tree').addEventListener('contextmenu', updateEditingCommands); |
1313 tree.addEventListener('rename', handleRename); | 1325 $('tree').addEventListener('rename', handleRename); |
1314 tree.addEventListener('load', handleLoadForTree); | 1326 $('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} */($('tree'))); |
1318 tree.contextMenu = $('context-menu'); | 1330 $('list').contextMenu = $('context-menu'); |
1331 $('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 $('tree').reload(); |
1375 } | 1389 } |
1376 | 1390 |
1377 initializeBookmarkManager(); | 1391 initializeBookmarkManager(); |
1378 })(); | 1392 })(); |
OLD | NEW |