Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(213)

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/animation/AnimationModel.js

Issue 2466123002: DevTools: reformat front-end code to match chromium style. (Closed)
Patch Set: all done Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5
6 /** 5 /**
7 * @constructor 6 * @unrestricted
8 * @extends {WebInspector.SDKModel}
9 * @param {!WebInspector.Target} target
10 */ 7 */
11 WebInspector.AnimationModel = function(target) 8 WebInspector.AnimationModel = class extends WebInspector.SDKModel {
12 { 9 /**
13 WebInspector.SDKModel.call(this, WebInspector.AnimationModel, target); 10 * @param {!WebInspector.Target} target
11 */
12 constructor(target) {
13 super(WebInspector.AnimationModel, target);
14 this._agent = target.animationAgent(); 14 this._agent = target.animationAgent();
15 target.registerAnimationDispatcher(new WebInspector.AnimationDispatcher(this )); 15 target.registerAnimationDispatcher(new WebInspector.AnimationDispatcher(this ));
16 /** @type {!Map.<string, !WebInspector.AnimationModel.Animation>} */ 16 /** @type {!Map.<string, !WebInspector.AnimationModel.Animation>} */
17 this._animationsById = new Map(); 17 this._animationsById = new Map();
18 /** @type {!Map.<string, !WebInspector.AnimationModel.AnimationGroup>} */ 18 /** @type {!Map.<string, !WebInspector.AnimationModel.AnimationGroup>} */
19 this._animationGroups = new Map(); 19 this._animationGroups = new Map();
20 /** @type {!Array.<string>} */ 20 /** @type {!Array.<string>} */
21 this._pendingAnimations = []; 21 this._pendingAnimations = [];
22 this._playbackRate = 1; 22 this._playbackRate = 1;
23 var resourceTreeModel = /** @type {!WebInspector.ResourceTreeModel} */ (WebI nspector.ResourceTreeModel.fromTarget(target)); 23 var resourceTreeModel =
24 /** @type {!WebInspector.ResourceTreeModel} */ (WebInspector.ResourceTre eModel.fromTarget(target));
24 resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.Events.Mai nFrameNavigated, this._reset, this); 25 resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.Events.Mai nFrameNavigated, this._reset, this);
25 this._screenshotCapture = new WebInspector.AnimationModel.ScreenshotCapture( target, this, resourceTreeModel); 26 this._screenshotCapture = new WebInspector.AnimationModel.ScreenshotCapture( target, this, resourceTreeModel);
27 }
28
29 /**
30 * @param {!WebInspector.Target} target
31 * @return {?WebInspector.AnimationModel}
32 */
33 static fromTarget(target) {
34 if (!target.hasDOMCapability())
35 return null;
36 if (!target[WebInspector.AnimationModel._symbol])
37 target[WebInspector.AnimationModel._symbol] = new WebInspector.AnimationMo del(target);
38
39 return target[WebInspector.AnimationModel._symbol];
40 }
41
42 _reset() {
43 this._animationsById.clear();
44 this._animationGroups.clear();
45 this._pendingAnimations = [];
46 this.dispatchEventToListeners(WebInspector.AnimationModel.Events.ModelReset) ;
47 }
48
49 /**
50 * @param {string} id
51 */
52 animationCreated(id) {
53 this._pendingAnimations.push(id);
54 }
55
56 /**
57 * @param {string} id
58 */
59 _animationCanceled(id) {
60 this._pendingAnimations.remove(id);
61 this._flushPendingAnimationsIfNeeded();
62 }
63
64 /**
65 * @param {!AnimationAgent.Animation} payload
66 */
67 animationStarted(payload) {
68 var animation = WebInspector.AnimationModel.Animation.parsePayload(this.targ et(), payload);
69
70 // Ignore Web Animations custom effects & groups.
71 if (animation.type() === 'WebAnimation' && animation.source().keyframesRule( ).keyframes().length === 0) {
72 this._pendingAnimations.remove(animation.id());
73 } else {
74 this._animationsById.set(animation.id(), animation);
75 if (this._pendingAnimations.indexOf(animation.id()) === -1)
76 this._pendingAnimations.push(animation.id());
77 }
78
79 this._flushPendingAnimationsIfNeeded();
80 }
81
82 _flushPendingAnimationsIfNeeded() {
83 for (var id of this._pendingAnimations) {
84 if (!this._animationsById.get(id))
85 return;
86 }
87
88 while (this._pendingAnimations.length)
89 this._matchExistingGroups(this._createGroupFromPendingAnimations());
90 }
91
92 /**
93 * @param {!WebInspector.AnimationModel.AnimationGroup} incomingGroup
94 * @return {boolean}
95 */
96 _matchExistingGroups(incomingGroup) {
97 var matchedGroup = null;
98 for (var group of this._animationGroups.values()) {
99 if (group._matches(incomingGroup)) {
100 matchedGroup = group;
101 group._update(incomingGroup);
102 break;
103 }
104 }
105
106 if (!matchedGroup) {
107 this._animationGroups.set(incomingGroup.id(), incomingGroup);
108 this._screenshotCapture.captureScreenshots(incomingGroup.finiteDuration(), incomingGroup._screenshots);
109 }
110 this.dispatchEventToListeners(
111 WebInspector.AnimationModel.Events.AnimationGroupStarted, matchedGroup | | incomingGroup);
112 return !!matchedGroup;
113 }
114
115 /**
116 * @return {!WebInspector.AnimationModel.AnimationGroup}
117 */
118 _createGroupFromPendingAnimations() {
119 console.assert(this._pendingAnimations.length);
120 var groupedAnimations = [this._animationsById.get(this._pendingAnimations.sh ift())];
121 var remainingAnimations = [];
122 for (var id of this._pendingAnimations) {
123 var anim = this._animationsById.get(id);
124 if (anim.startTime() === groupedAnimations[0].startTime())
125 groupedAnimations.push(anim);
126 else
127 remainingAnimations.push(id);
128 }
129 this._pendingAnimations = remainingAnimations;
130 return new WebInspector.AnimationModel.AnimationGroup(this, groupedAnimation s[0].id(), groupedAnimations);
131 }
132
133 /**
134 * @return {!Promise.<number>}
135 */
136 playbackRatePromise() {
137 /**
138 * @param {?Protocol.Error} error
139 * @param {number} playbackRate
140 * @return {number}
141 * @this {!WebInspector.AnimationModel}
142 */
143 function callback(error, playbackRate) {
144 if (error)
145 return 1;
146 this._playbackRate = playbackRate;
147 return playbackRate;
148 }
149
150 return this._agent.getPlaybackRate(callback.bind(this)).catchException(1);
151 }
152
153 /**
154 * @param {number} playbackRate
155 */
156 setPlaybackRate(playbackRate) {
157 this._playbackRate = playbackRate;
158 this._agent.setPlaybackRate(playbackRate);
159 }
160
161 /**
162 * @param {!Array.<string>} animations
163 */
164 _releaseAnimations(animations) {
165 this.target().animationAgent().releaseAnimations(animations);
166 }
167
168 /**
169 * @override
170 * @return {!Promise}
171 */
172 suspendModel() {
173 this._reset();
174 return this._agent.disable();
175 }
176
177 /**
178 * @override
179 * @return {!Promise}
180 */
181 resumeModel() {
182 if (!this._enabled)
183 return Promise.resolve();
184 return this._agent.enable();
185 }
186
187 ensureEnabled() {
188 if (this._enabled)
189 return;
190 this._agent.enable();
191 this._enabled = true;
192 }
26 }; 193 };
27 194
28 /** @enum {symbol} */ 195 /** @enum {symbol} */
29 WebInspector.AnimationModel.Events = { 196 WebInspector.AnimationModel.Events = {
30 AnimationGroupStarted: Symbol("AnimationGroupStarted"), 197 AnimationGroupStarted: Symbol('AnimationGroupStarted'),
31 ModelReset: Symbol("ModelReset") 198 ModelReset: Symbol('ModelReset')
32 }; 199 };
33 200
34 WebInspector.AnimationModel.prototype = { 201 WebInspector.AnimationModel._symbol = Symbol('AnimationModel');
35 _reset: function() 202
36 {
37 this._animationsById.clear();
38 this._animationGroups.clear();
39 this._pendingAnimations = [];
40 this.dispatchEventToListeners(WebInspector.AnimationModel.Events.ModelRe set);
41 },
42
43 /**
44 * @param {string} id
45 */
46 animationCreated: function(id)
47 {
48 this._pendingAnimations.push(id);
49 },
50
51 /**
52 * @param {string} id
53 */
54 _animationCanceled: function(id)
55 {
56 this._pendingAnimations.remove(id);
57 this._flushPendingAnimationsIfNeeded();
58 },
59
60 /**
61 * @param {!AnimationAgent.Animation} payload
62 */
63 animationStarted: function(payload)
64 {
65 var animation = WebInspector.AnimationModel.Animation.parsePayload(this. target(), payload);
66
67 // Ignore Web Animations custom effects & groups.
68 if (animation.type() === "WebAnimation" && animation.source().keyframesR ule().keyframes().length === 0) {
69 this._pendingAnimations.remove(animation.id());
70 } else {
71 this._animationsById.set(animation.id(), animation);
72 if (this._pendingAnimations.indexOf(animation.id()) === -1)
73 this._pendingAnimations.push(animation.id());
74 }
75
76 this._flushPendingAnimationsIfNeeded();
77 },
78
79 _flushPendingAnimationsIfNeeded: function()
80 {
81 for (var id of this._pendingAnimations) {
82 if (!this._animationsById.get(id))
83 return;
84 }
85
86 while (this._pendingAnimations.length)
87 this._matchExistingGroups(this._createGroupFromPendingAnimations());
88 },
89
90 /**
91 * @param {!WebInspector.AnimationModel.AnimationGroup} incomingGroup
92 * @return {boolean}
93 */
94 _matchExistingGroups: function(incomingGroup)
95 {
96 var matchedGroup = null;
97 for (var group of this._animationGroups.values()) {
98 if (group._matches(incomingGroup)) {
99 matchedGroup = group;
100 group._update(incomingGroup);
101 break;
102 }
103 }
104
105 if (!matchedGroup) {
106 this._animationGroups.set(incomingGroup.id(), incomingGroup);
107 this._screenshotCapture.captureScreenshots(incomingGroup.finiteDurat ion(), incomingGroup._screenshots);
108 }
109 this.dispatchEventToListeners(WebInspector.AnimationModel.Events.Animati onGroupStarted, matchedGroup || incomingGroup);
110 return !!matchedGroup;
111 },
112
113 /**
114 * @return {!WebInspector.AnimationModel.AnimationGroup}
115 */
116 _createGroupFromPendingAnimations: function()
117 {
118 console.assert(this._pendingAnimations.length);
119 var groupedAnimations = [this._animationsById.get(this._pendingAnimation s.shift())];
120 var remainingAnimations = [];
121 for (var id of this._pendingAnimations) {
122 var anim = this._animationsById.get(id);
123 if (anim.startTime() === groupedAnimations[0].startTime())
124 groupedAnimations.push(anim);
125 else
126 remainingAnimations.push(id);
127 }
128 this._pendingAnimations = remainingAnimations;
129 return new WebInspector.AnimationModel.AnimationGroup(this, groupedAnima tions[0].id(), groupedAnimations);
130 },
131
132 /**
133 * @return {!Promise.<number>}
134 */
135 playbackRatePromise: function()
136 {
137 /**
138 * @param {?Protocol.Error} error
139 * @param {number} playbackRate
140 * @return {number}
141 * @this {!WebInspector.AnimationModel}
142 */
143 function callback(error, playbackRate)
144 {
145 if (error)
146 return 1;
147 this._playbackRate = playbackRate;
148 return playbackRate;
149 }
150
151 return this._agent.getPlaybackRate(callback.bind(this)).catchException(1 );
152 },
153
154 /**
155 * @param {number} playbackRate
156 */
157 setPlaybackRate: function(playbackRate)
158 {
159 this._playbackRate = playbackRate;
160 this._agent.setPlaybackRate(playbackRate);
161 },
162
163 /**
164 * @param {!Array.<string>} animations
165 */
166 _releaseAnimations: function(animations)
167 {
168 this.target().animationAgent().releaseAnimations(animations);
169 },
170
171 /**
172 * @override
173 * @return {!Promise}
174 */
175 suspendModel: function()
176 {
177 this._reset();
178 return this._agent.disable();
179 },
180
181 /**
182 * @override
183 * @return {!Promise}
184 */
185 resumeModel: function()
186 {
187 if (!this._enabled)
188 return Promise.resolve();
189 return this._agent.enable();
190 },
191
192 ensureEnabled: function()
193 {
194 if (this._enabled)
195 return;
196 this._agent.enable();
197 this._enabled = true;
198 },
199
200 __proto__: WebInspector.SDKModel.prototype
201 };
202
203 WebInspector.AnimationModel._symbol = Symbol("AnimationModel");
204 203
205 /** 204 /**
206 * @param {!WebInspector.Target} target 205 * @unrestricted
207 * @return {?WebInspector.AnimationModel}
208 */ 206 */
209 WebInspector.AnimationModel.fromTarget = function(target) 207 WebInspector.AnimationModel.Animation = class extends WebInspector.SDKObject {
210 { 208 /**
211 if (!target.hasDOMCapability()) 209 * @param {!WebInspector.Target} target
212 return null; 210 * @param {!AnimationAgent.Animation} payload
213 if (!target[WebInspector.AnimationModel._symbol]) 211 */
214 target[WebInspector.AnimationModel._symbol] = new WebInspector.Animation Model(target); 212 constructor(target, payload) {
215 213 super(target);
216 return target[WebInspector.AnimationModel._symbol];
217 };
218
219 /**
220 * @constructor
221 * @extends {WebInspector.SDKObject}
222 * @param {!WebInspector.Target} target
223 * @param {!AnimationAgent.Animation} payload
224 */
225 WebInspector.AnimationModel.Animation = function(target, payload)
226 {
227 WebInspector.SDKObject.call(this, target);
228 this._payload = payload; 214 this._payload = payload;
229 this._source = new WebInspector.AnimationModel.AnimationEffect(this.target() , this._payload.source); 215 this._source = new WebInspector.AnimationModel.AnimationEffect(this.target() , this._payload.source);
230 }; 216 }
231 217
232 /** 218 /**
233 * @param {!WebInspector.Target} target 219 * @param {!WebInspector.Target} target
234 * @param {!AnimationAgent.Animation} payload 220 * @param {!AnimationAgent.Animation} payload
235 * @return {!WebInspector.AnimationModel.Animation} 221 * @return {!WebInspector.AnimationModel.Animation}
236 */ 222 */
237 WebInspector.AnimationModel.Animation.parsePayload = function(target, payload) 223 static parsePayload(target, payload) {
238 {
239 return new WebInspector.AnimationModel.Animation(target, payload); 224 return new WebInspector.AnimationModel.Animation(target, payload);
240 }; 225 }
226
227 /**
228 * @return {!AnimationAgent.Animation}
229 */
230 payload() {
231 return this._payload;
232 }
233
234 /**
235 * @return {string}
236 */
237 id() {
238 return this._payload.id;
239 }
240
241 /**
242 * @return {string}
243 */
244 name() {
245 return this._payload.name;
246 }
247
248 /**
249 * @return {boolean}
250 */
251 paused() {
252 return this._payload.pausedState;
253 }
254
255 /**
256 * @return {string}
257 */
258 playState() {
259 return this._playState || this._payload.playState;
260 }
261
262 /**
263 * @param {string} playState
264 */
265 setPlayState(playState) {
266 this._playState = playState;
267 }
268
269 /**
270 * @return {number}
271 */
272 playbackRate() {
273 return this._payload.playbackRate;
274 }
275
276 /**
277 * @return {number}
278 */
279 startTime() {
280 return this._payload.startTime;
281 }
282
283 /**
284 * @return {number}
285 */
286 endTime() {
287 if (!this.source().iterations)
288 return Infinity;
289 return this.startTime() + this.source().delay() + this.source().duration() * this.source().iterations() +
290 this.source().endDelay();
291 }
292
293 /**
294 * @return {number}
295 */
296 _finiteDuration() {
297 var iterations = Math.min(this.source().iterations(), 3);
298 return this.source().delay() + this.source().duration() * iterations;
299 }
300
301 /**
302 * @return {number}
303 */
304 currentTime() {
305 return this._payload.currentTime;
306 }
307
308 /**
309 * @return {!WebInspector.AnimationModel.AnimationEffect}
310 */
311 source() {
312 return this._source;
313 }
314
315 /**
316 * @return {!WebInspector.AnimationModel.Animation.Type}
317 */
318 type() {
319 return /** @type {!WebInspector.AnimationModel.Animation.Type} */ (this._pay load.type);
320 }
321
322 /**
323 * @param {!WebInspector.AnimationModel.Animation} animation
324 * @return {boolean}
325 */
326 overlaps(animation) {
327 // Infinite animations
328 if (!this.source().iterations() || !animation.source().iterations())
329 return true;
330
331 var firstAnimation = this.startTime() < animation.startTime() ? this : anima tion;
332 var secondAnimation = firstAnimation === this ? animation : this;
333 return firstAnimation.endTime() >= secondAnimation.startTime();
334 }
335
336 /**
337 * @param {number} duration
338 * @param {number} delay
339 */
340 setTiming(duration, delay) {
341 this._source.node().then(this._updateNodeStyle.bind(this, duration, delay));
342 this._source._duration = duration;
343 this._source._delay = delay;
344 this.target().animationAgent().setTiming(this.id(), duration, delay);
345 }
346
347 /**
348 * @param {number} duration
349 * @param {number} delay
350 * @param {!WebInspector.DOMNode} node
351 */
352 _updateNodeStyle(duration, delay, node) {
353 var animationPrefix;
354 if (this.type() === WebInspector.AnimationModel.Animation.Type.CSSTransition )
355 animationPrefix = 'transition-';
356 else if (this.type() === WebInspector.AnimationModel.Animation.Type.CSSAnima tion)
357 animationPrefix = 'animation-';
358 else
359 return;
360
361 var cssModel = WebInspector.CSSModel.fromTarget(node.target());
362 if (!cssModel)
363 return;
364 cssModel.setEffectivePropertyValueForNode(node.id, animationPrefix + 'durati on', duration + 'ms');
365 cssModel.setEffectivePropertyValueForNode(node.id, animationPrefix + 'delay' , delay + 'ms');
366 }
367
368 /**
369 * @return {!Promise.<?WebInspector.RemoteObject>}
370 */
371 remoteObjectPromise() {
372 /**
373 * @param {?Protocol.Error} error
374 * @param {!RuntimeAgent.RemoteObject} payload
375 * @return {?WebInspector.RemoteObject}
376 * @this {!WebInspector.AnimationModel.Animation}
377 */
378 function callback(error, payload) {
379 return !error ? this.target().runtimeModel.createRemoteObject(payload) : n ull;
380 }
381
382 return this.target().animationAgent().resolveAnimation(this.id(), callback.b ind(this));
383 }
384
385 /**
386 * @return {string}
387 */
388 _cssId() {
389 return this._payload.cssId || '';
390 }
391 };
392
241 393
242 /** @enum {string} */ 394 /** @enum {string} */
243 WebInspector.AnimationModel.Animation.Type = { 395 WebInspector.AnimationModel.Animation.Type = {
244 CSSTransition: "CSSTransition", 396 CSSTransition: 'CSSTransition',
245 CSSAnimation: "CSSAnimation", 397 CSSAnimation: 'CSSAnimation',
246 WebAnimation: "WebAnimation" 398 WebAnimation: 'WebAnimation'
247 };
248
249 WebInspector.AnimationModel.Animation.prototype = {
250 /**
251 * @return {!AnimationAgent.Animation}
252 */
253 payload: function()
254 {
255 return this._payload;
256 },
257
258 /**
259 * @return {string}
260 */
261 id: function()
262 {
263 return this._payload.id;
264 },
265
266 /**
267 * @return {string}
268 */
269 name: function()
270 {
271 return this._payload.name;
272 },
273
274 /**
275 * @return {boolean}
276 */
277 paused: function()
278 {
279 return this._payload.pausedState;
280 },
281
282 /**
283 * @return {string}
284 */
285 playState: function()
286 {
287 return this._playState || this._payload.playState;
288 },
289
290 /**
291 * @param {string} playState
292 */
293 setPlayState: function(playState)
294 {
295 this._playState = playState;
296 },
297
298 /**
299 * @return {number}
300 */
301 playbackRate: function()
302 {
303 return this._payload.playbackRate;
304 },
305
306 /**
307 * @return {number}
308 */
309 startTime: function()
310 {
311 return this._payload.startTime;
312 },
313
314 /**
315 * @return {number}
316 */
317 endTime: function()
318 {
319 if (!this.source().iterations)
320 return Infinity;
321 return this.startTime() + this.source().delay() + this.source().duration () * this.source().iterations() + this.source().endDelay();
322 },
323
324 /**
325 * @return {number}
326 */
327 _finiteDuration: function()
328 {
329 var iterations = Math.min(this.source().iterations(), 3);
330 return this.source().delay() + this.source().duration() * iterations;
331 },
332
333 /**
334 * @return {number}
335 */
336 currentTime: function()
337 {
338 return this._payload.currentTime;
339 },
340
341 /**
342 * @return {!WebInspector.AnimationModel.AnimationEffect}
343 */
344 source: function()
345 {
346 return this._source;
347 },
348
349 /**
350 * @return {!WebInspector.AnimationModel.Animation.Type}
351 */
352 type: function()
353 {
354 return /** @type {!WebInspector.AnimationModel.Animation.Type} */(this._ payload.type);
355 },
356
357 /**
358 * @param {!WebInspector.AnimationModel.Animation} animation
359 * @return {boolean}
360 */
361 overlaps: function(animation)
362 {
363 // Infinite animations
364 if (!this.source().iterations() || !animation.source().iterations())
365 return true;
366
367 var firstAnimation = this.startTime() < animation.startTime() ? this : a nimation;
368 var secondAnimation = firstAnimation === this ? animation : this;
369 return firstAnimation.endTime() >= secondAnimation.startTime();
370 },
371
372 /**
373 * @param {number} duration
374 * @param {number} delay
375 */
376 setTiming: function(duration, delay)
377 {
378 this._source.node().then(this._updateNodeStyle.bind(this, duration, dela y));
379 this._source._duration = duration;
380 this._source._delay = delay;
381 this.target().animationAgent().setTiming(this.id(), duration, delay);
382 },
383
384 /**
385 * @param {number} duration
386 * @param {number} delay
387 * @param {!WebInspector.DOMNode} node
388 */
389 _updateNodeStyle: function(duration, delay, node)
390 {
391 var animationPrefix;
392 if (this.type() === WebInspector.AnimationModel.Animation.Type.CSSTransi tion)
393 animationPrefix = "transition-";
394 else if (this.type() === WebInspector.AnimationModel.Animation.Type.CSSA nimation)
395 animationPrefix = "animation-";
396 else
397 return;
398
399 var cssModel = WebInspector.CSSModel.fromTarget(node.target());
400 if (!cssModel)
401 return;
402 cssModel.setEffectivePropertyValueForNode(node.id, animationPrefix + "du ration", duration + "ms");
403 cssModel.setEffectivePropertyValueForNode(node.id, animationPrefix + "de lay", delay + "ms");
404 },
405
406 /**
407 * @return {!Promise.<?WebInspector.RemoteObject>}
408 */
409 remoteObjectPromise: function()
410 {
411 /**
412 * @param {?Protocol.Error} error
413 * @param {!RuntimeAgent.RemoteObject} payload
414 * @return {?WebInspector.RemoteObject}
415 * @this {!WebInspector.AnimationModel.Animation}
416 */
417 function callback(error, payload)
418 {
419 return !error ? this.target().runtimeModel.createRemoteObject(payloa d) : null;
420 }
421
422 return this.target().animationAgent().resolveAnimation(this.id(), callba ck.bind(this));
423 },
424
425 /**
426 * @return {string}
427 */
428 _cssId: function()
429 {
430 return this._payload.cssId || "";
431 },
432
433 __proto__: WebInspector.SDKObject.prototype
434 }; 399 };
435 400
436 /** 401 /**
437 * @constructor 402 * @unrestricted
438 * @extends {WebInspector.SDKObject}
439 * @param {!WebInspector.Target} target
440 * @param {!AnimationAgent.AnimationEffect} payload
441 */ 403 */
442 WebInspector.AnimationModel.AnimationEffect = function(target, payload) 404 WebInspector.AnimationModel.AnimationEffect = class extends WebInspector.SDKObje ct {
443 { 405 /**
444 WebInspector.SDKObject.call(this, target); 406 * @param {!WebInspector.Target} target
407 * @param {!AnimationAgent.AnimationEffect} payload
408 */
409 constructor(target, payload) {
410 super(target);
445 this._payload = payload; 411 this._payload = payload;
446 if (payload.keyframesRule) 412 if (payload.keyframesRule)
447 this._keyframesRule = new WebInspector.AnimationModel.KeyframesRule(targ et, payload.keyframesRule); 413 this._keyframesRule = new WebInspector.AnimationModel.KeyframesRule(target , payload.keyframesRule);
448 this._delay = this._payload.delay; 414 this._delay = this._payload.delay;
449 this._duration = this._payload.duration; 415 this._duration = this._payload.duration;
450 }; 416 }
451 417
452 WebInspector.AnimationModel.AnimationEffect.prototype = { 418 /**
453 /** 419 * @return {number}
454 * @return {number} 420 */
455 */ 421 delay() {
456 delay: function() 422 return this._delay;
457 { 423 }
458 return this._delay; 424
459 }, 425 /**
460 426 * @return {number}
461 /** 427 */
462 * @return {number} 428 endDelay() {
463 */ 429 return this._payload.endDelay;
464 endDelay: function() 430 }
465 { 431
466 return this._payload.endDelay; 432 /**
467 }, 433 * @return {number}
468 434 */
469 /** 435 iterationStart() {
470 * @return {number} 436 return this._payload.iterationStart;
471 */ 437 }
472 iterationStart: function() 438
473 { 439 /**
474 return this._payload.iterationStart; 440 * @return {number}
475 }, 441 */
476 442 iterations() {
477 /** 443 // Animations with zero duration, zero delays and infinite iterations can't be shown.
478 * @return {number} 444 if (!this.delay() && !this.endDelay() && !this.duration())
479 */ 445 return 0;
480 iterations: function() 446 return this._payload.iterations || Infinity;
481 { 447 }
482 // Animations with zero duration, zero delays and infinite iterations ca n't be shown. 448
483 if (!this.delay() && !this.endDelay() && !this.duration()) 449 /**
484 return 0; 450 * @return {number}
485 return this._payload.iterations || Infinity; 451 */
486 }, 452 duration() {
487 453 return this._duration;
488 /** 454 }
489 * @return {number} 455
490 */ 456 /**
491 duration: function() 457 * @return {string}
492 { 458 */
493 return this._duration; 459 direction() {
494 }, 460 return this._payload.direction;
495 461 }
496 /** 462
497 * @return {string} 463 /**
498 */ 464 * @return {string}
499 direction: function() 465 */
500 { 466 fill() {
501 return this._payload.direction; 467 return this._payload.fill;
502 }, 468 }
503 469
504 /** 470 /**
505 * @return {string} 471 * @return {!Promise.<!WebInspector.DOMNode>}
506 */ 472 */
507 fill: function() 473 node() {
508 { 474 if (!this._deferredNode)
509 return this._payload.fill; 475 this._deferredNode = new WebInspector.DeferredDOMNode(this.target(), this. backendNodeId());
510 }, 476 return this._deferredNode.resolvePromise();
511 477 }
512 /** 478
513 * @return {!Promise.<!WebInspector.DOMNode>} 479 /**
514 */ 480 * @return {!WebInspector.DeferredDOMNode}
515 node: function() 481 */
516 { 482 deferredNode() {
517 if (!this._deferredNode) 483 return new WebInspector.DeferredDOMNode(this.target(), this.backendNodeId()) ;
518 this._deferredNode = new WebInspector.DeferredDOMNode(this.target(), this.backendNodeId()); 484 }
519 return this._deferredNode.resolvePromise(); 485
520 }, 486 /**
521 487 * @return {number}
522 /** 488 */
523 * @return {!WebInspector.DeferredDOMNode} 489 backendNodeId() {
524 */ 490 return this._payload.backendNodeId;
525 deferredNode: function() 491 }
526 { 492
527 return new WebInspector.DeferredDOMNode(this.target(), this.backendNodeI d()); 493 /**
528 }, 494 * @return {?WebInspector.AnimationModel.KeyframesRule}
529 495 */
530 /** 496 keyframesRule() {
531 * @return {number} 497 return this._keyframesRule;
532 */ 498 }
533 backendNodeId: function() 499
534 { 500 /**
535 return this._payload.backendNodeId; 501 * @return {string}
536 }, 502 */
537 503 easing() {
538 /** 504 return this._payload.easing;
539 * @return {?WebInspector.AnimationModel.KeyframesRule} 505 }
540 */
541 keyframesRule: function()
542 {
543 return this._keyframesRule;
544 },
545
546 /**
547 * @return {string}
548 */
549 easing: function()
550 {
551 return this._payload.easing;
552 },
553
554 __proto__: WebInspector.SDKObject.prototype
555 }; 506 };
556 507
557 /** 508 /**
558 * @constructor 509 * @unrestricted
559 * @extends {WebInspector.SDKObject}
560 * @param {!WebInspector.Target} target
561 * @param {!AnimationAgent.KeyframesRule} payload
562 */ 510 */
563 WebInspector.AnimationModel.KeyframesRule = function(target, payload) 511 WebInspector.AnimationModel.KeyframesRule = class extends WebInspector.SDKObject {
564 { 512 /**
565 WebInspector.SDKObject.call(this, target); 513 * @param {!WebInspector.Target} target
514 * @param {!AnimationAgent.KeyframesRule} payload
515 */
516 constructor(target, payload) {
517 super(target);
566 this._payload = payload; 518 this._payload = payload;
567 this._keyframes = this._payload.keyframes.map(function(keyframeStyle) { 519 this._keyframes = this._payload.keyframes.map(function(keyframeStyle) {
568 return new WebInspector.AnimationModel.KeyframeStyle(target, keyframeSty le); 520 return new WebInspector.AnimationModel.KeyframeStyle(target, keyframeStyle );
569 }); 521 });
570 }; 522 }
571 523
572 WebInspector.AnimationModel.KeyframesRule.prototype = { 524 /**
573 /** 525 * @param {!Array.<!AnimationAgent.KeyframeStyle>} payload
574 * @param {!Array.<!AnimationAgent.KeyframeStyle>} payload 526 */
575 */ 527 _setKeyframesPayload(payload) {
576 _setKeyframesPayload: function(payload) 528 this._keyframes = payload.map(function(keyframeStyle) {
577 { 529 return new WebInspector.AnimationModel.KeyframeStyle(this._target, keyfram eStyle);
578 this._keyframes = payload.map(function(keyframeStyle) { 530 });
579 return new WebInspector.AnimationModel.KeyframeStyle(this._target, k eyframeStyle); 531 }
580 }); 532
581 }, 533 /**
582 534 * @return {string|undefined}
583 /** 535 */
584 * @return {string|undefined} 536 name() {
585 */ 537 return this._payload.name;
586 name: function() 538 }
587 { 539
588 return this._payload.name; 540 /**
589 }, 541 * @return {!Array.<!WebInspector.AnimationModel.KeyframeStyle>}
590 542 */
591 /** 543 keyframes() {
592 * @return {!Array.<!WebInspector.AnimationModel.KeyframeStyle>} 544 return this._keyframes;
593 */ 545 }
594 keyframes: function()
595 {
596 return this._keyframes;
597 },
598
599 __proto__: WebInspector.SDKObject.prototype
600 }; 546 };
601 547
602 /** 548 /**
603 * @constructor 549 * @unrestricted
604 * @extends {WebInspector.SDKObject}
605 * @param {!WebInspector.Target} target
606 * @param {!AnimationAgent.KeyframeStyle} payload
607 */ 550 */
608 WebInspector.AnimationModel.KeyframeStyle = function(target, payload) 551 WebInspector.AnimationModel.KeyframeStyle = class extends WebInspector.SDKObject {
609 { 552 /**
610 WebInspector.SDKObject.call(this, target); 553 * @param {!WebInspector.Target} target
554 * @param {!AnimationAgent.KeyframeStyle} payload
555 */
556 constructor(target, payload) {
557 super(target);
611 this._payload = payload; 558 this._payload = payload;
612 this._offset = this._payload.offset; 559 this._offset = this._payload.offset;
613 }; 560 }
614 561
615 WebInspector.AnimationModel.KeyframeStyle.prototype = { 562 /**
616 /** 563 * @return {string}
617 * @return {string} 564 */
618 */ 565 offset() {
619 offset: function() 566 return this._offset;
620 { 567 }
621 return this._offset; 568
622 }, 569 /**
623 570 * @param {number} offset
624 /** 571 */
625 * @param {number} offset 572 setOffset(offset) {
626 */ 573 this._offset = offset * 100 + '%';
627 setOffset: function(offset) 574 }
628 { 575
629 this._offset = offset * 100 + "%"; 576 /**
630 }, 577 * @return {number}
631 578 */
632 /** 579 offsetAsNumber() {
633 * @return {number} 580 return parseFloat(this._offset) / 100;
634 */ 581 }
635 offsetAsNumber: function() 582
636 { 583 /**
637 return parseFloat(this._offset) / 100; 584 * @return {string}
638 }, 585 */
639 586 easing() {
640 /** 587 return this._payload.easing;
641 * @return {string} 588 }
642 */
643 easing: function()
644 {
645 return this._payload.easing;
646 },
647
648 __proto__: WebInspector.SDKObject.prototype
649 }; 589 };
650 590
651 /** 591 /**
652 * @constructor 592 * @unrestricted
653 * @extends {WebInspector.SDKObject}
654 * @param {!WebInspector.AnimationModel} model
655 * @param {string} id
656 * @param {!Array.<!WebInspector.AnimationModel.Animation>} animations
657 */ 593 */
658 WebInspector.AnimationModel.AnimationGroup = function(model, id, animations) 594 WebInspector.AnimationModel.AnimationGroup = class extends WebInspector.SDKObjec t {
659 { 595 /**
660 WebInspector.SDKObject.call(this, model.target()); 596 * @param {!WebInspector.AnimationModel} model
597 * @param {string} id
598 * @param {!Array.<!WebInspector.AnimationModel.Animation>} animations
599 */
600 constructor(model, id, animations) {
601 super(model.target());
661 this._model = model; 602 this._model = model;
662 this._id = id; 603 this._id = id;
663 this._animations = animations; 604 this._animations = animations;
664 this._paused = false; 605 this._paused = false;
665 this._screenshots = []; 606 this._screenshots = [];
666 this._screenshotImages = []; 607 this._screenshotImages = [];
667 }; 608 }
668 609
669 WebInspector.AnimationModel.AnimationGroup.prototype = { 610 /**
611 * @return {string}
612 */
613 id() {
614 return this._id;
615 }
616
617 /**
618 * @return {!Array.<!WebInspector.AnimationModel.Animation>}
619 */
620 animations() {
621 return this._animations;
622 }
623
624 release() {
625 this._model._animationGroups.remove(this.id());
626 this._model._releaseAnimations(this._animationIds());
627 }
628
629 /**
630 * @return {!Array.<string>}
631 */
632 _animationIds() {
670 /** 633 /**
634 * @param {!WebInspector.AnimationModel.Animation} animation
671 * @return {string} 635 * @return {string}
672 */ 636 */
673 id: function() 637 function extractId(animation) {
674 { 638 return animation.id();
675 return this._id; 639 }
676 }, 640
677 641 return this._animations.map(extractId);
642 }
643
644 /**
645 * @return {number}
646 */
647 startTime() {
648 return this._animations[0].startTime();
649 }
650
651 /**
652 * @return {number}
653 */
654 finiteDuration() {
655 var maxDuration = 0;
656 for (var i = 0; i < this._animations.length; ++i)
657 maxDuration = Math.max(maxDuration, this._animations[i]._finiteDuration()) ;
658 return maxDuration;
659 }
660
661 /**
662 * @param {number} currentTime
663 */
664 seekTo(currentTime) {
665 this.target().animationAgent().seekAnimations(this._animationIds(), currentT ime);
666 }
667
668 /**
669 * @return {boolean}
670 */
671 paused() {
672 return this._paused;
673 }
674
675 /**
676 * @param {boolean} paused
677 */
678 togglePause(paused) {
679 if (paused === this._paused)
680 return;
681 this._paused = paused;
682 this.target().animationAgent().setPaused(this._animationIds(), paused);
683 }
684
685 /**
686 * @return {!Promise.<number>}
687 */
688 currentTimePromise() {
678 /** 689 /**
679 * @return {!Array.<!WebInspector.AnimationModel.Animation>} 690 * @param {?Protocol.Error} error
680 */ 691 * @param {number} currentTime
681 animations: function()
682 {
683 return this._animations;
684 },
685
686 release: function()
687 {
688 this._model._animationGroups.remove(this.id());
689 this._model._releaseAnimations(this._animationIds());
690 },
691
692 /**
693 * @return {!Array.<string>}
694 */
695 _animationIds: function()
696 {
697 /**
698 * @param {!WebInspector.AnimationModel.Animation} animation
699 * @return {string}
700 */
701 function extractId(animation)
702 {
703 return animation.id();
704 }
705
706 return this._animations.map(extractId);
707 },
708
709 /**
710 * @return {number} 692 * @return {number}
711 */ 693 */
712 startTime: function() 694 function callback(error, currentTime) {
713 { 695 return !error ? currentTime : 0;
714 return this._animations[0].startTime(); 696 }
715 }, 697
716 698 var longestAnim = null;
699 for (var anim of this._animations) {
700 if (!longestAnim || anim.endTime() > longestAnim.endTime())
701 longestAnim = anim;
702 }
703 return this.target().animationAgent().getCurrentTime(longestAnim.id(), callb ack).catchException(0);
704 }
705
706 /**
707 * @param {!WebInspector.AnimationModel.AnimationGroup} group
708 * @return {boolean}
709 */
710 _matches(group) {
717 /** 711 /**
718 * @return {number} 712 * @param {!WebInspector.AnimationModel.Animation} anim
713 * @return {string}
719 */ 714 */
720 finiteDuration: function() 715 function extractId(anim) {
721 { 716 if (anim.type() === WebInspector.AnimationModel.Animation.Type.WebAnimatio n)
722 var maxDuration = 0; 717 return anim.type() + anim.id();
723 for (var i = 0; i < this._animations.length; ++i) 718 else
724 maxDuration = Math.max(maxDuration, this._animations[i]._finiteDurat ion()); 719 return anim._cssId();
725 return maxDuration; 720 }
726 }, 721
727 722 if (this._animations.length !== group._animations.length)
728 /** 723 return false;
729 * @param {number} currentTime 724 var left = this._animations.map(extractId).sort();
730 */ 725 var right = group._animations.map(extractId).sort();
731 seekTo: function(currentTime) 726 for (var i = 0; i < left.length; i++) {
732 { 727 if (left[i] !== right[i])
733 this.target().animationAgent().seekAnimations(this._animationIds(), curr entTime); 728 return false;
734 }, 729 }
735 730 return true;
736 /** 731 }
737 * @return {boolean} 732
738 */ 733 /**
739 paused: function() 734 * @param {!WebInspector.AnimationModel.AnimationGroup} group
740 { 735 */
741 return this._paused; 736 _update(group) {
742 }, 737 this._model._releaseAnimations(this._animationIds());
743 738 this._animations = group._animations;
744 /** 739 }
745 * @param {boolean} paused 740
746 */ 741 /**
747 togglePause: function(paused) 742 * @return {!Array.<!Image>}
748 { 743 */
749 if (paused === this._paused) 744 screenshots() {
750 return; 745 for (var i = 0; i < this._screenshots.length; ++i) {
751 this._paused = paused; 746 var image = new Image();
752 this.target().animationAgent().setPaused(this._animationIds(), paused); 747 image.src = 'data:image/jpeg;base64,' + this._screenshots[i];
753 }, 748 this._screenshotImages.push(image);
754 749 }
755 /** 750 this._screenshots = [];
756 * @return {!Promise.<number>} 751 return this._screenshotImages;
757 */ 752 }
758 currentTimePromise: function() 753 };
759 {
760 /**
761 * @param {?Protocol.Error} error
762 * @param {number} currentTime
763 * @return {number}
764 */
765 function callback(error, currentTime)
766 {
767 return !error ? currentTime : 0;
768 }
769
770 var longestAnim = null;
771 for (var anim of this._animations) {
772 if (!longestAnim || anim.endTime() > longestAnim.endTime())
773 longestAnim = anim;
774 }
775 return this.target().animationAgent().getCurrentTime(longestAnim.id(), c allback).catchException(0);
776 },
777
778 /**
779 * @param {!WebInspector.AnimationModel.AnimationGroup} group
780 * @return {boolean}
781 */
782 _matches: function(group)
783 {
784 /**
785 * @param {!WebInspector.AnimationModel.Animation} anim
786 * @return {string}
787 */
788 function extractId(anim)
789 {
790 if (anim.type() === WebInspector.AnimationModel.Animation.Type.WebAn imation)
791 return anim.type() + anim.id();
792 else
793 return anim._cssId();
794 }
795
796 if (this._animations.length !== group._animations.length)
797 return false;
798 var left = this._animations.map(extractId).sort();
799 var right = group._animations.map(extractId).sort();
800 for (var i = 0; i < left.length; i++) {
801 if (left[i] !== right[i])
802 return false;
803 }
804 return true;
805 },
806
807 /**
808 * @param {!WebInspector.AnimationModel.AnimationGroup} group
809 */
810 _update: function(group)
811 {
812 this._model._releaseAnimations(this._animationIds());
813 this._animations = group._animations;
814 },
815
816 /**
817 * @return {!Array.<!Image>}
818 */
819 screenshots: function()
820 {
821 for (var i = 0; i < this._screenshots.length; ++i) {
822 var image = new Image();
823 image.src = "data:image/jpeg;base64," + this._screenshots[i];
824 this._screenshotImages.push(image);
825 }
826 this._screenshots = [];
827 return this._screenshotImages;
828 },
829
830 __proto__: WebInspector.SDKObject.prototype
831 };
832
833 754
834 /** 755 /**
835 * @constructor
836 * @implements {AnimationAgent.Dispatcher} 756 * @implements {AnimationAgent.Dispatcher}
757 * @unrestricted
837 */ 758 */
838 WebInspector.AnimationDispatcher = function(animationModel) 759 WebInspector.AnimationDispatcher = class {
839 { 760 constructor(animationModel) {
840 this._animationModel = animationModel; 761 this._animationModel = animationModel;
841 }; 762 }
842 763
843 WebInspector.AnimationDispatcher.prototype = { 764 /**
844 /** 765 * @override
845 * @override 766 * @param {string} id
846 * @param {string} id 767 */
847 */ 768 animationCreated(id) {
848 animationCreated: function(id) 769 this._animationModel.animationCreated(id);
849 { 770 }
850 this._animationModel.animationCreated(id); 771
851 }, 772 /**
852 773 * @override
853 /** 774 * @param {string} id
854 * @override 775 */
855 * @param {string} id 776 animationCanceled(id) {
856 */ 777 this._animationModel._animationCanceled(id);
857 animationCanceled: function(id) 778 }
858 { 779
859 this._animationModel._animationCanceled(id); 780 /**
860 }, 781 * @override
861 782 * @param {!AnimationAgent.Animation} payload
862 /** 783 */
863 * @override 784 animationStarted(payload) {
864 * @param {!AnimationAgent.Animation} payload 785 this._animationModel.animationStarted(payload);
865 */ 786 }
866 animationStarted: function(payload)
867 {
868 this._animationModel.animationStarted(payload);
869 }
870 }; 787 };
871 788
872 /** 789 /**
873 * @constructor 790 * @unrestricted
874 * @param {!WebInspector.Target} target
875 * @param {!WebInspector.AnimationModel} model
876 * @param {!WebInspector.ResourceTreeModel} resourceTreeModel
877 */ 791 */
878 WebInspector.AnimationModel.ScreenshotCapture = function(target, model, resource TreeModel) 792 WebInspector.AnimationModel.ScreenshotCapture = class {
879 { 793 /**
794 * @param {!WebInspector.Target} target
795 * @param {!WebInspector.AnimationModel} model
796 * @param {!WebInspector.ResourceTreeModel} resourceTreeModel
797 */
798 constructor(target, model, resourceTreeModel) {
880 this._target = target; 799 this._target = target;
881 /** @type {!Array<!WebInspector.AnimationModel.ScreenshotCapture.Request>} * / 800 /** @type {!Array<!WebInspector.AnimationModel.ScreenshotCapture.Request>} * /
882 this._requests = []; 801 this._requests = [];
883 resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.Events.Scr eencastFrame, this._screencastFrame, this); 802 resourceTreeModel.addEventListener(
803 WebInspector.ResourceTreeModel.Events.ScreencastFrame, this._screencastF rame, this);
884 this._model = model; 804 this._model = model;
885 this._model.addEventListener(WebInspector.AnimationModel.Events.ModelReset, this._stopScreencast, this); 805 this._model.addEventListener(WebInspector.AnimationModel.Events.ModelReset, this._stopScreencast, this);
806 }
807
808 /**
809 * @param {number} duration
810 * @param {!Array<string>} screenshots
811 */
812 captureScreenshots(duration, screenshots) {
813 var screencastDuration = Math.min(duration / this._model._playbackRate, 3000 );
814 var endTime = screencastDuration + window.performance.now();
815 this._requests.push({endTime: endTime, screenshots: screenshots});
816
817 if (!this._endTime || endTime > this._endTime) {
818 clearTimeout(this._stopTimer);
819 this._stopTimer = setTimeout(this._stopScreencast.bind(this), screencastDu ration);
820 this._endTime = endTime;
821 }
822
823 if (this._capturing)
824 return;
825 this._capturing = true;
826 this._target.pageAgent().startScreencast('jpeg', 80, undefined, 300, 2);
827 }
828
829 /**
830 * @param {!WebInspector.Event} event
831 */
832 _screencastFrame(event) {
833 /**
834 * @param {!WebInspector.AnimationModel.ScreenshotCapture.Request} request
835 * @return {boolean}
836 */
837 function isAnimating(request) {
838 return request.endTime >= now;
839 }
840
841 if (!this._capturing)
842 return;
843
844 var base64Data = /** type {string} */ (event.data['data']);
845 var now = window.performance.now();
846 this._requests = this._requests.filter(isAnimating);
847 for (var request of this._requests)
848 request.screenshots.push(base64Data);
849 }
850
851 _stopScreencast() {
852 if (!this._capturing)
853 return;
854
855 delete this._stopTimer;
856 delete this._endTime;
857 this._requests = [];
858 this._capturing = false;
859 this._target.pageAgent().stopScreencast();
860 }
886 }; 861 };
887 862
888 /** @typedef {{ endTime: number, screenshots: !Array.<string>}} */ 863 /** @typedef {{ endTime: number, screenshots: !Array.<string>}} */
889 WebInspector.AnimationModel.ScreenshotCapture.Request; 864 WebInspector.AnimationModel.ScreenshotCapture.Request;
890
891 WebInspector.AnimationModel.ScreenshotCapture.prototype = {
892 /**
893 * @param {number} duration
894 * @param {!Array<string>} screenshots
895 */
896 captureScreenshots: function(duration, screenshots)
897 {
898 var screencastDuration = Math.min(duration / this._model._playbackRate, 3000);
899 var endTime = screencastDuration + window.performance.now();
900 this._requests.push({ endTime: endTime, screenshots: screenshots });
901
902 if (!this._endTime || endTime > this._endTime) {
903 clearTimeout(this._stopTimer);
904 this._stopTimer = setTimeout(this._stopScreencast.bind(this), screen castDuration);
905 this._endTime = endTime;
906 }
907
908 if (this._capturing)
909 return;
910 this._capturing = true;
911 this._target.pageAgent().startScreencast("jpeg", 80, undefined, 300, 2);
912 },
913
914 /**
915 * @param {!WebInspector.Event} event
916 */
917 _screencastFrame: function(event)
918 {
919 /**
920 * @param {!WebInspector.AnimationModel.ScreenshotCapture.Request} reque st
921 * @return {boolean}
922 */
923 function isAnimating(request)
924 {
925 return request.endTime >= now;
926 }
927
928 if (!this._capturing)
929 return;
930
931 var base64Data = /** type {string} */(event.data["data"]);
932 var now = window.performance.now();
933 this._requests = this._requests.filter(isAnimating);
934 for (var request of this._requests)
935 request.screenshots.push(base64Data);
936 },
937
938 _stopScreencast: function()
939 {
940 if (!this._capturing)
941 return;
942
943 delete this._stopTimer;
944 delete this._endTime;
945 this._requests = [];
946 this._capturing = false;
947 this._target.pageAgent().stopScreencast();
948 }
949 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698