]> git.wh0rd.org Git - tt-rss.git/blob - lib/dojo/fx.js.uncompressed.js
update dojo to 1.7.3
[tt-rss.git] / lib / dojo / fx.js.uncompressed.js
1 define("dojo/fx", [
2         "./_base/lang",
3         "./Evented",
4         "./_base/kernel",
5         "./_base/array",
6         "./_base/connect",
7         "./_base/fx",
8         "./dom",
9         "./dom-style",
10         "./dom-geometry",
11         "./ready",
12         "require" // for context sensitive loading of Toggler
13 ], function(lang, Evented, dojo, arrayUtil, connect, baseFx, dom, domStyle, geom, ready, require) {
14
15         // module:
16         //              dojo/fx
17         // summary:
18         //              TODOC
19
20
21         /*=====
22         dojo.fx = {
23                 // summary: Effects library on top of Base animations
24         };
25         var coreFx = dojo.fx;
26         =====*/
27         
28 // For back-compat, remove in 2.0.
29 if(!dojo.isAsync){
30         ready(0, function(){
31                 var requires = ["./fx/Toggler"];
32                 require(requires);      // use indirection so modules not rolled into a build
33         });
34 }
35
36         var coreFx = dojo.fx = {};
37
38         var _baseObj = {
39                         _fire: function(evt, args){
40                                 if(this[evt]){
41                                         this[evt].apply(this, args||[]);
42                                 }
43                                 return this;
44                         }
45                 };
46
47         var _chain = function(animations){
48                 this._index = -1;
49                 this._animations = animations||[];
50                 this._current = this._onAnimateCtx = this._onEndCtx = null;
51
52                 this.duration = 0;
53                 arrayUtil.forEach(this._animations, function(a){
54                         this.duration += a.duration;
55                         if(a.delay){ this.duration += a.delay; }
56                 }, this);
57         };
58         _chain.prototype = new Evented();
59         lang.extend(_chain, {
60                 _onAnimate: function(){
61                         this._fire("onAnimate", arguments);
62                 },
63                 _onEnd: function(){
64                         connect.disconnect(this._onAnimateCtx);
65                         connect.disconnect(this._onEndCtx);
66                         this._onAnimateCtx = this._onEndCtx = null;
67                         if(this._index + 1 == this._animations.length){
68                                 this._fire("onEnd");
69                         }else{
70                                 // switch animations
71                                 this._current = this._animations[++this._index];
72                                 this._onAnimateCtx = connect.connect(this._current, "onAnimate", this, "_onAnimate");
73                                 this._onEndCtx = connect.connect(this._current, "onEnd", this, "_onEnd");
74                                 this._current.play(0, true);
75                         }
76                 },
77                 play: function(/*int?*/ delay, /*Boolean?*/ gotoStart){
78                         if(!this._current){ this._current = this._animations[this._index = 0]; }
79                         if(!gotoStart && this._current.status() == "playing"){ return this; }
80                         var beforeBegin = connect.connect(this._current, "beforeBegin", this, function(){
81                                         this._fire("beforeBegin");
82                                 }),
83                                 onBegin = connect.connect(this._current, "onBegin", this, function(arg){
84                                         this._fire("onBegin", arguments);
85                                 }),
86                                 onPlay = connect.connect(this._current, "onPlay", this, function(arg){
87                                         this._fire("onPlay", arguments);
88                                         connect.disconnect(beforeBegin);
89                                         connect.disconnect(onBegin);
90                                         connect.disconnect(onPlay);
91                                 });
92                         if(this._onAnimateCtx){
93                                 connect.disconnect(this._onAnimateCtx);
94                         }
95                         this._onAnimateCtx = connect.connect(this._current, "onAnimate", this, "_onAnimate");
96                         if(this._onEndCtx){
97                                 connect.disconnect(this._onEndCtx);
98                         }
99                         this._onEndCtx = connect.connect(this._current, "onEnd", this, "_onEnd");
100                         this._current.play.apply(this._current, arguments);
101                         return this;
102                 },
103                 pause: function(){
104                         if(this._current){
105                                 var e = connect.connect(this._current, "onPause", this, function(arg){
106                                                 this._fire("onPause", arguments);
107                                                 connect.disconnect(e);
108                                         });
109                                 this._current.pause();
110                         }
111                         return this;
112                 },
113                 gotoPercent: function(/*Decimal*/percent, /*Boolean?*/ andPlay){
114                         this.pause();
115                         var offset = this.duration * percent;
116                         this._current = null;
117                         arrayUtil.some(this._animations, function(a){
118                                 if(a.duration <= offset){
119                                         this._current = a;
120                                         return true;
121                                 }
122                                 offset -= a.duration;
123                                 return false;
124                         });
125                         if(this._current){
126                                 this._current.gotoPercent(offset / this._current.duration, andPlay);
127                         }
128                         return this;
129                 },
130                 stop: function(/*boolean?*/ gotoEnd){
131                         if(this._current){
132                                 if(gotoEnd){
133                                         for(; this._index + 1 < this._animations.length; ++this._index){
134                                                 this._animations[this._index].stop(true);
135                                         }
136                                         this._current = this._animations[this._index];
137                                 }
138                                 var e = connect.connect(this._current, "onStop", this, function(arg){
139                                                 this._fire("onStop", arguments);
140                                                 connect.disconnect(e);
141                                         });
142                                 this._current.stop();
143                         }
144                         return this;
145                 },
146                 status: function(){
147                         return this._current ? this._current.status() : "stopped";
148                 },
149                 destroy: function(){
150                         if(this._onAnimateCtx){ connect.disconnect(this._onAnimateCtx); }
151                         if(this._onEndCtx){ connect.disconnect(this._onEndCtx); }
152                 }
153         });
154         lang.extend(_chain, _baseObj);
155
156         coreFx.chain = /*===== dojo.fx.chain = =====*/ function(/*dojo.Animation[]*/ animations){
157                 // summary:
158                 //              Chain a list of `dojo.Animation`s to run in sequence
159                 //
160                 // description:
161                 //              Return a `dojo.Animation` which will play all passed
162                 //              `dojo.Animation` instances in sequence, firing its own
163                 //              synthesized events simulating a single animation. (eg:
164                 //              onEnd of this animation means the end of the chain,
165                 //              not the individual animations within)
166                 //
167                 // example:
168                 //      Once `node` is faded out, fade in `otherNode`
169                 //      |       dojo.fx.chain([
170                 //      |               dojo.fadeIn({ node:node }),
171                 //      |               dojo.fadeOut({ node:otherNode })
172                 //      |       ]).play();
173                 //
174                 return new _chain(animations); // dojo.Animation
175         };
176
177         var _combine = function(animations){
178                 this._animations = animations||[];
179                 this._connects = [];
180                 this._finished = 0;
181
182                 this.duration = 0;
183                 arrayUtil.forEach(animations, function(a){
184                         var duration = a.duration;
185                         if(a.delay){ duration += a.delay; }
186                         if(this.duration < duration){ this.duration = duration; }
187                         this._connects.push(connect.connect(a, "onEnd", this, "_onEnd"));
188                 }, this);
189
190                 this._pseudoAnimation = new baseFx.Animation({curve: [0, 1], duration: this.duration});
191                 var self = this;
192                 arrayUtil.forEach(["beforeBegin", "onBegin", "onPlay", "onAnimate", "onPause", "onStop", "onEnd"],
193                         function(evt){
194                                 self._connects.push(connect.connect(self._pseudoAnimation, evt,
195                                         function(){ self._fire(evt, arguments); }
196                                 ));
197                         }
198                 );
199         };
200         lang.extend(_combine, {
201                 _doAction: function(action, args){
202                         arrayUtil.forEach(this._animations, function(a){
203                                 a[action].apply(a, args);
204                         });
205                         return this;
206                 },
207                 _onEnd: function(){
208                         if(++this._finished > this._animations.length){
209                                 this._fire("onEnd");
210                         }
211                 },
212                 _call: function(action, args){
213                         var t = this._pseudoAnimation;
214                         t[action].apply(t, args);
215                 },
216                 play: function(/*int?*/ delay, /*Boolean?*/ gotoStart){
217                         this._finished = 0;
218                         this._doAction("play", arguments);
219                         this._call("play", arguments);
220                         return this;
221                 },
222                 pause: function(){
223                         this._doAction("pause", arguments);
224                         this._call("pause", arguments);
225                         return this;
226                 },
227                 gotoPercent: function(/*Decimal*/percent, /*Boolean?*/ andPlay){
228                         var ms = this.duration * percent;
229                         arrayUtil.forEach(this._animations, function(a){
230                                 a.gotoPercent(a.duration < ms ? 1 : (ms / a.duration), andPlay);
231                         });
232                         this._call("gotoPercent", arguments);
233                         return this;
234                 },
235                 stop: function(/*boolean?*/ gotoEnd){
236                         this._doAction("stop", arguments);
237                         this._call("stop", arguments);
238                         return this;
239                 },
240                 status: function(){
241                         return this._pseudoAnimation.status();
242                 },
243                 destroy: function(){
244                         arrayUtil.forEach(this._connects, connect.disconnect);
245                 }
246         });
247         lang.extend(_combine, _baseObj);
248
249         coreFx.combine = /*===== dojo.fx.combine = =====*/ function(/*dojo.Animation[]*/ animations){
250                 // summary:
251                 //              Combine a list of `dojo.Animation`s to run in parallel
252                 //
253                 // description:
254                 //              Combine an array of `dojo.Animation`s to run in parallel,
255                 //              providing a new `dojo.Animation` instance encompasing each
256                 //              animation, firing standard animation events.
257                 //
258                 // example:
259                 //      Fade out `node` while fading in `otherNode` simultaneously
260                 //      |       dojo.fx.combine([
261                 //      |               dojo.fadeIn({ node:node }),
262                 //      |               dojo.fadeOut({ node:otherNode })
263                 //      |       ]).play();
264                 //
265                 // example:
266                 //      When the longest animation ends, execute a function:
267                 //      |       var anim = dojo.fx.combine([
268                 //      |               dojo.fadeIn({ node: n, duration:700 }),
269                 //      |               dojo.fadeOut({ node: otherNode, duration: 300 })
270                 //      |       ]);
271                 //      |       dojo.connect(anim, "onEnd", function(){
272                 //      |               // overall animation is done.
273                 //      |       });
274                 //      |       anim.play(); // play the animation
275                 //
276                 return new _combine(animations); // dojo.Animation
277         };
278
279         coreFx.wipeIn = /*===== dojo.fx.wipeIn = =====*/ function(/*Object*/ args){
280                 // summary:
281                 //              Expand a node to it's natural height.
282                 //
283                 // description:
284                 //              Returns an animation that will expand the
285                 //              node defined in 'args' object from it's current height to
286                 //              it's natural height (with no scrollbar).
287                 //              Node must have no margin/border/padding.
288                 //
289                 // args: Object
290                 //              A hash-map of standard `dojo.Animation` constructor properties
291                 //              (such as easing: node: duration: and so on)
292                 //
293                 // example:
294                 //      |       dojo.fx.wipeIn({
295                 //      |               node:"someId"
296                 //      |       }).play()
297                 var node = args.node = dom.byId(args.node), s = node.style, o;
298
299                 var anim = baseFx.animateProperty(lang.mixin({
300                         properties: {
301                                 height: {
302                                         // wrapped in functions so we wait till the last second to query (in case value has changed)
303                                         start: function(){
304                                                 // start at current [computed] height, but use 1px rather than 0
305                                                 // because 0 causes IE to display the whole panel
306                                                 o = s.overflow;
307                                                 s.overflow = "hidden";
308                                                 if(s.visibility == "hidden" || s.display == "none"){
309                                                         s.height = "1px";
310                                                         s.display = "";
311                                                         s.visibility = "";
312                                                         return 1;
313                                                 }else{
314                                                         var height = domStyle.get(node, "height");
315                                                         return Math.max(height, 1);
316                                                 }
317                                         },
318                                         end: function(){
319                                                 return node.scrollHeight;
320                                         }
321                                 }
322                         }
323                 }, args));
324
325                 var fini = function(){
326                         s.height = "auto";
327                         s.overflow = o;
328                 };
329                 connect.connect(anim, "onStop", fini);
330                 connect.connect(anim, "onEnd", fini);
331
332                 return anim; // dojo.Animation
333         };
334
335         coreFx.wipeOut = /*===== dojo.fx.wipeOut = =====*/ function(/*Object*/ args){
336                 // summary:
337                 //              Shrink a node to nothing and hide it.
338                 //
339                 // description:
340                 //              Returns an animation that will shrink node defined in "args"
341                 //              from it's current height to 1px, and then hide it.
342                 //
343                 // args: Object
344                 //              A hash-map of standard `dojo.Animation` constructor properties
345                 //              (such as easing: node: duration: and so on)
346                 //
347                 // example:
348                 //      |       dojo.fx.wipeOut({ node:"someId" }).play()
349
350                 var node = args.node = dom.byId(args.node), s = node.style, o;
351
352                 var anim = baseFx.animateProperty(lang.mixin({
353                         properties: {
354                                 height: {
355                                         end: 1 // 0 causes IE to display the whole panel
356                                 }
357                         }
358                 }, args));
359
360                 connect.connect(anim, "beforeBegin", function(){
361                         o = s.overflow;
362                         s.overflow = "hidden";
363                         s.display = "";
364                 });
365                 var fini = function(){
366                         s.overflow = o;
367                         s.height = "auto";
368                         s.display = "none";
369                 };
370                 connect.connect(anim, "onStop", fini);
371                 connect.connect(anim, "onEnd", fini);
372
373                 return anim; // dojo.Animation
374         };
375
376         coreFx.slideTo = /*===== dojo.fx.slideTo = =====*/ function(/*Object*/ args){
377                 // summary:
378                 //              Slide a node to a new top/left position
379                 //
380                 // description:
381                 //              Returns an animation that will slide "node"
382                 //              defined in args Object from its current position to
383                 //              the position defined by (args.left, args.top).
384                 //
385                 // args: Object
386                 //              A hash-map of standard `dojo.Animation` constructor properties
387                 //              (such as easing: node: duration: and so on). Special args members
388                 //              are `top` and `left`, which indicate the new position to slide to.
389                 //
390                 // example:
391                 //      |       .slideTo({ node: node, left:"40", top:"50", units:"px" }).play()
392
393                 var node = args.node = dom.byId(args.node),
394                         top = null, left = null;
395
396                 var init = (function(n){
397                         return function(){
398                                 var cs = domStyle.getComputedStyle(n);
399                                 var pos = cs.position;
400                                 top = (pos == 'absolute' ? n.offsetTop : parseInt(cs.top) || 0);
401                                 left = (pos == 'absolute' ? n.offsetLeft : parseInt(cs.left) || 0);
402                                 if(pos != 'absolute' && pos != 'relative'){
403                                         var ret = geom.position(n, true);
404                                         top = ret.y;
405                                         left = ret.x;
406                                         n.style.position="absolute";
407                                         n.style.top=top+"px";
408                                         n.style.left=left+"px";
409                                 }
410                         };
411                 })(node);
412                 init();
413
414                 var anim = baseFx.animateProperty(lang.mixin({
415                         properties: {
416                                 top: args.top || 0,
417                                 left: args.left || 0
418                         }
419                 }, args));
420                 connect.connect(anim, "beforeBegin", anim, init);
421
422                 return anim; // dojo.Animation
423         };
424
425         return coreFx;
426 });