diff options
Diffstat (limited to 'chromium/chrome/browser/resources/bookmark_manager/js/main.js')
-rw-r--r-- | chromium/chrome/browser/resources/bookmark_manager/js/main.js | 158 |
1 files changed, 116 insertions, 42 deletions
diff --git a/chromium/chrome/browser/resources/bookmark_manager/js/main.js b/chromium/chrome/browser/resources/bookmark_manager/js/main.js index d5e157fb5fb..d01fca22190 100644 --- a/chromium/chrome/browser/resources/bookmark_manager/js/main.js +++ b/chromium/chrome/browser/resources/bookmark_manager/js/main.js @@ -11,7 +11,6 @@ /** @const */ var ListItem = cr.ui.ListItem; /** @const */ var Menu = cr.ui.Menu; /** @const */ var MenuButton = cr.ui.MenuButton; -/** @const */ var Promise = cr.Promise; /** @const */ var Splitter = cr.ui.Splitter; /** @const */ var TreeItem = cr.ui.TreeItem; @@ -150,24 +149,24 @@ function updateHash() { /** * Navigates to a bookmark ID. * @param {string} id The ID to navigate to. - * @param {function()} callback Function called when list view loaded or + * @param {function()=} opt_callback Function called when list view loaded or * displayed specified folder. */ -function navigateTo(id, callback) { - updateHash(id); - - if (list.parentId == id) { - callback(); - return; - } +function navigateTo(id, opt_callback) { + window.location.hash = id; + updateAllCommands(); var metricsId = folderMetricsNameMap[id.replace(/^q=.*/, 'q=')] || folderMetricsNameMap['subfolder']; chrome.metricsPrivate.recordUserAction( 'BookmarkManager_NavigateTo_' + metricsId); - addOneShotEventListener(list, 'load', callback); - updateParentId(id); + if (opt_callback) { + if (list.parentId == id) + opt_callback(); + else + addOneShotEventListener(list, 'load', opt_callback); + } } /** @@ -282,8 +281,7 @@ function setSearch(searchText) { id = tree.selectedItem.bookmarkId; } - // Navigate now and update hash immediately. - navigateTo(id, updateHash); + navigateTo(id); } // Handle the logo button UI. @@ -314,6 +312,12 @@ function handleLoadForTree(e) { processHash(); } +/** + * Returns a promise for all the URLs in the {@code nodes} and the direct + * children of {@code nodes}. + * @param {!Array.<BookmarkTreeNode>} nodes . + * @return {!Promise.<Array.<string>>} . + */ function getAllUrls(nodes) { var urls = []; @@ -337,20 +341,13 @@ function getAllUrls(nodes) { if (bmm.isFolder(node)) return bmm.loadSubtree(node.id); // Not a folder so we already have all the data we need. - return new Promise(node); + return Promise.resolve(node); }); - var urlsPromise = new Promise(); - - var p = Promise.all.apply(null, promises); - p.addListener(function(nodes) { - nodes.forEach(function(node) { - addNodes(node); - }); - urlsPromise.value = urls; + return Promise.all(promises).then(function(nodes) { + nodes.forEach(addNodes); + return urls; }); - - return urlsPromise; } /** @@ -381,7 +378,7 @@ function getNodesForOpen(target) { * Returns a promise that will contain all URLs of all the selected bookmarks * and the nested bookmarks for use with the open commands. * @param {HTMLElement} target The target list or tree. - * @return {Promise} . + * @return {Promise.<Array.<string>>} . */ function getUrlsForOpenCommands(target) { return getAllUrls(getNodesForOpen(target)); @@ -418,7 +415,7 @@ function updateOpenCommand(e, command, singularId, pluralId, commandDisabled) { return; } - getUrlsForOpenCommands(e.target).addListener(function(urls) { + getUrlsForOpenCommands(e.target).then(function(urls) { var disabled = !urls.length; command.disabled = disabled; e.canExecute = !disabled; @@ -458,7 +455,8 @@ function handleCanExecuteForDocument(e) { break; case 'sort-command': e.canExecute = !list.isSearch() && - list.dataModel && list.dataModel.length > 1; + list.dataModel && list.dataModel.length > 1 && + !isUnmodifiable(tree.getBookmarkNodeById(list.parentId)); break; case 'undo-command': // The global undo command has no visible UI, so always enable it, and @@ -488,7 +486,9 @@ function canExecuteShared(e, isSearch) { case 'add-new-bookmark-command': case 'new-folder-command': - e.canExecute = !isSearch && canEdit; + var parentId = computeParentFolderForNewItem(); + var unmodifiable = isUnmodifiable(tree.getBookmarkNodeById(parentId)); + e.canExecute = !isSearch && canEdit && !unmodifiable; break; case 'open-in-new-tab-command': @@ -554,7 +554,7 @@ function canExecuteForList(e) { command.hidden = true; } else { var isFolder = bmm.isFolder(items[0]); - e.canExecute = isFolder && canEdit; + e.canExecute = isFolder && canEdit && !hasUnmodifiable(items); command.hidden = !isFolder; } break; @@ -567,7 +567,7 @@ function canExecuteForList(e) { command.hidden = false; } else { var isFolder = bmm.isFolder(items[0]); - e.canExecute = !isFolder && canEdit; + e.canExecute = !isFolder && canEdit && !hasUnmodifiable(items); command.hidden = isFolder; } break; @@ -578,7 +578,8 @@ function canExecuteForList(e) { case 'delete-command': case 'cut-command': - e.canExecute = canCopyItems() && canEdit; + e.canExecute = canCopyItems() && canEdit && + !hasUnmodifiable(list.selectedItems); break; case 'copy-command': @@ -623,7 +624,8 @@ function handleCanExecuteForTree(e) { switch (commandId) { case 'rename-folder-command': command.hidden = false; - e.canExecute = hasSelected() && !isTopLevelItem() && canEdit; + e.canExecute = hasSelected() && !isTopLevelItem() && canEdit && + !hasUnmodifiable(tree.selectedFolders); break; case 'edit-command': @@ -633,7 +635,8 @@ function handleCanExecuteForTree(e) { case 'delete-command': case 'cut-command': - e.canExecute = hasSelected() && !isTopLevelItem() && canEdit; + e.canExecute = hasSelected() && !isTopLevelItem() && canEdit && + !hasUnmodifiable(tree.selectedFolders); break; case 'copy-command': @@ -671,8 +674,7 @@ function updateEditingCommands() { } function handleChangeForTree(e) { - updateAllCommands(); - navigateTo(tree.selectedItem.bookmarkId, updateHash); + navigateTo(tree.selectedItem.bookmarkId); } function handleOrganizeButtonClick(e) { @@ -794,6 +796,22 @@ function getSelectedBookmarkIds() { } /** + * @param {BookmarkTreeNode} node The node to test. + * @return {boolean} Whether the given node is unmodifiable. + */ +function isUnmodifiable(node) { + return node && node.unmodifiable; +} + +/** + * @param {BookmarkList} A list of BookmarkNodes. + * @return {boolean} Whether any of the nodes is managed. + */ +function hasUnmodifiable(nodes) { + return nodes.some(isUnmodifiable); +} + +/** * Opens the selected bookmarks. * @param {LinkKind} kind The kind of link we want to open. * @param {HTMLElement} opt_eventTarget The target of the user initiated event. @@ -804,7 +822,7 @@ function openBookmarks(kind, opt_eventTarget) { // the whole tree since we would like to minimize the amount of data sent. var urlsP = getUrlsForOpenCommands(opt_eventTarget); - urlsP.addListener(function(urls) { + urlsP.then(function(urls) { getLinkController().openUrls(urls, kind); chrome.bookmarkManagerPrivate.recordLaunch(); }); @@ -816,10 +834,19 @@ function openBookmarks(kind, opt_eventTarget) { function openItem() { var bookmarkNodes = getSelectedBookmarkNodes(); // If we double clicked or pressed enter on a single folder, navigate to it. - if (bookmarkNodes.length == 1 && bmm.isFolder(bookmarkNodes[0])) { - navigateTo(bookmarkNodes[0].id, updateHash); - } else { + if (bookmarkNodes.length == 1 && bmm.isFolder(bookmarkNodes[0])) + navigateTo(bookmarkNodes[0].id); + else openBookmarks(LinkKind.FOREGROUND_TAB); +} + +/** + * Refreshes search results after delete or undo-delete. + * This ensures children of deleted folders do not remain in results + */ +function updateSearchResults() { + if (list.isSearch()) { + list.reload(); } } @@ -829,22 +856,27 @@ function openItem() { */ function deleteBookmarks() { var selectedIds = getSelectedBookmarkIds(); + var filteredIds = getFilteredSelectedBookmarkIds(); lastDeletedNodes = []; function performDelete() { - chrome.bookmarkManagerPrivate.removeTrees(selectedIds); + // Only remove filtered ids. + chrome.bookmarkManagerPrivate.removeTrees(filteredIds); $('undo-delete-command').canExecuteChange(); performGlobalUndo = undoDelete; } // First, store information about the bookmarks being deleted. + // Store all selected ids. selectedIds.forEach(function(id) { chrome.bookmarks.getSubTree(id, function(results) { lastDeletedNodes.push(results); // When all nodes have been saved, perform the deletion. - if (lastDeletedNodes.length === selectedIds.length) + if (lastDeletedNodes.length === selectedIds.length) { performDelete(); + updateSearchResults(); + } }); }); } @@ -875,6 +907,8 @@ function restoreTree(node, parentId) { restoreTree(child, result.id); }); } + + updateSearchResults(); }); } @@ -1081,6 +1115,43 @@ function pasteBookmark(id) { } /** + * Returns true if child is contained in another selected folder. + * Traces parent nodes up the tree until a selected ancestor or root is found. + */ +function hasSelectedAncestor(parentNode) { + function contains(arr, item) { + for (var i = 0; i < arr.length; i++) + if (arr[i] === item) + return true; + return false; + } + + // Don't search top level, cannot select permanent nodes in search. + if (parentNode == null || parentNode.id <= 2) + return false; + + // Found selected ancestor. + if (contains(getSelectedBookmarkNodes(), parentNode)) + return true; + + // Keep digging. + return hasSelectedAncestor(tree.getBookmarkNodeById(parentNode.parentId)); +} + +function getFilteredSelectedBookmarkIds() { + // Remove duplicates from filteredIds and return. + var filteredIds = new Array(); + // Selected nodes to iterate through for matches. + var nodes = getSelectedBookmarkNodes(); + + for (var i = 0; i < nodes.length; i++) + if (!hasSelectedAncestor(tree.getBookmarkNodeById(nodes[i].parentId))) + filteredIds.splice(0, 0, nodes[i].id); + + return filteredIds; +} + +/** * Handler for the command event. This is used for context menu of list/tree * and organized menu. * @param {!Event} e The event object. @@ -1134,7 +1205,10 @@ function handleCommand(e) { case 'cut-command': recordUserAction('Cut'); chrome.bookmarkManagerPrivate.cut(getSelectedBookmarkIds(), - updatePasteCommand); + function() { + updatePasteCommand(); + updateSearchResults(); + }); break; case 'paste-from-organize-menu-command': pasteBookmark(list.parentId); |