Change and remove things in extensions

This commit is contained in:
Fedor 2023-10-06 19:15:29 +03:00
parent 25620e4f4d
commit 5ce6c629a9
189 changed files with 289 additions and 15048 deletions

View File

@ -51,14 +51,6 @@ pref("extensions.webextensions.default-content-security-policy", "script-src 'se
pref("extensions.webextensions.remote", true);
pref("extensions.webextensions.background-delayed-startup", true);
// Extensions that should not be flagged as legacy in about:addons
pref("extensions.legacy.exceptions", "testpilot@cliqz.com,@testpilot-containers,jid1-NeEaf3sAHdKHPA@jetpack,@activity-streams,pulse@mozilla.com,@testpilot-addon,@min-vid,tabcentertest1@mozilla.com,snoozetabs@mozilla.com,speaktome@mozilla.com,hoverpad@mozilla.com");
// Require signed add-ons by default
pref("extensions.langpacks.signatures.required", false);
pref("xpinstall.signatures.required", false);
pref("xpinstall.signatures.devInfoURL", "data:text/plain,");
// Dictionary download preference
pref("browser.dictionaries.download.url", "data:text/plain,");
@ -717,7 +709,7 @@ pref("browser.preferences.search", true);
pref("browser.preferences.defaultPerformanceSettings.enabled", true);
pref("browser.download.show_plugins_in_list", true);
pref("browser.download.hide_plugins_without_extensions", true);
pref("browser.download.hide_plugins_without_extensions", false);
// Backspace and Shift+Backspace behavior
// 0 goes Back/Forward
@ -1582,8 +1574,6 @@ pref("browser.tabs.crashReporting.requestEmail", false);
pref("browser.tabs.crashReporting.emailMe", false);
pref("browser.tabs.crashReporting.email", "");
pref("extensions.legacy.enabled", false);
// How often to check for CPOW timeouts. CPOWs are only timed out by
// the hang monitor.
pref("dom.ipc.cpow.timeout", 500);

View File

@ -933,13 +933,6 @@ var BrowserPageActions = {
let action = this._contextAction;
this._contextAction = null;
PageActions.logTelemetry("managed", action);
AMTelemetry.recordActionEvent({
object: "pageAction",
action: "manage",
extra: { addonId: action.extensionID },
});
let viewID = "addons://detail/" + encodeURIComponent(action.extensionID);
window.BrowserOpenAddonsMgr(viewID);
},

View File

@ -15,7 +15,6 @@ ChromeUtils.import("resource://gre/modules/NotificationDB.jsm");
XPCOMUtils.defineLazyModuleGetters(this, {
AddonManager: "resource://gre/modules/AddonManager.jsm",
AMTelemetry: "resource://gre/modules/AddonManager.jsm",
NewTabPagePreloading: "resource:///modules/NewTabPagePreloading.jsm",
BrowserUsageTelemetry: "resource:///modules/BrowserUsageTelemetry.jsm",
BrowserUtils: "resource://gre/modules/BrowserUtils.jsm",
@ -534,13 +533,6 @@ XPCOMUtils.defineLazyPreferenceGetter(
false
);
XPCOMUtils.defineLazyPreferenceGetter(
this,
"gAddonAbuseReportEnabled",
"extensions.abuseReport.enabled",
false
);
customElements.setElementCreationCallback("translation-notification", () => {
Services.scriptloader.loadSubScript(
"chrome://browser/content/translation-notification.js",
@ -7763,19 +7755,6 @@ function promptRemoveExtension(addon) {
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 (
gHtmlAboutAddonsEnabled &&
gAddonAbuseReportEnabled &&
["extension", "theme"].includes(addon.type)
) {
checkboxMessage = getFormattedString(
"webext.remove.abuseReportCheckbox.message",
[document.getElementById("bundle_brand").getString("vendorShortName")]
);
}
const result = confirmEx(
null,
title,
@ -7834,20 +7813,16 @@ var ToolbarContextMenu = {
let manageExtension = popup.querySelector(
".customize-context-manageExtension"
);
let reportExtension = popup.querySelector(
".customize-context-reportExtension"
);
let separator = reportExtension.nextElementSibling;
let id = this._getExtensionId(popup);
let addon = id && (await AddonManager.getAddonByID(id));
let separator = popup.querySelector(
".customize-context-removeExtension"
).nextElementSibling;
for (let element of [removeExtension, manageExtension, separator]) {
element.hidden = !addon;
}
reportExtension.hidden =
!addon || !gAddonAbuseReportEnabled || !gHtmlAboutAddonsEnabled;
if (addon) {
removeExtension.disabled = !(
addon.permissions & AddonManager.PERM_CAN_UNINSTALL
@ -7862,45 +7837,18 @@ var ToolbarContextMenu = {
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");
}
}
},
async reportExtensionForContextAction(popup, reportEntryPoint) {
let id = this._getExtensionId(popup);
let addon = id && (await AddonManager.getAddonByID(id));
if (!addon) {
return;
}
const win = await BrowserOpenAddonsMgr("addons://list/extension");
win.openAbuseReport({
addonId: addon.id,
reportEntryPoint,
});
},
openAboutAddonsForContextAction(popup) {
let id = this._getExtensionId(popup);
if (id) {
let viewID = "addons://detail/" + encodeURIComponent(id);
BrowserOpenAddonsMgr(viewID);
AMTelemetry.recordActionEvent({
object: "browserAction",
action: "manage",
extra: { addonId: id },
});
}
},
};

View File

@ -398,11 +398,6 @@
label="&customizeMenu.removeExtension.label;"
contexttype="toolbaritem"
class="customize-context-removeExtension"/>
<menuitem oncommand="ToolbarContextMenu.reportExtensionForContextAction(this.parentElement, 'toolbar_context_menu')"
accesskey="&customizeMenu.reportExtension.accesskey;"
label="&customizeMenu.reportExtension.label;"
contexttype="toolbaritem"
class="customize-context-reportExtension"/>
<menuseparator/>
<menuitem oncommand="gCustomizeMode.addToPanel(document.popupNode)"
accesskey="&customizeMenu.pinToOverflowMenu.accesskey;"

View File

@ -115,10 +115,6 @@ add_task(async function startup() {
"network.loadinfo.skip_type_assertion": {
// This is accessed in debug only.
},
"extensions.getAddons.cache.enabled": {
min: 4,
max: 55,
},
"chrome.override_package.global": {
min: 0,
max: 50,

View File

@ -27,7 +27,6 @@ support-files =
skip-if = !e10s
[browser_permissions_pointerevent.js]
[browser_permissions_unsigned.js]
skip-if = require_signing
[browser_update_checkForUpdates.js]
[browser_update_findUpdates.js]
[browser_update_interactive_noprompt.js]

View File

@ -9,9 +9,6 @@ const { AddonTestUtils } = ChromeUtils.import(
AddonTestUtils.initMochitest(this);
hookExtensionsTelemetry();
AddonTestUtils.hookAMTelemetryEvents();
async function createWebExtension(details) {
let options = {
manifest: {
@ -104,7 +101,6 @@ async function test_sideloading({ useHtmlViews }) {
await SpecialPowers.pushPrefEnv({
set: [
["extensions.htmlaboutaddons.enabled", useHtmlViews],
["xpinstall.signatures.required", false],
["extensions.autoDisableScopes", 15],
["extensions.ui.ignoreUnsigned", true],
["extensions.allowPrivateBrowsingByDefault", false],
@ -373,16 +369,7 @@ async function test_sideloading({ useHtmlViews }) {
const getEventsForAddonId = (events, addonId) =>
events.filter(ev => ev.value === addonId);
const amEvents = AddonTestUtils.getAMTelemetryEvents();
// Test telemetry events for addon1 (1 permission and 1 origin).
info("Test telemetry events collected for addon1");
const baseEventAddon1 = createBaseEventAddon(1);
const collectedEventsAddon1 = getEventsForAddonId(
amEvents,
baseEventAddon1.value
);
const expectedEventsAddon1 = [
{
...baseEventAddon1,
@ -392,26 +379,7 @@ async function test_sideloading({ useHtmlViews }) {
{ ...baseEventAddon1, method: "uninstall" },
];
let i = 0;
for (let event of collectedEventsAddon1) {
Assert.deepEqual(
event,
expectedEventsAddon1[i++],
"Got the expected telemetry event"
);
}
is(
collectedEventsAddon1.length,
expectedEventsAddon1.length,
"Got the expected number of telemetry events for addon1"
);
const baseEventAddon2 = createBaseEventAddon(2);
const collectedEventsAddon2 = getEventsForAddonId(
amEvents,
baseEventAddon2.value
);
const expectedEventsAddon2 = [
{
...baseEventAddon2,
@ -421,21 +389,6 @@ async function test_sideloading({ useHtmlViews }) {
{ ...baseEventAddon2, method: "enable" },
{ ...baseEventAddon2, method: "uninstall" },
];
i = 0;
for (let event of collectedEventsAddon2) {
Assert.deepEqual(
event,
expectedEventsAddon2[i++],
"Got the expected telemetry event"
);
}
is(
collectedEventsAddon2.length,
expectedEventsAddon2.length,
"Got the expected number of telemetry events for addon2"
);
}
add_task(async function test_xul_aboutaddons_sideloading() {

View File

@ -65,9 +65,6 @@ add_task(async function setup() {
});
});
hookExtensionsTelemetry();
AddonTestUtils.hookAMTelemetryEvents();
// Helper function to test background updates.
async function backgroundUpdateTest(url, id, checkIconFn) {
await SpecialPowers.pushPrefEnv({
@ -209,35 +206,6 @@ async function backgroundUpdateTest(url, id, checkIconFn) {
await addon.uninstall();
await SpecialPowers.popPrefEnv();
// Test that the expected telemetry events have been recorded (and that they include the
// permission_prompt event).
const amEvents = AddonTestUtils.getAMTelemetryEvents();
const updateEvents = amEvents
.filter(evt => evt.method === "update")
.map(evt => {
delete evt.value;
return evt;
});
Assert.deepEqual(
updateEvents.map(evt => evt.extra && evt.extra.step),
[
// First update (cancelled).
"started",
"download_started",
"download_completed",
"permissions_prompt",
"cancelled",
// Second update (completed).
"started",
"download_started",
"download_completed",
"permissions_prompt",
"completed",
],
"Got the steps from the collected telemetry events"
);
const method = "update";
const object = "extension";
const baseExtra = {

View File

@ -9,9 +9,6 @@ const { AddonTestUtils } = ChromeUtils.import(
AddonTestUtils.initMochitest(this);
hookExtensionsTelemetry();
AddonTestUtils.hookAMTelemetryEvents();
const ID_PERMS = "update_perms@tests.mozilla.org";
const ID_ORIGINS = "update_origins@tests.mozilla.org";
@ -27,8 +24,6 @@ add_task(async function setup() {
// We don't have pre-pinned certificates for the local mochitest server
["extensions.install.requireBuiltInCerts", false],
["extensions.update.requireBuiltInCerts", false],
// Don't require the extensions to be signed
["xpinstall.signatures.required", false],
],
});
@ -92,23 +87,6 @@ async function testNoPrompt(origUrl, id) {
await addon.uninstall();
await SpecialPowers.popPrefEnv();
// Test that the expected telemetry events have been recorded (and that they do not
// include the permission_prompt event).
const amEvents = AddonTestUtils.getAMTelemetryEvents();
const updateEventsSteps = amEvents
.filter(evt => {
return evt.method === "update" && evt.extra && evt.extra.addon_id == id;
})
.map(evt => {
return evt.extra.step;
});
// Expect telemetry events related to a completed update with no permissions_prompt event.
Assert.deepEqual(
updateEventsSteps,
["started", "download_started", "download_completed", "completed"],
"Got the steps from the collected telemetry events"
);
}
// Test that an update that adds new non-promptable permissions is just

View File

@ -6,9 +6,6 @@ add_task(async function setup() {
["extensions.install.requireBuiltInCerts", false],
["extensions.update.requireBuiltInCerts", false],
// Don't require the extensions to be signed
["xpinstall.signatures.required", false],
// Point updates to the local mochitest server
["extensions.update.url", `${BASE}/browser_webext_update.json`],
],

View File

@ -451,8 +451,6 @@ async function interactiveUpdateTest(autoUpdate, checkFn) {
],
});
AddonTestUtils.hookAMTelemetryEvents();
// Trigger an update check, manually applying the update if we're testing
// without auto-update.
async function triggerUpdate(win, addon) {
@ -549,75 +547,6 @@ async function interactiveUpdateTest(autoUpdate, checkFn) {
BrowserTestUtils.removeTab(gBrowser.selectedTab);
await addon.uninstall();
await SpecialPowers.popPrefEnv();
const collectedUpdateEvents = AddonTestUtils.getAMTelemetryEvents().filter(
evt => {
return evt.method === "update";
}
);
Assert.deepEqual(
collectedUpdateEvents.map(evt => evt.extra.step),
[
// First update is cancelled on the permission prompt.
"started",
"download_started",
"download_completed",
"permissions_prompt",
"cancelled",
// Second update is expected to be completed.
"started",
"download_started",
"download_completed",
"permissions_prompt",
"completed",
],
"Got the expected sequence on update telemetry events"
);
ok(
collectedUpdateEvents.every(evt => evt.extra.addon_id === ID),
"Every update telemetry event should have the expected addon_id extra var"
);
ok(
collectedUpdateEvents.every(
evt => evt.extra.source === FAKE_INSTALL_SOURCE
),
"Every update telemetry event should have the expected source extra var"
);
ok(
collectedUpdateEvents.every(evt => evt.extra.updated_from === "user"),
"Every update telemetry event should have the update_from extra var 'user'"
);
let hasPermissionsExtras = collectedUpdateEvents
.filter(evt => {
return evt.extra.step === "permissions_prompt";
})
.every(evt => {
return Number.isInteger(parseInt(evt.extra.num_strings, 10));
});
ok(
hasPermissionsExtras,
"Every 'permissions_prompt' update telemetry event should have the permissions extra vars"
);
let hasDownloadTimeExtras = collectedUpdateEvents
.filter(evt => {
return evt.extra.step === "download_completed";
})
.every(evt => {
const download_time = parseInt(evt.extra.download_time, 10);
return !isNaN(download_time) && download_time > 0;
});
ok(
hasDownloadTimeExtras,
"Every 'download_completed' update telemetry event should have a download_time extra vars"
);
}
// The tests in this directory install a bunch of extensions but they

View File

@ -1771,29 +1771,6 @@ BrowserGlue.prototype = {
ExtensionsUI.init();
let signingRequired;
if (AppConstants.MOZ_REQUIRE_SIGNING) {
signingRequired = true;
} else {
signingRequired = Services.prefs.getBoolPref(
"xpinstall.signatures.required"
);
}
if (signingRequired) {
let disabledAddons = AddonManager.getStartupChanges(
AddonManager.STARTUP_CHANGE_DISABLED
);
AddonManager.getAddonsByIDs(disabledAddons).then(addons => {
for (let addon of addons) {
if (addon.signedState <= AddonManager.SIGNEDSTATE_MISSING) {
this._notifyUnsignedAddonsDisabled();
break;
}
}
});
}
if (AppConstants.MOZ_CRASHREPORTER) {
UnsubmittedCrashHandler.init();
}

View File

@ -39,11 +39,6 @@ ChromeUtils.defineModuleGetter(
"AddonManager",
"resource://gre/modules/AddonManager.jsm"
);
ChromeUtils.defineModuleGetter(
this,
"AMTelemetry",
"resource://gre/modules/AddonManager.jsm"
);
ChromeUtils.defineModuleGetter(
this,
"DragPositionManager",
@ -1338,13 +1333,11 @@ CustomizeMode.prototype = {
openAddonsManagerThemes(aEvent) {
aEvent.target.parentNode.parentNode.hidePopup();
AMTelemetry.recordLinkEvent({ object: "customize", value: "manageThemes" });
this.window.BrowserOpenAddonsMgr("addons://list/theme");
},
getMoreThemes(aEvent) {
aEvent.target.parentNode.parentNode.hidePopup();
AMTelemetry.recordLinkEvent({ object: "customize", value: "getThemes" });
let getMoreURL = Services.urlFormatter.formatURLPref(
"lightweightThemes.getMoreURL"
);
@ -1534,11 +1527,6 @@ CustomizeMode.prototype = {
button.addEventListener("command", async () => {
await button.theme.enable();
onThemeSelected(panel);
AMTelemetry.recordActionEvent({
object: "customize",
action: "enable",
extra: { type: "theme", addonId: theme.id },
});
});
panel.insertBefore(button, footer);
}

View File

@ -40,11 +40,6 @@
label="&customizeMenu.removeExtension.label;"
contexttype="toolbaritem"
class="customize-context-removeExtension"/>
<menuitem oncommand="ToolbarContextMenu.reportExtensionForContextAction(this.parentElement, 'toolbar_context_menu')"
accesskey="&customizeMenu.reportExtension.accesskey;"
label="&customizeMenu.reportExtension.label;"
contexttype="toolbaritem"
class="customize-context-reportExtension"/>
<menuseparator/>
<menuitem oncommand="gCustomizeMode.addToPanel(document.popupNode)"
id="customizationPanelItemContextMenuPin"

View File

@ -854,9 +854,6 @@
"extensions.blocklist.enabled": {
"type": "boolean"
},
"extensions.getAddons.showPane": {
"type": "boolean"
},
"geo.enabled": {
"type": "boolean"
},

View File

@ -1,11 +1,5 @@
"use strict";
XPCOMUtils.defineLazyPreferenceGetter(
this,
"ABUSE_REPORT_ENABLED",
"extensions.abuseReport.enabled",
false
);
XPCOMUtils.defineLazyPreferenceGetter(
this,
"HTML_ABOUTADDONS_ENABLED",
@ -207,10 +201,9 @@ add_task(async function browseraction_contextmenu_manage_extension() {
let manageExtension = menu.querySelector(
".customize-context-manageExtension"
);
let reportExtension = menu.querySelector(
".customize-context-reportExtension"
);
let separator = reportExtension.nextElementSibling;
let separator = popup.querySelector(
".customize-context-removeExtension"
).nextElementSibling;
info(`Check visibility: ${visible}`);
let expected = visible ? "visible" : "hidden";
@ -224,11 +217,6 @@ add_task(async function browseraction_contextmenu_manage_extension() {
!visible,
`Manage Extension should be ${expected}`
);
is(
reportExtension.hidden,
!ABUSE_REPORT_ENABLED || !HTML_ABOUTADDONS_ENABLED || !visible,
`Report Extension should be ${expected}`
);
is(
separator.hidden,
!visible,
@ -594,118 +582,3 @@ add_task(async function browseraction_contextmenu_remove_extension() {
await BrowserTestUtils.closeWindow(win);
});
// This test case verify reporting an extension from the browserAction
// context menu (when the browserAction is in the toolbox and in the
// overwflow menu, and repeat the test with and without the customize
// mode enabled).
add_task(async function browseraction_contextmenu_report_extension() {
SpecialPowers.pushPrefEnv({
set: [
["extensions.htmlaboutaddons.enabled", true],
["extensions.abuseReport.enabled", true],
],
});
let win = await BrowserTestUtils.openNewBrowserWindow();
let id = "addon_id@example.com";
let name = "Bad Add-on";
let buttonId = `${makeWidgetId(id)}-browser-action`;
let extension = ExtensionTestUtils.loadExtension({
manifest: {
name,
author: "Bad author",
applications: {
gecko: { id },
},
browser_action: {},
},
useAddonManager: "temporary",
});
async function testContextMenu(menuId, customizing) {
info(`Open browserAction context menu in ${menuId}`);
let menu = await openContextMenu(menuId, buttonId, win);
info(`Choosing 'Report Extension' in ${menuId} should show confirm dialog`);
let reportExtension = menu.querySelector(
".customize-context-reportExtension"
);
ok(!reportExtension.hidden, "Report extension should be visibile");
// When running in customizing mode "about:addons" will load in a new tab,
// otherwise it will replace the existing blank tab.
const onceAboutAddonsTab = customizing
? BrowserTestUtils.waitForNewTab(win.gBrowser, "about:addons")
: BrowserTestUtils.waitForCondition(() => {
return win.gBrowser.currentURI.spec === "about:addons";
}, "Wait an about:addons tab to be opened");
await closeChromeContextMenu(menuId, reportExtension, win);
await onceAboutAddonsTab;
const browser = win.gBrowser.selectedBrowser;
is(
browser.currentURI.spec,
"about:addons",
"Got about:addons tab selected"
);
await BrowserTestUtils.browserLoaded(browser);
const abuseReportFrame = await BrowserTestUtils.waitForCondition(() => {
return browser.contentDocument.querySelector(
"addon-abuse-report-xulframe"
);
}, "Wait the abuse report frame");
ok(
!abuseReportFrame.hidden,
"Abuse report frame has the expected visibility"
);
is(
abuseReportFrame.report.addon.id,
id,
"Abuse report frame has the expected addon id"
);
is(
abuseReportFrame.report.reportEntryPoint,
"toolbar_context_menu",
"Abuse report frame has the expected reportEntryPoint"
);
// Close the new about:addons tab when running in customize mode,
// or cancel the abuse report if the about:addons page has been
// loaded in the existing blank tab.
if (customizing) {
info("Closing the about:addons tab");
BrowserTestUtils.removeTab(win.gBrowser.selectedTab);
} else {
info("Navigate the about:addons tab to about:blank");
await BrowserTestUtils.loadURI(browser, "about:blank");
}
return menu;
}
await extension.startup();
info("Run tests in normal mode");
await runTestContextMenu({
buttonId,
customizing: false,
testContextMenu,
win,
});
info("Run tests in customize mode");
await runTestContextMenu({
buttonId,
customizing: true,
testContextMenu,
win,
});
await extension.unload();
await BrowserTestUtils.closeWindow(win);
});

View File

@ -4,10 +4,6 @@ const BASE =
"http://mochi.test:8888/browser/browser/components/extensions/test/browser/";
add_task(async function test_management_install() {
await SpecialPowers.pushPrefEnv({
set: [["xpinstall.signatures.required", false]],
});
registerCleanupFunction(async () => {
await SpecialPowers.popPrefEnv();
});

View File

@ -19,11 +19,6 @@
var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.defineModuleGetter(
this,
"AMTelemetry",
"resource://gre/modules/AddonManager.jsm"
);
ChromeUtils.defineModuleGetter(
this,
"formAutofillParent",
@ -121,10 +116,6 @@ function init_all() {
document.getElementById("addonsButton").addEventListener("click", () => {
let mainWindow = window.docShell.rootTreeItem.domWindow;
mainWindow.BrowserOpenAddonsMgr();
AMTelemetry.recordLinkEvent({
object: "aboutPreferences",
value: "about:addons",
});
});
document.dispatchEvent(

View File

@ -242,7 +242,6 @@ add_task(async function testDisabledBrowserLanguages() {
["intl.multilingual.enabled", true],
["intl.multilingual.downloadEnabled", true],
["intl.locale.requested", "en-US,pl,he,de"],
["extensions.langpacks.signatures.required", false],
["extensions.getAddons.langpacks.url", langpacksUrl],
],
});

View File

@ -2,12 +2,6 @@ export MOZ_PGO=1
. "$topsrcdir/browser/config/mozconfigs/linux32/common-opt"
# Add-on signing is not required for DevEdition
MOZ_REQUIRE_SIGNING=0
ac_add_options --with-branding=browser/branding/aurora
# Enable MOZ_ALLOW_LEGACY_EXTENSIONS
ac_add_options "MOZ_ALLOW_LEGACY_EXTENSIONS=1"
. "$topsrcdir/build/mozconfig.common.override"

View File

@ -15,7 +15,5 @@ export MOZILLA_OFFICIAL=1
# Don't autoclobber l10n, as this can lead to missing binaries and broken builds
# Bug 1283438
mk_add_options AUTOCLOBBER=
# Enable MOZ_ALLOW_LEGACY_EXTENSIONS
ac_add_options "MOZ_ALLOW_LEGACY_EXTENSIONS=1"
. "$topsrcdir/build/mozconfig.common.override"

View File

@ -1,10 +1,5 @@
. $topsrcdir/browser/config/mozconfigs/linux64/nightly
#add-on signing is checked but not enforced
MOZ_REQUIRE_SIGNING=0
# Enable MOZ_ALLOW_LEGACY_EXTENSIONS
ac_add_options "MOZ_ALLOW_LEGACY_EXTENSIONS=1"
ac_add_options --with-branding=browser/branding/unofficial
ac_add_options --enable-update-channel=default

View File

@ -3,11 +3,6 @@ MOZ_AUTOMATION_L10N_CHECK=0
ac_add_options --disable-debug
ac_add_options --enable-optimize="-O2 -gline-tables-only"
#add-on signing is checked but not enforced
MOZ_REQUIRE_SIGNING=0
# Enable MOZ_ALLOW_LEGACY_EXTENSIONS
ac_add_options "MOZ_ALLOW_LEGACY_EXTENSIONS=1"
. $topsrcdir/build/mozconfig.stylo
# ASan specific options on Linux

View File

@ -2,9 +2,6 @@ export MOZ_PGO=1
. "$topsrcdir/browser/config/mozconfigs/linux64/common-opt"
# Add-on signing is not required for DevEdition
MOZ_REQUIRE_SIGNING=0
ac_add_options --with-branding=browser/branding/aurora
export MOZ_LTO=1
@ -12,7 +9,4 @@ ac_add_options --enable-profile-use
ac_add_options --with-pgo-jarlog=/builds/worker/fetches/en-US.log
ac_add_options --with-pgo-profile-path=/builds/worker/fetches
# Enable MOZ_ALLOW_LEGACY_EXTENSIONS
ac_add_options "MOZ_ALLOW_LEGACY_EXTENSIONS=1"
. "$topsrcdir/build/mozconfig.common.override"

View File

@ -11,7 +11,4 @@ export MOZILLA_OFFICIAL=1
# Bug 1283438
mk_add_options AUTOCLOBBER=
# Enable MOZ_ALLOW_LEGACY_EXTENSIONS
ac_add_options "MOZ_ALLOW_LEGACY_EXTENSIONS=1"
. "$topsrcdir/build/mozconfig.common.override"

View File

@ -2,11 +2,6 @@
ac_add_options --disable-debug
ac_add_options --enable-optimize="-O2 -gline-tables-only"
#add-on signing is checked but not enforced
MOZ_REQUIRE_SIGNING=0
# Enable MOZ_ALLOW_LEGACY_EXTENSIONS
ac_add_options "MOZ_ALLOW_LEGACY_EXTENSIONS=1"
. $topsrcdir/build/mozconfig.stylo
# ASan specific options on Linux

View File

@ -2,11 +2,6 @@
unset MOZ_LTO
#add-on signing is checked but not enforced
MOZ_REQUIRE_SIGNING=0
# Enable MOZ_ALLOW_LEGACY_EXTENSIONS
ac_add_options "MOZ_ALLOW_LEGACY_EXTENSIONS=1"
ac_add_options --with-branding=browser/branding/unofficial
ac_add_options --enable-update-channel=default

View File

@ -1,8 +1,5 @@
. "$topsrcdir/browser/config/mozconfigs/macosx64/common-opt"
# Add-on signing is not required for DevEdition
MOZ_REQUIRE_SIGNING=0
ac_add_options --disable-install-strip
export MOZ_LTO=1
@ -20,7 +17,4 @@ fi
ac_add_options --with-branding=browser/branding/aurora
# Enable MOZ_ALLOW_LEGACY_EXTENSIONS
ac_add_options "MOZ_ALLOW_LEGACY_EXTENSIONS=1"
. "$topsrcdir/build/mozconfig.common.override"

View File

@ -26,7 +26,4 @@ export MOZILLA_OFFICIAL=1
# Bug 1283438
mk_add_options AUTOCLOBBER=
# Enable MOZ_ALLOW_LEGACY_EXTENSIONS
ac_add_options "MOZ_ALLOW_LEGACY_EXTENSIONS=1"
. "$topsrcdir/build/mozconfig.common.override"

View File

@ -1,10 +1,5 @@
. $topsrcdir/browser/config/mozconfigs/win32/nightly
#add-on signing is checked but not enforced
MOZ_REQUIRE_SIGNING=0
# Enable MOZ_ALLOW_LEGACY_EXTENSIONS
ac_add_options "MOZ_ALLOW_LEGACY_EXTENSIONS=1"
ac_add_options --with-branding=browser/branding/unofficial
ac_add_options --enable-update-channel=default

View File

@ -3,12 +3,6 @@ export MOZ_PGO=1
. "$topsrcdir/build/mozconfig.win-common"
. "$topsrcdir/browser/config/mozconfigs/win32/common-opt"
# Add-on signing is not required for DevEdition
MOZ_REQUIRE_SIGNING=0
ac_add_options --with-branding=browser/branding/aurora
# Enable MOZ_ALLOW_LEGACY_EXTENSIONS
ac_add_options "MOZ_ALLOW_LEGACY_EXTENSIONS=1"
. "$topsrcdir/build/mozconfig.common.override"

View File

@ -16,7 +16,4 @@ export MOZILLA_OFFICIAL=1
# Bug 1283438
mk_add_options AUTOCLOBBER=
# Enable MOZ_ALLOW_LEGACY_EXTENSIONS
ac_add_options "MOZ_ALLOW_LEGACY_EXTENSIONS=1"
. "$topsrcdir/build/mozconfig.common.override"

View File

@ -15,7 +15,6 @@ unset MAKECAB
# --enable-release
# LLVM_CONFIG
# MOZ_ADDON_SIGNING
# MOZ_REQUIRE_SIGNING
# --enable-js-shell
# build/mozconfig.automation
# MOZ_AUTOMATION_ flags

View File

@ -2,16 +2,10 @@
. "$topsrcdir/browser/config/mozconfigs/win64-aarch64/common-win64"
. "$topsrcdir/browser/config/mozconfigs/win64-aarch64/common-opt"
# Add-on signing is not required for DevEdition
MOZ_REQUIRE_SIGNING=0
export MOZ_LTO=1
ac_add_options --with-branding=browser/branding/aurora
# Enable MOZ_ALLOW_LEGACY_EXTENSIONS
ac_add_options "MOZ_ALLOW_LEGACY_EXTENSIONS=1"
unset ENABLE_CLANG_PLUGIN
. "$topsrcdir/build/mozconfig.common.override"

View File

@ -15,7 +15,4 @@ export MOZILLA_OFFICIAL=1
# Bug 1283438
mk_add_options AUTOCLOBBER=
# Enable MOZ_ALLOW_LEGACY_EXTENSIONS
ac_add_options "MOZ_ALLOW_LEGACY_EXTENSIONS=1"
. "$topsrcdir/build/mozconfig.common.override"

View File

@ -1,10 +1,5 @@
. $topsrcdir/browser/config/mozconfigs/win64/nightly
#add-on signing is checked but not enforced
MOZ_REQUIRE_SIGNING=0
# Enable MOZ_ALLOW_LEGACY_EXTENSIONS
ac_add_options "MOZ_ALLOW_LEGACY_EXTENSIONS=1"
ac_add_options --with-branding=browser/branding/unofficial
ac_add_options --enable-update-channel=default

View File

@ -4,12 +4,6 @@ export MOZ_PGO=1
. "$topsrcdir/browser/config/mozconfigs/win64/common-win64"
. "$topsrcdir/browser/config/mozconfigs/win64/common-opt"
# Add-on signing is not required for DevEdition
MOZ_REQUIRE_SIGNING=0
ac_add_options --with-branding=browser/branding/aurora
# Enable MOZ_ALLOW_LEGACY_EXTENSIONS
ac_add_options "MOZ_ALLOW_LEGACY_EXTENSIONS=1"
. "$topsrcdir/build/mozconfig.common.override"

View File

@ -15,7 +15,4 @@ export MOZILLA_OFFICIAL=1
# Bug 1283438
mk_add_options AUTOCLOBBER=
# Enable MOZ_ALLOW_LEGACY_EXTENSIONS
ac_add_options "MOZ_ALLOW_LEGACY_EXTENSIONS=1"
. "$topsrcdir/build/mozconfig.common.override"

View File

@ -14,8 +14,6 @@ unset MAKECAB
# --enable-crashreporter
# --enable-release
# LLVM_CONFIG
# MOZ_ADDON_SIGNING
# MOZ_REQUIRE_SIGNING
# --enable-js-shell
# build/mozconfig.automation
# MOZ_AUTOMATION_ flags

View File

@ -15,7 +15,6 @@ const { EventEmitter } = ChromeUtils.import(
XPCOMUtils.defineLazyModuleGetters(this, {
AddonManager: "resource://gre/modules/AddonManager.jsm",
AddonManagerPrivate: "resource://gre/modules/AddonManager.jsm",
AMTelemetry: "resource://gre/modules/AddonManager.jsm",
AppMenuNotifications: "resource://gre/modules/AppMenuNotifications.jsm",
BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.jsm",
ExtensionData: "resource://gre/modules/Extension.jsm",
@ -160,10 +159,6 @@ var ExtensionsUI = {
type: "sideload",
});
AMTelemetry.recordManageEvent(addon, "sideload_prompt", {
num_strings: strings.msgs.length,
});
this.showAddonsManager(browser, strings, addon.iconURL, "sideload").then(
async answer => {
if (answer) {
@ -187,11 +182,6 @@ var ExtensionsUI = {
},
showUpdate(browser, info) {
AMTelemetry.recordInstallEvent(info.install, {
step: "permissions_prompt",
num_strings: info.strings.msgs.length,
});
this.showAddonsManager(
browser,
info.strings,
@ -262,17 +252,6 @@ var ExtensionsUI = {
histkey = "installWeb";
}
if (info.type == "sideload") {
AMTelemetry.recordManageEvent(info.addon, "sideload_prompt", {
num_strings: strings.msgs.length,
});
} else {
AMTelemetry.recordInstallEvent(info.install, {
step: "permissions_prompt",
num_strings: strings.msgs.length,
});
}
this.showPermissionsPrompt(browser, strings, icon, histkey).then(
answer => {
if (answer) {
@ -554,13 +533,6 @@ var ExtensionsUI = {
origins: [],
};
await ExtensionPermissions.add(addon.id, perms);
AMTelemetry.recordActionEvent({
addon,
object: "doorhanger",
action: "privateBrowsingAllowed",
view: "postInstall",
value: "on",
});
// Reload the extension if it is already enabled. This ensures any change
// on the private browsing permission is properly handled.
@ -604,21 +576,11 @@ var ExtensionsUI = {
let action = {
callback: () => {
resolve();
AMTelemetry.recordActionEvent({
object: "doorhanger",
action: "dismiss",
view: "privateBrowsing",
});
},
dismiss: false,
};
let manage = {
callback: () => {
AMTelemetry.recordActionEvent({
object: "doorhanger",
action: "manage",
view: "privateBrowsing",
});
// Callback may happen in a different window, use the top window
// for the new tab.
let win = BrowserWindowTracker.getTopWindow();

View File

@ -18,9 +18,6 @@ mk_add_options AUTOCLOBBER=1
ac_add_options --enable-crashreporter
# Disable enforcing that add-ons are signed by the trusted root
MOZ_REQUIRE_SIGNING=${MOZ_REQUIRE_SIGNING-0}
ac_add_options --enable-js-shell
. "$topsrcdir/build/mozconfig.nasm"

View File

@ -61,7 +61,7 @@ pref("devtools.remote.tls-handshake-timeout", 10000);
// The extension ID for devtools-adb-extension
pref("devtools.remote.adb.extensionID", "adb@mozilla.org");
// The URL for for devtools-adb-extension (overridden in tests to a local path)
pref("devtools.remote.adb.extensionURL", "https://ftp.mozilla.org/pub/mozilla.org/labs/devtools/adb-extension/#OS#/adb-extension-latest-#OS#.xpi");
pref("devtools.remote.adb.extensionURL", "");
// URL of the remote JSON catalog used for device simulation
pref("devtools.devices.url", "https://code.cdn.mozilla.net/devices/devices.json");

View File

@ -9537,40 +9537,6 @@ nsresult nsDocShell::InternalLoad(nsDocShellLoadState* aLoadState,
!StaticPrefs::extensions_webextensions_remote()) {
break;
}
// This next bit is... awful. Basically, about:addons used to load the
// discovery pane remotely. Allow for that, if that's actually the state
// we're in (which is no longer the default at time of writing, but still
// tested). https://bugzilla.mozilla.org/show_bug.cgi?id=1565606 covers
// removing this atrocity.
nsCOMPtr<nsIWebNavigation> parent(do_QueryInterface(mParent));
if (parent) {
nsCOMPtr<nsIURI> parentURL;
parent->GetCurrentURI(getter_AddRefs(parentURL));
if (parentURL &&
parentURL->GetSpecOrDefault().EqualsLiteral("about:addons") &&
(!Preferences::GetBool("extensions.htmlaboutaddons.enabled",
true) ||
!Preferences::GetBool(
"extensions.htmlaboutaddons.discover.enabled", true))) {
nsCString discoveryURLString;
Preferences::GetCString("extensions.webservice.discoverURL",
discoveryURLString);
nsCOMPtr<nsIURI> discoveryURL;
NS_NewURI(getter_AddRefs(discoveryURL), discoveryURLString);
nsAutoCString discoveryPrePath;
if (discoveryURL) {
discoveryURL->GetPrePath(discoveryPrePath);
}
nsAutoCString requestedPrePath;
uri->GetPrePath(requestedPrePath);
// So allow the discovery path to load inside about:addons.
if (discoveryPrePath.Equals(requestedPrePath)) {
break;
}
}
}
#ifdef MOZ_LAYOUT_DEBUGGER
// Also allow loads in the layout debugger window.
nsCOMPtr<nsIDocShellTreeItem> rootItem;

View File

@ -3003,7 +3003,6 @@ bool ContentParent::ShouldSyncPreference(const char16_t* aData) {
BLACKLIST_ENTRY(u"browser.shell."),
BLACKLIST_ENTRY(u"browser.slowStartup."),
BLACKLIST_ENTRY(u"browser.startup."),
BLACKLIST_ENTRY(u"extensions.getAddons.cache."),
BLACKLIST_ENTRY(u"media.gmp-manager."),
BLACKLIST_ENTRY(u"media.gmp-gmpopenh264."),
BLACKLIST_ENTRY(u"privacy.sanitize."),

View File

@ -888,28 +888,6 @@ nsresult nsContentSecurityManager::CheckSystemPrincipalLoads(
return NS_OK;
}
// FIXME The discovery feature in about:addons uses the SystemPrincpal.
// We should remove this exception with bug 1544011.
static nsAutoCString sDiscoveryPrePath;
static bool recvdPrefValue = false;
if (!recvdPrefValue) {
nsAutoCString discoveryURLString;
Preferences::GetCString("extensions.webservice.discoverURL",
discoveryURLString);
// discoverURL is by default suffixed with parameters in path like
// /%LOCALE%/ so, we use the prePath for comparison
nsCOMPtr<nsIURI> discoveryURL;
NS_NewURI(getter_AddRefs(discoveryURL), discoveryURLString);
if (discoveryURL) {
discoveryURL->GetPrePath(sDiscoveryPrePath);
}
recvdPrefValue = true;
}
nsAutoCString requestedPrePath;
finalURI->GetPrePath(requestedPrePath);
if (requestedPrePath.Equals(sDiscoveryPrePath)) {
return NS_OK;
}
nsAutoCString requestedURL;
finalURI->GetAsciiSpec(requestedURL);
MOZ_LOG(

View File

@ -173,9 +173,6 @@ pref("xpinstall.whitelist.directRequest", false);
pref("xpinstall.whitelist.fileRequest", false);
pref("xpinstall.whitelist.add", "https://addons.mozilla.org");
pref("extensions.langpacks.signatures.required", true);
pref("xpinstall.signatures.required", true);
// Disable add-ons that are not installed by the user in all scopes by default (See the SCOPE
// constants in AddonManager.jsm for values to use here, and Bug 1405528 for a rationale).
pref("extensions.autoDisableScopes", 15);
@ -196,14 +193,6 @@ pref("extensions.minCompatibleAppVersion", "11.0");
pref("extensions.update.url", "https://versioncheck.addons.mozilla.org/update/VersionCheck.php?reqVersion=%REQ_VERSION%&id=%ITEM_ID%&version=%ITEM_VERSION%&maxAppVersion=%ITEM_MAXAPPVERSION%&status=%ITEM_STATUS%&appID=%APP_ID%&appVersion=%APP_VERSION%&appOS=%APP_OS%&appABI=%APP_ABI%&locale=%APP_LOCALE%&currentAppVersion=%CURRENT_APP_VERSION%&updateType=%UPDATE_TYPE%&compatMode=%COMPATIBILITY_MODE%");
pref("extensions.update.background.url", "https://versioncheck-bg.addons.mozilla.org/update/VersionCheck.php?reqVersion=%REQ_VERSION%&id=%ITEM_ID%&version=%ITEM_VERSION%&maxAppVersion=%ITEM_MAXAPPVERSION%&status=%ITEM_STATUS%&appID=%APP_ID%&appVersion=%APP_VERSION%&appOS=%APP_OS%&appABI=%APP_ABI%&locale=%APP_LOCALE%&currentAppVersion=%CURRENT_APP_VERSION%&updateType=%UPDATE_TYPE%&compatMode=%COMPATIBILITY_MODE%");
/* preferences for the Get Add-ons pane */
pref("extensions.getAddons.cache.enabled", true);
pref("extensions.getAddons.search.browseURL", "https://addons.mozilla.org/%LOCALE%/android/search?q=%TERMS%&platform=%OS%&appver=%VERSION%");
pref("extensions.getAddons.browseAddons", "https://addons.mozilla.org/%LOCALE%/android/collections/4757633/mob/?page=1&collection_sort=-popularity");
pref("extensions.getAddons.get.url", "https://services.addons.mozilla.org/api/v3/addons/search/?guid=%IDS%&lang=%LOCALE%");
pref("extensions.getAddons.compatOverides.url", "https://services.addons.mozilla.org/api/v3/addons/compat-override/?guid=%IDS%&lang=%LOCALE%");
pref("extensions.getAddons.langpacks.url", "https://services.addons.mozilla.org/api/v3/addons/language-tools/?app=android&type=language&appversion=%VERSION%");
/* preference for the locale picker */
pref("extensions.getLocales.get.url", "");
pref("extensions.compatability.locales.buildid", "0");
@ -220,8 +209,6 @@ pref("extensions.webextensions.default-content-security-policy", "script-src 'se
pref("extensions.webextensions.background-delayed-startup", true);
pref("extensions.legacy.enabled", false);
/* block popups by default, and notify the user about blocked popups */
pref("dom.disable_open_during_load", true);
pref("privacy.popups.showBrowserMessage", true);

View File

@ -288,21 +288,6 @@ var Addons = {
let outer = document.createElement("div");
outer.className = "addon-item list-item";
outer.setAttribute("role", "button");
outer.addEventListener(
"click",
function(event) {
try {
openLink(
Services.urlFormatter.formatURLPref(
"extensions.getAddons.browseAddons"
)
);
} catch (e) {
Cu.reportError(e);
}
},
true
);
let img = document.createElement("img");
img.className = "icon";

View File

@ -3,8 +3,5 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# This file is included at the bottom of all native android mozconfigs
#
# Disable enforcing that add-ons are signed by the trusted root
MOZ_REQUIRE_SIGNING=0
. "$topsrcdir/build/mozconfig.common.override"

View File

@ -2611,7 +2611,7 @@
# Private browsing opt-in is only supported on Firefox desktop.
- name: extensions.allowPrivateBrowsingByDefault
type: bool
value: @IS_ANDROID@
value: true
mirror: always
# This pref should be set to true only in case of regression related to the

View File

@ -2259,9 +2259,6 @@ pref("services.settings.security.onecrl.collection", "onecrl");
pref("services.settings.security.onecrl.signer", "onecrl.content-signature.mozilla.org");
pref("services.settings.security.onecrl.checked", 0);
pref("extensions.abuseReport.enabled", false);
pref("extensions.abuseReport.url", "data:text/plain,");
// Blocklist preferences
pref("extensions.blocklist.enabled", false);
// OneCRL freshness checking depends on this value, so if you change it,
@ -3932,11 +3929,7 @@ pref("browser.meta_refresh_when_inactive.disabled", false);
// XPInstall prefs
pref("xpinstall.whitelist.required", true);
// Only Firefox requires add-on signatures
pref("xpinstall.signatures.required", false);
pref("extensions.langpacks.signatures.required", false);
pref("extensions.webExtensionsMinPlatformVersion", "42.0a1");
pref("extensions.legacy.enabled", true);
// Other webextensions prefs
pref("extensions.webextensions.keepStorageOnUninstall", false);
@ -3970,7 +3963,7 @@ pref("extensions.webextensions.enablePerformanceCounters", true);
pref("extensions.webextensions.performanceCountersMaxAge", 5000);
// The HTML about:addons page.
pref("extensions.htmlaboutaddons.enabled", true);
pref("extensions.htmlaboutaddons.enabled", false);
// Whether to allow the inline options browser in HTML about:addons page.
pref("extensions.htmlaboutaddons.inline-options.enabled", true);
// Show recommendations on the extension and theme list views.

View File

@ -3008,11 +3008,6 @@ if test -n "$MOZ_BINARY_EXTENSIONS"; then
AC_DEFINE(MOZ_BINARY_EXTENSIONS)
fi
AC_SUBST(MOZ_REQUIRE_SIGNING)
if test "$MOZ_REQUIRE_SIGNING" = 1; then
AC_DEFINE(MOZ_REQUIRE_SIGNING)
fi
dnl ========================================================
dnl = Mac bundle name prefix
dnl ========================================================

View File

@ -89,8 +89,6 @@ def build_dict(config, env=os.environ):
d['telemetry'] = substs.get('MOZ_TELEMETRY_REPORTING') == '1'
d['tests_enabled'] = substs.get('ENABLE_TESTS') == "1"
d['bin_suffix'] = substs.get('BIN_SUFFIX', '')
d['require_signing'] = substs.get('MOZ_REQUIRE_SIGNING') == '1'
d['allow_legacy_extensions'] = substs.get('MOZ_ALLOW_LEGACY_EXTENSIONS') == '1'
d['official'] = bool(substs.get('MOZILLA_OFFICIAL'))
d['updater'] = substs.get('MOZ_UPDATER') == '1'
d['artifact'] = substs.get('MOZ_ARTIFACT_BUILDS') == '1'

View File

@ -13,13 +13,6 @@ const { AddonUtils } = ChromeUtils.import(
const HTTP_PORT = 8888;
const SERVER_ADDRESS = "http://127.0.0.1:8888";
var prefs = new Preferences();
prefs.set(
"extensions.getAddons.get.url",
SERVER_ADDRESS + "/search/guid:%IDS%"
);
AddonTestUtils.init(this);
AddonTestUtils.createAppInfo(
"xpcshell@tests.mozilla.org",

View File

@ -18,10 +18,6 @@ const { Preferences } = ChromeUtils.import(
);
const prefs = new Preferences();
prefs.set(
"extensions.getAddons.get.url",
"http://localhost:8888/search/guid:%IDS%"
);
prefs.set("extensions.install.requireSecureOrigin", false);
let engine;

View File

@ -26,7 +26,6 @@ class TestNotifications(PuppeteerMixin, MarionetteTestCase):
def tearDown(self):
try:
self.marionette.clear_pref('extensions.install.requireSecureOrigin')
self.marionette.clear_pref('xpinstall.signatures.required')
self.puppeteer.utils.permissions.remove(self.addons_url, 'install')
@ -67,15 +66,6 @@ class TestNotifications(PuppeteerMixin, MarionetteTestCase):
self.assertIn(self.browser.notification.origin, self.marionette.baseurl)
self.assertIsNotNone(self.browser.notification.label)
def test_addon_install_failed_notification(self):
"""Trigger add-on blocked notification using an unsigned add-on"""
# Ensure that installing unsigned extensions will fail
self.marionette.set_pref('xpinstall.signatures.required', True)
self.trigger_addon_notification(
'webextension-unsigned.xpi',
notification=AddOnInstallFailedNotification)
def trigger_addon_notification(self, addon, notification=AddOnInstallConfirmationNotification):
with self.marionette.using_context('content'):
self.marionette.navigate(self.addons_url)

View File

@ -60,8 +60,6 @@ class GeckoInstance(object):
# AddonManager.SCOPE_PROFILE + AddonManager.SCOPE_APPLICATION
"extensions.autoDisableScopes": 0,
"extensions.enabledScopes": 5,
# Disable metadata caching for installed add-ons by default
"extensions.getAddons.cache.enabled": False,
# Disable intalling any distribution add-ons
"extensions.installDistroAddons": False,
# Make sure Shield doesn't hit the network.
@ -73,8 +71,6 @@ class GeckoInstance(object):
# Turn off extension updates so they don't bother tests
"extensions.update.enabled": False,
"extensions.update.notifyUser": False,
# Make sure opening about:addons won"t hit the network
"extensions.webservice.discoverURL": "http://%(server)s/dummy/discoveryURL",
# Allow the application to have focus even it runs in the background
"focusmanager.testmode": True,

View File

@ -195,9 +195,6 @@ const RECOMMENDED_PREFS = new Map([
["extensions.autoDisableScopes", 0],
["extensions.enabledScopes", 5],
// Disable metadata caching for installed add-ons by default
["extensions.getAddons.cache.enabled", false],
// Disable installing any distribution extensions or add-ons.
// Should be set in profile.
["extensions.installDistroAddons", false],
@ -206,9 +203,6 @@ const RECOMMENDED_PREFS = new Map([
["extensions.update.enabled", false],
["extensions.update.notifyUser", false],
// Make sure opening about:addons will not hit the network
["extensions.webservice.discoverURL", "http://%(server)s/dummy/discoveryURL"],
// Allow the application to have focus even it runs in the background
["focusmanager.testmode", true],

View File

@ -29,9 +29,6 @@ config = {
"MAR_CHANNEL_ID=firefox-mozilla-beta"),
] + [
# File, from, to
("build/mozconfig.common",
"MOZ_REQUIRE_SIGNING=${MOZ_REQUIRE_SIGNING-0}",
"MOZ_REQUIRE_SIGNING=${MOZ_REQUIRE_SIGNING-1}"),
("build/mozconfig.common",
"# Disable enforcing that add-ons are signed by the trusted root",
"# Enable enforcing that add-ons are signed by the trusted root")

View File

@ -19,9 +19,6 @@ config = {
("build/mozconfig.common",
"# Enable enforcing that add-ons are signed by the trusted root",
"# Disable enforcing that add-ons are signed by the trusted root"),
("build/mozconfig.common",
"MOZ_REQUIRE_SIGNING=${MOZ_REQUIRE_SIGNING-1}",
"MOZ_REQUIRE_SIGNING=${MOZ_REQUIRE_SIGNING-0}"),
],
"vcs_share_base": os.path.join(ABS_WORK_DIR, 'hg-shared'),
# Pull from ESR repo, since we have already branched it and have landed esr-specific patches on it

View File

@ -34,11 +34,8 @@ user_pref("dom.send_after_paint_to_content", true);
// Only load extensions from the application and user profile
// AddonManager.SCOPE_PROFILE + AddonManager.SCOPE_APPLICATION
user_pref("extensions.enabledScopes", 5);
user_pref("extensions.legacy.enabled", true);
// Turn off extension updates so they don't bother tests
user_pref("extensions.update.enabled", false);
// Prevent network access for recommendations by default. The payload is {"results":[]}.
user_pref("extensions.getAddons.discovery.api_url", "data:;base64,eyJyZXN1bHRzIjpbXX0%3D");
// Disable useragent updates.
user_pref("general.useragent.updates.enabled", false);
// Ensure WR doesn't get enabled in tests unless we do it explicitly with the MOZ_WEBRENDER envvar.
@ -49,7 +46,6 @@ user_pref("media.gmp-manager.updateEnabled", false);
user_pref("security.certerrors.mitm.priming.enabled", false);
// Make enablePrivilege continue to work for test code. :-(
user_pref("security.turn_off_all_security_so_that_viruses_can_take_over_this_computer", true);
user_pref("xpinstall.signatures.required", false);
// Prevent Remote Settings to issue non local connections.
user_pref("services.settings.server", "http://localhost/remote-settings-dummy/v1");
// Ensure autoplay is enabled for all platforms.

View File

@ -50,15 +50,10 @@ user_pref("extensions.autoDisableScopes", 10);
user_pref("extensions.blocklist.enabled", false);
user_pref("extensions.blocklist.url", "http://127.0.0.1/extensions-dummy/blocklistURL");
user_pref("extensions.checkCompatibility", false);
user_pref("extensions.getAddons.get.url", "http://127.0.0.1/extensions-dummy/repositoryGetURL");
user_pref("extensions.getAddons.getWithPerformance.url", "http://127.0.0.1/extensions-dummy/repositoryGetWithPerformanceURL");
user_pref("extensions.getAddons.search.browseURL", "http://127.0.0.1/extensions-dummy/repositoryBrowseURL");
user_pref("extensions.hotfix.url", "http://127.0.0.1/extensions-dummy/hotfixURL");
user_pref("extensions.systemAddon.update.url", "http://127.0.0.1/dummy-system-addons.xml");
user_pref("extensions.update.background.url", "http://127.0.0.1/extensions-dummy/updateBackgroundURL");
user_pref("extensions.update.notifyUser", false);
user_pref("extensions.update.url", "http://127.0.0.1/extensions-dummy/updateURL");
user_pref("extensions.webservice.discoverURL", "http://127.0.0.1/extensions-dummy/discoveryURL");
user_pref("identity.fxaccounts.auth.uri", "https://127.0.0.1/fxa-dummy/");
user_pref("identity.fxaccounts.migrateToDevEdition", false);
// Avoid idle-daily notifications, to avoid expensive operations that may

View File

@ -38,7 +38,6 @@ user_pref("dom.use_xbl_scopes_for_remote_xul", false);
user_pref("extensions.autoDisableScopes", 0);
// Disable blocklist updates so we don't have them reported as leaks
user_pref("extensions.blocklist.enabled", false);
user_pref("extensions.getAddons.cache.enabled", false);
user_pref("extensions.systemAddon.update.url", "http://localhost/dummy-system-addons.xml");
user_pref("gfx.color_management.force_srgb", true);
user_pref("gfx.color_management.mode", 2);

View File

@ -105,13 +105,6 @@ user_pref("extensions.blocklist.itemURL", "http://{server}/extensions-dummy/bloc
user_pref("extensions.blocklist.url", "http://{server}/extensions-dummy/blocklistURL");
// XPI extensions are required for test harnesses to load
user_pref("extensions.defaultProviders.enabled", true);
// Disable metadata caching for installed add-ons by default
user_pref("extensions.getAddons.cache.enabled", false);
// Make sure AddonRepository won't hit the network
user_pref("extensions.getAddons.get.url", "http://{server}/extensions-dummy/repositoryGetURL");
user_pref("extensions.getAddons.getWithPerformance.url", "http://{server}/extensions-dummy/repositoryGetWithPerformanceURL");
user_pref("extensions.getAddons.search.browseURL", "http://{server}/extensions-dummy/repositoryBrowseURL");
user_pref("extensions.hotfix.url", "http://{server}/extensions-dummy/hotfixURL");
// Disable intalling any distribution add-ons
user_pref("extensions.installDistroAddons", false);
// Disable Screenshots by default for now
@ -120,8 +113,6 @@ user_pref("extensions.systemAddon.update.url", "http://{server}/dummy-system-add
user_pref("extensions.update.background.url", "http://{server}/extensions-dummy/updateBackgroundURL");
// Point update checks to the local testing server for fast failures
user_pref("extensions.update.url", "http://{server}/extensions-dummy/updateURL");
// Make sure opening about:addons won't hit the network
user_pref("extensions.webservice.discoverURL", "http://{server}/extensions-dummy/discoveryURL");
user_pref("extensions.privatebrowsing.notification", true);
user_pref("findbar.highlightAll", false);
user_pref("findbar.modalHighlight", false);

View File

@ -153,7 +153,6 @@ class ts_paint(TsBase):
@register_test()
class ts_paint_webext(ts_paint):
webextensions = '${talos}/webextensions/dummy/dummy.xpi'
preferences = {'xpinstall.signatures.required': False}
@register_test()
@ -555,7 +554,6 @@ class tp5o(PageloaderTest):
@register_test()
class tp5o_webext(tp5o):
webextensions = '${talos}/webextensions/dummy/dummy.xpi'
preferences = {'xpinstall.signatures.required': False}
@register_test()

View File

@ -313,7 +313,6 @@ class Test_get_config(object):
# assert test_config['unit'] == 'ms'
# TODO: this isn't overriden
# assert test_config['webextensions'] != '${talos}/webextensions/dummy/dummy-signed.xpi'
assert test_config['preferences'] == {'xpinstall.signatures.required': False}
def test_ts_paint_heavy_has_expected_attributes(self):
config = get_config(self.argv_ts_paint_heavy)
@ -633,7 +632,6 @@ class Test_get_config(object):
assert test_config['timeout'] == 1800
assert test_config['unit'] == 'ms'
assert test_config['webextensions'] == '${talos}/webextensions/dummy/dummy.xpi'
assert test_config['preferences'] == {'xpinstall.signatures.required': False}
@mock.patch('talos.config.build_manifest', conftest.patched_build_manifest)
def test_tp5o_scroll_has_expected_attributes(self):

View File

@ -1 +1 @@
{'deviceroot': '', 'dirs': {}, 'repository': 'https://hg.mozilla.org/releases/mozilla-release', 'buildid': '20131205075310', 'results_log': 'pathtoresults_log', 'symbols_path': None, 'bcontroller_config': 'pathtobcontroller', 'host': '', 'browser_name': 'Firefox', 'sourcestamp': '39faf812aaec', 'remote': False, 'child_process': 'plugin-container', 'browser_version': '26.0', 'extra_args': '', 'develop': True, 'preferences': {'browser.display.overlaynavbuttons': False, 'extensions.getAddons.get.url': 'http://127.0.0.1/extensions-dummy/repositoryGetURL', 'dom.max_chrome_script_run_time': 0, 'network.proxy.type': 1, 'extensions.update.background.url': 'http://127.0.0.1/extensions-dummy/updateBackgroundURL', 'network.proxy.http': 'localhost', 'plugins.update.url': 'http://127.0.0.1/plugins-dummy/updateCheckURL', 'dom.max_script_run_time': 0, 'extensions.update.enabled': False, 'browser.safebrowsing.keyURL': 'http://127.0.0.1/safebrowsing-dummy/newkey', 'media.navigator.permission.disabled': True, 'app.update.checkInstallTime': False, 'app.update.disabledForTesting': True, 'extensions.blocklist.url': 'http://127.0.0.1/extensions-dummy/blocklistURL', 'browser.EULA.override': True, 'extensions.checkCompatibility': False, 'talos.logfile': 'pathtofile', 'browser.safebrowsing.gethashURL': 'http://127.0.0.1/safebrowsing-dummy/gethash', 'extensions.hotfix.url': 'http://127.0.0.1/extensions-dummy/hotfixURL', 'dom.disable_window_move_resize': True, 'network.proxy.http_port': 80, 'browser.dom.window.dump.enabled': True, 'extensions.update.url': 'http://127.0.0.1/extensions-dummy/updateURL', 'browser.chrome.dynamictoolbar': False, 'browser.link.open_newwindow': 2, 'security.turn_off_all_security_so_that_viruses_can_take_over_this_computer': True, 'dom.disable_open_during_load': False, 'extensions.getAddons.search.browseURL': 'http://127.0.0.1/extensions-dummy/repositoryBrowseURL', 'browser.cache.disk.smart_size.enabled': False, 'extensions.getAddons.getWithPerformance.url': 'http://127.0.0.1/extensions-dummy/repositoryGetWithPerformanceURL', 'hangmonitor.timeout': 0, 'dom.send_after_paint_to_content': True, 'security.fileuri.strict_origin_policy': False, 'media.capturestream_hints.enabled': True, 'extensions.update.notifyUser': False, 'extensions.blocklist.enabled': False, 'browser.bookmarks.max_backups': 0, 'browser.shell.checkDefaultBrowser': False, 'media.peerconnection.enabled': True, 'dom.disable_window_flip': True, 'security.enable_java': False, 'browser.warnOnQuit': False, 'media.navigator.enabled': True, 'browser.safebrowsing.updateURL': 'http://127.0.0.1/safebrowsing-dummy/update', 'dom.allow_scripts_to_close_windows': True, 'extensions.webservice.discoverURL': 'http://127.0.0.1/extensions-dummy/discoveryURL'}, 'test_timeout': 1200, 'title': 'qm-pxp01', 'error_filename': 'pathtoerrorfile', 'webserver': 'localhost:15707', 'browser_path':ffox_path, 'port': 20701, 'browser_log': 'browser_output.txt', 'process': 'firefox.exe', 'xperf_path': 'C:/Program Files/Microsoft Windows Performance Toolkit/xperf.exe', 'extensions': ['pathtopageloader'], 'fennecIDs': '', 'init_url': 'http://localhost:15707/getInfo.html', 'browser_wait': 5}
{'deviceroot': '', 'dirs': {}, 'repository': 'https://hg.mozilla.org/releases/mozilla-release', 'buildid': '20131205075310', 'results_log': 'pathtoresults_log', 'symbols_path': None, 'bcontroller_config': 'pathtobcontroller', 'host': '', 'browser_name': 'Firefox', 'sourcestamp': '39faf812aaec', 'remote': False, 'child_process': 'plugin-container', 'browser_version': '26.0', 'extra_args': '', 'develop': True, 'preferences': {'browser.display.overlaynavbuttons': False, 'dom.max_chrome_script_run_time': 0, 'network.proxy.type': 1, 'extensions.update.background.url': 'http://127.0.0.1/extensions-dummy/updateBackgroundURL', 'network.proxy.http': 'localhost', 'plugins.update.url': 'http://127.0.0.1/plugins-dummy/updateCheckURL', 'dom.max_script_run_time': 0, 'extensions.update.enabled': False, 'browser.safebrowsing.keyURL': 'http://127.0.0.1/safebrowsing-dummy/newkey', 'media.navigator.permission.disabled': True, 'app.update.checkInstallTime': False, 'app.update.disabledForTesting': True, 'extensions.blocklist.url': 'http://127.0.0.1/extensions-dummy/blocklistURL', 'browser.EULA.override': True, 'extensions.checkCompatibility': False, 'talos.logfile': 'pathtofile', 'browser.safebrowsing.gethashURL': 'http://127.0.0.1/safebrowsing-dummy/gethash', 'dom.disable_window_move_resize': True, 'network.proxy.http_port': 80, 'browser.dom.window.dump.enabled': True, 'extensions.update.url': 'http://127.0.0.1/extensions-dummy/updateURL', 'browser.chrome.dynamictoolbar': False, 'browser.link.open_newwindow': 2, 'security.turn_off_all_security_so_that_viruses_can_take_over_this_computer': True, 'dom.disable_open_during_load': False, 'browser.cache.disk.smart_size.enabled': False, 'hangmonitor.timeout': 0, 'dom.send_after_paint_to_content': True, 'security.fileuri.strict_origin_policy': False, 'media.capturestream_hints.enabled': True, 'extensions.update.notifyUser': False, 'extensions.blocklist.enabled': False, 'browser.bookmarks.max_backups': 0, 'browser.shell.checkDefaultBrowser': False, 'media.peerconnection.enabled': True, 'dom.disable_window_flip': True, 'security.enable_java': False, 'browser.warnOnQuit': False, 'media.navigator.enabled': True, 'browser.safebrowsing.updateURL': 'http://127.0.0.1/safebrowsing-dummy/update', 'dom.allow_scripts_to_close_windows': True, 'test_timeout': 1200, 'title': 'qm-pxp01', 'error_filename': 'pathtoerrorfile', 'webserver': 'localhost:15707', 'browser_path':ffox_path, 'port': 20701, 'browser_log': 'browser_output.txt', 'process': 'firefox.exe', 'xperf_path': 'C:/Program Files/Microsoft Windows Performance Toolkit/xperf.exe', 'extensions': ['pathtopageloader'], 'fennecIDs': '', 'init_url': 'http://localhost:15707/getInfo.html', 'browser_wait': 5}

View File

@ -65,9 +65,6 @@ class TPSTestRunner(object):
'browser.warnOnQuit': False,
# Allow installing extensions dropped into the profile folder
'extensions.autoDisableScopes': 10,
'extensions.getAddons.get.url': 'http://127.0.0.1:4567/addons/api/%IDS%.json',
# Our pretend addons server doesn't support metadata...
'extensions.getAddons.cache.enabled': False,
'extensions.install.requireSecureOrigin': False,
'extensions.update.enabled': False,
# Don't open a dialog to show available add-on updates
@ -77,10 +74,8 @@ class TPSTestRunner(object):
'services.sync.autoconnectDelay': 60 * 60 * 10,
'toolkit.startup.max_resumed_crashes': -1,
# hrm - not sure what the release/beta channels will do?
'xpinstall.signatures.required': False,
'services.sync.testing.tps': True,
'engine.bookmarks.repair.enabled': False,
'extensions.legacy.enabled': True,
}
debug_preferences = {

View File

@ -45,7 +45,6 @@ XPCOMUtils.defineLazyModuleGetters(this, {
AddonManager: "resource://gre/modules/AddonManager.jsm",
AddonManagerPrivate: "resource://gre/modules/AddonManager.jsm",
AddonSettings: "resource://gre/modules/addons/AddonSettings.jsm",
AMTelemetry: "resource://gre/modules/AddonManager.jsm",
AppConstants: "resource://gre/modules/AppConstants.jsm",
AsyncShutdown: "resource://gre/modules/AsyncShutdown.jsm",
ExtensionPermissions: "resource://gre/modules/ExtensionPermissions.jsm",
@ -1844,14 +1843,12 @@ class Extension extends ExtensionData {
return (
this.addonData.signedState === AddonManager.SIGNEDSTATE_PRIVILEGED ||
this.addonData.signedState === AddonManager.SIGNEDSTATE_SYSTEM ||
this.addonData.builtIn ||
(AppConstants.MOZ_ALLOW_LEGACY_EXTENSIONS &&
this.addonData.temporarilyInstalled)
this.addonData.builtIn
);
}
get experimentsAllowed() {
return AddonSettings.ALLOW_LEGACY_EXTENSIONS || this.isPrivileged;
return this.isPrivileged;
}
saveStartupData() {
@ -2143,15 +2140,6 @@ class Extension extends ExtensionData {
origins: [],
});
await StartupCache.clearAddonData(addonData.id);
// Record a telemetry event for the extension automatically allowed on private browsing as
// part of the Firefox upgrade.
AMTelemetry.recordActionEvent({
extra: { addonId: addonData.id },
object: "appUpgrade",
action: "privateBrowsingAllowed",
value: "on",
});
}
}

View File

@ -2,14 +2,6 @@
// This test checks whether the theme experiments work
add_task(async function setup() {
await SpecialPowers.pushPrefEnv({
set: [
["extensions.legacy.enabled", AppConstants.MOZ_ALLOW_LEGACY_EXTENSIONS],
],
});
});
add_task(async function test_experiment_static_theme() {
let extension = ExtensionTestUtils.loadExtension({
manifest: {
@ -59,46 +51,28 @@ add_task(async function test_experiment_static_theme() {
await extension.startup();
const testExperimentApplied = rootEl => {
if (AppConstants.MOZ_ALLOW_LEGACY_EXTENSIONS) {
is(
rootEl.style.getPropertyValue("--some-color-property"),
hexToCSS("#ff00ff"),
"Color property should be parsed and set."
);
ok(
rootEl.style
.getPropertyValue("--some-image-property")
.startsWith("url("),
"Image property should be parsed."
);
ok(
rootEl.style
.getPropertyValue("--some-image-property")
.endsWith("background.jpg)"),
"Image property should be set."
);
is(
rootEl.style.getPropertyValue("--some-random-property"),
"no-repeat",
"Generic Property should be set."
);
} else {
is(
rootEl.style.getPropertyValue("--some-color-property"),
"",
"Color property should be unset"
);
is(
rootEl.style.getPropertyValue("--some-image-property"),
"",
"Image property should be unset"
);
is(
rootEl.style.getPropertyValue("--some-random-property"),
"",
"Generic Property should be unset."
);
}
is(
rootEl.style.getPropertyValue("--some-color-property"),
hexToCSS("#ff00ff"),
"Color property should be parsed and set."
);
ok(
rootEl.style
.getPropertyValue("--some-image-property")
.startsWith("url("),
"Image property should be parsed."
);
ok(
rootEl.style
.getPropertyValue("--some-image-property")
.endsWith("background.jpg)"),
"Image property should be set."
);
is(
rootEl.style.getPropertyValue("--some-random-property"),
"no-repeat",
"Generic Property should be set."
);
};
info("Testing that current window updated with the experiment applied");
@ -198,46 +172,28 @@ add_task(async function test_experiment_dynamic_theme() {
await extension.awaitMessage("theme-updated");
const testExperimentApplied = rootEl => {
if (AppConstants.MOZ_ALLOW_LEGACY_EXTENSIONS) {
is(
rootEl.style.getPropertyValue("--some-color-property"),
hexToCSS("#ff00ff"),
"Color property should be parsed and set."
);
ok(
rootEl.style
.getPropertyValue("--some-image-property")
.startsWith("url("),
"Image property should be parsed."
);
ok(
rootEl.style
.getPropertyValue("--some-image-property")
.endsWith("background.jpg)"),
"Image property should be set."
);
is(
rootEl.style.getPropertyValue("--some-random-property"),
"no-repeat",
"Generic Property should be set."
);
} else {
is(
rootEl.style.getPropertyValue("--some-color-property"),
"",
"Color property should be unset"
);
is(
rootEl.style.getPropertyValue("--some-image-property"),
"",
"Image property should be unset"
);
is(
rootEl.style.getPropertyValue("--some-random-property"),
"",
"Generic Property should be unset."
);
}
is(
rootEl.style.getPropertyValue("--some-color-property"),
hexToCSS("#ff00ff"),
"Color property should be parsed and set."
);
ok(
rootEl.style
.getPropertyValue("--some-image-property")
.startsWith("url("),
"Image property should be parsed."
);
ok(
rootEl.style
.getPropertyValue("--some-image-property")
.endsWith("background.jpg)"),
"Image property should be set."
);
is(
rootEl.style.getPropertyValue("--some-random-property"),
"no-repeat",
"Generic Property should be set."
);
};
testExperimentApplied(root);
@ -343,44 +299,26 @@ add_task(async function test_experiment_stylesheet() {
await extension.startup();
if (AppConstants.MOZ_ALLOW_LEGACY_EXTENSIONS) {
// Wait for stylesheet load.
await BrowserTestUtils.waitForCondition(
() => computedStyle.fill === expectedFill
);
// Wait for stylesheet load.
await BrowserTestUtils.waitForCondition(
() => computedStyle.fill === expectedFill
);
is(
root.style.getPropertyValue("--menu-button-background"),
expectedColor,
"Variable should be parsed and set."
);
is(
computedStyle.backgroundColor,
expectedColor,
"Menu button should be have correct background"
);
is(
computedStyle.fill,
expectedFill,
"Menu button should be have correct fill"
);
} else {
is(
root.style.getPropertyValue("--menu-button-background"),
"",
"Variable should be unset"
);
isnot(
computedStyle.backgroundColor,
expectedColor,
"Menu button should not have custom background"
);
isnot(
computedStyle.fill,
expectedFill,
"Menu button should not have stylesheet fill"
);
}
is(
root.style.getPropertyValue("--menu-button-background"),
expectedColor,
"Variable should be parsed and set."
);
is(
computedStyle.backgroundColor,
expectedColor,
"Menu button should be have correct background"
);
is(
computedStyle.fill,
expectedFill,
"Menu button should be have correct fill"
);
await extension.unload();

View File

@ -73,76 +73,3 @@ add_task(async function test_dynamic_theme() {
await extension.unload();
});
add_task(async function test_experiments_enabled() {
await SpecialPowers.pushPrefEnv({
set: [
["extensions.legacy.enabled", AppConstants.MOZ_ALLOW_LEGACY_EXTENSIONS],
],
});
info(
"Testing that experiments are handled correctly when legacy pref is enabled"
);
const extension = ExtensionTestUtils.loadExtension({
manifest: {
theme: {
properties: {
such_property: "much_wow",
unknown_property: "very_unknown",
},
},
theme_experiment: {
properties: {
such_property: "--such-property",
},
},
},
});
if (!AppConstants.MOZ_ALLOW_LEGACY_EXTENSIONS) {
await waitForConsole(
extension.startup,
"This extension is not allowed to run theme experiments"
);
} else {
await waitForConsole(
extension.startup,
"Unrecognized theme property found: properties.unknown_property"
);
}
await extension.unload();
await SpecialPowers.popPrefEnv();
});
add_task(async function test_experiments_disabled() {
await SpecialPowers.pushPrefEnv({
set: [["extensions.legacy.enabled", false]],
});
info(
"Testing that experiments are handled correctly when legacy pref is disabled"
);
const extension = ExtensionTestUtils.loadExtension({
manifest: {
theme: {
properties: {
such_property: "much_wow",
},
},
theme_experiment: {
properties: {
such_property: "--such-property",
},
},
},
});
await waitForConsole(
extension.startup,
"This extension is not allowed to run theme experiments"
);
await extension.unload();
await SpecialPowers.popPrefEnv();
});

View File

@ -160,7 +160,7 @@ add_task(async function test_bundled_experiments() {
{
isPrivileged: false,
temporarilyInstalled: true,
shouldHaveExperiments: AppConstants.MOZ_ALLOW_LEGACY_EXTENSIONS,
shouldHaveExperiments: true,
},
{
isPrivileged: false,

View File

@ -14,38 +14,6 @@ AddonTestUtils.createAppInfo(
);
AddonTestUtils.usePrivilegedSignatures = false;
// Assert on the expected "addonsManager.action" telemetry events (and optional filter events to verify
// by using a given actionType).
function assertActionAMTelemetryEvent(
expectedActionEvents,
assertMessage,
{ actionType } = {}
) {
const snapshot = Services.telemetry.snapshotEvents(
Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS,
true
);
ok(
snapshot.parent && snapshot.parent.length > 0,
"Got parent telemetry events in the snapshot"
);
const events = snapshot.parent
.filter(([timestamp, category, method, object, value, extra]) => {
return (
category === "addonsManager" &&
method === "action" &&
(!actionType ? true : extra && extra.action === actionType)
);
})
.map(([timestamp, category, method, object, value, extra]) => {
return { method, object, value, extra };
});
Assert.deepEqual(events, expectedActionEvents, assertMessage);
}
async function runIncognitoTest(
extensionData,
privateBrowsingAllowed,
@ -221,10 +189,4 @@ add_task(async function test_extension_incognito_spanning_grandfathered() {
extra: { addonId, action: "privateBrowsingAllowed" },
},
];
assertActionAMTelemetryEvent(
expectedEvents,
"Got the expected telemetry events for the grandfathered extensions",
{ actionType: "privateBrowsingAllowed" }
);
});

View File

@ -255,7 +255,6 @@ const DEFAULT_ENVIRONMENT_PREFS = new Map([
["extensions.formautofill.addresses.enabled", { what: RECORD_PREF_VALUE }],
["extensions.formautofill.creditCards.enabled", { what: RECORD_PREF_VALUE }],
["extensions.htmlaboutaddons.enabled", { what: RECORD_PREF_VALUE }],
["extensions.legacy.enabled", { what: RECORD_PREF_VALUE }],
["extensions.strictCompatibility", { what: RECORD_PREF_VALUE }],
["extensions.update.enabled", { what: RECORD_PREF_VALUE }],
["extensions.update.url", { what: RECORD_PREF_VALUE }],
@ -298,7 +297,6 @@ const DEFAULT_ENVIRONMENT_PREFS = new Map([
["security.pki.mitm_detected", { what: RECORD_PREF_VALUE }],
["security.mixed_content.block_active_content", { what: RECORD_PREF_VALUE }],
["security.mixed_content.block_display_content", { what: RECORD_PREF_VALUE }],
["xpinstall.signatures.required", { what: RECORD_PREF_VALUE }],
]);
const LOGGER_NAME = "Toolkit.Telemetry";

View File

@ -471,21 +471,6 @@ add_task(async function test_can_upload() {
PermissionTestUtils.remove(testHttpsUri, HC_PERMISSION);
});
add_task(async function test_hct_for_discopane() {
const discoHost = "https://discovery.addons.mozilla.org";
let discoHttpsUri = Services.io.newURI(discoHost);
let permission = PermissionTestUtils.testPermission(
discoHttpsUri,
HC_PERMISSION
);
ok(
permission == Services.perms.ALLOW_ACTION,
"Disco Pane needs Hybrid Content Permission for Telemetry data upload"
);
});
add_task(async function test_init_rejects() {
await SpecialPowers.pushPrefEnv({
set: [[TelemetryUtils.Preferences.FhrUploadEnabled, true]],

View File

@ -5,11 +5,6 @@
#LOCALIZATION NOTE (uninstallNotice) %S is the add-on name
uninstallNotice=%S has been removed.
#LOCALIZATION NOTE (numReviews): Semicolon-separated list of plural forms.
# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
# #1 is the number of reviews
numReviews=#1 review;#1 reviews
#LOCALIZATION NOTE (dateUpdated) %S is the date the addon was last updated
dateUpdated=Updated %S
@ -61,7 +56,6 @@ installCancelled=Install cancelled
#LOCALIZATION NOTE (details.notification.incompatible) %1$S is the add-on name, %2$S is brand name, %3$S is application version
details.notification.incompatible=%1$S is incompatible with %2$S %3$S.
#LOCALIZATION NOTE (details.notification.unsigned, details.notification.unsignedAndDisabled) %1$S is the add-on name, %2$S is brand name
details.notification.unsignedAndDisabled=%1$S could not be verified for use in %2$S and has been disabled.
details.notification.unsigned=%1$S could not be verified for use in %2$S. Proceed with caution.
details.notification.unsigned.link=More Information
#LOCALIZATION NOTE (details.notification.blocked) %1$S is the add-on name
@ -100,11 +94,6 @@ type.service.name=Services
type.legacy.name=Legacy Extensions
type.unsupported.name=Unsupported
#LOCALIZATION NOTE(legacyWarning.description) %S is the brandShortName
legacyWarning.description=Missing something? Some extensions are no longer supported by %S.
#LOCALIZATION NOTE(legacyThemeWarning.description) %S is the brandShortName
legacyThemeWarning.description=Missing something? Some themes are no longer supported by %S.
#LOCALIZATION NOTE(listHeading.discover) %S is the brandShortName
listHeading.discover=Personalize Your %S
listHeading.extension=Manage Your Extensions

View File

@ -192,30 +192,9 @@ detail-rating =
addon-restart-now =
.label = Restart now
disabled-unsigned-heading =
.value = Some add-ons have been disabled
disabled-unsigned-description =
The following add-ons have not been verified for use in { -brand-short-name }. You can
<label data-l10n-name="find-addons">find replacements</label> or ask the developer to get them verified.
disabled-unsigned-learn-more = Learn more about our efforts to help keep you safe online.
disabled-unsigned-devinfo =
Developers interested in getting their add-ons verified can continue by reading our
<label data-l10n-name="learn-more">manual</label>.
plugin-deprecation-description =
Missing something? Some plugins are no longer supported by { -brand-short-name }. <label data-l10n-name="learn-more">Learn More.</label>
legacy-warning-show-legacy = Show legacy extensions
legacy-extensions =
.value = Legacy Extensions
legacy-extensions-description =
These extensions do not meet current { -brand-short-name } standards so they have been deactivated. <label data-l10n-name="legacy-learn-more">Learn about the changes to add-ons</label>
private-browsing-description2 =
{ -brand-short-name } is changing how extensions work in private browsing. Any new extensions you add to
{ -brand-short-name } wont run by default in Private Windows. Unless you allow it in settings, the
@ -223,10 +202,6 @@ private-browsing-description2 =
there. Weve made this change to keep your private browsing private.
<label data-l10n-name="private-browsing-learn-more">Learn how to manage extension settings</label>
extensions-view-discopane =
.name = Recommendations
.tooltiptext = { extensions-view-discopane.name }
extensions-view-recent-updates =
.name = Recent Updates
.tooltiptext = { extensions-view-recent-updates.name }
@ -343,24 +318,6 @@ shortcuts-card-collapse-button = Show Less
go-back-button =
.tooltiptext = Go back
## Recommended add-ons page
# Explanatory introduction to the list of recommended add-ons. The action word
# ("recommends") in the final sentence is a link to external documentation.
discopane-intro =
Extensions and themes are like apps for your browser, and they let you
protect passwords, download videos, find deals, block annoying ads, change
how your browser looks, and much more. These small software programs are
often developed by a third party. Heres a selection { -brand-product-name }
<a data-l10n-name="learn-more-trigger">recommends</a> for exceptional
security, performance, and functionality.
# Notice to make user aware that the recommendations are personalized.
discopane-notice-recommendations =
Some of these recommendations are personalized. They are based on other
extensions youve installed, profile preferences, and usage statistics.
discopane-notice-learn-more = Learn more
privacy-policy = Privacy Policy
# Refers to the author of an add-on, shown below the name of the add-on.
@ -404,7 +361,6 @@ addon-detail-author-label = Author
addon-detail-version-label = Version
addon-detail-last-updated-label = Last Updated
addon-detail-homepage-label = Homepage
addon-detail-rating-label = Rating
# The average rating that the add-on has received.
# Variables:
@ -417,15 +373,6 @@ five-star-rating =
# $name (string) - The name of the add-on
addon-name-disabled = { $name } (disabled)
# The number of reviews that an add-on has received on AMO.
# Variables:
# $numberOfReviews (number) - The number of reviews received
addon-detail-reviews-link =
{ $numberOfReviews ->
[one] { $numberOfReviews } review
*[other] { $numberOfReviews } reviews
}
## Pending uninstall message bar
# Variables:
@ -448,12 +395,6 @@ addon-detail-private-browsing-help = When allowed, the extension will have acces
addon-detail-private-browsing-allow = Allow
addon-detail-private-browsing-disallow = Dont Allow
# This is the tooltip text for the recommended badge for an extension in about:addons. The
# badge is a small icon displayed next to an extension when it is recommended on AMO.
addon-badge-recommended =
.title = Recommended
.alt = Recommended
available-updates-heading = Available Updates
recent-updates-heading = Recent Updates
@ -461,10 +402,3 @@ release-notes-loading = Loading…
release-notes-error = Sorry, but there was an error loading the release notes.
addon-permissions-empty = This extension doesnt require any permissions
recommended-extensions-heading = Recommended Extensions
recommended-themes-heading = Recommended Themes
# A recommendation for the Firefox Color theme shown at the bottom of the theme
# list view. The "Firefox Color" name itself should not be translated.
recommended-theme-1 = Feeling creative? <a data-l10n-name="link">Build your own theme with Firefox Color.</a>

View File

@ -1,92 +0,0 @@
# 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/.
abuse-report-title-extension = Report This Extension to { -vendor-short-name }
abuse-report-title-theme = Report This Theme to { -vendor-short-name }
abuse-report-subtitle = Whats the issue?
# Variables:
# $author-name (string) - Name of the add-on author
abuse-report-addon-authored-by = by <a data-l10n-name="author-name">{ $author-name }</a>
abuse-report-learnmore =
Unsure what issue to select?
<a data-l10n-name="learnmore-link">Learn more about reporting extensions and themes</a>
abuse-report-submit-description = Describe the problem (optional)
abuse-report-textarea =
.placeholder = Its easier for us to address a problem if we have specifics. Please describe what youre experiencing. Thank you for helping us keep the web healthy.
abuse-report-submit-note =
Note: Dont include personal information (such as name, email address, phone number, physical address).
{ -vendor-short-name } keeps a permanent record of these reports.
## Panel buttons.
abuse-report-cancel-button = Cancel
abuse-report-next-button = Next
abuse-report-goback-button = Go back
abuse-report-submit-button = Submit
## Message bars descriptions.
## Variables:
## $addon-name (string) - Name of the add-on
abuse-report-messagebar-aborted = Report for <span data-l10n-name="addon-name">{ $addon-name }</span> canceled.
abuse-report-messagebar-submitting = Sending report for <span data-l10n-name="addon-name">{ $addon-name }</span>.
abuse-report-messagebar-submitted = Thank you for submitting a report. Do you want to remove <span data-l10n-name="addon-name">{ $addon-name }</span>?
abuse-report-messagebar-submitted-noremove = Thank you for submitting a report.
abuse-report-messagebar-removed-extension = Thank you for submitting a report. Youve removed the extension <span data-l10n-name="addon-name">{ $addon-name }</span>.
abuse-report-messagebar-removed-theme = Thank you for submitting a report. Youve removed the theme <span data-l10n-name="addon-name">{ $addon-name }</span>.
abuse-report-messagebar-error = There was an error sending the report for <span data-l10n-name="addon-name">{ $addon-name }</span>.
abuse-report-messagebar-error-recent-submit = The report for <span data-l10n-name="addon-name">{ $addon-name }</span> wasnt sent because another report was submitted recently.
## Message bars actions.
abuse-report-messagebar-action-remove-extension = Yes, Remove It
abuse-report-messagebar-action-keep-extension = No, Ill Keep It
abuse-report-messagebar-action-remove-theme = Yes, Remove It
abuse-report-messagebar-action-keep-theme = No, Ill Keep It
abuse-report-messagebar-action-retry = Retry
abuse-report-messagebar-action-cancel = Cancel
## Abuse report reasons (optionally paired with related examples and/or suggestions)
abuse-report-damage-reason = Damages my computer and data
abuse-report-damage-example = Example: Injected malware or stole data
abuse-report-spam-reason = Creates spam or advertising
abuse-report-spam-example = Example: Insert ads on webpages
abuse-report-settings-reason = Changed my search engine, homepage, or new tab without informing or asking me
abuse-report-settings-suggestions = Before reporting the extension, you can try changing your settings:
abuse-report-settings-suggestions-search = Change your default search settings
abuse-report-settings-suggestions-homepage = Change your homepage and new tab
abuse-report-deceptive-reason = Pretend to be something its not
abuse-report-deceptive-example = Example: Misleading description or imagery
abuse-report-broken-reason-extension = Doesnt work, breaks websites, or slows { -brand-product-name } down
abuse-report-broken-reason-theme = Doesnt work or breaks browser display
abuse-report-broken-example =
Example: Features are slow, hard to use, or dont work; parts of websites wont load or look unusual
abuse-report-broken-suggestions-extension =
It sounds like youve identified a bug. In addition to submitting a report here, the best way
to get a functionality issue resolved is to contact the extension developer.
<a data-l10n-name="support-link">Visit the extensions website</a> to get the developer information.
abuse-report-broken-suggestions-theme =
It sounds like youve identified a bug. In addition to submitting a report here, the best way
to get a functionality issue resolved is to contact the theme developer.
<a data-l10n-name="support-link">Visit the themes website</a> to get the developer information.
abuse-report-policy-reason = Hateful, violent, or illegal content
abuse-report-policy-suggestions =
Note: Copyright and trademark issues must be reported in a separate process.
<a data-l10n-name="report-infringement-link">Use these instructions</a> to
report the problem.
abuse-report-unwanted-reason = Never wanted this extension and cant get rid of it
abuse-report-unwanted-example = Example: An application installed it without my permission
abuse-report-other-reason = Something else

View File

@ -243,13 +243,6 @@ this.AppConstants = Object.freeze({
false,
#endif
MOZ_REQUIRE_SIGNING:
#ifdef MOZ_REQUIRE_SIGNING
true,
#else
false,
#endif
get MOZ_UNSIGNED_SCOPES() {
let result = 0;
#ifdef MOZ_UNSIGNED_APP_SCOPE
@ -261,13 +254,6 @@ this.AppConstants = Object.freeze({
return result;
},
MOZ_ALLOW_LEGACY_EXTENSIONS:
#ifdef MOZ_ALLOW_LEGACY_EXTENSIONS
true,
#else
false,
#endif
MENUBAR_CAN_AUTOHIDE:
#ifdef MENUBAR_CAN_AUTOHIDE
true,

View File

@ -621,18 +621,6 @@ project_flag('MOZ_BLOCK_PROFILE_DOWNGRADE',
help='Block users from starting profiles last used by a newer build',
set_as_define=True)
option(env='MOZ_ALLOW_LEGACY_EXTENSIONS',
default=milestone.is_nightly,
help='Allow legacy browser extensions')
@depends('MOZ_ALLOW_LEGACY_EXTENSIONS')
def legacy_extensions(value):
if bool(value):
return True
set_config('MOZ_ALLOW_LEGACY_EXTENSIONS', legacy_extensions)
set_define('MOZ_ALLOW_LEGACY_EXTENSIONS', legacy_extensions)
@depends('MOZ_PLACES', 'MOZ_ANDROID_HISTORY')
def check_places_and_android_history(places, android_history):
if places and android_history:

View File

@ -1,395 +0,0 @@
/* 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/. */
const EXPORTED_SYMBOLS = ["AbuseReporter", "AbuseReportError"];
const { XPCOMUtils } = ChromeUtils.import(
"resource://gre/modules/XPCOMUtils.jsm"
);
Cu.importGlobalProperties(["fetch"]);
const PREF_ABUSE_REPORT_URL = "extensions.abuseReport.url";
// Maximum length of the string properties sent to the API endpoint.
const MAX_STRING_LENGTH = 255;
// Minimum time between report submissions (in ms).
const MIN_MS_BETWEEN_SUBMITS = 30000;
XPCOMUtils.defineLazyModuleGetters(this, {
AddonManager: "resource://gre/modules/AddonManager.jsm",
AMTelemetry: "resource://gre/modules/AddonManager.jsm",
AppConstants: "resource://gre/modules/AppConstants.jsm",
ClientID: "resource://gre/modules/ClientID.jsm",
Services: "resource://gre/modules/Services.jsm",
});
XPCOMUtils.defineLazyPreferenceGetter(
this,
"ABUSE_REPORT_URL",
PREF_ABUSE_REPORT_URL
);
const PRIVATE_REPORT_PROPS = Symbol("privateReportProps");
const ERROR_TYPES = Object.freeze([
"ERROR_ABORTED_SUBMIT",
"ERROR_ADDON_NOTFOUND",
"ERROR_CLIENT",
"ERROR_NETWORK",
"ERROR_UNKNOWN",
"ERROR_RECENT_SUBMIT",
"ERROR_SERVER",
]);
class AbuseReportError extends Error {
constructor(errorType, errorInfo = undefined) {
if (!ERROR_TYPES.includes(errorType)) {
throw new Error(`Unknown AbuseReportError type "${errorType}"`);
}
let message = errorInfo ? `${errorType} - ${errorInfo}` : errorType;
super(message);
this.name = "AbuseReportError";
this.errorType = errorType;
this.errorInfo = errorInfo;
}
}
/**
* A singleton object used to create new AbuseReport instances for a given addonId
* and enforce a minium amount of time between two report submissions .
*/
const AbuseReporter = {
_lastReportTimestamp: null,
// Error types.
updateLastReportTimestamp() {
this._lastReportTimestamp = Date.now();
},
getTimeFromLastReport() {
const currentTimestamp = Date.now();
if (this._lastReportTimestamp > currentTimestamp) {
// Reset the last report timestamp if it is in the future.
this._lastReportTimestamp = null;
}
if (!this._lastReportTimestamp) {
return Infinity;
}
return currentTimestamp - this._lastReportTimestamp;
},
/**
* Create an AbuseReport instance, given the addonId and a reportEntryPoint.
*
* @param {string} addonId
* The id of the addon to create the report instance for.
* @param {object} options
* @param {string} options.reportEntryPoint
* An identifier that represent the entry point for the report flow.
*
* @returns {AbuseReport}
* An instance of the AbuseReport class, which represent an ongoing
* report.
*/
async createAbuseReport(addonId, { reportEntryPoint } = {}) {
const addon = await AddonManager.getAddonByID(addonId);
if (!addon) {
AMTelemetry.recordReportEvent({
addonId,
errorType: "ERROR_ADDON_NOTFOUND",
reportEntryPoint,
});
throw new AbuseReportError("ERROR_ADDON_NOTFOUND");
}
const reportData = await this.getReportData(addon);
return new AbuseReport({
addon,
reportData,
reportEntryPoint,
});
},
/**
* Helper function that retrieves from an addon object all the data to send
* as part of the submission request, besides the `reason`, `message` which are
* going to be received from the submit method of the report object returned
* by `createAbuseReport`.
* (See https://addons-server.readthedocs.io/en/latest/topics/api/abuse.html)
*
* @param {AddonWrapper} addon
* The addon object to collect the detail from.
*
* @return {object}
* An object that contains the collected details.
*/
async getReportData(addon) {
const truncateString = text =>
typeof text == "string" ? text.slice(0, MAX_STRING_LENGTH) : text;
let installInfo = addon.installTelemetryInfo;
const data = {
addon: addon.id,
addon_version: addon.version,
addon_name: truncateString(addon.name),
addon_summary: truncateString(addon.description),
addon_install_origin:
addon.sourceURI && truncateString(addon.sourceURI.spec),
addon_install_source_url:
installInfo &&
installInfo.sourceURL &&
truncateString(installInfo.sourceURL),
install_date: addon.installDate && addon.installDate.toISOString(),
};
// Map addon.installTelemetryInfo values to the supported addon_install_method
// values supported by the API endpoint (See API endpoint docs at
// https://addons-server.readthedocs.io/en/latest/topics/api/abuse.html).
let install_method = "other";
if (installInfo) {
const { source, method } = installInfo;
switch (source) {
case "enterprise-policy":
case "file-url":
case "system-addon":
case "temporary-addon":
install_method = source.replace(/-/g, "_");
break;
case "distribution":
case "sync":
install_method = source;
break;
default:
install_method = "other";
}
switch (method) {
case "sideload":
case "link":
install_method = method;
break;
case "amWebAPI":
case "installTrigger":
install_method = method.toLowerCase();
break;
case "drag-and-drop":
case "install-from-file":
case "management-webext-api":
install_method = method.replace(/-/g, "_");
break;
}
}
data.addon_install_method = install_method;
switch (addon.signedState) {
case AddonManager.SIGNEDSTATE_BROKEN:
data.addon_signature = "broken";
break;
case AddonManager.SIGNEDSTATE_UNKNOWN:
data.addon_signature = "unknown";
break;
case AddonManager.SIGNEDSTATE_MISSING:
data.addon_signature = "missing";
break;
case AddonManager.SIGNEDSTATE_PRELIMINARY:
data.addon_signature = "preliminary";
break;
case AddonManager.SIGNEDSTATE_SIGNED:
data.addon_signature = "signed";
break;
case AddonManager.SIGNEDSTATE_SYSTEM:
data.addon_signature = "system";
break;
case AddonManager.SIGNEDSTATE_PRIVILEGED:
data.addon_signature = "privileged";
break;
default:
data.addon_signature = `unknown: ${addon.signedState}`;
}
// Set "curated" as addon_signature on recommended addons
// (addon.isRecommended internally checks that the addon is also
// signed correctly).
if (addon.isRecommended) {
data.addon_signature = "curated";
}
data.client_id = await ClientID.getClientIdHash();
data.app = Services.appinfo.name.toLowerCase();
data.appversion = Services.appinfo.version;
data.lang = Services.locale.appLocaleAsLangTag;
data.operating_system = AppConstants.platform;
data.operating_system_version = Services.sysinfo.getProperty("version");
return data;
},
};
/**
* Represents an ongoing abuse report. Instances of this class are created
* by the `AbuseReporter.createAbuseReport` method.
*
* This object is used by the reporting UI panel and message bars to:
*
* - get an errorType in case of a report creation error (e.g. because of a
* previously submitted report)
* - get the addon details used inside the reporting panel
* - submit the abuse report (and re-submit if a previous submission failed
* and the user choose to retry to submit it again)
* - abort an ongoing submission
*
* @param {object} options
* @param {AddonWrapper|null} options.addon
* AddonWrapper instance for the extension/theme being reported.
* (May be null if the extension has not been found).
* @param {object|null} options.reportData
* An object which contains addon and environment details to send as part of a submission
* (may be null if the report has a createErrorType).
* @param {string} options.reportEntryPoint
* A string that identify how the report has been triggered.
*/
class AbuseReport {
constructor({ addon, createErrorType, reportData, reportEntryPoint }) {
this[PRIVATE_REPORT_PROPS] = {
aborted: false,
abortController: new AbortController(),
addon,
reportData,
reportEntryPoint,
};
}
recordTelemetry(errorType) {
const { addon, reportEntryPoint } = this;
AMTelemetry.recordReportEvent({
addonId: addon.id,
addonType: addon.type,
errorType,
reportEntryPoint,
});
}
/**
* Submit the current report, given a reason and a message.
*
* @params {object} options
* @params {string} options.reason
* String identifier for the report reason.
* @params {string} [options.message]
* An optional string which contains a description for the reported issue.
*
* @returns {Promise<void>}
* Resolves once the report has been successfully submitted.
* It rejects with an AbuseReportError if the report couldn't be
* submitted for a known reason (or another Error type otherwise).
*/
async submit({ reason, message }) {
const { aborted, abortController, reportData, reportEntryPoint } = this[
PRIVATE_REPORT_PROPS
];
// Record telemetry event and throw an AbuseReportError.
const rejectReportError = async (errorType, { response } = {}) => {
this.recordTelemetry(errorType);
let errorInfo;
if (response) {
try {
errorInfo = JSON.stringify({
status: response.status,
responseText: await response.text().catch(err => ""),
});
} catch (err) {
// leave the errorInfo empty if we failed to stringify it.
}
}
throw new AbuseReportError(errorType, errorInfo);
};
if (aborted) {
// Report aborted before being actually submitted.
return rejectReportError("ERROR_ABORTED_SUBMIT");
}
// Prevent submit of a new abuse report in less than MIN_MS_BETWEEN_SUBMITS.
let msFromLastReport = AbuseReporter.getTimeFromLastReport();
if (msFromLastReport < MIN_MS_BETWEEN_SUBMITS) {
return rejectReportError("ERROR_RECENT_SUBMIT");
}
let response;
try {
response = await fetch(ABUSE_REPORT_URL, {
signal: abortController.signal,
method: "POST",
credentials: "omit",
referrerPolicy: "no-referrer",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
...reportData,
report_entry_point: reportEntryPoint,
message,
reason,
}),
});
} catch (err) {
if (err.name === "AbortError") {
return rejectReportError("ERROR_ABORTED_SUBMIT");
}
Cu.reportError(err);
return rejectReportError("ERROR_NETWORK");
}
if (response.ok && response.status >= 200 && response.status < 400) {
// Ensure that the response is also a valid json format.
try {
await response.json();
} catch (err) {
this.recordTelemetry("ERROR_UNKNOWN");
throw err;
}
AbuseReporter.updateLastReportTimestamp();
this.recordTelemetry();
return undefined;
}
if (response.status >= 400 && response.status < 500) {
return rejectReportError("ERROR_CLIENT", { response });
}
if (response.status >= 500 && response.status < 600) {
return rejectReportError("ERROR_SERVER", { response });
}
// We got an unexpected HTTP status code.
return rejectReportError("ERROR_UNKNOWN", { response });
}
/**
* Abort the report submission.
*/
abort() {
const { abortController } = this[PRIVATE_REPORT_PROPS];
abortController.abort();
this[PRIVATE_REPORT_PROPS].aborted = true;
}
get addon() {
return this[PRIVATE_REPORT_PROPS].addon;
}
get reportEntryPoint() {
return this[PRIVATE_REPORT_PROPS].reportEntryPoint;
}
}

View File

@ -92,7 +92,7 @@ Services.ppmm.loadProcessScript(
const INTEGER = /^[1-9]\d*$/;
var EXPORTED_SYMBOLS = ["AddonManager", "AddonManagerPrivate", "AMTelemetry"];
var EXPORTED_SYMBOLS = ["AddonManager", "AddonManagerPrivate"];
const CATEGORY_PROVIDER_MODULE = "addon-provider-module";
@ -588,8 +588,6 @@ var gShutdownInProgress = false;
var gPluginPageListener = null;
var gBrowserUpdated = null;
var AMTelemetry;
/**
* This is the real manager, kept here rather than in AddonManager to keep its
* contents hidden from API users.
@ -606,15 +604,9 @@ var AddonManagerInternal = {
providerShutdowns: new Map(),
types: {},
startupChanges: {},
// Store telemetry details per addon provider
telemetryDetails: {},
upgradeListeners: new Map(),
externalExtensionLoaders: new Map(),
recordTimestamp(name, value) {
this.TelemetryTimestamps.add(name, value);
},
/**
* Start up a provider, and register its shutdown hook if it has one
*
@ -695,16 +687,6 @@ var AddonManagerInternal = {
return;
}
this.recordTimestamp("AMI_startup_begin");
// Enable the addonsManager telemetry event category.
AMTelemetry.init();
// clear this for xpcshell test restarts
for (let provider in this.telemetryDetails) {
delete this.telemetryDetails[provider];
}
let appChanged = undefined;
let oldAppVersion = null;
@ -886,7 +868,6 @@ var AddonManagerInternal = {
);
gStartupComplete = true;
this.recordTimestamp("AMI_startup_end");
} catch (e) {
logger.error("startup failed", e);
AddonManagerPrivate.recordException("AMI", "startup failed", e);
@ -1345,9 +1326,6 @@ var AddonManagerInternal = {
permissions: difference,
resolve,
reject,
// Reference to the related AddonInstall object (used in AMTelemetry to
// link the recorded event to the other events from the same install flow).
install: info.install,
},
};
Services.obs.notifyObservers(subject, "webextension-update-permissions");
@ -1758,9 +1736,6 @@ var AddonManagerInternal = {
* An optional <browser> element for download permissions prompts.
* @param {nsIPrincipal} [aOptions.triggeringPrincipal]
* The principal which is attempting to install the add-on.
* @param {Object} [aOptions.telemetryInfo]
* An optional object which provides details about the installation source
* included in the addon manager telemetry events.
* @throws if aUrl is not specified or if an optional argument of
* an improper type is passed.
*/
@ -1842,12 +1817,9 @@ var AddonManagerInternal = {
* The nsIFile where the add-on is located
* @param aMimetype
* An optional mimetype hint for the add-on
* @param aTelemetryInfo
* An optional object which provides details about the installation source
* included in the addon manager telemetry events.
* @throws if the aFile or aCallback arguments are not specified
*/
getInstallForFile(aFile, aMimetype, aTelemetryInfo) {
getInstallForFile(aFile, aMimetype) {
if (!gStarted) {
throw Components.Exception(
"AddonManager is not initialized",
@ -1874,8 +1846,7 @@ var AddonManagerInternal = {
let install = await promiseCallProvider(
provider,
"getInstallForFile",
aFile,
aTelemetryInfo
aFile
);
if (install) {
@ -3287,11 +3258,6 @@ var AddonManagerInternal = {
browser: target,
triggeringPrincipal: options.triggeringPrincipal,
hash: options.hash,
telemetryInfo: {
source: AddonManager.getInstallSourceFromHost(options.sourceHost),
sourceURL: options.sourceURL,
method: "amWebAPI",
},
}).then(install => {
let requireConfirm = true;
if (
@ -3495,10 +3461,6 @@ var AddonManagerPrivate = {
.BOOTSTRAP_REASONS;
},
recordTimestamp(name, value) {
AddonManagerInternal.recordTimestamp(name, value);
},
_simpleMeasures: {},
recordSimpleMeasure(name, value) {
this._simpleMeasures[name] = value;
@ -3527,14 +3489,6 @@ var AddonManagerPrivate = {
return this._simpleMeasures;
},
getTelemetryDetails() {
return AddonManagerInternal.telemetryDetails;
},
setTelemetryDetails(aProvider, aDetails) {
AddonManagerInternal.telemetryDetails[aProvider] = aDetails;
},
// Start a timer, record a simple measure of the time interval when
// timer.done() is called
simpleTimer(aName) {
@ -3643,7 +3597,6 @@ var AddonManager = {
// telemetry events.
_installHostSource: new Map([
["addons.mozilla.org", "amo"],
["discovery.addons.mozilla.org", "disco"],
]),
// Constants for the AddonInstall.state property
@ -3927,11 +3880,10 @@ var AddonManager = {
return AddonManagerInternal.getInstallForURL(aUrl, aOptions);
},
getInstallForFile(aFile, aMimetype, aTelemetryInfo) {
getInstallForFile(aFile, aMimetype) {
return AddonManagerInternal.getInstallForFile(
aFile,
aMimetype,
aTelemetryInfo
aMimetype
);
},
@ -4159,544 +4111,8 @@ var AddonManager = {
},
};
/**
* Listens to the AddonManager install and addon events and send telemetry events.
*/
AMTelemetry = {
telemetrySetupDone: false,
init() {
// Enable the addonsManager telemetry event category before the AddonManager
// has completed its startup, otherwise telemetry events recorded during the
// AddonManager/XPIProvider startup will not be recorded (e.g. the telemetry
// events for the extension migrated to the private browsing permission).
Services.telemetry.setEventRecordingEnabled("addonsManager", true);
},
// This method is called by the AddonManager, once it has been started, so that we can
// init the telemetry event category and start listening for the events related to the
// addons installation and management.
onStartup() {
if (this.telemetrySetupDone) {
return;
}
this.telemetrySetupDone = true;
Services.obs.addObserver(this, "addon-install-origin-blocked");
Services.obs.addObserver(this, "addon-install-disabled");
Services.obs.addObserver(this, "addon-install-blocked");
AddonManager.addInstallListener(this);
AddonManager.addAddonListener(this);
},
// Observer Service notification callback.
observe(subject, topic, data) {
switch (topic) {
case "addon-install-blocked": {
const { installs } = subject.wrappedJSObject;
this.recordInstallEvent(installs[0], { step: "site_warning" });
break;
}
case "addon-install-origin-blocked": {
const { installs } = subject.wrappedJSObject;
this.recordInstallEvent(installs[0], { step: "site_blocked" });
break;
}
case "addon-install-disabled": {
const { installs } = subject.wrappedJSObject;
this.recordInstallEvent(installs[0], {
step: "install_disabled_warning",
});
break;
}
}
},
// AddonManager install listener callbacks.
onNewInstall(install) {
this.recordInstallEvent(install, { step: "started" });
},
onInstallCancelled(install) {
this.recordInstallEvent(install, { step: "cancelled" });
},
onInstallPostponed(install) {
this.recordInstallEvent(install, { step: "postponed" });
},
onInstallFailed(install) {
this.recordInstallEvent(install, { step: "failed" });
},
onInstallEnded(install) {
this.recordInstallEvent(install, { step: "completed" });
},
onDownloadStarted(install) {
this.recordInstallEvent(install, { step: "download_started" });
},
onDownloadCancelled(install) {
this.recordInstallEvent(install, { step: "cancelled" });
},
onDownloadEnded(install) {
let download_time = Math.round(Cu.now() - install.downloadStartedAt);
this.recordInstallEvent(install, {
step: "download_completed",
download_time,
});
},
onDownloadFailed(install) {
let download_time = Math.round(Cu.now() - install.downloadStartedAt);
this.recordInstallEvent(install, {
step: "download_failed",
download_time,
});
},
// Addon listeners callbacks.
onUninstalled(addon) {
this.recordManageEvent(addon, "uninstall");
},
onEnabled(addon) {
this.recordManageEvent(addon, "enable");
},
onDisabled(addon) {
this.recordManageEvent(addon, "disable");
},
// Internal helpers methods.
/**
* Get a trimmed version of the given string if it is longer than 80 chars.
*
* @param {string} str
* The original string content.
*
* @returns {string}
* The trimmed version of the string when longer than 80 chars, or the given string
* unmodified otherwise.
*/
getTrimmedString(str) {
if (str.length <= 80) {
return str;
}
const length = str.length;
// Trim the string to prevent a flood of warnings messages logged internally by recordEvent,
// the trimmed version is going to be composed by the first 40 chars and the last 37 and 3 dots
// that joins the two parts, to visually indicate that the string has been trimmed.
return `${str.slice(0, 40)}...${str.slice(length - 37, length)}`;
},
/**
* Retrieve the addonId for the given AddonInstall instance.
*
* @param {AddonInstall} install
* The AddonInstall instance to retrieve the addonId from.
*
* @returns {string | null}
* The addonId for the given AddonInstall instance (if any).
*/
getAddonIdFromInstall(install) {
// Returns the id of the extension that is being installed, as soon as the
// addon is available in the AddonInstall instance (after being downloaded
// and validated successfully).
if (install.addon) {
return install.addon.id;
}
// While updating an addon, the existing addon can be
// used to retrieve the addon id since the first update event.
if (install.existingAddon) {
return install.existingAddon.id;
}
return null;
},
/**
* Retrieve the telemetry event's object property value for the given
* AddonInstall instance.
*
* @param {AddonInstall} install
* The AddonInstall instance to retrieve the event object from.
*
* @returns {string}
* The object for the given AddonInstall instance.
*/
getEventObjectFromInstall(install) {
let addonType;
if (install.type) {
// The AddonInstall wrapper already provides a type (if it was known when the
// install object has been created).
addonType = install.type;
} else if (install.addon) {
// The install flow has reached a step that has an addon instance which we can
// check to know the extension type (e.g. after download for the DownloadAddonInstall).
addonType = install.addon.type;
} else if (install.existingAddon) {
// The install flow is an update and we can look the existingAddon to check which was
// the add-on type that is being installed.
addonType = install.existingAddon.type;
}
return this.getEventObjectFromAddonType(addonType);
},
/**
* Retrieve the telemetry event source for the given AddonInstall instance.
*
* @param {AddonInstall} install
* The AddonInstall instance to retrieve the source from.
*
* @returns {Object | null}
* The telemetry infor ({source, method}) from the given AddonInstall instance.
*/
getInstallTelemetryInfo(install) {
if (install.installTelemetryInfo) {
return install.installTelemetryInfo;
} else if (
install.existingAddon &&
install.existingAddon.installTelemetryInfo
) {
// Get the install source from the existing addon (e.g. for an extension update).
return install.existingAddon.installTelemetryInfo;
}
return null;
},
/**
* Get the telemetry event's object property for the given addon type
*
* @param {string} addonType
* The addon type to convert into the related telemetry event object.
*
* @returns {string}
* The object for the given addon type.
*/
getEventObjectFromAddonType(addonType) {
switch (addonType) {
case undefined:
return "unknown";
case "extension":
case "theme":
case "locale":
case "dictionary":
return addonType;
default:
// Currently this should only include plugins and gmp-plugins
return "other";
}
},
convertToString(value) {
if (value == null) {
// Convert null and undefined to empty strings.
return "";
}
switch (typeof value) {
case "string":
return value;
case "boolean":
return value ? "1" : "0";
}
return String(value);
},
/**
* Convert all the telemetry event's extra_vars into strings, if needed.
*
* @param {object} extraVars
* @returns {object} The formatted extra vars.
*/
formatExtraVars({ addon, ...extraVars }) {
if (addon) {
extraVars.addonId = addon.id;
extraVars.type = addon.type;
}
// All the extra_vars in a telemetry event have to be strings.
for (var [key, value] of Object.entries(extraVars)) {
if (value == undefined) {
delete extraVars[key];
} else {
extraVars[key] = this.convertToString(value);
}
}
if (extraVars.addonId) {
extraVars.addonId = this.getTrimmedString(extraVars.addonId);
}
return extraVars;
},
/**
* Record an install or update event for the given AddonInstall instance.
*
* @param {AddonInstall} install
* The AddonInstall instance to record an install or update event for.
* @param {object} extraVars
* The additional extra_vars to include in the recorded event.
* @param {string} extraVars.step
* The current step in the install or update flow.
* @param {string} extraVars.download_time
* The number of ms needed to download the extension.
* @param {string} extraVars.num_strings
* The number of permission description string for the extension
* permission doorhanger.
*/
recordInstallEvent(install, extraVars) {
// Early exit if AMTelemetry's telemetry setup has not been done yet.
if (!this.telemetrySetupDone) {
return;
}
let extra = {};
let telemetryInfo = this.getInstallTelemetryInfo(install);
if (telemetryInfo && typeof telemetryInfo.source === "string") {
extra.source = telemetryInfo.source;
}
if (extra.source === "internal") {
// Do not record the telemetry event for installation sources
// that are marked as "internal".
return;
}
// Also include the install source's method when applicable (e.g. install events with
// source "about:addons" may have "install-from-file" or "url" as their source method).
if (telemetryInfo && typeof telemetryInfo.method === "string") {
extra.method = telemetryInfo.method;
}
let addonId = this.getAddonIdFromInstall(install);
let object = this.getEventObjectFromInstall(install);
let installId = String(install.installId);
let eventMethod = install.existingAddon ? "update" : "install";
if (addonId) {
extra.addon_id = this.getTrimmedString(addonId);
}
if (install.error) {
extra.error = AddonManager.errorToString(install.error);
}
if (eventMethod === "update") {
// For "update" telemetry events, also include an extra var which determine
// if the update has been requested by the user.
extra.updated_from = install.isUserRequestedUpdate ? "user" : "app";
}
// All the extra vars in a telemetry event have to be strings.
extra = this.formatExtraVars({ ...extraVars, ...extra });
this.recordEvent({ method: eventMethod, object, value: installId, extra });
},
/**
* Record a manage event for the given addon.
*
* @param {AddonWrapper} addon
* The AddonWrapper instance.
* @param {object} extraVars
* The additional extra_vars to include in the recorded event.
* @param {string} extraVars.num_strings
* The number of permission description string for the extension
* permission doorhanger.
*/
recordManageEvent(addon, method, extraVars) {
// Early exit if AMTelemetry's telemetry setup has not been done yet.
if (!this.telemetrySetupDone) {
return;
}
let extra = {};
if (addon.installTelemetryInfo) {
if ("source" in addon.installTelemetryInfo) {
extra.source = addon.installTelemetryInfo.source;
}
// Also include the install source's method when applicable (e.g. install events with
// source "about:addons" may have "install-from-file" or "url" as their source method).
if ("method" in addon.installTelemetryInfo) {
extra.method = addon.installTelemetryInfo.method;
}
}
if (extra.source === "internal") {
// Do not record the telemetry event for installation sources
// that are marked as "internal".
return;
}
let object = this.getEventObjectFromAddonType(addon.type);
let value = this.getTrimmedString(addon.id);
extra = { ...extraVars, ...extra };
let hasExtraVars = Object.keys(extra).length > 0;
extra = this.formatExtraVars(extra);
this.recordEvent({
method,
object,
value,
extra: hasExtraVars ? extra : null,
});
},
/**
* Record an event for when a link is clicked.
*
* @param {object} opts
* @param {string} opts.object
* The object of the event, should be an identifier for where the link
* is located. The accepted values are listed in the
* addonsManager.link object of the Events.yaml file.
* @param {string} opts.value The identifier for the link destination.
* @param {object} opts.extra
* The extra data to be sent, all keys must be registered in the
* extra_keys section of addonsManager.link in Events.yaml.
*/
recordLinkEvent({ object, value, extra = null }) {
this.recordEvent({ method: "link", object, value, extra });
},
/**
* Record an event for an action that took place.
*
* @param {object} opts
* @param {string} opts.object
* The object of the event, should an identifier for where the action
* took place. The accepted values are listed in the
* addonsManager.action object of the Events.yaml file.
* @param {string} opts.action The identifier for the action.
* @param {string} opts.value An optional value for the action.
* @param {object} opts.addon
* An optional object with the "id" and "type" properties, for example
* an AddonWrapper object. Passing this will set some extra properties.
* @param {string} opts.addon.id
* The add-on ID to assign to extra.addonId.
* @param {string} opts.addon.type
* The add-on type to assign to extra.type.
* @param {string} opts.view The current view, when object is aboutAddons.
* @param {object} opts.extra
* The extra data to be sent, all keys must be registered in the
* extra_keys section of addonsManager.action in Events.yaml. If
* opts.addon is passed then it will overwrite the addonId and type
* properties in this object, if they are set.
*/
recordActionEvent({ object, action, value, addon, view, extra }) {
extra = { ...extra, action, addon, view };
this.recordEvent({
method: "action",
object,
// Treat null and undefined as null.
value: value == null ? null : this.convertToString(value),
extra: this.formatExtraVars(extra),
});
},
/**
* Record an event for a view load in about:addons.
*
* @param {object} opts
* @param {string} opts.view
* The identifier for the view. The accepted values are listed in the
* object property of addonsManager.view object of the Events.yaml
* file.
* @param {AddonWrapper} opts.addon
* An optional add-on object related to the event.
* @param {string} opts.type
* An optional type for the view. If opts.addon is set it will
* overwrite this value with the type of the add-on.
*/
recordViewEvent({ view, addon, type }) {
this.recordEvent({
method: "view",
object: "aboutAddons",
value: view,
extra: this.formatExtraVars({ type, addon }),
});
},
/**
* Record an event on abuse report submissions.
*
* @params {object} opts
* @params {string} opts.addonId
* The id of the addon being reported.
* @params {string} [opts.addonType]
* The type of the addon being reported (only present for an existing
* addonId).
* @params {string} [opts.errorType]
* The AbuseReport errorType for a submission failure.
* @params {string} opts.reportEntryPoint
* The entry point of the abuse report.
*/
recordReportEvent({ addonId, addonType, errorType, reportEntryPoint }) {
this.recordEvent({
method: "report",
object: reportEntryPoint,
value: addonId,
extra: this.formatExtraVars({
addon_type: addonType,
error_type: errorType,
}),
});
},
recordEvent({ method, object, value, extra }) {
if (typeof value != "string") {
// The value must be a string or null, make sure it's valid so sending
// the event doesn't fail.
value = null;
}
try {
Services.telemetry.recordEvent(
"addonsManager",
method,
object,
value,
extra
);
} catch (err) {
// If the telemetry throws just log the error so it doesn't break any
// functionality.
Cu.reportError(err);
}
},
};
this.AddonManager.init();
// Setup the AMTelemetry once the AddonManager has been started.
this.AddonManager.addManagerListener(AMTelemetry);
// load the timestamps module into AddonManagerInternal
ChromeUtils.import(
"resource://gre/modules/TelemetryTimestamps.jsm",
AddonManagerInternal
);
Object.freeze(AddonManagerInternal);
Object.freeze(AddonManagerPrivate);
Object.freeze(AddonManager);

View File

@ -27,17 +27,14 @@ static bool IsValidHost(const nsACString& host) {
return false;
}
if (host.EqualsLiteral("addons.mozilla.org") ||
host.EqualsLiteral("discovery.addons.mozilla.org")) {
if (host.EqualsLiteral("addons.mozilla.org")) {
return true;
}
// When testing allow access to the developer sites.
if (Preferences::GetBool("extensions.webapi.testing", false)) {
if (host.LowerCaseEqualsLiteral("addons.allizom.org") ||
host.LowerCaseEqualsLiteral("discovery.addons.allizom.org") ||
host.LowerCaseEqualsLiteral("addons-dev.allizom.org") ||
host.LowerCaseEqualsLiteral("discovery.addons-dev.allizom.org") ||
host.LowerCaseEqualsLiteral("example.com")) {
return true;
}

View File

@ -87,22 +87,12 @@ amManager.prototype = {
retval = false;
}
let telemetryInfo = {
source: AddonManager.getInstallSourceFromHost(aPayload.sourceHost),
sourceURL: aPayload.sourceURL,
};
if ("method" in aPayload) {
telemetryInfo.method = aPayload.method;
}
AddonManager.getInstallForURL(uri, {
hash,
name,
icon,
browser: aBrowser,
triggeringPrincipal,
telemetryInfo,
sendCookies: true,
}).then(aInstall => {
function callCallback(status) {

View File

@ -17,11 +17,6 @@
max-width: var(--section-width);
}
#abuse-reports-messages {
margin-inline-start: 28px;
max-width: var(--section-width);
}
/* The margin between message bars. */
message-bar-stack > * {
margin-bottom: 8px;
@ -247,14 +242,6 @@ addon-details {
margin: 0;
}
.addon-detail-rating {
display: flex;
}
.addon-detail-rating > a {
margin-inline-start: 8px;
}
.more-options-button {
min-width: auto;
min-height: auto;

View File

@ -9,18 +9,13 @@
<link rel="localization" href="branding/brand.ftl">
<link rel="localization" href="toolkit/about/aboutAddons.ftl">
<link rel="localization" href="toolkit/about/abuseReports.ftl">
<script src="chrome://mozapps/content/extensions/named-deck.js"></script>
<script src="chrome://mozapps/content/extensions/aboutaddonsCommon.js"></script>
<script src="chrome://mozapps/content/extensions/message-bar.js"></script>
<script src="chrome://mozapps/content/extensions/abuse-reports.js"></script>
<script src="chrome://mozapps/content/extensions/aboutaddons.js"></script>
</head>
<body>
<message-bar-stack id="abuse-reports-messages" reverse max-message-bar-count="3">
</message-bar-stack>
<div id="main"></div>
<!-- Include helpers for the inline options browser select and context menus. -->
@ -81,26 +76,6 @@
</div>
</template>
<template name="addon-name-container-in-disco-card">
<div class="disco-card-head">
<span class="disco-addon-name"></span>
<span class="disco-addon-author"><a data-l10n-name="author" target="_blank"></a></span>
</div>
<button class="disco-cta-button primary" action="install-addon"></button>
<button class="disco-cta-button" data-l10n-id="manage-addon-button" action="manage-addon"></button>
</template>
<template name="addon-description-in-disco-card">
<div>
<strong class="disco-description-intro"></strong>
<span class="disco-description-main"></span>
</div>
<div class="disco-description-statistics">
<five-star-rating></five-star-rating>
<span class="disco-user-count"></span>
</div>
</template>
<template name="addon-details">
<div class="deck-tab-group">
<named-deck-button-group>
@ -122,33 +97,33 @@
data-l10n-attrs="accesskey">
</button>
</div>
<div class="addon-detail-row addon-detail-row-updates">
<!--div class="addon-detail-row addon-detail-row-updates">
<label data-l10n-id="addon-detail-updates-label"></label>
<div>
<button class="button-link" data-l10n-id="addon-detail-update-check-label" action="update-check" hidden></button>
<label>
<input type="radio" name="autoupdate" value="1" data-telemetry-value="default">
<input type="radio" name="autoupdate" value="1">
<span data-l10n-id="addon-detail-updates-radio-default"></span>
</label>
<label>
<input type="radio" name="autoupdate" value="2" data-telemetry-value="enabled">
<input type="radio" name="autoupdate" value="2">
<span data-l10n-id="addon-detail-updates-radio-on"></span>
</label>
<label>
<input type="radio" name="autoupdate" value="0" data-telemetry-value="">
<input type="radio" name="autoupdate" value="0">
<span data-l10n-id="addon-detail-updates-radio-off"></span>
</label>
</div>
</div>
</div-->
<div class="addon-detail-row addon-detail-row-has-help addon-detail-row-private-browsing" hidden>
<label data-l10n-id="detail-private-browsing-label"></label>
<div>
<label>
<input type="radio" name="private-browsing" value="1" data-telemetry-value="on">
<input type="radio" name="private-browsing" value="1">
<span data-l10n-id="addon-detail-private-browsing-allow"></span>
</label>
<label>
<input type="radio" name="private-browsing" value="0" data-telemetry-value="off">
<input type="radio" name="private-browsing" value="0">
<span data-l10n-id="addon-detail-private-browsing-disallow"></span>
</label>
</div>
@ -170,7 +145,7 @@
</div>
<div class="addon-detail-row addon-detail-row-author">
<label data-l10n-id="addon-detail-author-label"></label>
<a target="_blank" data-telemetry-name="author"></a>
<a target="_blank"></a>
</div>
<div class="addon-detail-row addon-detail-row-version">
<label data-l10n-id="addon-detail-version-label"></label>
@ -180,14 +155,7 @@
</div>
<div class="addon-detail-row addon-detail-row-homepage">
<label data-l10n-id="addon-detail-homepage-label"></label>
<a target="_blank" data-telemetry-name="homepage"></a>
</div>
<div class="addon-detail-row addon-detail-row-rating">
<label data-l10n-id="addon-detail-rating-label"></label>
<div class="addon-detail-rating">
<five-star-rating></five-star-rating>
<a target="_blank" data-telemetry-name="rating"></a>
</div>
<a target="_blank"></a>
</div>
</section>
<inline-options-browser name="preferences"></inline-options-browser>
@ -196,15 +164,6 @@
</named-deck>
</template>
<template name="five-star-rating">
<link rel="stylesheet" href="chrome://mozapps/content/extensions/rating-star.css">
<span class="rating-star"></span>
<span class="rating-star"></span>
<span class="rating-star"></span>
<span class="rating-star"></span>
<span class="rating-star"></span>
</template>
<template name="panel-list">
<link rel="stylesheet" href="chrome://mozapps/content/extensions/panel-list.css">
<div class="arrow top" role="presentation"></div>

View File

@ -4,14 +4,12 @@
/* eslint max-len: ["error", 80] */
/* exported initialize, hide, show */
/* import-globals-from aboutaddonsCommon.js */
/* import-globals-from abuse-reports.js */
/* global MozXULElement, windowRoot */
"use strict";
XPCOMUtils.defineLazyModuleGetters(this, {
AddonManager: "resource://gre/modules/AddonManager.jsm",
AMTelemetry: "resource://gre/modules/AddonManager.jsm",
ClientID: "resource://gre/modules/ClientID.jsm",
DeferredTask: "resource://gre/modules/DeferredTask.jsm",
E10SUtils: "resource://gre/modules/E10SUtils.jsm",
@ -60,13 +58,6 @@ XPCOMUtils.defineLazyPreferenceGetter(
const UPDATES_RECENT_TIMESPAN = 2 * 24 * 3600000; // 2 days (in milliseconds)
XPCOMUtils.defineLazyPreferenceGetter(
this,
"ABUSE_REPORT_ENABLED",
"extensions.abuseReport.enabled",
false
);
const PLUGIN_ICON_URL = "chrome://global/skin/plugins/pluginGeneric.svg";
const EXTENSION_ICON_URL =
"chrome://mozapps/skin/extensions/extensionGeneric.svg";
@ -81,7 +72,6 @@ const PERMISSION_MASKS = {
"change-privatebrowsing": AddonManager.PERM_CAN_CHANGE_PRIVATEBROWSING_ACCESS,
};
const PREF_TELEMETRY_ENABLED = "datareporting.healthreport.uploadEnabled";
const PRIVATE_BROWSING_PERM_NAME = "internal:privateBrowsingAllowed";
const PRIVATE_BROWSING_PERMS = {
permissions: [PRIVATE_BROWSING_PERM_NAME],
@ -152,14 +142,6 @@ const AddonCardListenerHandler = {
},
};
function isAbuseReportSupported(addon) {
return (
ABUSE_REPORT_ENABLED &&
["extension", "theme"].includes(addon.type) &&
!(addon.isBuiltin || addon.isSystem)
);
}
async function isAllowedInPrivateBrowsing(addon) {
// Use the Promise directly so this function stays sync for the other case.
let perms = await ExtensionPermissions.get(addon.id);
@ -202,13 +184,6 @@ async function getAddonMessageInfo(addon) {
message: formatString("blocked", [name]),
type: "error",
};
} else if (isDisabledUnsigned(addon)) {
return {
linkText: getString("unsigned.link"),
linkUrl: SUPPORT_URL + "unsigned-addons",
message: formatString("unsignedAndDisabled", [name, appName]),
type: "error",
};
} else if (
!addon.isCompatible &&
(AddonManager.checkCompatibility ||
@ -751,13 +726,9 @@ class AddonOptions extends HTMLElement {
case "remove":
el.hidden = !hasPermission(addon, "uninstall");
break;
case "report":
el.hidden = !isAbuseReportSupported(addon);
break;
case "toggle-disabled": {
let toggleDisabledAction = addon.userDisabled ? "enable" : "disable";
document.l10n.setAttributes(el, `${toggleDisabledAction}-addon-button`);
el.hidden = !hasPermission(addon, toggleDisabledAction);
break;
}
case "install-update":
@ -822,67 +793,6 @@ class PluginOptions extends AddonOptions {
}
customElements.define("plugin-options", PluginOptions);
class FiveStarRating extends HTMLElement {
static get observedAttributes() {
return ["rating"];
}
constructor() {
super();
this.attachShadow({ mode: "open" });
this.shadowRoot.append(importTemplate("five-star-rating"));
}
set rating(v) {
this.setAttribute("rating", v);
}
get rating() {
let v = parseFloat(this.getAttribute("rating"), 10);
if (v >= 0 && v <= 5) {
return v;
}
return 0;
}
get ratingBuckets() {
// 0 <= x < 0.25 = empty
// 0.25 <= x < 0.75 = half
// 0.75 <= x <= 1 = full
// ... et cetera, until x <= 5.
let { rating } = this;
return [0, 1, 2, 3, 4].map(ratingStart => {
let distanceToFull = rating - ratingStart;
if (distanceToFull < 0.25) {
return "empty";
}
if (distanceToFull < 0.75) {
return "half";
}
return "full";
});
}
connectedCallback() {
this.renderRating();
}
attributeChangedCallback() {
this.renderRating();
}
renderRating() {
let starElements = this.shadowRoot.querySelectorAll(".rating-star");
for (let [i, part] of this.ratingBuckets.entries()) {
starElements[i].setAttribute("fill", part);
}
document.l10n.setAttributes(this, "five-star-rating", {
rating: this.rating,
});
}
}
customElements.define("five-star-rating", FiveStarRating);
class ContentSelectDropdown extends HTMLElement {
connectedCallback() {
if (this.children.length > 0) {
@ -1231,12 +1141,6 @@ class AddonDetails extends HTMLElement {
if (e.type == "view-changed" && e.target == this.deck) {
switch (this.deck.selectedViewName) {
case "release-notes":
AMTelemetry.recordActionEvent({
object: "aboutAddons",
view: getTelemetryViewName(this),
action: "releaseNotes",
addon: this.addon,
});
let releaseNotes = this.querySelector("update-release-notes");
let uri = this.releaseNotesUri;
if (uri) {
@ -1339,10 +1243,10 @@ class AddonDetails extends HTMLElement {
this.querySelector(
".addon-detail-contribute"
).hidden = !addon.contributionURL;
this.querySelector(".addon-detail-row-updates").hidden = !hasPermission(
/*this.querySelector(".addon-detail-row-updates").hidden = !hasPermission(
addon,
"upgrade"
);
);*/
// By default, all private browsing rows are hidden. Possibly show one.
if (allowPrivateBrowsingByDefault || addon.type != "extension") {
@ -1419,19 +1323,6 @@ class AddonDetails extends HTMLElement {
homepageRow.hidden = true;
}
// Rating.
let ratingRow = this.querySelector(".addon-detail-row-rating");
if (addon.averageRating) {
ratingRow.querySelector("five-star-rating").rating = addon.averageRating;
let reviews = ratingRow.querySelector("a");
reviews.href = addon.reviewURL;
document.l10n.setAttributes(reviews, "addon-detail-reviews-link", {
numberOfReviews: addon.reviewCount,
});
} else {
ratingRow.hidden = true;
}
this.update();
}
@ -1526,7 +1417,6 @@ class AddonCard extends HTMLElement {
if (e.type == "click") {
switch (action) {
case "toggle-disabled":
this.recordActionEvent(addon.userDisabled ? "enable" : "disable");
if (addon.userDisabled) {
if (shouldShowPermissionsPrompt(addon)) {
await showPermissionsPrompt(addon);
@ -1547,15 +1437,12 @@ class AddonCard extends HTMLElement {
}
break;
case "always-activate":
this.recordActionEvent("enable");
addon.userDisabled = false;
break;
case "never-activate":
this.recordActionEvent("disable");
addon.userDisabled = true;
break;
case "update-check":
this.recordActionEvent("checkForUpdate");
let listener = {
onUpdateAvailable(addon, install) {
attachUpdateHandler(install);
@ -1584,7 +1471,6 @@ class AddonCard extends HTMLElement {
this.updateInstall = null;
break;
case "contribute":
this.recordActionEvent("contribute");
// prettier-ignore
windowRoot.ownerGlobal.openUILinkIn(addon.contributionURL, "tab", {
triggeringPrincipal:
@ -1595,10 +1481,8 @@ class AddonCard extends HTMLElement {
break;
case "preferences":
if (getOptionsType(addon) == "tab") {
this.recordActionEvent("preferences", "external");
openOptionsInTab(addon.optionsURL);
} else if (getOptionsType(addon) == "inline") {
this.recordActionEvent("preferences", "inline");
loadViewFn(`detail/${this.addon.id}/preferences`, e);
}
break;
@ -1610,16 +1494,9 @@ class AddonCard extends HTMLElement {
report,
} = windowRoot.ownerGlobal.promptRemoveExtension(addon);
let value = remove ? "accepted" : "cancelled";
this.recordActionEvent("uninstall", value);
if (remove) {
await addon.uninstall(true);
this.sendEvent("remove");
if (report) {
openAbuseReport({
addonId: addon.id,
reportEntryPoint: "uninstall",
});
}
} else {
this.sendEvent("remove-cancelled");
}
@ -1634,10 +1511,6 @@ class AddonCard extends HTMLElement {
this.panel.toggle(e);
}
break;
case "report":
this.panel.hide();
openAbuseReport({ addonId: addon.id, reportEntryPoint: "menu" });
break;
case "link":
if (e.target.getAttribute("url")) {
windowRoot.ownerGlobal.openWebLinkIn(
@ -1656,30 +1529,14 @@ class AddonCard extends HTMLElement {
// Handle a click on the card itself.
if (!this.expanded) {
loadViewFn(`detail/${this.addon.id}`, e);
} else if (
e.target.localName == "a" &&
e.target.getAttribute("data-telemetry-name")
) {
let value = e.target.getAttribute("data-telemetry-name");
AMTelemetry.recordLinkEvent({
object: "aboutAddons",
addon,
value,
extra: {
view: getTelemetryViewName(this),
},
});
}
break;
}
} else if (e.type == "change") {
let { name } = e.target;
let telemetryValue = e.target.getAttribute("data-telemetry-value");
if (name == "autoupdate") {
this.recordActionEvent("setAddonUpdate", telemetryValue);
addon.applyBackgroundUpdates = e.target.value;
} else if (name == "private-browsing") {
this.recordActionEvent("privateBrowsingAllowed", telemetryValue);
let policy = WebExtensionPolicy.getByID(addon.id);
let extension = policy && policy.extension;
@ -1961,16 +1818,6 @@ class AddonCard extends HTMLElement {
sendEvent(name, detail) {
this.dispatchEvent(new CustomEvent(name, { detail }));
}
recordActionEvent(action, value) {
AMTelemetry.recordActionEvent({
object: "aboutAddons",
view: getTelemetryViewName(this),
action,
addon: this.addon,
value,
});
}
}
customElements.define("addon-card", AddonCard);
@ -2118,15 +1965,6 @@ class AddonList extends HTMLElement {
message.append(addonName);
const undo = document.createElement("button");
undo.setAttribute("action", "undo");
undo.addEventListener("click", () => {
AMTelemetry.recordActionEvent({
object: "aboutAddons",
view: getTelemetryViewName(this),
action: "undo",
addon,
});
addon.cancelUninstall();
});
document.l10n.setAttributes(message, "pending-uninstall-description", {
addon: addon.name,
@ -2454,17 +2292,6 @@ class UpdatesView {
// Generic view management.
let mainEl = null;
/**
* The name of the view for an element, used for telemetry.
*
* @param {Element} el The element to find the view from. A parent of the
* element must define a current-view property.
* @returns {string} The current view name.
*/
function getTelemetryViewName(el) {
return el.closest("[current-view]").getAttribute("current-view");
}
/**
* Called from extensions.js once, when about:addons is loading.
*/

View File

@ -6,7 +6,7 @@
"use strict";
/* exported attachUpdateHandler, gBrowser, getBrowserElement, isCorrectlySigned,
* isDisabledUnsigned, loadReleaseNotes, openOptionsInTab,
* loadReleaseNotes, openOptionsInTab,
* promiseEvent, shouldShowPermissionsPrompt, showPermissionsPrompt */
const { AddonSettings } = ChromeUtils.import(
@ -69,10 +69,6 @@ function attachUpdateHandler(install) {
type: "update",
addon: info.addon,
icon: info.addon.icon,
// Reference to the related AddonInstall object (used in
// AMTelemetry to link the recorded event to the other events from
// the same install flow).
install,
permissions: difference,
resolve,
reject,
@ -191,11 +187,3 @@ function isCorrectlySigned(addon) {
// they aren't the correct type for signing.
return addon.isCorrectlySigned !== false;
}
function isDisabledUnsigned(addon) {
let signingRequired =
addon.type == "locale"
? AddonSettings.LANGPACKS_REQUIRE_SIGNING
: AddonSettings.REQUIRE_SIGNING;
return signingRequired && !isCorrectlySigned(addon);
}

View File

@ -1,135 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="chrome://global/skin/in-content/common.css">
<link rel="stylesheet" href="chrome://mozapps/content/extensions/aboutaddons.css">
<link rel="stylesheet" href="chrome://mozapps/content/extensions/abuse-report-panel.css">
<link rel="localization" href="branding/brand.ftl">
<link rel="localization" href="toolkit/about/aboutAddons.ftl">
<link rel="localization" href="toolkit/about/abuseReports.ftl">
<script src="chrome://mozapps/content/extensions/abuse-report-panel.js"></script>
</head>
<body>
<!-- WebComponents Templates -->
<template id="tmpl-abuse-report">
<div class="modal-overlay-outer"></div>
<div class="modal-panel-container">
<form class="card addon-abuse-report" onsubmit="return false;">
<div class="abuse-report-header">
<img class="card-heading-icon addon-icon"/>
<div class="card-contents">
<span class="addon-name"></span>
<span class="addon-author-box"
data-l10n-args='{"author-name": "author placeholder"}'
data-l10n-id="abuse-report-addon-authored-by">
<a data-l10n-name="author-name"
class="author" href="#" target="_blank"></a>
</span>
</div>
</div>
<button class="abuse-report-close-icon"></button>
<div class="abuse-report-contents">
<abuse-report-reasons-panel></abuse-report-reasons-panel>
<abuse-report-submit-panel hidden></abuse-report-submit-panel>
</div>
<div class="abuse-report-buttons">
<div class="abuse-report-reasons-buttons">
<button class="abuse-report-cancel"
data-l10n-id="abuse-report-cancel-button">
</button>
<button class="primary abuse-report-next"
data-l10n-id="abuse-report-next-button">
</button>
</div>
<div class="abuse-report-submit-buttons" hidden>
<button class="abuse-report-goback"
data-l10n-id="abuse-report-goback-button">
</button>
<button class="primary abuse-report-submit"
data-l10n-id="abuse-report-submit-button">
</button>
</div>
</div>
</form>
</div>
</template>
<template id="tmpl-reasons-panel">
<h2 class="abuse-report-title"></h2>
<hr>
<p class="abuse-report-subtitle"
data-l10n-id="abuse-report-subtitle">
</p>
<ul class="abuse-report-reasons">
<li is="abuse-report-reason-listitem" report-reason="other"></li>
</ul>
<p data-l10n-id="abuse-report-learnmore">
<a class="abuse-report-learnmore" target="_blank"
data-l10n-name="learnmore-link">
</a>
</p>
</template>
<template id="tmpl-submit-panel">
<h2 class="abuse-reason-title"></h2>
<abuse-report-reason-suggestions></abuse-report-reason-suggestions>
<hr>
<p class="abuse-report-subtitle" data-l10n-id="abuse-report-submit-description">
</p>
<textarea name="message" data-l10n-id="abuse-report-textarea"></textarea>
<p class="abuse-report-note" data-l10n-id="abuse-report-submit-note">
</p>
</template>
<template id="tmpl-reason-listitem">
<label>
<input type="radio" name="reason" class="radio">
<span class="reason-description"></span>
<span hidden class="abuse-report-note reason-example"></span>
</label>
</template>
<template id="tmpl-suggestions-settings">
<p data-l10n-id="abuse-report-settings-suggestions"><p>
<ul>
<li>
<a class="abuse-settings-search-learnmore" target="_blank"
data-l10n-id="abuse-report-settings-suggestions-search">
</a>
</li>
<li>
<a class="abuse-settings-homepage-learnmore" target="_blank"
data-l10n-id="abuse-report-settings-suggestions-homepage">
</a>
</li>
</ul>
</template>
<template id="tmpl-suggestions-policy">
<p data-l10n-id="abuse-report-policy-suggestions">
<a class="abuse-policy-learnmore" target="_blank"
data-l10n-name="report-infringement-link">
</a>
</p>
</template>
<template id="tmpl-suggestions-broken-extension">
<p data-l10n-id="abuse-report-broken-suggestions-extension">
<a class="extension-support-link" target="_blank"
data-l10n-name="support-link">
</a>
<p>
</template>
<template id="tmpl-suggestions-broken-theme">
<p data-l10n-id="abuse-report-broken-suggestions-theme">
<a class="extension-support-link" target="_blank"
data-l10n-name="support-link">
</a>
<p>
</template>
</body>
</html>

View File

@ -1,283 +0,0 @@
"use strict";
/* globals MozXULElement, Services, useHtmlViews, getHtmlBrowser, htmlBrowserLoaded */
{
const ABUSE_REPORT_ENABLED = Services.prefs.getBoolPref(
"extensions.abuseReport.enabled",
false
);
const ABUSE_REPORT_FRAME_URL =
"chrome://mozapps/content/extensions/abuse-report-frame.html";
const fm = Services.focus;
const { AbuseReporter } = ChromeUtils.import(
"resource://gre/modules/AbuseReporter.jsm"
);
class AddonAbuseReportsXULFrame extends MozXULElement {
constructor() {
super();
this.report = null;
// Keep track if the loadURI has already been called on the
// browser element.
this.browserLoadURI = false;
}
connectedCallback() {
this.textContent = "";
const content = MozXULElement.parseXULToFragment(`
<browser id="abuse-report-xulframe-overlay-inner"
type="content"
disablehistory="true"
transparent="true"
flex="1">
</browser>
`);
this.appendChild(content);
const browser = this.querySelector("browser");
this.promiseBrowserLoaded = new Promise(resolve => {
browser.addEventListener("load", () => resolve(browser), {
once: true,
});
});
document.addEventListener("focus", this);
this.promiseHtmlAboutAddons.then(win => {
win.document.addEventListener("abuse-report:new", this);
});
this.update();
}
disconnectedCallback() {
this.textContent = "";
this.browserLoadURI = false;
this.promiseBrowserLoaded = null;
this.report = null;
document.removeEventListener("focus", this);
this.promiseHtmlAboutAddons.then(win => {
win.document.removeEventListener("abuse-report:new", this);
});
}
handleEvent(evt) {
// The "abuse-report:new" events are dispatched from the html about:addons sub-frame
// (on the html about:addons document).
// "abuse-report:cancel", "abuse-report:submit" and "abuse-report:updated" are
// all dispatched from the AbuseReport webcomponent (on the AbuseReport element itself).
// All the "abuse-report:*" events are also forwarded (dispatched on the frame
// DOM element itself) to make it easier for the tests to wait for certain conditions
// to be reached.
switch (evt.type) {
case "focus":
this.focus();
break;
case "abuse-report:new":
this.openReport(evt.detail);
this.forwardEvent(evt);
break;
case "abuse-report:cancel":
this.cancelReport();
this.forwardEvent(evt);
break;
case "abuse-report:submit":
this.onSubmitReport(evt);
this.forwardEvent(evt);
break;
case "abuse-report:updated":
this.forwardEvent(evt);
break;
}
}
forwardEvent(evt) {
this.dispatchEvent(new CustomEvent(evt.type, { detail: evt.detail }));
}
async openReport({ addonId, reportEntryPoint }) {
if (this.report) {
throw new Error(
"Ignoring new abuse report request. AbuseReport panel already open"
);
} else {
try {
this.report = await AbuseReporter.createAbuseReport(addonId, {
reportEntryPoint,
});
this.update();
} catch (err) {
// Log the complete error in the console.
console.error("Error creating abuse report for", addonId, err);
// The report has an error on creation, and so instead of opening the report
// panel an error message-bar is created on the HTML about:addons page.
const win = await this.promiseHtmlAboutAddons;
win.document.dispatchEvent(
new CustomEvent("abuse-report:create-error", {
detail: {
addonId,
addon: err.addon,
errorType: err.errorType,
},
})
);
}
}
}
cancelReport() {
if (this.report) {
this.report.abort();
this.report = null;
this.update();
}
}
async onSubmitReport(evt) {
if (this.report) {
this.report = null;
this.update();
const win = await this.promiseHtmlAboutAddons;
win.document.dispatchEvent(evt);
}
}
focus() {
// Trap the focus in the abuse report modal while it is enabled.
if (this.hasAddonId) {
this.promiseAbuseReport.then(abuseReport => {
abuseReport.focus();
});
}
}
async update() {
const { report } = this;
if (report && report.addon && !report.errorType) {
const { addon, reportEntryPoint } = this.report;
this.addonId = addon.id;
this.reportEntryPoint = reportEntryPoint;
// Set the addon id on the addon-abuse-report webcomponent instance
// embedded in the XUL browser.
this.promiseAbuseReport.then(abuseReport => {
this.hidden = false;
abuseReport.addEventListener("abuse-report:updated", this, {
once: true,
});
abuseReport.addEventListener("abuse-report:submit", this, {
once: true,
});
abuseReport.addEventListener("abuse-report:cancel", this, {
once: true,
});
abuseReport.setAbuseReport(report);
// Hide the content of the underlying about:addons page from
// screen readers.
this.aboutAddonsContent.setAttribute("aria-hidden", true);
// Move the focus to the embedded window.
this.focus();
this.dispatchEvent(new CustomEvent("abuse-report:frame-shown"));
});
} else {
this.hidden = true;
this.removeAttribute("addon-id");
this.removeAttribute("report-entry-point");
// Make the content of the underlying about:addons page visible
// to screen readers.
this.aboutAddonsContent.setAttribute("aria-hidden", false);
// Move the focus back to the top level window.
fm.moveFocus(window, null, fm.MOVEFOCUS_ROOT, fm.FLAG_BYKEY);
this.promiseAbuseReport
.then(
abuseReport => {
abuseReport.removeEventListener("abuse-report:updated", this, {
once: true,
});
abuseReport.removeEventListener("abuse-report:submit", this, {
once: true,
});
abuseReport.removeEventListener("abuse-report:cancel", this, {
once: true,
});
abuseReport.setAbuseReport(null);
},
err => {
console.error("promiseAbuseReport rejected", err);
}
)
.then(() => {
this.dispatchEvent(new CustomEvent("abuse-report:frame-hidden"));
});
}
}
get aboutAddonsContent() {
return document.getElementById("main-page-content");
}
get promiseAbuseReport() {
if (!this.browserLoadURI) {
const browser = this.querySelector("browser");
browser.loadURI(ABUSE_REPORT_FRAME_URL, {
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
});
this.browserLoadURI = true;
}
return this.promiseBrowserLoaded.then(browser => {
return browser.contentDocument.querySelector("addon-abuse-report");
});
}
get promiseHtmlAboutAddons() {
const browser = getHtmlBrowser();
return htmlBrowserLoaded.then(() => {
return browser.contentWindow;
});
}
get hasAddonId() {
return !!this.addonId;
}
get addonId() {
return this.getAttribute("addon-id");
}
set addonId(value) {
this.setAttribute("addon-id", value);
}
get reportEntryPoint() {
return this.getAttribute("report-entry-point");
}
set reportEntryPoint(value) {
this.setAttribute("report-entry-point", value);
}
}
// If the html about:addons and the abuse report are both enabled, register
// the custom XUL WebComponent and append it to the XUL stack element
// (if not registered the element will be just a dummy hidden box)
if (useHtmlViews && ABUSE_REPORT_ENABLED) {
customElements.define(
"addon-abuse-report-xulframe",
AddonAbuseReportsXULFrame
);
}
// Helper method exported into the about:addons global, used to open the
// abuse report panel from outside of the about:addons page
// (e.g. triggered from the browserAction context menu).
window.openAbuseReport = ({ addonId, reportEntryPoint }) => {
const frame = document.querySelector("addon-abuse-report-xulframe");
frame.openReport({ addonId, reportEntryPoint });
};
}

View File

@ -1,217 +0,0 @@
/* Abuse Reports card */
:root {
--close-icon-url: url("chrome://global/skin/icons/close.svg");
--close-icon-size: 20px;
--radio-image-url: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3E %3Ccircle cx='8' cy='8' r='4' fill='%23fff'/%3E %3C/svg%3E");
--radio-size: 16px;
--modal-panel-min-width: 60%;
--modal-panel-margin-top: 36px;
--modal-panel-margin-bottom: 36px;
--modal-panel-margin: 20%;
--modal-panel-padding: 40px;
--line-height: 20px;
--textarea-height: 220px;
--button-padding: 52px;
--listitem-padding-bottom: 14px;
--list-radio-column-size: 28px;
--note-font-size: 14px;
--note-font-weight: 400;
--subtitle-font-size: 16px;
--subtitle-font-weight: 600;
--input-radio-border: var(--in-content-box-border-color);
--input-radio-background: var(--grey-90-a10);
--input-radio-background-hover: var(--grey-90-a20);
--input-radio-background-active: var(--grey-90-a30);
--input-radio-background-selected: var(--blue-60);
--input-radio-background-selected-hover: var(--blue-70);
--input-radio-background-selected-active: var(--blue-80);
--input-radio-focus-shadow: 0 0 0 1px #0a84ff inset, 0 0 0 1px #0a84ff, 0 0 0 4px rgba(10, 132, 255, 0.3);
}
@supports -moz-bool-pref("browser.in-content.dark-mode") {
@media (prefers-color-scheme: dark) {
:root {
--input-radio-background: #202023;
--input-radio-background-hover: #303033;
--input-radio-background-active: #404044;
}
}
}
/* Ensure that the document (embedded in the XUL about:addons using a
XUL browser) has a transparent background */
html {
background-color: transparent;
}
.modal-overlay-outer {
background: var(--grey-90-a60);
width: 100%;
height: 100%;
position: fixed;
z-index: -1;
}
.modal-panel-container {
padding-top: var(--modal-panel-margin-top);
padding-bottom: var(--modal-panel-margin-bottom);
padding-left: var(--modal-panel-margin);
padding-right: var(--modal-panel-margin);
}
.addon-abuse-report {
min-width: var(--modal-panel-min-width);
padding: var(--modal-panel-padding);
display: flex;
flex-direction: column;
position: relative;
}
.addon-abuse-report:hover {
/* Avoid the card box highlighting on hover. */
box-shadow: none;
}
.addon-abuse-report button {
padding: 0 var(--button-padding);
}
.abuse-report-close-icon {
/* position the close button in the panel upper-right corner */
position: absolute;
top: 12px;
inset-inline-end: 16px;
}
button.abuse-report-close-icon {
background: var(--close-icon-url) no-repeat center center;
-moz-context-properties: fill, fill-opacity;
color: inherit !important;
fill: currentColor;
fill-opacity: 0;
min-width: auto;
min-height: auto;
width: var(--close-icon-size);
height: var(--close-icon-size);
margin: 0;
padding: 0;
}
button.abuse-report-close-icon:hover {
fill-opacity: 0.1;
}
button.abuse-report-close-icon:hover:active {
fill-opacity: 0.2;
}
.abuse-report-header {
display: flex;
flex-direction: row;
}
.abuse-report-contents,
.abuse-report-contents > hr {
width: 100%;
}
.abuse-report-note {
color: var(--in-content-deemphasized-text);
font-size: var(--note-font-size);
font-weight: var(--note-font-weight);
line-height: var(--line-height);
}
.abuse-report-subtitle {
font-size: var(--subtitle-font-size);
font-weight: var(--subtitle-font-weight);
line-height: var(--line-height);
}
ul.abuse-report-reasons {
list-style-type: none;
padding-inline-start: 0;
}
ul.abuse-report-reasons > li {
display: flex;
padding-bottom: var(--listitem-padding-bottom);
}
ul.abuse-report-reasons > li > label {
width: 100%;
line-height: var(--line-height);
font-size: var(--subtitle-font-size);
font-weight: var(--note-font-weight);
}
ul.abuse-report-reasons > li > label {
display: grid;
grid-template-columns: var(--list-radio-column-size) auto;
grid-template-rows: 50% auto;
}
ul.abuse-report-reasons > li > label > [type=radio] {
grid-column: 1;
}
ul.abuse-report-reasons > li > label > span {
grid-column: 2;
}
ul.abuse-report-reasons > li > label > span:nth-child(2) {
padding-top: 2px;
}
.abuse-report-contents [type=radio] {
-moz-appearance: none;
height: var(--radio-size);
width: var(--radio-size);
border-radius: 100%;
border: 1px solid var(--input-radio-border);
background-color: var(--input-radio-background);
margin-inline-start: 4px;
margin-inline-end: 4px;
}
.abuse-report-contents [type=radio]:focus {
border: none;
box-shadow: var(--input-radio-focus-shadow);
}
.abuse-report-contents label:hover [type=radio]:not(:active),
.abuse-report-contents [type=radio]:hover {
background-color: var(--input-radio-background-hover);
}
.abuse-report-contents [type=radio]:active {
background-color: var(--input-radio-background-active);
}
.abuse-report-contents [type=radio]:checked {
background-image: var(--radio-image-url);
background-color: var(--input-radio-background-selected);
background-position: center center;
}
.abuse-report-contents label:hover [type=radio]:checked:not(:active),
.abuse-report-contents [type=radio]:checked:hover {
background-color: var(--input-radio-background-selected-hover);
}
.abuse-report-contents [type=radio]:checked:active {
background-color: var(--input-radio-background-selected-active);
}
abuse-report-submit-panel textarea {
width: 100%;
height: var(--textarea-height);
resize: none;
box-sizing: border-box;
}

View File

@ -1,730 +0,0 @@
/* 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/. */
/* eslint max-len: ["error", 80] */
"use strict";
ChromeUtils.defineModuleGetter(
this,
"Services",
"resource://gre/modules/Services.jsm"
);
const showOnAnyType = () => false;
const hideOnAnyType = () => true;
const hideOnThemeType = addonType => addonType === "theme";
// The reasons string used as a key in this Map is expected to stay in sync
// with the reasons string used in the "abuseReports.ftl" locale file and
// the suggestions templates included in abuse-reports-xulframe.html.
const ABUSE_REASONS = (window.ABUSE_REPORT_REASONS = {
damage: {
isExampleHidden: showOnAnyType,
isReasonHidden: hideOnThemeType,
},
spam: {
isExampleHidden: showOnAnyType,
isReasonHidden: showOnAnyType,
},
settings: {
hasSuggestions: true,
isExampleHidden: hideOnAnyType,
isReasonHidden: hideOnThemeType,
},
deceptive: {
isExampleHidden: showOnAnyType,
isReasonHidden: showOnAnyType,
},
broken: {
hasAddonTypeL10nId: true,
hasAddonTypeSuggestionTemplate: true,
hasSuggestions: true,
isExampleHidden: hideOnThemeType,
isReasonHidden: showOnAnyType,
},
policy: {
hasSuggestions: true,
isExampleHidden: hideOnAnyType,
isReasonHidden: showOnAnyType,
},
unwanted: {
isExampleHidden: showOnAnyType,
isReasonHidden: hideOnThemeType,
},
other: {
isExampleHidden: hideOnAnyType,
isReasonHidden: showOnAnyType,
},
});
function getReasonL10nId(reason, addonType) {
let l10nId = `abuse-report-${reason}-reason`;
// Special case reasons that have a addonType-specific
// l10n id.
if (ABUSE_REASONS[reason].hasAddonTypeL10nId) {
l10nId += `-${addonType}`;
}
return l10nId;
}
function getSuggestionsTemplate(reason, addonType) {
const reasonInfo = ABUSE_REASONS[reason];
if (!reasonInfo.hasSuggestions) {
return null;
}
let templateId = `tmpl-suggestions-${reason}`;
// Special case reasons that have a addonType-specific
// suggestion template.
if (reasonInfo.hasAddonTypeSuggestionTemplate) {
templateId += `-${addonType}`;
}
return document.getElementById(templateId);
}
// Map of the learnmore links metadata, keyed by link element class.
const LEARNMORE_LINKS = {
".abuse-report-learnmore": {
path: "reporting-extensions-and-themes-abuse",
},
".abuse-settings-search-learnmore": {
path: "prefs-search",
},
".abuse-settings-homepage-learnmore": {
path: "prefs-homepage",
},
".abuse-policy-learnmore": {
baseURL: "https://www.mozilla.org/%LOCALE%/",
path: "about/legal/report-infringement/",
},
};
// Format links that match the selector in the LEARNMORE_LINKS map
// found in a given container element.
function formatLearnMoreURLs(containerEl) {
for (const [linkClass, linkInfo] of Object.entries(LEARNMORE_LINKS)) {
for (const element of containerEl.querySelectorAll(linkClass)) {
const baseURL = linkInfo.baseURL
? Services.urlFormatter.formatURL(linkInfo.baseURL)
: Services.urlFormatter.formatURLPref("app.support.baseURL");
element.href = baseURL + linkInfo.path;
}
}
}
// Define a set of getters from a Map<propertyName, selector>.
function defineElementSelectorsGetters(object, propsMap) {
const props = Object.entries(propsMap).reduce((acc, entry) => {
const [name, selector] = entry;
acc[name] = { get: () => object.querySelector(selector) };
return acc;
}, {});
Object.defineProperties(object, props);
}
// Define a set of properties getters and setters for a
// Map<propertyName, attributeName>.
function defineElementAttributesProperties(object, propsMap) {
const props = Object.entries(propsMap).reduce((acc, entry) => {
const [name, attr] = entry;
acc[name] = {
get: () => object.getAttribute(attr),
set: value => {
object.setAttribute(attr, value);
},
};
return acc;
}, {});
Object.defineProperties(object, props);
}
// Return an object with properties associated to elements
// found using the related selector in the propsMap.
function getElements(containerEl, propsMap) {
return Object.entries(propsMap).reduce((acc, entry) => {
const [name, selector] = entry;
let elements = containerEl.querySelectorAll(selector);
acc[name] = elements.length > 1 ? elements : elements[0];
return acc;
}, {});
}
function dispatchCustomEvent(el, eventName, detail) {
el.dispatchEvent(new CustomEvent(eventName, { detail }));
}
// This WebComponent extends the li item to represent an abuse report reason
// and it is responsible for:
// - embedding a photon styled radio buttons
// - localizing the reason list item
// - optionally embedding a localized example, positioned
// below the reason label, and adjusts the item height
// accordingly
class AbuseReasonListItem extends HTMLLIElement {
constructor() {
super();
defineElementAttributesProperties(this, {
addonType: "addon-type",
reason: "report-reason",
checked: "checked",
});
}
connectedCallback() {
this.update();
}
async update() {
if (this.reason !== "other" && !this.addonType) {
return;
}
const { reason, checked, addonType } = this;
this.textContent = "";
const content = document.importNode(this.template.content, true);
if (reason) {
const reasonId = `abuse-reason-${reason}`;
const reasonInfo = ABUSE_REASONS[reason] || {};
const { labelEl, descriptionEl, radioEl } = getElements(content, {
labelEl: "label",
descriptionEl: ".reason-description",
radioEl: "input[type=radio]",
});
labelEl.setAttribute("for", reasonId);
radioEl.id = reasonId;
radioEl.value = reason;
radioEl.checked = !!checked;
// This reason has a different localized description based on the
// addon type.
document.l10n.setAttributes(
descriptionEl,
getReasonL10nId(reason, addonType)
);
// Show the reason example if supported for the addon type.
if (!reasonInfo.isExampleHidden(addonType)) {
const exampleEl = content.querySelector(".reason-example");
document.l10n.setAttributes(
exampleEl,
`abuse-report-${reason}-example`
);
exampleEl.hidden = false;
}
}
formatLearnMoreURLs(content);
this.appendChild(content);
}
get template() {
return document.getElementById("tmpl-reason-listitem");
}
}
// This WebComponents implements the first step of the abuse
// report submission and embeds a randomized reasons list.
class AbuseReasonsPanel extends HTMLElement {
constructor() {
super();
defineElementAttributesProperties(this, {
addonType: "addon-type",
});
}
connectedCallback() {
this.update();
}
update() {
if (!this.isConnected || !this.addonType) {
return;
}
const { addonType } = this;
this.textContent = "";
const content = document.importNode(this.template.content, true);
const { titleEl, listEl } = getElements(content, {
titleEl: ".abuse-report-title",
listEl: "ul.abuse-report-reasons",
});
// Change the title l10n-id if the addon type is theme.
document.l10n.setAttributes(titleEl, `abuse-report-title-${addonType}`);
// Create the randomized list of reasons.
const reasons = Object.keys(ABUSE_REASONS)
.filter(reason => reason !== "other")
.sort(() => Math.random() - 0.5);
for (const reason of reasons) {
const reasonInfo = ABUSE_REASONS[reason];
if (!reasonInfo || reasonInfo.isReasonHidden(addonType)) {
// Skip an extension only reason while reporting a theme.
continue;
}
const item = document.createElement("li", {
is: "abuse-report-reason-listitem",
});
item.reason = reason;
item.addonType = addonType;
listEl.prepend(item);
}
listEl.firstElementChild.checked = true;
formatLearnMoreURLs(content);
this.appendChild(content);
}
get template() {
return document.getElementById("tmpl-reasons-panel");
}
}
// This WebComponent is responsible for the suggestions, which are:
// - generated based on a template keyed by abuse report reason
// - localized by assigning fluent ids generated from the abuse report reason
// - learn more and extension support url are then generated when the
// specific reason expects it
class AbuseReasonSuggestions extends HTMLElement {
constructor() {
super();
defineElementAttributesProperties(this, {
extensionSupportURL: "extension-support-url",
reason: "report-reason",
});
}
update() {
const { addonType, extensionSupportURL, reason } = this;
if (!addonType) {
return;
}
this.textContent = "";
let template = getSuggestionsTemplate(reason, addonType);
if (template) {
let content = document.importNode(template.content, true);
formatLearnMoreURLs(content);
let extSupportLink = content.querySelector("a.extension-support-link");
if (extSupportLink) {
extSupportLink.href = extensionSupportURL;
}
this.appendChild(content);
this.hidden = false;
} else {
this.hidden = true;
}
}
get LEARNMORE_LINKS() {
return Object.keys(LEARNMORE_LINKS);
}
}
// This WebComponents implements the last step of the abuse report submission.
class AbuseSubmitPanel extends HTMLElement {
constructor() {
super();
defineElementAttributesProperties(this, {
addonType: "addon-type",
reason: "report-reason",
extensionSupportURL: "extensionSupportURL",
});
defineElementSelectorsGetters(this, {
_textarea: "textarea",
_title: ".abuse-reason-title",
_suggestions: "abuse-report-reason-suggestions",
});
}
connectedCallback() {
this.render();
}
render() {
this.textContent = "";
this.appendChild(document.importNode(this.template.content, true));
}
update() {
if (!this.isConnected || !this.addonType) {
return;
}
const { addonType, reason, _suggestions, _title } = this;
document.l10n.setAttributes(_title, getReasonL10nId(reason, addonType));
_suggestions.reason = reason;
_suggestions.addonType = addonType;
_suggestions.extensionSupportURL = this.extensionSupportURL;
_suggestions.update();
}
clear() {
this._textarea.value = "";
}
get template() {
return document.getElementById("tmpl-submit-panel");
}
}
// This WebComponent provides the abuse report
class AbuseReport extends HTMLElement {
constructor() {
super();
this._report = null;
defineElementSelectorsGetters(this, {
_form: "form",
_textarea: "textarea",
_radioCheckedReason: "[type=radio]:checked",
_reasonsPanel: "abuse-report-reasons-panel",
_submitPanel: "abuse-report-submit-panel",
_reasonsPanelButtons: ".abuse-report-reasons-buttons",
_submitPanelButtons: ".abuse-report-submit-buttons",
_iconClose: ".abuse-report-close-icon",
_btnNext: "button.abuse-report-next",
_btnCancel: "button.abuse-report-cancel",
_btnGoBack: "button.abuse-report-goback",
_btnSubmit: "button.abuse-report-submit",
_addonIconElement: ".abuse-report-header img.addon-icon",
_addonNameElement: ".abuse-report-header .addon-name",
_linkAddonAuthor: ".abuse-report-header .addon-author-box a.author",
});
}
connectedCallback() {
this.render();
this.addEventListener("click", this);
// Start listening to keydown events (to close the modal
// when Escape has been pressed and to handling the keyboard
// navigation).
document.addEventListener("keydown", this);
}
disconnectedCallback() {
this.textContent = "";
this.removeEventListener("click", this);
document.removeEventListener("keydown", this);
}
handleEvent(evt) {
if (!this.isConnected || !this.addon) {
return;
}
switch (evt.type) {
case "keydown":
if (evt.key === "Escape") {
// Prevent Esc to close the panel if the textarea is
// empty.
if (this.message && !this._submitPanel.hidden) {
return;
}
this.cancel();
}
this.handleKeyboardNavigation(evt);
break;
case "click":
if (evt.target === this._iconClose || evt.target === this._btnCancel) {
// NOTE: clear the focus on the clicked element to ensure that
// -moz-focusring pseudo class is not still set on the element
// when the panel is going to be shown again (See Bug 1560949).
evt.target.blur();
this.cancel();
}
if (evt.target === this._btnNext) {
this.switchToSubmitMode();
}
if (evt.target === this._btnGoBack) {
this.switchToListMode();
}
if (evt.target === this._btnSubmit) {
this.submit();
}
if (evt.target.localName === "a") {
evt.preventDefault();
evt.stopPropagation();
const url = evt.target.getAttribute("href");
// Ignore if url is empty.
if (url) {
window.windowRoot.ownerGlobal.openWebLinkIn(url, "tab", {
relatedToCurrent: true,
});
}
}
break;
}
}
handleKeyboardNavigation(evt) {
if (
evt.keyCode !== evt.DOM_VK_TAB ||
evt.altKey ||
evt.controlKey ||
evt.metaKey
) {
return;
}
const fm = Services.focus;
const backward = evt.shiftKey;
const isFirstFocusableElement = el => {
// Also consider the document body as a valid first focusable element.
if (el === document.body) {
return true;
}
// XXXrpl unfortunately there is no way to get the first focusable element
// without asking the focus manager to move focus to it (similar strategy
// is also being used in about:prefereces subdialog.js).
const rv = el == fm.moveFocus(window, null, fm.MOVEFOCUS_FIRST, 0);
fm.setFocus(el, 0);
return rv;
};
// If the focus is exiting the panel while navigating
// backward, focus the previous element sibling on the
// Firefox UI.
if (backward && isFirstFocusableElement(evt.target)) {
evt.preventDefault();
evt.stopImmediatePropagation();
const chromeWin = window.windowRoot.ownerGlobal;
Services.focus.moveFocus(
chromeWin,
null,
Services.MOVEFOCUS_BACKWARD,
Services.focus.FLAG_BYKEY
);
}
}
render() {
this.textContent = "";
this.appendChild(document.importNode(this.template.content, true));
}
async update() {
if (!this.addon) {
return;
}
const {
addonId,
_addonIconElement,
_addonNameElement,
_linkAddonAuthor,
_reasonsPanel,
_submitPanel,
} = this;
// Ensure that the first step of the abuse submission is the one
// currently visible.
this.switchToListMode();
// Cancel the abuse report if the addon is not an extension or theme.
if (!["extension", "theme"].includes(this.addonType)) {
this.cancel();
return;
}
_addonNameElement.textContent = this.addonName;
_linkAddonAuthor.href = this.authorURL || this.homepageURL;
_linkAddonAuthor.textContent = this.authorName;
document.l10n.setAttributes(
_linkAddonAuthor.parentNode,
"abuse-report-addon-authored-by",
{ "author-name": this.authorName }
);
_addonIconElement.setAttribute("src", this.iconURL);
_reasonsPanel.addonType = this.addonType;
_reasonsPanel.update();
_submitPanel.addonType = this.addonType;
_submitPanel.reason = this.reason;
_submitPanel.extensionSupportURL = this.supportURL;
_submitPanel.update();
this.focus();
dispatchCustomEvent(this, "abuse-report:updated", {
addonId,
panel: "reasons",
});
}
setAbuseReport(abuseReport) {
this._report = abuseReport;
// Clear the textarea from any previously entered content.
this._submitPanel.clear();
if (abuseReport) {
this.update();
this.hidden = false;
} else {
this.hidden = true;
}
}
focus() {
if (!this.isConnected || !this.addon) {
return;
}
if (this._reasonsPanel.hidden) {
const { _textarea } = this;
_textarea.focus();
_textarea.select();
} else {
const { _radioCheckedReason } = this;
if (_radioCheckedReason) {
_radioCheckedReason.focus();
}
}
}
cancel() {
if (!this.isConnected || !this.addon) {
return;
}
this._report = null;
dispatchCustomEvent(this, "abuse-report:cancel");
}
submit() {
if (!this.isConnected || !this.addon) {
return;
}
dispatchCustomEvent(this, "abuse-report:submit", {
addonId: this.addonId,
reason: this.reason,
message: this.message,
report: this._report,
});
}
switchToSubmitMode() {
if (!this.isConnected || !this.addon) {
return;
}
this._submitPanel.reason = this.reason;
this._submitPanel.update();
this._reasonsPanel.hidden = true;
this._reasonsPanelButtons.hidden = true;
this._submitPanel.hidden = false;
this._submitPanelButtons.hidden = false;
// Adjust the focused element when switching to the submit panel.
this.focus();
dispatchCustomEvent(this, "abuse-report:updated", {
addonId: this.addonId,
panel: "submit",
});
}
switchToListMode() {
if (!this.isConnected || !this.addon) {
return;
}
this._submitPanel.hidden = true;
this._submitPanelButtons.hidden = true;
this._reasonsPanel.hidden = false;
this._reasonsPanelButtons.hidden = false;
// Adjust the focused element when switching back to the list of reasons.
this.focus();
dispatchCustomEvent(this, "abuse-report:updated", {
addonId: this.addonId,
panel: "reasons",
});
}
get addon() {
return this._report && this._report.addon;
}
get addonId() {
return this.addon && this.addon.id;
}
get addonName() {
return this.addon && this.addon.name;
}
get addonType() {
return this.addon && this.addon.type;
}
get addonCreator() {
return this.addon && this.addon.creator;
}
get homepageURL() {
const { addon } = this;
return (addon && addon.homepageURL) || this.authorURL || "";
}
get authorName() {
// The author name may be missing on some of the test extensions
// (or for temporarily installed add-ons).
return (this.addonCreator && this.addonCreator.name) || "";
}
get authorURL() {
return (this.addonCreator && this.addonCreator.url) || "";
}
get iconURL() {
return this.addon && this.addon.iconURL;
}
get supportURL() {
return (this.addon && this.addon.supportURL) || this.homepageURL || "";
}
get message() {
return this._form.elements.message.value;
}
get reason() {
return this._form.elements.reason.value;
}
get template() {
return document.getElementById("tmpl-abuse-report");
}
}
customElements.define("abuse-report-reason-listitem", AbuseReasonListItem, {
extends: "li",
});
customElements.define(
"abuse-report-reason-suggestions",
AbuseReasonSuggestions
);
customElements.define("abuse-report-reasons-panel", AbuseReasonsPanel);
customElements.define("abuse-report-submit-panel", AbuseSubmitPanel);
customElements.define("addon-abuse-report", AbuseReport);
window.addEventListener(
"load",
() => {
document.body.prepend(document.createElement("addon-abuse-report"));
},
{ once: true }
);

View File

@ -1,252 +0,0 @@
/* 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/. */
/* eslint max-len: ["error", 80] */
/* exported openAbuseReport */
/**
* This script is part of the HTML about:addons page and it provides some
* helpers used for the Abuse Reporting submission (and related message bars).
*/
// Message Bars definitions.
const ABUSE_REPORT_MESSAGE_BARS = {
// Idle message-bar (used while the submission is still ongoing).
submitting: { id: "submitting", actions: ["cancel"] },
// Submitted report message-bar.
submitted: {
id: "submitted",
actionAddonTypeSuffix: true,
actions: ["remove", "keep"],
dismissable: true,
},
// Submitted report message-bar (with no remove actions).
"submitted-no-remove-action": {
id: "submitted-noremove",
dismissable: true,
},
// Submitted report and remove addon message-bar.
"submitted-and-removed": {
id: "removed",
addonTypeSuffix: true,
dismissable: true,
},
// The "aborted report" message bar is rendered as a generic informative one,
// because aborting a report is triggered by a user choice.
ERROR_ABORTED_SUBMIT: {
id: "aborted",
type: "generic",
dismissable: true,
},
// Errors message bars.
ERROR_ADDON_NOTFOUND: {
id: "error",
type: "error",
dismissable: true,
},
ERROR_CLIENT: {
id: "error",
type: "error",
dismissable: true,
},
ERROR_NETWORK: {
id: "error",
actions: ["retry", "cancel"],
type: "error",
},
ERROR_RECENT_SUBMIT: {
id: "error-recent-submit",
actions: ["retry", "cancel"],
type: "error",
},
ERROR_SERVER: {
id: "error",
actions: ["retry", "cancel"],
type: "error",
},
ERROR_UNKNOWN: {
id: "error",
actions: ["retry", "cancel"],
type: "error",
},
};
function openAbuseReport({ addonId, reportEntryPoint }) {
document.dispatchEvent(
new CustomEvent("abuse-report:new", {
detail: { addonId, reportEntryPoint },
})
);
}
// Helper function used to create abuse report message bars in the
// HTML about:addons page.
function createReportMessageBar(
definitionId,
{ addonId, addonName, addonType },
{ onclose, onaction } = {}
) {
const getMessageL10n = id => `abuse-report-messagebar-${id}`;
const getActionL10n = action => getMessageL10n(`action-${action}`);
const barInfo = ABUSE_REPORT_MESSAGE_BARS[definitionId];
if (!barInfo) {
throw new Error(`message-bar definition not found: ${definitionId}`);
}
const { id, dismissable, actions, type } = barInfo;
const messageEl = document.createElement("span");
// The message element includes an addon-name span (also filled by
// Fluent), which can be used to apply custom styles to the addon name
// included in the message bar (if needed).
const addonNameEl = document.createElement("span");
addonNameEl.setAttribute("data-l10n-name", "addon-name");
messageEl.append(addonNameEl);
document.l10n.setAttributes(
messageEl,
getMessageL10n(barInfo.addonTypeSuffix ? `${id}-${addonType}` : id),
{ "addon-name": addonName || addonId }
);
const barActions = actions
? actions.map(action => {
// Some of the message bars require a different per addonType
// Fluent id for their actions.
const actionId = barInfo.actionAddonTypeSuffix
? `${action}-${addonType}`
: action;
const buttonEl = document.createElement("button");
buttonEl.addEventListener("click", () => onaction && onaction(action));
document.l10n.setAttributes(buttonEl, getActionL10n(actionId));
return buttonEl;
})
: [];
const messagebar = document.createElement("message-bar");
messagebar.setAttribute("type", type || "generic");
if (dismissable) {
messagebar.setAttribute("dismissable", "");
}
messagebar.append(messageEl, ...barActions);
messagebar.addEventListener("message-bar:close", onclose, { once: true });
document.getElementById("abuse-reports-messages").append(messagebar);
document.dispatchEvent(
new CustomEvent("abuse-report:new-message-bar", {
detail: { definitionId, messagebar },
})
);
return messagebar;
}
async function submitReport({ report, reason, message }) {
const { addon } = report;
const addonId = addon.id;
const addonName = addon.name;
const addonType = addon.type;
// Create a message bar while we are still submitting the report.
const mbSubmitting = createReportMessageBar(
"submitting",
{ addonId, addonName, addonType },
{
onaction: action => {
if (action === "cancel") {
report.abort();
mbSubmitting.remove();
}
},
}
);
try {
await report.submit({ reason, message });
mbSubmitting.remove();
// Create a submitted message bar when the submission has been
// successful.
let barId;
if (!(addon.permissions & AddonManager.PERM_CAN_UNINSTALL)) {
// Do not offer remove action if the addon can't be uninstalled.
barId = "submitted-no-remove-action";
} else if (report.reportEntryPoint === "uninstall") {
// With reportEntryPoint "uninstall" a specific message bar
// is going to be used.
barId = "submitted-and-removed";
} else {
// All the other reportEntryPoint ("menu" and "toolbar_context_menu")
// use the same kind of message bar.
barId = "submitted";
}
const mbInfo = createReportMessageBar(
barId,
{
addonId,
addonName,
addonType,
},
{
onaction: action => {
mbInfo.remove();
// action "keep" doesn't require any further action,
// just handle "remove".
if (action === "remove") {
report.addon.uninstall(true);
}
},
}
);
} catch (err) {
// Log the complete error in the console.
console.error("Error submitting abuse report for", addonId, err);
mbSubmitting.remove();
// The report has a submission error, create a error message bar which
// may optionally allow the user to retry to submit the same report.
const barId =
err.errorType in ABUSE_REPORT_MESSAGE_BARS
? err.errorType
: "ERROR_UNKNOWN";
const mbError = createReportMessageBar(
barId,
{
addonId,
addonName,
addonType,
},
{
onaction: action => {
mbError.remove();
switch (action) {
case "retry":
submitReport({ report, reason, message });
break;
case "cancel":
report.abort();
break;
}
},
}
);
}
}
document.addEventListener("abuse-report:submit", ({ detail }) => {
submitReport(detail);
});
document.addEventListener("abuse-report:create-error", ({ detail }) => {
const { addonId, addon, errorType } = detail;
const barId =
errorType in ABUSE_REPORT_MESSAGE_BARS ? errorType : "ERROR_UNKNOWN";
createReportMessageBar(barId, {
addonId,
addonName: addon && addon.name,
addonType: addon && addon.type,
});
});

View File

@ -36,10 +36,6 @@ xhtml|link {
-moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#creator-link");
}
.meta-rating {
-moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#rating");
}
.download-progress, .download-progress[mode="undetermined"] {
-moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#download-progress");
}
@ -71,11 +67,6 @@ row[unsupported="true"] {
display: none;
}
#show-disabled-unsigned-extensions .button-text {
margin-inline-start: 3px !important;
margin-inline-end: 2px !important;
}
#header-searching:not([active]) {
visibility: hidden;
}
@ -186,12 +177,6 @@ row[unsupported="true"] {
max-width: 580px;
}
/* Make sure we're not animating hidden images. See bug 623739. */
#view-port:not([selectedIndex="0"]) #discover-view .loading,
#discover-view:not([selectedIndex="0"]) .loading {
display: none;
}
/* Elements in unselected richlistitems cannot be focused */
richlistitem:not([selected]) * {
-moz-user-focus: ignore;
@ -201,10 +186,6 @@ richlistitem:not([selected]) * {
width: 22em;
}
.discover-button[disabled="true"] {
display: none;
}
.view-pane:not(#legacy-view) .addon-control.replacement {
display: none;
}

File diff suppressed because it is too large Load Diff

View File

@ -18,110 +18,6 @@
xmlns:html="http://www.w3.org/1999/xhtml">
<!-- Rating - displays current/average rating, allows setting user rating -->
<binding id="rating">
<content>
<xul:image class="star"
onmouseover="document.getBindingParent(this)._hover(1);"
onclick="document.getBindingParent(this).userRating = 1;"/>
<xul:image class="star"
onmouseover="document.getBindingParent(this)._hover(2);"
onclick="document.getBindingParent(this).userRating = 2;"/>
<xul:image class="star"
onmouseover="document.getBindingParent(this)._hover(3);"
onclick="document.getBindingParent(this).userRating = 3;"/>
<xul:image class="star"
onmouseover="document.getBindingParent(this)._hover(4);"
onclick="document.getBindingParent(this).userRating = 4;"/>
<xul:image class="star"
onmouseover="document.getBindingParent(this)._hover(5);"
onclick="document.getBindingParent(this).userRating = 5;"/>
</content>
<implementation>
<constructor><![CDATA[
this._updateStars();
]]></constructor>
<property name="stars" readonly="true">
<getter><![CDATA[
return document.getAnonymousNodes(this);
]]></getter>
</property>
<property name="averageRating">
<getter><![CDATA[
if (this.hasAttribute("averagerating"))
return this.getAttribute("averagerating");
return -1;
]]></getter>
<setter><![CDATA[
this.setAttribute("averagerating", val);
if (this.showRating == "average")
this._updateStars();
]]></setter>
</property>
<property name="userRating">
<getter><![CDATA[
if (this.hasAttribute("userrating"))
return this.getAttribute("userrating");
return -1;
]]></getter>
<setter><![CDATA[
if (this.showRating != "user")
return;
this.setAttribute("userrating", val);
if (this.showRating == "user")
this._updateStars();
]]></setter>
</property>
<property name="showRating">
<getter><![CDATA[
if (this.hasAttribute("showrating"))
return this.getAttribute("showrating");
return "average";
]]></getter>
<setter><![CDATA[
if (val != "average" || val != "user")
throw Components.Exception("Invalid value", Cr.NS_ERROR_ILLEGAL_VALUE);
this.setAttribute("showrating", val);
this._updateStars();
]]></setter>
</property>
<method name="_updateStars">
<body><![CDATA[
var stars = this.stars;
var rating = this[this.showRating + "Rating"];
// average ratings can be non-whole numbers, round them so they
// match to their closest star
rating = Math.round(rating);
for (let i = 0; i < stars.length; i++)
stars[i].setAttribute("on", rating > i);
]]></body>
</method>
<method name="_hover">
<parameter name="aScore"/>
<body><![CDATA[
if (this.showRating != "user")
return;
var stars = this.stars;
for (let i = 0; i < stars.length; i++)
stars[i].setAttribute("on", i <= (aScore - 1));
]]></body>
</method>
</implementation>
<handlers>
<handler event="mouseout">
this._updateStars();
</handler>
</handlers>
</binding>
<!-- Download progress - shows graphical progress of download and any
related status message. -->
@ -903,8 +799,7 @@
this.setAttribute("previewURL", previewURL ? previewURL : "");
this.setAttribute("hasPreview", previewURL ? "true" : "fase");
let legacyWarning = legacyExtensionsEnabled && !this.mAddon.install &&
isLegacyExtension(this.mAddon);
let legacyWarning = isLegacyExtension(this.mAddon);
this.setAttribute("legacy", legacyWarning);
document.getAnonymousElementByAttribute(this, "anonid", "legacy").href = SUPPORT_URL + "webextensions";
@ -1027,14 +922,6 @@
this._errorLink.href = url;
this._errorLink.hidden = false;
});
} else if (!isUpgrade && isDisabledUnsigned(this.mAddon)) {
this.setAttribute("notification", "error");
this._error.textContent = gStrings.ext.formatStringFromName(
"notification.unsignedAndDisabled", [this.mAddon.name, gStrings.brandShortName]
);
this._errorLink.value = gStrings.ext.GetStringFromName("notification.unsigned.link");
this._errorLink.href = SUPPORT_URL + "unsigned-addons";
this._errorLink.hidden = false;
} else if ((!isUpgrade && !this.mAddon.isCompatible) && (AddonManager.checkCompatibility
|| (this.mAddon.blocklistState != Ci.nsIBlocklistService.STATE_SOFTBLOCKED))) {
this.setAttribute("notification", "warning");
@ -1235,11 +1122,6 @@
this.mManualUpdate.releaseNotesURI :
this.mAddon.releaseNotesURI;
this._fetchReleaseNotes(uri);
// Dispatch an event so extensions.js can record telemetry.
let event = document.createEvent("Events");
event.initEvent("RelNotesShow", true, true);
this.dispatchEvent(event);
}
]]></body>
</method>
@ -1267,11 +1149,6 @@
this.setAttribute("pending", "uninstall");
});
}
// Dispatch an event so extensions.js can track telemetry.
var event = document.createEvent("Events");
event.initEvent("Uninstall", true, true);
this.dispatchEvent(event);
]]></body>
</method>
@ -1526,11 +1403,6 @@
else if (this.getAttribute("wasDisabled") != "true")
this.mAddon.enable();
// Dispatch an event so extensions.js can record telemetry.
var event = document.createEvent("Events");
event.initEvent("Undo", true, true);
this.dispatchEvent(event);
this.removeAttribute("pending");
]]></body>
</method>

View File

@ -33,7 +33,6 @@
<script src="chrome://global/content/contentAreaUtils.js"/>
<script src="chrome://mozapps/content/extensions/aboutaddonsCommon.js"/>
<script src="chrome://mozapps/content/extensions/extensions.js"/>
<script src="chrome://mozapps/content/extensions/abuse-report-frame.js"/>
<popupset>
<!-- menu for an addon item -->
@ -97,7 +96,6 @@
<command id="cmd_focusSearch" oncommand=";"/>
<command id="cmd_findAllUpdates"/>
<command id="cmd_restartApp"/>
<command id="cmd_goToDiscoverPane"/>
<command id="cmd_goToRecentUpdates"/>
<command id="cmd_goToAvailableUpdates"/>
<command id="cmd_installFromFile"/>
@ -141,11 +139,6 @@
<vbox id="category-box">
<!-- category list -->
<richlistbox id="categories" flex="1">
<richlistitem id="category-discover" value="addons://discover/"
class="category"
data-l10n-id="extensions-view-discopane"
data-l10n-attrs="name"
priority="1000"/>
<richlistitem id="category-legacy" value="addons://legacy/"
class="category" priority="20000"
hidden="true"/>
@ -186,36 +179,6 @@
<vbox class="main-content" flex="1">
<!-- view port -->
<deck id="view-port" flex="1" selectedIndex="0">
<!-- discover view -->
<deck id="discover-view" flex="1" class="view-pane" selectedIndex="0">
<vbox id="discover-loading" align="center" pack="stretch" flex="1" class="alert-container">
<spacer class="alert-spacer-before"/>
<hbox class="alert loading" align="center">
<image/>
<label data-l10n-id="loading-label"/>
</hbox>
<spacer class="alert-spacer-after"/>
</vbox>
<vbox id="discover-error" align="center" pack="stretch" flex="1" class="alert-container">
<spacer class="alert-spacer-before"/>
<hbox>
<spacer class="discover-spacer-before"/>
<vbox class="alert" align="center">
<image class="discover-logo"/>
<vbox flex="1" align="stretch">
<label class="discover-title" data-l10n-id="discover-title"></label>
<description class="discover-description" data-l10n-id="discover-description"></description>
<description class="discover-footer" data-l10n-id="discover-footer"></description>
</vbox>
</vbox>
<spacer class="discover-spacer-after"/>
</hbox>
<spacer class="alert-spacer-after"/>
</vbox>
<browser id="discover-browser" type="content" flex="1"
disablehistory="true"/>
</deck>
<!-- container for views with the search/tools header -->
<vbox id="headered-views" flex="1">
@ -226,9 +189,6 @@
data-l10n-id="show-all-extensions-button"
command="cmd_showAllExtensions"/>
<spacer flex="1"/>
<button id="show-disabled-unsigned-extensions" hidden="true"
class="warning" data-l10n-id="show-unsigned-extensions-button"
command="cmd_showUnsignedExtensions"/>
<label id="search-label" control="header-search"/>
<textbox id="header-search" is="search-textbox" searchbutton="true"
data-l10n-id="search-header"
@ -265,9 +225,9 @@
<button id="header-utils-btn" type="menu" data-l10n-id="tools-menu">
<menupopup id="utils-menu">
<menuitem id="utils-updateNow"
<!--menuitem id="utils-updateNow"
data-l10n-id="extensions-updates-check-for-updates"
command="cmd_findAllUpdates"/>
command="cmd_findAllUpdates"/-->
<menuitem id="utils-viewUpdates"
data-l10n-id="extensions-updates-view-updates"
command="cmd_goToRecentUpdates"/>
@ -279,16 +239,16 @@
data-l10n-id="debug-addons"
command="cmd_debugAddons"/>
<menuseparator/>
<menuitem id="utils-autoUpdateDefault"
<!--menuitem id="utils-autoUpdateDefault"
data-l10n-id="extensions-updates-update-addons-automatically"
type="checkbox" autocheck="false"
command="cmd_toggleAutoUpdateDefault"/>
<menuitem id="utils-resetAddonUpdatesToAutomatic"
command="cmd_toggleAutoUpdateDefault"/-->
<!--menuitem id="utils-resetAddonUpdatesToAutomatic"
data-l10n-id="extensions-updates-reset-updates-to-automatic"
command="cmd_resetAddonAutoUpdate"/>
<menuitem id="utils-resetAddonUpdatesToManual"
command="cmd_resetAddonAutoUpdate"/-->
<!--menuitem id="utils-resetAddonUpdatesToManual"
data-l10n-id="extensions-updates-reset-updates-to-manual"
command="cmd_resetAddonAutoUpdate"/>
command="cmd_resetAddonAutoUpdate"/-->
<menuseparator/>
<menuitem id="manage-shortcuts"
data-l10n-id="manage-extensions-shortcuts"
@ -302,23 +262,6 @@
<!-- list view -->
<vbox id="list-view" flex="1" class="view-pane" align="stretch">
<!-- info UI for add-ons that have been disabled for being unsigned -->
<vbox id="disabled-unsigned-addons-info" class="alert-container" hidden="true">
<label id="disabled-unsigned-addons-heading" data-l10n-id="disabled-unsigned-heading"/>
<description data-l10n-id="disabled-unsigned-description">
<label class="plain" id="find-alternative-addons" data-l10n-name="find-addons" is="text-link"/>
</description>
<hbox pack="start"><label id="signing-learn-more" data-l10n-id="disabled-unsigned-learn-more" is="text-link"></label></hbox>
<description id="signing-dev-info" data-l10n-id="disabled-unsigned-devinfo">
<label class="plain" id="signing-dev-manual-link" data-l10n-name="learn-more" is="text-link"/>
</description>
</vbox>
<vbox id="legacy-extensions-notice" class="alert-container" hidden="true">
<vbox class="alert">
<description id="legacy-extensions-description">
<label class="plain" id="legacy-extensions-learnmore-link" data-l10n-id="legacy-warning-show-legacy" is="text-link"/>
</description>
</vbox>
</vbox>
<vbox id="private-browsing-notice" class="alert-container" hidden="true" align="start">
<hbox class="message-bar" align="start">
<image class="message-bar-icon"/>
@ -372,10 +315,6 @@
<spacer class="alert-spacer-before"/>
<vbox class="alert">
<label data-l10n-id="list-empty-installed"/>
<button class="discover-button"
id="discover-button-install"
data-l10n-id="list-empty-button"
command="cmd_goToDiscoverPane"/>
</vbox>
<spacer class="alert-spacer-after"/>
</vbox>
@ -613,14 +552,6 @@
<label class="detail-row-label" data-l10n-id="detail-repository-value"/>
<label id="detail-repository" class="detail-row-value" is="text-link"/>
</row>
<row class="detail-row-complex" id="detail-rating-row">
<label class="detail-row-label" data-l10n-id="detail-rating"/>
<hbox>
<label id="detail-rating" class="meta-value meta-rating"
showrating="average"/>
<label id="detail-reviews" is="text-link"/>
</hbox>
</row>
</rows>
</grid>
<hbox id="detail-controls">
@ -721,6 +652,5 @@
</deck>
</vbox>
</hbox>
<addon-abuse-report-xulframe hidden="true"></addon-abuse-report-xulframe>
</stack>
</page>

View File

@ -1,37 +0,0 @@
:host {
--rating-star-size: 1em;
--rating-star-spacing: 0.3ch;
display: inline-grid;
grid-template-columns: repeat(5, var(--rating-star-size));
grid-column-gap: var(--rating-star-spacing);
align-content: center;
}
:host([hidden]) {
display: none;
}
.rating-star {
display: inline-block;
width: var(--rating-star-size);
height: var(--rating-star-size);
background-image: url("chrome://mozapps/skin/extensions/rating-star.svg#empty");
background-position: center;
background-repeat: no-repeat;
background-size: 100%;
fill: currentColor;
-moz-context-properties: fill;
}
.rating-star[fill="half"] {
background-image: url("chrome://mozapps/skin/extensions/rating-star.svg#half");
}
.rating-star[fill="full"] {
background-image: url("chrome://mozapps/skin/extensions/rating-star.svg#full");
}
.rating-star[fill="half"]:dir(rtl) {
transform: scaleX(-1);
}

View File

@ -13,10 +13,6 @@ const { AppConstants } = ChromeUtils.import(
"resource://gre/modules/AppConstants.jsm"
);
const PREF_SIGNATURES_REQUIRED = "xpinstall.signatures.required";
const PREF_LANGPACK_SIGNATURES = "extensions.langpacks.signatures.required";
const PREF_ALLOW_LEGACY = "extensions.legacy.enabled";
var AddonSettings = {};
// Make a non-changable property that can't be manipulated from other
@ -30,35 +26,6 @@ function makeConstant(name, value) {
});
}
if (AppConstants.MOZ_REQUIRE_SIGNING && !Cu.isInAutomation) {
makeConstant("REQUIRE_SIGNING", true);
makeConstant("LANGPACKS_REQUIRE_SIGNING", true);
} else {
XPCOMUtils.defineLazyPreferenceGetter(
AddonSettings,
"REQUIRE_SIGNING",
PREF_SIGNATURES_REQUIRED,
false
);
XPCOMUtils.defineLazyPreferenceGetter(
AddonSettings,
"LANGPACKS_REQUIRE_SIGNING",
PREF_LANGPACK_SIGNATURES,
false
);
}
if (AppConstants.MOZ_ALLOW_LEGACY_EXTENSIONS || Cu.isInAutomation) {
XPCOMUtils.defineLazyPreferenceGetter(
AddonSettings,
"ALLOW_LEGACY_EXTENSIONS",
PREF_ALLOW_LEGACY,
true
);
} else {
makeConstant("ALLOW_LEGACY_EXTENSIONS", false);
}
if (AppConstants.MOZ_DEV_EDITION) {
makeConstant("DEFAULT_THEME_ID", "firefox-compact-dark@mozilla.org");
} else {

View File

@ -31,11 +31,6 @@ const { EventEmitter } = ChromeUtils.import(
);
const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
ChromeUtils.defineModuleGetter(
this,
"AMTelemetry",
"resource://gre/modules/AddonManager.jsm"
);
ChromeUtils.defineModuleGetter(
this,
"ExtensionTestCommon",
@ -330,7 +325,6 @@ var AddonTestUtils = {
addonsList: null,
appInfo: null,
addonStartup: null,
collectedTelemetryEvents: [],
testScope: null,
testUnpacked: false,
useRealCertChecks: false,
@ -411,9 +405,6 @@ var AddonTestUtils = {
// By default ignore bundled add-ons
Services.prefs.setBoolPref("extensions.installDistroAddons", false);
// Ensure signature checks are enabled by default
Services.prefs.setBoolPref("xpinstall.signatures.required", true);
// Write out an empty blocklist.xml file to the profile to ensure nothing
// is blocklisted by default
var blockFile = OS.Path.join(this.profileDir.path, "blocklist.xml");
@ -1533,21 +1524,16 @@ var AddonTestUtils = {
* @param {boolean} [ignoreIncompatible = false]
* Optional parameter to ignore add-ons that are incompatible
* with the application
* @param {Object} [installTelemetryInfo = undefined]
* Optional parameter to set the install telemetry info for the
* installed addon
* @returns {Promise}
* Resolves when the install has completed.
*/
async promiseInstallFile(
file,
ignoreIncompatible = false,
installTelemetryInfo
ignoreIncompatible = false
) {
let install = await AddonManager.getInstallForFile(
file,
null,
installTelemetryInfo
null
);
if (!install) {
throw new Error(`No AddonInstall created for ${file.path}`);
@ -1782,36 +1768,6 @@ var AddonTestUtils = {
}
},
/**
* Asserts that the expected installTelemetryInfo properties are available
* on the AddonWrapper or AddonInstall objects.
*
* @param {AddonWrapper|AddonInstall} addonOrInstall
* The addon or addonInstall object to check.
* @param {Object} expectedInstallInfo
* The expected installTelemetryInfo properties
* (every property can be a primitive value or a regular expression).
*/
checkInstallInfo(addonOrInstall, expectedInstallInfo) {
const installInfo = addonOrInstall.installTelemetryInfo;
const { Assert } = this.testScope;
for (const key of Object.keys(expectedInstallInfo)) {
const actual = installInfo[key];
let expected = expectedInstallInfo[key];
// Assert the property value using a regular expression.
if (expected && typeof expected.test == "function") {
Assert.ok(
expected.test(actual),
`${key} value "${actual}" has the value expected: "${expected}"`
);
} else {
Assert.deepEqual(actual, expected, `Got the expected value for ${key}`);
}
}
},
/**
* Helper to wait for a webextension to completely start
*
@ -1917,39 +1873,6 @@ var AddonTestUtils = {
]);
Services.prefs.setBoolPref(PREF_DISABLE_SECURITY, prevPrefVal);
},
// AMTelemetry events helpers.
/**
* Redefine AMTelemetry.recordEvent to collect the recorded telemetry events and
* ensure that there are no unexamined events after the test file is exiting.
*/
hookAMTelemetryEvents() {
let originalRecordEvent = AMTelemetry.recordEvent;
AMTelemetry.recordEvent = event => {
this.collectedTelemetryEvents.push(event);
};
this.testScope.registerCleanupFunction(() => {
this.testScope.Assert.deepEqual(
[],
this.collectedTelemetryEvents,
"No unexamined telemetry events after test is finished"
);
AMTelemetry.recordEvent = originalRecordEvent;
});
},
/**
* Retrive any AMTelemetry event collected and empty the array of the collected events.
*
* @returns {Array<Object>}
* The array of the collected telemetry data.
*/
getAMTelemetryEvents() {
let events = this.collectedTelemetryEvents;
this.collectedTelemetryEvents = [];
return events;
},
};
for (let [key, val] of Object.entries(AddonTestUtils)) {

View File

@ -56,10 +56,6 @@ const LOGGER_ID = "addons.update-checker";
// (Requires AddonManager.jsm)
var logger = Log.repository.getLogger(LOGGER_ID);
const updateTypeHistogram = Services.telemetry.getHistogramById(
"EXTENSION_UPDATE_TYPE"
);
/**
* Sanitizes the update URL in an update item, as returned by
* parseRDFManifest and parseJSONManifest. Ensures that:
@ -275,8 +271,7 @@ function UpdateParser(aId, aUrl, aObserver) {
let requireBuiltIn = Services.prefs.getBoolPref(
PREF_UPDATE_REQUIREBUILTINCERTS,
!AppConstants.MOZ_REQUIRE_SIGNING &&
!AppConstants.MOZ_APP_VERSION_DISPLAY.endsWith("esr")
!AppConstants.MOZ_APP_VERSION_DISPLAY.endsWith("esr")
);
logger.debug("Requesting " + aUrl);
@ -316,8 +311,7 @@ UpdateParser.prototype = {
let requireBuiltIn = Services.prefs.getBoolPref(
PREF_UPDATE_REQUIREBUILTINCERTS,
!AppConstants.MOZ_REQUIRE_SIGNING &&
!AppConstants.MOZ_APP_VERSION_DISPLAY.endsWith("esr")
!AppConstants.MOZ_APP_VERSION_DISPLAY.endsWith("esr")
);
try {
@ -352,7 +346,6 @@ UpdateParser.prototype = {
try {
let json = JSON.parse(request.responseText);
results = parseJSONManifest(this.id, request, json);
updateTypeHistogram.add("JSON");
} catch (e) {
logger.warn("onUpdateCheckComplete failed to parse update manifest", e);
this.notifyError(AddonManager.ERROR_PARSE_ERROR);

Some files were not shown because too many files have changed in this diff Show More