aboutsummaryrefslogtreecommitdiff
path: root/includes/js/dojo/fx.js
diff options
context:
space:
mode:
Diffstat (limited to 'includes/js/dojo/fx.js')
-rw-r--r--includes/js/dojo/fx.js415
1 files changed, 415 insertions, 0 deletions
diff --git a/includes/js/dojo/fx.js b/includes/js/dojo/fx.js
new file mode 100644
index 0000000..1473531
--- /dev/null
+++ b/includes/js/dojo/fx.js
@@ -0,0 +1,415 @@
+if(!dojo._hasResource["dojo.fx"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.fx"] = true;
+dojo.provide("dojo.fx");
+dojo.provide("dojo.fx.Toggler");
+
+/*=====
+dojo.fx = {
+ // summary: Effects library on top of Base animations
+};
+=====*/
+
+(function(){
+ var _baseObj = {
+ _fire: function(evt, args){
+ if(this[evt]){
+ this[evt].apply(this, args||[]);
+ }
+ return this;
+ }
+ };
+
+ var _chain = function(animations){
+ this._index = -1;
+ this._animations = animations||[];
+ this._current = this._onAnimateCtx = this._onEndCtx = null;
+
+ this.duration = 0;
+ dojo.forEach(this._animations, function(a){
+ this.duration += a.duration;
+ if(a.delay){ this.duration += a.delay; }
+ }, this);
+ };
+ dojo.extend(_chain, {
+ _onAnimate: function(){
+ this._fire("onAnimate", arguments);
+ },
+ _onEnd: function(){
+ dojo.disconnect(this._onAnimateCtx);
+ dojo.disconnect(this._onEndCtx);
+ this._onAnimateCtx = this._onEndCtx = null;
+ if(this._index + 1 == this._animations.length){
+ this._fire("onEnd");
+ }else{
+ // switch animations
+ this._current = this._animations[++this._index];
+ this._onAnimateCtx = dojo.connect(this._current, "onAnimate", this, "_onAnimate");
+ this._onEndCtx = dojo.connect(this._current, "onEnd", this, "_onEnd");
+ this._current.play(0, true);
+ }
+ },
+ play: function(/*int?*/ delay, /*Boolean?*/ gotoStart){
+ if(!this._current){ this._current = this._animations[this._index = 0]; }
+ if(!gotoStart && this._current.status() == "playing"){ return this; }
+ var beforeBegin = dojo.connect(this._current, "beforeBegin", this, function(){
+ this._fire("beforeBegin");
+ }),
+ onBegin = dojo.connect(this._current, "onBegin", this, function(arg){
+ this._fire("onBegin", arguments);
+ }),
+ onPlay = dojo.connect(this._current, "onPlay", this, function(arg){
+ this._fire("onPlay", arguments);
+ dojo.disconnect(beforeBegin);
+ dojo.disconnect(onBegin);
+ dojo.disconnect(onPlay);
+ });
+ if(this._onAnimateCtx){
+ dojo.disconnect(this._onAnimateCtx);
+ }
+ this._onAnimateCtx = dojo.connect(this._current, "onAnimate", this, "_onAnimate");
+ if(this._onEndCtx){
+ dojo.disconnect(this._onEndCtx);
+ }
+ this._onEndCtx = dojo.connect(this._current, "onEnd", this, "_onEnd");
+ this._current.play.apply(this._current, arguments);
+ return this;
+ },
+ pause: function(){
+ if(this._current){
+ var e = dojo.connect(this._current, "onPause", this, function(arg){
+ this._fire("onPause", arguments);
+ dojo.disconnect(e);
+ });
+ this._current.pause();
+ }
+ return this;
+ },
+ gotoPercent: function(/*Decimal*/percent, /*Boolean?*/ andPlay){
+ this.pause();
+ var offset = this.duration * percent;
+ this._current = null;
+ dojo.some(this._animations, function(a){
+ if(a.duration <= offset){
+ this._current = a;
+ return true;
+ }
+ offset -= a.duration;
+ return false;
+ });
+ if(this._current){
+ this._current.gotoPercent(offset / _current.duration, andPlay);
+ }
+ return this;
+ },
+ stop: function(/*boolean?*/ gotoEnd){
+ if(this._current){
+ if(gotoEnd){
+ for(; this._index + 1 < this._animations.length; ++this._index){
+ this._animations[this._index].stop(true);
+ }
+ this._current = this._animations[this._index];
+ }
+ var e = dojo.connect(this._current, "onStop", this, function(arg){
+ this._fire("onStop", arguments);
+ dojo.disconnect(e);
+ });
+ this._current.stop();
+ }
+ return this;
+ },
+ status: function(){
+ return this._current ? this._current.status() : "stopped";
+ },
+ destroy: function(){
+ if(this._onAnimateCtx){ dojo.disconnect(this._onAnimateCtx); }
+ if(this._onEndCtx){ dojo.disconnect(this._onEndCtx); }
+ }
+ });
+ dojo.extend(_chain, _baseObj);
+
+ dojo.fx.chain = function(/*dojo._Animation[]*/ animations){
+ // summary: Chain a list of dojo._Animation s to run in sequence
+ // example:
+ // | dojo.fx.chain([
+ // | dojo.fadeIn({ node:node }),
+ // | dojo.fadeOut({ node:otherNode })
+ // | ]).play();
+ //
+ return new _chain(animations) // dojo._Animation
+ };
+
+ var _combine = function(animations){
+ this._animations = animations||[];
+ this._connects = [];
+ this._finished = 0;
+
+ this.duration = 0;
+ dojo.forEach(animations, function(a){
+ var duration = a.duration;
+ if(a.delay){ duration += a.delay; }
+ if(this.duration < duration){ this.duration = duration; }
+ this._connects.push(dojo.connect(a, "onEnd", this, "_onEnd"));
+ }, this);
+
+ this._pseudoAnimation = new dojo._Animation({curve: [0, 1], duration: this.duration});
+ dojo.forEach(["beforeBegin", "onBegin", "onPlay", "onAnimate", "onPause", "onStop"],
+ function(evt){
+ this._connects.push(dojo.connect(this._pseudoAnimation, evt, dojo.hitch(this, "_fire", evt)));
+ },
+ this
+ );
+ };
+ dojo.extend(_combine, {
+ _doAction: function(action, args){
+ dojo.forEach(this._animations, function(a){
+ a[action].apply(a, args);
+ });
+ return this;
+ },
+ _onEnd: function(){
+ if(++this._finished == this._animations.length){
+ this._fire("onEnd");
+ }
+ },
+ _call: function(action, args){
+ var t = this._pseudoAnimation;
+ t[action].apply(t, args);
+ },
+ play: function(/*int?*/ delay, /*Boolean?*/ gotoStart){
+ this._finished = 0;
+ this._doAction("play", arguments);
+ this._call("play", arguments);
+ return this;
+ },
+ pause: function(){
+ this._doAction("pause", arguments);
+ this._call("pause", arguments);
+ return this;
+ },
+ gotoPercent: function(/*Decimal*/percent, /*Boolean?*/ andPlay){
+ var ms = this.duration * percent;
+ dojo.forEach(this._animations, function(a){
+ a.gotoPercent(a.duration < ms ? 1 : (ms / a.duration), andPlay);
+ });
+ this._call("gotoProcent", arguments);
+ return this;
+ },
+ stop: function(/*boolean?*/ gotoEnd){
+ this._doAction("stop", arguments);
+ this._call("stop", arguments);
+ return this;
+ },
+ status: function(){
+ return this._pseudoAnimation.status();
+ },
+ destroy: function(){
+ dojo.forEach(this._connects, dojo.disconnect);
+ }
+ });
+ dojo.extend(_combine, _baseObj);
+
+ dojo.fx.combine = function(/*dojo._Animation[]*/ animations){
+ // summary: Combine a list of dojo._Animation s to run in parallel
+ // example:
+ // | dojo.fx.combine([
+ // | dojo.fadeIn({ node:node }),
+ // | dojo.fadeOut({ node:otherNode })
+ // | ]).play();
+ return new _combine(animations); // dojo._Animation
+ };
+})();
+
+dojo.declare("dojo.fx.Toggler", null, {
+ // summary:
+ // class constructor for an animation toggler. It accepts a packed
+ // set of arguments about what type of animation to use in each
+ // direction, duration, etc.
+ //
+ // example:
+ // | var t = new dojo.fx.Toggler({
+ // | node: "nodeId",
+ // | showDuration: 500,
+ // | // hideDuration will default to "200"
+ // | showFunc: dojo.wipeIn,
+ // | // hideFunc will default to "fadeOut"
+ // | });
+ // | t.show(100); // delay showing for 100ms
+ // | // ...time passes...
+ // | t.hide();
+
+ // FIXME: need a policy for where the toggler should "be" the next
+ // time show/hide are called if we're stopped somewhere in the
+ // middle.
+
+ constructor: function(args){
+ var _t = this;
+
+ dojo.mixin(_t, args);
+ _t.node = args.node;
+ _t._showArgs = dojo.mixin({}, args);
+ _t._showArgs.node = _t.node;
+ _t._showArgs.duration = _t.showDuration;
+ _t.showAnim = _t.showFunc(_t._showArgs);
+
+ _t._hideArgs = dojo.mixin({}, args);
+ _t._hideArgs.node = _t.node;
+ _t._hideArgs.duration = _t.hideDuration;
+ _t.hideAnim = _t.hideFunc(_t._hideArgs);
+
+ dojo.connect(_t.showAnim, "beforeBegin", dojo.hitch(_t.hideAnim, "stop", true));
+ dojo.connect(_t.hideAnim, "beforeBegin", dojo.hitch(_t.showAnim, "stop", true));
+ },
+
+ // node: DomNode
+ // the node to toggle
+ node: null,
+
+ // showFunc: Function
+ // The function that returns the dojo._Animation to show the node
+ showFunc: dojo.fadeIn,
+
+ // hideFunc: Function
+ // The function that returns the dojo._Animation to hide the node
+ hideFunc: dojo.fadeOut,
+
+ // showDuration:
+ // Time in milliseconds to run the show Animation
+ showDuration: 200,
+
+ // hideDuration:
+ // Time in milliseconds to run the hide Animation
+ hideDuration: 200,
+
+ /*=====
+ _showArgs: null,
+ _showAnim: null,
+
+ _hideArgs: null,
+ _hideAnim: null,
+
+ _isShowing: false,
+ _isHiding: false,
+ =====*/
+
+ show: function(delay){
+ // summary: Toggle the node to showing
+ return this.showAnim.play(delay || 0);
+ },
+
+ hide: function(delay){
+ // summary: Toggle the node to hidden
+ return this.hideAnim.play(delay || 0);
+ }
+});
+
+dojo.fx.wipeIn = function(/*Object*/ args){
+ // summary
+ // Returns an animation that will expand the
+ // node defined in 'args' object from it's current height to
+ // it's natural height (with no scrollbar).
+ // Node must have no margin/border/padding.
+ args.node = dojo.byId(args.node);
+ var node = args.node, s = node.style;
+
+ var anim = dojo.animateProperty(dojo.mixin({
+ properties: {
+ height: {
+ // wrapped in functions so we wait till the last second to query (in case value has changed)
+ start: function(){
+ // start at current [computed] height, but use 1px rather than 0
+ // because 0 causes IE to display the whole panel
+ s.overflow="hidden";
+ if(s.visibility=="hidden"||s.display=="none"){
+ s.height="1px";
+ s.display="";
+ s.visibility="";
+ return 1;
+ }else{
+ var height = dojo.style(node, "height");
+ return Math.max(height, 1);
+ }
+ },
+ end: function(){
+ return node.scrollHeight;
+ }
+ }
+ }
+ }, args));
+
+ dojo.connect(anim, "onEnd", function(){
+ s.height = "auto";
+ });
+
+ return anim; // dojo._Animation
+}
+
+dojo.fx.wipeOut = function(/*Object*/ args){
+ // summary
+ // Returns an animation that will shrink node defined in "args"
+ // from it's current height to 1px, and then hide it.
+ var node = args.node = dojo.byId(args.node);
+ var s = node.style;
+
+ var anim = dojo.animateProperty(dojo.mixin({
+ properties: {
+ height: {
+ end: 1 // 0 causes IE to display the whole panel
+ }
+ }
+ }, args));
+
+ dojo.connect(anim, "beforeBegin", function(){
+ s.overflow = "hidden";
+ s.display = "";
+ });
+ dojo.connect(anim, "onEnd", function(){
+ s.height = "auto";
+ s.display = "none";
+ });
+
+ return anim; // dojo._Animation
+}
+
+dojo.fx.slideTo = function(/*Object?*/ args){
+ // summary
+ // Returns an animation that will slide "node"
+ // defined in args Object from its current position to
+ // the position defined by (args.left, args.top).
+ // example:
+ // | dojo.fx.slideTo({ node: node, left:"40", top:"50", unit:"px" }).play()
+
+ var node = (args.node = dojo.byId(args.node));
+
+ var top = null;
+ var left = null;
+
+ var init = (function(n){
+ return function(){
+ var cs = dojo.getComputedStyle(n);
+ var pos = cs.position;
+ top = (pos == 'absolute' ? n.offsetTop : parseInt(cs.top) || 0);
+ left = (pos == 'absolute' ? n.offsetLeft : parseInt(cs.left) || 0);
+ if(pos != 'absolute' && pos != 'relative'){
+ var ret = dojo.coords(n, true);
+ top = ret.y;
+ left = ret.x;
+ n.style.position="absolute";
+ n.style.top=top+"px";
+ n.style.left=left+"px";
+ }
+ };
+ })(node);
+ init();
+
+ var anim = dojo.animateProperty(dojo.mixin({
+ properties: {
+ top: { end: args.top||0 },
+ left: { end: args.left||0 }
+ }
+ }, args));
+ dojo.connect(anim, "beforeBegin", anim, init);
+
+ return anim; // dojo._Animation
+}
+
+}