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

Side by Side Diff: chrome/browser/resources/bookmark_manager/js/main.js

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

Powered by Google App Engine
This is Rietveld 408576698