|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 const { classes: Cc, utils: Cu, interfaces: Ci } = Components; |
|
6 |
|
7 var reportURL; |
|
8 |
|
9 Cu.import("resource://gre/modules/CrashReports.jsm"); |
|
10 Cu.import("resource://gre/modules/Services.jsm"); |
|
11 Cu.import("resource://gre/modules/XPCOMUtils.jsm"); |
|
12 Cu.import("resource://gre/modules/Task.jsm"); |
|
13 Cu.import("resource://gre/modules/osfile.jsm"); |
|
14 |
|
15 XPCOMUtils.defineLazyModuleGetter(this, "CrashSubmit", |
|
16 "resource://gre/modules/CrashSubmit.jsm"); |
|
17 |
|
18 const buildID = Services.appinfo.appBuildID; |
|
19 |
|
20 function submitSuccess(dumpid, ret) { |
|
21 let link = document.getElementById(dumpid); |
|
22 if (link) { |
|
23 link.className = ""; |
|
24 // reset the link to point at our new crash report. this way, if the |
|
25 // user clicks "Back", the link will be correct. |
|
26 let CrashID = ret.CrashID; |
|
27 link.firstChild.textContent = CrashID; |
|
28 link.setAttribute("id", CrashID); |
|
29 link.removeEventListener("click", submitPendingReport, true); |
|
30 |
|
31 if (reportURL) { |
|
32 link.setAttribute("href", reportURL + CrashID); |
|
33 // redirect the user to their brand new crash report |
|
34 window.location.href = reportURL + CrashID; |
|
35 } |
|
36 } |
|
37 } |
|
38 |
|
39 function submitError(dumpid) { |
|
40 //XXX: do something more useful here |
|
41 let link = document.getElementById(dumpid); |
|
42 if (link) |
|
43 link.className = ""; |
|
44 // dispatch an event, useful for testing |
|
45 let event = document.createEvent("Events"); |
|
46 event.initEvent("CrashSubmitFailed", true, false); |
|
47 document.dispatchEvent(event); |
|
48 } |
|
49 |
|
50 function submitPendingReport(event) { |
|
51 var link = event.target; |
|
52 var id = link.firstChild.textContent; |
|
53 if (CrashSubmit.submit(id, { submitSuccess: submitSuccess, |
|
54 submitError: submitError, |
|
55 noThrottle: true })) { |
|
56 link.className = "submitting"; |
|
57 } |
|
58 event.preventDefault(); |
|
59 return false; |
|
60 } |
|
61 |
|
62 function populateReportList() { |
|
63 var prefService = Cc["@mozilla.org/preferences-service;1"]. |
|
64 getService(Ci.nsIPrefBranch); |
|
65 |
|
66 try { |
|
67 reportURL = prefService.getCharPref("breakpad.reportURL"); |
|
68 // Ignore any non http/https urls |
|
69 if (!/^https?:/i.test(reportURL)) |
|
70 reportURL = null; |
|
71 } |
|
72 catch (e) { } |
|
73 if (!reportURL) { |
|
74 document.getElementById("clear-reports").style.display = "none"; |
|
75 document.getElementById("reportList").style.display = "none"; |
|
76 document.getElementById("noConfig").style.display = "block"; |
|
77 return; |
|
78 } |
|
79 let reports = CrashReports.getReports(); |
|
80 |
|
81 if (reports.length == 0) { |
|
82 document.getElementById("clear-reports").style.display = "none"; |
|
83 document.getElementById("reportList").style.display = "none"; |
|
84 document.getElementById("noReports").style.display = "block"; |
|
85 return; |
|
86 } |
|
87 |
|
88 var formatter = Cc["@mozilla.org/intl/scriptabledateformat;1"]. |
|
89 createInstance(Ci.nsIScriptableDateFormat); |
|
90 var body = document.getElementById("tbody"); |
|
91 var ios = Cc["@mozilla.org/network/io-service;1"]. |
|
92 getService(Ci.nsIIOService); |
|
93 var reportURI = ios.newURI(reportURL, null, null); |
|
94 // resolving this URI relative to /report/index |
|
95 var aboutThrottling = ios.newURI("../../about/throttling", null, reportURI); |
|
96 |
|
97 for (var i = 0; i < reports.length; i++) { |
|
98 var row = document.createElement("tr"); |
|
99 var cell = document.createElement("td"); |
|
100 row.appendChild(cell); |
|
101 var link = document.createElement("a"); |
|
102 if (reports[i].pending) { |
|
103 link.setAttribute("href", aboutThrottling.spec); |
|
104 link.addEventListener("click", submitPendingReport, true); |
|
105 } |
|
106 else { |
|
107 link.setAttribute("href", reportURL + reports[i].id); |
|
108 } |
|
109 link.setAttribute("id", reports[i].id); |
|
110 link.appendChild(document.createTextNode(reports[i].id)); |
|
111 cell.appendChild(link); |
|
112 |
|
113 var date = new Date(reports[i].date); |
|
114 cell = document.createElement("td"); |
|
115 var datestr = formatter.FormatDate("", |
|
116 Ci.nsIScriptableDateFormat.dateFormatShort, |
|
117 date.getFullYear(), |
|
118 date.getMonth() + 1, |
|
119 date.getDate()); |
|
120 cell.appendChild(document.createTextNode(datestr)); |
|
121 row.appendChild(cell); |
|
122 cell = document.createElement("td"); |
|
123 var timestr = formatter.FormatTime("", |
|
124 Ci.nsIScriptableDateFormat.timeFormatNoSeconds, |
|
125 date.getHours(), |
|
126 date.getMinutes(), |
|
127 date.getSeconds()); |
|
128 cell.appendChild(document.createTextNode(timestr)); |
|
129 row.appendChild(cell); |
|
130 body.appendChild(row); |
|
131 } |
|
132 } |
|
133 |
|
134 let clearReports = Task.async(function*() { |
|
135 let bundle = Services.strings.createBundle("chrome://global/locale/crashes.properties"); |
|
136 |
|
137 if (!Services. |
|
138 prompt.confirm(window, |
|
139 bundle.GetStringFromName("deleteconfirm.title"), |
|
140 bundle.GetStringFromName("deleteconfirm.description"))) { |
|
141 return; |
|
142 } |
|
143 |
|
144 let cleanupFolder = Task.async(function*(path, filter) { |
|
145 let iterator = new OS.File.DirectoryIterator(path); |
|
146 try { |
|
147 yield iterator.forEach(Task.async(function*(aEntry) { |
|
148 if (!filter || (yield filter(aEntry))) { |
|
149 yield OS.File.remove(aEntry.path); |
|
150 } |
|
151 })); |
|
152 } catch (e if e instanceof OS.File.Error && e.becauseNoSuchFile) { |
|
153 } finally { |
|
154 iterator.close(); |
|
155 } |
|
156 }); |
|
157 |
|
158 yield cleanupFolder(CrashReports.submittedDir.path, function*(aEntry) { |
|
159 return aEntry.name.startsWith("bp-") && aEntry.name.endsWith(".txt"); |
|
160 }); |
|
161 |
|
162 let oneYearAgo = Date.now() - 31586000000; |
|
163 yield cleanupFolder(CrashReports.reportsDir.path, function*(aEntry) { |
|
164 if (!aEntry.name.startsWith("InstallTime") || |
|
165 aEntry.name == "InstallTime" + buildID) { |
|
166 return false; |
|
167 } |
|
168 |
|
169 let date = aEntry.winLastWriteDate; |
|
170 if (!date) { |
|
171 let stat = yield OS.File.stat(aEntry.path); |
|
172 date = stat.lastModificationDate; |
|
173 } |
|
174 |
|
175 return (date < oneYearAgo); |
|
176 }); |
|
177 |
|
178 yield cleanupFolder(CrashReports.pendingDir.path); |
|
179 |
|
180 document.getElementById("clear-reports").style.display = "none"; |
|
181 document.getElementById("reportList").style.display = "none"; |
|
182 document.getElementById("noReports").style.display = "block"; |
|
183 }); |