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

Unified Diff: background.js

Issue 11161031: Show notifications on startup (Chrome) (Closed)
Patch Set: Use just one click handler for all links Created July 22, 2013, 9:34 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « .hgsubstate ('k') | icons/notification-critical.png » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: background.js
===================================================================
--- a/background.js
+++ b/background.js
@@ -33,6 +33,7 @@
var Prefs = require("prefs").Prefs;
var Synchronizer = require("synchronizer").Synchronizer;
var Utils = require("utils").Utils;
+var Notification = require("notification").Notification;
// Some types cannot be distinguished
RegExpFilter.typeMap.OBJECT_SUBREQUEST = RegExpFilter.typeMap.OBJECT;
@@ -107,6 +108,8 @@
return (result instanceof WhitelistFilter ? result : null);
}
+var activeNotification = null;
+
// Adds or removes page action icon according to options.
function refreshIconAndContextMenu(tab)
{
@@ -116,7 +119,11 @@
var excluded = isWhitelisted(tab.url);
var iconFilename = excluded ? "icons/abp-19-whitelisted.png" : "icons/abp-19.png";
- chrome.pageAction.setIcon({tabId: tab.id, path: iconFilename});
+
+ if (activeNotification)
+ activeNotification.tabIcons[tab.id] = iconFilename;
Wladimir Palant 2013/07/23 07:25:04 This will leak memory if many tabs are opened and
Felix Dahlke 2013/07/23 10:38:08 Done.
+ else
+ chrome.pageAction.setIcon({tabId: tab.id, path: iconFilename});
// Only show icon for pages we can influence (http: and https:)
if(/^https?:/.test(tab.url))
@@ -473,6 +480,137 @@
}
}
+var iconAnimationTimer = null;
+var iconAnimationRestartTimer = null;
Wladimir Palant 2013/07/23 07:25:04 A single timer should definitely be sufficient.
Felix Dahlke 2013/07/23 10:38:08 Done.
+
+function stopIconAnimation()
+{
+ if (iconAnimationRestartTimer)
+ {
+ clearTimeout(iconAnimationRestartTimer)
+ iconAnimationRestartTimer = null;
+ }
+
+ if (!iconAnimationTimer)
+ return;
+
+ clearTimeout(iconAnimationTimer);
+ iconAnimationTimer = null;
+ chrome.tabs.getAllInWindow(null, function(tabs)
+ {
+ tabs.forEach(refreshIconAndContextMenu);
+ });
+}
+
+function loadImages(imageFiles, callback)
+{
+ var images = {};
+ var imagesLoaded = 0;
+ imageFiles.forEach(function(imageFile)
+ {
+ var image = new Image();
+ image.src = imageFile;
+ image.addEventListener("load", function()
+ {
+ images[imageFile] = image;
+ if (++imagesLoaded === imageFiles.length)
+ callback(images);
+ });
+ });
+}
+
+function startIconAnimation()
+{
+ stopIconAnimation();
+
+ var normalIconFile = "icons/abp-19.png";
+ var whitelistedIconFile = "icons/abp-19-whitelisted.png";
+ var severitySuffix = activeNotification.severity === "critical"
+ ? "critical" : "information";
+ var notificationIconFile = "icons/notification-" + severitySuffix + ".png";
+ var iconFiles = [normalIconFile, whitelistedIconFile ,notificationIconFile];
+ loadImages(iconFiles, function(images)
+ {
+ var normalIcon = images[normalIconFile];
+ var notificationIcon = images[notificationIconFile];
+ var canvas = document.createElement("canvas");
+ canvas.width = normalIcon.width;
+ canvas.height = normalIcon.height;
+ var context = canvas.getContext("2d");
+
+ var animationStartTime = Date.now();
+ var animationInterval = 1000 / 5;
+ function animationStep()
+ {
+ var timeElapsed = Date.now() - animationStartTime;
+ var duration = 3000;
+ if (timeElapsed > duration)
+ {
+ stopIconAnimation();
+ iconAnimationRestartTimer = setTimeout(startIconAnimation, 5000);
+ return;
+ }
+
+ chrome.tabs.getSelected(null, function(tab)
+ {
+ var icon = images[activeNotification.tabIcons[tab.id]];
+ var animationTime = timeElapsed % duration;
+ var showDelay = 1000;
+ var fadeInEndTime = duration / 2 - showDelay / 2;
+ var fadeOutStartTime = fadeInEndTime + showDelay;
+
+ var opacity;
+ if (animationTime < fadeInEndTime)
+ opacity = animationTime / fadeInEndTime;
+ else if (animationTime > fadeOutStartTime)
+ opacity = 1 - (animationTime - fadeOutStartTime)
+ / (duration - fadeOutStartTime);
+
+ context.clearRect(0, 0, canvas.width, canvas.height);
+ context.globalAlpha = 1;
+ context.drawImage(icon, 0, 0);
+ context.globalAlpha = opacity;
+ context.drawImage(notificationIcon, 0, 0);
+ var imageData = context.getImageData(0, 0, canvas.width, canvas.height);
+
+ chrome.pageAction.setIcon({tabId: tab.id, imageData: imageData});
+ iconAnimationTimer = setTimeout(animationStep, animationInterval);
+ });
+ }
+ animationStep();
+ });
+}
+
+function prepareNotificationIconAndPopup()
+{
+ activeNotification.tabIcons = {};
+ activeNotification.onClicked = function()
+ {
+ stopIconAnimation();
+ activeNotification = null;
+ };
+ startIconAnimation();
+
+ chrome.tabs.getAllInWindow(null, function(tabs)
+ {
+ tabs.forEach(refreshIconAndContextMenu);
+ });
+}
+
+function showNotification(notification)
+{
+ activeNotification = notification;
+
+ if (activeNotification.severity === "critical")
+ {
+ var notification = webkitNotifications.createHTMLNotification("notification.html");
+ notification.show();
+ notification.addEventListener("close", prepareNotificationIconAndPopup);
+ }
+ else
+ prepareNotificationIconAndPopup();
+}
+
/**
* This function is a hack - we only know the tabId and document URL for a
* message but we need to know the frame ID. Try to find it in webRequest's
@@ -609,3 +747,10 @@
if(changeInfo.status == "loading")
refreshIconAndContextMenu(tab);
});
+
+setTimeout(function()
+{
+ var notificationToShow = Notification.getNextToShow();
+ if (notificationToShow)
+ showNotification(notificationToShow);
+}, 3 * 60 * 1000);
« no previous file with comments | « .hgsubstate ('k') | icons/notification-critical.png » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld