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

Side by Side Diff: lib/icon.js

Issue 29334787: Issue 3532 - Handle when the icon animaion is stopped while animating (Closed)
Patch Set: Created Jan. 28, 2016, 12:14 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 | 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 stopRequested = false;
29 let animationInterval = null; 29 let canUpdateIcon = true;
30 let onActivated = null; 30 let notRunning = Promise.resolve();
31 let whitelistedState = new ext.PageMap(); 31 let whitelistedState = new ext.PageMap();
32 32
33 function loadImage(url) 33 function loadImage(url)
34 { 34 {
35 return new Promise((resolve, reject) => 35 return new Promise((resolve, reject) =>
36 { 36 {
37 let image = new Image(); 37 let image = new Image();
38 image.src = url; 38 image.src = url;
39 image.addEventListener("load", () => 39 image.addEventListener("load", () =>
40 { 40 {
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 }); 116 });
117 } 117 }
118 118
119 function animateIcon(notificationType, frames) 119 function animateIcon(notificationType, frames)
120 { 120 {
121 ext.pages.query({active: true}, pages => 121 ext.pages.query({active: true}, pages =>
122 { 122 {
123 let animationStep = 0; 123 let animationStep = 0;
124 let opacity = 0; 124 let opacity = 0;
125 125
126 onActivated = page => 126 let onActivated = page =>
127 { 127 {
128 pages.push(page); 128 pages.push(page);
129 setIcon(page, notificationType, opacity, frames); 129 setIcon(page, notificationType, opacity, frames);
130 }; 130 };
131 ext.pages.onActivated.addListener(onActivated); 131 ext.pages.onActivated.addListener(onActivated);
132 132
133 frameInterval = setInterval(() => 133 canUpdateIcon = false;
134 let frameInterval = setInterval(() =>
134 { 135 {
135 let oldOpacity = opacity; 136 let oldOpacity = opacity;
136 opacity = frameOpacities[animationStep++]; 137 opacity = frameOpacities[animationStep++];
137 138
138 if (opacity != oldOpacity) 139 if (opacity != oldOpacity)
139 { 140 {
140 for (let page of pages) 141 for (let page of pages)
141 { 142 {
142 if (whitelistedState.has(page)) 143 if (whitelistedState.has(page))
143 setIcon(page, notificationType, opacity, frames); 144 setIcon(page, notificationType, opacity, frames);
144 } 145 }
145 } 146 }
146 147
147 if (animationStep > numberOfFrames) 148 if (animationStep > numberOfFrames)
148 { 149 {
149 clearInterval(frameInterval); 150 clearInterval(frameInterval);
150 ext.pages.onActivated.removeListener(onActivated); 151 ext.pages.onActivated.removeListener(onActivated);
151 frameInterval = onActivated = null; 152 canUpdateIcon = true;
152 } 153 }
153 }, 100); 154 }, 100);
154 }); 155 });
155 } 156 }
156 157
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
169 /** 158 /**
170 * Set the browser action icon for the given page, indicating whether 159 * Set the browser action icon for the given page, indicating whether
171 * adblocking is active there, and considering the icon animation. 160 * adblocking is active there, and considering the icon animation.
172 * 161 *
173 * @param {Page} page The page to set the browser action icon for 162 * @param {Page} page The page to set the browser action icon for
174 * @param {Boolean} whitelisted Whether the page has been whitelisted 163 * @param {Boolean} whitelisted Whether the page has been whitelisted
175 */ 164 */
176 exports.updateIcon = function(page, whitelisted) 165 exports.updateIcon = function(page, whitelisted)
177 { 166 {
178 whitelistedState.set(page, whitelisted); 167 whitelistedState.set(page, whitelisted);
179 if (frameInterval == null) 168 if (canUpdateIcon)
180 setIcon(page); 169 setIcon(page);
181 }; 170 };
182 171
183 let stopIconAnimation = 172 let stopIconAnimation =
184 /** 173 /**
185 * Stops to animate the browser action icon. 174 * Stops to animate the browser action icon.
175 *
176 * @return {Promise}
186 */ 177 */
187 exports.stopIconAnimation = function() 178 exports.stopIconAnimation = function()
188 { 179 {
189 if (frameInterval != null) 180 stopRequested = true;
190 clearInterval(frameInterval); 181 return notRunning.then(() =>
191 if (animationInterval != null) 182 {
192 clearInterval(animationInterval); 183 stopRequested = false;
193 if (onActivated) 184 });
194 ext.pages.onActivated.removeListener(onActivated);
195 frameInterval = animationInterval = onActivated = null;
196 }; 185 };
197 186
198 /** 187 /**
199 * Starts to animate the browser action icon to indicate a pending notifcation. 188 * Starts to animate the browser action icon to indicate a pending notifcation.
200 * 189 *
201 * @param {string} type The notification type (i.e: "information" or "critical" ) 190 * @param {string} type The notification type (i.e: "information" or "critical" )
202 */ 191 */
203 exports.startIconAnimation = function(type) 192 exports.startIconAnimation = function(type)
204 { 193 {
205 stopIconAnimation(); 194 notRunning = new Promise(resolve =>
206 runAnimationLoop(type); 195 {
196 Promise.all([renderFrames(type), stopIconAnimation()]).then(results =>
197 {
198 if (stopRequested)
199 {
200 resolve();
201 return;
202 }
203
204 let frames = results[0];
205 animateIcon(type, frames);
206
207 let animationInterval = setInterval(() =>
208 {
209 if (stopRequested)
210 {
211 clearInterval(animationInterval);
212 resolve();
213 return;
214 }
215
216 animateIcon(type, frames);
217 }, 10000);
218 });
219 });
207 }; 220 };
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