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

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

Powered by Google App Engine
This is Rietveld 408576698