aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tests/unit/accordion/accordion_defaults.js2
-rw-r--r--tests/unit/accordion/accordion_defaults_deprecated.js1
-rw-r--r--tests/unit/accordion/accordion_test_helpers.js6
-rw-r--r--ui/jquery.ui.accordion.js267
4 files changed, 112 insertions, 164 deletions
diff --git a/tests/unit/accordion/accordion_defaults.js b/tests/unit/accordion/accordion_defaults.js
index 9aa58e650..9ad85bbce 100644
--- a/tests/unit/accordion/accordion_defaults.js
+++ b/tests/unit/accordion/accordion_defaults.js
@@ -1,7 +1,7 @@
commonWidgetTests( "accordion", {
defaults: {
active: 0,
- animated: "slide",
+ animate: {},
collapsible: false,
disabled: false,
event: "click",
diff --git a/tests/unit/accordion/accordion_defaults_deprecated.js b/tests/unit/accordion/accordion_defaults_deprecated.js
index 3f45a1f10..99f5ac827 100644
--- a/tests/unit/accordion/accordion_defaults_deprecated.js
+++ b/tests/unit/accordion/accordion_defaults_deprecated.js
@@ -1,6 +1,7 @@
commonWidgetTests( "accordion", {
defaults: {
active: 0,
+ animate: null,
animated: "slide",
autoHeight: true,
clearStyle: false,
diff --git a/tests/unit/accordion/accordion_test_helpers.js b/tests/unit/accordion/accordion_test_helpers.js
index 66d60a469..7b316e983 100644
--- a/tests/unit/accordion/accordion_test_helpers.js
+++ b/tests/unit/accordion/accordion_test_helpers.js
@@ -18,13 +18,13 @@ function accordion_equalHeights( accordion, min, max ) {
}
function accordion_setupTeardown() {
- var animated = $.ui.accordion.prototype.options.animated;
+ var animate = $.ui.accordion.prototype.options.animate;
return {
setup: function() {
- $.ui.accordion.prototype.options.animated = false;
+ $.ui.accordion.prototype.options.animate = false;
},
teardown: function() {
- $.ui.accordion.prototype.options.animated = animated;
+ $.ui.accordion.prototype.options.animate = animate;
}
};
}
diff --git a/ui/jquery.ui.accordion.js b/ui/jquery.ui.accordion.js
index c56f3cbbf..8731c17ca 100644
--- a/ui/jquery.ui.accordion.js
+++ b/ui/jquery.ui.accordion.js
@@ -17,7 +17,7 @@ $.widget( "ui.accordion", {
version: "@VERSION",
options: {
active: 0,
- animated: "slide",
+ animate: {},
collapsible: false,
event: "click",
header: "> li > :first-child,> :not(li):even",
@@ -35,7 +35,7 @@ $.widget( "ui.accordion", {
_create: function() {
var options = this.options;
- this.lastToggle = {};
+ this.prevShow = this.prevHide = $();
this.element.addClass( "ui-accordion ui-widget ui-helper-reset" );
this.headers = this.element.find( options.header )
@@ -62,6 +62,7 @@ $.widget( "ui.accordion", {
this.active.next().addClass( "ui-accordion-content-active" );
this._createIcons();
+ this.originalHeight = this.element[0].style.height;
this.refresh();
// ARIA
@@ -156,6 +157,7 @@ $.widget( "ui.accordion", {
.removeAttr( "role" )
.removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled" );
if ( this.options.heightStyle !== "content" ) {
+ this.element.css( "height", this.originalHeight );
contents.css( "height", "" );
}
},
@@ -229,12 +231,12 @@ $.widget( "ui.accordion", {
},
refresh: function() {
- var options = this.options,
+ var heightStyle = this.options.heightStyle,
parent = this.element.parent(),
maxHeight,
overflow;
- if ( options.heightStyle === "fill" ) {
+ if ( heightStyle === "fill" ) {
// IE 6 treats height like minHeight, so we need to turn off overflow
// in order to get a reliable height
// we use the minHeight support test because we assume that only
@@ -267,7 +269,7 @@ $.widget( "ui.accordion", {
$( this ).innerHeight() + $( this ).height() ) );
})
.css( "overflow", "auto" );
- } else if ( options.heightStyle === "auto" ) {
+ } else if ( heightStyle === "auto" ) {
maxHeight = 0;
this.headers.next()
.each(function() {
@@ -276,7 +278,9 @@ $.widget( "ui.accordion", {
.height( maxHeight );
}
- return this;
+ if ( heightStyle !== "content" ) {
+ this.element.height( this.element.height() );
+ }
},
_activate: function( index ) {
@@ -361,41 +365,20 @@ $.widget( "ui.accordion", {
},
_toggle: function( data ) {
- var that = this,
- options = this.options,
- toShow = data.newContent,
- toHide = data.oldContent;
-
- function complete() {
- that._completed( data );
- }
+ var toShow = data.newContent,
+ toHide = this.prevShow.length ? this.prevShow : data.oldContent;
- if ( options.animated ) {
- var animations = $.ui.accordion.animations,
- animation = options.animated,
- additional;
-
- if ( !animations[ animation ] ) {
- additional = {
- easing: $.easing[ animation ] ? animation : "slide",
- duration: 700
- };
- animation = "slide";
- }
+ // handle activating a panel during the animation for another activation
+ this.prevShow.add( this.prevHide ).stop( true, true );
+ this.prevShow = toShow;
+ this.prevHide = toHide;
- animations[ animation ]({
- widget: this,
- toShow: toShow,
- toHide: toHide,
- prevShow: this.lastToggle.toShow,
- prevHide: this.lastToggle.toHide,
- complete: complete,
- down: toShow.length && ( !toHide.length || ( toShow.index() < toHide.index() ) )
- }, additional );
+ if ( this.options.animate ) {
+ this._animate( toShow, toHide, data );
} else {
toHide.hide();
toShow.show();
- complete();
+ this._completed( data );
}
// TODO assert that the blur and focus triggers are really necessary, remove otherwise
@@ -415,17 +398,51 @@ $.widget( "ui.accordion", {
.focus();
},
+ _animate: function( toShow, toHide, data ) {
+ var total, easing, duration,
+ that = this,
+ down = toShow.length &&
+ ( !toHide.length || ( toShow.index() < toHide.index() ) ),
+ animate = this.options.animate || {},
+ options = down && animate.down || animate,
+ complete = function() {
+ toShow.removeData( "accordionHeight" );
+ that._completed( data );
+ };
+
+ if ( typeof options === "number" ) {
+ duration = options;
+ }
+ if ( typeof options === "string" ) {
+ easing = options;
+ }
+ // fall back from options to animation in case of partial down settings
+ easing = easing || options.easing || animate.easing;
+ duration = duration || options.duration || animate.duration;
+
+ if ( !toHide.size() ) {
+ return toShow.animate( showProps, duration, easing, complete );
+ }
+ if ( !toShow.size() ) {
+ return toHide.animate( hideProps, duration, easing, complete );
+ }
+
+ total = toShow.show().outerHeight();
+ toHide.animate( hideProps, duration, easing );
+ toShow
+ .hide()
+ .data( "accordionHeight", {
+ total: total,
+ toHide: toHide
+ })
+ .animate( this.options.heightStyle === "content" ? showProps : showPropsAdjust,
+ duration, easing, complete );
+ },
+
_completed: function( data ) {
var toShow = data.newContent,
toHide = data.oldContent;
- if ( this.options.heightStyle === "content" ) {
- toShow.add( toHide ).css({
- height: "",
- overflow: ""
- });
- }
-
// other classes are removed before the animation; this one needs to stay until completed
toHide.removeClass( "ui-accordion-content-active" );
// Work around for rendering bug in IE (#5421)
@@ -437,123 +454,19 @@ $.widget( "ui.accordion", {
}
});
-$.extend( $.ui.accordion, {
- animations: {
- slide: function( options, additions ) {
- if ( options.prevShow || options.prevHide ) {
- options.prevHide.stop( true, true );
- options.toHide = options.prevShow;
- }
-
- var showOverflow = options.toShow.css( "overflow" ),
- showOverflowX = options.toHide.css( "overflowX" ),
- showOverflowY = options.toHide.css( "overflowY" ),
- hideOverflow = options.toHide.css( "overflow" ),
- hideOverflowX = options.toHide.css( "overflowX" ),
- hideOverflowY = options.toHide.css( "overflowY" ),
- percentDone = 0,
- showProps = {},
- hideProps = {},
- fxAttrs = [ "height", "paddingTop", "paddingBottom" ],
- originalWidth;
- options = $.extend({
- easing: "swing",
- duration: 300
- }, options, additions );
-
- options.widget.lastToggle = options;
-
- if ( !options.toHide.size() ) {
- originalWidth = options.toShow[0].style.width;
- options.toShow
- .show()
- .width( options.toShow.width() )
- .hide()
- .animate({
- height: "show",
- paddingTop: "show",
- paddingBottom: "show"
- }, {
- duration: options.duration,
- easing: options.easing,
- complete: function() {
- options.toShow.width( originalWidth );
- options.complete();
- }
- });
- return;
- }
- if ( !options.toShow.size() ) {
- options.toHide.animate({
- height: "hide",
- paddingTop: "hide",
- paddingBottom: "hide"
- }, options );
- return;
- }
- // fix width before calculating height of hidden element
- var s = options.toShow;
- originalWidth = s[0].style.width;
- s.width( s.parent().width()
- - parseFloat( s.css( "paddingLeft" ) )
- - parseFloat( s.css( "paddingRight" ) )
- - ( parseFloat( s.css( "borderLeftWidth" ) ) || 0 )
- - ( parseFloat( s.css( "borderRightWidth" ) ) || 0 ) );
-
- $.each( fxAttrs, function( i, prop ) {
- hideProps[ prop ] = "hide";
-
- var parts = ( "" + $.css( options.toShow[0], prop ) ).match( /^([\d+-.]+)(.*)$/ ),
- // work around bug when a panel has no height - #7335
- propVal = prop === "height" && parts[ 1 ] === "0" ? 1 : parts[ 1 ];
- showProps[ prop ] = {
- value: propVal,
- unit: parts[ 2 ] || "px"
- };
- });
- options.toShow.css({ height: 0, overflow: "hidden" }).show();
- options.toHide
- .filter( ":hidden" )
- .each( options.complete )
- .end()
- .filter( ":visible" )
- .animate( hideProps, {
- step: function( now, settings ) {
- if ( settings.prop == "height" || settings.prop == "paddingTop" || settings.prop == "paddingBottom" ) {
- percentDone = ( settings.end - settings.start === 0 ) ? 0 :
- ( settings.now - settings.start ) / ( settings.end - settings.start );
- }
-
- options.toShow[ 0 ].style[ settings.prop ] =
- ( percentDone * showProps[ settings.prop ].value )
- + showProps[ settings.prop ].unit;
- },
- duration: options.duration,
- easing: options.easing,
- complete: function() {
- options.toShow.css({
- width: originalWidth,
- overflow: showOverflow,
- overflowX: showOverflowX,
- overflowY: showOverflowY
- });
- options.toHide.css({
- overflow: hideOverflow,
- overflowX: hideOverflowX,
- overflowY: hideOverflowY
- });
- options.complete();
- }
- });
- },
- bounceslide: function( options ) {
- this.slide( options, {
- easing: options.down ? "easeOutBounce" : "swing",
- duration: options.down ? 1000 : 200
- });
- }
- }
-});
+$.fx.step.accordionHeight = function( fx ) {
+ var elem = $( fx.elem ),
+ data = elem.data( "accordionHeight" );
+ elem.height( data.total - elem.outerHeight() - data.toHide.outerHeight() + elem.height() );
+};
+var hideProps = {},
+ showProps = {},
+ showPropsAdjust = {};
+hideProps.height = hideProps.paddingTop = hideProps.paddingBottom =
+ hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide";
+showProps.height = showProps.paddingTop = showProps.paddingBottom =
+ showProps.borderTopWidth = showProps.borderBottomWidth = "show";
+$.extend( showPropsAdjust, showProps, { accordionHeight: "show" } );
@@ -697,6 +610,40 @@ if ( $.uiBackCompat !== false ) {
return ret;
};
}( jQuery, jQuery.ui.accordion.prototype ) );
+
+ // animated option
+ // NOTE: this only provides support for "slide", "bounceslide", and easings
+ // not the full $.ui.accordion.animations API
+ (function( $, prototype ) {
+ $.extend( prototype.options, {
+ animate: null,
+ animated: "slide"
+ });
+
+ var _create = prototype._create;
+ prototype._create = function() {
+ var options = this.options;
+ if ( options.animate === null ) {
+ if ( !options.animated ) {
+ options.animate = false;
+ } else if ( options.animated === "slide" ) {
+ options.animate = 300;
+ } else if ( options.animated === "bounceslide" ) {
+ options.animate = {
+ duration: 200,
+ down: {
+ easing: "easeOutBounce",
+ duration: 1000
+ }
+ }
+ } else {
+ options.animate = options.animated;
+ }
+ }
+
+ _create.call( this );
+ };
+ }( jQuery, jQuery.ui.accordion.prototype ) );
}
})( jQuery );