Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: issue-reporter.js

Issue 29727613: Issue 6386 - Add Requests and Filters data to the Report data
Patch Set: Rebased Created April 6, 2018, 4:46 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « issue-reporter.html ('k') | locale/en_US/issue-reporter.json » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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 });
OLDNEW
« no previous file with comments | « issue-reporter.html ('k') | locale/en_US/issue-reporter.json » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld