| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 /* | 
|  | 2  * This file is part of Adblock Plus <https://adblockplus.org/>, | 
|  | 3  * Copyright (C) 2006-present eyeo GmbH | 
|  | 4  * | 
|  | 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 | 
|  | 7  * published by the Free Software Foundation. | 
|  | 8  * | 
|  | 9  * Adblock Plus is distributed in the hope that it will be useful, | 
|  | 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|  | 12  * GNU General Public License for more details. | 
|  | 13  * | 
|  | 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/>. | 
|  | 16  */ | 
|  | 17 | 
|  | 18 "use strict"; | 
|  | 19 | 
|  | 20 window.ext = {}; | 
|  | 21 | 
|  | 22 let reportData = new DOMParser().parseFromString("<report></report>", "text/xml"
     ); | 
|  | 23 | 
|  | 24 let pages = { | 
|  | 25   "typeSelectorPage": [initTypeSelector, leaveTypeSelector], | 
|  | 26   "commentPage": [initCommentPage, leaveCommentPage], | 
|  | 27   "sendPage": [initSendPage, leaveSendPage] | 
|  | 28 }; | 
|  | 29 | 
|  | 30 document.addEventListener("DOMContentLoaded", () => | 
|  | 31 { | 
|  | 32   document.getElementById("cancel").addEventListener("click", () => | 
|  | 33   { | 
|  | 34     window.close(); | 
|  | 35   }); | 
|  | 36 | 
|  | 37   document.getElementById("continue").addEventListener("click", () => | 
|  | 38   { | 
|  | 39     if (!document.getElementById("continue").disabled) | 
|  | 40       pages[getCurrentPage()][1](); | 
|  | 41   }); | 
|  | 42 | 
|  | 43   document.addEventListener("keydown", event => | 
|  | 44   { | 
|  | 45     let blacklistedElements = new Set(["textarea", "button", "a"]) | 
|  | 46 | 
|  | 47     if (event.key == "Enter" && !blacklistedElements.has(event.target.localName)
     ) | 
|  | 48       document.getElementById("continue").click(); | 
|  | 49     else if (event.key == "Escape") | 
|  | 50       document.getElementById("cancel").click(); | 
|  | 51   }); | 
|  | 52 | 
|  | 53   browser.runtime.sendMessage({ | 
|  | 54     type: "app.get", | 
|  | 55     what: "doclink", | 
|  | 56     link: "reporter_privacy" | 
|  | 57   }).then(url => | 
|  | 58   { | 
|  | 59     document.getElementById("privacyPolicy").href = url; | 
|  | 60   }); | 
|  | 61 | 
|  | 62   initDataCollector(); | 
|  | 63 }); | 
|  | 64 | 
|  | 65 function getCurrentPage() | 
|  | 66 { | 
|  | 67   return document.querySelector(".page:not([hidden])").id; | 
|  | 68 } | 
|  | 69 | 
|  | 70 function setCurrentPage(pageId) | 
|  | 71 { | 
|  | 72   if (!pages.hasOwnProperty(pageId)) | 
|  | 73     return; | 
|  | 74 | 
|  | 75   let previousPage = document.querySelector(".page:not([hidden])"); | 
|  | 76   if (previousPage) | 
|  | 77     previousPage.hidden = true; | 
|  | 78 | 
|  | 79   document.getElementById(pageId).hidden = false; | 
|  | 80   pages[pageId][0](); | 
|  | 81 } | 
|  | 82 | 
|  | 83 function censorURL(url) | 
|  | 84 { | 
|  | 85   return url.replace(/([?;&\/#][^?;&\/#]+?=)[^?;&\/#]+/g, "$1*"); | 
|  | 86 } | 
|  | 87 | 
|  | 88 function encodeHTML(str) | 
|  | 89 { | 
|  | 90   return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").
     replace(/"/g, """); | 
|  | 91 } | 
|  | 92 | 
|  | 93 function serializeReportData() | 
|  | 94 { | 
|  | 95   let result = new XMLSerializer().serializeToString(reportData); | 
|  | 96 | 
|  | 97   // Insert line breaks before each new tag | 
|  | 98   result = result.replace(/(<[^\/]([^"<>]*|"[^"]*")*>)/g, "\n$1"); | 
|  | 99   result = result.replace(/^\n+/, ""); | 
|  | 100   return result; | 
|  | 101 } | 
|  | 102 | 
|  | 103 function retrieveAddonInfo() | 
|  | 104 { | 
|  | 105   let element = reportData.createElement("adblock-plus"); | 
|  | 106   return browser.runtime.sendMessage({ | 
|  | 107     type: "app.get", | 
|  | 108     what: "addonVersion" | 
|  | 109   }).then(addonVersion => | 
|  | 110   { | 
|  | 111     element.setAttribute("version", addonVersion); | 
|  | 112     return browser.runtime.sendMessage({ | 
|  | 113       type: "app.get", | 
|  | 114       what: "localeInfo" | 
|  | 115     }); | 
|  | 116   }).then(({locale}) => | 
|  | 117   { | 
|  | 118     element.setAttribute("locale", locale); | 
|  | 119     reportData.documentElement.appendChild(element); | 
|  | 120   }); | 
|  | 121 } | 
|  | 122 | 
|  | 123 function retrieveApplicationInfo() | 
|  | 124 { | 
|  | 125   let element = reportData.createElement("application"); | 
|  | 126   return browser.runtime.sendMessage({ | 
|  | 127     type: "app.get", | 
|  | 128     what: "application" | 
|  | 129   }).then(application => | 
|  | 130   { | 
|  | 131     element.setAttribute("name", application); | 
|  | 132     return browser.runtime.sendMessage({ | 
|  | 133       type: "app.get", | 
|  | 134       what: "applicationVersion" | 
|  | 135     }); | 
|  | 136   }).then(applicationVersion => | 
|  | 137   { | 
|  | 138     element.setAttribute("version", applicationVersion); | 
|  | 139     element.setAttribute("userAgent", navigator.userAgent); | 
|  | 140     reportData.documentElement.appendChild(element); | 
|  | 141   }); | 
|  | 142 } | 
|  | 143 | 
|  | 144 function retrievePlatformInfo() | 
|  | 145 { | 
|  | 146   let element = reportData.createElement("platform"); | 
|  | 147   return browser.runtime.sendMessage({ | 
|  | 148     type: "app.get", | 
|  | 149     what: "platform" | 
|  | 150   }).then(platform => | 
|  | 151   { | 
|  | 152     element.setAttribute("name", platform); | 
|  | 153     return browser.runtime.sendMessage({ | 
|  | 154       type: "app.get", | 
|  | 155       what: "platformVersion" | 
|  | 156     }); | 
|  | 157   }).then(platformVersion => | 
|  | 158   { | 
|  | 159     element.setAttribute("version", platformVersion); | 
|  | 160     reportData.documentElement.appendChild(element); | 
|  | 161   }); | 
|  | 162 } | 
|  | 163 | 
|  | 164 function retrieveTabURL(tabId) | 
|  | 165 { | 
|  | 166   return browser.tabs.get(tabId).then(tab => | 
|  | 167   { | 
|  | 168     let element = reportData.createElement("window"); | 
|  | 169     if (tab.url) | 
|  | 170       element.setAttribute("url", censorURL(tab.url)); | 
|  | 171     reportData.documentElement.appendChild(element); | 
|  | 172   }); | 
|  | 173 } | 
|  | 174 | 
|  | 175 function retrieveSubscriptions() | 
|  | 176 { | 
|  | 177   return browser.runtime.sendMessage({ | 
|  | 178     type: "subscriptions.get", | 
|  | 179     ignoreDisabled: true, | 
|  | 180     downloadable: true | 
|  | 181   }).then(subscriptions => | 
|  | 182   { | 
|  | 183     let element = reportData.createElement("subscriptions"); | 
|  | 184     for (let subscription of subscriptions) | 
|  | 185     { | 
|  | 186       if (!/^(http|https|ftp):/.test(subscription.url)) | 
|  | 187         continue; | 
|  | 188 | 
|  | 189       let now = Math.round(Date.now() / 1000); | 
|  | 190       let subscriptionElement = reportData.createElement("subscription"); | 
|  | 191       subscriptionElement.setAttribute("id", subscription.url); | 
|  | 192       if (subscription.lastDownload) | 
|  | 193         subscriptionElement.setAttribute("lastDownloadAttempt", subscription.las
     tDownload - now); | 
|  | 194       subscriptionElement.setAttribute("downloadStatus", subscription.downloadSt
     atus); | 
|  | 195       element.appendChild(subscriptionElement); | 
|  | 196     } | 
|  | 197     reportData.documentElement.appendChild(element); | 
|  | 198   }); | 
|  | 199 } | 
|  | 200 | 
|  | 201 function initDataCollector() | 
|  | 202 { | 
|  | 203   Promise.resolve().then(() => | 
|  | 204   { | 
|  | 205     let tabId = parseInt(location.search.replace(/^\?/, ""), 10) || 0; | 
|  | 206     let handlers = [ | 
|  | 207       retrieveAddonInfo(), | 
|  | 208       retrieveApplicationInfo(), | 
|  | 209       retrievePlatformInfo(), | 
|  | 210       retrieveTabURL(tabId), | 
|  | 211       retrieveSubscriptions() | 
|  | 212     ]; | 
|  | 213     return Promise.all(handlers); | 
|  | 214   }).then(() => | 
|  | 215   { | 
|  | 216     setCurrentPage("typeSelectorPage"); | 
|  | 217   }).catch(e => | 
|  | 218   { | 
|  | 219     if (!e.name && e.message) | 
|  | 220       e = e.message; | 
|  | 221     alert(e); | 
|  | 222     window.close(); | 
|  | 223   }); | 
|  | 224 } | 
|  | 225 | 
|  | 226 function initTypeSelector() | 
|  | 227 { | 
|  | 228   document.getElementById("typeFalsePositive").focus(); | 
|  | 229 | 
|  | 230 | 
|  | 231   for (let checkbox of document.querySelectorAll("input[name='type']")) | 
|  | 232   { | 
|  | 233     checkbox.addEventListener("click", () => | 
|  | 234     { | 
|  | 235       if (document.querySelector("input[name='type']:checked")) | 
|  | 236         document.getElementById("continue").disabled = false; | 
|  | 237     }); | 
|  | 238   } | 
|  | 239 } | 
|  | 240 | 
|  | 241 function leaveTypeSelector() | 
|  | 242 { | 
|  | 243   let checkbox = document.querySelector("input[name='type']:checked"); | 
|  | 244   reportData.documentElement.setAttribute("type", checkbox.value); | 
|  | 245   setCurrentPage("commentPage"); | 
|  | 246 } | 
|  | 247 | 
|  | 248 function initCommentPage() | 
|  | 249 { | 
|  | 250   let continueButton = document.getElementById("continue"); | 
|  | 251   continueButton.disabled = true; | 
|  | 252   continueButton.textContent = browser.i18n.getMessage("issueReporter_sendButton
     _label"); | 
|  | 253 | 
|  | 254   let emailElement = reportData.createElement("email"); | 
|  | 255   let emailField = document.getElementById("email"); | 
|  | 256   let anonymousSubmissionField = document.getElementById("anonymousSubmission"); | 
|  | 257   let validateEmail = () => | 
|  | 258   { | 
|  | 259     document.getElementById("anonymousSubmissionWarning").setAttribute("data-inv
     isible", !anonymousSubmissionField.checked); | 
|  | 260     if (anonymousSubmissionField.checked) | 
|  | 261     { | 
|  | 262       emailField.value = ""; | 
|  | 263       emailField.disabled = true; | 
|  | 264       continueButton.disabled = false; | 
|  | 265       if (emailElement.parentNode) | 
|  | 266         emailElement.parentNode.removeChild(emailElement); | 
|  | 267     } | 
|  | 268     else | 
|  | 269     { | 
|  | 270       emailField.disabled = false; | 
|  | 271 | 
|  | 272       let value = emailField.value.trim(); | 
|  | 273       emailElement.textContent = value; | 
|  | 274       reportData.documentElement.appendChild(emailElement); | 
|  | 275       continueButton.disabled = value == "" || !emailField.validity.valid; | 
|  | 276     } | 
|  | 277   }; | 
|  | 278   emailField.addEventListener("input", validateEmail); | 
|  | 279   anonymousSubmissionField.addEventListener("click", validateEmail); | 
|  | 280 | 
|  | 281   let commentElement = reportData.createElement("comment"); | 
|  | 282   document.getElementById("comment").addEventListener("input", event => | 
|  | 283   { | 
|  | 284     if (commentElement.parentNode) | 
|  | 285       commentElement.parentNode.removeChild(commentElement); | 
|  | 286 | 
|  | 287     let value = event.target.value.trim(); | 
|  | 288     commentElement.textContent = value.substr(0, 1000); | 
|  | 289     if (value) | 
|  | 290       reportData.documentElement.appendChild(commentElement); | 
|  | 291     document.getElementById("commentLengthWarning").setAttribute("data-invisible
     ", value.length <= 1000); | 
|  | 292   }); | 
|  | 293 | 
|  | 294   document.getElementById("showData").addEventListener("click", event => | 
|  | 295   { | 
|  | 296     event.preventDefault(); | 
|  | 297 | 
|  | 298     // window.open() won't open data: URIs in Chrome | 
|  | 299     browser.tabs.getCurrent().then(tab => | 
|  | 300     { | 
|  | 301       browser.tabs.create({ | 
|  | 302         url: "data:text/xml;charset=utf-8," + encodeURIComponent(serializeReport
     Data()), | 
|  | 303         openerTabId: tab.id | 
|  | 304       }); | 
|  | 305     }) | 
|  | 306   }); | 
|  | 307 | 
|  | 308   emailField.focus(); | 
|  | 309 } | 
|  | 310 | 
|  | 311 function leaveCommentPage() | 
|  | 312 { | 
|  | 313   setCurrentPage("sendPage"); | 
|  | 314 } | 
|  | 315 | 
|  | 316 function initSendPage() | 
|  | 317 { | 
|  | 318   document.getElementById("cancel").hidden = true; | 
|  | 319 | 
|  | 320   let continueButton = document.getElementById("continue"); | 
|  | 321   continueButton.textContent = browser.i18n.getMessage("issueReporter_doneButton
     _label"); | 
|  | 322   continueButton.disabled = true; | 
|  | 323 | 
|  | 324   let uuid = new Uint16Array(8); | 
|  | 325   window.crypto.getRandomValues(uuid); | 
|  | 326   uuid[3] = uuid[3] & 0x0FFF | 0x4000;  // version 4 | 
|  | 327   uuid[4] = uuid[4] & 0x3FFF | 0x8000;  // variant 1 | 
|  | 328 | 
|  | 329   let uuidString = ""; | 
|  | 330   for (let i = 0; i < uuid.length; i++) | 
|  | 331   { | 
|  | 332     let component = uuid[i].toString(16); | 
|  | 333     while (component.length < 4) | 
|  | 334       component = "0" + component; | 
|  | 335     uuidString += component; | 
|  | 336     if (i >= 1 && i<= 4) | 
|  | 337       uuidString += "-"; | 
|  | 338   } | 
|  | 339 | 
|  | 340   let params = new URLSearchParams({ | 
|  | 341     version: 1, | 
|  | 342     guid: uuidString, | 
|  | 343     lang: reportData.getElementsByTagName("adblock-plus")[0].getAttribute("local
     e") | 
|  | 344   }); | 
|  | 345   let url = "https://reports.adblockplus.org/submitReport?" + params; | 
|  | 346 | 
|  | 347   let reportSent = event => | 
|  | 348   { | 
|  | 349     let success; | 
|  | 350     let errorMessage; | 
|  | 351     try | 
|  | 352     { | 
|  | 353       success = request.status == 200; | 
|  | 354       errorMessage = request.status + " " + request.statusText; | 
|  | 355     } | 
|  | 356     catch (e) | 
|  | 357     { | 
|  | 358       // No request status, connection wasn't established. | 
|  | 359       success = false; | 
|  | 360       errorMessage = browser.i18n.getMessage("filters_subscription_lastDownload_
     connectionError"); | 
|  | 361     } | 
|  | 362 | 
|  | 363     let result; | 
|  | 364     try | 
|  | 365     { | 
|  | 366       result = request.responseText; | 
|  | 367     } | 
|  | 368     catch (e) | 
|  | 369     { | 
|  | 370       result = ""; | 
|  | 371     } | 
|  | 372 | 
|  | 373     result = result.replace(/%CONFIRMATION%/g, encodeHTML(browser.i18n.getMessag
     e("issueReporter_confirmationMessage"))); | 
|  | 374     result = result.replace(/%KNOWNISSUE%/g, encodeHTML(browser.i18n.getMessage(
     "issueReporter_knownIssueMessage"))); | 
|  | 375     result = result.replace(/(<html)\b/, '$1 dir="' + encodeHTML(window.getCompu
     tedStyle(document.documentElement, "").direction + '"')); | 
|  | 376 | 
|  | 377     document.getElementById("sendingProgressContainer").hidden = true; | 
|  | 378 | 
|  | 379     let resultFrame = document.getElementById("result"); | 
|  | 380     resultFrame.setAttribute("src", "data:text/html;charset=utf-8," + encodeURIC
     omponent(result)); | 
|  | 381     resultFrame.hidden = false; | 
|  | 382 | 
|  | 383     document.getElementById("continue").disabled = false; | 
|  | 384   }; | 
|  | 385 | 
|  | 386   let request = new XMLHttpRequest(); | 
|  | 387   request.open("POST", url); | 
|  | 388   request.setRequestHeader("Content-Type", "text/xml"); | 
|  | 389   request.setRequestHeader("X-Adblock-Plus", "1"); | 
|  | 390   request.addEventListener("load", reportSent); | 
|  | 391   request.addEventListener("error", reportSent); | 
|  | 392   request.upload.addEventListener("progress", event => | 
|  | 393   { | 
|  | 394     if (!event.lengthComputable) | 
|  | 395       return; | 
|  | 396 | 
|  | 397     let progress = Math.round(event.loaded / event.total * 100); | 
|  | 398     if (event.loaded > 0) | 
|  | 399     { | 
|  | 400       let progress = document.getElementById("sendingProgress"); | 
|  | 401       progress.max = event.total; | 
|  | 402       progress.value = event.loaded; | 
|  | 403     } | 
|  | 404   }); | 
|  | 405   request.send(serializeReportData()); | 
|  | 406 } | 
|  | 407 | 
|  | 408 function leaveSendPage() | 
|  | 409 { | 
|  | 410   window.close(); | 
|  | 411 } | 
| OLD | NEW | 
|---|