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

Side by Side Diff: background.js

Issue 11161031: Show notifications on startup (Chrome) (Closed)
Patch Set: Address issue from the Firefox review Created July 20, 2013, 10:51 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 | icons/notification-critical.png » ('j') | lib/prefs.js » ('J')
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 <http://adblockplus.org/>, 2 * This file is part of Adblock Plus <http://adblockplus.org/>,
3 * Copyright (C) 2006-2013 Eyeo GmbH 3 * Copyright (C) 2006-2013 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 15 matching lines...) Expand all
26 { 26 {
27 this.Subscription = Subscription; 27 this.Subscription = Subscription;
28 this.DownloadableSubscription = DownloadableSubscription; 28 this.DownloadableSubscription = DownloadableSubscription;
29 } 29 }
30 var FilterStorage = require("filterStorage").FilterStorage; 30 var FilterStorage = require("filterStorage").FilterStorage;
31 var ElemHide = require("elemHide").ElemHide; 31 var ElemHide = require("elemHide").ElemHide;
32 var defaultMatcher = require("matcher").defaultMatcher; 32 var defaultMatcher = require("matcher").defaultMatcher;
33 var Prefs = require("prefs").Prefs; 33 var Prefs = require("prefs").Prefs;
34 var Synchronizer = require("synchronizer").Synchronizer; 34 var Synchronizer = require("synchronizer").Synchronizer;
35 var Utils = require("utils").Utils; 35 var Utils = require("utils").Utils;
36 var Notification = require("notification").Notification;
36 37
37 // Some types cannot be distinguished 38 // Some types cannot be distinguished
38 RegExpFilter.typeMap.OBJECT_SUBREQUEST = RegExpFilter.typeMap.OBJECT; 39 RegExpFilter.typeMap.OBJECT_SUBREQUEST = RegExpFilter.typeMap.OBJECT;
39 RegExpFilter.typeMap.MEDIA = RegExpFilter.typeMap.FONT = RegExpFilter.typeMap.OT HER; 40 RegExpFilter.typeMap.MEDIA = RegExpFilter.typeMap.FONT = RegExpFilter.typeMap.OT HER;
40 41
41 var isFirstRun = false; 42 var isFirstRun = false;
42 var seenDataCorruption = false; 43 var seenDataCorruption = false;
43 require("filterNotifier").FilterNotifier.addListener(function(action) 44 require("filterNotifier").FilterNotifier.addListener(function(action)
44 { 45 {
45 if (action == "load") 46 if (action == "load")
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 chrome.pageAction.hide(tab.id); 127 chrome.pageAction.hide(tab.id);
127 else 128 else
128 chrome.pageAction.show(tab.id); 129 chrome.pageAction.show(tab.id);
129 130
130 // Set context menu status according to whether current tab has whitelisted domain 131 // Set context menu status according to whether current tab has whitelisted domain
131 if (excluded) 132 if (excluded)
132 chrome.contextMenus.removeAll(); 133 chrome.contextMenus.removeAll();
133 else 134 else
134 showContextMenu(); 135 showContextMenu();
135 } 136 }
137
138 if (activeNotification)
139 setNotificationPageAction(tab);
Wladimir Palant 2013/07/21 11:15:30 This logic seems wrong to me - you are overriding
Felix Dahlke 2013/07/22 12:30:15 Done.
136 } 140 }
137 141
138 /** 142 /**
139 * Old versions stored filter data in the localStorage object, this will import 143 * Old versions stored filter data in the localStorage object, this will import
140 * it into FilterStorage properly. 144 * it into FilterStorage properly.
141 */ 145 */
142 function importOldData() 146 function importOldData()
143 { 147 {
144 function addSubscription(url, title) 148 function addSubscription(url, title)
145 { 149 {
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
466 chrome.tabs.onUpdated.removeListener(listener); 470 chrome.tabs.onUpdated.removeListener(listener);
467 onLoad(); 471 onLoad();
468 } 472 }
469 }; 473 };
470 chrome.tabs.onUpdated.addListener(listener); 474 chrome.tabs.onUpdated.addListener(listener);
471 } 475 }
472 }); 476 });
473 } 477 }
474 } 478 }
475 479
480 var activeNotification;
Wladimir Palant 2013/07/21 11:15:30 Initialize with null so you don't work with undefi
Felix Dahlke 2013/07/22 12:30:15 Done, didn't notice that we always tend to do that
481
482 function loadImages(imageFiles, callback)
483 {
484 var images = {};
485 imageFiles.forEach(function(imageFile)
486 {
487 var image = new Image();
488 image.src = imageFile;
489 image.addEventListener("load", function()
490 {
491 images[imageFile] = image;
492 if (Object.keys(images).length === imageFiles.length)
Wladimir Palant 2013/07/21 11:15:30 I really don't like relying on Object.keys() only
Felix Dahlke 2013/07/22 12:30:15 I had a hunch you'd say this :) Done.
493 callback(images);
494 });
495 });
496 }
497
498 function startInformationNotificationAnimation()
499 {
500 var abpIconFile = "icons/abp-19.png";
Wladimir Palant 2013/07/21 11:15:30 What about "icons/abp-19-whitelisted.png"?
501 var notificationIconFile = "icons/notification-information.png";
502 var iconFiles = [abpIconFile, notificationIconFile];
503 loadImages(iconFiles, function(images)
504 {
505 var abpIcon = images[abpIconFile];
506 var notificationIcon = images[notificationIconFile];
507 var canvas = document.createElement("canvas");
508 canvas.width = abpIcon.width;
509 canvas.height = abpIcon.height;
510 var context = canvas.getContext("2d");
511
512 var animationStartTime = Date.now();
513 var animationInterval = 1000 / 60;
514 function animationStep()
515 {
516 var timeElapsed = Date.now() - animationStartTime;
517 var duration = 3000;
518 var animationTime = timeElapsed % duration;
519 var delay = 1000;
520 var fadeInEndTime = duration / 2 - delay / 2;
521 var fadeOutStartTime = fadeInEndTime + delay;
522
523 var opacity;
524 if (animationTime < fadeInEndTime)
525 opacity = animationTime / fadeInEndTime;
526 else if (animationTime > fadeOutStartTime)
527 opacity = 1 - (animationTime - fadeOutStartTime)
528 / (duration - fadeOutStartTime);
529
530 context.clearRect(0, 0, canvas.width, canvas.height);
531 context.globalAlpha = 1;
532 context.drawImage(abpIcon, 0, 0);
533 context.globalAlpha = opacity;
534 context.drawImage(notificationIcon, 0, 0);
535 var imageData = context.getImageData(0, 0, canvas.width, canvas.height);
536
537 chrome.tabs.getSelected(null, function(tab)
538 {
539 chrome.pageAction.setIcon({tabId: tab.id, imageData: imageData});
540 activeNotification.animationTimer =
541 setTimeout(animationStep, animationInterval);
542 });
Wladimir Palant 2013/07/21 11:15:30 Frankly, drawing images 60 times per second is a h
Felix Dahlke 2013/07/21 12:19:53 Well, drawing images 60 times per second is how an
543 }
544 animationStep();
545 });
546 }
547
548 function showInformationNotification()
549 {
550 activeNotification.onClicked = function()
551 {
552 clearTimeout(activeNotification.animationTimer);
553 chrome.tabs.getAllInWindow(null, function(tabs)
554 {
555 tabs.forEach(refreshIconAndContextMenu);
556 activeNotification = null;
557 });
558 };
559
560 startInformationNotificationAnimation();
561 }
562
563 function showCriticalNotification()
564 {
565 var notification = webkitNotifications.createHTMLNotification("notification.ht ml");
566 notification.show();
567 }
568
569 function setNotificationPageAction(tab)
570 {
571 if (activeNotification.severity !== "critical")
572 return;
573
574 var abpIconFile = "icons/abp-19.png";
575 var notificationIconFile = "icons/notification-critical.png";
Wladimir Palant 2013/07/21 11:15:30 Again, what about abp-19-whitelisted.png? Same co
576 var iconFiles = [abpIconFile, notificationIconFile];
577 loadImages(iconFiles, function(images)
578 {
579 var abpIcon = images[abpIconFile];
580 var notificationIcon = images[notificationIconFile];
581 var canvas = document.createElement("canvas");
582 canvas.width = abpIcon.width;
583 canvas.height = abpIcon.height;
584 var context = canvas.getContext("2d");
585 context.clearRect(0, 0, canvas.width, canvas.height);
586 context.drawImage(abpIcon, 0, 0);
587 context.drawImage(notificationIcon, 0, 0);
588 var imageData = context.getImageData(0, 0, canvas.width, canvas.height);
589 chrome.pageAction.setIcon({tabId: tab.id, imageData: imageData});
590 });
591 }
592
593 function showNotification(notification)
594 {
595 activeNotification = notification;
596
597 if (notification.severity === "critical")
598 showCriticalNotification();
599 else
600 showInformationNotification();
601
602 chrome.tabs.getAllInWindow(null, function(tabs)
603 {
604 tabs.forEach(setNotificationPageAction);
605 });
606 }
607
608 function getLocalizedTexts(notification)
609 {
610 return Notification.getLocalizedTexts(notification);
611 }
612
613 function getDocLinks(notification)
614 {
615 if (!notification.links)
616 return [];
617
618 var docLinks = [];
619 notification.links.forEach(function(link)
620 {
621 docLinks.push(Utils.getDocLink(link));
622 });
623 return docLinks;
624 }
625
476 /** 626 /**
477 * This function is a hack - we only know the tabId and document URL for a 627 * This function is a hack - we only know the tabId and document URL for a
478 * message but we need to know the frame ID. Try to find it in webRequest's 628 * message but we need to know the frame ID. Try to find it in webRequest's
479 * frame data. 629 * frame data.
480 */ 630 */
481 function getFrameId(tabId, url) 631 function getFrameId(tabId, url)
482 { 632 {
483 if (tabId in frames) 633 if (tabId in frames)
484 { 634 {
485 for (var f in frames[tabId]) 635 for (var f in frames[tabId])
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 refreshIconAndContextMenu(windows[i].tabs[j]); 752 refreshIconAndContextMenu(windows[i].tabs[j]);
603 }); 753 });
604 754
605 // Update icon if a tab changes location 755 // Update icon if a tab changes location
606 chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) 756 chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab)
607 { 757 {
608 chrome.tabs.sendRequest(tabId, {reqtype: "clickhide-deactivate"}) 758 chrome.tabs.sendRequest(tabId, {reqtype: "clickhide-deactivate"})
609 if(changeInfo.status == "loading") 759 if(changeInfo.status == "loading")
610 refreshIconAndContextMenu(tab); 760 refreshIconAndContextMenu(tab);
611 }); 761 });
762
763 setTimeout(function()
764 {
765 var notificationToShow = Notification.getNextToShow();
766 if (notificationToShow)
767 showNotification(notificationToShow);
768 }, 3 * 60 * 1000);
OLDNEW
« no previous file with comments | « no previous file | icons/notification-critical.png » ('j') | lib/prefs.js » ('J')

Powered by Google App Engine
This is Rietveld