]> source.dussan.org Git - jquery-ui.git/commitdiff
Accordion: Move accordion into widgets folder
authorAlexander Schmitz <arschmitz@gmail.com>
Wed, 15 Jul 2015 01:54:33 +0000 (21:54 -0400)
committerAlexander Schmitz <arschmitz@gmail.com>
Sat, 8 Aug 2015 04:29:37 +0000 (00:29 -0400)
Ref #13885

demos/bootstrap.js
tests/unit/accordion/common.js
tests/unit/accordion/core.js
tests/unit/accordion/events.js
tests/unit/accordion/helper.js
tests/unit/accordion/methods.js
tests/unit/accordion/options.js
ui/accordion.js [deleted file]
ui/widgets/accordion.js [new file with mode: 0644]

index 7fed08cbbe49bac7d7a54300017a8335a71ffe9d..af9aee13098a7105eeb383cbb8e6d5c97d912a2d 100644 (file)
@@ -24,7 +24,9 @@ var effectsAll = [
        "effect-size",
        "effect-slide"
 ];
-var widgets = [];
+var widgets = [
+       "accordion"
+];
 
 function getPath( module ) {
        for ( var i = 0; i < widgets.length; i++ ) {
index 8a859f0ca6da48278374968bff9029e5aeacd3eb..1a8ce55c4a15010f9ca532b125941124f6d111a3 100644 (file)
@@ -1,6 +1,6 @@
 define( [
        "lib/common",
-       "ui/accordion"
+       "ui/widgets/accordion"
 ], function( common ) {
 
 common.testWidget( "accordion", {
index 0a39311624c335c1b8fbe1092d56e433aa9cd515..ed538c368ea0080882b0c67c71b646b211694a2d 100644 (file)
@@ -1,7 +1,7 @@
 define( [
        "jquery",
        "./helper",
-       "ui/accordion"
+       "ui/widgets/accordion"
 ], function( $, testHelper ) {
 
 var setupTeardown = testHelper.setupTeardown,
index fef1a0aac508cd908405af569593ebdeb1789f52..03aee34343d1d997334111f310534fe96c0f7094 100644 (file)
@@ -1,7 +1,7 @@
 define( [
        "jquery",
        "./helper",
-       "ui/accordion"
+       "ui/widgets/accordion"
 ], function( $, testHelper ) {
 
 var setupTeardown = testHelper.setupTeardown,
index 5eb3a4bc3f2025c7c3f0b22d105063da5ac97234..ec9b7ecb8f3ae4628171ea48d732edfa036e9e48 100644 (file)
@@ -1,7 +1,7 @@
 define( [
        "jquery",
        "lib/helper",
-       "ui/accordion"
+       "ui/widgets/accordion"
 ], function( $, helper ) {
 
 return $.extend( helper, {
index efabfed10b19eae5f4684e74967a82ae5be9e2c5..455e80c58f3573fd63239cfe8ee819bb1338396b 100644 (file)
@@ -1,7 +1,7 @@
 define( [
        "jquery",
        "./helper",
-       "ui/accordion"
+       "ui/widgets/accordion"
 ], function( $, testHelper ) {
 
 var equalHeight = testHelper.equalHeight,
index 52d54ed32e431ed2e5dc6f018124da2b01ac5376..06248d6cb679fac5372e2ca65956f17394b98e5b 100644 (file)
@@ -1,7 +1,7 @@
 define( [
        "jquery",
        "./helper",
-       "ui/accordion"
+       "ui/widgets/accordion"
 ], function( $, testHelper ) {
 
 var equalHeight = testHelper.equalHeight,
diff --git a/ui/accordion.js b/ui/accordion.js
deleted file mode 100644 (file)
index fdc092f..0000000
+++ /dev/null
@@ -1,590 +0,0 @@
-/*!
- * jQuery UI Accordion @VERSION
- * http://jqueryui.com
- *
- * Copyright jQuery Foundation and other contributors
- * Released under the MIT license.
- * http://jquery.org/license
- */
-
-//>>label: Accordion
-//>>group: Widgets
-//>>description: Displays collapsible content panels for presenting information in a limited amount of space.
-//>>docs: http://api.jqueryui.com/accordion/
-//>>demos: http://jqueryui.com/accordion/
-//>>css.structure: ../themes/base/core.css
-//>>css.structure: ../themes/base/accordion.css
-//>>css.theme: ../themes/base/theme.css
-
-( function( factory ) {
-       if ( typeof define === "function" && define.amd ) {
-
-               // AMD. Register as an anonymous module.
-               define( [
-                       "jquery",
-                       "./version",
-                       "./version",
-                       "./keycode",
-                       "./unique-id",
-                       "./widget"
-               ], factory );
-       } else {
-
-               // Browser globals
-               factory( jQuery );
-       }
-}( function( $ ) {
-
-return $.widget( "ui.accordion", {
-       version: "@VERSION",
-       options: {
-               active: 0,
-               animate: {},
-               classes: {
-                       "ui-accordion-header": "ui-corner-top",
-                       "ui-accordion-header-collapsed": "ui-corner-all",
-                       "ui-accordion-content": "ui-corner-bottom"
-               },
-               collapsible: false,
-               event: "click",
-               header: "> li > :first-child, > :not(li):even",
-               heightStyle: "auto",
-               icons: {
-                       activeHeader: "ui-icon-triangle-1-s",
-                       header: "ui-icon-triangle-1-e"
-               },
-
-               // callbacks
-               activate: null,
-               beforeActivate: null
-       },
-
-       hideProps: {
-               borderTopWidth: "hide",
-               borderBottomWidth: "hide",
-               paddingTop: "hide",
-               paddingBottom: "hide",
-               height: "hide"
-       },
-
-       showProps: {
-               borderTopWidth: "show",
-               borderBottomWidth: "show",
-               paddingTop: "show",
-               paddingBottom: "show",
-               height: "show"
-       },
-
-       _create: function() {
-               var options = this.options;
-
-               this.prevShow = this.prevHide = $();
-               this._addClass( "ui-accordion", "ui-widget ui-helper-reset" );
-               this.element.attr( "role", "tablist" );
-
-               // don't allow collapsible: false and active: false / null
-               if ( !options.collapsible && ( options.active === false || options.active == null ) ) {
-                       options.active = 0;
-               }
-
-               this._processPanels();
-               // handle negative values
-               if ( options.active < 0 ) {
-                       options.active += this.headers.length;
-               }
-               this._refresh();
-       },
-
-       _getCreateEventData: function() {
-               return {
-                       header: this.active,
-                       panel: !this.active.length ? $() : this.active.next()
-               };
-       },
-
-       _createIcons: function() {
-               var icon, children,
-                       icons = this.options.icons;
-
-               if ( icons ) {
-                       icon = $( "<span>" );
-                       this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header );
-                       icon.prependTo( this.headers );
-                       children = this.active.children( ".ui-accordion-header-icon" );
-                       this._removeClass( children, icons.header )
-                               ._addClass( children, null, icons.activeHeader )
-                               ._addClass( this.headers, "ui-accordion-icons" );
-               }
-       },
-
-       _destroyIcons: function() {
-               this._removeClass( this.headers, "ui-accordion-icons" );
-               this.headers.children( ".ui-accordion-header-icon" ).remove();
-       },
-
-       _destroy: function() {
-               var contents;
-
-               // clean up main element
-               this.element.removeAttr( "role" );
-
-               // clean up headers
-               this.headers
-                       .removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" )
-                       .removeUniqueId();
-
-               this._destroyIcons();
-
-               // clean up content panels
-               contents = this.headers.next()
-                       .css( "display", "" )
-                       .removeAttr( "role aria-hidden aria-labelledby" )
-                       .removeUniqueId();
-
-               if ( this.options.heightStyle !== "content" ) {
-                       contents.css( "height", "" );
-               }
-       },
-
-       _setOption: function( key, 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" ) {
-                       this._destroyIcons();
-                       if ( value ) {
-                               this._createIcons();
-                       }
-               }
-
-               // Support: IE8 Only
-               // #5332 / #6059 - 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.element.attr( "aria-disabled", value );
-
-                       this._toggleClass( null, "ui-state-disabled", !!value );
-                       this._toggleClass( this.headers.add( this.headers.next() ), null, "ui-state-disabled",
-                               !!value );
-               }
-       },
-
-       _keydown: function( event ) {
-               if ( event.altKey || event.ctrlKey ) {
-                       return;
-               }
-
-               var keyCode = $.ui.keyCode,
-                       length = this.headers.length,
-                       currentIndex = this.headers.index( event.target ),
-                       toFocus = false;
-
-               switch ( event.keyCode ) {
-               case keyCode.RIGHT:
-               case keyCode.DOWN:
-                       toFocus = this.headers[ ( currentIndex + 1 ) % length ];
-                       break;
-               case keyCode.LEFT:
-               case keyCode.UP:
-                       toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
-                       break;
-               case keyCode.SPACE:
-               case keyCode.ENTER:
-                       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 ).trigger( "focus" );
-                       event.preventDefault();
-               }
-       },
-
-       _panelKeyDown: function( event ) {
-               if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
-                       $( event.currentTarget ).prev().trigger( "focus" );
-               }
-       },
-
-       refresh: function() {
-               var options = this.options;
-               this._processPanels();
-
-               // was collapsed or no panel
-               if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {
-                       options.active = false;
-                       this.active = $();
-               // active false only when collapsible is true
-               } else if ( options.active === false ) {
-                       this._activate( 0 );
-               // was active, but active panel is gone
-               } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
-                       // all remaining panel are disabled
-                       if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) {
-                               options.active = false;
-                               this.active = $();
-                       // activate previous panel
-                       } else {
-                               this._activate( Math.max( 0, options.active - 1 ) );
-                       }
-               // was active, active panel still exists
-               } else {
-                       // make sure active index is correct
-                       options.active = this.headers.index( this.active );
-               }
-
-               this._destroyIcons();
-
-               this._refresh();
-       },
-
-       _processPanels: function() {
-               var prevHeaders = this.headers,
-                       prevPanels = this.panels;
-
-               this.headers = this.element.find( this.options.header );
-               this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed",
-                       "ui-state-default" );
-
-               this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide();
-               this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" );
-
-               // Avoid memory leaks (#10056)
-               if ( prevPanels ) {
-                       this._off( prevHeaders.not( this.headers ) );
-                       this._off( prevPanels.not( this.panels ) );
-               }
-       },
-
-       _refresh: function() {
-               var maxHeight,
-                       options = this.options,
-                       heightStyle = options.heightStyle,
-                       parent = this.element.parent();
-
-               this.active = this._findActive( options.active );
-               this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" )
-                       ._removeClass( this.active, "ui-accordion-header-collapsed" );
-               this._addClass( this.active.next(), "ui-accordion-content-active" );
-               this.active.next().show();
-
-               this.headers
-                       .attr( "role", "tab" )
-                       .each( function() {
-                               var header = $( this ),
-                                       headerId = header.uniqueId().attr( "id" ),
-                                       panel = header.next(),
-                                       panelId = panel.uniqueId().attr( "id" );
-                               header.attr( "aria-controls", panelId );
-                               panel.attr( "aria-labelledby", headerId );
-                       } )
-                       .next()
-                               .attr( "role", "tabpanel" );
-
-               this.headers
-                       .not( this.active )
-                               .attr( {
-                                       "aria-selected": "false",
-                                       "aria-expanded": "false",
-                                       tabIndex: -1
-                               } )
-                               .next()
-                                       .attr( {
-                                               "aria-hidden": "true"
-                                       } )
-                                       .hide();
-
-               // make sure at least one header is in the tab order
-               if ( !this.active.length ) {
-                       this.headers.eq( 0 ).attr( "tabIndex", 0 );
-               } else {
-                       this.active.attr( {
-                               "aria-selected": "true",
-                               "aria-expanded": "true",
-                               tabIndex: 0
-                       } )
-                               .next()
-                                       .attr( {
-                                               "aria-hidden": "false"
-                                       } );
-               }
-
-               this._createIcons();
-
-               this._setupEvents( options.event );
-
-               if ( heightStyle === "fill" ) {
-                       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 );
-                       } );
-
-                       this.headers.each( function() {
-                               maxHeight -= $( this ).outerHeight( true );
-                       } );
-
-                       this.headers.next()
-                               .each( function() {
-                                       $( this ).height( Math.max( 0, maxHeight -
-                                               $( this ).innerHeight() + $( this ).height() ) );
-                               } )
-                               .css( "overflow", "auto" );
-               } else if ( heightStyle === "auto" ) {
-                       maxHeight = 0;
-                       this.headers.next()
-                               .each( function() {
-                                       maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
-                               } )
-                               .height( maxHeight );
-               }
-       },
-
-       _activate: function( index ) {
-               var active = this._findActive( index )[ 0 ];
-
-               // 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 typeof selector === "number" ? this.headers.eq( selector ) : $();
-       },
-
-       _setupEvents: function( event ) {
-               var events = {
-                       keydown: "_keydown"
-               };
-               if ( event ) {
-                       $.each( event.split( " " ), function( index, eventName ) {
-                               events[ eventName ] = "_eventHandler";
-                       } );
-               }
-
-               this._off( this.headers.add( this.headers.next() ) );
-               this._on( this.headers, events );
-               this._on( this.headers.next(), { keydown: "_panelKeyDown" } );
-               this._hoverable( this.headers );
-               this._focusable( this.headers );
-       },
-
-       _eventHandler: function( event ) {
-               var activeChildren, clickedChildren,
-                       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;
-               }
-
-               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( eventData );
-
-               // switch classes
-               // corner classes on the previously active header stay after the animation
-               this._removeClass( active, "ui-accordion-header-active", "ui-state-active" );
-               if ( options.icons ) {
-                       activeChildren = active.children( ".ui-accordion-header-icon" );
-                       this._removeClass( activeChildren, null, options.icons.activeHeader )
-                               ._addClass( activeChildren, null, options.icons.header );
-               }
-
-               if ( !clickedIsActive ) {
-                       this._removeClass( clicked, "ui-accordion-header-collapsed" )
-                               ._addClass( clicked, "ui-accordion-header-active", "ui-state-active" );
-                       if ( options.icons ) {
-                               clickedChildren = clicked.children( ".ui-accordion-header-icon" );
-                               this._removeClass( clickedChildren, null, options.icons.header )
-                                       ._addClass( clickedChildren, null, options.icons.activeHeader );
-                       }
-
-                       this._addClass( clicked.next(), "ui-accordion-content-active" );
-               }
-       },
-
-       _toggle: function( data ) {
-               var toShow = data.newPanel,
-                       toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
-
-               // 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-hidden": "true"
-               } );
-               toHide.prev().attr( {
-                       "aria-selected": "false",
-                       "aria-expanded": "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,
-                               "aria-expanded": "false"
-                       } );
-               } else if ( toShow.length ) {
-                       this.headers.filter( function() {
-                               return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
-                       } )
-                               .attr( "tabIndex", -1 );
-               }
-
-               toShow
-                       .attr( "aria-hidden", "false" )
-                       .prev()
-                               .attr( {
-                                       "aria-selected": "true",
-                                       "aria-expanded": "true",
-                                       tabIndex: 0
-                               } );
-       },
-
-       _animate: function( toShow, toHide, data ) {
-               var total, easing, duration,
-                       that = this,
-                       adjust = 0,
-                       boxSizing = toShow.css( "box-sizing" ),
-                       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;
-
-               if ( !toHide.length ) {
-                       return toShow.animate( this.showProps, duration, easing, complete );
-               }
-               if ( !toShow.length ) {
-                       return toHide.animate( this.hideProps, duration, easing, complete );
-               }
-
-               total = toShow.show().outerHeight();
-               toHide.animate( this.hideProps, {
-                       duration: duration,
-                       easing: easing,
-                       step: function( now, fx ) {
-                               fx.now = Math.round( now );
-                       }
-               } );
-               toShow
-                       .hide()
-                       .animate( this.showProps, {
-                               duration: duration,
-                               easing: easing,
-                               complete: complete,
-                               step: function( now, fx ) {
-                                       fx.now = Math.round( now );
-                                       if ( fx.prop !== "height" ) {
-                                               if ( boxSizing === "content-box" ) {
-                                                       adjust += fx.now;
-                                               }
-                                       } else if ( that.options.heightStyle !== "content" ) {
-                                               fx.now = Math.round( total - toHide.outerHeight() - adjust );
-                                               adjust = 0;
-                                       }
-                               }
-                       } );
-       },
-
-       _toggleComplete: function( data ) {
-               var toHide = data.oldPanel,
-                       prev = toHide.prev();
-
-               this._removeClass( toHide, "ui-accordion-content-active" );
-               this._removeClass( prev, "ui-accordion-header-active" )
-                       ._addClass( prev, "ui-accordion-header-collapsed" );
-
-               // Work around for rendering bug in IE (#5421)
-               if ( toHide.length ) {
-                       toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
-               }
-               this._trigger( "activate", null, data );
-       }
-} );
-
-} ) );
diff --git a/ui/widgets/accordion.js b/ui/widgets/accordion.js
new file mode 100644 (file)
index 0000000..88e9bdb
--- /dev/null
@@ -0,0 +1,589 @@
+/*!
+ * jQuery UI Accordion @VERSION
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ */
+
+//>>label: Accordion
+//>>group: Widgets
+//>>description: Displays collapsible content panels for presenting information in a limited amount of space.
+//>>docs: http://api.jqueryui.com/accordion/
+//>>demos: http://jqueryui.com/accordion/
+//>>css.structure: ../themes/base/core.css
+//>>css.structure: ../themes/base/accordion.css
+//>>css.theme: ../themes/base/theme.css
+
+( function( factory ) {
+       if ( typeof define === "function" && define.amd ) {
+
+               // AMD. Register as an anonymous module.
+               define( [
+                       "jquery",
+                       "../version",
+                       "../keycode",
+                       "../unique-id",
+                       "../widget"
+               ], factory );
+       } else {
+
+               // Browser globals
+               factory( jQuery );
+       }
+}( function( $ ) {
+
+return $.widget( "ui.accordion", {
+       version: "@VERSION",
+       options: {
+               active: 0,
+               animate: {},
+               classes: {
+                       "ui-accordion-header": "ui-corner-top",
+                       "ui-accordion-header-collapsed": "ui-corner-all",
+                       "ui-accordion-content": "ui-corner-bottom"
+               },
+               collapsible: false,
+               event: "click",
+               header: "> li > :first-child, > :not(li):even",
+               heightStyle: "auto",
+               icons: {
+                       activeHeader: "ui-icon-triangle-1-s",
+                       header: "ui-icon-triangle-1-e"
+               },
+
+               // callbacks
+               activate: null,
+               beforeActivate: null
+       },
+
+       hideProps: {
+               borderTopWidth: "hide",
+               borderBottomWidth: "hide",
+               paddingTop: "hide",
+               paddingBottom: "hide",
+               height: "hide"
+       },
+
+       showProps: {
+               borderTopWidth: "show",
+               borderBottomWidth: "show",
+               paddingTop: "show",
+               paddingBottom: "show",
+               height: "show"
+       },
+
+       _create: function() {
+               var options = this.options;
+
+               this.prevShow = this.prevHide = $();
+               this._addClass( "ui-accordion", "ui-widget ui-helper-reset" );
+               this.element.attr( "role", "tablist" );
+
+               // don't allow collapsible: false and active: false / null
+               if ( !options.collapsible && ( options.active === false || options.active == null ) ) {
+                       options.active = 0;
+               }
+
+               this._processPanels();
+               // handle negative values
+               if ( options.active < 0 ) {
+                       options.active += this.headers.length;
+               }
+               this._refresh();
+       },
+
+       _getCreateEventData: function() {
+               return {
+                       header: this.active,
+                       panel: !this.active.length ? $() : this.active.next()
+               };
+       },
+
+       _createIcons: function() {
+               var icon, children,
+                       icons = this.options.icons;
+
+               if ( icons ) {
+                       icon = $( "<span>" );
+                       this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header );
+                       icon.prependTo( this.headers );
+                       children = this.active.children( ".ui-accordion-header-icon" );
+                       this._removeClass( children, icons.header )
+                               ._addClass( children, null, icons.activeHeader )
+                               ._addClass( this.headers, "ui-accordion-icons" );
+               }
+       },
+
+       _destroyIcons: function() {
+               this._removeClass( this.headers, "ui-accordion-icons" );
+               this.headers.children( ".ui-accordion-header-icon" ).remove();
+       },
+
+       _destroy: function() {
+               var contents;
+
+               // clean up main element
+               this.element.removeAttr( "role" );
+
+               // clean up headers
+               this.headers
+                       .removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" )
+                       .removeUniqueId();
+
+               this._destroyIcons();
+
+               // clean up content panels
+               contents = this.headers.next()
+                       .css( "display", "" )
+                       .removeAttr( "role aria-hidden aria-labelledby" )
+                       .removeUniqueId();
+
+               if ( this.options.heightStyle !== "content" ) {
+                       contents.css( "height", "" );
+               }
+       },
+
+       _setOption: function( key, 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" ) {
+                       this._destroyIcons();
+                       if ( value ) {
+                               this._createIcons();
+                       }
+               }
+
+               // Support: IE8 Only
+               // #5332 / #6059 - 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.element.attr( "aria-disabled", value );
+
+                       this._toggleClass( null, "ui-state-disabled", !!value );
+                       this._toggleClass( this.headers.add( this.headers.next() ), null, "ui-state-disabled",
+                               !!value );
+               }
+       },
+
+       _keydown: function( event ) {
+               if ( event.altKey || event.ctrlKey ) {
+                       return;
+               }
+
+               var keyCode = $.ui.keyCode,
+                       length = this.headers.length,
+                       currentIndex = this.headers.index( event.target ),
+                       toFocus = false;
+
+               switch ( event.keyCode ) {
+               case keyCode.RIGHT:
+               case keyCode.DOWN:
+                       toFocus = this.headers[ ( currentIndex + 1 ) % length ];
+                       break;
+               case keyCode.LEFT:
+               case keyCode.UP:
+                       toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
+                       break;
+               case keyCode.SPACE:
+               case keyCode.ENTER:
+                       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 ).trigger( "focus" );
+                       event.preventDefault();
+               }
+       },
+
+       _panelKeyDown: function( event ) {
+               if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
+                       $( event.currentTarget ).prev().trigger( "focus" );
+               }
+       },
+
+       refresh: function() {
+               var options = this.options;
+               this._processPanels();
+
+               // was collapsed or no panel
+               if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {
+                       options.active = false;
+                       this.active = $();
+               // active false only when collapsible is true
+               } else if ( options.active === false ) {
+                       this._activate( 0 );
+               // was active, but active panel is gone
+               } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
+                       // all remaining panel are disabled
+                       if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) {
+                               options.active = false;
+                               this.active = $();
+                       // activate previous panel
+                       } else {
+                               this._activate( Math.max( 0, options.active - 1 ) );
+                       }
+               // was active, active panel still exists
+               } else {
+                       // make sure active index is correct
+                       options.active = this.headers.index( this.active );
+               }
+
+               this._destroyIcons();
+
+               this._refresh();
+       },
+
+       _processPanels: function() {
+               var prevHeaders = this.headers,
+                       prevPanels = this.panels;
+
+               this.headers = this.element.find( this.options.header );
+               this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed",
+                       "ui-state-default" );
+
+               this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide();
+               this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" );
+
+               // Avoid memory leaks (#10056)
+               if ( prevPanels ) {
+                       this._off( prevHeaders.not( this.headers ) );
+                       this._off( prevPanels.not( this.panels ) );
+               }
+       },
+
+       _refresh: function() {
+               var maxHeight,
+                       options = this.options,
+                       heightStyle = options.heightStyle,
+                       parent = this.element.parent();
+
+               this.active = this._findActive( options.active );
+               this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" )
+                       ._removeClass( this.active, "ui-accordion-header-collapsed" );
+               this._addClass( this.active.next(), "ui-accordion-content-active" );
+               this.active.next().show();
+
+               this.headers
+                       .attr( "role", "tab" )
+                       .each( function() {
+                               var header = $( this ),
+                                       headerId = header.uniqueId().attr( "id" ),
+                                       panel = header.next(),
+                                       panelId = panel.uniqueId().attr( "id" );
+                               header.attr( "aria-controls", panelId );
+                               panel.attr( "aria-labelledby", headerId );
+                       } )
+                       .next()
+                               .attr( "role", "tabpanel" );
+
+               this.headers
+                       .not( this.active )
+                               .attr( {
+                                       "aria-selected": "false",
+                                       "aria-expanded": "false",
+                                       tabIndex: -1
+                               } )
+                               .next()
+                                       .attr( {
+                                               "aria-hidden": "true"
+                                       } )
+                                       .hide();
+
+               // make sure at least one header is in the tab order
+               if ( !this.active.length ) {
+                       this.headers.eq( 0 ).attr( "tabIndex", 0 );
+               } else {
+                       this.active.attr( {
+                               "aria-selected": "true",
+                               "aria-expanded": "true",
+                               tabIndex: 0
+                       } )
+                               .next()
+                                       .attr( {
+                                               "aria-hidden": "false"
+                                       } );
+               }
+
+               this._createIcons();
+
+               this._setupEvents( options.event );
+
+               if ( heightStyle === "fill" ) {
+                       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 );
+                       } );
+
+                       this.headers.each( function() {
+                               maxHeight -= $( this ).outerHeight( true );
+                       } );
+
+                       this.headers.next()
+                               .each( function() {
+                                       $( this ).height( Math.max( 0, maxHeight -
+                                               $( this ).innerHeight() + $( this ).height() ) );
+                               } )
+                               .css( "overflow", "auto" );
+               } else if ( heightStyle === "auto" ) {
+                       maxHeight = 0;
+                       this.headers.next()
+                               .each( function() {
+                                       maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
+                               } )
+                               .height( maxHeight );
+               }
+       },
+
+       _activate: function( index ) {
+               var active = this._findActive( index )[ 0 ];
+
+               // 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 typeof selector === "number" ? this.headers.eq( selector ) : $();
+       },
+
+       _setupEvents: function( event ) {
+               var events = {
+                       keydown: "_keydown"
+               };
+               if ( event ) {
+                       $.each( event.split( " " ), function( index, eventName ) {
+                               events[ eventName ] = "_eventHandler";
+                       } );
+               }
+
+               this._off( this.headers.add( this.headers.next() ) );
+               this._on( this.headers, events );
+               this._on( this.headers.next(), { keydown: "_panelKeyDown" } );
+               this._hoverable( this.headers );
+               this._focusable( this.headers );
+       },
+
+       _eventHandler: function( event ) {
+               var activeChildren, clickedChildren,
+                       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;
+               }
+
+               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( eventData );
+
+               // switch classes
+               // corner classes on the previously active header stay after the animation
+               this._removeClass( active, "ui-accordion-header-active", "ui-state-active" );
+               if ( options.icons ) {
+                       activeChildren = active.children( ".ui-accordion-header-icon" );
+                       this._removeClass( activeChildren, null, options.icons.activeHeader )
+                               ._addClass( activeChildren, null, options.icons.header );
+               }
+
+               if ( !clickedIsActive ) {
+                       this._removeClass( clicked, "ui-accordion-header-collapsed" )
+                               ._addClass( clicked, "ui-accordion-header-active", "ui-state-active" );
+                       if ( options.icons ) {
+                               clickedChildren = clicked.children( ".ui-accordion-header-icon" );
+                               this._removeClass( clickedChildren, null, options.icons.header )
+                                       ._addClass( clickedChildren, null, options.icons.activeHeader );
+                       }
+
+                       this._addClass( clicked.next(), "ui-accordion-content-active" );
+               }
+       },
+
+       _toggle: function( data ) {
+               var toShow = data.newPanel,
+                       toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
+
+               // 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-hidden": "true"
+               } );
+               toHide.prev().attr( {
+                       "aria-selected": "false",
+                       "aria-expanded": "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,
+                               "aria-expanded": "false"
+                       } );
+               } else if ( toShow.length ) {
+                       this.headers.filter( function() {
+                               return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
+                       } )
+                               .attr( "tabIndex", -1 );
+               }
+
+               toShow
+                       .attr( "aria-hidden", "false" )
+                       .prev()
+                               .attr( {
+                                       "aria-selected": "true",
+                                       "aria-expanded": "true",
+                                       tabIndex: 0
+                               } );
+       },
+
+       _animate: function( toShow, toHide, data ) {
+               var total, easing, duration,
+                       that = this,
+                       adjust = 0,
+                       boxSizing = toShow.css( "box-sizing" ),
+                       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;
+
+               if ( !toHide.length ) {
+                       return toShow.animate( this.showProps, duration, easing, complete );
+               }
+               if ( !toShow.length ) {
+                       return toHide.animate( this.hideProps, duration, easing, complete );
+               }
+
+               total = toShow.show().outerHeight();
+               toHide.animate( this.hideProps, {
+                       duration: duration,
+                       easing: easing,
+                       step: function( now, fx ) {
+                               fx.now = Math.round( now );
+                       }
+               } );
+               toShow
+                       .hide()
+                       .animate( this.showProps, {
+                               duration: duration,
+                               easing: easing,
+                               complete: complete,
+                               step: function( now, fx ) {
+                                       fx.now = Math.round( now );
+                                       if ( fx.prop !== "height" ) {
+                                               if ( boxSizing === "content-box" ) {
+                                                       adjust += fx.now;
+                                               }
+                                       } else if ( that.options.heightStyle !== "content" ) {
+                                               fx.now = Math.round( total - toHide.outerHeight() - adjust );
+                                               adjust = 0;
+                                       }
+                               }
+                       } );
+       },
+
+       _toggleComplete: function( data ) {
+               var toHide = data.oldPanel,
+                       prev = toHide.prev();
+
+               this._removeClass( toHide, "ui-accordion-content-active" );
+               this._removeClass( prev, "ui-accordion-header-active" )
+                       ._addClass( prev, "ui-accordion-header-collapsed" );
+
+               // Work around for rendering bug in IE (#5421)
+               if ( toHide.length ) {
+                       toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
+               }
+               this._trigger( "activate", null, data );
+       }
+} );
+
+} ) );