gecko/browser/modules/TabCrashReporter.jsm
Dave Townsend 053e14970a Bug 1112304: Update about:tabcrashed to match the new UX spec. r=dao
Uses in-content styles for the tab crash page and adds an overlay to the favicon
for crashed tabs. Adds support for closing the crashed tab. The strings here
also refer to being able to restore all tabs, that will be implemented and
landed at the same time in bug 1109650 to avoid l10n churn.

--HG--
extra : rebase_source : 7afc65aff19c4da16959adb09f82006ec541fa31
extra : amend_source : 4a8323e5c1a66fb4e2fafa96e4e5c8cf9814acba
2015-01-13 12:33:26 -08:00

102 lines
2.8 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/. */
"use strict";
let Cc = Components.classes;
let Ci = Components.interfaces;
let Cu = Components.utils;
this.EXPORTED_SYMBOLS = [ "TabCrashReporter" ];
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "CrashSubmit",
"resource://gre/modules/CrashSubmit.jsm");
this.TabCrashReporter = {
init: function () {
if (this.initialized)
return;
this.initialized = true;
Services.obs.addObserver(this, "ipc:content-shutdown", false);
Services.obs.addObserver(this, "oop-frameloader-crashed", false);
this.childMap = new Map();
this.browserMap = new WeakMap();
},
observe: function (aSubject, aTopic, aData) {
switch (aTopic) {
case "ipc:content-shutdown":
aSubject.QueryInterface(Ci.nsIPropertyBag2);
if (!aSubject.get("abnormal"))
return;
this.childMap.set(aSubject.get("childID"), aSubject.get("dumpID"));
break;
case "oop-frameloader-crashed":
aSubject.QueryInterface(Ci.nsIFrameLoader);
let browser = aSubject.ownerElement;
if (!browser)
return;
this.browserMap.set(browser, aSubject.childID);
break;
}
},
submitCrashReport: function (aBrowser) {
let childID = this.browserMap.get(aBrowser);
let dumpID = this.childMap.get(childID);
if (!dumpID)
return
if (CrashSubmit.submit(dumpID, { recordSubmission: true })) {
this.childMap.set(childID, null); // Avoid resubmission.
this.removeSubmitCheckboxesForSameCrash(childID);
}
},
removeSubmitCheckboxesForSameCrash: function(childID) {
let enumerator = Services.wm.getEnumerator("navigator:browser");
while (enumerator.hasMoreElements()) {
let window = enumerator.getNext();
if (!window.gMultiProcessBrowser)
continue;
for (let browser of window.gBrowser.browsers) {
if (browser.isRemoteBrowser)
continue;
let doc = browser.contentDocument;
if (!doc.documentURI.startsWith("about:tabcrashed"))
continue;
if (this.browserMap.get(browser) == childID) {
this.browserMap.delete(browser);
browser.contentDocument.documentElement.classList.remove("crashDumpAvailable");
browser.contentDocument.documentElement.classList.add("crashDumpSubmitted");
}
}
}
},
onAboutTabCrashedLoad: function (aBrowser) {
if (!this.childMap)
return;
let dumpID = this.childMap.get(this.browserMap.get(aBrowser));
if (!dumpID)
return;
aBrowser.contentDocument.documentElement.classList.add("crashDumpAvailable");
}
}