--- a/browser/base/content/browser-places.js
+++ b/browser/base/content/browser-places.js
@@ -4,30 +4,35 @@
////////////////////////////////////////////////////////////////////////////////
//// StarUI
var StarUI = {
_itemId: -1,
uri: null,
_batching: false,
+ _isNewBookmark: false,
+ _autoCloseTimer: 0,
_element: function(aID) {
return document.getElementById(aID);
},
// Edit-bookmark panel
get panel() {
delete this.panel;
var element = this._element("editBookmarkPanel");
// initially the panel is hidden
// to avoid impacting startup / new window performance
element.hidden = false;
+ element.addEventListener("keypress", this, false);
+ element.addEventListener("mouseout", this, false);
+ element.addEventListener("mouseover", this, false);
element.addEventListener("popuphidden", this, false);
- element.addEventListener("keypress", this, false);
+ element.addEventListener("popupshown", this, false);
return this.panel = element;
},
// Array of command elements to disable when the panel is opened.
get _blockedCommands() {
delete this._blockedCommands;
return this._blockedCommands =
["cmd_close", "cmd_closeWindow"].map(id => this._element(id));
@@ -53,87 +58,113 @@ var StarUI = {
elt.removeAttribute("disabled");
elt.removeAttribute("wasDisabled");
});
},
// nsIDOMEventListener
handleEvent(aEvent) {
switch (aEvent.type) {
+ case "mouseover":
+ clearTimeout(this._autoCloseTimer);
+ break;
case "popuphidden":
+ clearTimeout(this._autoCloseTimer);
if (aEvent.originalTarget == this.panel) {
if (!this._element("editBookmarkPanelContent").hidden)
this.quitEditMode();
if (this._anchorToolbarButton) {
this._anchorToolbarButton.removeAttribute("open");
this._anchorToolbarButton = null;
}
this._restoreCommandsState();
this._itemId = -1;
if (this._batching)
this.endBatch();
- switch (this._actionOnHide) {
- case "cancel": {
- if (!PlacesUIUtils.useAsyncTransactions) {
+ if (this._uriForRemoval) {
+ if (this._isNewBookmark) {
+ if (!PlacesUtils.useAsyncTransactions) {
PlacesUtils.transactionManager.undoTransaction();
break;
}
- PlacesTransactions.undo().catch(Cu.reportError);
+ PlacesTransactions().undo().catch(Cu.reportError);
break;
}
- case "remove": {
- // Remove all bookmarks for the bookmark's url, this also removes
- // the tags for the url.
- if (!PlacesUIUtils.useAsyncTransactions) {
- let itemIds = PlacesUtils.getBookmarksForURI(this._uriForRemoval);
- for (let itemId of itemIds) {
- let txn = new PlacesRemoveItemTransaction(itemId);
- PlacesUtils.transactionManager.doTransaction(txn);
- }
- break;
+ // Remove all bookmarks for the bookmark's url, this also removes
+ // the tags for the url.
+ if (!PlacesUIUtils.useAsyncTransactions) {
+ let itemIds = PlacesUtils.getBookmarksForURI(this._uriForRemoval);
+ for (let itemId of itemIds) {
+ let txn = new PlacesRemoveItemTransaction(itemId);
+ PlacesUtils.transactionManager.doTransaction(txn);
}
-
- PlacesTransactions.RemoveBookmarksForUrls(this._uriForRemoval)
- .transact().catch(Cu.reportError);
break;
}
+
+ PlacesTransactions.RemoveBookmarksForUrls([this._uriForRemoval])
+ .transact().catch(Cu.reportError);
}
- this._actionOnHide = "";
}
break;
case "keypress":
+ clearTimeout(this._autoCloseTimer);
+
if (aEvent.defaultPrevented) {
// The event has already been consumed inside of the panel.
break;
}
+
switch (aEvent.keyCode) {
case KeyEvent.DOM_VK_ESCAPE:
- if (!this._element("editBookmarkPanelContent").hidden)
- this.cancelButtonOnCommand();
+ this.panel.hidePopup();
break;
case KeyEvent.DOM_VK_RETURN:
if (aEvent.target.classList.contains("expander-up") ||
aEvent.target.classList.contains("expander-down") ||
aEvent.target.id == "editBMPanel_newFolderButton") {
//XXX Why is this necessary? The defaultPrevented check should
// be enough.
break;
}
this.panel.hidePopup();
break;
}
break;
+ case "mouseout": {
+ let ancestor = aEvent.target;
+ while (ancestor) {
+ if (ancestor == this.panel) {
+ break;
+ }
+ ancestor = ancestor.parentNode;
+ }
+ // Explicit fall-through
+ }
+ case "popupshown":
+ // auto-close if new and not interacted with
+ if (this._isNewBookmark) {
+ // 3500ms matches the timeout that Pocket uses in
+ // browser/extensions/pocket/content/panels/js/saved.js
+ let delay = 3500;
+ if (this._closePanelQuickForTesting) {
+ delay /= 10;
+ }
+ this._autoCloseTimer = setTimeout(() => this.panel.hidePopup(), delay, this);
+ }
+ break;
}
},
_overlayLoaded: false,
_overlayLoading: false,
- showEditBookmarkPopup: Task.async(function* (aNode, aAnchorElement, aPosition) {
+ showEditBookmarkPopup: Task.async(function* (aNode, aAnchorElement, aPosition, aIsNewBookmark) {
+ this._isNewBookmark = aIsNewBookmark;
+ this._uriForRemoval = "";
// TODO: Deprecate this once async transactions are enabled and the legacy
// transactions code is gone (bug 1131491) - we don't want addons to to use
// the completeNodeLikeObjectForItemId, so it's better if they keep passing
// the item-id for now).
if (typeof(aNode) == "number") {
let itemId = aNode;
if (PlacesUIUtils.useAsyncTransactions) {
let guid = yield PlacesUtils.promiseItemGuid(itemId);
@@ -172,36 +203,28 @@ var StarUI = {
}).bind(this)
);
}),
_doShowEditBookmarkPanel: Task.async(function* (aNode, aAnchorElement, aPosition) {
if (this.panel.state != "closed")
return;
- this._blockCommands(); // un-done in the popuphiding handler
+ this._blockCommands(); // un-done in the popuphidden handler
- // Set panel title:
- // if we are batching, i.e. the bookmark has been added now,
- // then show Page Bookmarked, else if the bookmark did already exist,
- // we are about editing it, then use Edit This Bookmark.
this._element("editBookmarkPanelTitle").value =
- this._batching ?
+ this._isNewBookmark ?
gNavigatorBundle.getString("editBookmarkPanel.pageBookmarkedTitle") :
gNavigatorBundle.getString("editBookmarkPanel.editBookmarkTitle");
- // No description; show the Done, Cancel;
+ // No description; show the Done, Remove;
this._element("editBookmarkPanelDescription").textContent = "";
this._element("editBookmarkPanelBottomButtons").hidden = false;
this._element("editBookmarkPanelContent").hidden = false;
- // The remove button is shown only if we're not already batching, i.e.
- // if the cancel button/ESC does not remove the bookmark.
- this._element("editBookmarkPanelRemoveButton").hidden = this._batching;
-
// The label of the remove button differs if the URI is bookmarked
// multiple times.
let bookmarks = PlacesUtils.getBookmarksForURI(gBrowser.currentURI);
let forms = gNavigatorBundle.getString("editBookmark.removeBookmarks.label");
let label = PluralForm.get(bookmarks.length, forms).replace("#1", bookmarks.length);
this._element("editBookmarkPanelRemoveButton").label = label;
// unset the unstarred state, if set
@@ -245,24 +268,18 @@ var StarUI = {
},
quitEditMode: function SU_quitEditMode() {
this._element("editBookmarkPanelContent").hidden = true;
this._element("editBookmarkPanelBottomButtons").hidden = true;
gEditItemOverlay.uninitPanel(true);
},
- cancelButtonOnCommand: function SU_cancelButtonOnCommand() {
- this._actionOnHide = "cancel";
- this.panel.hidePopup(true);
- },
-
removeBookmarkButtonCommand: function SU_removeBookmarkButtonCommand() {
this._uriForRemoval = PlacesUtils.bookmarks.getBookmarkURI(this._itemId);
- this._actionOnHide = "remove";
this.panel.hidePopup();
},
// Matching the way it is used in the Library, editBookmarkOverlay implements
// an instant-apply UI, having no batched-Undo/Redo support.
// However, in this context (the Star UI) we have a Cancel button whose
// expected behavior is to undo all the operations done in the panel.
// Sometime in the future this needs to be reimplemented using a
@@ -320,37 +337,38 @@ var PlacesCommandHook = {
bookmarkPage: Task.async(function* (aBrowser, aParent, aShowEditUI) {
if (PlacesUIUtils.useAsyncTransactions) {
yield this._bookmarkPagePT(aBrowser, aParent, aShowEditUI);
return;
}
var uri = aBrowser.currentURI;
var itemId = PlacesUtils.getMostRecentBookmarkForURI(uri);
- if (itemId == -1) {
+ let isNewBookmark = itemId == -1;
+ if (isNewBookmark) {
// Bug 1148838 - Make this code work for full page plugins.
var title;
var description;
var charset;
let docInfo = yield this._getPageDetails(aBrowser);
try {
title = docInfo.isErrorPage ? PlacesUtils.history.getPageTitle(uri)
: aBrowser.contentTitle;
title = title || uri.spec;
description = docInfo.description;
charset = aBrowser.characterSet;
}
catch (e) { }
- if (aShowEditUI) {
- // If we bookmark the page here (i.e. page was not "starred" already)
- // but open right into the "edit" state, start batching here, so
- // "Cancel" in that state removes the bookmark.
+ if (aShowEditUI && isNewBookmark) {
+ // If we bookmark the page here but open right into a cancelable
+ // state (i.e. new bookmark in Library), start batching here so
+ // all of the actions can be undone in a single undo step.
StarUI.beginBatch();
}
var parent = aParent !== undefined ?
aParent : PlacesUtils.unfiledBookmarksFolderId;
var descAnno = { name: PlacesUIUtils.DESCRIPTION_ANNO, value: description };
var txn = new PlacesCreateBookmarkTransaction(uri, parent,
PlacesUtils.bookmarks.DEFAULT_INDEX,
@@ -371,34 +389,35 @@ var PlacesCommandHook = {
return;
// Try to dock the panel to:
// 1. the bookmarks menu button
// 2. the identity icon
// 3. the content area
if (BookmarkingUI.anchor) {
StarUI.showEditBookmarkPopup(itemId, BookmarkingUI.anchor,
- "bottomcenter topright");
+ "bottomcenter topright", isNewBookmark);
return;
}
let identityIcon = document.getElementById("identity-icon");
if (isElementVisible(identityIcon)) {
StarUI.showEditBookmarkPopup(itemId, identityIcon,
- "bottomcenter topright");
+ "bottomcenter topright", isNewBookmark);
} else {
- StarUI.showEditBookmarkPopup(itemId, aBrowser, "overlap");
+ StarUI.showEditBookmarkPopup(itemId, aBrowser, "overlap", isNewBookmark);
}
}),
// TODO: Replace bookmarkPage code with this function once legacy
// transactions are removed.
_bookmarkPagePT: Task.async(function* (aBrowser, aParentId, aShowEditUI) {
let url = new URL(aBrowser.currentURI.spec);
let info = yield PlacesUtils.bookmarks.fetch({ url });
+ let isNewBookmark = !info;
if (!info) {
let parentGuid = aParentId !== undefined ?
yield PlacesUtils.promiseItemGuid(aParentId) :
PlacesUtils.bookmarks.unfiledGuid;
info = { url, parentGuid };
// Bug 1148838 - Make this code work for full page plugins.
let description = null;
let charset = null;
@@ -412,20 +431,20 @@ var PlacesCommandHook = {
info.title = info.title || url.href;
description = docInfo.description;
charset = aBrowser.characterSet;
}
catch (e) {
Components.utils.reportError(e);
}
- if (aShowEditUI) {
- // If we bookmark the page here (i.e. page was not "starred" already)
- // but open right into the "edit" state, start batching here, so
- // "Cancel" in that state removes the bookmark.
+ if (aShowEditUI && isNewBookmark) {
+ // If we bookmark the page here but open right into a cancelable
+ // state (i.e. new bookmark in Library), start batching here so
+ // all of the actions can be undone in a single undo step.
StarUI.beginBatch();
}
if (description) {
info.annotations = [{ name: PlacesUIUtils.DESCRIPTION_ANNO
, value: description }];
}
@@ -447,26 +466,26 @@ var PlacesCommandHook = {
let node = yield PlacesUIUtils.promiseNodeLikeFromFetchInfo(info);
// Try to dock the panel to:
// 1. the bookmarks menu button
// 2. the identity icon
// 3. the content area
if (BookmarkingUI.anchor) {
StarUI.showEditBookmarkPopup(node, BookmarkingUI.anchor,
- "bottomcenter topright");
+ "bottomcenter topright", isNewBookmark);
return;
}
let identityIcon = document.getElementById("identity-icon");
if (isElementVisible(identityIcon)) {
StarUI.showEditBookmarkPopup(node, identityIcon,
- "bottomcenter topright");
+ "bottomcenter topright", isNewBookmark);
} else {
- StarUI.showEditBookmarkPopup(node, aBrowser, "overlap");
+ StarUI.showEditBookmarkPopup(node, aBrowser, "overlap", isNewBookmark);
}
}),
_getPageDetails(browser) {
return new Promise(resolve => {
let mm = browser.messageManager;
mm.addMessageListener("Bookmarks:GetPageDetails:Result", function listener(msg) {
mm.removeMessageListener("Bookmarks:GetPageDetails:Result", listener);
@@ -1635,29 +1654,25 @@ var BookmarkingUI = {
if (this._currentAreaType == CustomizableUI.TYPE_MENU_PANEL) {
this._showSubview();
return;
}
let widget = CustomizableUI.getWidget(this.BOOKMARK_BUTTON_ID)
.forWindow(window);
if (widget.overflowed) {
- // Allow to close the panel if the page is already bookmarked, cause
- // we are going to open the edit bookmark panel.
- if (isBookmarked)
- widget.node.removeAttribute("closemenu");
- else
- widget.node.setAttribute("closemenu", "none");
+ // Close the overflow panel because the Edit Bookmark panel will appear.
+ widget.node.removeAttribute("closemenu");
}
// Ignore clicks on the star if we are updating its state.
if (!this._pendingStmt) {
if (!isBookmarked)
this._showBookmarkedNotification();
- PlacesCommandHook.bookmarkCurrentPage(isBookmarked);
+ PlacesCommandHook.bookmarkCurrentPage(true);
}
},
onCurrentPageContextPopupShowing() {
this._updateBookmarkPageMenuItem();
},
handleEvent: function BUI_handleEvent(aEvent) {
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -175,41 +175,35 @@
aria-labelledby="editBookmarkPanelTitle">
<row id="editBookmarkPanelHeader" align="center" hidden="true">
<vbox align="center">
<image id="editBookmarkPanelStarIcon"/>
</vbox>
<vbox>
<label id="editBookmarkPanelTitle"/>
<description id="editBookmarkPanelDescription"/>
- <hbox>
- <button id="editBookmarkPanelRemoveButton"
- class="editBookmarkPanelHeaderButton"
- oncommand="StarUI.removeBookmarkButtonCommand();"
- accesskey="&editBookmark.removeBookmark.accessKey;"/>
- </hbox>
</vbox>
</row>
<vbox id="editBookmarkPanelContent" flex="1" hidden="true"/>
<hbox id="editBookmarkPanelBottomButtons" pack="end">
#ifndef XP_UNIX
<button id="editBookmarkPanelDoneButton"
class="editBookmarkPanelBottomButton"
label="&editBookmark.done.label;"
default="true"
oncommand="StarUI.panel.hidePopup();"/>
- <button id="editBookmarkPanelDeleteButton"
+ <button id="editBookmarkPanelRemoveButton"
class="editBookmarkPanelBottomButton"
- label="&editBookmark.cancel.label;"
- oncommand="StarUI.cancelButtonOnCommand();"/>
+ oncommand="StarUI.removeBookmarkButtonCommand();"
+ accesskey="&editBookmark.removeBookmark.accessKey;"/>
#else
- <button id="editBookmarkPanelDeleteButton"
+ <button id="editBookmarkPanelRemoveButton"
class="editBookmarkPanelBottomButton"
- label="&editBookmark.cancel.label;"
- oncommand="StarUI.cancelButtonOnCommand();"/>
+ oncommand="StarUI.removeBookmarkButtonCommand();"
+ accesskey="&editBookmark.removeBookmark.accessKey;"/>
<button id="editBookmarkPanelDoneButton"
class="editBookmarkPanelBottomButton"
label="&editBookmark.done.label;"
default="true"
oncommand="StarUI.panel.hidePopup();"/>
#endif
</hbox>
</panel>
--- a/browser/base/content/test/general/browser.ini
+++ b/browser/base/content/test/general/browser.ini
@@ -146,16 +146,17 @@ skip-if = e10s # Bug 1101993 - times out
[browser_autocomplete_no_title.js]
[browser_autocomplete_autoselect.js]
[browser_autocomplete_oldschool_wrap.js]
[browser_autocomplete_tag_star_visibility.js]
[browser_backButtonFitts.js]
skip-if = os == "mac" # The Fitt's Law back button is not supported on OS X
[browser_beforeunload_duplicate_dialogs.js]
[browser_blob-channelname.js]
+[browser_bookmark_popup.js]
[browser_bookmark_titles.js]
skip-if = buildapp == 'mulet' || toolkit == "windows" # Disabled on Windows due to frequent failures (bugs 825739, 841341)
[browser_bug304198.js]
[browser_bug321000.js]
skip-if = true # browser_bug321000.js is disabled because newline handling is shaky (bug 592528)
[browser_bug329212.js]
skip-if = e10s # Bug 1236991 - Update or remove tests that use fillInPageTooltip
[browser_bug331772_xul_tooltiptext_in_html.js]
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/general/browser_bookmark_popup.js
@@ -0,0 +1,247 @@
+/* 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 opening and closing the bookmarks panel.
+ */
+
+let bookmarkPanel = document.getElementById("editBookmarkPanel");
+let bookmarkStar = document.getElementById("bookmarks-menu-button");
+let bookmarkPanelTitle = document.getElementById("editBookmarkPanelTitle");
+
+StarUI._closePanelQuickForTesting = true;
+Services.prefs.setBoolPref("browser.bookmarks.closePanelQuickForTesting", true);
+
+function* test_bookmarks_popup({isNewBookmark, popupShowFn, popupEditFn,
+ shouldAutoClose, popupHideFn, isBookmarkRemoved}) {
+ let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:home");
+ try {
+ if (!isNewBookmark) {
+ yield PlacesUtils.bookmarks.insert({
+ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
+ url: "about:home",
+ title: "Home Page"
+ });
+ }
+
+ is(bookmarkStar.hasAttribute("starred"), !isNewBookmark,
+ "Page should only be starred prior to popupshown if editing bookmark");
+ let shownPromise = promisePopupShown(bookmarkPanel);
+ yield popupShowFn(tab.linkedBrowser);
+ yield shownPromise;
+
+ if (popupEditFn) {
+ yield popupEditFn();
+ }
+ let bookmarks = [];
+ yield PlacesUtils.bookmarks.fetch({url: "about:home"}, bm => bookmarks.push(bm));
+ is(bookmarks.length, 1, "Only one bookmark should exist");
+ is(bookmarkStar.getAttribute("starred"), "true", "Page is starred");
+ is(bookmarkPanel.state, "open", "Check that panel state is 'open'");
+ is(bookmarkPanelTitle.value,
+ isNewBookmark ?
+ gNavigatorBundle.getString("editBookmarkPanel.pageBookmarkedTitle") :
+ gNavigatorBundle.getString("editBookmarkPanel.editBookmarkTitle"),
+ "title should match isEditingBookmark state");
+
+ if (!shouldAutoClose) {
+ yield new Promise(resolve => setTimeout(resolve, 400));
+ }
+
+ let hiddenPromise = promisePopupHidden(bookmarkPanel);
+ if (popupHideFn) {
+ yield popupHideFn();
+ }
+ yield hiddenPromise;
+ is(bookmarkStar.hasAttribute("starred"), !isBookmarkRemoved,
+ "Page is starred after closing");
+ } finally {
+ let bookmark = yield PlacesUtils.bookmarks.fetch({url: "about:home"});
+ is(!!bookmark, !isBookmarkRemoved,
+ "bookmark should not be present if a panel action should've removed it");
+ if (bookmark) {
+ yield PlacesUtils.bookmarks.remove(bookmark);
+ }
+ gBrowser.removeTab(tab);
+ }
+}
+
+add_task(function* panel_shown_for_new_bookmarks_and_autocloses() {
+ yield test_bookmarks_popup({
+ isNewBookmark: true,
+ popupShowFn() {
+ bookmarkStar.click();
+ },
+ shouldAutoClose: true,
+ isBookmarkRemoved: false,
+ });
+});
+
+add_task(function* panel_shown_for_once_for_doubleclick_on_new_bookmark_star_and_autocloses() {
+ yield test_bookmarks_popup({
+ isNewBookmark: true,
+ popupShowFn() {
+ EventUtils.synthesizeMouse(bookmarkStar, 10, 10, { clickCount: 2 },
+ window);
+ },
+ shouldAutoClose: true,
+ isBookmarkRemoved: false,
+ });
+});
+
+add_task(function* panel_shown_once_for_slow_doubleclick_on_new_bookmark_star_and_autocloses() {
+ yield test_bookmarks_popup({
+ isNewBookmark: true,
+ *popupShowFn() {
+ EventUtils.synthesizeMouse(bookmarkStar, 10, 10, window);
+ yield new Promise(resolve => setTimeout(resolve, 500));
+ EventUtils.synthesizeMouse(bookmarkStar, 10, 10, window);
+ },
+ shouldAutoClose: true,
+ isBookmarkRemoved: false,
+ });
+});
+
+add_task(function* panel_shown_for_keyboardshortcut_on_new_bookmark_star_and_autocloses() {
+ yield test_bookmarks_popup({
+ isNewBookmark: true,
+ popupShowFn() {
+ EventUtils.synthesizeKey("D", {accelKey: true}, window);
+ },
+ shouldAutoClose: true,
+ isBookmarkRemoved: false,
+ });
+});
+
+add_task(function* panel_shown_for_new_bookmarks_mouseover_mouseout() {
+ yield test_bookmarks_popup({
+ isNewBookmark: true,
+ popupShowFn() {
+ bookmarkStar.click();
+ },
+ *popupEditFn() {
+ let panelHeader = document.getElementById("editBookmarkPanelHeader");
+ yield new Promise(resolve => {
+ EventUtils.synthesizeNativeMouseMove(panelHeader, 0, 0, resolve, window);
+ });
+ yield new Promise(resolve => setTimeout(resolve, 400));
+ is(bookmarkPanel.state, "open", "Panel should still be open on mouseover");
+ yield new Promise(resolve => {
+ EventUtils.synthesizeNativeMouseMove(bookmarkStar, 0, 0, resolve, window);
+ });
+ info("Should autoclose now on mouseout");
+ },
+ shouldAutoClose: true,
+ isBookmarkRemoved: false,
+ });
+});
+
+add_task(function* panel_shown_for_new_bookmark_no_autoclose_close_with_ESC() {
+ yield test_bookmarks_popup({
+ isNewBookmark: false,
+ popupShowFn() {
+ bookmarkStar.click();
+ },
+ shouldAutoClose: false,
+ popupHideFn() {
+ EventUtils.synthesizeKey("VK_ESCAPE", {accelKey: true}, window);
+ },
+ isBookmarkRemoved: false,
+ });
+});
+
+add_task(function* panel_shown_for_editing_no_autoclose_close_with_ESC() {
+ yield test_bookmarks_popup({
+ isNewBookmark: false,
+ popupShowFn() {
+ bookmarkStar.click();
+ },
+ shouldAutoClose: false,
+ popupHideFn() {
+ EventUtils.synthesizeKey("VK_ESCAPE", {accelKey: true}, window);
+ },
+ isBookmarkRemoved: false,
+ });
+});
+
+add_task(function* panel_shown_for_new_bookmark_keypress_no_autoclose() {
+ yield test_bookmarks_popup({
+ isNewBookmark: true,
+ popupShowFn() {
+ bookmarkStar.click();
+ },
+ popupEditFn() {
+ EventUtils.sendChar("VK_TAB", window);
+ },
+ shouldAutoClose: false,
+ popupHideFn() {
+ bookmarkPanel.hidePopup();
+ },
+ isBookmarkRemoved: false,
+ });
+});
+
+add_task(function* contextmenu_new_bookmark_click_no_autoclose() {
+ yield test_bookmarks_popup({
+ isNewBookmark: true,
+ *popupShowFn(browser) {
+ let contextMenu = document.getElementById("contentAreaContextMenu");
+ let awaitPopupShown = BrowserTestUtils.waitForEvent(contextMenu,
+ "popupshown");
+ let awaitPopupHidden = BrowserTestUtils.waitForEvent(contextMenu,
+ "popuphidden");
+ yield BrowserTestUtils.synthesizeMouseAtCenter("body", {
+ type: "contextmenu",
+ button: 2
+ }, browser);
+ yield awaitPopupShown;
+ document.getElementById("context-bookmarkpage").click();
+ contextMenu.hidePopup();
+ yield awaitPopupHidden;
+ },
+ popupEditFn() {
+ bookmarkPanelTitle.click();
+ },
+ shouldAutoClose: false,
+ popupHideFn() {
+ bookmarkPanel.hidePopup();
+ },
+ isBookmarkRemoved: false,
+ });
+});
+
+add_task(function* bookmarks_menu_new_bookmark_remove_bookmark() {
+ yield test_bookmarks_popup({
+ isNewBookmark: true,
+ popupShowFn(browser) {
+ document.getElementById("menu_bookmarkThisPage").doCommand();
+ },
+ shouldAutoClose: true,
+ popupHideFn() {
+ document.getElementById("editBookmarkPanelRemoveButton").click();
+ },
+ isBookmarkRemoved: true,
+ });
+});
+
+add_task(function* ctrl_d_edit_bookmark_remove_bookmark() {
+ yield test_bookmarks_popup({
+ isNewBookmark: false,
+ popupShowFn(browser) {
+ EventUtils.synthesizeKey("D", {accelKey: true}, window);
+ },
+ shouldAutoClose: true,
+ popupHideFn() {
+ document.getElementById("editBookmarkPanelRemoveButton").click();
+ },
+ isBookmarkRemoved: true,
+ });
+});
+
+registerCleanupFunction(function() {
+ Services.prefs.clearUserPref("browser.bookmarks.closePanelQuickForTesting");
+ delete StarUI._closePanelQuickForTesting;
+})
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -736,17 +736,16 @@ you can use these alternative items. Oth
<!ENTITY findAgainCmd.commandkey "g">
<!ENTITY findAgainCmd.commandkey2 "VK_F3">
<!ENTITY findSelectionCmd.commandkey "e">
<!ENTITY spellAddDictionaries.label "Add Dictionaries…">
<!ENTITY spellAddDictionaries.accesskey "A">
<!ENTITY editBookmark.done.label "Done">
-<!ENTITY editBookmark.cancel.label "Cancel">
<!ENTITY editBookmark.removeBookmark.accessKey "R">
<!ENTITY identity.connectionSecure "Secure Connection">
<!ENTITY identity.connectionNotSecure "Connection is Not Secure">
<!ENTITY identity.connectionFile "This page is stored on your computer.">
<!ENTITY identity.connectionVerified1 "You are securely connected to this site, run by:">
<!ENTITY identity.connectionInternal "This is a secure &brandShortName; page.">
<!ENTITY identity.insecureLoginForms2 "Logins entered on this page could be compromised.">