зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1580554 - Open abuse report panel in a separate dialog window. r=mstriemer
Introduced a new "extensions.abuseReport.openDialog" pref: - when set to false (current default): the abuse report panel is opened as a subframe of the about:addons tab - when set to true: the abuse report panel is opened in its own dialog window Differential Revision: https://phabricator.services.mozilla.com/D45570 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
45b356558e
Коммит
b62acf4aca
|
@ -2303,6 +2303,8 @@ pref("services.settings.security.onecrl.signer", "onecrl.content-signature.mozil
|
||||||
pref("services.settings.security.onecrl.checked", 0);
|
pref("services.settings.security.onecrl.checked", 0);
|
||||||
|
|
||||||
pref("extensions.abuseReport.enabled", true);
|
pref("extensions.abuseReport.enabled", true);
|
||||||
|
// Opened as a sub-frame of the about:addons page when set to false.
|
||||||
|
pref("extensions.abuseReport.openDialog", false);
|
||||||
pref("extensions.abuseReport.url", "https://services.addons.mozilla.org/api/v4/abuse/report/addon/");
|
pref("extensions.abuseReport.url", "https://services.addons.mozilla.org/api/v4/abuse/report/addon/");
|
||||||
|
|
||||||
// Blocklist preferences
|
// Blocklist preferences
|
||||||
|
|
|
@ -11,6 +11,7 @@ const { XPCOMUtils } = ChromeUtils.import(
|
||||||
Cu.importGlobalProperties(["fetch"]);
|
Cu.importGlobalProperties(["fetch"]);
|
||||||
|
|
||||||
const PREF_ABUSE_REPORT_URL = "extensions.abuseReport.url";
|
const PREF_ABUSE_REPORT_URL = "extensions.abuseReport.url";
|
||||||
|
const PREF_ABUSE_REPORT_OPEN_DIALOG = "extensions.abuseReport.openDialog";
|
||||||
|
|
||||||
// Maximum length of the string properties sent to the API endpoint.
|
// Maximum length of the string properties sent to the API endpoint.
|
||||||
const MAX_STRING_LENGTH = 255;
|
const MAX_STRING_LENGTH = 255;
|
||||||
|
@ -32,6 +33,13 @@ XPCOMUtils.defineLazyPreferenceGetter(
|
||||||
PREF_ABUSE_REPORT_URL
|
PREF_ABUSE_REPORT_URL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
XPCOMUtils.defineLazyPreferenceGetter(
|
||||||
|
this,
|
||||||
|
"SHOULD_OPEN_DIALOG",
|
||||||
|
PREF_ABUSE_REPORT_OPEN_DIALOG,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
const PRIVATE_REPORT_PROPS = Symbol("privateReportProps");
|
const PRIVATE_REPORT_PROPS = Symbol("privateReportProps");
|
||||||
|
|
||||||
const ERROR_TYPES = Object.freeze([
|
const ERROR_TYPES = Object.freeze([
|
||||||
|
@ -201,6 +209,114 @@ const AbuseReporter = {
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function that opens an abuse report form in a new dialog window.
|
||||||
|
*
|
||||||
|
* @param {string} addonId
|
||||||
|
* The addonId being reported.
|
||||||
|
* @param {string} reportEntryPoint
|
||||||
|
* The entry point from which the user has triggered the abuse report
|
||||||
|
* flow.
|
||||||
|
* @param {XULElement} browser
|
||||||
|
* The browser element (if any) that is opening the report window.
|
||||||
|
*
|
||||||
|
* @return {Promise<AbuseReportDialog>}
|
||||||
|
* Returns an AbuseReportDialog object, rejects if it fails to open
|
||||||
|
* the dialog.
|
||||||
|
*
|
||||||
|
* @typedef {object} AbuseReportDialog
|
||||||
|
* An object that represents the abuse report dialog.
|
||||||
|
* @prop {function} close
|
||||||
|
* A method that closes the report dialog (used by the caller
|
||||||
|
* to close the dialog when the user chooses to close the window
|
||||||
|
* that started the abuse report flow).
|
||||||
|
* @prop {Promise<AbuseReport|undefined} promiseReport
|
||||||
|
* A promise resolved to an AbuseReport instance if the report should
|
||||||
|
* be submitted, or undefined if the user has cancelled the report.
|
||||||
|
* Rejects if it fails to create an AbuseReport instance or to open
|
||||||
|
* the abuse report window.
|
||||||
|
*/
|
||||||
|
async openDialog(addonId, reportEntryPoint, browser) {
|
||||||
|
const chromeWin = browser && browser.ownerGlobal;
|
||||||
|
if (!chromeWin) {
|
||||||
|
throw new Error("Abuse Reporter dialog cancelled, opener tab closed");
|
||||||
|
}
|
||||||
|
|
||||||
|
const report = await AbuseReporter.createAbuseReport(addonId, {
|
||||||
|
reportEntryPoint,
|
||||||
|
});
|
||||||
|
const params = Cc["@mozilla.org/array;1"].createInstance(
|
||||||
|
Ci.nsIMutableArray
|
||||||
|
);
|
||||||
|
|
||||||
|
const dialogInit = {
|
||||||
|
report,
|
||||||
|
openWebLink(url) {
|
||||||
|
chromeWin.openWebLinkIn(url, "tab", {
|
||||||
|
relatedToCurrent: true,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
params.appendElement(dialogInit);
|
||||||
|
|
||||||
|
let win;
|
||||||
|
function closeDialog() {
|
||||||
|
if (win && !win.closed) {
|
||||||
|
win.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const promiseReport = new Promise((resolve, reject) => {
|
||||||
|
dialogInit.deferredReport = { resolve, reject };
|
||||||
|
}).then(
|
||||||
|
({ userCancelled }) => {
|
||||||
|
closeDialog();
|
||||||
|
return userCancelled ? undefined : report;
|
||||||
|
},
|
||||||
|
err => {
|
||||||
|
Cu.reportError(
|
||||||
|
`Unexpected abuse report panel error: ${err} :: ${err.stack}`
|
||||||
|
);
|
||||||
|
closeDialog();
|
||||||
|
return Promise.reject({
|
||||||
|
message: "Unexpected abuse report panel error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const promiseReportPanel = new Promise((resolve, reject) => {
|
||||||
|
dialogInit.deferredReportPanel = { resolve, reject };
|
||||||
|
});
|
||||||
|
|
||||||
|
dialogInit.promiseReport = promiseReport;
|
||||||
|
dialogInit.promiseReportPanel = promiseReportPanel;
|
||||||
|
|
||||||
|
win = Services.ww.openWindow(
|
||||||
|
chromeWin,
|
||||||
|
"chrome://mozapps/content/extensions/abuse-report-frame.html",
|
||||||
|
"addons-abuse-report-dialog",
|
||||||
|
// Set the dialog window options (including a reasonable initial
|
||||||
|
// window height size, eventually adjusted by the panel once it
|
||||||
|
// has been rendered its content).
|
||||||
|
"dialog,centerscreen,alwaysOnTop,height=700",
|
||||||
|
params
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
close: closeDialog,
|
||||||
|
promiseReport,
|
||||||
|
|
||||||
|
// Properties used in tests
|
||||||
|
promiseReportPanel,
|
||||||
|
window: win,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
get openDialogDisabled() {
|
||||||
|
return !SHOULD_OPEN_DIALOG;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -234,6 +350,10 @@ class AbuseReport {
|
||||||
addon,
|
addon,
|
||||||
reportData,
|
reportData,
|
||||||
reportEntryPoint,
|
reportEntryPoint,
|
||||||
|
// message and reason are initially null, and then set by the panel
|
||||||
|
// using the related set method.
|
||||||
|
message: null,
|
||||||
|
reason: null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,21 +370,20 @@ class AbuseReport {
|
||||||
/**
|
/**
|
||||||
* Submit the current report, given a reason and a message.
|
* 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>}
|
* @returns {Promise<void>}
|
||||||
* Resolves once the report has been successfully submitted.
|
* Resolves once the report has been successfully submitted.
|
||||||
* It rejects with an AbuseReportError if the report couldn't be
|
* It rejects with an AbuseReportError if the report couldn't be
|
||||||
* submitted for a known reason (or another Error type otherwise).
|
* submitted for a known reason (or another Error type otherwise).
|
||||||
*/
|
*/
|
||||||
async submit({ reason, message }) {
|
async submit() {
|
||||||
const { aborted, abortController, reportData, reportEntryPoint } = this[
|
const {
|
||||||
PRIVATE_REPORT_PROPS
|
aborted,
|
||||||
];
|
abortController,
|
||||||
|
message,
|
||||||
|
reason,
|
||||||
|
reportData,
|
||||||
|
reportEntryPoint,
|
||||||
|
} = this[PRIVATE_REPORT_PROPS];
|
||||||
|
|
||||||
// Record telemetry event and throw an AbuseReportError.
|
// Record telemetry event and throw an AbuseReportError.
|
||||||
const rejectReportError = async (errorType, { response } = {}) => {
|
const rejectReportError = async (errorType, { response } = {}) => {
|
||||||
|
@ -359,4 +478,24 @@ class AbuseReport {
|
||||||
get reportEntryPoint() {
|
get reportEntryPoint() {
|
||||||
return this[PRIVATE_REPORT_PROPS].reportEntryPoint;
|
return this[PRIVATE_REPORT_PROPS].reportEntryPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the open message (called from the panel when the user submit the report)
|
||||||
|
*
|
||||||
|
* @parm {string} message
|
||||||
|
* An optional string which contains a description for the reported issue.
|
||||||
|
*/
|
||||||
|
setMessage(message) {
|
||||||
|
this[PRIVATE_REPORT_PROPS].message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the report reason (called from the panel when the user submit the report)
|
||||||
|
*
|
||||||
|
* @parm {string} reason
|
||||||
|
* String identifier for the report reason.
|
||||||
|
*/
|
||||||
|
setReason(reason) {
|
||||||
|
this[PRIVATE_REPORT_PROPS].reason = reason;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,15 +13,20 @@
|
||||||
<link rel="localization" href="toolkit/about/aboutAddons.ftl">
|
<link rel="localization" href="toolkit/about/aboutAddons.ftl">
|
||||||
<link rel="localization" href="toolkit/about/abuseReports.ftl">
|
<link rel="localization" href="toolkit/about/abuseReports.ftl">
|
||||||
|
|
||||||
<script src="chrome://mozapps/content/extensions/abuse-report-panel.js"></script>
|
<script defer src="chrome://mozapps/content/extensions/abuse-report-panel.js"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
<addon-abuse-report></addon-abuse-report>
|
||||||
|
|
||||||
<!-- WebComponents Templates -->
|
<!-- WebComponents Templates -->
|
||||||
<template id="tmpl-abuse-report">
|
<template id="tmpl-modal">
|
||||||
<div class="modal-overlay-outer"></div>
|
<div class="modal-overlay-outer"></div>
|
||||||
<div class="modal-panel-container">
|
<div class="modal-panel-container"></div>
|
||||||
<form class="card addon-abuse-report" onsubmit="return false;">
|
</template>
|
||||||
|
|
||||||
|
<template id="tmpl-abuse-report">
|
||||||
|
<form class="addon-abuse-report" onsubmit="return false;">
|
||||||
<div class="abuse-report-header">
|
<div class="abuse-report-header">
|
||||||
<img class="card-heading-icon addon-icon"/>
|
<img class="card-heading-icon addon-icon"/>
|
||||||
<div class="card-contents">
|
<div class="card-contents">
|
||||||
|
@ -58,7 +63,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template id="tmpl-reasons-panel">
|
<template id="tmpl-reasons-panel">
|
||||||
|
|
|
@ -281,7 +281,18 @@
|
||||||
// abuse report panel from outside of the about:addons page
|
// abuse report panel from outside of the about:addons page
|
||||||
// (e.g. triggered from the browserAction context menu).
|
// (e.g. triggered from the browserAction context menu).
|
||||||
window.openAbuseReport = ({ addonId, reportEntryPoint }) => {
|
window.openAbuseReport = ({ addonId, reportEntryPoint }) => {
|
||||||
|
if (AbuseReporter.openDialogDisabled) {
|
||||||
const frame = document.querySelector("addon-abuse-report-xulframe");
|
const frame = document.querySelector("addon-abuse-report-xulframe");
|
||||||
frame.openReport({ addonId, reportEntryPoint });
|
frame.openReport({ addonId, reportEntryPoint });
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
htmlBrowserLoaded.then(() => {
|
||||||
|
getHtmlBrowser().contentWindow.openAbuseReport({
|
||||||
|
addonId,
|
||||||
|
reportEntryPoint,
|
||||||
|
});
|
||||||
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -215,3 +215,36 @@ abuse-report-submit-panel textarea {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Adapt styles for the panel opened in its own dialog window */
|
||||||
|
|
||||||
|
html.dialog-window {
|
||||||
|
background-color: var(--in-content-box-background);
|
||||||
|
height: 100%;
|
||||||
|
min-width: 740px;
|
||||||
|
}
|
||||||
|
|
||||||
|
html.dialog-window body {
|
||||||
|
overflow: hidden;
|
||||||
|
min-height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
html.dialog-window .abuse-report-close-icon {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
html.dialog-window addon-abuse-report {
|
||||||
|
flex-grow: 1;
|
||||||
|
display: flex;
|
||||||
|
/* Ensure that the dialog window starts from a reasonable initial size */
|
||||||
|
--modal-panel-min-width: 700px;
|
||||||
|
}
|
||||||
|
|
||||||
|
html.dialog-window addon-abuse-report form {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
html.dialog-window addon-abuse-report form .abuse-report-contents {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
|
@ -11,6 +11,16 @@ ChromeUtils.defineModuleGetter(
|
||||||
"resource://gre/modules/Services.jsm"
|
"resource://gre/modules/Services.jsm"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const IS_DIALOG_WINDOW = window.arguments && window.arguments.length;
|
||||||
|
|
||||||
|
let openWebLink = IS_DIALOG_WINDOW
|
||||||
|
? window.arguments[0].wrappedJSObject.openWebLink
|
||||||
|
: url => {
|
||||||
|
window.windowRoot.ownerGlobal.openWebLinkIn(url, "tab", {
|
||||||
|
relatedToCurrent: true,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const showOnAnyType = () => false;
|
const showOnAnyType = () => false;
|
||||||
const hideOnAnyType = () => true;
|
const hideOnAnyType = () => true;
|
||||||
const hideOnThemeType = addonType => addonType === "theme";
|
const hideOnThemeType = addonType => addonType === "theme";
|
||||||
|
@ -449,7 +459,11 @@ class AbuseReport extends HTMLElement {
|
||||||
}
|
}
|
||||||
this.cancel();
|
this.cancel();
|
||||||
}
|
}
|
||||||
|
if (!IS_DIALOG_WINDOW) {
|
||||||
|
// Workaround keyboard navigation issues when
|
||||||
|
// the panel is running in its own dialog window.
|
||||||
this.handleKeyboardNavigation(evt);
|
this.handleKeyboardNavigation(evt);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case "click":
|
case "click":
|
||||||
if (evt.target === this._iconClose || evt.target === this._btnCancel) {
|
if (evt.target === this._iconClose || evt.target === this._btnCancel) {
|
||||||
|
@ -474,9 +488,7 @@ class AbuseReport extends HTMLElement {
|
||||||
const url = evt.target.getAttribute("href");
|
const url = evt.target.getAttribute("href");
|
||||||
// Ignore if url is empty.
|
// Ignore if url is empty.
|
||||||
if (url) {
|
if (url) {
|
||||||
window.windowRoot.ownerGlobal.openWebLinkIn(url, "tab", {
|
openWebLink(url);
|
||||||
relatedToCurrent: true,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -527,7 +539,23 @@ class AbuseReport extends HTMLElement {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
this.textContent = "";
|
this.textContent = "";
|
||||||
this.appendChild(document.importNode(this.template.content, true));
|
const formTemplate = document.importNode(this.template.content, true);
|
||||||
|
if (IS_DIALOG_WINDOW) {
|
||||||
|
this.appendChild(formTemplate);
|
||||||
|
} else {
|
||||||
|
// Append the report form inside a modal overlay when the report panel
|
||||||
|
// is a sub-frame of the about:addons tab.
|
||||||
|
const modalTemplate = document.importNode(
|
||||||
|
this.modalTemplate.content,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
this.appendChild(modalTemplate);
|
||||||
|
this.querySelector(".modal-panel-container").appendChild(formTemplate);
|
||||||
|
|
||||||
|
// Add the card styles to the form.
|
||||||
|
this.querySelector("form").classList.add("card");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async update() {
|
async update() {
|
||||||
|
@ -581,6 +609,7 @@ class AbuseReport extends HTMLElement {
|
||||||
_submitPanel.update();
|
_submitPanel.update();
|
||||||
|
|
||||||
this.focus();
|
this.focus();
|
||||||
|
|
||||||
dispatchCustomEvent(this, "abuse-report:updated", {
|
dispatchCustomEvent(this, "abuse-report:updated", {
|
||||||
addonId,
|
addonId,
|
||||||
panel: "reasons",
|
panel: "reasons",
|
||||||
|
@ -628,10 +657,10 @@ class AbuseReport extends HTMLElement {
|
||||||
if (!this.isConnected || !this.addon) {
|
if (!this.isConnected || !this.addon) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
this._report.setMessage(this.message);
|
||||||
|
this._report.setReason(this.reason);
|
||||||
dispatchCustomEvent(this, "abuse-report:submit", {
|
dispatchCustomEvent(this, "abuse-report:submit", {
|
||||||
addonId: this.addonId,
|
addonId: this.addonId,
|
||||||
reason: this.reason,
|
|
||||||
message: this.message,
|
|
||||||
report: this._report,
|
report: this._report,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -721,6 +750,10 @@ class AbuseReport extends HTMLElement {
|
||||||
return this._form.elements.reason.value;
|
return this._form.elements.reason.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get modalTemplate() {
|
||||||
|
return document.getElementById("tmpl-modal");
|
||||||
|
}
|
||||||
|
|
||||||
get template() {
|
get template() {
|
||||||
return document.getElementById("tmpl-abuse-report");
|
return document.getElementById("tmpl-abuse-report");
|
||||||
}
|
}
|
||||||
|
@ -737,10 +770,54 @@ customElements.define("abuse-report-reasons-panel", AbuseReasonsPanel);
|
||||||
customElements.define("abuse-report-submit-panel", AbuseSubmitPanel);
|
customElements.define("abuse-report-submit-panel", AbuseSubmitPanel);
|
||||||
customElements.define("addon-abuse-report", AbuseReport);
|
customElements.define("addon-abuse-report", AbuseReport);
|
||||||
|
|
||||||
window.addEventListener(
|
// The panel has been opened in a new dialog window.
|
||||||
"load",
|
if (IS_DIALOG_WINDOW) {
|
||||||
|
// CSS customizations when panel is in its own window
|
||||||
|
// (vs. being an about:addons subframe).
|
||||||
|
document.documentElement.className = "dialog-window";
|
||||||
|
|
||||||
|
const {
|
||||||
|
report,
|
||||||
|
deferredReport,
|
||||||
|
deferredReportPanel,
|
||||||
|
} = window.arguments[0].wrappedJSObject;
|
||||||
|
|
||||||
|
const el = document.querySelector("addon-abuse-report");
|
||||||
|
el.addEventListener("abuse-report:submit", () => {
|
||||||
|
deferredReport.resolve({
|
||||||
|
userCancelled: false,
|
||||||
|
report,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
el.addEventListener(
|
||||||
|
"abuse-report:cancel",
|
||||||
() => {
|
() => {
|
||||||
document.body.prepend(document.createElement("addon-abuse-report"));
|
deferredReport.resolve({ userCancelled: true });
|
||||||
},
|
},
|
||||||
{ once: true }
|
{ once: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Adjust window size (if needed) once the fluent strings have been
|
||||||
|
// added to the document and the document has been flushed.
|
||||||
|
el.addEventListener(
|
||||||
|
"abuse-report:updated",
|
||||||
|
async () => {
|
||||||
|
const form = document.querySelector("form");
|
||||||
|
await document.l10n.translateFragment(form);
|
||||||
|
const { clientWidth, clientHeight } = await window.promiseDocumentFlushed(
|
||||||
|
() => form
|
||||||
|
);
|
||||||
|
// Resolve promiseReportPanel once the panel completed the initial render
|
||||||
|
// (used in tests).
|
||||||
|
deferredReportPanel.resolve(el);
|
||||||
|
if (
|
||||||
|
window.innerWidth !== clientWidth ||
|
||||||
|
window.innerheight !== clientHeight
|
||||||
|
) {
|
||||||
|
window.resizeTo(clientWidth, clientHeight);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ once: true }
|
||||||
|
);
|
||||||
|
el.setAbuseReport(report);
|
||||||
|
}
|
||||||
|
|
|
@ -11,6 +11,10 @@
|
||||||
* helpers used for the Abuse Reporting submission (and related message bars).
|
* helpers used for the Abuse Reporting submission (and related message bars).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
const { AbuseReporter } = ChromeUtils.import(
|
||||||
|
"resource://gre/modules/AbuseReporter.jsm"
|
||||||
|
);
|
||||||
|
|
||||||
// Message Bars definitions.
|
// Message Bars definitions.
|
||||||
const ABUSE_REPORT_MESSAGE_BARS = {
|
const ABUSE_REPORT_MESSAGE_BARS = {
|
||||||
// Idle message-bar (used while the submission is still ongoing).
|
// Idle message-bar (used while the submission is still ongoing).
|
||||||
|
@ -73,14 +77,66 @@ const ABUSE_REPORT_MESSAGE_BARS = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function openAbuseReport({ addonId, reportEntryPoint }) {
|
async function openAbuseReport({ addonId, reportEntryPoint }) {
|
||||||
|
if (AbuseReporter.openDialogDisabled) {
|
||||||
document.dispatchEvent(
|
document.dispatchEvent(
|
||||||
new CustomEvent("abuse-report:new", {
|
new CustomEvent("abuse-report:new", {
|
||||||
detail: { addonId, reportEntryPoint },
|
detail: { addonId, reportEntryPoint },
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
// Helper function used to create abuse report message bars in the
|
||||||
// HTML about:addons page.
|
// HTML about:addons page.
|
||||||
function createReportMessageBar(
|
function createReportMessageBar(
|
||||||
|
@ -143,12 +199,20 @@ function createReportMessageBar(
|
||||||
return messagebar;
|
return messagebar;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function submitReport({ report, reason, message }) {
|
async function submitReport({ report }) {
|
||||||
const { addon } = report;
|
const { addon } = report;
|
||||||
const addonId = addon.id;
|
const addonId = addon.id;
|
||||||
const addonName = addon.name;
|
const addonName = addon.name;
|
||||||
const addonType = addon.type;
|
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.
|
// Create a message bar while we are still submitting the report.
|
||||||
const mbSubmitting = createReportMessageBar(
|
const mbSubmitting = createReportMessageBar(
|
||||||
"submitting",
|
"submitting",
|
||||||
|
@ -164,7 +228,7 @@ async function submitReport({ report, reason, message }) {
|
||||||
);
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await report.submit({ reason, message });
|
await report.submit();
|
||||||
mbSubmitting.remove();
|
mbSubmitting.remove();
|
||||||
|
|
||||||
// Create a submitted message bar when the submission has been
|
// Create a submitted message bar when the submission has been
|
||||||
|
@ -227,7 +291,7 @@ async function submitReport({ report, reason, message }) {
|
||||||
mbError.remove();
|
mbError.remove();
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case "retry":
|
case "retry":
|
||||||
submitReport({ report, reason, message });
|
submitReport({ report });
|
||||||
break;
|
break;
|
||||||
case "cancel":
|
case "cancel":
|
||||||
report.abort();
|
report.abort();
|
||||||
|
|
|
@ -773,10 +773,11 @@ add_task(async function test_abusereport_submit() {
|
||||||
|
|
||||||
const expectedDetail = {
|
const expectedDetail = {
|
||||||
addonId: extension.id,
|
addonId: extension.id,
|
||||||
reason: abuseReportEl.reason,
|
|
||||||
message: abuseReportEl.message,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const expectedReason = abuseReportEl.reason;
|
||||||
|
const expectedMessage = abuseReportEl.message;
|
||||||
|
|
||||||
let reportSubmitted;
|
let reportSubmitted;
|
||||||
const onReportSubmitted = new Promise(resolve => {
|
const onReportSubmitted = new Promise(resolve => {
|
||||||
apiRequestHandler = ({ data, request, response }) => {
|
apiRequestHandler = ({ data, request, response }) => {
|
||||||
|
@ -802,8 +803,6 @@ add_task(async function test_abusereport_submit() {
|
||||||
|
|
||||||
const actualDetail = {
|
const actualDetail = {
|
||||||
addonId: submitEvent.detail.addonId,
|
addonId: submitEvent.detail.addonId,
|
||||||
reason: submitEvent.detail.reason,
|
|
||||||
message: submitEvent.detail.message,
|
|
||||||
};
|
};
|
||||||
Assert.deepEqual(
|
Assert.deepEqual(
|
||||||
actualDetail,
|
actualDetail,
|
||||||
|
@ -838,12 +837,12 @@ add_task(async function test_abusereport_submit() {
|
||||||
);
|
);
|
||||||
is(
|
is(
|
||||||
reportSubmitted.reason,
|
reportSubmitted.reason,
|
||||||
expectedDetail.reason,
|
expectedReason,
|
||||||
"Got the expected reason in the submitted report"
|
"Got the expected reason in the submitted report"
|
||||||
);
|
);
|
||||||
is(
|
is(
|
||||||
reportSubmitted.message,
|
reportSubmitted.message,
|
||||||
expectedDetail.message,
|
expectedMessage,
|
||||||
"Got the expected message in the submitted report"
|
"Got the expected message in the submitted report"
|
||||||
);
|
);
|
||||||
is(
|
is(
|
||||||
|
|
|
@ -325,7 +325,9 @@ add_task(async function test_report_create_and_submit() {
|
||||||
};
|
};
|
||||||
|
|
||||||
info("Submitting report");
|
info("Submitting report");
|
||||||
await report.submit(reportProperties);
|
report.setMessage(reportProperties.message);
|
||||||
|
report.setReason(reportProperties.reason);
|
||||||
|
await report.submit();
|
||||||
|
|
||||||
const expectedEntries = Object.entries({
|
const expectedEntries = Object.entries({
|
||||||
report_entry_point: reportEntryPoint,
|
report_entry_point: reportEntryPoint,
|
||||||
|
@ -382,11 +384,10 @@ add_task(async function test_error_recent_submit() {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Submit the two reports in fast sequence.
|
// Submit the two reports in fast sequence.
|
||||||
await report.submit({ reason: "reason1" });
|
report.setReason("reason1");
|
||||||
await assertRejectsAbuseReportError(
|
report2.setReason("reason2");
|
||||||
report2.submit({ reason: "reason2" }),
|
await report.submit();
|
||||||
"ERROR_RECENT_SUBMIT"
|
await assertRejectsAbuseReportError(report2.submit(), "ERROR_RECENT_SUBMIT");
|
||||||
);
|
|
||||||
equal(
|
equal(
|
||||||
reportSubmitted.reason,
|
reportSubmitted.reason,
|
||||||
"reason1",
|
"reason1",
|
||||||
|
@ -443,7 +444,8 @@ add_task(async function test_submission_server_error() {
|
||||||
ADDON_ID,
|
ADDON_ID,
|
||||||
REPORT_OPTIONS
|
REPORT_OPTIONS
|
||||||
);
|
);
|
||||||
const promiseSubmit = report.submit({ reason: "a-reason" });
|
report.setReason("a-reason");
|
||||||
|
const promiseSubmit = report.submit();
|
||||||
if (typeof expectedErrorType === "string") {
|
if (typeof expectedErrorType === "string") {
|
||||||
// Assert a specific AbuseReportError errorType.
|
// Assert a specific AbuseReportError errorType.
|
||||||
await assertRejectsAbuseReportError(
|
await assertRejectsAbuseReportError(
|
||||||
|
@ -565,7 +567,8 @@ add_task(async function test_submission_aborting() {
|
||||||
ADDON_ID,
|
ADDON_ID,
|
||||||
REPORT_OPTIONS
|
REPORT_OPTIONS
|
||||||
);
|
);
|
||||||
const promiseResult = report.submit({ reason: "a-reason" });
|
report.setReason("a-reason");
|
||||||
|
const promiseResult = report.submit();
|
||||||
|
|
||||||
await onRequestReceived;
|
await onRequestReceived;
|
||||||
|
|
||||||
|
@ -624,7 +627,9 @@ add_task(async function test_truncated_string_properties() {
|
||||||
REPORT_OPTIONS
|
REPORT_OPTIONS
|
||||||
);
|
);
|
||||||
|
|
||||||
await report.submit({ message: "fake-message", reason: "fake-reason" });
|
report.setMessage("fake-message");
|
||||||
|
report.setReason("fake-reason");
|
||||||
|
await report.submit();
|
||||||
|
|
||||||
const expected = {
|
const expected = {
|
||||||
addon_name: generateString(255),
|
addon_name: generateString(255),
|
||||||
|
@ -686,7 +691,9 @@ add_task(async function test_report_recommended() {
|
||||||
addonId,
|
addonId,
|
||||||
REPORT_OPTIONS
|
REPORT_OPTIONS
|
||||||
);
|
);
|
||||||
await report.submit({ message: "fake-message", reason: "fake-reason" });
|
report.setMessage("fake-message");
|
||||||
|
report.setReason("fake-reason");
|
||||||
|
await report.submit();
|
||||||
equal(
|
equal(
|
||||||
reportSubmitted.addon_signature,
|
reportSubmitted.addon_signature,
|
||||||
expectedAddonSignature,
|
expectedAddonSignature,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче