From 59c9f75951bb1d17b751894f5bd9ad9e207c0b03 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Scott=20Gonz=C3=A1lez?= Date: Thu, 22 Jul 2010 19:10:14 -0400 Subject: [PATCH] Accordion: Coding standards. --- ui/jquery.ui.accordion.js | 487 ++++++++++++++++++++++---------------- 1 file changed, 280 insertions(+), 207 deletions(-) diff --git a/ui/jquery.ui.accordion.js b/ui/jquery.ui.accordion.js index f21b63cce..bea5a3e0f 100644 --- a/ui/jquery.ui.accordion.js +++ b/ui/jquery.ui.accordion.js @@ -13,10 +13,10 @@ */ (function( $, undefined ) { -$.widget("ui.accordion", { +$.widget( "ui.accordion", { options: { active: 0, - animated: 'slide', + animated: "slide", autoHeight: true, clearStyle: false, collapsible: false, @@ -29,293 +29,337 @@ $.widget("ui.accordion", { }, navigation: false, navigationFilter: function() { - return this.href.toLowerCase() == location.href.toLowerCase(); + return this.href.toLowerCase() === location.href.toLowerCase(); } }, + _create: function() { var o = this.options, self = this; this.running = 0; - this.element.addClass("ui-accordion ui-widget ui-helper-reset"); - + this.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 - this.element.children("li").addClass("ui-accordion-li-fix"); + this.element.children( "li" ).addClass( "ui-accordion-li-fix" ); - this.headers = this.element.find(o.header) - .addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all") - .bind("mouseenter.accordion", function() { - if (o.disabled) { return; } - $(this).addClass('ui-state-hover'); + this.headers = this.element.find( o.header ) + .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" ) + .bind( "mouseenter.accordion", function() { + if ( o.disabled ) { + return; + } + $( this ).addClass( "ui-state-hover" ); }) - .bind("mouseleave.accordion", function() { - if (o.disabled) { return; } - $(this).removeClass('ui-state-hover'); + .bind( "mouseleave.accordion", function() { + if ( o.disabled ) { + return; + } + $( this ).removeClass( "ui-state-hover" ); }) - .bind("focus.accordion", function() { - if (o.disabled) { return; } - $(this).addClass('ui-state-focus'); + .bind( "focus.accordion", function() { + if ( o.disabled ) { + return; + } + $( this ).addClass( "ui-state-focus" ); }) - .bind("blur.accordion", function() { - if (o.disabled) { return; } - $(this).removeClass('ui-state-focus'); + .bind( "blur.accordion", function() { + if ( o.disabled ) { + return; + } + $( this ).removeClass( "ui-state-focus" ); }); - this.headers - .next() - .addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom"); + this.headers.next() + .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" ); if ( o.navigation ) { - var current = this.element.find("a").filter(o.navigationFilter).eq(0); + var current = this.element.find( "a" ).filter( o.navigationFilter ).eq( 0 ); if ( current.length ) { - var header = current.closest(".ui-accordion-header"); + var header = current.closest( ".ui-accordion-header" ); if ( header.length ) { // anchor within header this.active = header; } else { // anchor within content - this.active = current.closest(".ui-accordion-content").prev(); + this.active = current.closest( ".ui-accordion-content" ).prev(); } } } - this.active = this._findActive(this.active || o.active) - .addClass("ui-state-default ui-state-active") - .toggleClass("ui-corner-all ui-corner-top"); - this.active.next().addClass('ui-accordion-content-active'); + this.active = this._findActive( this.active || o.active ) + .addClass( "ui-state-default ui-state-active" ) + .toggleClass( "ui-corner-all ui-corner-top" ); + this.active.next().addClass( "ui-accordion-content-active" ); - //Append icon elements this._createIcons(); - this.resize(); - - //ARIA - this.element.attr('role','tablist'); + + // ARIA + this.element.attr( "role", "tablist" ); this.headers - .attr('role','tab') - .bind('keydown', function(event) { return self._keydown(event); }) + .attr( "role", "tab" ) + .bind( "keydown.accordion", function( event ) { + return self._keydown( event ); + }) .next() - .attr('role','tabpanel'); + .attr( "role", "tabpanel" ); this.headers - .not(this.active || "") - .attr('aria-expanded','false') - .attr("tabIndex", "-1") + .not( this.active || "" ) + .attr({ + "aria-expanded": "false", + tabIndex: -1 + }) .next() - .hide(); + .hide(); // make sure at least one header is in the tab order - if (!this.active.length) { - this.headers.eq(0).attr('tabIndex','0'); + if ( !this.active.length ) { + this.headers.eq( 0 ).attr( "tabIndex", 0 ); } else { this.active - .attr('aria-expanded','true') - .attr('tabIndex', '0'); + .attr({ + "aria-expanded": "true", + tabIndex: 0 + }); } - // only need links in taborder for Safari - if (!$.browser.safari) - this.headers.find('a').attr('tabIndex','-1'); + // only need links in tab order for Safari + if ( !$.browser.safari ) { + this.headers.find( "a" ).attr( "tabIndex", -1 ); + } - if (o.event) { - this.headers.bind(o.event.split(" ").join(".accordion ") + ".accordion", function(event) { - self._clickHandler.call(self, event, this); + if ( o.event ) { + this.headers.bind( o.event.split(" ").join(".accordion ") + ".accordion", function(event) { + self._clickHandler.call( self, event, this ); event.preventDefault(); }); } - }, - + _createIcons: function() { var o = this.options; - if (o.icons) { - $("").addClass("ui-icon " + o.icons.header).prependTo(this.headers); - this.active.children(".ui-icon").toggleClass(o.icons.header).toggleClass(o.icons.headerSelected); - this.element.addClass("ui-accordion-icons"); + if ( o.icons ) { + $( "" ) + .addClass( "ui-icon " + o.icons.header ) + .prependTo( this.headers ); + this.active.children( ".ui-icon" ) + .toggleClass(o.icons.header) + .toggleClass(o.icons.headerSelected); + this.element.addClass( "ui-accordion-icons" ); } }, - + _destroyIcons: function() { - this.headers.children(".ui-icon").remove(); - this.element.removeClass("ui-accordion-icons"); + this.headers.children( ".ui-icon" ).remove(); + this.element.removeClass( "ui-accordion-icons" ); }, destroy: function() { var o = this.options; this.element - .removeClass("ui-accordion ui-widget ui-helper-reset") - .removeAttr("role"); + .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("tabIndex"); + .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( "tabIndex" ); - this.headers.find("a").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 (o.autoHeight || o.fillHeight) { - contents.css("height", ""); + 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 ( o.autoHeight || o.fillHeight ) { + contents.css( "height", "" ); } return $.Widget.prototype.destroy.call( this ); }, - - _setOption: function(key, value) { - $.Widget.prototype._setOption.apply(this, arguments); + + _setOption: function( key, value ) { + $.Widget.prototype._setOption.apply( this, arguments ); - if (key == "active") { - this.activate(value); + if ( key == "active" ) { + this.activate( value ); } - if (key == "icons") { + if ( key == "icons" ) { this._destroyIcons(); - if (value) { + 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") { + if ( key == "disabled" ) { this.headers.add(this.headers.next()) - [ value ? "addClass" : "removeClass"]( + [ value ? "addClass" : "removeClass" ]( "ui-accordion-disabled ui-state-disabled" ); } }, - _keydown: function(event) { - + _keydown: function( event ) { var o = this.options, keyCode = $.ui.keyCode; - if (o.disabled || event.altKey || event.ctrlKey) + if ( o.disabled || event.altKey || event.ctrlKey ) { return; + } - var length = this.headers.length; - var currentIndex = this.headers.index(event.target); - var toFocus = false; + var length = this.headers.length, + currentIndex = this.headers.index(event.target), + toFocus = false; - switch(event.keyCode) { + switch ( event.keyCode ) { case keyCode.RIGHT: case keyCode.DOWN: - toFocus = this.headers[(currentIndex + 1) % length]; + toFocus = this.headers[ ( currentIndex + 1 ) % length ]; break; case keyCode.LEFT: case keyCode.UP: - toFocus = this.headers[(currentIndex - 1 + length) % length]; + toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; break; case keyCode.SPACE: case keyCode.ENTER: - this._clickHandler({ target: event.target }, event.target); + this._clickHandler( { target: event.target }, event.target ); event.preventDefault(); } - if (toFocus) { - $(event.target).attr('tabIndex','-1'); - $(toFocus).attr('tabIndex','0'); + if ( toFocus ) { + $( event.target ).attr( "tabIndex", -1 ); + $( toFocus ).attr( "tabIndex", 0 ); toFocus.focus(); return false; } return true; - }, resize: function() { - var o = this.options, maxHeight; - if (o.fillSpace) { - - if($.browser.msie) { var defOverflow = this.element.parent().css('overflow'); this.element.parent().css('overflow', 'hidden'); } + if ( o.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); } - + if ($.browser.msie) { + this.element.parent().css( "overflow", defOverflow ); + } + this.headers.each(function() { - maxHeight -= $(this).outerHeight(true); + maxHeight -= $( this ).outerHeight( true ); }); - this.headers.next().each(function() { - $(this).height(Math.max(0, maxHeight - $(this).innerHeight() + $(this).height())); - }).css('overflow', 'auto'); - + this.headers.next() + .each(function() { + $( this ).height( Math.max( 0, maxHeight - + $( this ).innerHeight() + $( this ).height() ) ); + }) + .css( "overflow", "auto" ); } else if ( o.autoHeight ) { maxHeight = 0; - this.headers.next().each(function() { - maxHeight = Math.max(maxHeight, $(this).height("").height()); - }).height(maxHeight); + this.headers.next() + .each(function() { + maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); + }) + .height( maxHeight ); } return this; }, - activate: function(index) { + 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); + 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)) + ? typeof selector === "number" + ? this.headers.filter( ":eq(" + selector + ")" ) + : this.headers.not( this.headers.not( selector ) ) : selector === false - ? $([]) - : this.headers.filter(":eq(0)"); + ? $( [] ) + : this.headers.filter( ":eq(0)" ); }, - // TODO isn't event.target enough? why the seperate target argument? - _clickHandler: function(event, target) { - + // TODO isn't event.target enough? why the separate target argument? + _clickHandler: function( event, target ) { var o = this.options; - if (o.disabled) + if ( o.disabled ) { return; - + } + // called only when using activate(false) to close all parts programmatically - if (!event.target) { - if (!o.collapsible) + if ( !event.target ) { + if ( !o.collapsible ) { return; - this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all") - .children(".ui-icon").removeClass(o.icons.headerSelected).addClass(o.icons.header); - this.active.next().addClass('ui-accordion-content-active'); + } + this.active + .removeClass( "ui-state-active ui-corner-top" ) + .addClass( "ui-state-default ui-corner-all" ) + .children( ".ui-icon" ) + .removeClass( o.icons.headerSelected ) + .addClass( o.icons.header ); + this.active.next().addClass( "ui-accordion-content-active" ); var toHide = this.active.next(), data = { options: o, - newHeader: $([]), + newHeader: $( [] ), oldHeader: o.active, - newContent: $([]), + newContent: $( [] ), oldContent: toHide }, - toShow = (this.active = $([])); - this._toggle(toShow, toHide, data); + toShow = ( this.active = $( [] ) ); + this._toggle( toShow, toHide, data ); return; } // get the click target - var clicked = $(event.currentTarget || target); - var clickedIsActive = clicked[0] == this.active[0]; - + 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? - o.active = o.collapsible && clickedIsActive ? false : this.headers.index(clicked); + o.active = o.collapsible && clickedIsActive ? + false : + this.headers.index( clicked ); // if animations are still active, or the active header is the target, ignore click - if (this.running || (!o.collapsible && clickedIsActive)) { + if ( this.running || ( !o.collapsible && clickedIsActive ) ) { return; } // switch classes - this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all") - .children(".ui-icon").removeClass(o.icons.headerSelected).addClass(o.icons.header); - if (!clickedIsActive) { - clicked.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top") - .children(".ui-icon").removeClass(o.icons.header).addClass(o.icons.headerSelected); - clicked.next().addClass('ui-accordion-content-active'); + this.active + .removeClass( "ui-state-active ui-corner-top" ) + .addClass( "ui-state-default ui-corner-all" ) + .children( ".ui-icon" ) + .removeClass( o.icons.headerSelected ) + .addClass( o.icons.header ); + if ( !clickedIsActive ) { + clicked + .removeClass( "ui-state-default ui-corner-all" ) + .addClass( "ui-state-active ui-corner-top" ) + .children( ".ui-icon" ) + .removeClass( o.icons.header ) + .addClass( o.icons.headerSelected ); + clicked + .next() + .addClass( "ui-accordion-content-active" ); } // find elements to show and hide @@ -331,30 +375,32 @@ $.widget("ui.accordion", { down = this.headers.index( this.active[0] ) > this.headers.index( clicked[0] ); this.active = clickedIsActive ? $([]) : clicked; - this._toggle(toShow, toHide, data, clickedIsActive, down); + this._toggle( toShow, toHide, data, clickedIsActive, down ); return; - }, - _toggle: function(toShow, toHide, data, clickedIsActive, down) { - + _toggle: function( toShow, toHide, data, clickedIsActive, down ) { var o = this.options, self = this; this.toShow = toShow; this.toHide = toHide; this.data = data; - var complete = function() { if(!self) return; return self._completed.apply(self, arguments); }; + var complete = function() { + if ( !self ) { + return; + } + return self._completed.apply( self, arguments ); + }; // trigger changestart event - this._trigger("changestart", null, this.data); + this._trigger( "changestart", null, this.data ); // count elements to animate this.running = toHide.size() === 0 ? toShow.size() : toHide.size(); - if (o.animated) { - + if ( o.animated ) { var animOptions = {}; if ( o.collapsible && clickedIsActive ) { @@ -375,97 +421,112 @@ $.widget("ui.accordion", { }; } - if (!o.proxied) { + if ( !o.proxied ) { o.proxied = o.animated; } - if (!o.proxiedDuration) { + if ( !o.proxiedDuration ) { o.proxiedDuration = o.duration; } - o.animated = $.isFunction(o.proxied) ? - o.proxied(animOptions) : o.proxied; + o.animated = $.isFunction( o.proxied ) ? + o.proxied( animOptions ) : + o.proxied; - o.duration = $.isFunction(o.proxiedDuration) ? - o.proxiedDuration(animOptions) : o.proxiedDuration; + o.duration = $.isFunction( o.proxiedDuration ) ? + o.proxiedDuration( animOptions ) : + o.proxiedDuration; var animations = $.ui.accordion.animations, duration = o.duration, easing = o.animated; - if (easing && !animations[easing] && !$.easing[easing]) { - easing = 'slide'; + if ( easing && !animations[ easing ] && !$.easing[ easing ] ) { + easing = "slide"; } - if (!animations[easing]) { - animations[easing] = function(options) { - this.slide(options, { + if ( !animations[ easing ] ) { + animations[ easing ] = function( options ) { + this.slide( options, { easing: easing, duration: duration || 700 }); }; } - animations[easing](animOptions); - + animations[ easing ]( animOptions ); } else { - - if (o.collapsible && clickedIsActive) { + if ( o.collapsible && clickedIsActive ) { toShow.toggle(); } else { toHide.hide(); toShow.show(); } - complete(true); - + complete( true ); } // TODO assert that the blur and focus triggers are really necessary, remove otherwise - toHide.prev().attr('aria-expanded','false').attr("tabIndex", "-1").blur(); - toShow.prev().attr('aria-expanded','true').attr("tabIndex", "0").focus(); - + toHide.prev() + .attr({ + "aria-expanded": "false", + tabIndex: -1 + }) + .blur(); + toShow.prev() + .attr({ + "aria-expanded": "true", + tabIndex: 0 + }) + .focus(); }, - _completed: function(cancel) { - + _completed: function( cancel ) { var o = this.options; this.running = cancel ? 0 : --this.running; - if (this.running) return; + if ( this.running ) { + return; + } - if (o.clearStyle) { - this.toShow.add(this.toHide).css({ + if ( o.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"); + this.toHide.removeClass( "ui-accordion-content-active" ); - this._trigger('change', null, this.data); + this._trigger( "change", null, this.data ); } - }); - -$.extend($.ui.accordion, { +$.extend( $.ui.accordion, { version: "@VERSION", animations: { - slide: function(options, additions) { + slide: function( options, additions ) { options = $.extend({ easing: "swing", duration: 300 - }, options, additions); + }, options, additions ); if ( !options.toHide.size() ) { - options.toShow.animate({height: "show", paddingTop: "show", paddingBottom: "show"}, options); + 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); + options.toHide.animate({ + height: "hide", + paddingTop: "hide", + paddingBottom: "hide" + }, options ); return; } - var overflow = options.toShow.css('overflow'), + var overflow = options.toShow.css( "overflow" ), percentDone = 0, showProps = {}, hideProps = {}, @@ -474,45 +535,57 @@ $.extend($.ui.accordion, { // fix width before calculating height of hidden element var s = options.toShow; originalWidth = s[0].style.width; - s.width( parseInt(s.parent().width(),10) - parseInt(s.css("paddingLeft"),10) - parseInt(s.css("paddingRight"),10) - (parseInt(s.css("borderLeftWidth"),10) || 0) - (parseInt(s.css("borderRightWidth"),10) || 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' + s.width( parseInt( s.parent().width(), 10 ) + - parseInt( s.css( "paddingLeft" ), 10 ) + - parseInt( s.css( "paddingRight" ), 10 ) + - ( parseInt( s.css( "borderLeftWidth" ), 10 ) || 0 ) + - ( parseInt( s.css( "borderRightWidth" ), 10) || 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) { + 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') { + if ( settings.prop == "height" ) { percentDone = ( settings.end - settings.start === 0 ) ? 0 : - (settings.now - settings.start) / (settings.end - settings.start); + ( settings.now - settings.start ) / ( settings.end - settings.start ); } - - options.toShow[0].style[settings.prop] = - (percentDone * showProps[settings.prop].value) + showProps[settings.prop].unit; + + 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( "height", "" ); } - options.toShow.css("width", originalWidth); - options.toShow.css({overflow: overflow}); + options.toShow.css({ + width: originalWidth, + overflow: overflow + }); options.complete(); } }); }, - bounceslide: function(options) { - this.slide(options, { + bounceslide: function( options ) { + this.slide( options, { easing: options.down ? "easeOutBounce" : "swing", duration: options.down ? 1000 : 200 }); @@ -520,4 +593,4 @@ $.extend($.ui.accordion, { } }); -})(jQuery); +})( jQuery ); -- 2.39.5