/*! * jQuery UI 1.8.22 * * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI */ (function( $, undefined ) { // prevent duplicate loading // this is only a problem because we proxy existing functions // and we don't want to double proxy them $.ui = $.ui || {}; if ( $.ui.version ) { return; } $.extend( $.ui, { version: "1.8.22", keyCode: { ALT: 18, BACKSPACE: 8, CAPS_LOCK: 20, COMMA: 188, COMMAND: 91, COMMAND_LEFT: 91, // COMMAND COMMAND_RIGHT: 93, CONTROL: 17, DELETE: 46, DOWN: 40, END: 35, ENTER: 13, ESCAPE: 27, HOME: 36, INSERT: 45, LEFT: 37, MENU: 93, // COMMAND_RIGHT NUMPAD_ADD: 107, NUMPAD_DECIMAL: 110, NUMPAD_DIVIDE: 111, NUMPAD_ENTER: 108, NUMPAD_MULTIPLY: 106, NUMPAD_SUBTRACT: 109, PAGE_DOWN: 34, PAGE_UP: 33, PERIOD: 190, RIGHT: 39, SHIFT: 16, SPACE: 32, TAB: 9, UP: 38, WINDOWS: 91 // COMMAND } }); // plugins $.fn.extend({ propAttr: $.fn.prop || $.fn.attr, _focus: $.fn.focus, focus: function( delay, fn ) { return typeof delay === "number" ? this.each(function() { var elem = this; setTimeout(function() { $( elem ).focus(); if ( fn ) { fn.call( elem ); } }, delay ); }) : this._focus.apply( this, arguments ); }, scrollParent: function() { var scrollParent; if (($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) { scrollParent = this.parents().filter(function() { return (/(relative|absolute|fixed)/).test($.curCSS(this,'position',1)) && (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1)); }).eq(0); } else { scrollParent = this.parents().filter(function() { return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1)); }).eq(0); } return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent; }, zIndex: function( zIndex ) { if ( zIndex !== undefined ) { return this.css( "zIndex", zIndex ); } if ( this.length ) { var elem = $( this[ 0 ] ), position, value; while ( elem.length && elem[ 0 ] !== document ) { // Ignore z-index if position is set to a value where z-index is ignored by the browser // This makes behavior of this function consistent across browsers // WebKit always returns auto if the element is positioned position = elem.css( "position" ); if ( position === "absolute" || position === "relative" || position === "fixed" ) { // IE returns 0 when zIndex is not specified // other browsers return a string // we ignore the case of nested elements with an explicit value of 0 //
value = parseInt( elem.css( "zIndex" ), 10 ); if ( !isNaN( value ) && value !== 0 ) { return value; } } elem = elem.parent(); } } return 0; }, disableSelection: function() { return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) + ".ui-disableSelection", function( event ) { event.preventDefault(); }); }, enableSelection: function() { return this.unbind( ".ui-disableSelection" ); } }); // support: jQuery <1.8 if ( !$( "" ).outerWidth( 1 ).jquery ) { $.each( [ "Width", "Height" ], function( i, name ) { var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ], type = name.toLowerCase(), orig = { innerWidth: $.fn.innerWidth, innerHeight: $.fn.innerHeight, outerWidth: $.fn.outerWidth, outerHeight: $.fn.outerHeight }; function reduce( elem, size, border, margin ) { $.each( side, function() { size -= parseFloat( $.curCSS( elem, "padding" + this, true) ) || 0; if ( border ) { size -= parseFloat( $.curCSS( elem, "border" + this + "Width", true) ) || 0; } if ( margin ) { size -= parseFloat( $.curCSS( elem, "margin" + this, true) ) || 0; } }); return size; } $.fn[ "inner" + name ] = function( size ) { if ( size === undefined ) { return orig[ "inner" + name ].call( this ); } return this.each(function() { $( this ).css( type, reduce( this, size ) + "px" ); }); }; $.fn[ "outer" + name] = function( size, margin ) { if ( typeof size !== "number" ) { return orig[ "outer" + name ].call( this, size ); } return this.each(function() { $( this).css( type, reduce( this, size, true, margin ) + "px" ); }); }; }); } // selectors function focusable( element, isTabIndexNotNaN ) { var nodeName = element.nodeName.toLowerCase(); if ( "area" === nodeName ) { var map = element.parentNode, mapName = map.name, img; if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { return false; } img = $( "img[usemap=#" + mapName + "]" )[0]; return !!img && visible( img ); } return ( /input|select|textarea|button|object/.test( nodeName ) ? !element.disabled : "a" == nodeName ? element.href || isTabIndexNotNaN : isTabIndexNotNaN) // the element and all of its ancestors must be visible && visible( element ); } function visible( element ) { return !$( element ).parents().andSelf().filter(function() { return $.curCSS( this, "visibility" ) === "hidden" || $.expr.filters.hidden( this ); }).length; } $.extend( $.expr[ ":" ], { data: $.expr.createPseudo ? $.expr.createPseudo(function( dataName ) { return function( elem ) { return !!$.data( elem, dataName ); }; }) : // support: jQuery <1.8 function( elem, i, match ) { return !!$.data( elem, match[ 3 ] ); }, focusable: function( element ) { return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) ); }, tabbable: function( element ) { var tabIndex = $.attr( element, "tabindex" ), isTabIndexNaN = isNaN( tabIndex ); return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN ); } }); // support $(function() { var body = document.body, div = body.appendChild( div = document.createElement( "div" ) ); // access offsetHeight before setting the style to prevent a layout bug // in IE 9 which causes the elemnt to continue to take up space even // after it is removed from the DOM (#8026) div.offsetHeight; $.extend( div.style, { minHeight: "100px", height: "auto", padding: 0, borderWidth: 0 }); $.support.minHeight = div.offsetHeight === 100; $.support.selectstart = "onselectstart" in div; // set display to none to avoid a layout bug in IE // http://dev.jquery.com/ticket/4014 body.removeChild( div ).style.display = "none"; }); // jQuery <1.4.3 uses curCSS, in 1.4.3 - 1.7.2 curCSS = css, 1.8+ only has css if ( !$.curCSS ) { $.curCSS = $.css; } // deprecated $.extend( $.ui, { // $.ui.plugin is deprecated. Use the proxy pattern instead. plugin: { add: function( module, option, set ) { var proto = $.ui[ module ].prototype; for ( var i in set ) { proto.plugins[ i ] = proto.plugins[ i ] || []; proto.plugins[ i ].push( [ option, set[ i ] ] ); } }, call: function( instance, name, args ) { var set = instance.plugins[ name ]; if ( !set || !instance.element[ 0 ].parentNode ) { return; } for ( var i = 0; i < set.length; i++ ) { if ( instance.options[ set[ i ][ 0 ] ] ) { set[ i ][ 1 ].apply( instance.element, args ); } } } }, // will be deprecated when we switch to jQuery 1.4 - use jQuery.contains() contains: function( a, b ) { return document.compareDocumentPosition ? a.compareDocumentPosition( b ) & 16 : a !== b && a.contains( b ); }, // only used by resizable hasScroll: function( el, a ) { //If overflow is hidden, the element might have extra content, but the user wants to hide it if ( $( el ).css( "overflow" ) === "hidden") { return false; } var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", has = false; if ( el[ scroll ] > 0 ) { return true; } // TODO: determine which cases actually cause this to happen // if the element doesn't have the scroll set, see if it's possible to // set the scroll el[ scroll ] = 1; has = ( el[ scroll ] > 0 ); el[ scroll ] = 0; return has; }, // these are odd functions, fix the API or move into individual plugins isOverAxis: function( x, reference, size ) { //Determines when x coordinate is over "b" element axis return ( x > reference ) && ( x < ( reference + size ) ); }, isOver: function( y, x, top, left, height, width ) { //Determines when x, y coordinates is over "b" element return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width ); } }); })( jQuery ); /*! * jQuery UI Widget 1.8.22 * * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Widget */ (function( $, undefined ) { // jQuery 1.4+ if ( $.cleanData ) { var _cleanData = $.cleanData; $.cleanData = function( elems ) { for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { try { $( elem ).triggerHandler( "remove" ); // http://bugs.jquery.com/ticket/8235 } catch( e ) {} } _cleanData( elems ); }; } else { var _remove = $.fn.remove; $.fn.remove = function( selector, keepData ) { return this.each(function() { if ( !keepData ) { if ( !selector || $.filter( selector, [ this ] ).length ) { $( "*", this ).add( [ this ] ).each(function() { try { $( this ).triggerHandler( "remove" ); // http://bugs.jquery.com/ticket/8235 } catch( e ) {} }); } } return _remove.call( $(this), selector, keepData ); }); }; } $.widget = function( name, base, prototype ) { var namespace = name.split( "." )[ 0 ], fullName; name = name.split( "." )[ 1 ]; fullName = namespace + "-" + name; if ( !prototype ) { prototype = base; base = $.Widget; } // create selector for plugin $.expr[ ":" ][ fullName ] = function( elem ) { return !!$.data( elem, name ); }; $[ namespace ] = $[ namespace ] || {}; $[ namespace ][ name ] = function( options, element ) { // allow instantiation without initializing for simple inheritance if ( arguments.length ) { this._createWidget( options, element ); } }; var basePrototype = new base(); // we need to make the options hash a property directly on the new instance // otherwise we'll modify the options hash on the prototype that we're // inheriting from // $.each( basePrototype, function( key, val ) { // if ( $.isPlainObject(val) ) { // basePrototype[ key ] = $.extend( {}, val ); // } // }); basePrototype.options = $.extend( true, {}, basePrototype.options ); $[ namespace ][ name ].prototype = $.extend( true, basePrototype, { namespace: namespace, widgetName: name, widgetEventPrefix: $[ namespace ][ name ].prototype.widgetEventPrefix || name, widgetBaseClass: fullName }, prototype ); $.widget.bridge( name, $[ namespace ][ name ] ); }; $.widget.bridge = function( name, object ) { $.fn[ name ] = function( options ) { var isMethodCall = typeof options === "string", args = Array.prototype.slice.call( arguments, 1 ), returnValue = this; // allow multiple hashes to be passed on init options = !isMethodCall && args.length ? $.extend.apply( null, [ true, options ].concat(args) ) : options; // prevent calls to internal methods if ( isMethodCall && options.charAt( 0 ) === "_" ) { return returnValue; } if ( isMethodCall ) { this.each(function() { var instance = $.data( this, name ), methodValue = instance && $.isFunction( instance[options] ) ? instance[ options ].apply( instance, args ) : instance; // TODO: add this back in 1.9 and use $.error() (see #5972) // if ( !instance ) { // throw "cannot call methods on " + name + " prior to initialization; " + // "attempted to call method '" + options + "'"; // } // if ( !$.isFunction( instance[options] ) ) { // throw "no such method '" + options + "' for " + name + " widget instance"; // } // var methodValue = instance[ options ].apply( instance, args ); if ( methodValue !== instance && methodValue !== undefined ) { returnValue = methodValue; return false; } }); } else { this.each(function() { var instance = $.data( this, name ); if ( instance ) { instance.option( options || {} )._init(); } else { $.data( this, name, new object( options, this ) ); } }); } return returnValue; }; }; $.Widget = function( options, element ) { // allow instantiation without initializing for simple inheritance if ( arguments.length ) { this._createWidget( options, element ); } }; $.Widget.prototype = { widgetName: "widget", widgetEventPrefix: "", options: { disabled: false }, _createWidget: function( options, element ) { // $.widget.bridge stores the plugin instance, but we do it anyway // so that it's stored even before the _create function runs $.data( element, this.widgetName, this ); this.element = $( element ); this.options = $.extend( true, {}, this.options, this._getCreateOptions(), options ); var self = this; this.element.bind( "remove." + this.widgetName, function() { self.destroy(); }); this._create(); this._trigger( "create" ); this._init(); }, _getCreateOptions: function() { return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ]; }, _create: function() {}, _init: function() {}, destroy: function() { this.element .unbind( "." + this.widgetName ) .removeData( this.widgetName ); this.widget() .unbind( "." + this.widgetName ) .removeAttr( "aria-disabled" ) .removeClass( this.widgetBaseClass + "-disabled " + "ui-state-disabled" ); }, widget: function() { return this.element; }, option: function( key, value ) { var options = key; if ( arguments.length === 0 ) { // don't return a reference to the internal hash return $.extend( {}, this.options ); } if (typeof key === "string" ) { if ( value === undefined ) { return this.options[ key ]; } options = {}; options[ key ] = value; } this._setOptions( options ); return this; }, _setOptions: function( options ) { var self = this; $.each( options, function( key, value ) { self._setOption( key, value ); }); return this; }, _setOption: function( key, value ) { this.options[ key ] = value; if ( key === "disabled" ) { this.widget() [ value ? "addClass" : "removeClass"]( this.widgetBaseClass + "-disabled" + " " + "ui-state-disabled" ) .attr( "aria-disabled", value ); } return this; }, enable: function() { return this._setOption( "disabled", false ); }, disable: function() { return this._setOption( "disabled", true ); }, _trigger: function( type, event, data ) { var prop, orig, callback = this.options[ type ]; data = data || {}; event = $.Event( event ); event.type = ( type === this.widgetEventPrefix ? type : this.widgetEventPrefix + type ).toLowerCase(); // the original event may come from any element // so we need to reset the target on the new event event.target = this.element[ 0 ]; // copy original event properties over to the new event orig = event.originalEvent; if ( orig ) { for ( prop in orig ) { if ( !( prop in event ) ) { event[ prop ] = orig[ prop ]; } } } this.element.trigger( event, data ); return !( $.isFunction(callback) && callback.call( this.element[0], event, data ) === false || event.isDefaultPrevented() ); } }; })( jQuery ); /*! * jQuery UI Accordion 1.8.22 * * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Accordion * * Depends: * jquery.ui.core.js * jquery.ui.widget.js */ (function( $, undefined ) { $.widget( "ui.accordion", { options: { active: 0, animated: "slide", autoHeight: true, clearStyle: false, collapsible: false, event: "click", fillSpace: false, header: "> li > :first-child,> :not(li):even", icons: { header: "ui-icon-triangle-1-e", headerSelected: "ui-icon-triangle-1-s" }, navigation: false, navigationFilter: function() { return this.href.toLowerCase() === location.href.toLowerCase(); } }, _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" ); }); self.headers.next() .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" ); 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(); } } } 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" ); self._createIcons(); self.resize(); // ARIA self.element.attr( "role", "tablist" ); self.headers .attr( "role", "tab" ) .bind( "keydown.accordion", function( event ) { return self._keydown( event ); }) .next() .attr( "role", "tabpanel" ); self.headers .not( self.active || "" ) .attr({ "aria-expanded": "false", "aria-selected": "false", tabIndex: -1 }) .next() .hide(); // make sure at least one header is in the tab order if ( !self.active.length ) { self.headers.eq( 0 ).attr( "tabIndex", 0 ); } else { self.active .attr({ "aria-expanded": "true", "aria-selected": "true", tabIndex: 0 }); } // only need links in tab order for Safari if ( !$.browser.safari ) { self.headers.find( "a" ).attr( "tabIndex", -1 ); } if ( options.event ) { self.headers.bind( options.event.split(" ").join(".accordion ") + ".accordion", function(event) { self._clickHandler.call( self, event, this ); event.preventDefault(); }); } }, _createIcons: function() { var options = this.options; if ( options.icons ) { $( "" ) .addClass( "ui-icon " + options.icons.header ) .prependTo( this.headers ); this.active.children( ".ui-icon" ) .toggleClass(options.icons.header) .toggleClass(options.icons.headerSelected); this.element.addClass( "ui-accordion-icons" ); } }, _destroyIcons: function() { this.headers.children( ".ui-icon" ).remove(); this.element.removeClass( "ui-accordion-icons" ); }, destroy: function() { var options = this.options; this.element .removeClass( "ui-accordion ui-widget ui-helper-reset" ) .removeAttr( "role" ); 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" ) .removeAttr( "role" ) .removeAttr( "aria-expanded" ) .removeAttr( "aria-selected" ) .removeAttr( "tabIndex" ); this.headers.find( "a" ).removeAttr( "tabIndex" ); this._destroyIcons(); var 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 ) { 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 == "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" ); } }, _keydown: function( event ) { if ( this.options.disabled || 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._clickHandler( { target: event.target }, event.target ); event.preventDefault(); } if ( toFocus ) { $( event.target ).attr( "tabIndex", -1 ); $( toFocus ).attr( "tabIndex", 0 ); toFocus.focus(); return false; } return true; }, resize: function() { var options = this.options, maxHeight; if ( options.fillSpace ) { if ( $.browser.msie ) { var defOverflow = this.element.parent().css( "overflow" ); this.element.parent().css( "overflow", "hidden"); } maxHeight = this.element.parent().height(); if ($.browser.msie) { this.element.parent().css( "overflow", defOverflow ); } 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 ( options.autoHeight ) { maxHeight = 0; this.headers.next() .each(function() { maxHeight = Math.max( maxHeight, $( this ).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 var active = this._findActive( index )[ 0 ]; this._clickHandler( { target: active }, active ); return this; }, _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)" ); }, // 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 ); return; } // 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 ) ) { 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] ); // 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 ); // switch classes 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 ); if ( !clickedIsActive ) { clicked .removeClass( "ui-state-default ui-corner-all" ) .addClass( "ui-state-active ui-corner-top" ) .children( ".ui-icon" ) .removeClass( options.icons.header ) .addClass( options.icons.headerSelected ); clicked .next() .addClass( "ui-accordion-content-active" ); } return; }, _toggle: function( toShow, toHide, data, clickedIsActive, down ) { var self = this, options = self.options; self.toShow = toShow; self.toHide = toHide; self.data = data; var complete = function() { if ( !self ) { return; } return self._completed.apply( self, arguments ); }; // 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 }; } if ( !options.proxied ) { options.proxied = options.animated; } if ( !options.proxiedDuration ) { options.proxiedDuration = options.duration; } options.animated = $.isFunction( options.proxied ) ? options.proxied( animOptions ) : options.proxied; 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"; } if ( !animations[ easing ] ) { animations[ easing ] = function( options ) { this.slide( options, { easing: easing, duration: duration || 700 }); }; } animations[ easing ]( animOptions ); } else { if ( options.collapsible && clickedIsActive ) { toShow.toggle(); } else { toHide.hide(); toShow.show(); } complete( true ); } // 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(); }, _completed: function( cancel ) { this.running = cancel ? 0 : --this.running; if ( this.running ) { return; } if ( this.options.clearStyle ) { this.toShow.add( this.toHide ).css({ height: "", overflow: "" }); } // 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; } this._trigger( "change", null, this.data ); } }); $.extend( $.ui.accordion, { version: "1.8.22", 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; } if ( !options.toShow.size() ) { options.toHide.animate({ height: "hide", paddingTop: "hide", paddingBottom: "hide" }, options ); return; } 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(); } }); }, bounceslide: function( options ) { this.slide( options, { easing: options.down ? "easeOutBounce" : "swing", duration: options.down ? 1000 : 200 }); } } }); })( jQuery ); /*! * jQuery UI Tabs 1.8.22 * * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Tabs * * Depends: * jquery.ui.core.js * jquery.ui.widget.js */ (function( $, undefined ) { var tabId = 0, listId = 0; function getNextTabId() { return ++tabId; } function getNextListId() { return ++listId; } $.widget( "ui.tabs", { options: { add: null, ajaxOptions: null, cache: false, cookie: null, // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true } collapsible: false, disable: null, disabled: [], enable: null, event: "click", fx: null, // e.g. { height: 'toggle', opacity: 'toggle', duration: 200 } idPrefix: "ui-tabs-", load: null, panelTemplate: "
", remove: null, select: null, show: null, spinner: "Loading…", tabTemplate: "
  • #{label}
  • " }, _create: function() { this._tabify( true ); }, _setOption: function( key, value ) { if ( key == "selected" ) { if (this.options.collapsible && value == this.options.selected ) { return; } this.select( value ); } else { this.options[ key ] = value; this._tabify(); } }, _tabId: function( a ) { return a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF-]/g, "" ) || this.options.idPrefix + getNextTabId(); }, _sanitizeSelector: function( hash ) { // we need this because an id may contain a ":" return hash.replace( /:/g, "\\:" ); }, _cookie: function() { var cookie = this.cookie || ( this.cookie = this.options.cookie.name || "ui-tabs-" + getNextListId() ); return $.cookie.apply( null, [ cookie ].concat( $.makeArray( arguments ) ) ); }, _ui: function( tab, panel ) { return { tab: tab, panel: panel, index: this.anchors.index( tab ) }; }, _cleanup: function() { // restore all former loading tabs labels this.lis.filter( ".ui-state-processing" ) .removeClass( "ui-state-processing" ) .find( "span:data(label.tabs)" ) .each(function() { var el = $( this ); el.html( el.data( "label.tabs" ) ).removeData( "label.tabs" ); }); }, _tabify: function( init ) { var self = this, o = this.options, fragmentId = /^#.+/; // Safari 2 reports '#' for an empty hash this.list = this.element.find( "ol,ul" ).eq( 0 ); this.lis = $( " > li:has(a[href])", this.list ); this.anchors = this.lis.map(function() { return $( "a", this )[ 0 ]; }); this.panels = $( [] ); this.anchors.each(function( i, a ) { var href = $( a ).attr( "href" ); // For dynamically created HTML that contains a hash as href IE < 8 expands // such href to the full page url with hash and then misinterprets tab as ajax. // Same consideration applies for an added tab with a fragment identifier // since a[href=#fragment-identifier] does unexpectedly not match. // Thus normalize href attribute... var hrefBase = href.split( "#" )[ 0 ], baseEl; if ( hrefBase && ( hrefBase === location.toString().split( "#" )[ 0 ] || ( baseEl = $( "base" )[ 0 ]) && hrefBase === baseEl.href ) ) { href = a.hash; a.href = href; } // inline tab if ( fragmentId.test( href ) ) { self.panels = self.panels.add( self.element.find( self._sanitizeSelector( href ) ) ); // remote tab // prevent loading the page itself if href is just "#" } else if ( href && href !== "#" ) { // required for restore on destroy $.data( a, "href.tabs", href ); // TODO until #3808 is fixed strip fragment identifier from url // (IE fails to load from such url) $.data( a, "load.tabs", href.replace( /#.*$/, "" ) ); var id = self._tabId( a ); a.href = "#" + id; var $panel = self.element.find( "#" + id ); if ( !$panel.length ) { $panel = $( o.panelTemplate ) .attr( "id", id ) .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) .insertAfter( self.panels[ i - 1 ] || self.list ); $panel.data( "destroy.tabs", true ); } self.panels = self.panels.add( $panel ); // invalid tab href } else { o.disabled.push( i ); } }); // initialization from scratch if ( init ) { // attach necessary classes for styling this.element.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" ); this.list.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ); this.lis.addClass( "ui-state-default ui-corner-top" ); this.panels.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ); // Selected tab // use "selected" option or try to retrieve: // 1. from fragment identifier in url // 2. from cookie // 3. from selected class attribute on
  • if ( o.selected === undefined ) { if ( location.hash ) { this.anchors.each(function( i, a ) { if ( a.hash == location.hash ) { o.selected = i; return false; } }); } if ( typeof o.selected !== "number" && o.cookie ) { o.selected = parseInt( self._cookie(), 10 ); } if ( typeof o.selected !== "number" && this.lis.filter( ".ui-tabs-selected" ).length ) { o.selected = this.lis.index( this.lis.filter( ".ui-tabs-selected" ) ); } o.selected = o.selected || ( this.lis.length ? 0 : -1 ); } else if ( o.selected === null ) { // usage of null is deprecated, TODO remove in next release o.selected = -1; } // sanity check - default to first tab... o.selected = ( ( o.selected >= 0 && this.anchors[ o.selected ] ) || o.selected < 0 ) ? o.selected : 0; // Take disabling tabs via class attribute from HTML // into account and update option properly. // A selected tab cannot become disabled. o.disabled = $.unique( o.disabled.concat( $.map( this.lis.filter( ".ui-state-disabled" ), function( n, i ) { return self.lis.index( n ); }) ) ).sort(); if ( $.inArray( o.selected, o.disabled ) != -1 ) { o.disabled.splice( $.inArray( o.selected, o.disabled ), 1 ); } // highlight selected tab this.panels.addClass( "ui-tabs-hide" ); this.lis.removeClass( "ui-tabs-selected ui-state-active" ); // check for length avoids error when initializing empty list if ( o.selected >= 0 && this.anchors.length ) { self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) ).removeClass( "ui-tabs-hide" ); this.lis.eq( o.selected ).addClass( "ui-tabs-selected ui-state-active" ); // seems to be expected behavior that the show callback is fired self.element.queue( "tabs", function() { self._trigger( "show", null, self._ui( self.anchors[ o.selected ], self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) )[ 0 ] ) ); }); this.load( o.selected ); } // clean up to avoid memory leaks in certain versions of IE 6 // TODO: namespace this event $( window ).bind( "unload", function() { self.lis.add( self.anchors ).unbind( ".tabs" ); self.lis = self.anchors = self.panels = null; }); // update selected after add/remove } else { o.selected = this.lis.index( this.lis.filter( ".ui-tabs-selected" ) ); } // update collapsible // TODO: use .toggleClass() this.element[ o.collapsible ? "addClass" : "removeClass" ]( "ui-tabs-collapsible" ); // set or update cookie after init and add/remove respectively if ( o.cookie ) { this._cookie( o.selected, o.cookie ); } // disable tabs for ( var i = 0, li; ( li = this.lis[ i ] ); i++ ) { $( li )[ $.inArray( i, o.disabled ) != -1 && // TODO: use .toggleClass() !$( li ).hasClass( "ui-tabs-selected" ) ? "addClass" : "removeClass" ]( "ui-state-disabled" ); } // reset cache if switching from cached to not cached if ( o.cache === false ) { this.anchors.removeData( "cache.tabs" ); } // remove all handlers before, tabify may run on existing tabs after add or option change this.lis.add( this.anchors ).unbind( ".tabs" ); if ( o.event !== "mouseover" ) { var addState = function( state, el ) { if ( el.is( ":not(.ui-state-disabled)" ) ) { el.addClass( "ui-state-" + state ); } }; var removeState = function( state, el ) { el.removeClass( "ui-state-" + state ); }; this.lis.bind( "mouseover.tabs" , function() { addState( "hover", $( this ) ); }); this.lis.bind( "mouseout.tabs", function() { removeState( "hover", $( this ) ); }); this.anchors.bind( "focus.tabs", function() { addState( "focus", $( this ).closest( "li" ) ); }); this.anchors.bind( "blur.tabs", function() { removeState( "focus", $( this ).closest( "li" ) ); }); } // set up animations var hideFx, showFx; if ( o.fx ) { if ( $.isArray( o.fx ) ) { hideFx = o.fx[ 0 ]; showFx = o.fx[ 1 ]; } else { hideFx = showFx = o.fx; } } // Reset certain styles left over from animation // and prevent IE's ClearType bug... function resetStyle( $el, fx ) { $el.css( "display", "" ); if ( !$.support.opacity && fx.opacity ) { $el[ 0 ].style.removeAttribute( "filter" ); } } // Show a tab... var showTab = showFx ? function( clicked, $show ) { $( clicked ).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" ); $show.hide().removeClass( "ui-tabs-hide" ) // avoid flicker that way .animate( showFx, showFx.duration || "normal", function() { resetStyle( $show, showFx ); self._trigger( "show", null, self._ui( clicked, $show[ 0 ] ) ); }); } : function( clicked, $show ) { $( clicked ).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" ); $show.removeClass( "ui-tabs-hide" ); self._trigger( "show", null, self._ui( clicked, $show[ 0 ] ) ); }; // Hide a tab, $show is optional... var hideTab = hideFx ? function( clicked, $hide ) { $hide.animate( hideFx, hideFx.duration || "normal", function() { self.lis.removeClass( "ui-tabs-selected ui-state-active" ); $hide.addClass( "ui-tabs-hide" ); resetStyle( $hide, hideFx ); self.element.dequeue( "tabs" ); }); } : function( clicked, $hide, $show ) { self.lis.removeClass( "ui-tabs-selected ui-state-active" ); $hide.addClass( "ui-tabs-hide" ); self.element.dequeue( "tabs" ); }; // attach tab event handler, unbind to avoid duplicates from former tabifying... this.anchors.bind( o.event + ".tabs", function() { var el = this, $li = $(el).closest( "li" ), $hide = self.panels.filter( ":not(.ui-tabs-hide)" ), $show = self.element.find( self._sanitizeSelector( el.hash ) ); // If tab is already selected and not collapsible or tab disabled or // or is already loading or click callback returns false stop here. // Check if click handler returns false last so that it is not executed // for a disabled or loading tab! if ( ( $li.hasClass( "ui-tabs-selected" ) && !o.collapsible) || $li.hasClass( "ui-state-disabled" ) || $li.hasClass( "ui-state-processing" ) || self.panels.filter( ":animated" ).length || self._trigger( "select", null, self._ui( this, $show[ 0 ] ) ) === false ) { this.blur(); return false; } o.selected = self.anchors.index( this ); self.abort(); // if tab may be closed if ( o.collapsible ) { if ( $li.hasClass( "ui-tabs-selected" ) ) { o.selected = -1; if ( o.cookie ) { self._cookie( o.selected, o.cookie ); } self.element.queue( "tabs", function() { hideTab( el, $hide ); }).dequeue( "tabs" ); this.blur(); return false; } else if ( !$hide.length ) { if ( o.cookie ) { self._cookie( o.selected, o.cookie ); } self.element.queue( "tabs", function() { showTab( el, $show ); }); // TODO make passing in node possible, see also http://dev.jqueryui.com/ticket/3171 self.load( self.anchors.index( this ) ); this.blur(); return false; } } if ( o.cookie ) { self._cookie( o.selected, o.cookie ); } // show new tab if ( $show.length ) { if ( $hide.length ) { self.element.queue( "tabs", function() { hideTab( el, $hide ); }); } self.element.queue( "tabs", function() { showTab( el, $show ); }); self.load( self.anchors.index( this ) ); } else { throw "jQuery UI Tabs: Mismatching fragment identifier."; } // Prevent IE from keeping other link focussed when using the back button // and remove dotted border from clicked link. This is controlled via CSS // in modern browsers; blur() removes focus from address bar in Firefox // which can become a usability and annoying problem with tabs('rotate'). if ( $.browser.msie ) { this.blur(); } }); // disable click in any case this.anchors.bind( "click.tabs", function(){ return false; }); }, _getIndex: function( index ) { // meta-function to give users option to provide a href string instead of a numerical index. // also sanitizes numerical indexes to valid values. if ( typeof index == "string" ) { index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) ); } return index; }, destroy: function() { var o = this.options; this.abort(); this.element .unbind( ".tabs" ) .removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" ) .removeData( "tabs" ); this.list.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ); this.anchors.each(function() { var href = $.data( this, "href.tabs" ); if ( href ) { this.href = href; } var $this = $( this ).unbind( ".tabs" ); $.each( [ "href", "load", "cache" ], function( i, prefix ) { $this.removeData( prefix + ".tabs" ); }); }); this.lis.unbind( ".tabs" ).add( this.panels ).each(function() { if ( $.data( this, "destroy.tabs" ) ) { $( this ).remove(); } else { $( this ).removeClass([ "ui-state-default", "ui-corner-top", "ui-tabs-selected", "ui-state-active", "ui-state-hover", "ui-state-focus", "ui-state-disabled", "ui-tabs-panel", "ui-widget-content", "ui-corner-bottom", "ui-tabs-hide" ].join( " " ) ); } }); if ( o.cookie ) { this._cookie( null, o.cookie ); } return this; }, add: function( url, label, index ) { if ( index === undefined ) { index = this.anchors.length; } var self = this, o = this.options, $li = $( o.tabTemplate.replace( /#\{href\}/g, url ).replace( /#\{label\}/g, label ) ), id = !url.indexOf( "#" ) ? url.replace( "#", "" ) : this._tabId( $( "a", $li )[ 0 ] ); $li.addClass( "ui-state-default ui-corner-top" ).data( "destroy.tabs", true ); // try to find an existing element before creating a new one var $panel = self.element.find( "#" + id ); if ( !$panel.length ) { $panel = $( o.panelTemplate ) .attr( "id", id ) .data( "destroy.tabs", true ); } $panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide" ); if ( index >= this.lis.length ) { $li.appendTo( this.list ); $panel.appendTo( this.list[ 0 ].parentNode ); } else { $li.insertBefore( this.lis[ index ] ); $panel.insertBefore( this.panels[ index ] ); } o.disabled = $.map( o.disabled, function( n, i ) { return n >= index ? ++n : n; }); this._tabify(); if ( this.anchors.length == 1 ) { o.selected = 0; $li.addClass( "ui-tabs-selected ui-state-active" ); $panel.removeClass( "ui-tabs-hide" ); this.element.queue( "tabs", function() { self._trigger( "show", null, self._ui( self.anchors[ 0 ], self.panels[ 0 ] ) ); }); this.load( 0 ); } this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) ); return this; }, remove: function( index ) { index = this._getIndex( index ); var o = this.options, $li = this.lis.eq( index ).remove(), $panel = this.panels.eq( index ).remove(); // If selected tab was removed focus tab to the right or // in case the last tab was removed the tab to the left. if ( $li.hasClass( "ui-tabs-selected" ) && this.anchors.length > 1) { this.select( index + ( index + 1 < this.anchors.length ? 1 : -1 ) ); } o.disabled = $.map( $.grep( o.disabled, function(n, i) { return n != index; }), function( n, i ) { return n >= index ? --n : n; }); this._tabify(); this._trigger( "remove", null, this._ui( $li.find( "a" )[ 0 ], $panel[ 0 ] ) ); return this; }, enable: function( index ) { index = this._getIndex( index ); var o = this.options; if ( $.inArray( index, o.disabled ) == -1 ) { return; } this.lis.eq( index ).removeClass( "ui-state-disabled" ); o.disabled = $.grep( o.disabled, function( n, i ) { return n != index; }); this._trigger( "enable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) ); return this; }, disable: function( index ) { index = this._getIndex( index ); var self = this, o = this.options; // cannot disable already selected tab if ( index != o.selected ) { this.lis.eq( index ).addClass( "ui-state-disabled" ); o.disabled.push( index ); o.disabled.sort(); this._trigger( "disable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) ); } return this; }, select: function( index ) { index = this._getIndex( index ); if ( index == -1 ) { if ( this.options.collapsible && this.options.selected != -1 ) { index = this.options.selected; } else { return this; } } this.anchors.eq( index ).trigger( this.options.event + ".tabs" ); return this; }, load: function( index ) { index = this._getIndex( index ); var self = this, o = this.options, a = this.anchors.eq( index )[ 0 ], url = $.data( a, "load.tabs" ); this.abort(); // not remote or from cache if ( !url || this.element.queue( "tabs" ).length !== 0 && $.data( a, "cache.tabs" ) ) { this.element.dequeue( "tabs" ); return; } // load remote from here on this.lis.eq( index ).addClass( "ui-state-processing" ); if ( o.spinner ) { var span = $( "span", a ); span.data( "label.tabs", span.html() ).html( o.spinner ); } this.xhr = $.ajax( $.extend( {}, o.ajaxOptions, { url: url, success: function( r, s ) { self.element.find( self._sanitizeSelector( a.hash ) ).html( r ); // take care of tab labels self._cleanup(); if ( o.cache ) { $.data( a, "cache.tabs", true ); } self._trigger( "load", null, self._ui( self.anchors[ index ], self.panels[ index ] ) ); try { o.ajaxOptions.success( r, s ); } catch ( e ) {} }, error: function( xhr, s, e ) { // take care of tab labels self._cleanup(); self._trigger( "load", null, self._ui( self.anchors[ index ], self.panels[ index ] ) ); try { // Passing index avoid a race condition when this method is // called after the user has selected another tab. // Pass the anchor that initiated this request allows // loadError to manipulate the tab content panel via $(a.hash) o.ajaxOptions.error( xhr, s, index, a ); } catch ( e ) {} } } ) ); // last, so that load event is fired before show... self.element.dequeue( "tabs" ); return this; }, abort: function() { // stop possibly running animations this.element.queue( [] ); this.panels.stop( false, true ); // "tabs" queue must not contain more than two elements, // which are the callbacks for the latest clicked tab... this.element.queue( "tabs", this.element.queue( "tabs" ).splice( -2, 2 ) ); // terminate pending requests from other tabs if ( this.xhr ) { this.xhr.abort(); delete this.xhr; } // take care of tab labels this._cleanup(); return this; }, url: function( index, url ) { this.anchors.eq( index ).removeData( "cache.tabs" ).data( "load.tabs", url ); return this; }, length: function() { return this.anchors.length; } }); $.extend( $.ui.tabs, { version: "1.8.22" }); /* * Tabs Extensions */ /* * Rotate */ $.extend( $.ui.tabs.prototype, { rotation: null, rotate: function( ms, continuing ) { var self = this, o = this.options; var rotate = self._rotate || ( self._rotate = function( e ) { clearTimeout( self.rotation ); self.rotation = setTimeout(function() { var t = o.selected; self.select( ++t < self.anchors.length ? t : 0 ); }, ms ); if ( e ) { e.stopPropagation(); } }); var stop = self._unrotate || ( self._unrotate = !continuing ? function(e) { if (e.clientX) { // in case of a true click self.rotate(null); } } : function( e ) { rotate(); }); // start rotation if ( ms ) { this.element.bind( "tabsshow", rotate ); this.anchors.bind( o.event + ".tabs", stop ); rotate(); // stop rotation } else { clearTimeout( self.rotation ); this.element.unbind( "tabsshow", rotate ); this.anchors.unbind( o.event + ".tabs", stop ); delete this._rotate; delete this._unrotate; } return this; } }); })( jQuery );