michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: "use strict"; michael@0: michael@0: let Cc = Components.classes; michael@0: let Ci = Components.interfaces; michael@0: let Cu = Components.utils; michael@0: michael@0: this.EXPORTED_SYMBOLS = [ "TabCrashReporter" ]; michael@0: michael@0: Cu.import("resource://gre/modules/XPCOMUtils.jsm"); michael@0: Cu.import("resource://gre/modules/Services.jsm"); michael@0: michael@0: XPCOMUtils.defineLazyModuleGetter(this, "CrashSubmit", michael@0: "resource://gre/modules/CrashSubmit.jsm"); michael@0: michael@0: this.TabCrashReporter = { michael@0: init: function () { michael@0: if (this.initialized) michael@0: return; michael@0: this.initialized = true; michael@0: michael@0: Services.obs.addObserver(this, "ipc:content-shutdown", false); michael@0: Services.obs.addObserver(this, "oop-frameloader-crashed", false); michael@0: michael@0: this.childMap = new Map(); michael@0: this.browserMap = new WeakMap(); michael@0: }, michael@0: michael@0: observe: function (aSubject, aTopic, aData) { michael@0: switch (aTopic) { michael@0: case "ipc:content-shutdown": michael@0: aSubject.QueryInterface(Ci.nsIPropertyBag2); michael@0: michael@0: if (!aSubject.get("abnormal")) michael@0: return; michael@0: michael@0: this.childMap.set(aSubject.get("childID"), aSubject.get("dumpID")); michael@0: break; michael@0: michael@0: case "oop-frameloader-crashed": michael@0: aSubject.QueryInterface(Ci.nsIFrameLoader); michael@0: michael@0: let browser = aSubject.ownerElement; michael@0: if (!browser) michael@0: return; michael@0: michael@0: this.browserMap.set(browser, aSubject.childID); michael@0: break; michael@0: } michael@0: }, michael@0: michael@0: submitCrashReport: function (aBrowser) { michael@0: let childID = this.browserMap.get(aBrowser); michael@0: let dumpID = this.childMap.get(childID); michael@0: if (!dumpID) michael@0: return michael@0: michael@0: if (CrashSubmit.submit(dumpID)) { michael@0: this.childMap.set(childID, null); // Avoid resubmission. michael@0: } michael@0: }, michael@0: michael@0: onAboutTabCrashedLoad: function (aBrowser) { michael@0: if (!this.childMap) michael@0: return; michael@0: michael@0: let dumpID = this.childMap.get(this.browserMap.get(aBrowser)); michael@0: if (!dumpID) michael@0: return; michael@0: michael@0: aBrowser.contentDocument.documentElement.classList.add("crashDumpAvaible"); michael@0: } michael@0: }