Below are the diffs from Visual.js which include four new functions
for sliding elements on/off to the left/right and two for sliding
pairs of elements together, one on and one off, and one for sliding
pairs of elements in a direction relative to their position in the
DOM.

The diffs also include the changes I discussed in my previous post
about issues with slideDown and blindDown.

I have tested these on divs whose width are 100% of the browser window
on both Firefox 3rc2 and Safari 3.1.1. I have not tested with any
variation of IE. I also have not tested with divs with a smaller than
100% width though there's nothing to suggest it won't work right.

Index: Visual.js
===================================================================
--- Visual.js   (revision 1383)
+++ Visual.js   (working copy)
@@ -1431,14 +1431,16 @@
         scaleContent: false,
         scaleX: false,
         scaleFrom: 0,
-        scaleMode: {originalHeight: s.getElementHeight(element),
-            originalWidth: s.getElementWidth(element)},
         restoreAfterFinish: true,
-        afterSetupInternal: function (effect) {
+        beforeSetupInternal: function (effect) {
             elemClip = d.makeClipping(effect.element);
-            s.setStyle(effect.element, {height: '0px'});
             s.showElement(effect.element);
+            effect.options.scaleMode = {originalHeight:
s.getElementHeight(element),
+                originalWidth: s.getElementWidth(element)};
         },
+        afterSetupInternal: function (effect) {
+            s.setStyle(effect.element, {height: '0px'});
+        },
         afterFinishInternal: function (effect) {
             d.undoClipping(effect.element, elemClip);
         }
@@ -1582,18 +1584,20 @@
         scaleContent: false,
         scaleX: false,
         scaleFrom: 0,
-        scaleMode: {originalHeight: s.getElementHeight(element),
-            originalWidth: s.getElementWidth(element)},
         restoreAfterFinish: true,
+        beforeSetupInternal: function (effect) {
+            elemClip = d.makeClipping(effect.element);
+            s.showElement(effect.element);
+            scaleMode = {originalHeight: s.getElementHeight(element),
+                originalWidth: s.getElementWidth(element)};
+        },
         afterSetupInternal: function (effect) {
             d.makePositioned(effect.element);
             d.makePositioned(effect.element.firstChild);
             if (/Opera/.test(navigator.userAgent)) {
                 s.setStyle(effect.element, {top: ''});
             }
-            elemClip = d.makeClipping(effect.element);
             s.setStyle(effect.element, {height: '0px'});
-            s.showElement(effect.element);
         },
         afterUpdateInternal: function (effect) {
             s.setStyle(effect.element.firstChild,
@@ -1665,7 +1669,450 @@
     }, options);
     return new MochiKit.Visual.Scale(element, 0, options);
 };
