I've added the original patch to Trac #312:

http://trac.mochikit.com/ticket/312

New functionality in MochiKit.Visual is low priority right now, so I
moved it to version 1.5. I also think more generic helper functions
are needed to make new functions like these most compact and readable.
Perhaps the best ideas from MochiKit.Animator should be included?

Cheers,

/Per

On Tue, Jun 10, 2008 at 8:28 PM, Michael Bond <[EMAIL PROTECTED]> wrote:
>
> Ok, had a couple visual glitches that are now fixed with the patch
> below:
>
> 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,
> @@ -1666,6 +1670,452 @@
>     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,
> +        left: element.firstChild.style.left,
> +        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',
> +                left: '0px'
> +            });
> +            s.setStyle(effect.element.firstChild, {
> +                width: scaleMode.originalWidth,
> +                right: effect.dims[1]
> +            });
> +            d.makePositioned(effect.element);
> +            d.makePositioned(effect.element.firstChild);
> +        },
> +        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,
> +                left: originalStyle.left
> +            });
> +            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.slidePairLeft(elements, options);
> +        } else {
> +            return MochiKit.Visual.slidePairRight(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 +2445,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 [email protected]
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