summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/app/bookmarks_strings.grdp6
-rw-r--r--chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc2
-rw-r--r--chrome/browser/resources/bookmark_manager/css/bmm.css110
-rw-r--r--chrome/browser/resources/bookmark_manager/js/main.js247
-rw-r--r--chrome/browser/resources/bookmark_manager/main.html77
5 files changed, 325 insertions, 117 deletions
diff --git a/chrome/app/bookmarks_strings.grdp b/chrome/app/bookmarks_strings.grdp
index 2dedb8b..49d3707 100644
--- a/chrome/app/bookmarks_strings.grdp
+++ b/chrome/app/bookmarks_strings.grdp
@@ -348,6 +348,9 @@
<message name="IDS_BOOKMARK_MANAGER" desc="The label of the menu item that shows the bookmark manager">
&amp;Bookmark manager
</message>
+ <message name="IDS_BOOKMARK_MANAGER_FOLDERS_MENU" desc="Title of the folders menu in the bookmark manager.">
+ Folders
+ </message>
<message name="IDS_BOOKMARK_MANAGER_ORGANIZE_MENU" desc="Title of the organize menu in the bookmark manager.">
Organize
</message>
@@ -383,6 +386,9 @@
<message name="IDS_BOOKMARK_MANAGER" desc="In Title Case: The label of the menu item that shows the bookmark manager">
&amp;Bookmark Manager
</message>
+ <message name="IDS_BOOKMARK_MANAGER_FOLDERS_MENU" desc="In Title Case: Title of the folders menu in the bookmark manager.">
+ Folders
+ </message>
<message name="IDS_BOOKMARK_MANAGER_ORGANIZE_MENU" desc="In Title Case: Title of the organize menu in the bookmark manager.">
Organize
</message>
diff --git a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc
index fea374a..fbb5cc9 100644
--- a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc
+++ b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc
@@ -451,6 +451,8 @@ bool BookmarkManagerPrivateGetStringsFunction::RunAsync() {
l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_TITLE));
localized_strings->SetString("search_button",
l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_SEARCH_BUTTON));
+ localized_strings->SetString("folders_menu",
+ l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_FOLDERS_MENU));
localized_strings->SetString("organize_menu",
l10n_util::GetStringUTF16(IDS_BOOKMARK_MANAGER_ORGANIZE_MENU));
localized_strings->SetString("show_in_folder",
diff --git a/chrome/browser/resources/bookmark_manager/css/bmm.css b/chrome/browser/resources/bookmark_manager/css/bmm.css
index 1d8cf39..7d7aff4 100644
--- a/chrome/browser/resources/bookmark_manager/css/bmm.css
+++ b/chrome/browser/resources/bookmark_manager/css/bmm.css
@@ -14,8 +14,8 @@ body {
}
body {
- -webkit-flex-direction: column;
- display: -webkit-flex;
+ display: flex;
+ flex-direction: column;
}
list {
@@ -28,7 +28,7 @@ list > * {
-webkit-padding-end: 20px;
-webkit-padding-start: 3px;
color: hsl(0, 0%, 70%);
- display: -webkit-flex;
+ display: flex;
line-height: 20px;
margin: 0;
overflow: visible;
@@ -54,9 +54,9 @@ list > * > .label {
}
list > * > .url {
- -webkit-flex: 1;
direction: ltr; /* URLs always read LTR */
display: none;
+ flex: 1;
}
list > :hover > .url,
@@ -201,27 +201,73 @@ list > .folder > .label,
</if>
.main {
- -webkit-flex: 1;
- display: -webkit-flex;
+ border-top: 1px solid rgb(156, 194, 239);
+ display: flex;
+ flex: 1;
}
-#tree-container {
- -webkit-padding-end: 5px;
- -webkit-padding-start: 10px;
- box-sizing: border-box;
+.pane,
+.splitter {
+ display: flex;
+ flex-direction: column;
+}
+
+.pane > :first-child,
+.splitter > :first-child {
+ background-color: rgb(235, 239, 249);
+ flex: none;
+ padding: 5px 10px;
+ white-space: nowrap;
+}
+
+.splitter > :first-child {
+ overflow: hidden;
+ padding-left: 0;
+ padding-right: 0;
+ width: 15px;
+}
+
+.splitter button {
+ visibility: hidden; /* This button is only used for height matching. */
+}
+
+#tree-pane {
/* min-width and max-width are used by the split pane. */
max-width: 50%;
- min-width: 50px;
- overflow: auto;
- padding-bottom: 5px;
- padding-top: 5px;
+ min-width: 150px;
width: 200px;
}
-#tree {
+#list-pane {
+ flex: 1;
+}
+
+#list-pane > :first-child {
+ -webkit-padding-start: 0; /* Accounts for extra splitter resize width. */
+}
+
+#tree-container {
+ overflow: auto;
+}
+
+#list,
+#tree-container {
+ flex: 1;
+}
+
+#tree,
+#list {
+ -webkit-padding-end: 5px;
+ box-sizing: border-box;
display: inline-block;
+ margin-bottom: 5px;
+ margin-top: 5px;
min-width: 100%;
- overflow: visible; /* let the container do the scrolling */
+}
+
+#tree {
+ /* Only pad the tree as the splitter adds a lot of whitespace for the list. */
+ -webkit-padding-start: 10px;
}
.tree-item > .tree-row {
@@ -232,23 +278,13 @@ list > .folder > .label,
top: 2px;
}
-#list {
- -webkit-flex: 1;
- -webkit-padding-end: 5px;
- box-sizing: border-box;
- padding-bottom: 5px;
- padding-top: 5px;
-}
-
.splitter {
- -webkit-border-end: 15px solid white;
- -webkit-border-start: 0;
- background-color: rgb(235, 239, 249);
+ border-left: 5px solid rgb(235, 239, 249);
cursor: e-resize;
- width: 5px;
<if expr="is_macosx">
cursor: col-resize;
</if>
+ overflow-x: hidden;
}
.tree-row.drag-on,
@@ -291,7 +327,7 @@ list.drag-above::before {
list > .drag-below,
list > .drag-above {
- overflow : visible;
+ overflow: visible;
}
.summary > * {
@@ -299,9 +335,10 @@ list > .drag-above {
margin: 0;
}
-.summary button {
+#folders-button,
+#organize-button,
+.splitter button {
-webkit-appearance: none;
- -webkit-margin-start: 16px;
-webkit-padding-end: 11px;
-webkit-padding-start: 0;
background: transparent -webkit-canvas(drop-down-arrow)
@@ -313,7 +350,16 @@ list > .drag-above {
padding-top: 0;
}
-html[dir=rtl] .summary button {
+#folders-button {
+ -webkit-margin-start: 16px;
+}
+
+#organize-button {
+ -webkit-margin-start: 4px;
+}
+
+html[dir=rtl] #folders-button,
+html[dir=rtl] #organize-button {
background-position: left center;
}
diff --git a/chrome/browser/resources/bookmark_manager/js/main.js b/chrome/browser/resources/bookmark_manager/js/main.js
index a02fded..429abce 100644
--- a/chrome/browser/resources/bookmark_manager/js/main.js
+++ b/chrome/browser/resources/bookmark_manager/js/main.js
@@ -16,9 +16,9 @@
/**
* An array containing the BookmarkTreeNodes that were deleted in the last
* deletion action. This is used for implementing undo.
- * @type {Array.<Array.<BookmarkTreeNode>>}
+ * @type {?{nodes: Array.<BookmarkTreeNode>, target: (EventTarget|undefined)}}
*/
-var lastDeletedNodes;
+var lastDeleted;
/**
*
@@ -161,11 +161,10 @@ function navigateTo(id, opt_callback) {
'BookmarkManager_NavigateTo_' + metricsId);
if (opt_callback) {
- var list = getRequiredElement('list');
- if (list.parentId == id)
+ if (bmm.list.parentId == id)
opt_callback();
else
- addOneShotEventListener(list, 'load', opt_callback);
+ addOneShotEventListener(bmm.list, 'load', opt_callback);
}
}
@@ -398,8 +397,6 @@ function updateOpenCommand(e, command, singularId, pluralId, commandDisabled) {
// The command label reflects the selection which might not reflect
// how many bookmarks will be opened. For example if you right click an
// empty area in a folder with 1 bookmark the text should still say "all".
- assert(!e.target || e.target instanceof BookmarkList ||
- e.target instanceof BookmarkTree);
var selectedNodes = getSelectedBookmarkNodes(e.target).filter(notNewNode);
var singular = selectedNodes.length == 1 && !bmm.isFolder(selectedNodes[0]);
command.label = loadTimeData.getString(singular ? singularId : pluralId);
@@ -425,19 +422,52 @@ function updateOpenCommand(e, command, singularId, pluralId, commandDisabled) {
* @param {Function=} opt_f Function to call after the state has been updated.
*/
function updatePasteCommand(opt_f) {
- function update(canPaste) {
- var organizeMenuCommand = $('paste-from-organize-menu-command');
- var contextMenuCommand = $('paste-from-context-menu-command');
- organizeMenuCommand.disabled = !canPaste;
- contextMenuCommand.disabled = !canPaste;
- if (opt_f)
- opt_f();
+ function update(commandId, canPaste) {
+ $(commandId).disabled = !canPaste;
}
- // We cannot paste into search view.
- if (bmm.list.isSearch())
- update(false);
- else
- chrome.bookmarkManagerPrivate.canPaste(bmm.list.parentId, update);
+
+ var promises = [];
+
+ // The folders menu.
+ if (bmm.tree.selectedItem) {
+ promises.push(new Promise(function(resolve) {
+ var id = bmm.tree.selectedItem.bookmarkId;
+ chrome.bookmarkManagerPrivate.canPaste(id, function(canPaste) {
+ update('paste-from-folders-menu-command', canPaste);
+ resolve(canPaste);
+ });
+ }));
+ } else {
+ // Tree's not loaded yet.
+ update('paste-from-folders-menu-command', false);
+ }
+
+ // The organize menu.
+ var listId = bmm.list.parentId;
+ if (bmm.list.isSearch() || !listId) {
+ // We cannot paste into search view or the list isn't ready.
+ update('paste-from-organize-menu-command', false);
+ } else {
+ promises.push(new Promise(function(resolve) {
+ chrome.bookmarkManagerPrivate.canPaste(listId, function(canPaste) {
+ update('paste-from-organize-menu-command', canPaste);
+ resolve(canPaste);
+ });
+ }));
+ }
+
+ Promise.all(promises).then(function() {
+ var cmd;
+ if (document.activeElement == bmm.list)
+ cmd = 'paste-from-organize-menu-command';
+ else if (document.activeElement == bmm.tree)
+ cmd = 'paste-from-folders-menu-command';
+
+ if (cmd)
+ update('paste-from-context-menu-command', !$(cmd).disabled);
+
+ if (opt_f) opt_f();
+ });
}
function handleCanExecuteForDocument(e) {
@@ -446,15 +476,18 @@ function handleCanExecuteForDocument(e) {
case 'import-menu-command':
e.canExecute = canEdit;
break;
+
case 'export-menu-command':
// We can always execute the export-menu command.
e.canExecute = true;
break;
+
case 'sort-command':
e.canExecute = !bmm.list.isSearch() &&
bmm.list.dataModel && bmm.list.dataModel.length > 1 &&
!isUnmodifiable(bmm.tree.getBookmarkNodeById(bmm.list.parentId));
break;
+
case 'undo-command':
// If the search box is active, pass the undo command through
// (fixes http://crbug.com/278112). Otherwise, because
@@ -462,8 +495,10 @@ function handleCanExecuteForDocument(e) {
// just make it a no-op if undo is not possible.
e.canExecute = e.currentTarget.activeElement !== $('term');
break;
+
default:
canExecuteForList(e);
+ canExecuteForTree(e);
break;
}
}
@@ -476,8 +511,8 @@ function handleCanExecuteForDocument(e) {
*/
function canExecuteShared(e, isSearch) {
var command = e.command;
- var commandId = command.id;
- switch (commandId) {
+ switch (command.id) {
+ case 'paste-from-folders-menu-command':
case 'paste-from-organize-menu-command':
case 'paste-from-context-menu-command':
updatePasteCommand();
@@ -485,6 +520,7 @@ function canExecuteShared(e, isSearch) {
case 'add-new-bookmark-command':
case 'new-folder-command':
+ case 'new-folder-from-folders-menu-command':
var parentId = computeParentFolderForNewItem();
var unmodifiable = isUnmodifiable(
bmm.tree.getBookmarkNodeById(parentId));
@@ -494,15 +530,18 @@ function canExecuteShared(e, isSearch) {
case 'open-in-new-tab-command':
updateOpenCommand(e, command, 'open_in_new_tab', 'open_all', false);
break;
+
case 'open-in-background-tab-command':
updateOpenCommand(e, command, '', '', false);
break;
+
case 'open-in-new-window-command':
updateOpenCommand(e, command,
'open_in_new_window', 'open_all_new_window',
// Disabled when incognito is forced.
incognitoModeAvailability == 'forced' || !canOpenNewWindows);
break;
+
case 'open-incognito-window-command':
updateOpenCommand(e, command,
'open_incognito', 'open_all_incognito',
@@ -511,7 +550,7 @@ function canExecuteShared(e, isSearch) {
break;
case 'undo-delete-command':
- e.canExecute = !!lastDeletedNodes;
+ e.canExecute = !!lastDeleted;
break;
}
}
@@ -521,9 +560,6 @@ function canExecuteShared(e, isSearch) {
* @param {!cr.ui.CanExecuteEvent} e Can execute event object.
*/
function canExecuteForList(e) {
- var command = e.command;
- var commandId = command.id;
-
function hasSelected() {
return !!bmm.list.selectedItem;
}
@@ -545,7 +581,8 @@ function canExecuteForList(e) {
return bmm.list.isSearch();
}
- switch (commandId) {
+ var command = e.command;
+ switch (command.id) {
case 'rename-folder-command':
// Show rename if a single folder is selected.
var items = bmm.list.selectedItems;
@@ -604,25 +641,27 @@ function handleCanExecuteForList(e) {
// Update canExecute for the commands when the tree is the active element.
function handleCanExecuteForTree(e) {
if (e.target != bmm.tree) return;
+ canExecuteForTree(e);
+}
- var command = e.command;
- var commandId = command.id;
-
+function canExecuteForTree(e) {
function hasSelected() {
- return !!e.target.selectedItem;
+ return !!bmm.tree.selectedItem;
}
function isSearch() {
- var item = e.target.selectedItem;
- return item == searchTreeItem;
+ return bmm.tree.selectedItem == searchTreeItem;
}
function isTopLevelItem() {
- return e.target.selectedItem.parentNode == bmm.tree;
+ return bmm.tree.selectedItem &&
+ bmm.tree.selectedItem.parentNode == bmm.tree;
}
- switch (commandId) {
+ var command = e.command;
+ switch (command.id) {
case 'rename-folder-command':
+ case 'rename-folder-from-folders-menu-command':
command.hidden = false;
e.canExecute = hasSelected() && !isTopLevelItem() && canEdit &&
!hasUnmodifiable(bmm.tree.selectedFolders);
@@ -634,15 +673,22 @@ function handleCanExecuteForTree(e) {
break;
case 'delete-command':
+ case 'delete-from-folders-menu-command':
case 'cut-command':
+ case 'cut-from-folders-menu-command':
e.canExecute = hasSelected() && !isTopLevelItem() && canEdit &&
!hasUnmodifiable(bmm.tree.selectedFolders);
break;
case 'copy-command':
+ case 'copy-from-folders-menu-command':
e.canExecute = hasSelected() && !isTopLevelItem();
break;
+ case 'undo-delete-from-folders-menu-command':
+ e.canExecute = lastDeleted && lastDeleted.target == bmm.tree;
+ break;
+
default:
canExecuteShared(e, isSearch());
}
@@ -659,9 +705,19 @@ function updateAllCommands() {
}
function updateEditingCommands() {
- var editingCommands = ['cut', 'delete', 'rename-folder', 'edit',
- 'add-new-bookmark', 'new-folder', 'sort',
- 'paste-from-context-menu', 'paste-from-organize-menu'];
+ var editingCommands = [
+ 'add-new-bookmark',
+ 'cut',
+ 'cut-from-folders-menu',
+ 'delete',
+ 'edit',
+ 'new-folder',
+ 'paste-from-context-menu',
+ 'paste-from-folders-menu',
+ 'paste-from-organize-menu',
+ 'rename-folder',
+ 'sort',
+ ];
chrome.bookmarkManagerPrivate.canEdit(function(result) {
if (result != canEdit) {
@@ -677,11 +733,15 @@ function handleChangeForTree(e) {
navigateTo(bmm.tree.selectedItem.bookmarkId);
}
-function handleOrganizeButtonClick(e) {
+function handleMenuButtonClicked(e) {
updateEditingCommands();
- $('add-new-bookmark-command').canExecuteChange();
- $('new-folder-command').canExecuteChange();
- $('sort-command').canExecuteChange();
+
+ if (e.currentTarget.id == 'folders-menu') {
+ $('copy-from-folders-menu-command').canExecuteChange();
+ $('undo-delete-from-folders-menu-command').canExecuteChange();
+ } else {
+ $('copy-command').canExecuteChange();
+ }
}
function handleRename(e) {
@@ -776,7 +836,7 @@ function getLinkController() {
* Returns the selected bookmark nodes of the provided tree or list.
* If |opt_target| is not provided or null the active element is used.
* Only call this if the list or the tree is focused.
- * @param {(BookmarkList|BookmarkTree)=} opt_target The target list or tree.
+ * @param {EventTarget=} opt_target The target list or tree.
* @return {!Array} Array of bookmark nodes.
*/
function getSelectedBookmarkNodes(opt_target) {
@@ -785,10 +845,11 @@ function getSelectedBookmarkNodes(opt_target) {
}
/**
+ * @param {EventTarget=} opt_target The target list or tree.
* @return {!Array.<string>} An array of the selected bookmark IDs.
*/
-function getSelectedBookmarkIds() {
- var selectedNodes = getSelectedBookmarkNodes();
+function getSelectedBookmarkIds(opt_target) {
+ var selectedNodes = getSelectedBookmarkNodes(opt_target);
selectedNodes.sort(function(a, b) { return a.index - b.index });
return selectedNodes.map(function(node) {
return node.id;
@@ -852,16 +913,21 @@ function updateSearchResults() {
/**
* Deletes the selected bookmarks. The bookmarks are saved in memory in case
* the user needs to undo the deletion.
+ * @param {EventTarget=} opt_target The deleter of bookmarks.
*/
-function deleteBookmarks() {
- var selectedIds = getSelectedBookmarkIds();
- var filteredIds = getFilteredSelectedBookmarkIds();
- lastDeletedNodes = [];
+function deleteBookmarks(opt_target) {
+ var selectedIds = getSelectedBookmarkIds(opt_target);
+ if (!selectedIds.length)
+ return;
+
+ var filteredIds = getFilteredSelectedBookmarkIds(opt_target);
+ lastDeleted = {nodes: [], target: opt_target};
function performDelete() {
// Only remove filtered ids.
chrome.bookmarkManagerPrivate.removeTrees(filteredIds);
$('undo-delete-command').canExecuteChange();
+ $('undo-delete-from-folders-menu-command').canExecuteChange();
performGlobalUndo = undoDelete;
}
@@ -869,10 +935,10 @@ function deleteBookmarks() {
// Store all selected ids.
selectedIds.forEach(function(id) {
chrome.bookmarks.getSubTree(id, function(results) {
- lastDeletedNodes.push(results);
+ lastDeleted.nodes.push(results);
// When all nodes have been saved, perform the deletion.
- if (lastDeletedNodes.length === selectedIds.length) {
+ if (lastDeleted.nodes.length === selectedIds.length) {
performDelete();
updateSearchResults();
}
@@ -916,11 +982,12 @@ function restoreTree(node, opt_parentId) {
* Restores the last set of bookmarks that was deleted.
*/
function undoDelete() {
- lastDeletedNodes.forEach(function(arr) {
- arr.forEach(restoreTree);
+ lastDeleted.nodes.forEach(function(node) {
+ restoreTree(node);
});
- lastDeletedNodes = null;
+ lastDeleted = null;
$('undo-delete-command').canExecuteChange();
+ $('undo-delete-from-folders-menu-command').canExecuteChange();
// Only a single level of undo is supported, so disable global undo now.
performGlobalUndo = null;
@@ -955,8 +1022,9 @@ function editSelectedItem() {
/**
* Callback for the new folder command. This creates a new folder and starts
* a rename of it.
+ * @param {EventTarget=} opt_target The target to create a new folder in.
*/
-function newFolder() {
+function newFolder(opt_target) {
performGlobalUndo = null; // This can't be undone, so disable global undo.
var parentId = computeParentFolderForNewItem();
@@ -969,7 +1037,7 @@ function newFolder() {
}, callback);
}
- if (document.activeElement == bmm.tree) {
+ if ((opt_target || document.activeElement) == bmm.tree) {
createFolder(function(newNode) {
navigateTo(newNode.id, function() {
bmm.treeLookup[newNode.id].editing = true;
@@ -1139,11 +1207,15 @@ function hasSelectedAncestor(parentNode) {
bmm.tree.getBookmarkNodeById(parentNode.parentId));
}
-function getFilteredSelectedBookmarkIds() {
+/**
+ * @param {EventTarget=} opt_target A target to get bookmark IDs from.
+ * @return {Array.<string>} An array of bookmarks IDs.
+ */
+function getFilteredSelectedBookmarkIds(opt_target) {
// Remove duplicates from filteredIds and return.
- var filteredIds = new Array();
+ var filteredIds = [];
// Selected nodes to iterate through for matches.
- var nodes = getSelectedBookmarkNodes();
+ var nodes = getSelectedBookmarkNodes(opt_target);
for (var i = 0; i < nodes.length; i++)
if (!hasSelectedAncestor(bmm.tree.getBookmarkNodeById(nodes[i].parentId)))
@@ -1159,16 +1231,18 @@ function getFilteredSelectedBookmarkIds() {
*/
function handleCommand(e) {
var command = e.command;
- var commandId = command.id;
- switch (commandId) {
+ var target;
+ switch (command.id) {
case 'import-menu-command':
recordUserAction('Import');
chrome.bookmarks.import();
break;
+
case 'export-menu-command':
recordUserAction('Export');
chrome.bookmarks.export();
break;
+
case 'undo-command':
if (performGlobalUndo) {
recordUserAction('UndoGlobal');
@@ -1177,73 +1251,106 @@ function handleCommand(e) {
recordUserAction('UndoNone');
}
break;
+
case 'show-in-folder-command':
recordUserAction('ShowInFolder');
showInFolder();
break;
+
case 'open-in-new-tab-command':
case 'open-in-background-tab-command':
recordUserAction('OpenInNewTab');
openBookmarks(LinkKind.BACKGROUND_TAB,
assertInstanceof(e.target, HTMLElement));
break;
+
case 'open-in-new-window-command':
recordUserAction('OpenInNewWindow');
openBookmarks(LinkKind.WINDOW,
assertInstanceof(e.target, HTMLElement));
break;
+
case 'open-incognito-window-command':
recordUserAction('OpenIncognito');
openBookmarks(LinkKind.INCOGNITO,
assertInstanceof(e.target, HTMLElement));
break;
+
+ case 'delete-from-folders-menu-command':
+ target = bmm.tree;
case 'delete-command':
recordUserAction('Delete');
- deleteBookmarks();
+ deleteBookmarks(target);
break;
+
+ case 'copy-from-folders-menu-command':
+ target = bmm.tree;
case 'copy-command':
recordUserAction('Copy');
- chrome.bookmarkManagerPrivate.copy(getSelectedBookmarkIds(),
+ chrome.bookmarkManagerPrivate.copy(getSelectedBookmarkIds(target),
updatePasteCommand);
break;
+
+ case 'cut-from-folders-menu-command':
+ target = bmm.tree;
case 'cut-command':
recordUserAction('Cut');
- chrome.bookmarkManagerPrivate.cut(getSelectedBookmarkIds(),
+ chrome.bookmarkManagerPrivate.cut(getSelectedBookmarkIds(target),
function() {
updatePasteCommand();
updateSearchResults();
});
break;
+
case 'paste-from-organize-menu-command':
pasteBookmark(bmm.list.parentId);
break;
+
+ case 'paste-from-folders-menu-command':
+ pasteBookmark(bmm.tree.selectedItem.bookmarkId);
+ break;
+
case 'paste-from-context-menu-command':
pasteBookmark(getSelectedId());
break;
+
case 'sort-command':
recordUserAction('Sort');
chrome.bookmarkManagerPrivate.sortChildren(bmm.list.parentId);
break;
+
case 'rename-folder-command':
editSelectedItem();
break;
+
+ case 'rename-folder-from-folders-menu-command':
+ bmm.tree.selectedItem.editing = true;
+ break;
+
case 'edit-command':
recordUserAction('Edit');
editSelectedItem();
break;
+
case 'new-folder-command':
+ target = bmm.tree;
+ case 'new-folder-from-folders-menu-command':
recordUserAction('NewFolder');
- newFolder();
+ newFolder(target);
break;
+
case 'add-new-bookmark-command':
recordUserAction('AddPage');
addPage();
break;
+
case 'open-in-same-window-command':
recordUserAction('OpenInSame');
openItem();
break;
+
case 'undo-delete-command':
+ case 'undo-delete-from-folders-menu-command':
recordUserAction('UndoDelete');
undoDelete();
break;
@@ -1280,14 +1387,14 @@ function initializeSplitter() {
var splitter = document.querySelector('.main > .splitter');
Splitter.decorate(splitter);
+ var splitterStyle = splitter.previousElementSibling.style;
+
// The splitter persists the size of the left component in the local store.
if ('treeWidth' in window.localStorage)
- splitter.previousElementSibling.style.width =
- window.localStorage['treeWidth'];
+ splitterStyle.width = window.localStorage['treeWidth'];
splitter.addEventListener('resize', function(e) {
- window.localStorage['treeWidth'] =
- splitter.previousElementSibling.style.width;
+ window.localStorage['treeWidth'] = splitterStyle.width;
});
}
@@ -1342,8 +1449,8 @@ function continueInitializeBookmarkManager(localizedStrings) {
$('term').addEventListener('search', handleSearch);
- document.querySelector('.summary button').addEventListener(
- 'click', handleOrganizeButtonClick);
+ $('folders-button').addEventListener('click', handleMenuButtonClicked);
+ $('organize-button').addEventListener('click', handleMenuButtonClicked);
document.addEventListener('canExecute', handleCanExecuteForDocument);
document.addEventListener('command', handleCommand);
diff --git a/chrome/browser/resources/bookmark_manager/main.html b/chrome/browser/resources/bookmark_manager/main.html
index 0ae8e56..d38a43c 100644
--- a/chrome/browser/resources/bookmark_manager/main.html
+++ b/chrome/browser/resources/bookmark_manager/main.html
@@ -58,24 +58,36 @@ found in the LICENSE file.
<header>
<h2 i18n-content="title"></h2>
<form>
- <input type="search" id="term" tabindex=1 autofocus incremental
- i18n-values="placeholder:search_button">
+ <input type="search" id="term" i18n-values="placeholder:search_button"
+ autofocus incremental>
</form>
</header>
-<div class="summary">
- <div>
- <button menu="#organize-menu" tabindex="4" i18n-content="organize_menu">
- </button>
+<div class="main">
+ <div id="tree-pane" class="pane">
+ <div>
+ <button menu="#folders-menu" i18n-content="folders_menu"
+ id="folders-button"></button>
+ </div>
+ <div id="tree-container">
+ <tree id="tree" role="tree"></tree>
+ </div>
</div>
-</div>
-
-<div class=main>
- <div id=tree-container>
- <tree id=tree tabindex=2 role="tree"></tree>
+ <div class="splitter">
+ <div>
+ <!-- Used to occupy the correct amount of vertical space. -->
+ <button menu="#no-menu"></button>
+ </div>
+ </div>
+ <div id="list-pane" class="pane">
+ <div>
+ <button menu="#organize-menu" i18n-content="organize_menu"
+ id="organize-button"></button>
+ </div>
+ <!-- The list doesn't use a scroll container as it truncates horizontally
+ and handles its own vertical overflow. -->
+ <list id="list"></list>
</div>
- <div class=splitter></div>
- <list id=list tabindex=2></list>
</div>
<!-- Organize menu -->
@@ -88,8 +100,6 @@ found in the LICENSE file.
<command i18n-values=".label:copy" id="copy-command"></command>
<command i18n-values=".label:paste" id="paste-from-organize-menu-command">
</command>
-<command i18n-values=".label:paste" id="paste-from-context-menu-command">
-</command>
<command i18n-values=".label:delete" id="delete-command"></command>
<command i18n-values=".label:undo_delete" id="undo-delete-command"></command>
<command i18n-values=".label:sort" id="sort-command"></command>
@@ -97,10 +107,27 @@ found in the LICENSE file.
</command>
<command i18n-values=".label:new_folder" id="new-folder-command"></command>
+<!-- Folders menu -->
+<command i18n-values=".label:cut" id="cut-from-folders-menu-command"></command>
+<command i18n-values=".label:copy" id="copy-from-folders-menu-command">
+</command>
+<command i18n-values=".label:paste" id="paste-from-folders-menu-command">
+</command>
+<command i18n-values=".label:new_folder"
+ id="new-folder-from-folders-menu-command"></command>
+<command i18n-values=".label:delete" id="delete-from-folders-menu-command">
+</command>
+<command i18n-values=".label:undo_delete"
+ id="undo-delete-from-folders-menu-command"></command>
+
<!-- Tools menu -->
<command i18n-values=".label:import_menu" id="import-menu-command"></command>
<command i18n-values=".label:export_menu" id="export-menu-command"></command>
+<!-- Context menu -->
+<command i18n-values=".label:paste" id="paste-from-context-menu-command">
+</command>
+
<!-- open * are handled in canExecute handler -->
<command id="open-in-new-tab-command"></command>
<command id="open-in-background-tab-command"></command>
@@ -110,8 +137,28 @@ found in the LICENSE file.
<command id="undo-command"></command>
+<command i18n-values=".label:rename_folder"
+ id="rename-folder-from-folders-menu-command"></command>
+<command i18n-values=".label:paste" id="paste-from-folders-menu-command">
+</command>
+
<!-- TODO(arv): I think the commands might be better created in code? -->
+<menu id="folders-menu">
+ <button command="#new-folder-from-folders-menu-command"></button>
+ <hr>
+ <button command="#rename-folder-from-folders-menu-command"></button>
+ <hr>
+ <button command="#cut-from-folders-menu-command"></button>
+ <button command="#copy-from-folders-menu-command"></button>
+ <button command="#paste-from-folders-menu-command"></button>
+ <hr>
+ <button command="#delete-from-folders-menu-command"></button>
+ <button command="#undo-delete-from-folders-menu-command"></button>
+</menu>
+
+<menu id="no-menu"></menu>
+
<menu id="organize-menu">
<button command="#add-new-bookmark-command"></button>
<button command="#new-folder-command"></button>