/* 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-env mozilla/remote-page */
var AboutTabCrashed = {
/**
* This can be set to true once this page receives a message from the
* parent saying whether or not a crash report is available.
*/
hasReport:
false,
/**
* The messages that we might receive from the parent.
*/
MESSAGES: [
"SetCrashReportAvailable",
"CrashReportSent",
"UpdateCount"],
/**
* Items for which we will listen for click events.
*/
CLICK_TARGETS: [
"closeTab",
"restoreTab",
"restoreAll",
"sendReport"],
/**
* Returns information about this crashed tab.
*
* @return (Object) An object with the following properties:
* title (String):
* The title of the page that crashed.
* URL (String):
* The URL of the page that crashed.
*/
get pageData() {
delete this.pageData;
let URL = document.documentURI;
let queryString = URL.replace(/^about:tabcrashed?e=tabcrashed/,
"");
let titleMatch = queryString.match(/d=([^&]*)/);
let URLMatch = queryString.match(/u=([^&]*)/);
return (
this.pageData = {
title:
titleMatch && titleMatch[1] ? decodeURIComponent(titleMatch[1]) :
"",
URL: URLMatch && URLMatch[1] ? decodeURIComponent(URLMatch[1]) :
"",
});
},
init() {
addEventListener(
"DOMContentLoaded",
this);
document.title =
this.pageData.title;
},
receiveMessage(message) {
switch (message.name) {
case "UpdateCount": {
this.setMultiple(message.data.count > 1);
break;
}
case "SetCrashReportAvailable": {
this.onSetCrashReportAvailable(message);
break;
}
case "CrashReportSent": {
this.onCrashReportSent();
break;
}
}
},
handleEvent(event) {
switch (event.type) {
case "DOMContentLoaded": {
this.onDOMContentLoaded();
break;
}
case "click": {
this.onClick(event);
break;
}
}
},
onDOMContentLoaded() {
this.MESSAGES.forEach(msg =>
RPMAddMessageListener(msg,
this.receiveMessage.bind(
this))
);
this.CLICK_TARGETS.forEach(targetID => {
let el = document.getElementById(targetID);
el.addEventListener(
"click",
this);
});
// Error pages are loaded as LOAD_BACKGROUND, so they don't get load events.
let event =
new CustomEvent(
"AboutTabCrashedLoad", { bubbles:
true });
document.dispatchEvent(event);
RPMSendAsyncMessage(
"Load");
},
onClick(event) {
switch (event.target.id) {
case "closeTab": {
this.sendMessage(
"closeTab");
break;
}
case "restoreTab": {
this.sendMessage(
"restoreTab");
break;
}
case "restoreAll": {
this.sendMessage(
"restoreAll");
break;
}
case "sendReport": {
this.showCrashReportUI(event.target.checked);
break;
}
}
},
/**
* After this page tells the parent that it has loaded, the parent
* will respond with whether or not a crash report is available. This
* method handles that message.
*
* @param message
* The message from the parent, which should contain a data
* Object property with the following properties:
*
* hasReport (bool):
* Whether or not there is a crash report.
*
* sendReport (bool):
* Whether or not the the user prefers to send the report
* by default.
*
* includeURL (bool):
* Whether or not the user prefers to send the URL of
* the tab that crashed.
*
* requestAutoSubmit (bool):
* Whether or not we should ask the user to automatically
* submit backlogged crash reports.
*
*/
onSetCrashReportAvailable(message) {
let data = message.data;
if (data.hasReport) {
this.hasReport =
true;
document.documentElement.classList.add(
"crashDumpAvailable");
document.getElementById(
"sendReport").checked = data.sendReport;
document.getElementById(
"includeURL").checked = data.includeURL;
this.showCrashReportUI(data.sendReport);
}
else {
this.showCrashReportUI(
false);
}
if (data.requestAutoSubmit) {
document.getElementById(
"requestAutoSubmit").hidden =
false;
}
let event =
new CustomEvent(
"AboutTabCrashedReady", { bubbles:
true });
document.dispatchEvent(event);
},
/**
* Handler for when the parent reports that the crash report associated
* with this about:tabcrashed page has been sent.
*/
onCrashReportSent() {
document.documentElement.classList.remove(
"crashDumpAvailable");
document.documentElement.classList.add(
"crashDumpSubmitted");
},
/**
* Toggles the display of the crash report form.
*
* @param shouldShow (bool)
* True if the crash report form should be shown
*/
showCrashReportUI(shouldShow) {
let options = document.getElementById(
"options");
options.hidden = !shouldShow;
},
/**
* Toggles whether or not the page is one of several visible pages
* showing the crash reporter. This controls some of the language
* on the page, along with what the "primary" button is.
*
* @param hasMultiple (bool)
* True if there are multiple crash report pages being shown.
*/
setMultiple(hasMultiple) {
let main = document.getElementById(
"main");
main.setAttribute(
"multiple", hasMultiple);
let restoreTab = document.getElementById(
"restoreTab");
// The "Restore All" button has the "primary" class by default, so
// we only need to modify the "Restore Tab" button.
if (hasMultiple) {
restoreTab.classList.remove(
"primary");
}
else {
restoreTab.classList.add(
"primary");
}
},
/**
* Sends a message to the parent in response to the user choosing
* one of the actions available on the page. This might also send up
* crash report information if the user has chosen to submit a crash
* report.
*
* @param messageName (String)
* The message to send to the parent
*/
sendMessage(messageName) {
let comments =
"";
let URL =
"";
let sendReport =
false;
let includeURL =
false;
let autoSubmit =
false;
if (
this.hasReport) {
sendReport = document.getElementById(
"sendReport").checked;
if (sendReport) {
comments = document.getElementById(
"comments").value.trim();
includeURL = document.getElementById(
"includeURL").checked;
if (includeURL) {
URL =
this.pageData.URL.trim();
}
}
}
let requestAutoSubmit = document.getElementById(
"requestAutoSubmit");
if (requestAutoSubmit.hidden) {
// The checkbox is hidden if the user has already opted in to sending
// backlogged crash reports.
autoSubmit =
true;
}
else {
autoSubmit = document.getElementById(
"autoSubmit").checked;
}
RPMSendAsyncMessage(messageName, {
sendReport,
comments,
includeURL,
URL,
autoSubmit,
hasReport:
this.hasReport,
});
},
};
AboutTabCrashed.init();