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 let reportData = new DOMParser().parseFromString("<report></report>", | 20 let reportData = new DOMParser().parseFromString("<report></report>", |
21 "text/xml"); | 21 "text/xml"); |
22 | 22 |
23 let pages = { | 23 let pages = { |
24 typeSelectorPage: [initTypeSelector, leaveTypeSelector], | 24 typeSelectorPage: [initTypeSelector, leaveTypeSelector], |
25 commentPage: [initCommentPage, leaveCommentPage], | 25 commentPage: [initCommentPage, leaveCommentPage], |
26 sendPage: [initSendPage, leaveSendPage] | 26 sendPage: [initSendPage, leaveSendPage] |
27 }; | 27 }; |
28 | 28 |
| 29 let dataGatheringTabId = null; |
| 30 let isMinimumTimeMet = false; |
| 31 |
29 document.addEventListener("DOMContentLoaded", () => | 32 document.addEventListener("DOMContentLoaded", () => |
30 { | 33 { |
31 document.getElementById("cancel").addEventListener("click", () => | 34 document.getElementById("cancel").addEventListener("click", () => |
32 { | 35 { |
33 closeMe(); | 36 closeMe(); |
34 }); | 37 }); |
35 | 38 |
36 document.getElementById("continue").addEventListener("click", () => | 39 document.getElementById("continue").addEventListener("click", () => |
37 { | 40 { |
38 if (!document.getElementById("continue").disabled) | 41 if (!document.getElementById("continue").disabled) |
39 pages[getCurrentPage()][1](); | 42 pages[getCurrentPage()][1](); |
40 }); | 43 }); |
41 | 44 |
42 document.addEventListener("keydown", event => | 45 document.addEventListener("keydown", event => |
43 { | 46 { |
44 let blacklisted = new Set(["textarea", "button", "a"]); | 47 let blacklisted = new Set(["textarea", "button", "a"]); |
45 | 48 |
46 if (event.key == "Enter" && !blacklisted.has(event.target.localName)) | 49 if (event.key == "Enter" && !blacklisted.has(event.target.localName)) |
47 document.getElementById("continue").click(); | 50 document.getElementById("continue").click(); |
48 else if (event.key == "Escape") | 51 else if (event.key == "Escape") |
49 document.getElementById("cancel").click(); | 52 document.getElementById("cancel").click(); |
50 }); | 53 }); |
51 | 54 |
| 55 document.getElementById("hide-notification").addEventListener("click", () => |
| 56 { |
| 57 document.getElementById("notification").setAttribute("aria-hidden", true); |
| 58 }); |
| 59 |
52 browser.runtime.sendMessage({ | 60 browser.runtime.sendMessage({ |
53 type: "app.get", | 61 type: "app.get", |
54 what: "doclink", | 62 what: "doclink", |
55 link: "reporter_privacy" | 63 link: "reporter_privacy" |
56 }).then(url => | 64 }).then(url => |
57 { | 65 { |
58 document.getElementById("privacyPolicy").href = url; | 66 document.getElementById("privacyPolicy").href = url; |
59 }); | 67 }); |
60 | 68 |
61 initDataCollector(); | 69 initDataCollector(); |
62 }); | 70 }); |
63 | 71 |
64 function closeMe() | 72 function closeMe() |
65 { | 73 { |
| 74 closeRequestsCollectingTab(); |
66 browser.runtime.sendMessage({ | 75 browser.runtime.sendMessage({ |
67 type: "app.get", | 76 type: "app.get", |
68 what: "senderId" | 77 what: "senderId" |
69 }).then(tabId => browser.tabs.remove(tabId)); | 78 }).then(tabId => browser.tabs.remove(tabId)); |
70 } | 79 } |
71 | 80 |
72 function getCurrentPage() | 81 function getCurrentPage() |
73 { | 82 { |
74 return document.querySelector(".page:not([hidden])").id; | 83 return document.querySelector(".page:not([hidden])").id; |
75 } | 84 } |
76 | 85 |
77 function setCurrentPage(pageId) | 86 function setCurrentPage(pageId) |
78 { | 87 { |
79 if (!pages.hasOwnProperty(pageId)) | 88 if (!pages.hasOwnProperty(pageId)) |
80 return; | 89 return; |
81 | 90 |
82 let previousPage = document.querySelector(".page:not([hidden])"); | 91 let previousPage = document.querySelector(".page:not([hidden])"); |
83 if (previousPage) | 92 if (previousPage) |
84 previousPage.hidden = true; | 93 previousPage.hidden = true; |
85 | 94 |
86 document.getElementById(pageId).hidden = false; | 95 document.getElementById(pageId).hidden = false; |
| 96 document.body.dataset.page = pageId; |
87 pages[pageId][0](); | 97 pages[pageId][0](); |
88 } | 98 } |
89 | 99 |
90 function censorURL(url) | 100 function censorURL(url) |
91 { | 101 { |
92 return url.replace(/([?;&/#][^?;&/#]+?=)[^?;&/#]+/g, "$1*"); | 102 return url.replace(/([?;&/#][^?;&/#]+?=)[^?;&/#]+/g, "$1*"); |
93 } | 103 } |
94 | 104 |
95 function encodeHTML(str) | 105 function encodeHTML(str) |
96 { | 106 { |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
228 subscriptionElement.setAttribute("downloadStatus", | 238 subscriptionElement.setAttribute("downloadStatus", |
229 subscription.downloadStatus); | 239 subscription.downloadStatus); |
230 subscriptionElement.setAttribute("disabledFilters", | 240 subscriptionElement.setAttribute("disabledFilters", |
231 subscription.disabledFilters.length); | 241 subscription.disabledFilters.length); |
232 element.appendChild(subscriptionElement); | 242 element.appendChild(subscriptionElement); |
233 } | 243 } |
234 reportData.documentElement.appendChild(element); | 244 reportData.documentElement.appendChild(element); |
235 }); | 245 }); |
236 } | 246 } |
237 | 247 |
| 248 function collectRequests(tabId) |
| 249 { |
| 250 return browser.tabs.get(tabId).then(tab => |
| 251 { |
| 252 return browser.tabs.create({active: false, url: tab.url}); |
| 253 }).then((dataCollectingTab) => |
| 254 { |
| 255 dataGatheringTabId = dataCollectingTab.id; |
| 256 browser.runtime.sendMessage({ |
| 257 type: "app.collectHits", |
| 258 tab: dataCollectingTab |
| 259 }); |
| 260 |
| 261 function minimumTimeMet() |
| 262 { |
| 263 isMinimumTimeMet = true; |
| 264 document.getElementById("showData").disabled = false; |
| 265 validateCommentsPage(); |
| 266 } |
| 267 browser.tabs.onUpdated.addListener((shadowTabId, changeInfo) => |
| 268 { |
| 269 if (shadowTabId == dataGatheringTabId && changeInfo.status == "complete") |
| 270 minimumTimeMet(); |
| 271 }); |
| 272 window.setTimeout(minimumTimeMet, 5000); |
| 273 }); |
| 274 } |
| 275 |
| 276 function closeRequestsCollectingTab() |
| 277 { |
| 278 browser.tabs.remove(dataGatheringTabId); |
| 279 } |
| 280 |
238 function initDataCollector() | 281 function initDataCollector() |
239 { | 282 { |
240 Promise.resolve().then(() => | 283 Promise.resolve().then(() => |
241 { | 284 { |
242 let tabId = parseInt(location.search.replace(/^\?/, ""), 10) || 0; | 285 let tabId = parseInt(location.search.replace(/^\?/, ""), 10) || 0; |
243 let handlers = [ | 286 let handlers = [ |
244 retrieveAddonInfo(), | 287 retrieveAddonInfo(), |
245 retrieveApplicationInfo(), | 288 retrieveApplicationInfo(), |
246 retrievePlatformInfo(), | 289 retrievePlatformInfo(), |
247 retrieveTabURL(tabId), | 290 retrieveTabURL(tabId), |
| 291 collectRequests(tabId), |
248 retrieveSubscriptions() | 292 retrieveSubscriptions() |
249 ]; | 293 ]; |
250 return Promise.all(handlers); | 294 return Promise.all(handlers); |
251 }).then(() => | 295 }).then(() => |
252 { | 296 { |
253 setCurrentPage("typeSelectorPage"); | 297 setCurrentPage("typeSelectorPage"); |
254 }).catch(e => | 298 }).catch(e => |
255 { | 299 { |
256 console.error(e); | 300 console.error(e); |
257 alert(e); | 301 alert(e); |
(...skipping 16 matching lines...) Expand all Loading... |
274 } | 318 } |
275 } | 319 } |
276 | 320 |
277 function leaveTypeSelector() | 321 function leaveTypeSelector() |
278 { | 322 { |
279 let checkbox = document.querySelector("input[name='type']:checked"); | 323 let checkbox = document.querySelector("input[name='type']:checked"); |
280 reportData.documentElement.setAttribute("type", checkbox.value); | 324 reportData.documentElement.setAttribute("type", checkbox.value); |
281 setCurrentPage("commentPage"); | 325 setCurrentPage("commentPage"); |
282 } | 326 } |
283 | 327 |
284 function initCommentPage() | 328 function validateCommentsPage() |
285 { | 329 { |
286 let continueButton = document.getElementById("continue"); | 330 let sendButton = document.getElementById("send"); |
287 let label = browser.i18n.getMessage("issueReporter_sendButton_label"); | |
288 continueButton.textContent = label; | |
289 continueButton.disabled = true; | |
290 | |
291 let emailElement = reportData.createElement("email"); | 331 let emailElement = reportData.createElement("email"); |
292 let emailField = document.getElementById("email"); | 332 let emailField = document.getElementById("email"); |
293 let anonymousSubmissionField = document.getElementById("anonymousSubmission"); | 333 let anonymousSubmissionField = document.getElementById("anonymousSubmission"); |
294 let validateEmail = () => | 334 document.getElementById("anonymousSubmissionWarning") |
| 335 .setAttribute("data-invisible", !anonymousSubmissionField.checked); |
| 336 if (anonymousSubmissionField.checked) |
295 { | 337 { |
296 document.getElementById("anonymousSubmissionWarning") | 338 emailField.value = ""; |
297 .setAttribute("data-invisible", !anonymousSubmissionField.checked); | 339 emailField.disabled = true; |
298 if (anonymousSubmissionField.checked) | 340 sendButton.disabled = !isMinimumTimeMet; |
299 { | 341 if (emailElement.parentNode) |
300 emailField.value = ""; | 342 emailElement.parentNode.removeChild(emailElement); |
301 emailField.disabled = true; | 343 } |
302 continueButton.disabled = false; | 344 else |
303 if (emailElement.parentNode) | 345 { |
304 emailElement.parentNode.removeChild(emailElement); | 346 emailField.disabled = false; |
305 } | |
306 else | |
307 { | |
308 emailField.disabled = false; | |
309 | 347 |
310 let value = emailField.value.trim(); | 348 let value = emailField.value.trim(); |
311 emailElement.textContent = value; | 349 emailElement.textContent = value; |
312 reportData.documentElement.appendChild(emailElement); | 350 reportData.documentElement.appendChild(emailElement); |
313 continueButton.disabled = value == "" || !emailField.validity.valid; | 351 sendButton.disabled = (value == "" || !emailField.validity.valid || |
314 } | 352 !isMinimumTimeMet); |
315 }; | 353 } |
316 emailField.addEventListener("input", validateEmail); | 354 } |
317 anonymousSubmissionField.addEventListener("click", validateEmail); | 355 |
| 356 function initCommentPage() |
| 357 { |
| 358 let anonymousSubmissionField = document.getElementById("anonymousSubmission"); |
| 359 let emailField = document.getElementById("email"); |
| 360 emailField.addEventListener("input", validateCommentsPage); |
| 361 anonymousSubmissionField.addEventListener("click", validateCommentsPage); |
318 | 362 |
319 let commentElement = reportData.createElement("comment"); | 363 let commentElement = reportData.createElement("comment"); |
320 document.getElementById("comment").addEventListener("input", event => | 364 document.getElementById("comment").addEventListener("input", event => |
321 { | 365 { |
322 if (commentElement.parentNode) | 366 if (commentElement.parentNode) |
323 commentElement.parentNode.removeChild(commentElement); | 367 commentElement.parentNode.removeChild(commentElement); |
324 | 368 |
325 let value = event.target.value.trim(); | 369 let value = event.target.value.trim(); |
326 commentElement.textContent = value.substr(0, 1000); | 370 commentElement.textContent = value.substr(0, 1000); |
327 if (value) | 371 if (value) |
328 reportData.documentElement.appendChild(commentElement); | 372 reportData.documentElement.appendChild(commentElement); |
329 document.getElementById("commentLengthWarning") | 373 document.getElementById("commentLengthWarning") |
330 .setAttribute("data-invisible", value.length <= 1000); | 374 .setAttribute("data-invisible", value.length <= 1000); |
331 }); | 375 }); |
332 | 376 |
333 let showDataOverlay = document.getElementById("showDataOverlay"); | 377 let showDataOverlay = document.getElementById("showDataOverlay"); |
334 document.getElementById("showData").addEventListener("click", event => | 378 document.getElementById("showData").addEventListener("click", event => |
335 { | 379 { |
336 event.preventDefault(); | 380 event.preventDefault(); |
| 381 closeRequestsCollectingTab(); |
337 | 382 |
338 showDataOverlay.hidden = false; | 383 showDataOverlay.hidden = false; |
339 | 384 |
340 let element = document.getElementById("showDataValue"); | 385 let element = document.getElementById("showDataValue"); |
341 element.value = serializeReportData(); | 386 element.value = serializeReportData(); |
342 element.focus(); | 387 element.focus(); |
343 }); | 388 }); |
344 | 389 |
345 document.getElementById("showDataClose").addEventListener("click", event => | 390 document.getElementById("showDataClose").addEventListener("click", event => |
346 { | 391 { |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
507 progress.value = event.loaded; | 552 progress.value = event.loaded; |
508 } | 553 } |
509 }); | 554 }); |
510 request.send(serializeReportData()); | 555 request.send(serializeReportData()); |
511 } | 556 } |
512 | 557 |
513 function leaveSendPage() | 558 function leaveSendPage() |
514 { | 559 { |
515 closeMe(); | 560 closeMe(); |
516 } | 561 } |
| 562 |
| 563 let port = browser.runtime.connect({name: "ui"}); |
| 564 |
| 565 port.onMessage.addListener((message) => |
| 566 { |
| 567 switch (message.type) |
| 568 { |
| 569 case "app.respond": |
| 570 switch (message.action) |
| 571 { |
| 572 case "devLog": |
| 573 const [request, filter, subscriptions] = message.args; |
| 574 |
| 575 let existingRequest = reportData.querySelector(`[location="${request.u
rl}"]`); |
| 576 // TODO: refactor the implementation |
| 577 if (existingRequest) |
| 578 { |
| 579 let countNum = Number(existingRequest.getAttribute("count")); |
| 580 existingRequest.setAttribute("count", countNum + 1); |
| 581 } |
| 582 else |
| 583 { |
| 584 let requestElem = reportData.createElement("request"); |
| 585 requestElem.setAttribute("location", request.url); |
| 586 requestElem.setAttribute("type", request.type); |
| 587 requestElem.setAttribute("docDomain", request.docDomain); |
| 588 requestElem.setAttribute("thirdParty", request.thirdParty); |
| 589 requestElem.setAttribute("count", 1); |
| 590 reportData.documentElement.appendChild(requestElem); |
| 591 } |
| 592 if (filter) |
| 593 { |
| 594 let existingFilter = reportData.querySelector(`[text="${filter.text}
"]`); |
| 595 if (existingFilter) |
| 596 { |
| 597 let countNum = Number(existingFilter.getAttribute("hitcount")); |
| 598 existingFilter.setAttribute("hitcount", countNum + 1); |
| 599 } |
| 600 else |
| 601 { |
| 602 let filterElem = reportData.createElement("filter"); |
| 603 filterElem.setAttribute("text", filter.text); |
| 604 filterElem.setAttribute("subscriptions", subscriptions.join(",")); |
| 605 filterElem.setAttribute("hitcount", 1); |
| 606 reportData.documentElement.appendChild(filterElem); |
| 607 } |
| 608 } |
| 609 break; |
| 610 } |
| 611 break; |
| 612 } |
| 613 }); |
| 614 |
| 615 port.postMessage({ |
| 616 type: "app.listen", |
| 617 filter: ["devLog"] |
| 618 }); |
OLD | NEW |