| 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. |
| 576 querySelector(`[location="${request.url}"]`); |
| 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. |
| 595 querySelector(`[text="${filter.text}"]`); |
| 596 if (existingFilter) |
| 597 { |
| 598 let countNum = Number(existingFilter.getAttribute("hitcount")); |
| 599 existingFilter.setAttribute("hitcount", countNum + 1); |
| 600 } |
| 601 else |
| 602 { |
| 603 let filterElem = reportData.createElement("filter"); |
| 604 filterElem.setAttribute("text", filter.text); |
| 605 filterElem.setAttribute("subscriptions", subscriptions.join(",")); |
| 606 filterElem.setAttribute("hitcount", 1); |
| 607 reportData.documentElement.appendChild(filterElem); |
| 608 } |
| 609 } |
| 610 break; |
| 611 } |
| 612 break; |
| 613 } |
| 614 }); |
| 615 |
| 616 port.postMessage({ |
| 617 type: "app.listen", |
| 618 filter: ["devLog"] |
| 619 }); |
| OLD | NEW |