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

Delta Between Two Patch Sets: popup.js

Issue 29570614: Issue 5028 - Use browser namespace (Closed) Base URL: https://hg.adblockplus.org/adblockpluschrome/
Left Patch Set: Created Oct. 9, 2017, 3:12 p.m.
Right Patch Set: Update adblockplusui dependency Created Oct. 17, 2017, 1:02 p.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') | qunit/tests/prefs.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 /*
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/>.
1 */ 16 */
2 17
3 "use strict"; 18 "use strict";
4 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: browser.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
5 let tab = null; 47 let tab = null;
6 48
7 function getPref(key, callback) 49 function getPref(key, callback)
8 { 50 {
9 chrome.runtime.sendMessage({type: "prefs.get", key}, callback); 51 browser.runtime.sendMessage({type: "prefs.get", key}, callback);
52 }
53
54 function setPref(key, value, callback)
55 {
56 browser.runtime.sendMessage({type: "prefs.set", key, value}, callback);
10 } 57 }
11 58
12 function togglePref(key, callback) 59 function togglePref(key, callback)
13 { 60 {
14 chrome.runtime.sendMessage({type: "prefs.toggle", key}, callback); 61 browser.runtime.sendMessage({type: "prefs.toggle", key}, callback);
15 } 62 }
16 63
17 function isPageWhitelisted(callback) 64 function isPageWhitelisted(callback)
18 { 65 {
19 chrome.runtime.sendMessage({type: "filters.isWhitelisted", tab}, callback); 66 browser.runtime.sendMessage({type: "filters.isWhitelisted", tab}, callback);
20 } 67 }
21 68
22 function whenPageReady() 69 function whenPageReady()
23 { 70 {
24 return new Promise(resolve => 71 return new Promise(resolve =>
25 { 72 {
26 function onMessage(message, sender) 73 function onMessage(message, sender)
27 { 74 {
28 if (message.type == "composer.ready" && sender.page && 75 if (message.type == "composer.ready" && sender.page &&
29 sender.page.id == tab.id) 76 sender.page.id == tab.id)
30 { 77 {
31 chrome.runtime.onMessage.removeListener(onMessage); 78 browser.runtime.onMessage.removeListener(onMessage);
32 resolve(); 79 resolve();
33 } 80 }
34 } 81 }
35 82
36 chrome.runtime.onMessage.addListener(onMessage); 83 browser.runtime.onMessage.addListener(onMessage);
37 84
38 chrome.runtime.sendMessage({ 85 browser.runtime.sendMessage({
39 type: "composer.isPageReady", 86 type: "composer.isPageReady",
40 pageId: tab.id 87 pageId: tab.id
41 }, 88 },
42 ready => 89 ready =>
43 { 90 {
44 if (ready) 91 if (ready)
45 { 92 {
46 chrome.runtime.onMessage.removeListener(onMessage); 93 browser.runtime.onMessage.removeListener(onMessage);
47 resolve(); 94 resolve();
48 } 95 }
49 }); 96 });
50 }); 97 });
51 } 98 }
52 99
53 function onLoad() 100 function toggleEnabled()
54 { 101 {
55 chrome.tabs.query({active: true, lastFocusedWindow: true}, tabs => 102 let disabled = document.body.classList.toggle("disabled");
103 browser.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 browser.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 browser.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 browser.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 = browser.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 browser.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 = browser.i18n.getMessage("stats_over",
235 (9000).toLocaleString());
236 }
237
238 browser.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", () =>
255 {
256 browser.tabs.query({active: true, lastFocusedWindow: true}, tabs =>
56 { 257 {
57 if (tabs.length > 0) 258 if (tabs.length > 0)
58 tab = {id: tabs[0].id, url: tabs[0].url}; 259 tab = {id: tabs[0].id, url: tabs[0].url};
59 260
60 let urlProtocol = tab && tab.url && new URL(tab.url).protocol; 261 let urlProtocol = tab && tab.url && new URL(tab.url).protocol;
61 262
62 // Mark page as 'local' to hide non-relevant elements 263 // Mark page as 'local' to hide non-relevant elements
63 if (urlProtocol != "http:" && urlProtocol != "https:") 264 if (urlProtocol != "http:" && urlProtocol != "https:")
265 {
266 document.body.classList.add("local");
267 document.body.classList.remove("nohtml");
268 }
269 else
270 {
271 whenPageReady().then(() =>
272 {
273 document.body.classList.remove("nohtml");
274 });
275 }
276
277 // Ask content script whether clickhide is active. If so, show
278 // cancel button. If that isn't the case, ask background.html
279 // whether it has cached filters. If so, ask the user whether she
280 // wants those filters. Otherwise, we are in default state.
281 if (tab)
282 {
283 isPageWhitelisted(whitelisted =>
284 {
285 if (whitelisted)
286 document.body.classList.add("disabled");
287 });
288
289 browser.tabs.sendMessage(tab.id, {
290 type: "composer.content.getState"
291 },
292 response =>
293 {
294 if (response && response.active)
295 document.body.classList.add("clickhide-active");
296 });
297 }
298
299 updateStats();
300 document.getElementById("stats-container").removeAttribute("hidden");
301 });
302
303 document.getElementById("enabled").addEventListener(
304 "click", toggleEnabled
305 );
306 document.getElementById("clickhide").addEventListener(
307 "click", activateClickHide
308 );
309 document.getElementById("clickhide-cancel").addEventListener(
310 "click", cancelClickHide
311 );
312 document.getElementById("options").addEventListener("click", () =>
313 {
314 browser.runtime.sendMessage({type: "app.open", what: "options"});
315 window.close();
316 });
317
318 // Set up collapsing of menu items
319 for (let collapser of document.getElementsByClassName("collapse"))
320 {
321 collapser.addEventListener("click", toggleCollapse);
322 getPref(collapser.dataset.option, value =>
323 {
324 if (value)
325 {
326 document.getElementById(
327 collapser.dataset.collapsible
328 ).classList.remove("collapsed");
329 }
330 });
331 }
332
333 document.getElementById("share-box").addEventListener("click", share);
334 let showIconNumber = document.getElementById("show-iconnumber");
335 getPref("show_statsinicon", showStatsInIcon =>
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 {
347 browser.runtime.sendMessage({
348 type: "notifications.get",
349 displayMethod: "popup"
350 }, notification =>
351 {
352 if (!notification)
353 return;
354
355 let titleElement = document.getElementById("notification-title");
356 let messageElement = document.getElementById("notification-message");
357
358 titleElement.textContent = notification.texts.title;
359
360 getDocLinks(notification).then(docLinks =>
361 {
362 insertMessage(messageElement, notification.texts.message, docLinks);
363
364 messageElement.addEventListener("click", event =>
365 {
366 let link = event.target;
367 while (link && link != messageElement && link.localName != "a")
368 link = link.parentNode;
369 if (!link)
370 return;
371 event.preventDefault();
372 event.stopPropagation();
373 browser.tabs.create({url: link.href});
374 });
375 });
376
377 let notificationElement = document.getElementById("notification");
378 notificationElement.className = notification.type;
379 notificationElement.hidden = false;
380 notificationElement.addEventListener("click", event =>
381 {
382 if (event.target.id == "notification-close")
383 notificationElement.classList.add("closing");
384 else if (event.target.id == "notification-optout" ||
385 event.target.id == "notification-hide")
386 {
387 if (event.target.id == "notification-optout")
388 setPref("notifications_ignoredcategories", true);
389
390 notificationElement.hidden = true;
391 notification.onClicked();
392 }
393 }, true);
394 });
395 });
LEFTRIGHT

Powered by Google App Engine
This is Rietveld