+/** @id MochiKit.Visual.slideOnLeft */
+MochiKit.Visual.slideOnLeft = function (element, /* optional */
options) {
+    /***

+    Slide an element on moving from right to left.
+    It must have a single inner child to work correctly
+
+    ***/
+    if (!element.hasChildNodes()) {
+        throw "MochiKit.Visual.slideOnLeft must be used on a element
with a child";
+    }
+    var d = MochiKit.DOM;
+    var b = MochiKit.Base;
+    var s = MochiKit.Style;
+    var elemClip;
+    element = d.getElement(element);
+    d.removeEmptyTextNodes(element);
+
+    /* don't want s.getElementWidth/Height, want the raw values for
full restore */
+    var originalStyle = {
+        height: element.style.height,
+        width: element.style.width,
+        left: element.style.left,
+        innerWidth: element.firstChild.style.width
+    };
+
+    options = b.update({
+        scaleContent: false,
+        scaleY: false,
+        scaleFrom: 0,
+        restoreAfterFinish: true,
+        beforeSetupInternal: function (effect) {
+            elemClip = d.makeClipping(effect.element);
+            s.showElement(effect.element);
+            scaleMode = {
+                originalHeight: s.getElementHeight(effect.element),
+                originalWidth: s.getElementWidth(effect.element)
+            };
+        },
+        afterSetupInternal: function (effect) {
+            s.setStyle(effect.element, {
+                width: '0px',
+                left: effect.dims[1]
+            });
+            s.setStyle(effect.element.firstChild, {
+                width: scaleMode.originalWidth
+            });
+            d.makePositioned(effect.element);
+            d.makePositioned(effect.element.firstChild);
+            if (/Opera/.test(navigator.userAgent)) {
+                s.setStyle(effect.element, {left: ''});
+            }
+        },
+        afterUpdateInternal: function (effect) {
+            s.setStyle(effect.element, {
+               left: (effect.dims[1] -
s.getElementWidth(effect.element)) + 'px'
+            });
+        },
+        afterFinishInternal: function (effect) {
+            d.undoClipping(effect.element, elemClip);
+            // IE will crash if child is undoPositioned first
+            if (/MSIE/.test(navigator.userAgent)) {
+                d.undoPositioned(effect.element);
+                d.undoPositioned(effect.element.firstChild);
+            } else {
+                d.undoPositioned(effect.element.firstChild);
+                d.undoPositioned(effect.element);
+            }
+            s.setStyle(effect.element, {
+                height: originalStyle.height,
+                width: originalStyle.width,
+                left: originalStyle.left
+            });
+            s.setStyle(effect.element.firstChild, {
+                width: originalStyle.innerWidth
+            });
+        }
+    }, options);
+
+    return new MochiKit.Visual.Scale(element, 100, options);
+}
+
+/** @id MochiKit.Visual.slideOnRight */
+MochiKit.Visual.slideOnRight = function (element, /* optional */
options) {
+    /***
+
+    Slide an element on moving from left to right.
+    It must have a single inner child to work correctly
+
+    ***/
+    if (!element.hasChildNodes()) {
+        throw "MochiKit.Visual.slideOnRight must be used on a element
with a child";
+    }
+    var d = MochiKit.DOM;
+    var b = MochiKit.Base;
+    var s = MochiKit.Style;
+    var elemClip;
+    element = d.getElement(element);
+    d.removeEmptyTextNodes(element);
+
+    /* don't want s.getElementWidth/Height, want the raw values for
full restore */
+    var originalStyle = {
+        height: element.style.height,
+        width: element.style.width,
+        innerRight: element.firstChild.style.right,
+        innerWidth: element.firstChild.style.width
+    };
+
+    options = b.update({
+        scaleContent: false,
+        scaleY: false,
+        scaleFrom: 0,
+        restoreAfterFinish: true,
+        beforeSetupInternal: function (effect) {
+            elemClip = d.makeClipping(effect.element);
+            s.showElement(effect.element);
+            scaleMode = {
+                originalHeight: s.getElementHeight(effect.element),
+                originalWidth: s.getElementWidth(effect.element)
+            };
+        },
+        afterSetupInternal: function (effect) {
+            s.setStyle(effect.element, {width: '0px'});
+            s.setStyle(effect.element.firstChild, {
+                width: scaleMode.originalWidth,
+                right: effect.dims[1]
+            });
+            d.makePositioned(effect.element);
+            d.makePositioned(effect.element.firstChild);
+            if (/Opera/.test(navigator.userAgent)) {
+                s.setStyle(effect.element, {left: ''});
+            }
+        },
+        afterUpdateInternal: function (effect) {
+            s.setStyle(effect.element.firstChild, {
+               right: (effect.dims[1] -
s.getElementWidth(effect.element)) + 'px'
+            });
+        },
+        afterFinishInternal: function (effect) {
+            d.undoClipping(effect.element, elemClip);
+            // IE will crash if child is undoPositioned first
+            if (/MSIE/.test(navigator.userAgent)) {
+                d.undoPositioned(effect.element);
+                d.undoPositioned(effect.element.firstChild);
+            } else {
+                d.undoPositioned(effect.element.firstChild);
+                d.undoPositioned(effect.element);
+            }
+            s.setStyle(effect.element, {
+                height: originalStyle.height,
+                width: originalStyle.width
+            });
+            s.setStyle(effect.element.firstChild, {
+                right: originalStyle.innerRight,
+                width: originalStyle.innerWidth
+            });
+        }
+    }, options);
+
+    return new MochiKit.Visual.Scale(element, 100, options);
+}
+
+/** @id MochiKit.Visual.slideOffLeft */
+MochiKit.Visual.slideOffLeft = function (element, /* optional */
options) {
+    /***
+
+    Slide an element off moving from right to left.
+    It must have a single inner child to work correctly
+
+    ***/
+    if (!element.hasChildNodes()) {
+        throw "MochiKit.Visual.slideOffLeft must be used on a element
with a child";
+    }
+    var d = MochiKit.DOM;
+    var b = MochiKit.Base;
+    var s = MochiKit.Style;
+    var elemClip;
+    element = d.getElement(element);
+    d.removeEmptyTextNodes(element);
+
+    /* don't want s.getElementWidth/Height, want the raw values for
full restore */
+    var originalStyle = {
+        height: element.style.height,
+        width: element.style.width,
+        right: element.style.right,
+        left: element.style.left,
+        innerRight: element.firstChild.style.right
+    };
+
+    options = b.update({
+        scaleContent: false,
+        scaleY: false,
+        scaleFrom: 100,
+        restoreAfterFinish: true,
+        beforeSetupInternal: function (effect) {
+            elemClip = d.makeClipping(effect.element);
+            s.showElement(effect.element);
+            scaleMode = {
+                originalHeight: s.getElementHeight(effect.element),
+                originalWidth: s.getElementWidth(effect.element),
+            };
+        },
+        afterSetupInternal: function (effect) {
+            s.setStyle(effect.element, {left: '0px'});
+            s.setStyle(effect.element.firstChild, {width:
scaleMode.originalWidth});
+            d.makePositioned(effect.element);
+            d.makePositioned(effect.element.firstChild);
+            if (/Opera/.test(navigator.userAgent)) {
+                s.setStyle(effect.element, {right: ''});
+            }
+        },
+        afterUpdateInternal: function (effect) {
+            s.setStyle(effect.element.firstChild, {
+               right: (effect.dims[1] -
s.getElementWidth(effect.element)) + 'px'
+            });
+        },
+        afterFinishInternal: function (effect) {
+            s.hideElement(effect.element);
+            d.undoClipping(effect.element, elemClip);
+            d.undoPositioned(effect.element.firstChild);
+            d.undoPositioned(effect.element);
+            s.setStyle(effect.element, {
+                width: originalStyle.width,
+                height: originalStyle.height,
+                right: originalStyle.right,
+                left: originalStyle.left
+            });
+            s.setStyle(effect.element.firstChild, {
+                right: originalStyle.innerRight
+            });
+        }
+    }, options);
+    return new MochiKit.Visual.Scale(element, 0, options);
+};
+
+/** @id MochiKit.Visual.slideOffRight */
+MochiKit.Visual.slideOffRight = function (element, /* optional */
options) {
+    /***
+
+    Slide an element off moving from left to right.
+    It must have a single inner child to work correctly
+
+    ***/
+    if (!element.hasChildNodes()) {
+        throw "MochiKit.Visual.slideOffRight must be used on a
element with a child";
+    }
+    var d = MochiKit.DOM;
+    var b = MochiKit.Base;
+    var s = MochiKit.Style;
+    var elemClip;
+    element = d.getElement(element);
+    d.removeEmptyTextNodes(element);
+
+    /* don't want s.getElementWidth/Height, want the raw values for
full restore */
+    var originalStyle = {
+        height: element.style.height,
+        width: element.style.width,
+        right: element.style.right,
+        left: element.style.left,
+        innerWidth: element.firstChild.style.width
+    };
+
+    options = b.update({
+        scaleContent: false,
+        scaleY: false,
+        scaleFrom: 100,
+        restoreAfterFinish: true,
+        beforeSetupInternal: function (effect) {
+            elemClip = d.makeClipping(effect.element);
+            s.showElement(effect.element);
+            scaleMode = {
+                originalHeight: s.getElementHeight(effect.element),
+                originalWidth: s.getElementWidth(effect.element),
+            };
+        },
+        afterSetupInternal: function (effect) {
+            s.setStyle(effect.element, {left: '0px'});
+            s.setStyle(effect.element.firstChild, {width:
scaleMode.originalWidth});
+            d.makePositioned(effect.element);
+            d.makePositioned(effect.element.firstChild);
+            if (/Opera/.test(navigator.userAgent)) {
+                s.setStyle(effect.element, {right: ''});
+            }
+        },
+        afterUpdateInternal: function (effect) {
+            s.setStyle(effect.element, {
+               left: (effect.dims[1] -
s.getElementWidth(effect.element)) + 'px'
+            });
+        },
+        afterFinishInternal: function (effect) {
+            s.hideElement(effect.element);
+            d.undoClipping(effect.element, elemClip);
+            d.undoPositioned(effect.element.firstChild);
+            d.undoPositioned(effect.element);
+            s.setStyle(effect.element, {
+                width: originalStyle.width,
+                height: originalStyle.height,
+                right: originalStyle.right,
+                left: originalStyle.left
+            });
+            s.setStyle(effect.element.firstChild, {
+                width: originalStyle.innerWidth
+            });
+        }
+    }, options);
+    return new MochiKit.Visual.Scale(element, 0, options);
+};
+
+/** @id MochiKit.Visual.slidePairLeft */
+MochiKit.Visual.slidePairLeft = function (elements, /* optional */
options) {
+    /***
+
+    Slide the first element off and the second element off from right
to left.
+
+    ***/
+    if (elements[0] != elements[1]) {
+        var d = MochiKit.DOM;
+        var b = MochiKit.Base;
+        var s = MochiKit.Style;
+        var v = MochiKit.Visual;
+        elements = [d.getElement(elements[0]),
d.getElement(elements[1])];
+        var parent = elements[1].parentNode;
+        var originalStyle = {
+            position: [
+                elements[0].style.position,
+                elements[1].style.position
+            ],
+            parentWidth: parent.style.width,
+            parentHeight: parent.style.height
+        };
+        options = b.update({
+            beforeSetupInternal: function (effect) {
+            },
+            afterSetupInternal: function (effect) {
+                s.setStyle(effect.effects[0].element.parentNode, {
+                    width:
Math.max(s.getElementWidth(effect.effects[0].element),
+
s.getElementWidth(effect.effects[1].element)),
+                    height:
Math.max(s.getElementHeight(effect.effects[0].element),
+
s.getElementHeight(effect.effects[1].element))
+                });
+                s.setStyle(effect.effects[0].element, {position:
'absolute'});
+                s.setStyle(effect.effects[1].element, {position:
'absolute'});
+            },
+            afterFinishInternal: function (effect) {
+                s.setStyle(effect.effects[0].element, {
+                    position: originalStyle.position[0]
+                });
+                s.setStyle(effect.effects[1].element, {
+                    position: originalStyle.position[1]
+                });
+                s.setStyle(parent, {
+                    width: originalStyle.parentWidth,
+                    height: originalStyle.parentHeight
+                });
+            }
+        }, options);
+        return new v.Parallel(
+            [v.slideOffLeft(elements[0]),
v.slideOnLeft(elements[1])],
+            options);
+    } else {
+        return null;
+    }
+}
+
+/** @id MochiKit.Visual.slidePairRight */
+MochiKit.Visual.slidePairRight = function (elements, /* optional */
options) {
+    /***
+
+    Slide the first element off and the second element off from left
to right.
+
+    ***/
+    if (elements[0] != elements[1]) {
+        var d = MochiKit.DOM;
+        var b = MochiKit.Base;
+        var s = MochiKit.Style;
+        elements = [d.getElement(elements[0]),
d.getElement(elements[1])];
+        var parent = elements[1].parentNode;
+        var originalStyle = {
+            position: [
+                elements[0].style.position,
+                elements[1].style.position
+            ],
+            parentWidth: parent.style.width,
+            parentHeight: parent.style.height
+        };
+        options = b.update({
+            beforeSetupInternal: function (effect) {
+            },
+            afterSetupInternal: function (effect) {
+                s.setStyle(effect.effects[0].element.parentNode, {
+                    width:
Math.max(s.getElementWidth(effect.effects[0].element),
+
s.getElementWidth(effect.effects[1].element)),
+                    height:
Math.max(s.getElementHeight(effect.effects[0].element),
+
s.getElementHeight(effect.effects[1].element))
+                });
+                s.setStyle(effect.effects[0].element, {position:
'absolute'});
+                s.setStyle(effect.effects[1].element, {position:
'absolute'});
+            },
+            afterFinishInternal: function (effect) {
+                s.setStyle(effect.effects[0].element, {
+                    position: originalStyle.position[0]
+                });
+                s.setStyle(effect.effects[1].element, {
+                    position: originalStyle.position[1]
+                });
+                s.setStyle(parent, {
+                    width: originalStyle.parentWidth,
+                    height: originalStyle.parentHeight
+                });
+            }
+        }, options);
+        return new MochiKit.Visual.Parallel(
+            [slideOffRight(elements[0]), slideOnRight(elements[1])],
+            options);
+    } else {
+        return null;
+    }
+}
+
+/** @id MochiKit.Visual.slidePairRight */
+MochiKit.Visual.slidePair = function (elements, /* optional */
options) {
+    /***
+
+    Slide the first element on and the second element off. Direction
is based
+    on relative position of the two elements in the child node list.
It assumes
+    both are siblings.
+
+    ***/
+    if (elements[0] != elements[1]) {
+        for (sibling = elements[0].nextSibling;
+            sibling && sibling != elements[1];
+            sibling = sibling.nextSibling) {
+        }
+        if (sibling == elements[1]) {
+            return MochiKit.Visual.slidePairRight(elements, options);
+        } else {
+            return MochiKit.Visual.slidePairLeft(elements, options);
+        }
+    } else {
+        return null;
+    }
+}
+
+
 // Bug in opera makes the TD containing this element expand for a
instance
 // after finish
 /** @id MochiKit.Visual.squish */
@@ -1995,6 +2442,13 @@
     "shake",
     "slideDown",
     "slideUp",
+    "slideOnLeft",
+    "slideOnRight",
+    "slideOffLeft",
+    "slideOffRight",
+    "slidePairLeft",
+    "slidePairRight",
+    "slidePair",
     "squish",
     "grow",
     "shrink",

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"MochiKit" group.
To post to this group, send email to mochikit@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/mochikit?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to