Revert of Roll src/third_party/WebKit e0eac24:489c548 (svn 193311:193320) (patchset...
[chromium-blink-merge.git] / third_party / web-animations-js / sources / src / web-animations-next-player.js
blob54d8f80574b7c25bc6825c8719f297d0c9367128
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 //     You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 //     See the License for the specific language governing permissions and
13 // limitations under the License.
15 (function(shared, scope, testing) {
16   scope.Player = function(source) {
17     this.source = source;
18     if (source) {
19       // FIXME: detach existing player.
20       source.player = this;
21     }
22     this._isGroup = false;
23     this._player = null;
24     this._childPlayers = [];
25     this._callback = null;
26     this._rebuildUnderlyingPlayer();
27     // Players are constructed in the idle state.
28     this._player.cancel();
29   };
31   // TODO: add a source getter/setter
32   scope.Player.prototype = {
33     _rebuildUnderlyingPlayer: function() {
34       if (this._player) {
35         this._player.cancel();
36         this._player = null;
37       }
39       if (!this.source || this.source instanceof window.Animation) {
40         this._player = scope.newUnderlyingPlayerForAnimation(this.source);
41         scope.bindPlayerForAnimation(this);
42       }
43       if (this.source instanceof window.AnimationSequence || this.source instanceof window.AnimationGroup) {
44         this._player = scope.newUnderlyingPlayerForGroup(this.source);
45         scope.bindPlayerForGroup(this);
46       }
48       // FIXME: move existing currentTime/startTime/playState to new player
49     },
50     get paused() {
51       return this._player.paused;
52     },
53     get playState() {
54       return this._player.playState;
55     },
56     get onfinish() {
57       return this._onfinish;
58     },
59     set onfinish(v) {
60       if (typeof v == 'function') {
61         this._onfinish = v;
62         this._player.onfinish = (function(e) {
63           e.target = this;
64           v.call(this, e);
65         }).bind(this);
66       } else {
67         this._player.onfinish = v;
68         this.onfinish = this._player.onfinish;
69       }
70     },
71     get currentTime() {
72       return this._player.currentTime;
73     },
74     set currentTime(v) {
75       this._player.currentTime = v;
76       this._register();
77       this._forEachChild(function(child, offset) {
78         child.currentTime = v - offset;
79       });
80     },
81     get startTime() {
82       return this._player.startTime;
83     },
84     set startTime(v) {
85       this._player.startTime = v;
86       this._register();
87       this._forEachChild(function(child, offset) {
88         child.startTime = v + offset;
89       });
90     },
91     get playbackRate() {
92       return this._player.playbackRate;
93     },
94     get finished() {
95       return this._player.finished;
96     },
97     play: function() {
98       this._player.play();
99       this._register();
100       scope.awaitStartTime(this);
101       this._forEachChild(function(child) {
102         var time = child.currentTime;
103         child.play();
104         child.currentTime = time;
105       });
106     },
107     pause: function() {
108       this._player.pause();
109       this._register();
110       this._forEachChild(function(child) {
111         child.pause();
112       });
113     },
114     finish: function() {
115       this._player.finish();
116       this._register();
117       // TODO: child players??
118     },
119     cancel: function() {
120       this._player.cancel();
121       this._register();
122       this._removePlayers();
123     },
124     reverse: function() {
125       this._player.reverse();
126       scope.awaitStartTime(this);
127       this._register();
128       this._forEachChild(function(child, offset) {
129         child.reverse();
130         child.startTime = this.startTime + offset * this.playbackRate;
131         child.currentTime = this.currentTime + offset * this.playbackRate;
132       });
133     },
134     addEventListener: function(type, handler) {
135       var wrapped = handler;
136       if (typeof handler == 'function') {
137         wrapped = (function(e) {
138           e.target = this;
139           handler.call(this, e);
140         }).bind(this);
141         handler._wrapper = wrapped;
142       }
143       this._player.addEventListener(type, wrapped);
144     },
145     removeEventListener: function(type, handler) {
146       this._player.removeEventListener(type, (handler && handler._wrapper) || handler);
147     },
148     _removePlayers: function() {
149       while (this._childPlayers.length)
150         this._childPlayers.pop().cancel();
151     },
152     _forEachChild: function(f) {
153       var offset = 0;
154       this._childPlayers.forEach(function(child) {
155         f.call(this, child, offset);
156         if (this.source instanceof window.AnimationSequence)
157           offset += child.source.activeDuration;
158       }.bind(this));
159     },
160   };
162 })(webAnimationsShared, webAnimationsNext, webAnimationsTesting);