1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 /* eslint-env mozilla/remote-page */
7 var AboutTabCrashed = {
9 * This can be set to true once this page receives a message from the
10 * parent saying whether or not a crash report is available.
15 * The messages that we might receive from the parent.
17 MESSAGES: ["SetCrashReportAvailable", "CrashReportSent", "UpdateCount"],
20 * Items for which we will listen for click events.
22 CLICK_TARGETS: ["closeTab", "restoreTab", "restoreAll", "sendReport"],
25 * Returns information about this crashed tab.
27 * @return (Object) An object with the following properties:
29 * The title of the page that crashed.
31 * The URL of the page that crashed.
36 let URL = document.documentURI;
37 let queryString = URL.replace(/^about:tabcrashed?e=tabcrashed/, "");
39 let titleMatch = queryString.match(/d=([^&]*)/);
40 let URLMatch = queryString.match(/u=([^&]*)/);
42 return (this.pageData = {
44 titleMatch && titleMatch[1] ? decodeURIComponent(titleMatch[1]) : "",
45 URL: URLMatch && URLMatch[1] ? decodeURIComponent(URLMatch[1]) : "",
50 addEventListener("DOMContentLoaded", this);
52 document.title = this.pageData.title;
55 receiveMessage(message) {
56 switch (message.name) {
58 this.setMultiple(message.data.count > 1);
61 case "SetCrashReportAvailable": {
62 this.onSetCrashReportAvailable(message);
65 case "CrashReportSent": {
66 this.onCrashReportSent();
74 case "DOMContentLoaded": {
75 this.onDOMContentLoaded();
85 onDOMContentLoaded() {
86 this.MESSAGES.forEach(msg =>
87 RPMAddMessageListener(msg, this.receiveMessage.bind(this))
90 this.CLICK_TARGETS.forEach(targetID => {
91 let el = document.getElementById(targetID);
92 el.addEventListener("click", this);
95 // Error pages are loaded as LOAD_BACKGROUND, so they don't get load events.
96 let event = new CustomEvent("AboutTabCrashedLoad", { bubbles: true });
97 document.dispatchEvent(event);
99 RPMSendAsyncMessage("Load");
103 switch (event.target.id) {
105 this.sendMessage("closeTab");
110 this.sendMessage("restoreTab");
115 this.sendMessage("restoreAll");
120 this.showCrashReportUI(event.target.checked);
127 * After this page tells the parent that it has loaded, the parent
128 * will respond with whether or not a crash report is available. This
129 * method handles that message.
132 * The message from the parent, which should contain a data
133 * Object property with the following properties:
136 * Whether or not there is a crash report.
139 * Whether or not the the user prefers to send the report
143 * Whether or not the user prefers to send the URL of
144 * the tab that crashed.
146 * requestAutoSubmit (bool):
147 * Whether or not we should ask the user to automatically
148 * submit backlogged crash reports.
151 onSetCrashReportAvailable(message) {
152 let data = message.data;
154 if (data.hasReport) {
155 this.hasReport = true;
156 document.documentElement.classList.add("crashDumpAvailable");
158 document.getElementById("sendReport").checked = data.sendReport;
159 document.getElementById("includeURL").checked = data.includeURL;
161 this.showCrashReportUI(data.sendReport);
163 this.showCrashReportUI(false);
166 if (data.requestAutoSubmit) {
167 document.getElementById("requestAutoSubmit").hidden = false;
170 let event = new CustomEvent("AboutTabCrashedReady", { bubbles: true });
171 document.dispatchEvent(event);
175 * Handler for when the parent reports that the crash report associated
176 * with this about:tabcrashed page has been sent.
178 onCrashReportSent() {
179 document.documentElement.classList.remove("crashDumpAvailable");
180 document.documentElement.classList.add("crashDumpSubmitted");
184 * Toggles the display of the crash report form.
186 * @param shouldShow (bool)
187 * True if the crash report form should be shown
189 showCrashReportUI(shouldShow) {
190 let options = document.getElementById("options");
191 options.hidden = !shouldShow;
195 * Toggles whether or not the page is one of several visible pages
196 * showing the crash reporter. This controls some of the language
197 * on the page, along with what the "primary" button is.
199 * @param hasMultiple (bool)
200 * True if there are multiple crash report pages being shown.
202 setMultiple(hasMultiple) {
203 let main = document.getElementById("main");
204 main.setAttribute("multiple", hasMultiple);
206 let restoreTab = document.getElementById("restoreTab");
208 // The "Restore All" button has the "primary" class by default, so
209 // we only need to modify the "Restore Tab" button.
211 restoreTab.classList.remove("primary");
213 restoreTab.classList.add("primary");
218 * Sends a message to the parent in response to the user choosing
219 * one of the actions available on the page. This might also send up
220 * crash report information if the user has chosen to submit a crash
223 * @param messageName (String)
224 * The message to send to the parent
226 sendMessage(messageName) {
229 let sendReport = false;
230 let includeURL = false;
231 let autoSubmit = false;
233 if (this.hasReport) {
234 sendReport = document.getElementById("sendReport").checked;
236 comments = document.getElementById("comments").value.trim();
238 includeURL = document.getElementById("includeURL").checked;
240 URL = this.pageData.URL.trim();
245 let requestAutoSubmit = document.getElementById("requestAutoSubmit");
246 if (requestAutoSubmit.hidden) {
247 // The checkbox is hidden if the user has already opted in to sending
248 // backlogged crash reports.
251 autoSubmit = document.getElementById("autoSubmit").checked;
254 RPMSendAsyncMessage(messageName, {
260 hasReport: this.hasReport,
265 AboutTabCrashed.init();