OLD | NEW |
1 /* | 1 /* |
2 * This file is part of Adblock Plus <https://adblockplus.org/>, | 2 * This file is part of Adblock Plus <https://adblockplus.org/>, |
3 * Copyright (C) 2006-present eyeo GmbH | 3 * Copyright (C) 2006-present eyeo GmbH |
4 * | 4 * |
5 * Adblock Plus is free software: you can redistribute it and/or modify | 5 * Adblock Plus is free software: you can redistribute it and/or modify |
6 * it under the terms of the GNU General Public License version 3 as | 6 * it under the terms of the GNU General Public License version 3 as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
8 * | 8 * |
9 * Adblock Plus is distributed in the hope that it will be useful, | 9 * Adblock Plus is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 * GNU General Public License for more details. | 12 * GNU General Public License for more details. |
13 * | 13 * |
14 * You should have received a copy of the GNU General Public License | 14 * You should have received a copy of the GNU General Public License |
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. | 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
16 */ | 16 */ |
17 | 17 |
18 "use strict"; | 18 "use strict"; |
19 | 19 |
20 window.ext = {}; | 20 window.ext = {}; |
21 | 21 |
22 let reportData = new DOMParser().parseFromString("<report></report>", "text/xml"
); | 22 let reportData = new DOMParser().parseFromString("<report></report>", |
| 23 "text/xml"); |
23 | 24 |
24 let pages = { | 25 let pages = { |
25 "typeSelectorPage": [initTypeSelector, leaveTypeSelector], | 26 typeSelectorPage: [initTypeSelector, leaveTypeSelector], |
26 "commentPage": [initCommentPage, leaveCommentPage], | 27 commentPage: [initCommentPage, leaveCommentPage], |
27 "sendPage": [initSendPage, leaveSendPage] | 28 sendPage: [initSendPage, leaveSendPage] |
28 }; | 29 }; |
29 | 30 |
30 document.addEventListener("DOMContentLoaded", () => | 31 document.addEventListener("DOMContentLoaded", () => |
31 { | 32 { |
32 document.getElementById("cancel").addEventListener("click", () => | 33 document.getElementById("cancel").addEventListener("click", () => |
33 { | 34 { |
34 window.close(); | 35 window.close(); |
35 }); | 36 }); |
36 | 37 |
37 document.getElementById("continue").addEventListener("click", () => | 38 document.getElementById("continue").addEventListener("click", () => |
38 { | 39 { |
39 if (!document.getElementById("continue").disabled) | 40 if (!document.getElementById("continue").disabled) |
40 pages[getCurrentPage()][1](); | 41 pages[getCurrentPage()][1](); |
41 }); | 42 }); |
42 | 43 |
43 document.addEventListener("keydown", event => | 44 document.addEventListener("keydown", event => |
44 { | 45 { |
45 let blacklistedElements = new Set(["textarea", "button", "a"]) | 46 let blacklisted = new Set(["textarea", "button", "a"]); |
46 | 47 |
47 if (event.key == "Enter" && !blacklistedElements.has(event.target.localName)
) | 48 if (event.key == "Enter" && !blacklisted.has(event.target.localName)) |
48 document.getElementById("continue").click(); | 49 document.getElementById("continue").click(); |
49 else if (event.key == "Escape") | 50 else if (event.key == "Escape") |
50 document.getElementById("cancel").click(); | 51 document.getElementById("cancel").click(); |
51 }); | 52 }); |
52 | 53 |
53 browser.runtime.sendMessage({ | 54 browser.runtime.sendMessage({ |
54 type: "app.get", | 55 type: "app.get", |
55 what: "doclink", | 56 what: "doclink", |
56 link: "reporter_privacy" | 57 link: "reporter_privacy" |
57 }).then(url => | 58 }).then(url => |
(...skipping 17 matching lines...) Expand all Loading... |
75 let previousPage = document.querySelector(".page:not([hidden])"); | 76 let previousPage = document.querySelector(".page:not([hidden])"); |
76 if (previousPage) | 77 if (previousPage) |
77 previousPage.hidden = true; | 78 previousPage.hidden = true; |
78 | 79 |
79 document.getElementById(pageId).hidden = false; | 80 document.getElementById(pageId).hidden = false; |
80 pages[pageId][0](); | 81 pages[pageId][0](); |
81 } | 82 } |
82 | 83 |
83 function censorURL(url) | 84 function censorURL(url) |
84 { | 85 { |
85 return url.replace(/([?;&\/#][^?;&\/#]+?=)[^?;&\/#]+/g, "$1*"); | 86 return url.replace(/([?;&/#][^?;&/#]+?=)[^?;&/#]+/g, "$1*"); |
86 } | 87 } |
87 | 88 |
88 function encodeHTML(str) | 89 function encodeHTML(str) |
89 { | 90 { |
90 return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").
replace(/"/g, """); | 91 return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").
replace(/"/g, """); |
91 } | 92 } |
92 | 93 |
93 function serializeReportData() | 94 function serializeReportData() |
94 { | 95 { |
95 let result = new XMLSerializer().serializeToString(reportData); | 96 let result = new XMLSerializer().serializeToString(reportData); |
96 | 97 |
97 // Insert line breaks before each new tag | 98 // Insert line breaks before each new tag |
98 result = result.replace(/(<[^\/]([^"<>]*|"[^"]*")*>)/g, "\n$1"); | 99 result = result.replace(/(<[^/]([^"<>]*|"[^"]*")*>)/g, "\n$1"); |
99 result = result.replace(/^\n+/, ""); | 100 result = result.replace(/^\n+/, ""); |
100 return result; | 101 return result; |
101 } | 102 } |
102 | 103 |
103 function retrieveAddonInfo() | 104 function retrieveAddonInfo() |
104 { | 105 { |
105 let element = reportData.createElement("adblock-plus"); | 106 let element = reportData.createElement("adblock-plus"); |
106 return browser.runtime.sendMessage({ | 107 return browser.runtime.sendMessage({ |
107 type: "app.get", | 108 type: "app.get", |
108 what: "addonVersion" | 109 what: "addonVersion" |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 let element = reportData.createElement("subscriptions"); | 184 let element = reportData.createElement("subscriptions"); |
184 for (let subscription of subscriptions) | 185 for (let subscription of subscriptions) |
185 { | 186 { |
186 if (!/^(http|https|ftp):/.test(subscription.url)) | 187 if (!/^(http|https|ftp):/.test(subscription.url)) |
187 continue; | 188 continue; |
188 | 189 |
189 let now = Math.round(Date.now() / 1000); | 190 let now = Math.round(Date.now() / 1000); |
190 let subscriptionElement = reportData.createElement("subscription"); | 191 let subscriptionElement = reportData.createElement("subscription"); |
191 subscriptionElement.setAttribute("id", subscription.url); | 192 subscriptionElement.setAttribute("id", subscription.url); |
192 if (subscription.lastDownload) | 193 if (subscription.lastDownload) |
193 subscriptionElement.setAttribute("lastDownloadAttempt", subscription.las
tDownload - now); | 194 { |
194 subscriptionElement.setAttribute("downloadStatus", subscription.downloadSt
atus); | 195 subscriptionElement.setAttribute("lastDownloadAttempt", |
| 196 subscription.lastDownload - now); |
| 197 } |
| 198 subscriptionElement.setAttribute("downloadStatus", |
| 199 subscription.downloadStatus); |
195 element.appendChild(subscriptionElement); | 200 element.appendChild(subscriptionElement); |
196 } | 201 } |
197 reportData.documentElement.appendChild(element); | 202 reportData.documentElement.appendChild(element); |
198 }); | 203 }); |
199 } | 204 } |
200 | 205 |
201 function initDataCollector() | 206 function initDataCollector() |
202 { | 207 { |
203 Promise.resolve().then(() => | 208 Promise.resolve().then(() => |
204 { | 209 { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
241 function leaveTypeSelector() | 246 function leaveTypeSelector() |
242 { | 247 { |
243 let checkbox = document.querySelector("input[name='type']:checked"); | 248 let checkbox = document.querySelector("input[name='type']:checked"); |
244 reportData.documentElement.setAttribute("type", checkbox.value); | 249 reportData.documentElement.setAttribute("type", checkbox.value); |
245 setCurrentPage("commentPage"); | 250 setCurrentPage("commentPage"); |
246 } | 251 } |
247 | 252 |
248 function initCommentPage() | 253 function initCommentPage() |
249 { | 254 { |
250 let continueButton = document.getElementById("continue"); | 255 let continueButton = document.getElementById("continue"); |
| 256 let label = browser.i18n.getMessage("issueReporter_sendButton_label"); |
| 257 continueButton.textContent = label; |
251 continueButton.disabled = true; | 258 continueButton.disabled = true; |
252 continueButton.textContent = browser.i18n.getMessage("issueReporter_sendButton
_label"); | |
253 | 259 |
254 let emailElement = reportData.createElement("email"); | 260 let emailElement = reportData.createElement("email"); |
255 let emailField = document.getElementById("email"); | 261 let emailField = document.getElementById("email"); |
256 let anonymousSubmissionField = document.getElementById("anonymousSubmission"); | 262 let anonymousSubmissionField = document.getElementById("anonymousSubmission"); |
257 let validateEmail = () => | 263 let validateEmail = () => |
258 { | 264 { |
259 document.getElementById("anonymousSubmissionWarning").setAttribute("data-inv
isible", !anonymousSubmissionField.checked); | 265 document.getElementById("anonymousSubmissionWarning") |
| 266 .setAttribute("data-invisible", !anonymousSubmissionField.checked); |
260 if (anonymousSubmissionField.checked) | 267 if (anonymousSubmissionField.checked) |
261 { | 268 { |
262 emailField.value = ""; | 269 emailField.value = ""; |
263 emailField.disabled = true; | 270 emailField.disabled = true; |
264 continueButton.disabled = false; | 271 continueButton.disabled = false; |
265 if (emailElement.parentNode) | 272 if (emailElement.parentNode) |
266 emailElement.parentNode.removeChild(emailElement); | 273 emailElement.parentNode.removeChild(emailElement); |
267 } | 274 } |
268 else | 275 else |
269 { | 276 { |
(...skipping 11 matching lines...) Expand all Loading... |
281 let commentElement = reportData.createElement("comment"); | 288 let commentElement = reportData.createElement("comment"); |
282 document.getElementById("comment").addEventListener("input", event => | 289 document.getElementById("comment").addEventListener("input", event => |
283 { | 290 { |
284 if (commentElement.parentNode) | 291 if (commentElement.parentNode) |
285 commentElement.parentNode.removeChild(commentElement); | 292 commentElement.parentNode.removeChild(commentElement); |
286 | 293 |
287 let value = event.target.value.trim(); | 294 let value = event.target.value.trim(); |
288 commentElement.textContent = value.substr(0, 1000); | 295 commentElement.textContent = value.substr(0, 1000); |
289 if (value) | 296 if (value) |
290 reportData.documentElement.appendChild(commentElement); | 297 reportData.documentElement.appendChild(commentElement); |
291 document.getElementById("commentLengthWarning").setAttribute("data-invisible
", value.length <= 1000); | 298 document.getElementById("commentLengthWarning") |
| 299 .setAttribute("data-invisible", value.length <= 1000); |
292 }); | 300 }); |
293 | 301 |
294 document.getElementById("showData").addEventListener("click", event => | 302 document.getElementById("showData").addEventListener("click", event => |
295 { | 303 { |
296 event.preventDefault(); | 304 event.preventDefault(); |
297 | 305 |
298 // window.open() won't open data: URIs in Chrome | 306 // window.open() won't open data: URIs in Chrome |
299 browser.tabs.getCurrent().then(tab => | 307 browser.tabs.getCurrent().then(tab => |
300 { | 308 { |
301 browser.tabs.create({ | 309 browser.tabs.create({ |
302 url: "data:text/xml;charset=utf-8," + encodeURIComponent(serializeReport
Data()), | 310 url: "data:text/xml;charset=utf-8," + |
| 311 encodeURIComponent(serializeReportData()), |
303 openerTabId: tab.id | 312 openerTabId: tab.id |
304 }); | 313 }); |
305 }) | 314 }); |
306 }); | 315 }); |
307 | 316 |
308 emailField.focus(); | 317 emailField.focus(); |
309 } | 318 } |
310 | 319 |
311 function leaveCommentPage() | 320 function leaveCommentPage() |
312 { | 321 { |
313 setCurrentPage("sendPage"); | 322 setCurrentPage("sendPage"); |
314 } | 323 } |
315 | 324 |
316 function initSendPage() | 325 function initSendPage() |
317 { | 326 { |
318 document.getElementById("cancel").hidden = true; | 327 document.getElementById("cancel").hidden = true; |
319 | 328 |
320 let continueButton = document.getElementById("continue"); | 329 let continueButton = document.getElementById("continue"); |
321 continueButton.textContent = browser.i18n.getMessage("issueReporter_doneButton
_label"); | 330 let label = browser.i18n.getMessage("issueReporter_doneButton_label"); |
| 331 continueButton.textContent = label; |
322 continueButton.disabled = true; | 332 continueButton.disabled = true; |
323 | 333 |
324 let uuid = new Uint16Array(8); | 334 let uuid = new Uint16Array(8); |
325 window.crypto.getRandomValues(uuid); | 335 window.crypto.getRandomValues(uuid); |
326 uuid[3] = uuid[3] & 0x0FFF | 0x4000; // version 4 | 336 uuid[3] = uuid[3] & 0x0FFF | 0x4000; // version 4 |
327 uuid[4] = uuid[4] & 0x3FFF | 0x8000; // variant 1 | 337 uuid[4] = uuid[4] & 0x3FFF | 0x8000; // variant 1 |
328 | 338 |
329 let uuidString = ""; | 339 let uuidString = ""; |
330 for (let i = 0; i < uuid.length; i++) | 340 for (let i = 0; i < uuid.length; i++) |
331 { | 341 { |
332 let component = uuid[i].toString(16); | 342 let component = uuid[i].toString(16); |
333 while (component.length < 4) | 343 while (component.length < 4) |
334 component = "0" + component; | 344 component = "0" + component; |
335 uuidString += component; | 345 uuidString += component; |
336 if (i >= 1 && i<= 4) | 346 if (i >= 1 && i <= 4) |
337 uuidString += "-"; | 347 uuidString += "-"; |
338 } | 348 } |
339 | 349 |
340 let params = new URLSearchParams({ | 350 let params = new URLSearchParams({ |
341 version: 1, | 351 version: 1, |
342 guid: uuidString, | 352 guid: uuidString, |
343 lang: reportData.getElementsByTagName("adblock-plus")[0].getAttribute("local
e") | 353 lang: reportData.getElementsByTagName("adblock-plus")[0] |
| 354 .getAttribute("locale") |
344 }); | 355 }); |
345 let url = "https://reports.adblockplus.org/submitReport?" + params; | 356 let url = "https://reports.adblockplus.org/submitReport?" + params; |
346 | 357 |
347 let reportSent = event => | 358 let reportSent = event => |
348 { | 359 { |
349 let success = false; | 360 let success = false; |
350 let errorMessage = browser.i18n.getMessage("filters_subscription_lastDownloa
d_connectionError"); | 361 let errorMessage = browser.i18n.getMessage( |
| 362 "filters_subscription_lastDownload_connectionError" |
| 363 ); |
351 try | 364 try |
352 { | 365 { |
353 success = request.status == 200; | 366 success = request.status == 200; |
354 if (request.status != 0) | 367 if (request.status != 0) |
355 errorMessage = request.status + " " + request.statusText; | 368 errorMessage = request.status + " " + request.statusText; |
356 } | 369 } |
357 catch (e) | 370 catch (e) |
358 { | 371 { |
359 // Getting request status might throw if no connection was established | 372 // Getting request status might throw if no connection was established |
360 } | 373 } |
(...skipping 19 matching lines...) Expand all Loading... |
380 | 393 |
381 while (errorElement.firstChild) | 394 while (errorElement.firstChild) |
382 errorElement.removeChild(errorElement.firstChild); | 395 errorElement.removeChild(errorElement.firstChild); |
383 | 396 |
384 let link = document.createElement("a"); | 397 let link = document.createElement("a"); |
385 link.textContent = linkText; | 398 link.textContent = linkText; |
386 browser.runtime.sendMessage({ | 399 browser.runtime.sendMessage({ |
387 type: "app.get", | 400 type: "app.get", |
388 what: "doclink", | 401 what: "doclink", |
389 link: "reporter_connect_issue" | 402 link: "reporter_connect_issue" |
390 }).then(url => | 403 }).then(supportUrl => |
391 { | 404 { |
392 link.href = url; | 405 link.href = supportUrl; |
393 }); | 406 }); |
394 | 407 |
395 | 408 |
396 errorElement.appendChild(document.createTextNode(beforeLink)); | 409 errorElement.appendChild(document.createTextNode(beforeLink)); |
397 errorElement.appendChild(link); | 410 errorElement.appendChild(link); |
398 errorElement.appendChild(document.createTextNode(afterLink)); | 411 errorElement.appendChild(document.createTextNode(afterLink)); |
399 | 412 |
400 errorElement.hidden = false; | 413 errorElement.hidden = false; |
401 } | 414 } |
402 | 415 |
403 result = result.replace(/%CONFIRMATION%/g, encodeHTML(browser.i18n.getMessag
e("issueReporter_confirmationMessage"))); | 416 result = result.replace(/%CONFIRMATION%/g, encodeHTML(browser.i18n.getMessag
e("issueReporter_confirmationMessage"))); |
404 result = result.replace(/%KNOWNISSUE%/g, encodeHTML(browser.i18n.getMessage(
"issueReporter_knownIssueMessage"))); | 417 result = result.replace(/%KNOWNISSUE%/g, encodeHTML(browser.i18n.getMessage(
"issueReporter_knownIssueMessage"))); |
405 result = result.replace(/(<html)\b/, '$1 dir="' + encodeHTML(window.getCompu
tedStyle(document.documentElement, "").direction + '"')); | 418 result = result.replace(/(<html)\b/, '$1 dir="' + encodeHTML(window.getCompu
tedStyle(document.documentElement, "").direction + '"')); |
406 | 419 |
407 document.getElementById("sendReportMessage").hidden = true; | 420 document.getElementById("sendReportMessage").hidden = true; |
408 document.getElementById("sendingProgressContainer").hidden = true; | 421 document.getElementById("sendingProgressContainer").hidden = true; |
409 | 422 |
410 let resultFrame = document.getElementById("result"); | 423 let resultFrame = document.getElementById("result"); |
411 resultFrame.setAttribute("src", "data:text/html;charset=utf-8," + encodeURIC
omponent(result)); | 424 resultFrame.setAttribute("src", "data:text/html;charset=utf-8," + |
| 425 encodeURIComponent(result)); |
412 resultFrame.hidden = false; | 426 resultFrame.hidden = false; |
413 | 427 |
414 document.getElementById("continue").disabled = false; | 428 document.getElementById("continue").disabled = false; |
415 }; | 429 }; |
416 | 430 |
417 let request = new XMLHttpRequest(); | 431 let request = new XMLHttpRequest(); |
418 request.open("POST", url); | 432 request.open("POST", url); |
419 request.setRequestHeader("Content-Type", "text/xml"); | 433 request.setRequestHeader("Content-Type", "text/xml"); |
420 request.setRequestHeader("X-Adblock-Plus", "1"); | 434 request.setRequestHeader("X-Adblock-Plus", "1"); |
421 request.addEventListener("load", reportSent); | 435 request.addEventListener("load", reportSent); |
422 request.addEventListener("error", reportSent); | 436 request.addEventListener("error", reportSent); |
423 request.upload.addEventListener("progress", event => | 437 request.upload.addEventListener("progress", event => |
424 { | 438 { |
425 if (!event.lengthComputable) | 439 if (!event.lengthComputable) |
426 return; | 440 return; |
427 | 441 |
428 let progress = Math.round(event.loaded / event.total * 100); | |
429 if (event.loaded > 0) | 442 if (event.loaded > 0) |
430 { | 443 { |
431 let progress = document.getElementById("sendingProgress"); | 444 let progress = document.getElementById("sendingProgress"); |
432 progress.max = event.total; | 445 progress.max = event.total; |
433 progress.value = event.loaded; | 446 progress.value = event.loaded; |
434 } | 447 } |
435 }); | 448 }); |
436 request.send(serializeReportData()); | 449 request.send(serializeReportData()); |
437 } | 450 } |
438 | 451 |
439 function leaveSendPage() | 452 function leaveSendPage() |
440 { | 453 { |
441 window.close(); | 454 window.close(); |
442 } | 455 } |
OLD | NEW |