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