forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			306 lines
		
	
	
	
		
			8.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			306 lines
		
	
	
	
		
			8.4 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-env mozilla/frame-script */
 | |
| 
 | |
| 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;
 | |
|       }
 | |
|       case "input": {
 | |
|         this.onInput(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);
 | |
|     });
 | |
| 
 | |
|     // For setting "emailMe" checkbox automatically on email value change.
 | |
|     document.getElementById("email").addEventListener("input", 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;
 | |
|       }
 | |
|     }
 | |
|   },
 | |
| 
 | |
|   onInput(event) {
 | |
|     switch (event.target.id) {
 | |
|       case "email": {
 | |
|         document.getElementById("emailMe").checked = !!event.target.value;
 | |
|         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.
 | |
|    *
 | |
|    *        emailMe (bool):
 | |
|    *          Whether or not to send the email address of the user
 | |
|    *          in the report.
 | |
|    *
 | |
|    *        email (String):
 | |
|    *          The email address of the user (empty if emailMe is false).
 | |
|    *
 | |
|    *        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;
 | |
| 
 | |
|       if (data.requestEmail) {
 | |
|         document.getElementById("requestEmail").hidden = false;
 | |
|         document.getElementById("emailMe").checked = data.emailMe;
 | |
|         if (data.emailMe) {
 | |
|           document.getElementById("email").value = data.email;
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       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 email = "";
 | |
|     let URL = "";
 | |
|     let sendReport = false;
 | |
|     let emailMe = 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();
 | |
|         }
 | |
| 
 | |
|         if (!document.getElementById("requestEmail").hidden) {
 | |
|           emailMe = document.getElementById("emailMe").checked;
 | |
|           if (emailMe) {
 | |
|             email = document.getElementById("email").value.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,
 | |
|       email,
 | |
|       emailMe,
 | |
|       includeURL,
 | |
|       URL,
 | |
|       autoSubmit,
 | |
|       hasReport: this.hasReport,
 | |
|     });
 | |
|   },
 | |
| };
 | |
| 
 | |
| AboutTabCrashed.init();
 | 
