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

Side by Side Diff: background.js

Issue 6063199216467968: Issue 2642 - Moved notifications code to separate module (Closed)
Patch Set: Fixed typo in comment Created June 5, 2015, 2:06 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 | « no previous file | lib/notificationHelper.js » ('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-2015 Eyeo GmbH 3 * Copyright (C) 2006-2015 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
(...skipping 22 matching lines...) Expand all
33 this.isFrameWhitelisted = isFrameWhitelisted; 33 this.isFrameWhitelisted = isFrameWhitelisted;
34 this.processKey = processKey; 34 this.processKey = processKey;
35 this.getKey = getKey; 35 this.getKey = getKey;
36 } 36 }
37 with(require("url")) 37 with(require("url"))
38 { 38 {
39 this.stringifyURL = stringifyURL; 39 this.stringifyURL = stringifyURL;
40 this.isThirdParty = isThirdParty; 40 this.isThirdParty = isThirdParty;
41 this.extractHostFromFrame = extractHostFromFrame; 41 this.extractHostFromFrame = extractHostFromFrame;
42 } 42 }
43 with(require("icon"))
44 {
45 this.updateIcon = updateIcon;
46 this.startIconAnimation = startIconAnimation;
47 this.stopIconAnimation = stopIconAnimation;
48 }
49 var FilterStorage = require("filterStorage").FilterStorage; 43 var FilterStorage = require("filterStorage").FilterStorage;
50 var FilterNotifier = require("filterNotifier").FilterNotifier; 44 var FilterNotifier = require("filterNotifier").FilterNotifier;
51 var ElemHide = require("elemHide").ElemHide; 45 var ElemHide = require("elemHide").ElemHide;
52 var defaultMatcher = require("matcher").defaultMatcher; 46 var defaultMatcher = require("matcher").defaultMatcher;
53 var Prefs = require("prefs").Prefs; 47 var Prefs = require("prefs").Prefs;
54 var Synchronizer = require("synchronizer").Synchronizer; 48 var Synchronizer = require("synchronizer").Synchronizer;
55 var Utils = require("utils").Utils; 49 var Utils = require("utils").Utils;
56 var NotificationStorage = require("notification").Notification;
57 var initAntiAdblockNotification = require("antiadblockInit").initAntiAdblockNoti fication;
58 var parseFilters = require("filterValidation").parseFilters; 50 var parseFilters = require("filterValidation").parseFilters;
59 var composeFilters = require("filterComposer").composeFilters; 51 var composeFilters = require("filterComposer").composeFilters;
60 52 var updateIcon = require("icon").updateIcon;
61 // Chrome on Linux does not fully support chrome.notifications until version 35 53 var initNotifications = require("notificationHelper").initNotifications;
62 // https://code.google.com/p/chromium/issues/detail?id=291485
63 var canUseChromeNotifications = (function()
64 {
65 var info = require("info");
66 if (info.platform == "chromium" && "notifications" in chrome)
67 {
68 if (navigator.platform.indexOf("Linux") == -1)
69 return true;
70 if (Services.vc.compare(info.applicationVersion, "35") >= 0)
71 return true;
72 }
73 return false;
74 })();
75 54
76 var seenDataCorruption = false; 55 var seenDataCorruption = false;
77 var filterlistsReinitialized = false; 56 var filterlistsReinitialized = false;
78 57
79 function init() 58 function init()
80 { 59 {
81 var filtersLoaded = false; 60 var filtersLoaded = false;
82 var prefsLoaded = false; 61 var prefsLoaded = false;
83 62
84 var checkLoaded = function() 63 var checkLoaded = function()
(...skipping 16 matching lines...) Expand all
101 seenDataCorruption = previousVersion && FilterStorage.firstRun; 80 seenDataCorruption = previousVersion && FilterStorage.firstRun;
102 Prefs.currentVersion = info.addonVersion; 81 Prefs.currentVersion = info.addonVersion;
103 addSubscription(previousVersion); 82 addSubscription(previousVersion);
104 } 83 }
105 84
106 // The "Hide placeholders" option has been removed from the UI in 1.8.8.1285 85 // The "Hide placeholders" option has been removed from the UI in 1.8.8.1285
107 // So we reset the option for users updating from older versions. 86 // So we reset the option for users updating from older versions.
108 if (previousVersion && Services.vc.compare(previousVersion, "1.8.8.1285") < 0) 87 if (previousVersion && Services.vc.compare(previousVersion, "1.8.8.1285") < 0)
109 Prefs.hidePlaceholders = true; 88 Prefs.hidePlaceholders = true;
110 89
111 if (canUseChromeNotifications) 90 initNotifications();
112 initChromeNotifications();
113 initAntiAdblockNotification();
114 91
115 // Update browser actions and context menus when whitelisting might have 92 // Update browser actions and context menus when whitelisting might have
116 // changed. That is now when initally loading the filters and later when 93 // changed. That is now when initally loading the filters and later when
117 // importing backups or saving filter changes. 94 // importing backups or saving filter changes.
118 FilterNotifier.addListener(function(action) 95 FilterNotifier.addListener(function(action)
119 { 96 {
120 if (action == "load" || action == "save") 97 if (action == "load" || action == "save")
121 refreshIconAndContextMenuForAllPages(); 98 refreshIconAndContextMenuForAllPages();
122 }); 99 });
123 refreshIconAndContextMenuForAllPages(); 100 refreshIconAndContextMenuForAllPages();
(...skipping 19 matching lines...) Expand all
143 FilterNotifier.addListener(onFilterAction); 120 FilterNotifier.addListener(onFilterAction);
144 Prefs.onLoaded.addListener(onPrefsLoaded); 121 Prefs.onLoaded.addListener(onPrefsLoaded);
145 } 122 }
146 init(); 123 init();
147 124
148 // Special-case domains for which we cannot use style-based hiding rules. 125 // Special-case domains for which we cannot use style-based hiding rules.
149 // See http://crbug.com/68705. 126 // See http://crbug.com/68705.
150 var noStyleRulesHosts = ["mail.google.com", "mail.yahoo.com", "www.google.com"]; 127 var noStyleRulesHosts = ["mail.google.com", "mail.yahoo.com", "www.google.com"];
151 128
152 var htmlPages = new ext.PageMap(); 129 var htmlPages = new ext.PageMap();
153 var activeNotification = null;
154 130
155 var contextMenuItem = { 131 var contextMenuItem = {
156 title: ext.i18n.getMessage("block_element"), 132 title: ext.i18n.getMessage("block_element"),
157 contexts: ["image", "video", "audio"], 133 contexts: ["image", "video", "audio"],
158 onclick: function(page) 134 onclick: function(page)
159 { 135 {
160 page.sendMessage({type: "clickhide-new-filter"}); 136 page.sendMessage({type: "clickhide-new-filter"});
161 } 137 }
162 }; 138 };
163 139
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 else 259 else
284 notifyUser(); 260 notifyUser();
285 } 261 }
286 262
287 Prefs.onChanged.addListener(function(name) 263 Prefs.onChanged.addListener(function(name)
288 { 264 {
289 if (name == "shouldShowBlockElementMenu") 265 if (name == "shouldShowBlockElementMenu")
290 refreshIconAndContextMenuForAllPages(); 266 refreshIconAndContextMenuForAllPages();
291 }); 267 });
292 268
293 function prepareNotificationIconAndPopup()
294 {
295 var animateIcon = (activeNotification.type !== "question");
296 activeNotification.onClicked = function()
297 {
298 if (animateIcon)
299 stopIconAnimation();
300 notificationClosed();
301 };
302 if (animateIcon)
303 startIconAnimation(activeNotification.type);
304 }
305
306 function openNotificationLinks()
307 {
308 if (activeNotification.links)
309 {
310 activeNotification.links.forEach(function(link)
311 {
312 ext.windows.getLastFocused(function(win)
313 {
314 win.openTab(Utils.getDocLink(link));
315 });
316 });
317 }
318 }
319
320 function notificationButtonClick(buttonIndex)
321 {
322 if (activeNotification.type === "question")
323 {
324 NotificationStorage.triggerQuestionListeners(activeNotification.id, buttonIn dex === 0);
325 NotificationStorage.markAsShown(activeNotification.id);
326 activeNotification.onClicked();
327 }
328 else if (activeNotification.links && activeNotification.links[buttonIndex])
329 {
330 ext.windows.getLastFocused(function(win)
331 {
332 win.openTab(Utils.getDocLink(activeNotification.links[buttonIndex]));
333 });
334 }
335 }
336
337 function notificationClosed()
338 {
339 activeNotification = null;
340 }
341
342 function imgToBase64(url, callback)
343 {
344 var canvas = document.createElement("canvas"),
345 ctx = canvas.getContext("2d"),
346 img = new Image;
347 img.src = url;
348 img.onload = function()
349 {
350 canvas.height = img.height;
351 canvas.width = img.width;
352 ctx.drawImage(img, 0, 0);
353 callback(canvas.toDataURL("image/png"));
354 canvas = null;
355 };
356 }
357
358 function initChromeNotifications()
359 {
360 // Chrome hides notifications in notification center when clicked so we need t o clear them
361 function clearActiveNotification(notificationId)
362 {
363 if (activeNotification && activeNotification.type != "question" && !("links" in activeNotification))
364 return;
365
366 chrome.notifications.clear(notificationId, function(wasCleared)
367 {
368 if (wasCleared)
369 notificationClosed();
370 });
371 }
372
373 chrome.notifications.onButtonClicked.addListener(function(notificationId, butt onIndex)
374 {
375 notificationButtonClick(buttonIndex);
376 clearActiveNotification(notificationId);
377 });
378 chrome.notifications.onClicked.addListener(clearActiveNotification);
379 chrome.notifications.onClosed.addListener(notificationClosed);
380 }
381
382 function showNotification(notification)
383 {
384 if (activeNotification && activeNotification.id === notification.id)
385 return;
386
387 activeNotification = notification;
388 if (activeNotification.type === "critical" || activeNotification.type === "que stion")
389 {
390 var texts = NotificationStorage.getLocalizedTexts(notification);
391 var title = texts.title || "";
392 var message = texts.message ? texts.message.replace(/<\/?(a|strong)>/g, "") : "";
393 var iconUrl = ext.getURL("icons/detailed/abp-128.png");
394 var hasLinks = activeNotification.links && activeNotification.links.length > 0;
395
396 if (canUseChromeNotifications)
397 {
398 var opts = {
399 type: "basic",
400 title: title,
401 message: message,
402 buttons: [],
403 priority: 2 // We use the highest priority to prevent the notification f rom closing automatically
404 };
405 if (activeNotification.type === "question")
406 {
407 opts.buttons.push({title: ext.i18n.getMessage("overlay_notification_butt on_yes")});
408 opts.buttons.push({title: ext.i18n.getMessage("overlay_notification_butt on_no")});
409 }
410 else
411 {
412 var regex = /<a>(.*?)<\/a>/g;
413 var plainMessage = texts.message || "";
414 var match;
415 while (match = regex.exec(plainMessage))
416 opts.buttons.push({title: match[1]});
417 }
418
419 imgToBase64(iconUrl, function(iconData)
420 {
421 opts["iconUrl"] = iconData;
422 chrome.notifications.create("", opts, function() {});
423 });
424 }
425 else if ("Notification" in window && activeNotification.type !== "question")
426 {
427 if (hasLinks)
428 message += " " + ext.i18n.getMessage("notification_without_buttons");
429
430 imgToBase64(iconUrl, function(iconData)
431 {
432 var notification = new Notification(
433 title,
434 {
435 lang: Utils.appLocale,
436 dir: ext.i18n.getMessage("@@bidi_dir"),
437 body: message,
438 icon: iconData
439 }
440 );
441
442 notification.addEventListener("click", openNotificationLinks);
443 notification.addEventListener("close", notificationClosed);
444 });
445 }
446 else
447 {
448 var message = title + "\n" + message;
449 if (hasLinks)
450 message += "\n\n" + ext.i18n.getMessage("notification_with_buttons");
451
452 var approved = confirm(message);
453 if (activeNotification.type === "question")
454 notificationButtonClick(approved ? 0 : 1);
455 else if (approved)
456 openNotificationLinks();
457 }
458 }
459 prepareNotificationIconAndPopup();
460 }
461
462 // This is a hack to speedup loading of the options page on Safari. 269 // This is a hack to speedup loading of the options page on Safari.
463 // Once we replaced the background page proxy with message passing 270 // Once we replaced the background page proxy with message passing
464 // this global function should removed. 271 // this global function should removed.
465 function getUserFilters() 272 function getUserFilters()
466 { 273 {
467 var filters = []; 274 var filters = [];
468 var exceptions = []; 275 var exceptions = [];
469 276
470 for (var i = 0; i < FilterStorage.subscriptions.length; i++) 277 for (var i = 0; i < FilterStorage.subscriptions.length; i++)
471 { 278 {
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
610 break; 417 break;
611 } 418 }
612 }); 419 });
613 420
614 // update icon when page changes location 421 // update icon when page changes location
615 ext.pages.onLoading.addListener(function(page) 422 ext.pages.onLoading.addListener(function(page)
616 { 423 {
617 page.sendMessage({type: "clickhide-deactivate"}); 424 page.sendMessage({type: "clickhide-deactivate"});
618 refreshIconAndContextMenu(page); 425 refreshIconAndContextMenu(page);
619 }); 426 });
620
621 setTimeout(function()
622 {
623 var notificationToShow = NotificationStorage.getNextToShow();
624 if (notificationToShow)
625 showNotification(notificationToShow);
626 }, 3 * 60 * 1000);
OLDNEW
« no previous file with comments | « no previous file | lib/notificationHelper.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld