Bug 1110511 - Add comment and email input to about:tabcrashed. r=felipe,ntim

Original patch by Ursula Sarracini
This commit is contained in:
Mike Conley 2015-09-30 17:50:48 -04:00
parent 54c5fbc0c6
commit 4859e86f4f
8 changed files with 200 additions and 16 deletions

View File

@ -1882,6 +1882,12 @@ pref("browser.tabs.remote.autostart.1", false);
pref("browser.tabs.remote.autostart.2", true);
#endif
// For the about:tabcrashed page
pref("browser.tabs.crashReporting.sendReport", true);
pref("browser.tabs.crashReporting.includeURL", false);
pref("browser.tabs.crashReporting.emailMe", false);
pref("browser.tabs.crashReporting.email", "");
#ifdef NIGHTLY_BUILD
#ifndef MOZ_MULET
pref("layers.async-pan-zoom.enabled", true);

View File

@ -3,27 +3,66 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
function parseQueryString() {
let url = document.documentURI;
let queryString = url.replace(/^about:tabcrashed?e=tabcrashed/, "");
let URL = document.documentURI;
let queryString = URL.replace(/^about:tabcrashed?e=tabcrashed/, "");
let titleMatch = queryString.match(/d=([^&]*)/);
return titleMatch && titleMatch[1] ? decodeURIComponent(titleMatch[1]) : "";
let URLMatch = queryString.match(/u=([^&]*)/);
return {
title: titleMatch && titleMatch[1] ? decodeURIComponent(titleMatch[1]) : "",
URL: URLMatch && URLMatch[1] ? decodeURIComponent(URLMatch[1]) : "",
};
}
document.title = parseQueryString();
function displayUI() {
if (!hasReport()) {
return;
}
function shouldSendReport() {
if (!document.documentElement.classList.contains("crashDumpAvailable"))
return false;
return document.getElementById("sendReport").checked;
let sendCrashReport = document.getElementById("sendReport").checked;
let container = document.getElementById("crash-reporter-container");
container.hidden = !sendCrashReport;
}
function hasReport() {
return document.documentElement.classList.contains("crashDumpAvailable");
}
function sendEvent(message) {
let comments = "";
let email = "";
let URL = "";
let sendCrashReport = false;
let emailMe = false;
let includeURL = false;
if (hasReport()) {
sendCrashReport = document.getElementById("sendReport").checked;
if (sendCrashReport) {
comments = document.getElementById("comments").value.trim();
includeURL = document.getElementById("includeURL").checked;
if (includeURL) {
URL = parseQueryString().URL.trim();
}
emailMe = document.getElementById("emailMe").checked;
if (emailMe) {
email = document.getElementById("email").value.trim();
}
}
}
let event = new CustomEvent("AboutTabCrashedMessage", {
bubbles: true,
detail: {
message,
sendCrashReport: shouldSendReport(),
sendCrashReport,
comments,
email,
emailMe,
includeURL,
URL,
},
});
@ -42,6 +81,17 @@ function restoreAll() {
sendEvent("restoreAll");
}
document.title = parseQueryString().title;
// Error pages are loaded as LOAD_BACKGROUND, so they don't get load events.
var event = new CustomEvent("AboutTabCrashedLoad", {bubbles:true});
document.dispatchEvent(event);
addEventListener("DOMContentLoaded", function() {
let sendReport = document.getElementById("sendReport");
sendReport.addEventListener("click", function() {
displayUI();
});
displayUI();
});

View File

@ -37,8 +37,22 @@
<p>&tabCrashed.message;</p>
<div id="report-box">
<input type="checkbox" id="sendReport" checked="checked"/>
<input type="checkbox" id="sendReport"/>
<label for="sendReport">&tabCrashed.sendReport;</label>
<div id="crash-reporter-container" hidden="true">
<p id="crash-reporter-title">&tabCrashed.crashReporter;</p>
<textarea id="comments" placeholder="&tabCrashed.commentPlaceholder;" rows="4"></textarea>
<ul id="options">
<li><input type="checkbox" id="includeURL"/>
<label for="includeURL">&tabCrashed.includeURL;</label></li>
<li><input type="checkbox" id="emailMe"/>
<label for="emailMe">&tabCrashed.emailMe;</label></li>
</ul>
<input type="text" id="email" placeholder="&tabCrashed.emailPlaceholder;"/>
</div>
</div>
<p id="reportSent">&tabCrashed.reportSent;</p>

View File

@ -1166,7 +1166,15 @@ var gBrowserInit = {
let browser = gBrowser.getBrowserForDocument(ownerDoc);
#ifdef MOZ_CRASHREPORTER
if (event.detail.sendCrashReport) {
TabCrashReporter.submitCrashReport(browser);
TabCrashReporter.submitCrashReport(browser, {
comments: event.detail.comments,
email: event.detail.email,
emailMe: event.detail.emailMe,
includeURL: event.detail.includeURL,
URL: event.detail.URL,
});
} else {
TabCrashReporter.dontSubmitCrashReport();
}
#endif

View File

@ -5,6 +5,11 @@
<!ENTITY tabCrashed.header "Bad news first: This tab has crashed">
<!ENTITY tabCrashed.message "Now for the good news: You can just close this tab, restore it or restore all your crashed tabs.">
<!ENTITY tabCrashed.sendReport "Submit a crash report to help prevent more bad news">
<!ENTITY tabCrashed.includeURL "Include the address of the page I was on">
<!ENTITY tabCrashed.commentPlaceholder "Add a comment (comments are publicly visible)">
<!ENTITY tabCrashed.emailPlaceholder "Enter your email address here">
<!ENTITY tabCrashed.emailMe "Email me when more information is available">
<!ENTITY tabCrashed.crashReporter "Mozilla Crash Reporter">
<!ENTITY tabCrashed.reportSent "Crash report already submitted; thank you for helping make &brandShortName; better!">
<!ENTITY tabCrashed.closeTab "Close This Tab">
<!ENTITY tabCrashed.restoreTab "Restore This Tab">

View File

@ -17,6 +17,11 @@ XPCOMUtils.defineLazyModuleGetter(this, "CrashSubmit",
"resource://gre/modules/CrashSubmit.jsm");
this.TabCrashReporter = {
get prefs() {
delete this.prefs;
return this.prefs = Services.prefs.getBranch("browser.tabs.crashReporting.");
},
init: function () {
if (this.initialized)
return;
@ -52,6 +57,31 @@ this.TabCrashReporter = {
}
},
/**
* Submits a crash report from about:tabcrashed
*
* @param aBrowser
* The <xul:browser> that the report was sent from.
* @param aFormData
* An Object with the following properties:
*
* includeURL (bool):
* Whether to include the URL that the user was on
* in the crashed tab before the crash occurred.
* URL (String)
* The URL that the user was on in the crashed tab
* before the crash occurred.
* emailMe (bool):
* Whether or not to include the user's email address
* in the crash report.
* email (String):
* The email address of the user.
* comments (String):
* Any additional comments from the user.
*
* Note that it is expected that all properties are set,
* even if they are empty.
*/
submitCrashReport: function (aBrowser, aFormData) {
let childID = this.browserMap.get(aBrowser.permanentKey);
let dumpID = this.childMap.get(childID);
@ -67,10 +97,23 @@ this.TabCrashReporter = {
},
}).then(null, Cu.reportError);
this.prefs.setBoolPref("sendReport", true);
this.prefs.setBoolPref("includeURL", aFormData.includeURL);
this.prefs.setBoolPref("emailMe", aFormData.emailMe);
if (aFormData.emailMe) {
this.prefs.setCharPref("email", aFormData.email);
} else {
this.prefs.setCharPref("email", "");
}
this.childMap.set(childID, null); // Avoid resubmission.
this.removeSubmitCheckboxesForSameCrash(childID);
},
dontSubmitCrashReport: function() {
this.prefs.setBoolPref("sendReport", false);
},
removeSubmitCheckboxesForSameCrash: function(childID) {
let enumerator = Services.wm.getEnumerator("navigator:browser");
while (enumerator.hasMoreElements()) {
@ -108,7 +151,23 @@ this.TabCrashReporter = {
if (!dumpID)
return;
aBrowser.contentDocument.documentElement.classList.add("crashDumpAvailable");
let doc = aBrowser.contentDocument;
doc.documentElement.classList.add("crashDumpAvailable");
let sendReport = this.prefs.getBoolPref("sendReport");
doc.getElementById("sendReport").checked = sendReport;
let includeURL = this.prefs.getBoolPref("includeURL");
doc.getElementById("includeURL").checked = includeURL;
let emailMe = this.prefs.getBoolPref("emailMe");
doc.getElementById("emailMe").checked = emailMe;
if (emailMe) {
let email = this.prefs.getCharPref("email", "");
doc.getElementById("email").value = email;
}
},
hideRestoreAllButton: function (aBrowser) {

View File

@ -9,3 +9,34 @@
#reportSent {
font-weight: bold;
}
#crash-reporter-container {
width: 80%;
background-color: var(--in-content-box-background-hover);
margin: 24px 0;
padding: 14px;
border: 1px solid var(--in-content-box-border-color);
border-radius: 2px;
}
#crash-reporter-title {
font-weight: bold;
margin: 0 0 14px 0;
}
input[type="text"],
textarea {
width: 100%;
box-sizing: border-box;
resize: none;
}
#options {
list-style: none;
margin-inline-start: 0;
}
input[type="text"],
#options > li {
margin: 14px 0 0 0;
}

View File

@ -406,13 +406,11 @@ xul|button[type="menu"] > xul|menupopup xul|menuseparator {
/* textboxes */
html|input[type="text"],
html|textarea,
xul|textbox {
-moz-appearance: none;
height: 30px;
color: var(--in-content-text-color);
line-height: 20px;
padding-right: 10px;
padding-left: 10px;
border: 1px solid var(--in-content-box-border-color);
-moz-border-top-colors: none !important;
-moz-border-right-colors: none !important;
@ -422,6 +420,19 @@ xul|textbox {
background-color: var(--in-content-box-background);
}
xul|textbox {
min-height: 30px;
padding-right: 10px;
padding-left: 10px;
}
html|input[type="text"],
html|textarea {
font-family: inherit;
font-size: inherit;
padding: 5px 10px;
}
html|input[type="text"]:focus,
html|textarea:focus,
xul|textbox[focused] {