/* * jQuery UI Accordion *  * Copyright (c) 2007, 2008 Jörn Zaefferer * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * http://docs.jquery.com/UI/Accordion * * Depends: *	ui.core.js */(function($) {$.widget("ui.accordion", {init: function() {var options = this.options;if ( options.navigation ) {var current = this.element.find("a").filter(options.navigationFilter);if ( current.length ) {if ( current.filter(options.header).length ) {options.active = current;} else {options.active = current.parent().parent().prev();current.addClass("current");}}}// calculate active if not specified, using the first headeroptions.headers = this.element.find(options.header);options.active = findActive(options.headers, options.active);// IE7-/Win - Extra vertical space in Lists fixedif ($.browser.msie) {this.element.find('a').css('zoom', '1');}if (!this.element.hasClass("ui-accordion")) {this.element.addClass("ui-accordion");$("<span class='ui-accordion-left'/>").insertBefore(options.headers);$("<span class='ui-accordion-right'/>").appendTo(options.headers);options.headers.addClass("ui-accordion-header").attr("tabindex", "0");}var maxHeight;if ( options.fillSpace ) {maxHeight = this.element.parent().height();options.headers.each(function() {maxHeight -= $(this).outerHeight();});var maxPadding = 0;options.headers.next().each(function() {maxPadding = Math.max(maxPadding, $(this).innerHeight() - $(this).height());}).height(maxHeight - maxPadding);} else if ( options.autoHeight ) {maxHeight = 0;options.headers.next().each(function() {maxHeight = Math.max(maxHeight, $(this).outerHeight());}).height(maxHeight);}options.headers.not(options.active || "").next().hide();options.active.parent().andSelf().addClass(options.selectedClass);if (options.event) {this.element.bind((options.event) + ".accordion", clickHandler);}},activate: function(index) {// call clickHandler with custom eventclickHandler.call(this.element[0], {target: findActive( this.options.headers, index )[0]});},destroy: function() {this.options.headers.next().css("display", "");if ( this.options.fillSpace || this.options.autoHeight ) {this.options.headers.next().css("height", "");}$.removeData(this.element[0], "accordion");this.element.removeClass("ui-accordion").unbind(".accordion");}});function scopeCallback(callback, scope) {return function() {return callback.apply(scope, arguments);};};function completed(cancel) {// if removed while animated data can be emptyif (!$.data(this, "accordion")) {return;}var instance = $.data(this, "accordion");var options = instance.options;options.running = cancel ? 0 : --options.running;if ( options.running ) {return;}if ( options.clearStyle ) {options.toShow.add(options.toHide).css({height: "",overflow: ""});}$(this).triggerHandler("accordionchange", [$.event.fix({type: 'accordionchange', target: instance.element[0]}), options.data], options.change);}function toggle(toShow, toHide, data, clickedActive, down) {var options = $.data(this, "accordion").options;options.toShow = toShow;options.toHide = toHide;options.data = data;var complete = scopeCallback(completed, this);// count elements to animateoptions.running = toHide.size() === 0 ? toShow.size() : toHide.size();if ( options.animated ) {if ( !options.alwaysOpen && clickedActive ) {$.ui.accordion.animations[options.animated]({toShow: jQuery([]),toHide: toHide,complete: complete,down: down,autoHeight: options.autoHeight});} else {$.ui.accordion.animations[options.animated]({toShow: toShow,toHide: toHide,complete: complete,down: down,autoHeight: options.autoHeight});}} else {if ( !options.alwaysOpen && clickedActive ) {toShow.toggle();} else {toHide.hide();toShow.show();}complete(true);}}function clickHandler(event) {var options = $.data(this, "accordion").options;if (options.disabled) {return false;}// called only when using activate(false) to close all parts programmaticallyif ( !event.target && !options.alwaysOpen ) {options.active.parent().andSelf().toggleClass(options.selectedClass);var toHide = options.active.next(),data = {options: options,newHeader: jQuery([]),oldHeader: options.active,newContent: jQuery([]),oldContent: toHide},toShow = (options.active = $([]));toggle.call(this, toShow, toHide, data );return false;}// get the click targetvar clicked = $(event.target);// due to the event delegation model, we have to check if one// of the parent elements is our actual header, and find that// otherwise stick with the initial targetclicked = $( clicked.parents(options.header)[0] || clicked );var clickedActive = clicked[0] == options.active[0];// if animations are still active, or the active header is the target, ignore clickif (options.running || (options.alwaysOpen && clickedActive)) {return false;}if (!clicked.is(options.header)) {return;}// switch classesoptions.active.parent().andSelf().toggleClass(options.selectedClass);if ( !clickedActive ) {clicked.parent().andSelf().addClass(options.selectedClass);}// find elements to show and hidevar toShow = clicked.next(),toHide = options.active.next(),//data = [clicked, options.active, toShow, toHide],data = {options: options,newHeader: clicked,oldHeader: options.active,newContent: toShow,oldContent: toHide},down = options.headers.index( options.active[0] ) > options.headers.index( clicked[0] );options.active = clickedActive ? $([]) : clicked;toggle.call(this, toShow, toHide, data, clickedActive, down );return false;};function findActive(headers, selector) {return selector != undefined? typeof selector == "number"? headers.filter(":eq(" + selector + ")"): headers.not(headers.not(selector)): selector === false? $([]): headers.filter(":eq(0)");}$.extend($.ui.accordion, {defaults: {selectedClass: "selected",alwaysOpen: true,animated: 'slide',event: "click",header: "a",autoHeight: true,running: 0,navigationFilter: function() {return this.href.toLowerCase() == location.href.toLowerCase();}},animations: {slide: function(options, additions) {options = $.extend({easing: "swing",duration: 300}, options, additions);if ( !options.toHide.size() ) {options.toShow.animate({height: "show"}, options);return;}var hideHeight = options.toHide.height(),showHeight = options.toShow.height(),difference = showHeight / hideHeight;options.toShow.css({ height: 0, overflow: 'hidden' }).show();options.toHide.filter(":hidden").each(options.complete).end().filter(":visible").animate({height:"hide"},{step: function(now) {var current = (hideHeight - now) * difference;if ($.browser.msie || $.browser.opera) {current = Math.ceil(current);}options.toShow.height( current );},duration: options.duration,easing: options.easing,complete: function() {if ( !options.autoHeight ) {options.toShow.css("height", "auto");}options.complete();}});},bounceslide: function(options) {this.slide(options, {easing: options.down ? "bounceout" : "swing",duration: options.down ? 1000 : 200});},easeslide: function(options) {this.slide(options, {easing: "easeinout",duration: 700});}}});// deprecated, use accordion("activate", index) instead$.fn.activate = function(index) {return this.accordion("activate", index);};})(jQuery);