Bug 411490: Add about:crashes for easier access to crash reports. r=mano, a=beltzner
This commit is contained in:
Родитель
70b6efb1bf
Коммит
f7e006e23f
|
@ -70,6 +70,9 @@ static RedirEntry kRedirMap[] = {
|
|||
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT },
|
||||
{ "plugins", "chrome://global/content/plugins.html", 0 },
|
||||
{ "config", "chrome://global/content/config.xul", 0 },
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
{ "crashes", "chrome://global/content/crashes.xhtml", 0 },
|
||||
#endif
|
||||
#ifdef MOZ_XUL_APP
|
||||
{ "logo", "chrome://branding/content/about.png",
|
||||
#else
|
||||
|
|
|
@ -156,6 +156,13 @@ static const nsModuleComponentInfo gDocShellModuleInfo[] = {
|
|||
NS_ABOUT_MODULE_CONTRACTID_PREFIX "config",
|
||||
nsAboutRedirector::Create
|
||||
},
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
{ "about:crashes",
|
||||
NS_ABOUT_REDIRECTOR_MODULE_CID,
|
||||
NS_ABOUT_MODULE_CONTRACTID_PREFIX "crashes",
|
||||
nsAboutRedirector::Create
|
||||
},
|
||||
#endif
|
||||
{ "about:credits",
|
||||
NS_ABOUT_REDIRECTOR_MODULE_CID,
|
||||
NS_ABOUT_MODULE_CONTRACTID_PREFIX "credits",
|
||||
|
|
|
@ -0,0 +1,206 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
|
||||
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"
|
||||
[
|
||||
<!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
|
||||
<!ENTITY % crashesDTD SYSTEM "chrome://global/locale/crashes.dtd">
|
||||
%globalDTD;
|
||||
%crashesDTD;
|
||||
]>
|
||||
|
||||
#ifdef MOZ_THUNDERBIRD
|
||||
#ifdef XP_MACOSX
|
||||
#define FORCE_DIR
|
||||
#endif
|
||||
#endif
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<style type="text/css">
|
||||
:root {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
table {
|
||||
padding-bottom: 2em;
|
||||
}
|
||||
th {
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
}
|
||||
/* name */
|
||||
th:first-child {
|
||||
-moz-padding-end: 2em;
|
||||
}
|
||||
/* date */
|
||||
td:first-child + td {
|
||||
-moz-padding-start: 1em;
|
||||
-moz-padding-end: .5em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
/* time */
|
||||
td:last-child {
|
||||
-moz-padding-start: .5em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.clear-reports {
|
||||
float: right;
|
||||
}
|
||||
|
||||
th[chromedir="rtl"] {
|
||||
text-align: right;
|
||||
}
|
||||
.clear-reports[chromedir="rtl"] {
|
||||
float: left;
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" media="screen, projection" type="text/css"
|
||||
href="chrome://global/skin/dirListing/dirListing.css"/>
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
var reportsDir;
|
||||
|
||||
function findInsertionPoint(reports, date) {
|
||||
if (reports.length == 0)
|
||||
return 0;
|
||||
|
||||
var min = 0;
|
||||
var max = reports.length - 1;
|
||||
while (min < max) {
|
||||
var mid = parseInt((min + max) / 2);
|
||||
if (reports[mid].date < date)
|
||||
max = mid - 1;
|
||||
else if (reports[mid].date > date)
|
||||
min = mid + 1;
|
||||
else
|
||||
return mid;
|
||||
}
|
||||
if (reports[min].date <= date)
|
||||
return min;
|
||||
return min+1;
|
||||
}
|
||||
|
||||
function populateReportList() {
|
||||
var prefService = Cc["@mozilla.org/preferences-service;1"].
|
||||
getService(Ci.nsIPrefBranch);
|
||||
var reportURL = prefService.getCharPref("breakpad.reportURL");
|
||||
var directoryService = Cc["@mozilla.org/file/directory_service;1"].
|
||||
getService(Ci.nsIProperties);
|
||||
|
||||
#ifdef FORCE_DIR
|
||||
var app = Cc["@mozilla.org/xre/app-info;1"].
|
||||
getService(Ci.nsIXULAppInfo);
|
||||
|
||||
// Doesn't appear to be a key for the app support directory
|
||||
reportsDir = directoryService.get("ULibDir", Ci.nsIFile);
|
||||
reportsDir.append("Application Support");
|
||||
reportsDir.append(app.name);
|
||||
#else
|
||||
reportsDir = directoryService.get("UAppData", Ci.nsIFile);
|
||||
#endif
|
||||
reportsDir.append("Crash Reports");
|
||||
reportsDir.append("submitted");
|
||||
|
||||
var reports = [];
|
||||
if (reportsDir.exists() && reportsDir.isDirectory()) {
|
||||
var entries = reportsDir.directoryEntries;
|
||||
while (entries.hasMoreElements()) {
|
||||
var file = entries.getNext().QueryInterface(Ci.nsIFile);
|
||||
var leaf = file.leafName;
|
||||
if (leaf.substring(0, 3) == "bp-" &&
|
||||
leaf.substring(leaf.length - 4) == ".txt") {
|
||||
var entry = {
|
||||
id: leaf.substring(3, leaf.length - 4),
|
||||
date: file.lastModifiedTime
|
||||
};
|
||||
var pos = findInsertionPoint(reports, entry.date);
|
||||
reports.splice(pos, 0, entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (reports.length == 0) {
|
||||
document.getElementById("reportList").style.display = "none";
|
||||
document.getElementById("noReports").style.display = "block";
|
||||
return;
|
||||
}
|
||||
|
||||
var formatter = Cc["@mozilla.org/intl/scriptabledateformat;1"].
|
||||
createInstance(Ci.nsIScriptableDateFormat);
|
||||
var body = document.getElementById("tbody");
|
||||
for (var i = 0; i < reports.length; i++) {
|
||||
var row = document.createElement("tr");
|
||||
var cell = document.createElement("td");
|
||||
row.appendChild(cell);
|
||||
var link = document.createElement("a");
|
||||
link.setAttribute("href", reportURL + reports[i].id);
|
||||
link.appendChild(document.createTextNode(reports[i].id));
|
||||
cell.appendChild(link);
|
||||
|
||||
var date = new Date(reports[i].date);
|
||||
cell = document.createElement("td");
|
||||
var datestr = formatter.FormatDate("",
|
||||
Ci.nsIScriptableDateFormat.dateFormatShort,
|
||||
date.getFullYear(),
|
||||
date.getMonth() + 1,
|
||||
date.getDate());
|
||||
cell.appendChild(document.createTextNode(datestr));
|
||||
row.appendChild(cell);
|
||||
cell = document.createElement("td");
|
||||
var timestr = formatter.FormatTime("",
|
||||
Ci.nsIScriptableDateFormat.timeFormatNoSeconds,
|
||||
date.getHours(),
|
||||
date.getMinutes(),
|
||||
date.getSeconds());
|
||||
cell.appendChild(document.createTextNode(timestr));
|
||||
row.appendChild(cell);
|
||||
body.appendChild(row);
|
||||
}
|
||||
}
|
||||
|
||||
function clearReports() {
|
||||
var bundles = Cc["@mozilla.org/intl/stringbundle;1"].
|
||||
getService(Ci.nsIStringBundleService);
|
||||
var bundle = bundles.createBundle("chrome://global/locale/crashes.properties");
|
||||
var prompts = Cc["@mozilla.org/embedcomp/prompt-service;1"].
|
||||
getService(Ci.nsIPromptService);
|
||||
if (!prompts.confirm(window,
|
||||
bundle.GetStringFromName("deleteconfirm.title"),
|
||||
bundle.GetStringFromName("deleteconfirm.description")))
|
||||
return;
|
||||
|
||||
var entries = reportsDir.directoryEntries;
|
||||
while (entries.hasMoreElements()) {
|
||||
var file = entries.getNext().QueryInterface(Ci.nsIFile);
|
||||
var leaf = file.leafName;
|
||||
if (leaf.substring(0, 3) == "bp-" &&
|
||||
leaf.substring(leaf.length - 4) == ".txt") {
|
||||
file.remove(false);
|
||||
}
|
||||
}
|
||||
document.getElementById("reportList").style.display = "none";
|
||||
document.getElementById("noReports").style.display = "block";
|
||||
}
|
||||
]]>
|
||||
</script>
|
||||
<title>&crashes.title;</title>
|
||||
</head><body onload="populateReportList()" dir="&locale.dir;">
|
||||
<button chromedir="&locale.dir;" class="clear-reports"
|
||||
onclick="clearReports()">&clearReports.label;</button>
|
||||
<h1>&crashes.title;</h1>
|
||||
<div id="reportList">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th chromedir="&locale.dir;">&id.heading;</th>
|
||||
<th chromedir="&locale.dir;" colspan="2">&date.heading;</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="tbody">
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p id="noReports" style="display: none">&noReports.label;</p>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,2 @@
|
|||
toolkit.jar:
|
||||
*+ content/global/crashes.xhtml (content/crashes.xhtml)
|
|
@ -0,0 +1,5 @@
|
|||
<!ENTITY crashes.title "Submitted Crash Reports">
|
||||
<!ENTITY id.heading "Report ID">
|
||||
<!ENTITY date.heading "Date Submitted">
|
||||
<!ENTITY noReports.label "No crash reports have been submitted.">
|
||||
<!ENTITY clearReports.label "Remove Reports">
|
|
@ -0,0 +1,2 @@
|
|||
deleteconfirm.title=Are you sure?
|
||||
deleteconfirm.description=This will delete all reports and cannot be undone
|
|
@ -56,6 +56,8 @@
|
|||
locale/@AB_CD@/global/nsProgressDialog.properties (%chrome/global/nsProgressDialog.properties)
|
||||
locale/@AB_CD@/global/history/history.properties (%chrome/global/history/history.properties)
|
||||
locale/@AB_CD@/global/xpinstall/xpinstall.properties (%chrome/global/xpinstall/xpinstall.properties)
|
||||
locale/@AB_CD@/global/crashes.dtd (%crashreporter/crashes.dtd)
|
||||
locale/@AB_CD@/global/crashes.properties (%crashreporter/crashes.properties)
|
||||
% locale global-region @AB_CD@ %locale/@AB_CD@/global-region/
|
||||
+ locale/@AB_CD@/global-region/region.dtd (%chrome/global-region/region.dtd)
|
||||
+ locale/@AB_CD@/global-region/region.properties (%chrome/global-region/region.properties)
|
||||
|
|
Загрузка…
Ссылка в новой задаче