| LEFT | RIGHT | 
|    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 103 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  114 function refreshIconAndContextMenu(tab) |  114 function refreshIconAndContextMenu(tab) | 
|  115 { |  115 { | 
|  116   // The tab could have been closed by the time this function is called |  116   // The tab could have been closed by the time this function is called | 
|  117   if(!tab) |  117   if(!tab) | 
|  118     return; |  118     return; | 
|  119  |  119  | 
|  120   var excluded = isWhitelisted(tab.url); |  120   var excluded = isWhitelisted(tab.url); | 
|  121   var iconFilename = excluded ? "icons/abp-19-whitelisted.png" : "icons/abp-19.p
     ng"; |  121   var iconFilename = excluded ? "icons/abp-19-whitelisted.png" : "icons/abp-19.p
     ng"; | 
|  122  |  122  | 
|  123   if (activeNotification) |  123   if (activeNotification) | 
|  124     activeNotification.tabIcons[tab.id] = iconFilename; |  124     startIconAnimation(tab, iconFilename); | 
|  125   else |  125   else | 
|  126     chrome.pageAction.setIcon({tabId: tab.id, path: iconFilename}); |  126     chrome.pageAction.setIcon({tabId: tab.id, path: iconFilename}); | 
|  127  |  127  | 
|  128   // Only show icon for pages we can influence (http: and https:) |  128   // Only show icon for pages we can influence (http: and https:) | 
|  129   if(/^https?:/.test(tab.url)) |  129   if(/^https?:/.test(tab.url)) | 
|  130   { |  130   { | 
|  131     chrome.pageAction.setTitle({tabId: tab.id, title: "Adblock Plus"}); |  131     chrome.pageAction.setTitle({tabId: tab.id, title: "Adblock Plus"}); | 
|  132     if ("shouldShowIcon" in localStorage && localStorage["shouldShowIcon"] == "f
     alse") |  132     if ("shouldShowIcon" in localStorage && localStorage["shouldShowIcon"] == "f
     alse") | 
|  133       chrome.pageAction.hide(tab.id); |  133       chrome.pageAction.hide(tab.id); | 
|  134     else |  134     else | 
| (...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  474             onLoad(); |  474             onLoad(); | 
|  475           } |  475           } | 
|  476         }; |  476         }; | 
|  477         chrome.tabs.onUpdated.addListener(listener); |  477         chrome.tabs.onUpdated.addListener(listener); | 
|  478       } |  478       } | 
|  479     }); |  479     }); | 
|  480   } |  480   } | 
|  481 } |  481 } | 
|  482  |  482  | 
|  483 var iconAnimationTimer = null; |  483 var iconAnimationTimer = null; | 
|  484 var iconAnimationRestartTimer = null; |  484 var animatedIconTab = null; | 
|  485  |  485  | 
|  486 function stopIconAnimation() |  486 function stopIconAnimation() | 
|  487 { |  487 { | 
|  488   if (iconAnimationRestartTimer) |  | 
|  489   { |  | 
|  490     clearTimeout(iconAnimationRestartTimer) |  | 
|  491     iconAnimationRestartTimer = null; |  | 
|  492   } |  | 
|  493  |  | 
|  494   if (!iconAnimationTimer) |  488   if (!iconAnimationTimer) | 
|  495     return; |  489     return; | 
|  496  |  490  | 
|  497   clearTimeout(iconAnimationTimer); |  491   clearTimeout(iconAnimationTimer); | 
|  498   iconAnimationTimer = null; |  492   iconAnimationTimer = null; | 
|  499   chrome.tabs.getAllInWindow(null, function(tabs) |  493   animatedIconTab = null; | 
|  500   { |  | 
|  501     tabs.forEach(refreshIconAndContextMenu); |  | 
|  502   }); |  | 
|  503 } |  494 } | 
|  504  |  495  | 
|  505 function loadImages(imageFiles, callback) |  496 function loadImages(imageFiles, callback) | 
|  506 { |  497 { | 
|  507   var images = {}; |  498   var images = {}; | 
|  508   var imagesLoaded = 0; |  499   var imagesLoaded = 0; | 
|  509   imageFiles.forEach(function(imageFile) |  500   imageFiles.forEach(function(imageFile) | 
|  510   { |  501   { | 
|  511     var image = new Image(); |  502     var image = new Image(); | 
|  512     image.src = imageFile; |  503     image.src = imageFile; | 
|  513     image.addEventListener("load", function() |  504     image.addEventListener("load", function() | 
|  514     { |  505     { | 
|  515       images[imageFile] = image; |  506       images[imageFile] = image; | 
|  516       if (++imagesLoaded === imageFiles.length) |  507       if (++imagesLoaded === imageFiles.length) | 
|  517         callback(images); |  508         callback(images); | 
|  518     }); |  509     }); | 
|  519   }); |  510   }); | 
|  520 } |  511 } | 
|  521  |  512  | 
|  522 function startIconAnimation() |  513 function startIconAnimation(tab, iconPath) | 
|  523 { |  514 { | 
|  524   stopIconAnimation(); |  515   stopIconAnimation(); | 
|  525  |  516   animatedIconTab = tab; | 
|  526   var normalIconFile = "icons/abp-19.png"; |  517  | 
|  527   var whitelistedIconFile = "icons/abp-19-whitelisted.png"; |  | 
|  528   var severitySuffix = activeNotification.severity === "critical" |  518   var severitySuffix = activeNotification.severity === "critical" | 
|  529       ? "critical" : "information"; |  519       ? "critical" : "information"; | 
|  530   var notificationIconFile = "icons/notification-" + severitySuffix + ".png"; |  520   var notificationIconPath = "icons/notification-" + severitySuffix + ".png"; | 
|  531   var iconFiles = [normalIconFile, whitelistedIconFile ,notificationIconFile]; |  521   var iconFiles = [iconPath, notificationIconPath]; | 
|  532   loadImages(iconFiles, function(images) |  522   loadImages(iconFiles, function(images) | 
|  533   { |  523   { | 
|  534     var normalIcon = images[normalIconFile]; |  524     var icon = images[iconPath]; | 
|  535     var notificationIcon = images[notificationIconFile]; |  525     var notificationIcon = images[notificationIconPath]; | 
 |  526  | 
|  536     var canvas = document.createElement("canvas"); |  527     var canvas = document.createElement("canvas"); | 
|  537     canvas.width = normalIcon.width; |  528     canvas.width = icon.width; | 
|  538     canvas.height = normalIcon.height; |  529     canvas.height = icon.height; | 
|  539     var context = canvas.getContext("2d"); |  530     var context = canvas.getContext("2d"); | 
|  540  |  531  | 
|  541     var animationStartTime = Date.now(); |  532     var currentFrame = 0; | 
|  542     var animationInterval = 1000 / 5; |  533     var frameOpacities = [0, 0.2, 0.4, 0.6, 0.8, | 
 |  534                           1, 1, 1, 1, 1, | 
 |  535                           0.8, 0.6, 0.4, 0.2, 0]; | 
 |  536  | 
|  543     function animationStep() |  537     function animationStep() | 
|  544     { |  538     { | 
|  545       var timeElapsed = Date.now() - animationStartTime; |  539       var opacity = frameOpacities[currentFrame]; | 
|  546       var duration = 3000; |  540       context.clearRect(0, 0, canvas.width, canvas.height); | 
|  547       if (timeElapsed > duration) |  541       context.globalAlpha = 1; | 
|  548       { |  542       context.drawImage(icon, 0, 0); | 
|  549         stopIconAnimation(); |  543       context.globalAlpha = opacity; | 
|  550         iconAnimationRestartTimer = setTimeout(startIconAnimation, 5000); |  544       context.drawImage(notificationIcon, 0, 0); | 
|  551         return; |  545       var imageData = context.getImageData(0, 0, canvas.width, canvas.height); | 
|  552       } |  546       chrome.pageAction.setIcon({tabId: tab.id, imageData: imageData}); | 
|  553  |  547  | 
|  554       chrome.tabs.getSelected(null, function(tab) |  548       var interval; | 
|  555       { |  549       currentFrame++; | 
|  556         var icon = images[activeNotification.tabIcons[tab.id]]; |  550       if (currentFrame < frameOpacities.length) | 
|  557         var animationTime = timeElapsed % duration; |  551       { | 
|  558         var showDelay = 1000; |  552         var duration = 3000; | 
|  559         var fadeInEndTime = duration / 2 - showDelay / 2; |  553         interval = duration / frameOpacities.length; | 
|  560         var fadeOutStartTime = fadeInEndTime + showDelay; |  554       } | 
|  561  |  555       else | 
|  562         var opacity; |  556       { | 
|  563         if (animationTime < fadeInEndTime) |  557         currentFrame = 0; | 
|  564           opacity = animationTime / fadeInEndTime; |  558         interval = 10000; | 
|  565         else if (animationTime > fadeOutStartTime) |  559       } | 
|  566           opacity = 1 - (animationTime - fadeOutStartTime) |  560       iconAnimationTimer = setTimeout(animationStep, interval); | 
|  567             / (duration - fadeOutStartTime); |  | 
|  568  |  | 
|  569         context.clearRect(0, 0, canvas.width, canvas.height); |  | 
|  570         context.globalAlpha = 1; |  | 
|  571         context.drawImage(icon, 0, 0); |  | 
|  572         context.globalAlpha = opacity; |  | 
|  573         context.drawImage(notificationIcon, 0, 0); |  | 
|  574         var imageData = context.getImageData(0, 0, canvas.width, canvas.height); |  | 
|  575  |  | 
|  576         chrome.pageAction.setIcon({tabId: tab.id, imageData: imageData}); |  | 
|  577         iconAnimationTimer = setTimeout(animationStep, animationInterval); |  | 
|  578       }); |  | 
|  579     } |  561     } | 
|  580     animationStep(); |  562     animationStep(); | 
|  581   }); |  563   }); | 
|  582 } |  564 } | 
|  583  |  565  | 
|  584 function prepareNotificationIconAndPopup() |  566 function prepareNotificationIconAndPopup() | 
|  585 { |  567 { | 
|  586   activeNotification.tabIcons = {}; |  | 
|  587   activeNotification.onClicked = function() |  568   activeNotification.onClicked = function() | 
|  588   { |  569   { | 
 |  570     var tab = animatedIconTab; | 
|  589     stopIconAnimation(); |  571     stopIconAnimation(); | 
|  590     activeNotification = null; |  572     activeNotification = null; | 
 |  573     refreshIconAndContextMenu(tab); | 
|  591   }; |  574   }; | 
|  592   startIconAnimation(); |  575  | 
|  593  |  576   chrome.windows.getLastFocused({populate: true}, function(window) | 
|  594   chrome.tabs.getAllInWindow(null, function(tabs) |  577   { | 
|  595   { |  578     chrome.tabs.query({active: true, windowId: window.id}, function(tabs) | 
|  596     tabs.forEach(refreshIconAndContextMenu); |  579     { | 
 |  580       tabs.forEach(refreshIconAndContextMenu); | 
 |  581     }); | 
|  597   }); |  582   }); | 
|  598 } |  583 } | 
|  599  |  584  | 
|  600 function showNotification(notification) |  585 function showNotification(notification) | 
|  601 { |  586 { | 
|  602   activeNotification = notification; |  587   activeNotification = notification; | 
|  603  |  588  | 
|  604   if (activeNotification.severity === "critical") |  589   if (activeNotification.severity === "critical") | 
|  605   { |  590   { | 
|  606     var notification = webkitNotifications.createHTMLNotification("notification.
     html"); |  591     var notification = webkitNotifications.createHTMLNotification("notification.
     html"); | 
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  741 }); |  726 }); | 
|  742  |  727  | 
|  743 // Update icon if a tab changes location |  728 // Update icon if a tab changes location | 
|  744 chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) |  729 chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) | 
|  745 { |  730 { | 
|  746   chrome.tabs.sendRequest(tabId, {reqtype: "clickhide-deactivate"}) |  731   chrome.tabs.sendRequest(tabId, {reqtype: "clickhide-deactivate"}) | 
|  747   if(changeInfo.status == "loading") |  732   if(changeInfo.status == "loading") | 
|  748     refreshIconAndContextMenu(tab); |  733     refreshIconAndContextMenu(tab); | 
|  749 }); |  734 }); | 
|  750  |  735  | 
 |  736 // Refresh icon when switching tabs or windows | 
 |  737 chrome.tabs.onActivated.addListener(function(activeInfo) | 
 |  738 { | 
 |  739   refreshIconAndContextMenu(animatedIconTab); | 
 |  740   chrome.tabs.get(activeInfo.tabId, refreshIconAndContextMenu); | 
 |  741 }); | 
 |  742 chrome.windows.onFocusChanged.addListener(function(windowId) | 
 |  743 { | 
 |  744   refreshIconAndContextMenu(animatedIconTab); | 
 |  745   chrome.tabs.query({active: true, windowId: windowId}, function(tabs) | 
 |  746   { | 
 |  747     tabs.forEach(refreshIconAndContextMenu); | 
 |  748   }); | 
 |  749 }); | 
 |  750  | 
|  751 setTimeout(function() |  751 setTimeout(function() | 
|  752 { |  752 { | 
|  753   var notificationToShow = Notification.getNextToShow(); |  753   var notificationToShow = Notification.getNextToShow(); | 
|  754   if (notificationToShow) |  754   if (notificationToShow) | 
|  755     showNotification(notificationToShow); |  755     showNotification(notificationToShow); | 
|  756 }, 3 * 60 * 1000); |  756 }, 3 * 60 * 1000); | 
| LEFT | RIGHT |