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