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

Delta Between Two Patch Sets: popup.js

Issue 29570774: Issue 5593 - Merge notification.js and stats.js into popup.js (Closed) Base URL: https://hg.adblockplus.org/adblockpluschrome/
Left Patch Set: Created Oct. 9, 2017, 5:39 p.m.
Right Patch Set: Rename ev to event Created Oct. 10, 2017, 5:17 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « popup.html ('k') | stats.js » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
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 const shareURL = "https://adblockplus.org/";
21 const messageMark = {};
22
23 const shareLinks = {
24 facebook: ["https://www.facebook.com/dialog/feed", {
25 app_id: "475542399197328",
26 link: shareURL,
27 redirect_uri: "https://www.facebook.com/",
28 ref: "adcounter",
29 name: messageMark,
30 actions: JSON.stringify([
31 {
32 name: chrome.i18n.getMessage("stats_share_download"),
33 link: shareURL
34 }
35 ])
36 }],
37 gplus: ["https://plus.google.com/share", {
38 url: shareURL
39 }],
40 twitter: ["https://twitter.com/intent/tweet", {
41 text: messageMark,
42 url: shareURL,
43 via: "AdblockPlus"
44 }]
45 };
46
20 let tab = null; 47 let tab = null;
21 48
22 function getPref(key, callback) 49 function getPref(key, callback)
23 { 50 {
24 chrome.runtime.sendMessage({type: "prefs.get", key}, callback); 51 chrome.runtime.sendMessage({type: "prefs.get", key}, callback);
25 } 52 }
26 53
27 function setPref(key, value, callback) 54 function setPref(key, value, callback)
28 { 55 {
29 chrome.runtime.sendMessage({type: "prefs.set", key, value}, callback); 56 chrome.runtime.sendMessage({type: "prefs.set", key, value}, callback);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 { 90 {
64 if (ready) 91 if (ready)
65 { 92 {
66 chrome.runtime.onMessage.removeListener(onMessage); 93 chrome.runtime.onMessage.removeListener(onMessage);
67 resolve(); 94 resolve();
68 } 95 }
69 }); 96 });
70 }); 97 });
71 } 98 }
72 99
73 function onLoad() 100 function toggleEnabled()
Manish Jethani 2017/10/10 05:08:56 onLoad has been inlined, i.e. it's an anonymous fu
101 {
102 let disabled = document.body.classList.toggle("disabled");
103 chrome.runtime.sendMessage({
104 type: disabled ? "filters.whitelist" : "filters.unwhitelist",
105 tab
106 });
107 }
108
109 function activateClickHide()
110 {
111 document.body.classList.add("clickhide-active");
112 chrome.tabs.sendMessage(tab.id, {
113 type: "composer.content.startPickingElement"
114 });
115
116 // Close the popup after a few seconds, so user doesn't have to
117 activateClickHide.timeout = window.setTimeout(window.close, 5000);
118 }
119
120 function cancelClickHide()
121 {
122 if (activateClickHide.timeout)
123 {
124 window.clearTimeout(activateClickHide.timeout);
125 activateClickHide.timeout = null;
126 }
127 document.body.classList.remove("clickhide-active");
128 chrome.tabs.sendMessage(tab.id, {type: "composer.content.finished"});
129 }
130
131 function toggleCollapse(event)
132 {
133 let collapser = event.currentTarget;
134 let collapsible = document.getElementById(collapser.dataset.collapsible);
135 collapsible.classList.toggle("collapsed");
136 togglePref(collapser.dataset.option);
137 }
138
139 function getDocLinks(notification)
140 {
141 if (!notification.links)
142 return Promise.resolve([]);
143
144 return Promise.all(
145 notification.links.map(link =>
146 {
147 return new Promise((resolve, reject) =>
148 {
149 chrome.runtime.sendMessage({
150 type: "app.get",
151 what: "doclink",
152 link
153 }, resolve);
154 });
155 })
156 );
157 }
158
159 function insertMessage(element, text, links)
160 {
161 let match = /^(.*?)<(a|strong)>(.*?)<\/\2>(.*)$/.exec(text);
162 if (!match)
163 {
164 element.appendChild(document.createTextNode(text));
165 return;
166 }
167
168 let before = match[1];
169 let tagName = match[2];
170 let value = match[3];
171 let after = match[4];
172
173 insertMessage(element, before, links);
174
175 let newElement = document.createElement(tagName);
176 if (tagName == "a" && links && links.length)
177 newElement.href = links.shift();
178 insertMessage(newElement, value, links);
179 element.appendChild(newElement);
180
181 insertMessage(element, after, links);
182 }
183
184 function createShareLink(network, blockedCount)
185 {
186 let url = shareLinks[network][0];
187 let params = shareLinks[network][1];
188
189 let querystring = [];
190 for (let key in params)
191 {
192 let value = params[key];
193 if (value == messageMark)
194 value = chrome.i18n.getMessage("stats_share_message", blockedCount);
195 querystring.push(
196 encodeURIComponent(key) + "=" + encodeURIComponent(value)
197 );
198 }
199 return url + "?" + querystring.join("&");
200 }
201
202 function updateStats()
203 {
204 let statsPage = document.getElementById("stats-page");
205 chrome.runtime.sendMessage({
206 type: "stats.getBlockedPerPage",
207 tab
208 },
209 blockedPage =>
210 {
211 ext.i18n.setElementText(statsPage, "stats_label_page",
212 [blockedPage.toLocaleString()]);
213 });
214
215 let statsTotal = document.getElementById("stats-total");
216 getPref("blocked_total", blockedTotal =>
217 {
218 ext.i18n.setElementText(statsTotal, "stats_label_total",
219 [blockedTotal.toLocaleString()]);
220 });
221 }
222
223 function share(event)
224 {
225 getPref("blocked_total", blockedTotal =>
226 {
227 // Easter Egg
228 if (blockedTotal <= 9000 || blockedTotal >= 10000)
229 {
230 blockedTotal = blockedTotal.toLocaleString();
231 }
232 else
233 {
234 blockedTotal = chrome.i18n.getMessage("stats_over",
235 (9000).toLocaleString());
236 }
237
238 chrome.tabs.create({
239 url: createShareLink(event.target.dataset.social, blockedTotal)
240 });
241 });
242 }
243
244 function toggleIconNumber()
245 {
246 togglePref("show_statsinicon", showStatsInIcon =>
247 {
248 document.getElementById("show-iconnumber").setAttribute(
249 "aria-checked", showStatsInIcon
250 );
251 });
252 }
253
254 document.addEventListener("DOMContentLoaded", () =>
74 { 255 {
75 chrome.tabs.query({active: true, lastFocusedWindow: true}, tabs => 256 chrome.tabs.query({active: true, lastFocusedWindow: true}, tabs =>
76 { 257 {
77 if (tabs.length > 0) 258 if (tabs.length > 0)
78 tab = {id: tabs[0].id, url: tabs[0].url}; 259 tab = {id: tabs[0].id, url: tabs[0].url};
79 260
80 let urlProtocol = tab && tab.url && new URL(tab.url).protocol; 261 let urlProtocol = tab && tab.url && new URL(tab.url).protocol;
81 262
82 // Mark page as 'local' to hide non-relevant elements 263 // Mark page as 'local' to hide non-relevant elements
83 if (urlProtocol != "http:" && urlProtocol != "https:") 264 if (urlProtocol != "http:" && urlProtocol != "https:")
(...skipping 23 matching lines...) Expand all
107 288
108 chrome.tabs.sendMessage(tab.id, { 289 chrome.tabs.sendMessage(tab.id, {
109 type: "composer.content.getState" 290 type: "composer.content.getState"
110 }, 291 },
111 response => 292 response =>
112 { 293 {
113 if (response && response.active) 294 if (response && response.active)
114 document.body.classList.add("clickhide-active"); 295 document.body.classList.add("clickhide-active");
115 }); 296 });
116 } 297 }
298
299 updateStats();
300 document.getElementById("stats-container").removeAttribute("hidden");
117 }); 301 });
118 302
119 document.getElementById("enabled").addEventListener( 303 document.getElementById("enabled").addEventListener(
120 "click", toggleEnabled, false 304 "click", toggleEnabled
121 ); 305 );
122 document.getElementById("clickhide").addEventListener( 306 document.getElementById("clickhide").addEventListener(
123 "click", activateClickHide, false 307 "click", activateClickHide
124 ); 308 );
125 document.getElementById("clickhide-cancel").addEventListener( 309 document.getElementById("clickhide-cancel").addEventListener(
126 "click", cancelClickHide, false 310 "click", cancelClickHide
127 ); 311 );
128 document.getElementById("options").addEventListener("click", () => 312 document.getElementById("options").addEventListener("click", () =>
129 { 313 {
130 chrome.runtime.sendMessage({type: "app.open", what: "options"}); 314 chrome.runtime.sendMessage({type: "app.open", what: "options"});
131 window.close(); 315 window.close();
132 }, false); 316 });
133 317
134 // Set up collapsing of menu items 318 // Set up collapsing of menu items
135 for (let collapser of document.getElementsByClassName("collapse")) 319 for (let collapser of document.getElementsByClassName("collapse"))
136 { 320 {
137 collapser.addEventListener("click", toggleCollapse, false); 321 collapser.addEventListener("click", toggleCollapse);
138 getPref(collapser.dataset.option, value => 322 getPref(collapser.dataset.option, value =>
139 { 323 {
140 if (value) 324 if (value)
141 { 325 {
142 document.getElementById( 326 document.getElementById(
143 collapser.dataset.collapsible 327 collapser.dataset.collapsible
144 ).classList.remove("collapsed"); 328 ).classList.remove("collapsed");
145 } 329 }
146 }); 330 });
147 } 331 }
148 } 332
149 333 document.getElementById("share-box").addEventListener("click", share);
150 function toggleEnabled() 334 let showIconNumber = document.getElementById("show-iconnumber");
151 { 335 getPref("show_statsinicon", showStatsInIcon =>
152 let disabled = document.body.classList.toggle("disabled"); 336 {
337 showIconNumber.setAttribute("aria-checked", showStatsInIcon);
338 });
339 showIconNumber.addEventListener("click", toggleIconNumber);
340 document.querySelector("label[for='show-iconnumber']").addEventListener(
341 "click", toggleIconNumber
342 );
343 });
344
345 window.addEventListener("load", () =>
346 {
153 chrome.runtime.sendMessage({ 347 chrome.runtime.sendMessage({
154 type: disabled ? "filters.whitelist" : "filters.unwhitelist", 348 type: "notifications.get",
155 tab 349 displayMethod: "popup"
156 }); 350 }, notification =>
157 } 351 {
158 352 if (!notification)
159 function activateClickHide()
160 {
161 document.body.classList.add("clickhide-active");
162 chrome.tabs.sendMessage(tab.id, {
163 type: "composer.content.startPickingElement"
164 });
165
166 // Close the popup after a few seconds, so user doesn't have to
167 activateClickHide.timeout = window.setTimeout(window.close, 5000);
168 }
169
170 function cancelClickHide()
171 {
172 if (activateClickHide.timeout)
173 {
174 window.clearTimeout(activateClickHide.timeout);
175 activateClickHide.timeout = null;
176 }
177 document.body.classList.remove("clickhide-active");
178 chrome.tabs.sendMessage(tab.id, {type: "composer.content.finished"});
179 }
180
181 function toggleCollapse(event)
182 {
183 let collapser = event.currentTarget;
184 let collapsible = document.getElementById(collapser.dataset.collapsible);
185 collapsible.classList.toggle("collapsed");
186 togglePref(collapser.dataset.option);
187 }
188
189 document.addEventListener("DOMContentLoaded", onLoad, false);
190
191 /* Notifications */
192
193 (function()
Manish Jethani 2017/10/09 17:43:24 The logic inside these anonymous functions needs t
Sebastian Noack 2017/10/09 19:29:46 Yeah, please, go ahead.
Manish Jethani 2017/10/10 05:08:56 Done.
194 {
195 function getDocLinks(notification)
196 {
197 if (!notification.links)
198 return Promise.resolve([]);
199
200 return Promise.all(
201 notification.links.map(link =>
202 {
203 return new Promise((resolve, reject) =>
204 {
205 chrome.runtime.sendMessage({
206 type: "app.get",
207 what: "doclink",
208 link
209 }, resolve);
210 });
211 })
212 );
213 }
214
215 function insertMessage(element, text, links)
216 {
217 let match = /^(.*?)<(a|strong)>(.*?)<\/\2>(.*)$/.exec(text);
218 if (!match)
219 {
220 element.appendChild(document.createTextNode(text));
221 return; 353 return;
222 } 354
223 355 let titleElement = document.getElementById("notification-title");
224 let before = match[1]; 356 let messageElement = document.getElementById("notification-message");
225 let tagName = match[2]; 357
226 let value = match[3]; 358 titleElement.textContent = notification.texts.title;
227 let after = match[4]; 359
228 360 getDocLinks(notification).then(docLinks =>
229 insertMessage(element, before, links); 361 {
230 362 insertMessage(messageElement, notification.texts.message, docLinks);
231 let newElement = document.createElement(tagName); 363
232 if (tagName == "a" && links && links.length) 364 messageElement.addEventListener("click", event =>
233 newElement.href = links.shift(); 365 {
234 insertMessage(newElement, value, links); 366 let link = event.target;
235 element.appendChild(newElement); 367 while (link && link != messageElement && link.localName != "a")
236 368 link = link.parentNode;
237 insertMessage(element, after, links); 369 if (!link)
238 } 370 return;
239 371 event.preventDefault();
240 window.addEventListener("load", () => 372 event.stopPropagation();
241 { 373 chrome.tabs.create({url: link.href});
242 chrome.runtime.sendMessage({ 374 });
243 type: "notifications.get",
244 displayMethod: "popup"
245 }, notification =>
246 {
247 if (!notification)
248 return;
249
250 let titleElement = document.getElementById("notification-title");
251 let messageElement = document.getElementById("notification-message");
252
253 titleElement.textContent = notification.texts.title;
254
255 getDocLinks(notification).then(docLinks =>
256 {
257 insertMessage(messageElement, notification.texts.message, docLinks);
258
259 messageElement.addEventListener("click", event =>
260 {
261 let link = event.target;
262 while (link && link != messageElement && link.localName != "a")
263 link = link.parentNode;
264 if (!link)
265 return;
266 event.preventDefault();
267 event.stopPropagation();
268 chrome.tabs.create({url: link.href});
269 });
270 });
271
272 let notificationElement = document.getElementById("notification");
273 notificationElement.className = notification.type;
274 notificationElement.hidden = false;
275 notificationElement.addEventListener("click", event =>
276 {
277 if (event.target.id == "notification-close")
278 notificationElement.classList.add("closing");
279 else if (event.target.id == "notification-optout" ||
280 event.target.id == "notification-hide")
281 {
282 if (event.target.id == "notification-optout")
283 setPref("notifications_ignoredcategories", true);
284
285 notificationElement.hidden = true;
286 notification.onClicked();
287 }
288 }, true);
289 }); 375 });
290 }, false); 376
291 }()); 377 let notificationElement = document.getElementById("notification");
292 378 notificationElement.className = notification.type;
293 /* Stats */ 379 notificationElement.hidden = false;
294 380 notificationElement.addEventListener("click", event =>
295 (function() 381 {
296 { 382 if (event.target.id == "notification-close")
297 let currentTab; 383 notificationElement.classList.add("closing");
298 const shareURL = "https://adblockplus.org/"; 384 else if (event.target.id == "notification-optout" ||
299 385 event.target.id == "notification-hide")
300 let messageMark = {}; 386 {
301 let shareLinks = { 387 if (event.target.id == "notification-optout")
302 facebook: ["https://www.facebook.com/dialog/feed", { 388 setPref("notifications_ignoredcategories", true);
303 app_id: "475542399197328", 389
304 link: shareURL, 390 notificationElement.hidden = true;
305 redirect_uri: "https://www.facebook.com/", 391 notification.onClicked();
306 ref: "adcounter", 392 }
307 name: messageMark, 393 }, true);
308 actions: JSON.stringify([ 394 });
309 { 395 });
310 name: chrome.i18n.getMessage("stats_share_download"),
311 link: shareURL
312 }
313 ])
314 }],
315 gplus: ["https://plus.google.com/share", {
316 url: shareURL
317 }],
318 twitter: ["https://twitter.com/intent/tweet", {
319 text: messageMark,
320 url: shareURL,
321 via: "AdblockPlus"
322 }]
323 };
324
325 function createShareLink(network, blockedCount)
326 {
327 let url = shareLinks[network][0];
328 let params = shareLinks[network][1];
329
330 let querystring = [];
331 for (let key in params)
332 {
333 let value = params[key];
334 if (value == messageMark)
335 value = chrome.i18n.getMessage("stats_share_message", blockedCount);
336 querystring.push(
337 encodeURIComponent(key) + "=" + encodeURIComponent(value)
338 );
339 }
340 return url + "?" + querystring.join("&");
341 }
342
343 function onLoad()
344 {
345 document.getElementById("share-box").addEventListener("click", share,
346 false);
347 let showIconNumber = document.getElementById("show-iconnumber");
348 getPref("show_statsinicon", showStatsInIcon =>
349 {
350 showIconNumber.setAttribute("aria-checked", showStatsInIcon);
351 });
352 showIconNumber.addEventListener("click", toggleIconNumber, false);
353 document.querySelector("label[for='show-iconnumber']").addEventListener(
354 "click", toggleIconNumber, false
355 );
356
357 // Update stats
358 chrome.tabs.query({active: true, lastFocusedWindow: true}, tabs =>
359 {
360 currentTab = tabs[0];
361 updateStats();
362
363 document.getElementById("stats-container").removeAttribute("hidden");
364 });
365 }
366
367 function updateStats()
368 {
369 let statsPage = document.getElementById("stats-page");
370 chrome.runtime.sendMessage({
371 type: "stats.getBlockedPerPage",
372 tab: currentTab
Manish Jethani 2017/10/10 05:08:56 Note: There's no currentTab anymore, it's just tab
373 },
374 blockedPage =>
375 {
376 ext.i18n.setElementText(statsPage, "stats_label_page",
377 [blockedPage.toLocaleString()]);
378 });
379
380 let statsTotal = document.getElementById("stats-total");
381 getPref("blocked_total", blockedTotal =>
382 {
383 ext.i18n.setElementText(statsTotal, "stats_label_total",
384 [blockedTotal.toLocaleString()]);
385 });
386 }
387
388 function share(ev)
389 {
390 getPref("blocked_total", blockedTotal =>
391 {
392 // Easter Egg
393 if (blockedTotal <= 9000 || blockedTotal >= 10000)
394 {
395 blockedTotal = blockedTotal.toLocaleString();
396 }
397 else
398 {
399 blockedTotal = chrome.i18n.getMessage("stats_over",
400 (9000).toLocaleString());
401 }
402
403 chrome.tabs.create({
404 url: createShareLink(ev.target.dataset.social, blockedTotal)
405 });
406 });
407 }
408
409 function toggleIconNumber()
410 {
411 togglePref("show_statsinicon", showStatsInIcon =>
412 {
413 document.getElementById("show-iconnumber").setAttribute(
414 "aria-checked", showStatsInIcon
415 );
416 });
417 }
418
419 document.addEventListener("DOMContentLoaded", onLoad, false);
420 }());
LEFTRIGHT

Powered by Google App Engine
This is Rietveld