mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-11-09 04:39:03 +02:00
310 lines
8.8 KiB
JavaScript
310 lines
8.8 KiB
JavaScript
/* 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] */
|
|
/* import-globals-from aboutaddonsCommon.js */
|
|
/* 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).
|
|
*/
|
|
|
|
const { AbuseReporter } = ChromeUtils.import(
|
|
"resource://gre/modules/AbuseReporter.jsm"
|
|
);
|
|
|
|
// 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",
|
|
},
|
|
};
|
|
|
|
async function openAbuseReport({ addonId, reportEntryPoint }) {
|
|
try {
|
|
const reportDialog = await AbuseReporter.openDialog(
|
|
addonId,
|
|
reportEntryPoint,
|
|
window.docShell.chromeEventHandler
|
|
);
|
|
|
|
// Warn the user before the about:addons tab while an
|
|
// abuse report dialog is still open, and close the
|
|
// report dialog if the user choose to close the related
|
|
// about:addons tab.
|
|
const beforeunloadListener = evt => evt.preventDefault();
|
|
const unloadListener = () => reportDialog.close();
|
|
const clearUnloadListeners = () => {
|
|
window.removeEventListener("beforeunload", beforeunloadListener);
|
|
window.removeEventListener("unload", unloadListener);
|
|
};
|
|
window.addEventListener("beforeunload", beforeunloadListener);
|
|
window.addEventListener("unload", unloadListener);
|
|
|
|
reportDialog.promiseReport
|
|
.then(
|
|
report => {
|
|
if (report) {
|
|
submitReport({ report });
|
|
}
|
|
},
|
|
err => {
|
|
Cu.reportError(
|
|
`Unexpected abuse report panel error: ${err} :: ${err.stack}`
|
|
);
|
|
reportDialog.close();
|
|
}
|
|
)
|
|
.then(clearUnloadListeners);
|
|
} catch (err) {
|
|
document.dispatchEvent(
|
|
new CustomEvent("abuse-report:create-error", {
|
|
detail: {
|
|
addonId,
|
|
addon: err.addon,
|
|
errorType: err.errorType,
|
|
},
|
|
})
|
|
);
|
|
}
|
|
}
|
|
|
|
window.openAbuseReport = openAbuseReport;
|
|
|
|
// 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 }) {
|
|
const { addon } = report;
|
|
const addonId = addon.id;
|
|
const addonName = addon.name;
|
|
const addonType = addon.type;
|
|
|
|
// Ensure that the tab that originated the report dialog is selected
|
|
// when the user is submitting the report.
|
|
const { gBrowser } = window.windowRoot.ownerGlobal;
|
|
if (gBrowser && gBrowser.getTabForBrowser) {
|
|
let tab = gBrowser.getTabForBrowser(window.docShell.chromeEventHandler);
|
|
gBrowser.selectedTab = tab;
|
|
}
|
|
|
|
// 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();
|
|
mbSubmitting.remove();
|
|
|
|
// Create a submitted message bar when the submission has been
|
|
// successful.
|
|
let barId;
|
|
if (
|
|
!(addon.permissions & AddonManager.PERM_CAN_UNINSTALL) &&
|
|
!isPending(addon, "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 });
|
|
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,
|
|
});
|
|
});
|