diff options
author | Timo Tijhof <krinklemail@gmail.com> | 2014-06-05 00:20:47 +0200 |
---|---|---|
committer | Timo Tijhof <krinklemail@gmail.com> | 2014-06-05 00:29:23 +0200 |
commit | 3cb2ccd87863abb8a99ed7d970730ae9e4138fcc (patch) | |
tree | e0b2c7d4592f748c1e9f2c8210de97a44a491860 /resources/lib/jquery.ui/jquery.ui.accordion.js | |
parent | 966c249fb32b9f49e11bce31f71f02d5d5273c00 (diff) | |
download | mediawikicore-3cb2ccd87863abb8a99ed7d970730ae9e4138fcc.tar.gz mediawikicore-3cb2ccd87863abb8a99ed7d970730ae9e4138fcc.zip |
Upgrade jQuery UI from 1.8.24 to 1.9.2
jQuery UI 1.10 has already been released, and 1.11 is on the
horizon (1.9 is marked "legacy" as of writing). 1.10 drops the
compatibility layer for 1.8 API. So, users should definitely be
encouraged to upgrade their code to move away from the deprecated
1.8 APIs. However, to take it one step at a time, this commit
upgrades us to 1.9 first. That way we're at least not using an
unsupported code base anymore, while at the same time not rolling
out breaking changes.
jQuery UI has redesigned many of its APIs[1], but compatibility
with the jQuery UI 1.8 API is maintained throughout 1.9.x.
* Base theme is now called "Smoothness".
* Sorting the entries in Resources.php alphabetically to make it
easier to ensure all files are listed when comparing them
side-by-side.
* Update dependencies to match the "Depends:" header inside
the javascript files.
* In jQuery UI 1.9, effect files were renamed to match the
jquery.ui.*.js naming pattern.
* New modules:
- jquery.ui.menu
- jquery.ui.spinner
- jquery.ui.tooltip
* Release notes:
- http://blog.jqueryui.com/2012/10/jquery-ui-1-9-0/
- http://jqueryui.com/upgrade-guide/1.9/
- http://jqueryui.com/changelog/1.9.0/
- http://blog.jqueryui.com/2012/10/jquery-ui-1-9-1/
- http://jqueryui.com/changelog/1.9.1/
- http://blog.jqueryui.com/2012/11/jquery-ui-1-9-2/
[1] http://blog.jqueryui.com/2011/03/api-redesigns-the-past-present-and-future/
Bug: 47076
Change-Id: I0e10b42fb7c25b9d4704719f21c44c08f36ddfa7
Diffstat (limited to 'resources/lib/jquery.ui/jquery.ui.accordion.js')
-rw-r--r-- | resources/lib/jquery.ui/jquery.ui.accordion.js | 954 |
1 files changed, 537 insertions, 417 deletions
diff --git a/resources/lib/jquery.ui/jquery.ui.accordion.js b/resources/lib/jquery.ui/jquery.ui.accordion.js index dc1ba60aa4ef..55bbecba59db 100644 --- a/resources/lib/jquery.ui/jquery.ui.accordion.js +++ b/resources/lib/jquery.ui/jquery.ui.accordion.js @@ -1,11 +1,12 @@ /*! - * jQuery UI Accordion 1.8.24 + * jQuery UI Accordion 1.9.2 + * http://jqueryui.com * - * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. * http://jquery.org/license * - * http://docs.jquery.com/UI/Accordion + * http://api.jqueryui.com/accordion/ * * Depends: * jquery.ui.core.js @@ -13,207 +14,231 @@ */ (function( $, undefined ) { +var uid = 0, + hideProps = {}, + showProps = {}; + +hideProps.height = hideProps.paddingTop = hideProps.paddingBottom = + hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide"; +showProps.height = showProps.paddingTop = showProps.paddingBottom = + showProps.borderTopWidth = showProps.borderBottomWidth = "show"; + $.widget( "ui.accordion", { + version: "1.9.2", options: { active: 0, - animated: "slide", - autoHeight: true, - clearStyle: false, + animate: {}, collapsible: false, event: "click", - fillSpace: false, header: "> li > :first-child,> :not(li):even", + heightStyle: "auto", icons: { - header: "ui-icon-triangle-1-e", - headerSelected: "ui-icon-triangle-1-s" + activeHeader: "ui-icon-triangle-1-s", + header: "ui-icon-triangle-1-e" }, - navigation: false, - navigationFilter: function() { - return this.href.toLowerCase() === location.href.toLowerCase(); - } + + // callbacks + activate: null, + beforeActivate: null }, _create: function() { - var self = this, - options = self.options; - - self.running = 0; - - self.element - .addClass( "ui-accordion ui-widget ui-helper-reset" ) - // in lack of child-selectors in CSS - // we need to mark top-LIs in a UL-accordion for some IE-fix - .children( "li" ) - .addClass( "ui-accordion-li-fix" ); - - self.headers = self.element.find( options.header ) - .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" ) - .bind( "mouseenter.accordion", function() { - if ( options.disabled ) { - return; - } - $( this ).addClass( "ui-state-hover" ); - }) - .bind( "mouseleave.accordion", function() { - if ( options.disabled ) { - return; - } - $( this ).removeClass( "ui-state-hover" ); - }) - .bind( "focus.accordion", function() { - if ( options.disabled ) { - return; - } - $( this ).addClass( "ui-state-focus" ); - }) - .bind( "blur.accordion", function() { - if ( options.disabled ) { - return; - } - $( this ).removeClass( "ui-state-focus" ); - }); + var accordionId = this.accordionId = "ui-accordion-" + + (this.element.attr( "id" ) || ++uid), + options = this.options; - self.headers.next() - .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" ); + this.prevShow = this.prevHide = $(); + this.element.addClass( "ui-accordion ui-widget ui-helper-reset" ); - if ( options.navigation ) { - var current = self.element.find( "a" ).filter( options.navigationFilter ).eq( 0 ); - if ( current.length ) { - var header = current.closest( ".ui-accordion-header" ); - if ( header.length ) { - // anchor within header - self.active = header; - } else { - // anchor within content - self.active = current.closest( ".ui-accordion-content" ).prev(); - } - } + this.headers = this.element.find( options.header ) + .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" ); + this._hoverable( this.headers ); + this._focusable( this.headers ); + + this.headers.next() + .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" ) + .hide(); + + // don't allow collapsible: false and active: false / null + if ( !options.collapsible && (options.active === false || options.active == null) ) { + options.active = 0; + } + // handle negative values + if ( options.active < 0 ) { + options.active += this.headers.length; } + this.active = this._findActive( options.active ) + .addClass( "ui-accordion-header-active ui-state-active" ) + .toggleClass( "ui-corner-all ui-corner-top" ); + this.active.next() + .addClass( "ui-accordion-content-active" ) + .show(); - self.active = self._findActive( self.active || options.active ) - .addClass( "ui-state-default ui-state-active" ) - .toggleClass( "ui-corner-all" ) - .toggleClass( "ui-corner-top" ); - self.active.next().addClass( "ui-accordion-content-active" ); + this._createIcons(); + this.refresh(); - self._createIcons(); - self.resize(); - // ARIA - self.element.attr( "role", "tablist" ); + this.element.attr( "role", "tablist" ); - self.headers + this.headers .attr( "role", "tab" ) - .bind( "keydown.accordion", function( event ) { - return self._keydown( event ); + .each(function( i ) { + var header = $( this ), + headerId = header.attr( "id" ), + panel = header.next(), + panelId = panel.attr( "id" ); + if ( !headerId ) { + headerId = accordionId + "-header-" + i; + header.attr( "id", headerId ); + } + if ( !panelId ) { + panelId = accordionId + "-panel-" + i; + panel.attr( "id", panelId ); + } + header.attr( "aria-controls", panelId ); + panel.attr( "aria-labelledby", headerId ); }) .next() .attr( "role", "tabpanel" ); - self.headers - .not( self.active || "" ) + this.headers + .not( this.active ) .attr({ - "aria-expanded": "false", "aria-selected": "false", tabIndex: -1 }) .next() + .attr({ + "aria-expanded": "false", + "aria-hidden": "true" + }) .hide(); // make sure at least one header is in the tab order - if ( !self.active.length ) { - self.headers.eq( 0 ).attr( "tabIndex", 0 ); + if ( !this.active.length ) { + this.headers.eq( 0 ).attr( "tabIndex", 0 ); } else { - self.active + this.active.attr({ + "aria-selected": "true", + tabIndex: 0 + }) + .next() .attr({ "aria-expanded": "true", - "aria-selected": "true", - tabIndex: 0 + "aria-hidden": "false" }); } - // only need links in tab order for Safari - if ( !$.browser.safari ) { - self.headers.find( "a" ).attr( "tabIndex", -1 ); - } + this._on( this.headers, { keydown: "_keydown" }); + this._on( this.headers.next(), { keydown: "_panelKeyDown" }); + this._setupEvents( options.event ); + }, - if ( options.event ) { - self.headers.bind( options.event.split(" ").join(".accordion ") + ".accordion", function(event) { - self._clickHandler.call( self, event, this ); - event.preventDefault(); - }); - } + _getCreateEventData: function() { + return { + header: this.active, + content: !this.active.length ? $() : this.active.next() + }; }, _createIcons: function() { - var options = this.options; - if ( options.icons ) { - $( "<span></span>" ) - .addClass( "ui-icon " + options.icons.header ) + var icons = this.options.icons; + if ( icons ) { + $( "<span>" ) + .addClass( "ui-accordion-header-icon ui-icon " + icons.header ) .prependTo( this.headers ); - this.active.children( ".ui-icon" ) - .toggleClass(options.icons.header) - .toggleClass(options.icons.headerSelected); - this.element.addClass( "ui-accordion-icons" ); + this.active.children( ".ui-accordion-header-icon" ) + .removeClass( icons.header ) + .addClass( icons.activeHeader ); + this.headers.addClass( "ui-accordion-icons" ); } }, _destroyIcons: function() { - this.headers.children( ".ui-icon" ).remove(); - this.element.removeClass( "ui-accordion-icons" ); + this.headers + .removeClass( "ui-accordion-icons" ) + .children( ".ui-accordion-header-icon" ) + .remove(); }, - destroy: function() { - var options = this.options; + _destroy: function() { + var contents; + // clean up main element this.element .removeClass( "ui-accordion ui-widget ui-helper-reset" ) .removeAttr( "role" ); + // clean up headers this.headers - .unbind( ".accordion" ) - .removeClass( "ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" ) + .removeClass( "ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" ) .removeAttr( "role" ) - .removeAttr( "aria-expanded" ) .removeAttr( "aria-selected" ) - .removeAttr( "tabIndex" ); - - this.headers.find( "a" ).removeAttr( "tabIndex" ); + .removeAttr( "aria-controls" ) + .removeAttr( "tabIndex" ) + .each(function() { + if ( /^ui-accordion/.test( this.id ) ) { + this.removeAttribute( "id" ); + } + }); this._destroyIcons(); - var contents = this.headers.next() + + // clean up content panels + contents = this.headers.next() .css( "display", "" ) .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 ( options.autoHeight || options.fillHeight ) { + .removeAttr( "aria-expanded" ) + .removeAttr( "aria-hidden" ) + .removeAttr( "aria-labelledby" ) + .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" ) + .each(function() { + if ( /^ui-accordion/.test( this.id ) ) { + this.removeAttribute( "id" ); + } + }); + if ( this.options.heightStyle !== "content" ) { contents.css( "height", "" ); } - - return $.Widget.prototype.destroy.call( this ); }, _setOption: function( key, value ) { - $.Widget.prototype._setOption.apply( this, arguments ); - - if ( key == "active" ) { - this.activate( value ); + if ( key === "active" ) { + // _activate() will handle invalid values and update this.options + this._activate( value ); + return; + } + + if ( key === "event" ) { + if ( this.options.event ) { + this._off( this.headers, this.options.event ); + } + this._setupEvents( value ); + } + + this._super( key, value ); + + // setting collapsible: false while collapsed; open first panel + if ( key === "collapsible" && !value && this.options.active === false ) { + this._activate( 0 ); } - if ( key == "icons" ) { + + if ( key === "icons" ) { this._destroyIcons(); if ( value ) { this._createIcons(); } } + // #5332 - opacity doesn't cascade to positioned elements in IE // so we need to add the disabled class to the headers and panels - if ( key == "disabled" ) { - this.headers.add(this.headers.next()) - [ value ? "addClass" : "removeClass" ]( - "ui-accordion-disabled ui-state-disabled" ); + if ( key === "disabled" ) { + this.headers.add( this.headers.next() ) + .toggleClass( "ui-state-disabled", !!value ); } }, _keydown: function( event ) { - if ( this.options.disabled || event.altKey || event.ctrlKey ) { + if ( event.altKey || event.ctrlKey ) { return; } @@ -233,32 +258,57 @@ $.widget( "ui.accordion", { break; case keyCode.SPACE: case keyCode.ENTER: - this._clickHandler( { target: event.target }, event.target ); - event.preventDefault(); + this._eventHandler( event ); + break; + case keyCode.HOME: + toFocus = this.headers[ 0 ]; + break; + case keyCode.END: + toFocus = this.headers[ length - 1 ]; + break; } if ( toFocus ) { $( event.target ).attr( "tabIndex", -1 ); $( toFocus ).attr( "tabIndex", 0 ); toFocus.focus(); - return false; + event.preventDefault(); } + }, - return true; + _panelKeyDown : function( event ) { + if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { + $( event.currentTarget ).prev().focus(); + } }, - resize: function() { - var options = this.options, - maxHeight; + refresh: function() { + var maxHeight, overflow, + heightStyle = this.options.heightStyle, + parent = this.element.parent(); + - if ( options.fillSpace ) { - if ( $.browser.msie ) { - var defOverflow = this.element.parent().css( "overflow" ); - this.element.parent().css( "overflow", "hidden"); + 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 + // browsers that don't support minHeight will treat height as minHeight + if ( !$.support.minHeight ) { + overflow = parent.css( "overflow" ); + parent.css( "overflow", "hidden"); } - maxHeight = this.element.parent().height(); - if ($.browser.msie) { - this.element.parent().css( "overflow", defOverflow ); + maxHeight = parent.height(); + this.element.siblings( ":visible" ).each(function() { + var elem = $( this ), + position = elem.css( "position" ); + + if ( position === "absolute" || position === "fixed" ) { + return; + } + maxHeight -= elem.outerHeight( true ); + }); + if ( overflow ) { + parent.css( "overflow", overflow ); } this.headers.each(function() { @@ -271,341 +321,411 @@ $.widget( "ui.accordion", { $( this ).innerHeight() + $( this ).height() ) ); }) .css( "overflow", "auto" ); - } else if ( options.autoHeight ) { + } else if ( heightStyle === "auto" ) { maxHeight = 0; this.headers.next() .each(function() { - maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); + maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); }) .height( maxHeight ); } - - return this; }, - activate: function( index ) { - // TODO this gets called on init, changing the option without an explicit call for that - this.options.active = index; - // call clickHandler with custom event + _activate: function( index ) { var active = this._findActive( index )[ 0 ]; - this._clickHandler( { target: active }, active ); - return this; + // trying to activate the already active panel + if ( active === this.active[ 0 ] ) { + return; + } + + // trying to collapse, simulate a click on the currently active header + active = active || this.active[ 0 ]; + + this._eventHandler({ + target: active, + currentTarget: active, + preventDefault: $.noop + }); }, _findActive: function( selector ) { - return selector - ? typeof selector === "number" - ? this.headers.filter( ":eq(" + selector + ")" ) - : this.headers.not( this.headers.not( selector ) ) - : selector === false - ? $( [] ) - : this.headers.filter( ":eq(0)" ); + return typeof selector === "number" ? this.headers.eq( selector ) : $(); }, - // TODO isn't event.target enough? why the separate target argument? - _clickHandler: function( event, target ) { - var options = this.options; - if ( options.disabled ) { - return; - } - - // called only when using activate(false) to close all parts programmatically - if ( !event.target ) { - if ( !options.collapsible ) { - return; - } - this.active - .removeClass( "ui-state-active ui-corner-top" ) - .addClass( "ui-state-default ui-corner-all" ) - .children( ".ui-icon" ) - .removeClass( options.icons.headerSelected ) - .addClass( options.icons.header ); - this.active.next().addClass( "ui-accordion-content-active" ); - var toHide = this.active.next(), - data = { - options: options, - newHeader: $( [] ), - oldHeader: options.active, - newContent: $( [] ), - oldContent: toHide - }, - toShow = ( this.active = $( [] ) ); - this._toggle( toShow, toHide, data ); + _setupEvents: function( event ) { + var events = {}; + if ( !event ) { return; } + $.each( event.split(" "), function( index, eventName ) { + events[ eventName ] = "_eventHandler"; + }); + this._on( this.headers, events ); + }, - // get the click target - var clicked = $( event.currentTarget || target ), - clickedIsActive = clicked[0] === this.active[0]; - - // TODO the option is changed, is that correct? - // TODO if it is correct, shouldn't that happen after determining that the click is valid? - options.active = options.collapsible && clickedIsActive ? - false : - this.headers.index( clicked ); - - // if animations are still active, or the active header is the target, ignore click - if ( this.running || ( !options.collapsible && clickedIsActive ) ) { + _eventHandler: function( event ) { + var options = this.options, + active = this.active, + clicked = $( event.currentTarget ), + clickedIsActive = clicked[ 0 ] === active[ 0 ], + collapsing = clickedIsActive && options.collapsible, + toShow = collapsing ? $() : clicked.next(), + toHide = active.next(), + eventData = { + oldHeader: active, + oldPanel: toHide, + newHeader: collapsing ? $() : clicked, + newPanel: toShow + }; + + event.preventDefault(); + + if ( + // click on active header, but not collapsible + ( clickedIsActive && !options.collapsible ) || + // allow canceling activation + ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { return; } - // find elements to show and hide - var active = this.active, - toShow = clicked.next(), - toHide = this.active.next(), - data = { - options: options, - newHeader: clickedIsActive && options.collapsible ? $([]) : clicked, - oldHeader: this.active, - newContent: clickedIsActive && options.collapsible ? $([]) : toShow, - oldContent: toHide - }, - down = this.headers.index( this.active[0] ) > this.headers.index( clicked[0] ); + options.active = collapsing ? false : this.headers.index( clicked ); // when the call to ._toggle() comes after the class changes // it causes a very odd bug in IE 8 (see #6720) - this.active = clickedIsActive ? $([]) : clicked; - this._toggle( toShow, toHide, data, clickedIsActive, down ); + this.active = clickedIsActive ? $() : clicked; + this._toggle( eventData ); // switch classes - active - .removeClass( "ui-state-active ui-corner-top" ) - .addClass( "ui-state-default ui-corner-all" ) - .children( ".ui-icon" ) - .removeClass( options.icons.headerSelected ) + // corner classes on the previously active header stay after the animation + active.removeClass( "ui-accordion-header-active ui-state-active" ); + if ( options.icons ) { + active.children( ".ui-accordion-header-icon" ) + .removeClass( options.icons.activeHeader ) .addClass( options.icons.header ); + } + if ( !clickedIsActive ) { clicked - .removeClass( "ui-state-default ui-corner-all" ) - .addClass( "ui-state-active ui-corner-top" ) - .children( ".ui-icon" ) + .removeClass( "ui-corner-all" ) + .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ); + if ( options.icons ) { + clicked.children( ".ui-accordion-header-icon" ) .removeClass( options.icons.header ) - .addClass( options.icons.headerSelected ); + .addClass( options.icons.activeHeader ); + } + clicked .next() .addClass( "ui-accordion-content-active" ); } + }, + + _toggle: function( data ) { + var toShow = data.newPanel, + toHide = this.prevShow.length ? this.prevShow : data.oldPanel; - return; + // handle activating a panel during the animation for another activation + this.prevShow.add( this.prevHide ).stop( true, true ); + this.prevShow = toShow; + this.prevHide = toHide; + + if ( this.options.animate ) { + this._animate( toShow, toHide, data ); + } else { + toHide.hide(); + toShow.show(); + this._toggleComplete( data ); + } + + toHide.attr({ + "aria-expanded": "false", + "aria-hidden": "true" + }); + toHide.prev().attr( "aria-selected", "false" ); + // if we're switching panels, remove the old header from the tab order + // if we're opening from collapsed state, remove the previous header from the tab order + // if we're collapsing, then keep the collapsing header in the tab order + if ( toShow.length && toHide.length ) { + toHide.prev().attr( "tabIndex", -1 ); + } else if ( toShow.length ) { + this.headers.filter(function() { + return $( this ).attr( "tabIndex" ) === 0; + }) + .attr( "tabIndex", -1 ); + } + + toShow + .attr({ + "aria-expanded": "true", + "aria-hidden": "false" + }) + .prev() + .attr({ + "aria-selected": "true", + tabIndex: 0 + }); }, - _toggle: function( toShow, toHide, data, clickedIsActive, down ) { - var self = this, - options = self.options; + _animate: function( toShow, toHide, data ) { + var total, easing, duration, + that = this, + adjust = 0, + down = toShow.length && + ( !toHide.length || ( toShow.index() < toHide.index() ) ), + animate = this.options.animate || {}, + options = down && animate.down || animate, + complete = function() { + that._toggleComplete( 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; - self.toShow = toShow; - self.toHide = toHide; - self.data = data; + if ( !toHide.length ) { + return toShow.animate( showProps, duration, easing, complete ); + } + if ( !toShow.length ) { + return toHide.animate( hideProps, duration, easing, complete ); + } - var complete = function() { - if ( !self ) { - return; + total = toShow.show().outerHeight(); + toHide.animate( hideProps, { + duration: duration, + easing: easing, + step: function( now, fx ) { + fx.now = Math.round( now ); } - return self._completed.apply( self, arguments ); - }; + }); + toShow + .hide() + .animate( showProps, { + duration: duration, + easing: easing, + complete: complete, + step: function( now, fx ) { + fx.now = Math.round( now ); + if ( fx.prop !== "height" ) { + adjust += fx.now; + } else if ( that.options.heightStyle !== "content" ) { + fx.now = Math.round( total - toHide.outerHeight() - adjust ); + adjust = 0; + } + } + }); + }, - // trigger changestart event - self._trigger( "changestart", null, self.data ); - - // count elements to animate - self.running = toHide.size() === 0 ? toShow.size() : toHide.size(); - - if ( options.animated ) { - var animOptions = {}; - - if ( options.collapsible && clickedIsActive ) { - animOptions = { - toShow: $( [] ), - toHide: toHide, - complete: complete, - down: down, - autoHeight: options.autoHeight || options.fillSpace - }; - } else { - animOptions = { - toShow: toShow, - toHide: toHide, - complete: complete, - down: down, - autoHeight: options.autoHeight || options.fillSpace - }; - } + _toggleComplete: function( data ) { + var toHide = data.oldPanel; - if ( !options.proxied ) { - options.proxied = options.animated; - } + toHide + .removeClass( "ui-accordion-content-active" ) + .prev() + .removeClass( "ui-corner-top" ) + .addClass( "ui-corner-all" ); - if ( !options.proxiedDuration ) { - options.proxiedDuration = options.duration; - } + // Work around for rendering bug in IE (#5421) + if ( toHide.length ) { + toHide.parent()[0].className = toHide.parent()[0].className; + } - options.animated = $.isFunction( options.proxied ) ? - options.proxied( animOptions ) : - options.proxied; + this._trigger( "activate", null, data ); + } +}); - options.duration = $.isFunction( options.proxiedDuration ) ? - options.proxiedDuration( animOptions ) : - options.proxiedDuration; - var animations = $.ui.accordion.animations, - duration = options.duration, - easing = options.animated; - if ( easing && !animations[ easing ] && !$.easing[ easing ] ) { - easing = "slide"; +// DEPRECATED +if ( $.uiBackCompat !== false ) { + // navigation options + (function( $, prototype ) { + $.extend( prototype.options, { + navigation: false, + navigationFilter: function() { + return this.href.toLowerCase() === location.href.toLowerCase(); } - if ( !animations[ easing ] ) { - animations[ easing ] = function( options ) { - this.slide( options, { - easing: easing, - duration: duration || 700 + }); + + var _create = prototype._create; + prototype._create = function() { + if ( this.options.navigation ) { + var that = this, + headers = this.element.find( this.options.header ), + content = headers.next(), + current = headers.add( content ) + .find( "a" ) + .filter( this.options.navigationFilter ) + [ 0 ]; + if ( current ) { + headers.add( content ).each( function( index ) { + if ( $.contains( this, current ) ) { + that.options.active = Math.floor( index / 2 ); + return false; + } }); - }; + } } + _create.call( this ); + }; + }( jQuery, jQuery.ui.accordion.prototype ) ); + + // height options + (function( $, prototype ) { + $.extend( prototype.options, { + heightStyle: null, // remove default so we fall back to old values + autoHeight: true, // use heightStyle: "auto" + clearStyle: false, // use heightStyle: "content" + fillSpace: false // use heightStyle: "fill" + }); + + var _create = prototype._create, + _setOption = prototype._setOption; + + $.extend( prototype, { + _create: function() { + this.options.heightStyle = this.options.heightStyle || + this._mergeHeightStyle(); + + _create.call( this ); + }, - animations[ easing ]( animOptions ); - } else { - if ( options.collapsible && clickedIsActive ) { - toShow.toggle(); - } else { - toHide.hide(); - toShow.show(); - } + _setOption: function( key ) { + if ( key === "autoHeight" || key === "clearStyle" || key === "fillSpace" ) { + this.options.heightStyle = this._mergeHeightStyle(); + } + _setOption.apply( this, arguments ); + }, - complete( true ); - } + _mergeHeightStyle: function() { + var options = this.options; - // TODO assert that the blur and focus triggers are really necessary, remove otherwise - toHide.prev() - .attr({ - "aria-expanded": "false", - "aria-selected": "false", - tabIndex: -1 - }) - .blur(); - toShow.prev() - .attr({ - "aria-expanded": "true", - "aria-selected": "true", - tabIndex: 0 - }) - .focus(); - }, + if ( options.fillSpace ) { + return "fill"; + } - _completed: function( cancel ) { - this.running = cancel ? 0 : --this.running; - if ( this.running ) { - return; - } + if ( options.clearStyle ) { + return "content"; + } - if ( this.options.clearStyle ) { - this.toShow.add( this.toHide ).css({ - height: "", - overflow: "" - }); - } + if ( options.autoHeight ) { + return "auto"; + } + } + }); + }( jQuery, jQuery.ui.accordion.prototype ) ); - // other classes are removed before the animation; this one needs to stay until completed - this.toHide.removeClass( "ui-accordion-content-active" ); - // Work around for rendering bug in IE (#5421) - if ( this.toHide.length ) { - this.toHide.parent()[0].className = this.toHide.parent()[0].className; - } + // icon options + (function( $, prototype ) { + $.extend( prototype.options.icons, { + activeHeader: null, // remove default so we fall back to old values + headerSelected: "ui-icon-triangle-1-s" + }); - this._trigger( "change", null, this.data ); - } -}); + var _createIcons = prototype._createIcons; + prototype._createIcons = function() { + if ( this.options.icons ) { + this.options.icons.activeHeader = this.options.icons.activeHeader || + this.options.icons.headerSelected; + } + _createIcons.call( this ); + }; + }( jQuery, jQuery.ui.accordion.prototype ) ); -$.extend( $.ui.accordion, { - version: "1.8.24", - animations: { - slide: function( options, additions ) { - options = $.extend({ - easing: "swing", - duration: 300 - }, options, additions ); - if ( !options.toHide.size() ) { - options.toShow.animate({ - height: "show", - paddingTop: "show", - paddingBottom: "show" - }, options ); - return; + // expanded active option, activate method + (function( $, prototype ) { + prototype.activate = prototype._activate; + + var _findActive = prototype._findActive; + prototype._findActive = function( index ) { + if ( index === -1 ) { + index = false; } - if ( !options.toShow.size() ) { - options.toHide.animate({ - height: "hide", - paddingTop: "hide", - paddingBottom: "hide" - }, options ); - return; + if ( index && typeof index !== "number" ) { + index = this.headers.index( this.headers.filter( index ) ); + if ( index === -1 ) { + index = false; + } + } + return _findActive.call( this, index ); + }; + }( jQuery, jQuery.ui.accordion.prototype ) ); + + // resize method + jQuery.ui.accordion.prototype.resize = jQuery.ui.accordion.prototype.refresh; + + // change events + (function( $, prototype ) { + $.extend( prototype.options, { + change: null, + changestart: null + }); + + var _trigger = prototype._trigger; + prototype._trigger = function( type, event, data ) { + var ret = _trigger.apply( this, arguments ); + if ( !ret ) { + return false; } - var overflow = options.toShow.css( "overflow" ), - percentDone = 0, - showProps = {}, - hideProps = {}, - fxAttrs = [ "height", "paddingTop", "paddingBottom" ], - originalWidth; - // 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+-.]+)(.*)$/ ); - showProps[ prop ] = { - value: parts[ 1 ], - 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 ) { - // only calculate the percent when animating height - // IE gets very inconsistent results when animating elements - // with small values, which is common for padding - if ( settings.prop == "height" ) { - 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() { - if ( !options.autoHeight ) { - options.toShow.css( "height", "" ); - } - options.toShow.css({ - width: originalWidth, - overflow: overflow - }); - options.complete(); + if ( type === "beforeActivate" ) { + ret = _trigger.call( this, "changestart", event, { + oldHeader: data.oldHeader, + oldContent: data.oldPanel, + newHeader: data.newHeader, + newContent: data.newPanel + }); + } else if ( type === "activate" ) { + ret = _trigger.call( this, "change", event, { + oldHeader: data.oldHeader, + oldContent: data.oldPanel, + newHeader: data.newHeader, + newContent: data.newPanel + }); + } + 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; } - }); - }, - bounceslide: function( options ) { - this.slide( options, { - easing: options.down ? "easeOutBounce" : "swing", - duration: options.down ? 1000 : 200 - }); - } - } -}); + } + + _create.call( this ); + }; + }( jQuery, jQuery.ui.accordion.prototype ) ); +} })( jQuery ); |