From 7563ded7df1d0c27595d9da8db463e6ad53a9bdb Mon Sep 17 00:00:00 2001 From: Erica Wright Date: Tue, 2 Mar 2021 15:34:56 +0000 Subject: [PATCH] Bug 1692668 - Update bookmarks context menu for clarity. r=Gijs,fluent-reviewers,flod Differential Revision: https://phabricator.services.mozilla.com/D106046 --- browser/base/content/browser-places.js | 2 +- .../places/content/browserPlacesViews.js | 14 +- .../components/places/content/controller.js | 36 ++- browser/components/places/content/places.js | 10 +- .../components/places/content/places.xhtml | 6 +- .../content/placesContextMenu.inc.xhtml | 130 +++++---- .../places/tests/browser/browser.ini | 1 + .../browser_bookmark_change_location.js | 6 +- .../browser_bookmark_context_menu_contents.js | 249 ++++++++++++++++++ .../browser/browser_bookmark_remove_tags.js | 4 +- .../browser/browser_bookmarks_change_title.js | 4 +- ...marks_toolbar_context_menu_view_options.js | 6 +- .../browser_panelview_bookmarks_delete.js | 4 +- .../tests/browser/browser_remove_bookmarks.js | 12 +- .../browser_toolbar_other_bookmarks.js | 6 +- browser/locales/en-US/browser/places.ftl | 53 ++-- 16 files changed, 446 insertions(+), 97 deletions(-) create mode 100644 browser/components/places/tests/browser/browser_bookmark_context_menu_contents.js diff --git a/browser/base/content/browser-places.js b/browser/base/content/browser-places.js index da3f8d11807d..f30883e28996 100644 --- a/browser/base/content/browser-places.js +++ b/browser/base/content/browser-places.js @@ -1688,7 +1688,7 @@ var BookmarkingUI = { // Used by the Places context menu in the Bookmarks Toolbar // when nothing is selected - menu.setAttribute("selectiontype", "none"); + menu.setAttribute("selectiontype", "none|single"); MozXULElement.insertFTLIfNeeded("browser/toolbarContextMenu.ftl"); let menuItems = [ diff --git a/browser/components/places/content/browserPlacesViews.js b/browser/components/places/content/browserPlacesViews.js index 17c9347e39c2..8210a1bc64db 100644 --- a/browser/components/places/content/browserPlacesViews.js +++ b/browser/components/places/content/browserPlacesViews.js @@ -260,6 +260,9 @@ PlacesViewBase.prototype = { ); existingOtherBookmarksItem?.remove(); + let manageBookmarksMenu = aPopup.querySelector( + "#placesContext_showAllBookmarks" + ); // Add the View menu for the Bookmarks Toolbar and "Show Other Bookmarks" menu item // if the click originated from the Bookmarks Toolbar. if (gBookmarksToolbar2h2020) { @@ -267,13 +270,16 @@ PlacesViewBase.prototype = { existingSubmenu?.remove(); let bookmarksToolbar = document.getElementById("PersonalToolbar"); if (bookmarksToolbar?.contains(aPopup.triggerNode)) { + manageBookmarksMenu.removeAttribute("hidden"); + let menu = BookmarkingUI.buildBookmarksToolbarSubmenu(bookmarksToolbar); - aPopup.appendChild(menu); + aPopup.insertBefore(menu, manageBookmarksMenu); if ( aPopup.triggerNode.id === "OtherBookmarks" || aPopup.triggerNode.id === "PlacesChevron" || - aPopup.triggerNode.id === "PlacesToolbarItems" + aPopup.triggerNode.id === "PlacesToolbarItems" || + aPopup.triggerNode.parentNode.id === "PlacesToolbarItems" ) { let otherBookmarksMenuItem = BookmarkingUI.buildShowOtherBookmarksMenuItem(); @@ -284,7 +290,11 @@ PlacesViewBase.prototype = { ); } } + } else { + manageBookmarksMenu.setAttribute("hidden", "true"); } + } else { + manageBookmarksMenu.setAttribute("hidden", "true"); } return this.controller.buildContextMenu(aPopup); diff --git a/browser/components/places/content/controller.js b/browser/components/places/content/controller.js index 6cd4a1259dc2..935b876b6a86 100644 --- a/browser/components/places/content/controller.js +++ b/browser/components/places/content/controller.js @@ -549,6 +549,8 @@ PlacesController.prototype = { * true if it should be hidden inside the private browsing mode * 9) The "forcehideintabbrowser" attribute may be set on a menu-item if * it should be hidden when we're in a tabbed browsing window. + * 10) The "forcehidenotintabbrowser" attribute may be set on a menu-item if + * it should be hidden when we're not in a tabbed browsing window. * @param aPopup * The menupopup to build children into. * @return true if at least one item is visible, false otherwise. @@ -587,12 +589,16 @@ PlacesController.prototype = { var hideIfInTabBrowser = item.getAttribute("forcehideintabbrowser") == "true" && window.top.gBrowser; + var hideIfNotInTabBrowser = + item.getAttribute("forcehidenotintabbrowser") == "true" && + !window.top.gBrowser; var hideIfPrivate = item.getAttribute("hideifprivatebrowsing") == "true" && PrivateBrowsingUtils.isWindowPrivate(window); var shouldHideItem = hideIfNoIP || hideIfInTabBrowser || + hideIfNotInTabBrowser || hideIfPrivate || !this._shouldShowMenuItem(item, metadata); item.hidden = item.disabled = shouldHideItem; @@ -621,20 +627,32 @@ PlacesController.prototype = { // New separator, count again: visibleItemsBeforeSep = false; } + + if (item.id === "placesContext_deleteBookmark") { + document.l10n.setAttributes(item, "places-remove-bookmark", { + count: metadata.length, + }); + } } - // Set Open Folder/Links In Tabs items enabled state if they're visible + // Set Open Folder/Links In Tabs or Open Bookmark item's enabled state if they're visible if (usableItemCount > 0) { - var openContainerInTabsItem = document.getElementById( + let openContainerInTabsItem = document.getElementById( "placesContext_openContainer:tabs" ); - if (!openContainerInTabsItem.hidden) { - var containerToUse = this._view.selectedNode || this._view.result.root; - if (PlacesUtils.nodeIsContainer(containerToUse)) { - if (!PlacesUtils.hasChildURIs(containerToUse)) { - openContainerInTabsItem.disabled = true; - // Ensure that we don't display the menu if nothing is enabled: - usableItemCount--; + let openBookmarksItem = document.getElementById( + "placesContext_openBookmarkContainer:tabs" + ); + for (let menuItem of [openContainerInTabsItem, openBookmarksItem]) { + if (!menuItem.hidden) { + var containerToUse = + this._view.selectedNode || this._view.result.root; + if (PlacesUtils.nodeIsContainer(containerToUse)) { + if (!PlacesUtils.hasChildURIs(containerToUse)) { + menuItem.disabled = true; + // Ensure that we don't display the menu if nothing is enabled: + usableItemCount--; + } } } } diff --git a/browser/components/places/content/places.js b/browser/components/places/content/places.js index 205c1feec106..6c8ebfeb5141 100644 --- a/browser/components/places/content/places.js +++ b/browser/components/places/content/places.js @@ -229,10 +229,12 @@ var PlacesOrganizer = { } } - // remove the "Properties" context-menu item, we've our own details pane - document - .getElementById("placesContext") - .removeChild(document.getElementById("placesContext_show:info")); + // remove the "Edit" and "Edit Bookmark" context-menu item, we're in our own details pane + let contextMenu = document.getElementById("placesContext"); + contextMenu.removeChild(document.getElementById("placesContext_show:info")); + contextMenu.removeChild( + document.getElementById("placesContext_show_bookmark:info") + ); if (!Services.policies.isAllowed("profileImport")) { document diff --git a/browser/components/places/content/places.xhtml b/browser/components/places/content/places.xhtml index 2a23499a5113..8f89e2259872 100644 --- a/browser/components/places/content/places.xhtml +++ b/browser/components/places/content/places.xhtml @@ -177,13 +177,13 @@ + data-l10n-id="places-add-bookmark"/> + data-l10n-id="places-add-folder"/> + data-l10n-id="places-add-separator"/> #ifdef XP_MACOSX diff --git a/browser/components/places/content/placesContextMenu.inc.xhtml b/browser/components/places/content/placesContextMenu.inc.xhtml index d5d174e1fcbd..586c58250f12 100644 --- a/browser/components/places/content/placesContextMenu.inc.xhtml +++ b/browser/components/places/content/placesContextMenu.inc.xhtml @@ -12,9 +12,16 @@ selectiontype="single" selection="link" forcehideintabbrowser="true"/> + + selection="folder|host|query" + forcehideselection="bookmark" + forcehideintabbrowser="true"/> + selection="link" + forcehideintabbrowser="true"/> - - - + + - - - - - - + selection="bookmark"/> + selection="tagChild|folder|query|dynamiccontainer|separator|host" + forcehideselection="bookmark"/> + + + + + + + + + + + - + diff --git a/browser/components/places/tests/browser/browser.ini b/browser/components/places/tests/browser/browser.ini index d2d56e371f30..68fb170ee673 100644 --- a/browser/components/places/tests/browser/browser.ini +++ b/browser/components/places/tests/browser/browser.ini @@ -16,6 +16,7 @@ skip-if = (verify && debug) [browser_autoshow_bookmarks_toolbar.js] [browser_bookmark_add_tags.js] [browser_bookmark_backup_export_import.js] +[browser_bookmark_context_menu_contents.js] [browser_bookmark_change_location.js] [browser_bookmark_folder_moveability.js] [browser_bookmark_menu_ctrl_click.js] diff --git a/browser/components/places/tests/browser/browser_bookmark_change_location.js b/browser/components/places/tests/browser/browser_bookmark_change_location.js index 29f2213f7fce..c54dcc2241b9 100644 --- a/browser/components/places/tests/browser/browser_bookmark_change_location.js +++ b/browser/components/places/tests/browser/browser_bookmark_change_location.js @@ -52,9 +52,13 @@ add_task(async function test_change_location_from_Toolbar() { button: 2, type: "contextmenu", }); + console.log("JKJKJKJKJKafterBEFORE"); await promisePopup; + console.log("JKJKJKJKJKafter"); - let properties = document.getElementById("placesContext_show:info"); + let properties = document.getElementById( + "placesContext_show_bookmark:info" + ); EventUtils.synthesizeMouseAtCenter(properties, {}); }, async function test(dialogWin) { diff --git a/browser/components/places/tests/browser/browser_bookmark_context_menu_contents.js b/browser/components/places/tests/browser/browser_bookmark_context_menu_contents.js new file mode 100644 index 000000000000..2e267fa01b8e --- /dev/null +++ b/browser/components/places/tests/browser/browser_bookmark_context_menu_contents.js @@ -0,0 +1,249 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +/** + * Test removing bookmarks from the Bookmarks Toolbar and Library. + */ +const BOOKMARKS_H2_2020_PREF = "browser.toolbars.bookmarks.2h2020"; +const bookmarksInfo = [ + { + title: "firefox", + url: "http://example.com", + }, + { + title: "rules", + url: "http://example.com/2", + }, + { + title: "yo", + url: "http://example.com/2", + }, +]; +const TEST_URL = "about:mozilla"; + +add_task(async function setup() { + await PlacesUtils.bookmarks.eraseEverything(); + + let toolbar = document.getElementById("PersonalToolbar"); + let wasCollapsed = toolbar.collapsed; + + // Uncollapse the personal toolbar if needed. + if (wasCollapsed) { + await promiseSetToolbarVisibility(toolbar, true); + } + + registerCleanupFunction(async () => { + // Collapse the personal toolbar if needed. + if (wasCollapsed) { + await promiseSetToolbarVisibility(toolbar, false); + } + await PlacesUtils.bookmarks.eraseEverything(); + }); +}); + +let OptionItemExists = elementId => { + let optionItem = document.getElementById(elementId); + + Assert.ok(optionItem, "Context menu contains the appropriate option"); + Assert.ok( + BrowserTestUtils.is_visible(optionItem), + "Context menu option is visible" + ); +}; + +let OptionsMatchExpected = (contextMenu, expectedOptionItems) => { + let idList = []; + for (let elem of contextMenu.children) { + if ( + BrowserTestUtils.is_visible(elem) && + elem.localName !== "menuseparator" + ) { + idList.push(elem.id); + } + } + + Assert.deepEqual( + idList.sort(), + expectedOptionItems.sort(), + "Content is the same across both lists" + ); +}; + +let checkContextMenu = async (cbfunc, optionItems) => { + await SpecialPowers.pushPrefEnv({ + set: [[BOOKMARKS_H2_2020_PREF, true]], + }); + await PlacesUtils.bookmarks.insert({ + parentGuid: PlacesUtils.bookmarks.toolbarGuid, + title: "Second Bookmark Title", + url: TEST_URL, + }); + + await PlacesUtils.bookmarks.insertTree({ + guid: PlacesUtils.bookmarks.unfiledGuid, + children: bookmarksInfo, + }); + + let contextMenu = await cbfunc(); + + for (let item of optionItems) { + OptionItemExists(item); + } + + OptionsMatchExpected(contextMenu, optionItems); + contextMenu.hidePopup(); + await PlacesUtils.bookmarks.eraseEverything(); +}; + +add_task(async function test_bookmark_contextmenu_contents() { + let optionItems = [ + "placesContext_open:newtab", + "placesContext_open:newwindow", + "placesContext_open:newprivatewindow", + "placesContext_show_bookmark:info", + "placesContext_deleteBookmark", + "placesContext_cut", + "placesContext_copy", + "placesContext_paste_group", + "placesContext_new:bookmark", + "placesContext_new:folder", + "placesContext_new:separator", + "placesContext_showAllBookmarks", + "toggle_PersonalToolbar", + "show-other-bookmarks_PersonalToolbar", + ]; + + await checkContextMenu(async function() { + let toolbarBookmark = await PlacesUtils.bookmarks.insert({ + parentGuid: PlacesUtils.bookmarks.toolbarGuid, + title: "Bookmark Title", + url: TEST_URL, + }); + + let toolbarNode = getToolbarNodeForItemGuid(toolbarBookmark.guid); + + let contextMenu = document.getElementById("placesContext"); + let popupShownPromise = BrowserTestUtils.waitForEvent( + contextMenu, + "popupshown" + ); + + EventUtils.synthesizeMouseAtCenter(toolbarNode, { + button: 2, + type: "contextmenu", + }); + await popupShownPromise; + return contextMenu; + }, optionItems); +}); + +add_task(async function test_empty_contextmenu_contents() { + let optionItems = [ + "placesContext_openBookmarkContainer:tabs", + "placesContext_new:bookmark", + "placesContext_new:folder", + "placesContext_new:separator", + "placesContext_paste", + "placesContext_showAllBookmarks", + "toggle_PersonalToolbar", + "show-other-bookmarks_PersonalToolbar", + ]; + + await checkContextMenu(async function() { + let contextMenu = document.getElementById("placesContext"); + let toolbar = document.querySelector("#PlacesToolbarItems"); + let openToolbarContextMenuPromise = BrowserTestUtils.waitForPopupEvent( + contextMenu, + "shown" + ); + + // Use the end of the toolbar because the beginning (and even middle, on + // some resolutions) might be occluded by the empty toolbar message, which + // has a different context menu. + let bounds = toolbar.getBoundingClientRect(); + EventUtils.synthesizeMouse(toolbar, bounds.width - 5, 5, { + type: "contextmenu", + }); + + await openToolbarContextMenuPromise; + return contextMenu; + }, optionItems); +}); + +add_task(async function test_separator_contextmenu_contents() { + let optionItems = [ + "placesContext_delete", + "placesContext_cut", + "placesContext_copy", + "placesContext_paste_group", + "placesContext_new:bookmark", + "placesContext_new:folder", + "placesContext_new:separator", + "placesContext_showAllBookmarks", + "toggle_PersonalToolbar", + "show-other-bookmarks_PersonalToolbar", + ]; + + await checkContextMenu(async function() { + let sep = await PlacesUtils.bookmarks.insert({ + type: PlacesUtils.bookmarks.TYPE_SEPARATOR, + parentGuid: PlacesUtils.bookmarks.toolbarGuid, + }); + + let toolbarNode = getToolbarNodeForItemGuid(sep.guid); + let contextMenu = document.getElementById("placesContext"); + let popupShownPromise = BrowserTestUtils.waitForEvent( + contextMenu, + "popupshown" + ); + + EventUtils.synthesizeMouseAtCenter(toolbarNode, { + button: 2, + type: "contextmenu", + }); + await popupShownPromise; + return contextMenu; + }, optionItems); +}); + +add_task(async function test_folder_contextmenu_contents() { + let optionItems = [ + "placesContext_openBookmarkContainer:tabs", + "placesContext_show:info", + "placesContext_delete", + "placesContext_cut", + "placesContext_copy", + "placesContext_paste_group", + "placesContext_new:bookmark", + "placesContext_new:folder", + "placesContext_new:separator", + "placesContext_sortBy:name", + "placesContext_showAllBookmarks", + "toggle_PersonalToolbar", + "show-other-bookmarks_PersonalToolbar", + ]; + + await checkContextMenu(async function() { + let folder = await PlacesUtils.bookmarks.insert({ + type: PlacesUtils.bookmarks.TYPE_FOLDER, + parentGuid: PlacesUtils.bookmarks.toolbarGuid, + }); + + let toolbarNode = getToolbarNodeForItemGuid(folder.guid); + let contextMenu = document.getElementById("placesContext"); + let popupShownPromise = BrowserTestUtils.waitForEvent( + contextMenu, + "popupshown" + ); + + EventUtils.synthesizeMouseAtCenter(toolbarNode, { + button: 2, + type: "contextmenu", + }); + await popupShownPromise; + return contextMenu; + }, optionItems); +}); diff --git a/browser/components/places/tests/browser/browser_bookmark_remove_tags.js b/browser/components/places/tests/browser/browser_bookmark_remove_tags.js index 5478458eba6e..a0297f20b762 100644 --- a/browser/components/places/tests/browser/browser_bookmark_remove_tags.js +++ b/browser/components/places/tests/browser/browser_bookmark_remove_tags.js @@ -107,7 +107,9 @@ add_task(async function test_remove_tags_from_Toolbar() { }); await promisePopup; - let properties = document.getElementById("placesContext_show:info"); + let properties = document.getElementById( + "placesContext_show_bookmark:info" + ); EventUtils.synthesizeMouseAtCenter(properties, {}); }, async function test(dialogWin) { diff --git a/browser/components/places/tests/browser/browser_bookmarks_change_title.js b/browser/components/places/tests/browser/browser_bookmarks_change_title.js index e7ee543a8099..84694986ad54 100644 --- a/browser/components/places/tests/browser/browser_bookmarks_change_title.js +++ b/browser/components/places/tests/browser/browser_bookmarks_change_title.js @@ -116,7 +116,9 @@ add_task(async function test_change_title_from_Toolbar() { }); await promisePopup; - let properties = document.getElementById("placesContext_show:info"); + let properties = document.getElementById( + "placesContext_show_bookmark:info" + ); EventUtils.synthesizeMouseAtCenter(properties, {}); }, async function test(dialogWin) { diff --git a/browser/components/places/tests/browser/browser_bookmarks_toolbar_context_menu_view_options.js b/browser/components/places/tests/browser/browser_bookmarks_toolbar_context_menu_view_options.js index bd198a8c8ee5..cc09f6503220 100644 --- a/browser/components/places/tests/browser/browser_bookmarks_toolbar_context_menu_view_options.js +++ b/browser/components/places/tests/browser/browser_bookmarks_toolbar_context_menu_view_options.js @@ -37,7 +37,7 @@ add_task(async function testPopup() { ); ok(!bookmarksToolbar.collapsed, "Bookmarks toolbar should be visible"); - // 1. Right-click on a bookmark and check that the submenu is not visible + // 1. Right-click on a bookmark and check that the submenu is visible let bookmarkItem = bookmarksToolbar.querySelector( `.bookmark-item[label="firefox"]` ); @@ -45,8 +45,8 @@ add_task(async function testPopup() { let contextMenu = document.getElementById("placesContext"); let popup = await openContextMenu(contextMenu, bookmarkItem); ok( - popup.target.querySelector("#toggle_PersonalToolbar").hidden, - "Bookmarks toolbar submenu should not appear on a .bookmark-item" + !popup.target.querySelector("#toggle_PersonalToolbar").hidden, + "Bookmarks toolbar submenu should appear on a .bookmark-item" ); contextMenu.hidePopup(); diff --git a/browser/components/places/tests/browser/browser_panelview_bookmarks_delete.js b/browser/components/places/tests/browser/browser_panelview_bookmarks_delete.js index 2e8d3973a5a6..163ab9cf2caf 100644 --- a/browser/components/places/tests/browser/browser_panelview_bookmarks_delete.js +++ b/browser/components/places/tests/browser/browser_panelview_bookmarks_delete.js @@ -63,7 +63,9 @@ add_task(async function test_panelview_bookmarks_delete() { }); observer.observe(list, { childList: true }); }); - let placesContextDelete = document.getElementById("placesContext_delete"); + let placesContextDelete = document.getElementById( + "placesContext_deleteBookmark" + ); EventUtils.synthesizeMouseAtCenter(placesContextDelete, {}); await promise; diff --git a/browser/components/places/tests/browser/browser_remove_bookmarks.js b/browser/components/places/tests/browser/browser_remove_bookmarks.js index 71f559a3fd09..7d6ed4a17d5b 100644 --- a/browser/components/places/tests/browser/browser_remove_bookmarks.js +++ b/browser/components/places/tests/browser/browser_remove_bookmarks.js @@ -51,7 +51,9 @@ add_task(async function test_remove_bookmark_from_toolbar() { }); await popupShownPromise; - let contextMenuDeleteItem = document.getElementById("placesContext_delete"); + let contextMenuDeleteBookmark = document.getElementById( + "placesContext_deleteBookmark" + ); let removePromise = PlacesTestUtils.waitForNotification( "bookmark-removed", @@ -59,7 +61,7 @@ add_task(async function test_remove_bookmark_from_toolbar() { "places" ); - EventUtils.synthesizeMouseAtCenter(contextMenuDeleteItem, {}); + EventUtils.synthesizeMouseAtCenter(contextMenuDeleteBookmark, {}); await removePromise; @@ -106,8 +108,8 @@ add_task(async function test_remove_bookmark_from_library() { ); let contextMenu = library.document.getElementById("placesContext"); - let contextMenuDeleteItem = library.document.getElementById( - "placesContext_delete" + let contextMenuDeleteBookmark = library.document.getElementById( + "placesContext_deleteBookmark" ); let popupShownPromise = BrowserTestUtils.waitForEvent( @@ -143,7 +145,7 @@ add_task(async function test_remove_bookmark_from_library() { events => events.some(event => event.url == uris[0]), "places" ); - EventUtils.synthesizeMouseAtCenter(contextMenuDeleteItem, {}, library); + EventUtils.synthesizeMouseAtCenter(contextMenuDeleteBookmark, {}, library); await removePromise; diff --git a/browser/components/places/tests/browser/browser_toolbar_other_bookmarks.js b/browser/components/places/tests/browser/browser_toolbar_other_bookmarks.js index 0510897c32a3..3e63b9524524 100644 --- a/browser/components/places/tests/browser/browser_toolbar_other_bookmarks.js +++ b/browser/components/places/tests/browser/browser_toolbar_other_bookmarks.js @@ -218,8 +218,10 @@ add_task(async function testDeletingMenuItems() { await popupEventPromise; info("Delete bookmark menu item from popup."); - let deleteMenuItem = document.getElementById("placesContext_delete"); - EventUtils.synthesizeMouseAtCenter(deleteMenuItem, {}); + let deleteMenuBookmark = document.getElementById( + "placesContext_deleteBookmark" + ); + EventUtils.synthesizeMouseAtCenter(deleteMenuBookmark, {}); await TestUtils.waitForCondition(() => { let popup = document.querySelector("#OtherBookmarksPopup"); diff --git a/browser/locales/en-US/browser/places.ftl b/browser/locales/en-US/browser/places.ftl index 787994038043..34dd85831380 100644 --- a/browser/locales/en-US/browser/places.ftl +++ b/browser/locales/en-US/browser/places.ftl @@ -5,30 +5,33 @@ places-open = .label = Open .accesskey = O -places-open-tab = - .label = Open in a New Tab +places-open-in-tab = + .label = Open in New Tab .accesskey = w +places-open-all-bookmarks = + .label = Open All Bookmarks + .accesskey = O places-open-all-in-tabs = .label = Open All in Tabs .accesskey = O -places-open-window = - .label = Open in a New Window +places-open-in-window = + .label = Open in New Window .accesskey = N -places-open-private-window = - .label = Open in a New Private Window +places-open-in-private-window = + .label = Open in New Private Window .accesskey = P -places-new-bookmark = - .label = New Bookmark… +places-add-bookmark = + .label = Add Bookmark… .accesskey = B -places-new-folder-contextmenu = - .label = New Folder… +places-add-folder-contextmenu = + .label = Add Folder… .accesskey = F -places-new-folder = - .label = New Folder… +places-add-folder = + .label = Add Folder… .accesskey = o -places-new-separator = - .label = New Separator +places-add-separator = + .label = Add Separator .accesskey = S places-view = @@ -61,8 +64,12 @@ places-delete-domain-data = places-sortby-name = .label = Sort By Name .accesskey = r -places-properties = - .label = Properties +# places-edit-bookmark and places-edit-generic will show one or the other and can have the same access key. +places-edit-bookmark = + .label = Edit Bookmark… + .accesskey = i +places-edit-generic = + .label = Edit… .accesskey = i # Managed bookmarks are created by an administrator and cannot be changed by the user. @@ -75,3 +82,17 @@ managed-bookmarks-subfolder = # This label is used for the "Other Bookmarks" folder that appears in the bookmarks toolbar. other-bookmarks-folder = .label = Other Bookmarks + +# Variables: +# $count (number) - The number of elements being selected for removal. +places-remove-bookmark = + .label = + { $count -> + [1] Remove Bookmark + *[other] Remove Bookmarks + } + .accesskey = e + +places-manage-bookmarks = + .label = Manage Bookmarks + .accesskey = M