Subversion Repositories Applications.papyrus

Rev

Rev 1987 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
        Copyright (c) 2004-2006, The Dojo Foundation
        All Rights Reserved.

        Licensed under the Academic Free License version 2.1 or above OR the
        modified BSD license. For more information on Dojo licensing, see:

                http://dojotoolkit.org/community/licensing.shtml
*/



dojo.provide("dojo.lfx.html");
dojo.require("dojo.gfx.color");
dojo.require("dojo.lfx.Animation");
dojo.require("dojo.lang.array");
dojo.require("dojo.html.display");
dojo.require("dojo.html.color");
dojo.require("dojo.html.layout");
dojo.lfx.html._byId = function (nodes) {
        if (!nodes) {
                return [];
        }
        if (dojo.lang.isArrayLike(nodes)) {
                if (!nodes.alreadyChecked) {
                        var n = [];
                        dojo.lang.forEach(nodes, function (node) {
                                n.push(dojo.byId(node));
                        });
                        n.alreadyChecked = true;
                        return n;
                } else {
                        return nodes;
                }
        } else {
                var n = [];
                n.push(dojo.byId(nodes));
                n.alreadyChecked = true;
                return n;
        }
};
dojo.lfx.html.propertyAnimation = function (nodes, propertyMap, duration, easing, handlers) {
        nodes = dojo.lfx.html._byId(nodes);
        var targs = {"propertyMap":propertyMap, "nodes":nodes, "duration":duration, "easing":easing || dojo.lfx.easeDefault};
        var setEmUp = function (args) {
                if (args.nodes.length == 1) {
                        var pm = args.propertyMap;
                        if (!dojo.lang.isArray(args.propertyMap)) {
                                var parr = [];
                                for (var pname in pm) {
                                        pm[pname].property = pname;
                                        parr.push(pm[pname]);
                                }
                                pm = args.propertyMap = parr;
                        }
                        dojo.lang.forEach(pm, function (prop) {
                                if (dj_undef("start", prop)) {
                                        if (prop.property != "opacity") {
                                                prop.start = parseInt(dojo.html.getComputedStyle(args.nodes[0], prop.property));
                                        } else {
                                                prop.start = dojo.html.getOpacity(args.nodes[0]);
                                        }
                                }
                        });
                }
        };
        var coordsAsInts = function (coords) {
                var cints = [];
                dojo.lang.forEach(coords, function (c) {
                        cints.push(Math.round(c));
                });
                return cints;
        };
        var setStyle = function (n, style) {
                n = dojo.byId(n);
                if (!n || !n.style) {
                        return;
                }
                for (var s in style) {
                        try {
                                if (s == "opacity") {
                                        dojo.html.setOpacity(n, style[s]);
                                } else {
                                        n.style[s] = style[s];
                                }
                        }
                        catch (e) {
                                dojo.debug(e);
                        }
                }
        };
        var propLine = function (properties) {
                this._properties = properties;
                this.diffs = new Array(properties.length);
                dojo.lang.forEach(properties, function (prop, i) {
                        if (dojo.lang.isFunction(prop.start)) {
                                prop.start = prop.start(prop, i);
                        }
                        if (dojo.lang.isFunction(prop.end)) {
                                prop.end = prop.end(prop, i);
                        }
                        if (dojo.lang.isArray(prop.start)) {
                                this.diffs[i] = null;
                        } else {
                                if (prop.start instanceof dojo.gfx.color.Color) {
                                        prop.startRgb = prop.start.toRgb();
                                        prop.endRgb = prop.end.toRgb();
                                } else {
                                        this.diffs[i] = prop.end - prop.start;
                                }
                        }
                }, this);
                this.getValue = function (n) {
                        var ret = {};
                        dojo.lang.forEach(this._properties, function (prop, i) {
                                var value = null;
                                if (dojo.lang.isArray(prop.start)) {
                                } else {
                                        if (prop.start instanceof dojo.gfx.color.Color) {
                                                value = (prop.units || "rgb") + "(";
                                                for (var j = 0; j < prop.startRgb.length; j++) {
                                                        value += Math.round(((prop.endRgb[j] - prop.startRgb[j]) * n) + prop.startRgb[j]) + (j < prop.startRgb.length - 1 ? "," : "");
                                                }
                                                value += ")";
                                        } else {
                                                value = ((this.diffs[i]) * n) + prop.start + (prop.property != "opacity" ? prop.units || "px" : "");
                                        }
                                }
                                ret[dojo.html.toCamelCase(prop.property)] = value;
                        }, this);
                        return ret;
                };
        };
        var anim = new dojo.lfx.Animation({beforeBegin:function () {
                setEmUp(targs);
                anim.curve = new propLine(targs.propertyMap);
        }, onAnimate:function (propValues) {
                dojo.lang.forEach(targs.nodes, function (node) {
                        setStyle(node, propValues);
                });
        }}, targs.duration, null, targs.easing);
        if (handlers) {
                for (var x in handlers) {
                        if (dojo.lang.isFunction(handlers[x])) {
                                anim.connect(x, anim, handlers[x]);
                        }
                }
        }
        return anim;
};
dojo.lfx.html._makeFadeable = function (nodes) {
        var makeFade = function (node) {
                if (dojo.render.html.ie) {
                        if ((node.style.zoom.length == 0) && (dojo.html.getStyle(node, "zoom") == "normal")) {
                                node.style.zoom = "1";
                        }
                        if ((node.style.width.length == 0) && (dojo.html.getStyle(node, "width") == "auto")) {
                                node.style.width = "auto";
                        }
                }
        };
        if (dojo.lang.isArrayLike(nodes)) {
                dojo.lang.forEach(nodes, makeFade);
        } else {
                makeFade(nodes);
        }
};
dojo.lfx.html.fade = function (nodes, values, duration, easing, callback) {
        nodes = dojo.lfx.html._byId(nodes);
        var props = {property:"opacity"};
        if (!dj_undef("start", values)) {
                props.start = values.start;
        } else {
                props.start = function () {
                        return dojo.html.getOpacity(nodes[0]);
                };
        }
        if (!dj_undef("end", values)) {
                props.end = values.end;
        } else {
                dojo.raise("dojo.lfx.html.fade needs an end value");
        }
        var anim = dojo.lfx.propertyAnimation(nodes, [props], duration, easing);
        anim.connect("beforeBegin", function () {
                dojo.lfx.html._makeFadeable(nodes);
        });
        if (callback) {
                anim.connect("onEnd", function () {
                        callback(nodes, anim);
                });
        }
        return anim;
};
dojo.lfx.html.fadeIn = function (nodes, duration, easing, callback) {
        return dojo.lfx.html.fade(nodes, {end:1}, duration, easing, callback);
};
dojo.lfx.html.fadeOut = function (nodes, duration, easing, callback) {
        return dojo.lfx.html.fade(nodes, {end:0}, duration, easing, callback);
};
dojo.lfx.html.fadeShow = function (nodes, duration, easing, callback) {
        nodes = dojo.lfx.html._byId(nodes);
        dojo.lang.forEach(nodes, function (node) {
                dojo.html.setOpacity(node, 0);
        });
        var anim = dojo.lfx.html.fadeIn(nodes, duration, easing, callback);
        anim.connect("beforeBegin", function () {
                if (dojo.lang.isArrayLike(nodes)) {
                        dojo.lang.forEach(nodes, dojo.html.show);
                } else {
                        dojo.html.show(nodes);
                }
        });
        return anim;
};
dojo.lfx.html.fadeHide = function (nodes, duration, easing, callback) {
        var anim = dojo.lfx.html.fadeOut(nodes, duration, easing, function () {
                if (dojo.lang.isArrayLike(nodes)) {
                        dojo.lang.forEach(nodes, dojo.html.hide);
                } else {
                        dojo.html.hide(nodes);
                }
                if (callback) {
                        callback(nodes, anim);
                }
        });
        return anim;
};
dojo.lfx.html.wipeIn = function (nodes, duration, easing, callback) {
        nodes = dojo.lfx.html._byId(nodes);
        var anims = [];
        dojo.lang.forEach(nodes, function (node) {
                var oprop = {};
                var origTop, origLeft, origPosition;
                with (node.style) {
                        origTop = top;
                        origLeft = left;
                        origPosition = position;
                        top = "-9999px";
                        left = "-9999px";
                        position = "absolute";
                        display = "";
                }
                var nodeHeight = dojo.html.getBorderBox(node).height;
                with (node.style) {
                        top = origTop;
                        left = origLeft;
                        position = origPosition;
                        display = "none";
                }
                var anim = dojo.lfx.propertyAnimation(node, {"height":{start:1, end:function () {
                        return nodeHeight;
                }}}, duration, easing);
                anim.connect("beforeBegin", function () {
                        oprop.overflow = node.style.overflow;
                        oprop.height = node.style.height;
                        with (node.style) {
                                overflow = "hidden";
                                height = "1px";
                        }
                        dojo.html.show(node);
                });
                anim.connect("onEnd", function () {
                        with (node.style) {
                                overflow = oprop.overflow;
                                height = oprop.height;
                        }
                        if (callback) {
                                callback(node, anim);
                        }
                });
                anims.push(anim);
        });
        return dojo.lfx.combine(anims);
};
dojo.lfx.html.wipeOut = function (nodes, duration, easing, callback) {
        nodes = dojo.lfx.html._byId(nodes);
        var anims = [];
        dojo.lang.forEach(nodes, function (node) {
                var oprop = {};
                var anim = dojo.lfx.propertyAnimation(node, {"height":{start:function () {
                        return dojo.html.getContentBox(node).height;
                }, end:1}}, duration, easing, {"beforeBegin":function () {
                        oprop.overflow = node.style.overflow;
                        oprop.height = node.style.height;
                        with (node.style) {
                                overflow = "hidden";
                        }
                        dojo.html.show(node);
                }, "onEnd":function () {
                        dojo.html.hide(node);
                        with (node.style) {
                                overflow = oprop.overflow;
                                height = oprop.height;
                        }
                        if (callback) {
                                callback(node, anim);
                        }
                }});
                anims.push(anim);
        });
        return dojo.lfx.combine(anims);
};
dojo.lfx.html.slideTo = function (nodes, coords, duration, easing, callback) {
        nodes = dojo.lfx.html._byId(nodes);
        var anims = [];
        var compute = dojo.html.getComputedStyle;
        if (dojo.lang.isArray(coords)) {
                dojo.deprecated("dojo.lfx.html.slideTo(node, array)", "use dojo.lfx.html.slideTo(node, {top: value, left: value});", "0.5");
                coords = {top:coords[0], left:coords[1]};
        }
        dojo.lang.forEach(nodes, function (node) {
                var top = null;
                var left = null;
                var init = (function () {
                        var innerNode = node;
                        return function () {
                                var pos = compute(innerNode, "position");
                                top = (pos == "absolute" ? node.offsetTop : parseInt(compute(node, "top")) || 0);
                                left = (pos == "absolute" ? node.offsetLeft : parseInt(compute(node, "left")) || 0);
                                if (!dojo.lang.inArray(["absolute", "relative"], pos)) {
                                        var ret = dojo.html.abs(innerNode, true);
                                        dojo.html.setStyleAttributes(innerNode, "position:absolute;top:" + ret.y + "px;left:" + ret.x + "px;");
                                        top = ret.y;
                                        left = ret.x;
                                }
                        };
                })();
                init();
                var anim = dojo.lfx.propertyAnimation(node, {"top":{start:top, end:(coords.top || 0)}, "left":{start:left, end:(coords.left || 0)}}, duration, easing, {"beforeBegin":init});
                if (callback) {
                        anim.connect("onEnd", function () {
                                callback(nodes, anim);
                        });
                }
                anims.push(anim);
        });
        return dojo.lfx.combine(anims);
};
dojo.lfx.html.slideBy = function (nodes, coords, duration, easing, callback) {
        nodes = dojo.lfx.html._byId(nodes);
        var anims = [];
        var compute = dojo.html.getComputedStyle;
        if (dojo.lang.isArray(coords)) {
                dojo.deprecated("dojo.lfx.html.slideBy(node, array)", "use dojo.lfx.html.slideBy(node, {top: value, left: value});", "0.5");
                coords = {top:coords[0], left:coords[1]};
        }
        dojo.lang.forEach(nodes, function (node) {
                var top = null;
                var left = null;
                var init = (function () {
                        var innerNode = node;
                        return function () {
                                var pos = compute(innerNode, "position");
                                top = (pos == "absolute" ? node.offsetTop : parseInt(compute(node, "top")) || 0);
                                left = (pos == "absolute" ? node.offsetLeft : parseInt(compute(node, "left")) || 0);
                                if (!dojo.lang.inArray(["absolute", "relative"], pos)) {
                                        var ret = dojo.html.abs(innerNode, true);
                                        dojo.html.setStyleAttributes(innerNode, "position:absolute;top:" + ret.y + "px;left:" + ret.x + "px;");
                                        top = ret.y;
                                        left = ret.x;
                                }
                        };
                })();
                init();
                var anim = dojo.lfx.propertyAnimation(node, {"top":{start:top, end:top + (coords.top || 0)}, "left":{start:left, end:left + (coords.left || 0)}}, duration, easing).connect("beforeBegin", init);
                if (callback) {
                        anim.connect("onEnd", function () {
                                callback(nodes, anim);
                        });
                }
                anims.push(anim);
        });
        return dojo.lfx.combine(anims);
};
dojo.lfx.html.explode = function (start, endNode, duration, easing, callback) {
        var h = dojo.html;
        start = dojo.byId(start);
        endNode = dojo.byId(endNode);
        var startCoords = h.toCoordinateObject(start, true);
        var outline = document.createElement("div");
        h.copyStyle(outline, endNode);
        if (endNode.explodeClassName) {
                outline.className = endNode.explodeClassName;
        }
        with (outline.style) {
                position = "absolute";
                display = "none";
                var backgroundStyle = h.getStyle(start, "background-color");
                backgroundColor = backgroundStyle ? backgroundStyle.toLowerCase() : "transparent";
                backgroundColor = (backgroundColor == "transparent") ? "rgb(221, 221, 221)" : backgroundColor;
        }
        dojo.body().appendChild(outline);
        with (endNode.style) {
                visibility = "hidden";
                display = "block";
        }
        var endCoords = h.toCoordinateObject(endNode, true);
        with (endNode.style) {
                display = "none";
                visibility = "visible";
        }
        var props = {opacity:{start:0.5, end:1}};
        dojo.lang.forEach(["height", "width", "top", "left"], function (type) {
                props[type] = {start:startCoords[type], end:endCoords[type]};
        });
        var anim = new dojo.lfx.propertyAnimation(outline, props, duration, easing, {"beforeBegin":function () {
                h.setDisplay(outline, "block");
        }, "onEnd":function () {
                h.setDisplay(endNode, "block");
                outline.parentNode.removeChild(outline);
        }});
        if (callback) {
                anim.connect("onEnd", function () {
                        callback(endNode, anim);
                });
        }
        return anim;
};
dojo.lfx.html.implode = function (startNode, end, duration, easing, callback) {
        var h = dojo.html;
        startNode = dojo.byId(startNode);
        end = dojo.byId(end);
        var startCoords = dojo.html.toCoordinateObject(startNode, true);
        var endCoords = dojo.html.toCoordinateObject(end, true);
        var outline = document.createElement("div");
        dojo.html.copyStyle(outline, startNode);
        if (startNode.explodeClassName) {
                outline.className = startNode.explodeClassName;
        }
        dojo.html.setOpacity(outline, 0.3);
        with (outline.style) {
                position = "absolute";
                display = "none";
                backgroundColor = h.getStyle(startNode, "background-color").toLowerCase();
        }
        dojo.body().appendChild(outline);
        var props = {opacity:{start:1, end:0.5}};
        dojo.lang.forEach(["height", "width", "top", "left"], function (type) {
                props[type] = {start:startCoords[type], end:endCoords[type]};
        });
        var anim = new dojo.lfx.propertyAnimation(outline, props, duration, easing, {"beforeBegin":function () {
                dojo.html.hide(startNode);
                dojo.html.show(outline);
        }, "onEnd":function () {
                outline.parentNode.removeChild(outline);
        }});
        if (callback) {
                anim.connect("onEnd", function () {
                        callback(startNode, anim);
                });
        }
        return anim;
};
dojo.lfx.html.highlight = function (nodes, startColor, duration, easing, callback) {
        nodes = dojo.lfx.html._byId(nodes);
        var anims = [];
        dojo.lang.forEach(nodes, function (node) {
                var color = dojo.html.getBackgroundColor(node);
                var bg = dojo.html.getStyle(node, "background-color").toLowerCase();
                var bgImage = dojo.html.getStyle(node, "background-image");
                var wasTransparent = (bg == "transparent" || bg == "rgba(0, 0, 0, 0)");
                while (color.length > 3) {
                        color.pop();
                }
                var rgb = new dojo.gfx.color.Color(startColor);
                var endRgb = new dojo.gfx.color.Color(color);
                var anim = dojo.lfx.propertyAnimation(node, {"background-color":{start:rgb, end:endRgb}}, duration, easing, {"beforeBegin":function () {
                        if (bgImage) {
                                node.style.backgroundImage = "none";
                        }
                        node.style.backgroundColor = "rgb(" + rgb.toRgb().join(",") + ")";
                }, "onEnd":function () {
                        if (bgImage) {
                                node.style.backgroundImage = bgImage;
                        }
                        if (wasTransparent) {
                                node.style.backgroundColor = "transparent";
                        }
                        if (callback) {
                                callback(node, anim);
                        }
                }});
                anims.push(anim);
        });
        return dojo.lfx.combine(anims);
};
dojo.lfx.html.unhighlight = function (nodes, endColor, duration, easing, callback) {
        nodes = dojo.lfx.html._byId(nodes);
        var anims = [];
        dojo.lang.forEach(nodes, function (node) {
                var color = new dojo.gfx.color.Color(dojo.html.getBackgroundColor(node));
                var rgb = new dojo.gfx.color.Color(endColor);
                var bgImage = dojo.html.getStyle(node, "background-image");
                var anim = dojo.lfx.propertyAnimation(node, {"background-color":{start:color, end:rgb}}, duration, easing, {"beforeBegin":function () {
                        if (bgImage) {
                                node.style.backgroundImage = "none";
                        }
                        node.style.backgroundColor = "rgb(" + color.toRgb().join(",") + ")";
                }, "onEnd":function () {
                        if (callback) {
                                callback(node, anim);
                        }
                }});
                anims.push(anim);
        });
        return dojo.lfx.combine(anims);
};
dojo.lang.mixin(dojo.lfx, dojo.lfx.html);