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

Side by Side Diff: lib/icon.js

Issue 29334778: Issue 3532 - Improved preformance of icon animation and fixed a memory leak (Closed)
Patch Set: Moved and renamed functions Created Jan. 28, 2016, 10:13 a.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 | no next file » | 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-2016 Eyeo GmbH 3 * Copyright (C) 2006-2016 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
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 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/>. 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 17
18 /** @module icon */ 18 /** @module icon */
19 19
20 "use strict"; 20 "use strict";
21 21
22 const frameOpacities = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 22 const frameOpacities = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9,
23 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 23 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
24 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, 0.0]; 24 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, 0.0];
25 const numberOfFrames = frameOpacities.length; 25 const numberOfFrames = frameOpacities.length;
26 const safariPlatform = require("info").platform == "safari"; 26 const safariPlatform = require("info").platform == "safari";
27 27
28 let frameInterval = null; 28 let frameInterval = null;
29 let animationInterval = null; 29 let animationInterval = null;
30 let onActivated = null;
30 let whitelistedState = new ext.PageMap(); 31 let whitelistedState = new ext.PageMap();
31 32
32 function loadImage(url) 33 function loadImage(url)
33 { 34 {
34 return new Promise((resolve, reject) => 35 return new Promise((resolve, reject) =>
35 { 36 {
36 let image = new Image(); 37 let image = new Image();
37 image.src = url; 38 image.src = url;
38 image.addEventListener("load", () => 39 image.addEventListener("load", () =>
39 { 40 {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 imageData[size] = context.getImageData(0, 0, size, size); 109 imageData[size] = context.getImageData(0, 0, size, size);
109 } 110 }
110 frames["" + opacity + whitelisted] = imageData; 111 frames["" + opacity + whitelisted] = imageData;
111 } 112 }
112 } 113 }
113 114
114 return frames; 115 return frames;
115 }); 116 });
116 } 117 }
117 118
118 function runAnimation(notificationType) 119 function animateIcon(notificationType, frames)
119 { 120 {
120 function playAnimation(frames) 121 ext.pages.query({active: true}, pages =>
121 { 122 {
122 let animationStep = 0; 123 let animationStep = 0;
123 ext.pages.query({active: true}, pages => 124 let opacity = 0;
125
126 onActivated = page =>
124 { 127 {
125 function appendActivePage(page) 128 pages.push(page);
129 setIcon(page, notificationType, opacity, frames);
130 };
131 ext.pages.onActivated.addListener(onActivated);
132
133 frameInterval = setInterval(() =>
134 {
135 let oldOpacity = opacity;
136 opacity = frameOpacities[animationStep++];
137
138 if (opacity != oldOpacity)
126 { 139 {
127 pages.push(page);
128 }
129 ext.pages.onActivated.addListener(appendActivePage);
130
131 frameInterval = setInterval(() =>
132 {
133 let opacity = frameOpacities[animationStep++];
134 for (let page of pages) 140 for (let page of pages)
135 { 141 {
136 if (whitelistedState.has(page)) 142 if (whitelistedState.has(page))
137 setIcon(page, notificationType, opacity, frames); 143 setIcon(page, notificationType, opacity, frames);
138 }; 144 }
145 }
139 146
140 if (animationStep > numberOfFrames) 147 if (animationStep > numberOfFrames)
141 { 148 {
142 animationStep = 0; 149 clearInterval(frameInterval);
143 clearInterval(frameInterval); 150 ext.pages.onActivated.removeListener(onActivated);
144 frameInterval = null; 151 frameInterval = onActivated = null;
145 ext.pages.onActivated.removeListener(appendActivePage); 152 }
146 } 153 }, 100);
147 }, 100);
148 });
149 }
150
151 renderFrames(notificationType).then(frames =>
152 {
153 playAnimation(frames);
154 animationInterval = setInterval(() => { playAnimation(frames); }, 10000);
155 }); 154 });
156 } 155 }
157 156
157 function runAnimationLoop(notificationType)
158 {
159 renderFrames(notificationType).then(frames =>
160 {
161 animateIcon(notificationType, frames);
162 animationInterval = setInterval(() =>
163 {
164 animateIcon(notificationType, frames);
165 }, 10000);
166 });
167 }
168
158 /** 169 /**
159 * Set the browser action icon for the given page, indicating whether 170 * Set the browser action icon for the given page, indicating whether
160 * adblocking is active there, and considering the icon animation. 171 * adblocking is active there, and considering the icon animation.
161 * 172 *
162 * @param {Page} page The page to set the browser action icon for 173 * @param {Page} page The page to set the browser action icon for
163 * @param {Boolean} whitelisted Whether the page has been whitelisted 174 * @param {Boolean} whitelisted Whether the page has been whitelisted
164 */ 175 */
165 exports.updateIcon = function(page, whitelisted) 176 exports.updateIcon = function(page, whitelisted)
166 { 177 {
167 whitelistedState.set(page, whitelisted); 178 whitelistedState.set(page, whitelisted);
168 if (frameInterval == null) 179 if (frameInterval == null)
169 setIcon(page); 180 setIcon(page);
170 }; 181 };
171 182
172 let stopIconAnimation = 183 let stopIconAnimation =
173 /** 184 /**
174 * Stops to animate the browser action icon. 185 * Stops to animate the browser action icon.
175 */ 186 */
176 exports.stopIconAnimation = function() 187 exports.stopIconAnimation = function()
177 { 188 {
178 if (frameInterval != null) 189 if (frameInterval != null)
179 clearInterval(frameInterval); 190 clearInterval(frameInterval);
180 if (animationInterval != null) 191 if (animationInterval != null)
181 clearInterval(animationInterval); 192 clearInterval(animationInterval);
182 frameInterval = animationInterval = null; 193 if (onActivated)
194 ext.pages.onActivated.removeListener(onActivated);
195 frameInterval = animationInterval = onActivated = null;
183 }; 196 };
184 197
185 /** 198 /**
186 * Starts to animate the browser action icon to indicate a pending notifcation. 199 * Starts to animate the browser action icon to indicate a pending notifcation.
187 * 200 *
188 * @param {string} type The notification type (i.e: "information" or "critical" ) 201 * @param {string} type The notification type (i.e: "information" or "critical" )
189 */ 202 */
190 exports.startIconAnimation = function(type) 203 exports.startIconAnimation = function(type)
191 { 204 {
192 stopIconAnimation(); 205 stopIconAnimation();
193 runAnimation(type); 206 runAnimationLoop(type);
194 }; 207 };
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld