зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1489430 - Add "Remove Extension" context menu item for pageAction. r=robwu,mstriemer,fluent-reviewers,Gijs
Differential Revision: https://phabricator.services.mozilla.com/D69831 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
a91be586fd
Коммит
b90b5b3778
|
@ -1006,3 +1006,86 @@ var gExtensionsNotifications = {
|
|||
}
|
||||
},
|
||||
};
|
||||
|
||||
var BrowserAddonUI = {
|
||||
promptRemoveExtension(addon) {
|
||||
let { name } = addon;
|
||||
let brand = document
|
||||
.getElementById("bundle_brand")
|
||||
.getString("brandShorterName");
|
||||
let { getFormattedString, getString } = gNavigatorBundle;
|
||||
let title = getFormattedString("webext.remove.confirmation.title", [name]);
|
||||
let message = getFormattedString("webext.remove.confirmation.message", [
|
||||
name,
|
||||
brand,
|
||||
]);
|
||||
let btnTitle = getString("webext.remove.confirmation.button");
|
||||
let {
|
||||
BUTTON_TITLE_IS_STRING: titleString,
|
||||
BUTTON_TITLE_CANCEL: titleCancel,
|
||||
BUTTON_POS_0,
|
||||
BUTTON_POS_1,
|
||||
confirmEx,
|
||||
} = Services.prompt;
|
||||
let btnFlags = BUTTON_POS_0 * titleString + BUTTON_POS_1 * titleCancel;
|
||||
let checkboxState = { value: false };
|
||||
let checkboxMessage = null;
|
||||
|
||||
// Enable abuse report checkbox in the remove extension dialog,
|
||||
// if enabled by the about:config prefs and the addon type
|
||||
// is currently supported.
|
||||
if (
|
||||
gAddonAbuseReportEnabled &&
|
||||
["extension", "theme"].includes(addon.type)
|
||||
) {
|
||||
checkboxMessage = getFormattedString(
|
||||
"webext.remove.abuseReportCheckbox.message",
|
||||
[document.getElementById("bundle_brand").getString("vendorShortName")]
|
||||
);
|
||||
}
|
||||
const result = confirmEx(
|
||||
null,
|
||||
title,
|
||||
message,
|
||||
btnFlags,
|
||||
btnTitle,
|
||||
null,
|
||||
null,
|
||||
checkboxMessage,
|
||||
checkboxState
|
||||
);
|
||||
return { remove: result === 0, report: checkboxState.value };
|
||||
},
|
||||
|
||||
async reportAddon(addonId, reportEntryPoint) {
|
||||
const win = await BrowserOpenAddonsMgr("addons://list/extension");
|
||||
|
||||
win.openAbuseReport({ addonId, reportEntryPoint });
|
||||
},
|
||||
|
||||
async removeAddon(addonId, eventObject) {
|
||||
let addon = addonId && (await AddonManager.getAddonByID(addonId));
|
||||
if (!addon || !(addon.permissions & AddonManager.PERM_CAN_UNINSTALL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let { remove, report } = this.promptRemoveExtension(addon);
|
||||
|
||||
AMTelemetry.recordActionEvent({
|
||||
object: eventObject,
|
||||
action: "uninstall",
|
||||
value: remove ? "accepted" : "cancelled",
|
||||
extra: { addonId },
|
||||
});
|
||||
|
||||
if (remove) {
|
||||
// Leave the extension in pending uninstall if we are also reporting the
|
||||
// add-on.
|
||||
await addon.uninstall(report);
|
||||
|
||||
if (report) {
|
||||
await this.reportAddon(addon.id, "uninstall");
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -911,7 +911,7 @@ var BrowserPageActions = {
|
|||
* @param popup (DOM node, required)
|
||||
* The context menu popup DOM node.
|
||||
*/
|
||||
onContextMenuShowing(event, popup) {
|
||||
async onContextMenuShowing(event, popup) {
|
||||
if (event.target != popup) {
|
||||
return;
|
||||
}
|
||||
|
@ -933,6 +933,16 @@ var BrowserPageActions = {
|
|||
: "extensionUnpinned";
|
||||
}
|
||||
popup.setAttribute("state", state);
|
||||
|
||||
let removeExtension = popup.querySelector(".removeExtensionItem");
|
||||
let { extensionID } = this._contextAction;
|
||||
let addon = extensionID && (await AddonManager.getAddonByID(extensionID));
|
||||
removeExtension.hidden = !addon;
|
||||
if (addon) {
|
||||
removeExtension.disabled = !(
|
||||
addon.permissions & AddonManager.PERM_CAN_UNINSTALL
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -968,6 +978,19 @@ var BrowserPageActions = {
|
|||
window.BrowserOpenAddonsMgr(viewID);
|
||||
},
|
||||
|
||||
/**
|
||||
* Call this from the menu item in the context menu that removes an add-on.
|
||||
*/
|
||||
removeExtensionForContextAction() {
|
||||
if (!this._contextAction) {
|
||||
return;
|
||||
}
|
||||
let action = this._contextAction;
|
||||
this._contextAction = null;
|
||||
|
||||
BrowserAddonUI.removeAddon(action.extensionID, "pageAction");
|
||||
},
|
||||
|
||||
_contextAction: null,
|
||||
|
||||
/**
|
||||
|
|
|
@ -142,7 +142,7 @@ XPCOMUtils.defineLazyScriptGetter(
|
|||
);
|
||||
XPCOMUtils.defineLazyScriptGetter(
|
||||
this,
|
||||
["gExtensionsNotifications", "gXPInstallObserver"],
|
||||
["BrowserAddonUI", "gExtensionsNotifications", "gXPInstallObserver"],
|
||||
"chrome://browser/content/browser-addons.js"
|
||||
);
|
||||
XPCOMUtils.defineLazyScriptGetter(
|
||||
|
@ -7106,52 +7106,6 @@ function UpdateCurrentCharset(target) {
|
|||
}
|
||||
}
|
||||
|
||||
function promptRemoveExtension(addon) {
|
||||
let { name } = addon;
|
||||
let brand = document
|
||||
.getElementById("bundle_brand")
|
||||
.getString("brandShorterName");
|
||||
let { getFormattedString, getString } = gNavigatorBundle;
|
||||
let title = getFormattedString("webext.remove.confirmation.title", [name]);
|
||||
let message = getFormattedString("webext.remove.confirmation.message", [
|
||||
name,
|
||||
brand,
|
||||
]);
|
||||
let btnTitle = getString("webext.remove.confirmation.button");
|
||||
let {
|
||||
BUTTON_TITLE_IS_STRING: titleString,
|
||||
BUTTON_TITLE_CANCEL: titleCancel,
|
||||
BUTTON_POS_0,
|
||||
BUTTON_POS_1,
|
||||
confirmEx,
|
||||
} = Services.prompt;
|
||||
let btnFlags = BUTTON_POS_0 * titleString + BUTTON_POS_1 * titleCancel;
|
||||
let checkboxState = { value: false };
|
||||
let checkboxMessage = null;
|
||||
|
||||
// Enable abuse report checkbox in the remove extension dialog,
|
||||
// if enabled by the about:config prefs and the addon type
|
||||
// is currently supported.
|
||||
if (gAddonAbuseReportEnabled && ["extension", "theme"].includes(addon.type)) {
|
||||
checkboxMessage = getFormattedString(
|
||||
"webext.remove.abuseReportCheckbox.message",
|
||||
[document.getElementById("bundle_brand").getString("vendorShortName")]
|
||||
);
|
||||
}
|
||||
const result = confirmEx(
|
||||
null,
|
||||
title,
|
||||
message,
|
||||
btnFlags,
|
||||
btnTitle,
|
||||
null,
|
||||
null,
|
||||
checkboxMessage,
|
||||
checkboxState
|
||||
);
|
||||
return { remove: result === 0, report: checkboxState.value };
|
||||
}
|
||||
|
||||
var ToolbarContextMenu = {
|
||||
updateDownloadsAutoHide(popup) {
|
||||
let checkbox = document.getElementById(
|
||||
|
@ -7218,25 +7172,8 @@ var ToolbarContextMenu = {
|
|||
|
||||
async removeExtensionForContextAction(popup) {
|
||||
let id = this._getExtensionId(popup);
|
||||
let addon = id && (await AddonManager.getAddonByID(id));
|
||||
if (!addon || !(addon.permissions & AddonManager.PERM_CAN_UNINSTALL)) {
|
||||
return;
|
||||
}
|
||||
let { remove, report } = promptRemoveExtension(addon);
|
||||
AMTelemetry.recordActionEvent({
|
||||
object: "browserAction",
|
||||
action: "uninstall",
|
||||
value: remove ? "accepted" : "cancelled",
|
||||
extra: { addonId: addon.id },
|
||||
});
|
||||
if (remove) {
|
||||
// Leave the extension in pending uninstall if we are also
|
||||
// reporting the add-on.
|
||||
await addon.uninstall(report);
|
||||
if (report) {
|
||||
this.reportExtensionForContextAction(popup, "uninstall");
|
||||
}
|
||||
}
|
||||
|
||||
await BrowserAddonUI.removeAddon(id, "browserAction");
|
||||
},
|
||||
|
||||
async reportExtensionForContextAction(popup, reportEntryPoint) {
|
||||
|
@ -7245,11 +7182,8 @@ var ToolbarContextMenu = {
|
|||
if (!addon) {
|
||||
return;
|
||||
}
|
||||
const win = await BrowserOpenAddonsMgr("addons://list/extension");
|
||||
win.openAbuseReport({
|
||||
addonId: addon.id,
|
||||
reportEntryPoint,
|
||||
});
|
||||
|
||||
await BrowserAddonUI.reportAddon(addon.id, reportEntryPoint);
|
||||
},
|
||||
|
||||
openAboutAddonsForContextAction(popup) {
|
||||
|
|
|
@ -591,6 +591,9 @@
|
|||
<menuitem class="pageActionContextMenuItem extensionPinned extensionUnpinned"
|
||||
oncommand="BrowserPageActions.openAboutAddonsForContextAction();"
|
||||
data-l10n-id="page-action-manage-extension"/>
|
||||
<menuitem class="pageActionContextMenuItem extensionPinned extensionUnpinned removeExtensionItem"
|
||||
oncommand="BrowserPageActions.removeExtensionForContextAction();"
|
||||
data-l10n-id="page-action-remove-extension"/>
|
||||
</menupopup>
|
||||
|
||||
#include ../../components/places/content/bookmarksHistoryTooltip.inc.xhtml
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
support-files =
|
||||
head.js
|
||||
|
||||
[browser_PageActions_removeExtension.js]
|
||||
[browser_page_action_menu_add_search_engine.js]
|
||||
support-files =
|
||||
page_action_menu_add_search_engine_one.html
|
||||
|
|
|
@ -0,0 +1,322 @@
|
|||
"use strict";
|
||||
|
||||
const { EnterprisePolicyTesting } = ChromeUtils.import(
|
||||
"resource://testing-common/EnterprisePolicyTesting.jsm"
|
||||
);
|
||||
|
||||
const { ExtensionCommon } = ChromeUtils.import(
|
||||
"resource://gre/modules/ExtensionCommon.jsm"
|
||||
);
|
||||
|
||||
const { TelemetryTestUtils } = ChromeUtils.import(
|
||||
"resource://testing-common/TelemetryTestUtils.jsm"
|
||||
);
|
||||
|
||||
const TELEMETRY_EVENTS_FILTERS = {
|
||||
category: "addonsManager",
|
||||
method: "action",
|
||||
};
|
||||
|
||||
// Initialization. Must run first.
|
||||
add_task(async function init() {
|
||||
// The page action urlbar button, and therefore the panel, is only shown when
|
||||
// the current tab is actionable -- i.e., a normal web page. about:blank is
|
||||
// not, so open a new tab first thing, and close it when this test is done.
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab({
|
||||
gBrowser,
|
||||
url: "http://example.com/",
|
||||
});
|
||||
|
||||
registerCleanupFunction(async () => {
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
});
|
||||
|
||||
add_task(async function contextMenu_removeExtension_panel() {
|
||||
Services.telemetry.clearEvents();
|
||||
|
||||
// We use an extension that shows a page action so that we can test the
|
||||
// "remove extension" item in the context menu.
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
name: "Test contextMenu",
|
||||
page_action: { show_matches: ["<all_urls>"] },
|
||||
},
|
||||
|
||||
useAddonManager: "temporary",
|
||||
});
|
||||
|
||||
await extension.startup();
|
||||
|
||||
let actionId = ExtensionCommon.makeWidgetId(extension.id);
|
||||
|
||||
// Open the panel and then open the context menu on the action's item.
|
||||
await promisePageActionPanelOpen();
|
||||
let panelButton = BrowserPageActions.panelButtonNodeForActionID(actionId);
|
||||
let contextMenuPromise = promisePanelShown("pageActionContextMenu");
|
||||
EventUtils.synthesizeMouseAtCenter(panelButton, {
|
||||
type: "contextmenu",
|
||||
button: 2,
|
||||
});
|
||||
await contextMenuPromise;
|
||||
|
||||
let removeExtensionItem = getRemoveExtensionItem();
|
||||
Assert.ok(removeExtensionItem, "'Remove' item exists");
|
||||
Assert.ok(!removeExtensionItem.hidden, "'Remove' item is visible");
|
||||
Assert.ok(!removeExtensionItem.disabled, "'Remove' item is not disabled");
|
||||
|
||||
// Click the "remove extension" item, a prompt should be displayed and then
|
||||
// the add-on should be uninstalled. We mock the prompt service to confirm
|
||||
// the removal of the add-on.
|
||||
contextMenuPromise = promisePanelHidden("pageActionContextMenu");
|
||||
let addonUninstalledPromise = promiseAddonUninstalled(extension.id);
|
||||
mockPromptService();
|
||||
EventUtils.synthesizeMouseAtCenter(removeExtensionItem, {});
|
||||
await Promise.all([contextMenuPromise, addonUninstalledPromise]);
|
||||
|
||||
// Done, clean up.
|
||||
await extension.unload();
|
||||
|
||||
TelemetryTestUtils.assertEvents(
|
||||
[
|
||||
{
|
||||
object: "pageAction",
|
||||
value: "accepted",
|
||||
extra: { addonId: extension.id, action: "uninstall" },
|
||||
},
|
||||
],
|
||||
TELEMETRY_EVENTS_FILTERS
|
||||
);
|
||||
|
||||
// urlbar tests that run after this one can break if the mouse is left over
|
||||
// the area where the urlbar popup appears, which seems to happen due to the
|
||||
// above synthesized mouse events. Move it over the urlbar.
|
||||
EventUtils.synthesizeMouseAtCenter(gURLBar.inputField, { type: "mousemove" });
|
||||
gURLBar.focus();
|
||||
});
|
||||
|
||||
add_task(async function contextMenu_removeExtension_urlbar() {
|
||||
Services.telemetry.clearEvents();
|
||||
|
||||
// We use an extension that shows a page action so that we can test the
|
||||
// "remove extension" item in the context menu.
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
name: "Test contextMenu",
|
||||
page_action: { show_matches: ["<all_urls>"] },
|
||||
},
|
||||
|
||||
useAddonManager: "temporary",
|
||||
});
|
||||
|
||||
await extension.startup();
|
||||
// The pageAction implementation enables the button at the next animation
|
||||
// frame, so before we look for the button we should wait one animation frame
|
||||
// as well.
|
||||
await promiseAnimationFrame();
|
||||
|
||||
let actionId = ExtensionCommon.makeWidgetId(extension.id);
|
||||
|
||||
// Open the context menu on the action's urlbar button.
|
||||
let urlbarButton = BrowserPageActions.urlbarButtonNodeForActionID(actionId);
|
||||
let contextMenuPromise = promisePanelShown("pageActionContextMenu");
|
||||
EventUtils.synthesizeMouseAtCenter(urlbarButton, {
|
||||
type: "contextmenu",
|
||||
button: 2,
|
||||
});
|
||||
await contextMenuPromise;
|
||||
|
||||
let removeExtensionItem = getRemoveExtensionItem();
|
||||
Assert.ok(removeExtensionItem, "'Remove' item exists");
|
||||
Assert.ok(!removeExtensionItem.hidden, "'Remove' item is visible");
|
||||
Assert.ok(!removeExtensionItem.disabled, "'Remove' item is not disabled");
|
||||
|
||||
// Click the "remove extension" item, a prompt should be displayed and then
|
||||
// the add-on should be uninstalled. We mock the prompt service to cancel the
|
||||
// removal of the add-on.
|
||||
contextMenuPromise = promisePanelHidden("pageActionContextMenu");
|
||||
let promptService = mockPromptService();
|
||||
let promptCancelledPromise = new Promise(resolve => {
|
||||
promptService.confirmEx = () => resolve();
|
||||
});
|
||||
EventUtils.synthesizeMouseAtCenter(removeExtensionItem, {});
|
||||
await Promise.all([contextMenuPromise, promptCancelledPromise]);
|
||||
|
||||
// Done, clean up.
|
||||
await extension.unload();
|
||||
|
||||
TelemetryTestUtils.assertEvents(
|
||||
[
|
||||
{
|
||||
object: "pageAction",
|
||||
value: "cancelled",
|
||||
extra: { addonId: extension.id, action: "uninstall" },
|
||||
},
|
||||
],
|
||||
TELEMETRY_EVENTS_FILTERS
|
||||
);
|
||||
|
||||
// urlbar tests that run after this one can break if the mouse is left over
|
||||
// the area where the urlbar popup appears, which seems to happen due to the
|
||||
// above synthesized mouse events. Move it over the urlbar.
|
||||
EventUtils.synthesizeMouseAtCenter(gURLBar.inputField, { type: "mousemove" });
|
||||
gURLBar.focus();
|
||||
});
|
||||
|
||||
add_task(async function contextMenu_removeExtension_disabled_in_panel() {
|
||||
// We use an extension that shows a page action so that we can test the
|
||||
// "remove extension" item in the context menu.
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
name: "Test contextMenu",
|
||||
page_action: { show_matches: ["<all_urls>"] },
|
||||
},
|
||||
|
||||
useAddonManager: "temporary",
|
||||
});
|
||||
|
||||
await extension.startup();
|
||||
// Add a policy to prevent the add-on from being uninstalled.
|
||||
await EnterprisePolicyTesting.setupPolicyEngineWithJson({
|
||||
policies: {
|
||||
Extensions: {
|
||||
Locked: [extension.id],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
let actionId = ExtensionCommon.makeWidgetId(extension.id);
|
||||
|
||||
// Open the panel and then open the context menu on the action's item.
|
||||
await promisePageActionPanelOpen();
|
||||
let panelButton = BrowserPageActions.panelButtonNodeForActionID(actionId);
|
||||
let contextMenuPromise = promisePanelShown("pageActionContextMenu");
|
||||
EventUtils.synthesizeMouseAtCenter(panelButton, {
|
||||
type: "contextmenu",
|
||||
button: 2,
|
||||
});
|
||||
await contextMenuPromise;
|
||||
|
||||
let removeExtensionItem = getRemoveExtensionItem();
|
||||
Assert.ok(removeExtensionItem, "'Remove' item exists");
|
||||
Assert.ok(!removeExtensionItem.hidden, "'Remove' item is visible");
|
||||
Assert.ok(removeExtensionItem.disabled, "'Remove' item is disabled");
|
||||
|
||||
// Press escape to hide the context menu.
|
||||
contextMenuPromise = promisePanelHidden("pageActionContextMenu");
|
||||
EventUtils.synthesizeKey("KEY_Escape");
|
||||
await contextMenuPromise;
|
||||
|
||||
// Done, clean up.
|
||||
await extension.unload();
|
||||
await EnterprisePolicyTesting.setupPolicyEngineWithJson("");
|
||||
|
||||
// urlbar tests that run after this one can break if the mouse is left over
|
||||
// the area where the urlbar popup appears, which seems to happen due to the
|
||||
// above synthesized mouse events. Move it over the urlbar.
|
||||
EventUtils.synthesizeMouseAtCenter(gURLBar.inputField, { type: "mousemove" });
|
||||
gURLBar.focus();
|
||||
});
|
||||
|
||||
add_task(async function contextMenu_removeExtension_disabled_in_urlbar() {
|
||||
// We use an extension that shows a page action so that we can test the
|
||||
// "remove extension" item in the context menu.
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
name: "Test contextMenu",
|
||||
page_action: { show_matches: ["<all_urls>"] },
|
||||
},
|
||||
|
||||
useAddonManager: "temporary",
|
||||
});
|
||||
|
||||
await extension.startup();
|
||||
// The pageAction implementation enables the button at the next animation
|
||||
// frame, so before we look for the button we should wait one animation frame
|
||||
// as well.
|
||||
await promiseAnimationFrame();
|
||||
// Add a policy to prevent the add-on from being uninstalled.
|
||||
await EnterprisePolicyTesting.setupPolicyEngineWithJson({
|
||||
policies: {
|
||||
Extensions: {
|
||||
Locked: [extension.id],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
let actionId = ExtensionCommon.makeWidgetId(extension.id);
|
||||
|
||||
// Open the context menu on the action's urlbar button.
|
||||
let urlbarButton = BrowserPageActions.urlbarButtonNodeForActionID(actionId);
|
||||
let contextMenuPromise = promisePanelShown("pageActionContextMenu");
|
||||
EventUtils.synthesizeMouseAtCenter(urlbarButton, {
|
||||
type: "contextmenu",
|
||||
button: 2,
|
||||
});
|
||||
await contextMenuPromise;
|
||||
|
||||
let removeExtensionItem = getRemoveExtensionItem();
|
||||
Assert.ok(removeExtensionItem, "'Remove' item exists");
|
||||
Assert.ok(!removeExtensionItem.hidden, "'Remove' item is visible");
|
||||
Assert.ok(removeExtensionItem.disabled, "'Remove' item is disabled");
|
||||
|
||||
// Press escape to hide the context menu.
|
||||
contextMenuPromise = promisePanelHidden("pageActionContextMenu");
|
||||
EventUtils.synthesizeKey("KEY_Escape");
|
||||
await contextMenuPromise;
|
||||
|
||||
// Done, clean up.
|
||||
await extension.unload();
|
||||
await EnterprisePolicyTesting.setupPolicyEngineWithJson("");
|
||||
|
||||
// urlbar tests that run after this one can break if the mouse is left over
|
||||
// the area where the urlbar popup appears, which seems to happen due to the
|
||||
// above synthesized mouse events. Move it over the urlbar.
|
||||
EventUtils.synthesizeMouseAtCenter(gURLBar.inputField, { type: "mousemove" });
|
||||
gURLBar.focus();
|
||||
});
|
||||
|
||||
function promiseAddonUninstalled(addonId) {
|
||||
return new Promise(resolve => {
|
||||
let listener = {};
|
||||
listener.onUninstalled = addon => {
|
||||
if (addon.id == addonId) {
|
||||
AddonManager.removeAddonListener(listener);
|
||||
resolve();
|
||||
}
|
||||
};
|
||||
AddonManager.addAddonListener(listener);
|
||||
});
|
||||
}
|
||||
|
||||
function mockPromptService() {
|
||||
let { prompt } = Services;
|
||||
|
||||
let promptService = {
|
||||
// The prompt returns 1 for cancelled and 0 for accepted.
|
||||
_response: 0,
|
||||
QueryInterface: ChromeUtils.generateQI([Ci.nsIPromptService]),
|
||||
confirmEx: () => promptService._response,
|
||||
};
|
||||
|
||||
Services.prompt = promptService;
|
||||
|
||||
registerCleanupFunction(() => {
|
||||
Services.prompt = prompt;
|
||||
});
|
||||
|
||||
return promptService;
|
||||
}
|
||||
|
||||
function getRemoveExtensionItem() {
|
||||
return document.querySelector(
|
||||
"#pageActionContextMenu > menuitem[label='Remove Extension']"
|
||||
);
|
||||
}
|
||||
|
||||
async function promiseAnimationFrame(win = window) {
|
||||
await new Promise(resolve => win.requestAnimationFrame(resolve));
|
||||
|
||||
let { tm } = Services;
|
||||
return new Promise(resolve => tm.dispatchToMainThread(resolve));
|
||||
}
|
|
@ -208,12 +208,13 @@ add_task(async function test_hiddenPageActionContextMenu() {
|
|||
return window.getComputedStyle(node).visibility == "visible";
|
||||
});
|
||||
|
||||
is(menuItems.length, 3, "Correct number of children");
|
||||
const [dontShowItem, separator, manageItem] = menuItems;
|
||||
is(menuItems.length, 4, "Correct number of children");
|
||||
const [dontShowItem, separator, manageItem, removeItem] = menuItems;
|
||||
|
||||
is(dontShowItem.label, "Remove from Address Bar", "Correct first child");
|
||||
is(separator.tagName, "menuseparator", "Correct second child");
|
||||
is(manageItem.label, "Manage Extension\u2026", "Correct third child");
|
||||
is(removeItem.label, "Remove Extension", "Correct fourth child");
|
||||
|
||||
await closeChromeContextMenu(menu.id);
|
||||
await closeChromeContextMenu(BrowserPageActions.panelNode.id);
|
||||
|
|
|
@ -111,6 +111,8 @@ page-action-manage-extension =
|
|||
.label = Manage Extension…
|
||||
page-action-remove-from-urlbar =
|
||||
.label = Remove from Address Bar
|
||||
page-action-remove-extension =
|
||||
.label = Remove Extension
|
||||
|
||||
## Auto-hide Context Menu
|
||||
|
||||
|
|
|
@ -1533,10 +1533,11 @@ add_task(async function contextMenu() {
|
|||
});
|
||||
await contextMenuPromise;
|
||||
|
||||
// The context menu should show the "remove" item and the "manage" item.
|
||||
// Click the "remove" item.
|
||||
// The context menu should show the "remove" item and the "manage" item. The
|
||||
// 4th item is "remove extension" but it is hidden in this test case because
|
||||
// the page action isn't bound to an addon. Click the "remove" item.
|
||||
let menuItems = collectContextMenuItems();
|
||||
Assert.equal(menuItems.length, 3, "Context menu has 3 children");
|
||||
Assert.equal(menuItems.length, 4, "Context menu has 4 children");
|
||||
Assert.equal(
|
||||
menuItems[0].label,
|
||||
"Remove from Address Bar",
|
||||
|
@ -1552,6 +1553,13 @@ add_task(async function contextMenu() {
|
|||
"Manage Extension\u2026",
|
||||
"'Manage' item is present"
|
||||
);
|
||||
Assert.equal(
|
||||
menuItems[3].label,
|
||||
"Remove Extension",
|
||||
"'Remove' item is present"
|
||||
);
|
||||
Assert.ok(menuItems[3].hidden, "'Remove' item is hidden");
|
||||
|
||||
contextMenuPromise = promisePanelHidden("pageActionContextMenu");
|
||||
EventUtils.synthesizeMouseAtCenter(menuItems[0], {});
|
||||
await contextMenuPromise;
|
||||
|
@ -1570,10 +1578,10 @@ add_task(async function contextMenu() {
|
|||
});
|
||||
await contextMenuPromise;
|
||||
|
||||
// The context menu should show the "add" item and the "manage" item. Click
|
||||
// the "add" item.
|
||||
// The context menu should show the "add" item and the "manage" item. The 4th
|
||||
// item is "remove extension" but it is hidden. Click the "add" item.
|
||||
menuItems = collectContextMenuItems();
|
||||
Assert.equal(menuItems.length, 3, "Context menu has 3 children");
|
||||
Assert.equal(menuItems.length, 4, "Context menu has 4 children");
|
||||
Assert.equal(
|
||||
menuItems[0].label,
|
||||
"Add to Address Bar",
|
||||
|
@ -1589,6 +1597,13 @@ add_task(async function contextMenu() {
|
|||
"Manage Extension\u2026",
|
||||
"'Manage' item is present"
|
||||
);
|
||||
Assert.equal(
|
||||
menuItems[3].label,
|
||||
"Remove Extension",
|
||||
"'Remove' item is present"
|
||||
);
|
||||
Assert.ok(menuItems[3].hidden, "'Remove' item is hidden");
|
||||
|
||||
contextMenuPromise = promisePanelHidden("pageActionContextMenu");
|
||||
EventUtils.synthesizeMouseAtCenter(menuItems[0], {});
|
||||
await contextMenuPromise;
|
||||
|
@ -1598,7 +1613,7 @@ add_task(async function contextMenu() {
|
|||
return BrowserPageActions.urlbarButtonNodeForActionID(action.id);
|
||||
}, "Waiting for urlbar button to be added back");
|
||||
|
||||
// Open the context menu again on the action's button in the panel. (The
|
||||
// Open the context menu again on the action's button in the panel. (The
|
||||
// panel should still be open.)
|
||||
contextMenuPromise = promisePanelShown("pageActionContextMenu");
|
||||
EventUtils.synthesizeMouseAtCenter(panelButton, {
|
||||
|
@ -1607,10 +1622,11 @@ add_task(async function contextMenu() {
|
|||
});
|
||||
await contextMenuPromise;
|
||||
|
||||
// The context menu should show the "remove" item and the "manage" item.
|
||||
// Click the "manage" item. about:addons should open.
|
||||
// The context menu should show the "remove" item and the "manage" item. The
|
||||
// 4th item is "remove extension" but it is hidden. Click the "manage" item.
|
||||
// about:addons should open.
|
||||
menuItems = collectContextMenuItems();
|
||||
Assert.equal(menuItems.length, 3, "Context menu has 3 children");
|
||||
Assert.equal(menuItems.length, 4, "Context menu has 4 children");
|
||||
Assert.equal(
|
||||
menuItems[0].label,
|
||||
"Remove from Address Bar",
|
||||
|
@ -1626,6 +1642,14 @@ add_task(async function contextMenu() {
|
|||
"Manage Extension\u2026",
|
||||
"'Manage' item is present"
|
||||
);
|
||||
Assert.equal(
|
||||
menuItems[3].label,
|
||||
"Remove Extension",
|
||||
"'Remove' item is present"
|
||||
);
|
||||
Assert.ok(menuItems[3].hidden, "'Remove' item is hidden");
|
||||
|
||||
// Click the "manage" item, about:addons should open.
|
||||
contextMenuPromise = promisePanelHidden("pageActionContextMenu");
|
||||
let aboutAddonsPromise = BrowserTestUtils.waitForNewTab(
|
||||
gBrowser,
|
||||
|
@ -1645,10 +1669,11 @@ add_task(async function contextMenu() {
|
|||
});
|
||||
await contextMenuPromise;
|
||||
|
||||
// The context menu should show the "remove" item and the "manage" item.
|
||||
// Click the "remove" item.
|
||||
// The context menu should show the "remove" item and the "manage" item. The
|
||||
// 4th item is "remove extension" but it is hidden. Click the "manage" item.
|
||||
// about:addons should open.
|
||||
menuItems = collectContextMenuItems();
|
||||
Assert.equal(menuItems.length, 3, "Context menu has 3 children");
|
||||
Assert.equal(menuItems.length, 4, "Context menu has 4 children");
|
||||
Assert.equal(
|
||||
menuItems[0].label,
|
||||
"Remove from Address Bar",
|
||||
|
@ -1664,6 +1689,13 @@ add_task(async function contextMenu() {
|
|||
"Manage Extension\u2026",
|
||||
"'Manage' item is present"
|
||||
);
|
||||
Assert.equal(
|
||||
menuItems[3].label,
|
||||
"Remove Extension",
|
||||
"'Remove' item is present"
|
||||
);
|
||||
Assert.ok(menuItems[3].hidden, "'Remove' item is hidden");
|
||||
|
||||
contextMenuPromise = promisePanelHidden("pageActionContextMenu");
|
||||
EventUtils.synthesizeMouseAtCenter(menuItems[0], {});
|
||||
await contextMenuPromise;
|
||||
|
@ -1682,10 +1714,10 @@ add_task(async function contextMenu() {
|
|||
});
|
||||
await contextMenuPromise;
|
||||
|
||||
// The context menu should show the "add" item and the "manage" item. Click
|
||||
// the "add" item.
|
||||
// The context menu should show the "remove" item and the "manage" item. The
|
||||
// 4th item is "remove extension" but it is hidden. Click the "remove" item.
|
||||
menuItems = collectContextMenuItems();
|
||||
Assert.equal(menuItems.length, 3, "Context menu has 3 children");
|
||||
Assert.equal(menuItems.length, 4, "Context menu has 4 children");
|
||||
Assert.equal(
|
||||
menuItems[0].label,
|
||||
"Add to Address Bar",
|
||||
|
@ -1701,6 +1733,13 @@ add_task(async function contextMenu() {
|
|||
"Manage Extension\u2026",
|
||||
"'Manage' item is present"
|
||||
);
|
||||
Assert.equal(
|
||||
menuItems[3].label,
|
||||
"Remove Extension",
|
||||
"'Remove' item is present"
|
||||
);
|
||||
Assert.ok(menuItems[3].hidden, "'Remove' item is hidden");
|
||||
|
||||
contextMenuPromise = promisePanelHidden("pageActionContextMenu");
|
||||
EventUtils.synthesizeMouseAtCenter(menuItems[0], {});
|
||||
await contextMenuPromise;
|
||||
|
@ -1719,10 +1758,10 @@ add_task(async function contextMenu() {
|
|||
});
|
||||
await contextMenuPromise;
|
||||
|
||||
// The context menu should show the "remove" item and the "manage" item.
|
||||
// Click the "manage" item. about:addons should open.
|
||||
// The context menu should show the "add" item and the "manage" item. The 4th
|
||||
// item is "remove extension" but it is hidden. Click the "add" item.
|
||||
menuItems = collectContextMenuItems();
|
||||
Assert.equal(menuItems.length, 3, "Context menu has 3 children");
|
||||
Assert.equal(menuItems.length, 4, "Context menu has 4 children");
|
||||
Assert.equal(
|
||||
menuItems[0].label,
|
||||
"Remove from Address Bar",
|
||||
|
@ -1738,6 +1777,14 @@ add_task(async function contextMenu() {
|
|||
"Manage Extension\u2026",
|
||||
"'Manage' item is present"
|
||||
);
|
||||
Assert.equal(
|
||||
menuItems[3].label,
|
||||
"Remove Extension",
|
||||
"'Remove' item is present"
|
||||
);
|
||||
Assert.ok(menuItems[3].hidden, "'Remove' item is hidden");
|
||||
|
||||
// Click the "manage" item, about:addons should open.
|
||||
contextMenuPromise = promisePanelHidden("pageActionContextMenu");
|
||||
aboutAddonsPromise = BrowserTestUtils.waitForNewTab(gBrowser, "about:addons");
|
||||
EventUtils.synthesizeMouseAtCenter(menuItems[2], {});
|
||||
|
|
|
@ -2886,7 +2886,9 @@ class AddonCard extends HTMLElement {
|
|||
let {
|
||||
remove,
|
||||
report,
|
||||
} = windowRoot.ownerGlobal.promptRemoveExtension(addon);
|
||||
} = windowRoot.ownerGlobal.BrowserAddonUI.promptRemoveExtension(
|
||||
addon
|
||||
);
|
||||
let value = remove ? "accepted" : "cancelled";
|
||||
this.recordActionEvent("uninstall", value);
|
||||
if (remove) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче