| [ Index ] |
PHP Cross Reference of Drupal 6 (gatewave) |
[Summary view] [Print] [Text view]
1 /* 2 * jQuery UI Accordion 1.7.2 3 * 4 * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) 5 * Dual licensed under the MIT (MIT-LICENSE.txt) 6 * and GPL (GPL-LICENSE.txt) licenses. 7 * 8 * http://docs.jquery.com/UI/Accordion 9 * 10 * Depends: 11 * ui.core.js 12 */ 13 (function($) { 14 15 $.widget("ui.accordion", { 16 17 _init: function() { 18 19 var o = this.options, self = this; 20 this.running = 0; 21 22 // if the user set the alwaysOpen option on init 23 // then we need to set the collapsible option 24 // if they set both on init, collapsible will take priority 25 if (o.collapsible == $.ui.accordion.defaults.collapsible && 26 o.alwaysOpen != $.ui.accordion.defaults.alwaysOpen) { 27 o.collapsible = !o.alwaysOpen; 28 } 29 30 if ( o.navigation ) { 31 var current = this.element.find("a").filter(o.navigationFilter); 32 if ( current.length ) { 33 if ( current.filter(o.header).length ) { 34 this.active = current; 35 } else { 36 this.active = current.parent().parent().prev(); 37 current.addClass("ui-accordion-content-active"); 38 } 39 } 40 } 41 42 this.element.addClass("ui-accordion ui-widget ui-helper-reset"); 43 44 // in lack of child-selectors in CSS we need to mark top-LIs in a UL-accordion for some IE-fix 45 if (this.element[0].nodeName == "UL") { 46 this.element.children("li").addClass("ui-accordion-li-fix"); 47 } 48 49 this.headers = this.element.find(o.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all") 50 .bind("mouseenter.accordion", function(){ $(this).addClass('ui-state-hover'); }) 51 .bind("mouseleave.accordion", function(){ $(this).removeClass('ui-state-hover'); }) 52 .bind("focus.accordion", function(){ $(this).addClass('ui-state-focus'); }) 53 .bind("blur.accordion", function(){ $(this).removeClass('ui-state-focus'); }); 54 55 this.headers 56 .next() 57 .addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom"); 58 59 this.active = this._findActive(this.active || o.active).toggleClass("ui-state-default").toggleClass("ui-state-active").toggleClass("ui-corner-all").toggleClass("ui-corner-top"); 60 this.active.next().addClass('ui-accordion-content-active'); 61 62 //Append icon elements 63 $("<span/>").addClass("ui-icon " + o.icons.header).prependTo(this.headers); 64 this.active.find(".ui-icon").toggleClass(o.icons.header).toggleClass(o.icons.headerSelected); 65 66 // IE7-/Win - Extra vertical space in lists fixed 67 if ($.browser.msie) { 68 this.element.find('a').css('zoom', '1'); 69 } 70 71 this.resize(); 72 73 //ARIA 74 this.element.attr('role','tablist'); 75 76 this.headers 77 .attr('role','tab') 78 .bind('keydown', function(event) { return self._keydown(event); }) 79 .next() 80 .attr('role','tabpanel'); 81 82 this.headers 83 .not(this.active || "") 84 .attr('aria-expanded','false') 85 .attr("tabIndex", "-1") 86 .next() 87 .hide(); 88 89 // make sure at least one header is in the tab order 90 if (!this.active.length) { 91 this.headers.eq(0).attr('tabIndex','0'); 92 } else { 93 this.active 94 .attr('aria-expanded','true') 95 .attr('tabIndex', '0'); 96 } 97 98 // only need links in taborder for Safari 99 if (!$.browser.safari) 100 this.headers.find('a').attr('tabIndex','-1'); 101 102 if (o.event) { 103 this.headers.bind((o.event) + ".accordion", function(event) { return self._clickHandler.call(self, event, this); }); 104 } 105 106 }, 107 108 destroy: function() { 109 var o = this.options; 110 111 this.element 112 .removeClass("ui-accordion ui-widget ui-helper-reset") 113 .removeAttr("role") 114 .unbind('.accordion') 115 .removeData('accordion'); 116 117 this.headers 118 .unbind(".accordion") 119 .removeClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-corner-top") 120 .removeAttr("role").removeAttr("aria-expanded").removeAttr("tabindex"); 121 122 this.headers.find("a").removeAttr("tabindex"); 123 this.headers.children(".ui-icon").remove(); 124 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"); 125 if (o.autoHeight || o.fillHeight) { 126 contents.css("height", ""); 127 } 128 }, 129 130 _setData: function(key, value) { 131 if(key == 'alwaysOpen') { key = 'collapsible'; value = !value; } 132 $.widget.prototype._setData.apply(this, arguments); 133 }, 134 135 _keydown: function(event) { 136 137 var o = this.options, keyCode = $.ui.keyCode; 138 139 if (o.disabled || event.altKey || event.ctrlKey) 140 return; 141 142 var length = this.headers.length; 143 var currentIndex = this.headers.index(event.target); 144 var toFocus = false; 145 146 switch(event.keyCode) { 147 case keyCode.RIGHT: 148 case keyCode.DOWN: 149 toFocus = this.headers[(currentIndex + 1) % length]; 150 break; 151 case keyCode.LEFT: 152 case keyCode.UP: 153 toFocus = this.headers[(currentIndex - 1 + length) % length]; 154 break; 155 case keyCode.SPACE: 156 case keyCode.ENTER: 157 return this._clickHandler({ target: event.target }, event.target); 158 } 159 160 if (toFocus) { 161 $(event.target).attr('tabIndex','-1'); 162 $(toFocus).attr('tabIndex','0'); 163 toFocus.focus(); 164 return false; 165 } 166 167 return true; 168 169 }, 170 171 resize: function() { 172 173 var o = this.options, maxHeight; 174 175 if (o.fillSpace) { 176 177 if($.browser.msie) { var defOverflow = this.element.parent().css('overflow'); this.element.parent().css('overflow', 'hidden'); } 178 maxHeight = this.element.parent().height(); 179 if($.browser.msie) { this.element.parent().css('overflow', defOverflow); } 180 181 this.headers.each(function() { 182 maxHeight -= $(this).outerHeight(); 183 }); 184 185 var maxPadding = 0; 186 this.headers.next().each(function() { 187 maxPadding = Math.max(maxPadding, $(this).innerHeight() - $(this).height()); 188 }).height(Math.max(0, maxHeight - maxPadding)) 189 .css('overflow', 'auto'); 190 191 } else if ( o.autoHeight ) { 192 maxHeight = 0; 193 this.headers.next().each(function() { 194 maxHeight = Math.max(maxHeight, $(this).outerHeight()); 195 }).height(maxHeight); 196 } 197 198 }, 199 200 activate: function(index) { 201 // call clickHandler with custom event 202 var active = this._findActive(index)[0]; 203 this._clickHandler({ target: active }, active); 204 }, 205 206 _findActive: function(selector) { 207 return selector 208 ? typeof selector == "number" 209 ? this.headers.filter(":eq(" + selector + ")") 210 : this.headers.not(this.headers.not(selector)) 211 : selector === false 212 ? $([]) 213 : this.headers.filter(":eq(0)"); 214 }, 215 216 _clickHandler: function(event, target) { 217 218 var o = this.options; 219 if (o.disabled) return false; 220 221 // called only when using activate(false) to close all parts programmatically 222 if (!event.target && o.collapsible) { 223 this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all") 224 .find(".ui-icon").removeClass(o.icons.headerSelected).addClass(o.icons.header); 225 this.active.next().addClass('ui-accordion-content-active'); 226 var toHide = this.active.next(), 227 data = { 228 options: o, 229 newHeader: $([]), 230 oldHeader: o.active, 231 newContent: $([]), 232 oldContent: toHide 233 }, 234 toShow = (this.active = $([])); 235 this._toggle(toShow, toHide, data); 236 return false; 237 } 238 239 // get the click target 240 var clicked = $(event.currentTarget || target); 241 var clickedIsActive = clicked[0] == this.active[0]; 242 243 // if animations are still active, or the active header is the target, ignore click 244 if (this.running || (!o.collapsible && clickedIsActive)) { 245 return false; 246 } 247 248 // switch classes 249 this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all") 250 .find(".ui-icon").removeClass(o.icons.headerSelected).addClass(o.icons.header); 251 this.active.next().addClass('ui-accordion-content-active'); 252 if (!clickedIsActive) { 253 clicked.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top") 254 .find(".ui-icon").removeClass(o.icons.header).addClass(o.icons.headerSelected); 255 clicked.next().addClass('ui-accordion-content-active'); 256 } 257 258 // find elements to show and hide 259 var toShow = clicked.next(), 260 toHide = this.active.next(), 261 data = { 262 options: o, 263 newHeader: clickedIsActive && o.collapsible ? $([]) : clicked, 264 oldHeader: this.active, 265 newContent: clickedIsActive && o.collapsible ? $([]) : toShow.find('> *'), 266 oldContent: toHide.find('> *') 267 }, 268 down = this.headers.index( this.active[0] ) > this.headers.index( clicked[0] ); 269 270 this.active = clickedIsActive ? $([]) : clicked; 271 this._toggle(toShow, toHide, data, clickedIsActive, down); 272 273 return false; 274 275 }, 276 277 _toggle: function(toShow, toHide, data, clickedIsActive, down) { 278 279 var o = this.options, self = this; 280 281 this.toShow = toShow; 282 this.toHide = toHide; 283 this.data = data; 284 285 var complete = function() { if(!self) return; return self._completed.apply(self, arguments); }; 286 287 // trigger changestart event 288 this._trigger("changestart", null, this.data); 289 290 // count elements to animate 291 this.running = toHide.size() === 0 ? toShow.size() : toHide.size(); 292 293 if (o.animated) { 294 295 var animOptions = {}; 296 297 if ( o.collapsible && clickedIsActive ) { 298 animOptions = { 299 toShow: $([]), 300 toHide: toHide, 301 complete: complete, 302 down: down, 303 autoHeight: o.autoHeight || o.fillSpace 304 }; 305 } else { 306 animOptions = { 307 toShow: toShow, 308 toHide: toHide, 309 complete: complete, 310 down: down, 311 autoHeight: o.autoHeight || o.fillSpace 312 }; 313 } 314 315 if (!o.proxied) { 316 o.proxied = o.animated; 317 } 318 319 if (!o.proxiedDuration) { 320 o.proxiedDuration = o.duration; 321 } 322 323 o.animated = $.isFunction(o.proxied) ? 324 o.proxied(animOptions) : o.proxied; 325 326 o.duration = $.isFunction(o.proxiedDuration) ? 327 o.proxiedDuration(animOptions) : o.proxiedDuration; 328 329 var animations = $.ui.accordion.animations, 330 duration = o.duration, 331 easing = o.animated; 332 333 if (!animations[easing]) { 334 animations[easing] = function(options) { 335 this.slide(options, { 336 easing: easing, 337 duration: duration || 700 338 }); 339 }; 340 } 341 342 animations[easing](animOptions); 343 344 } else { 345 346 if (o.collapsible && clickedIsActive) { 347 toShow.toggle(); 348 } else { 349 toHide.hide(); 350 toShow.show(); 351 } 352 353 complete(true); 354 355 } 356 357 toHide.prev().attr('aria-expanded','false').attr("tabIndex", "-1").blur(); 358 toShow.prev().attr('aria-expanded','true').attr("tabIndex", "0").focus(); 359 360 }, 361 362 _completed: function(cancel) { 363 364 var o = this.options; 365 366 this.running = cancel ? 0 : --this.running; 367 if (this.running) return; 368 369 if (o.clearStyle) { 370 this.toShow.add(this.toHide).css({ 371 height: "", 372 overflow: "" 373 }); 374 } 375 376 this._trigger('change', null, this.data); 377 } 378 379 }); 380 381 382 $.extend($.ui.accordion, { 383 version: "1.7.2", 384 defaults: { 385 active: null, 386 alwaysOpen: true, //deprecated, use collapsible 387 animated: 'slide', 388 autoHeight: true, 389 clearStyle: false, 390 collapsible: false, 391 event: "click", 392 fillSpace: false, 393 header: "> li > :first-child,> :not(li):even", 394 icons: { 395 header: "ui-icon-triangle-1-e", 396 headerSelected: "ui-icon-triangle-1-s" 397 }, 398 navigation: false, 399 navigationFilter: function() { 400 return this.href.toLowerCase() == location.href.toLowerCase(); 401 } 402 }, 403 animations: { 404 slide: function(options, additions) { 405 options = $.extend({ 406 easing: "swing", 407 duration: 300 408 }, options, additions); 409 if ( !options.toHide.size() ) { 410 options.toShow.animate({height: "show"}, options); 411 return; 412 } 413 if ( !options.toShow.size() ) { 414 options.toHide.animate({height: "hide"}, options); 415 return; 416 } 417 var overflow = options.toShow.css('overflow'), 418 percentDone, 419 showProps = {}, 420 hideProps = {}, 421 fxAttrs = [ "height", "paddingTop", "paddingBottom" ], 422 originalWidth; 423 // fix width before calculating height of hidden element 424 var s = options.toShow; 425 originalWidth = s[0].style.width; 426 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) ); 427 428 $.each(fxAttrs, function(i, prop) { 429 hideProps[prop] = 'hide'; 430 431 var parts = ('' + $.css(options.toShow[0], prop)).match(/^([\d+-.]+)(.*)$/); 432 showProps[prop] = { 433 value: parts[1], 434 unit: parts[2] || 'px' 435 }; 436 }); 437 options.toShow.css({ height: 0, overflow: 'hidden' }).show(); 438 options.toHide.filter(":hidden").each(options.complete).end().filter(":visible").animate(hideProps,{ 439 step: function(now, settings) { 440 // only calculate the percent when animating height 441 // IE gets very inconsistent results when animating elements 442 // with small values, which is common for padding 443 if (settings.prop == 'height') { 444 percentDone = (settings.now - settings.start) / (settings.end - settings.start); 445 } 446 447 options.toShow[0].style[settings.prop] = 448 (percentDone * showProps[settings.prop].value) + showProps[settings.prop].unit; 449 }, 450 duration: options.duration, 451 easing: options.easing, 452 complete: function() { 453 if ( !options.autoHeight ) { 454 options.toShow.css("height", ""); 455 } 456 options.toShow.css("width", originalWidth); 457 options.toShow.css({overflow: overflow}); 458 options.complete(); 459 } 460 }); 461 }, 462 bounceslide: function(options) { 463 this.slide(options, { 464 easing: options.down ? "easeOutBounce" : "swing", 465 duration: options.down ? 1000 : 200 466 }); 467 }, 468 easeslide: function(options) { 469 this.slide(options, { 470 easing: "easeinout", 471 duration: 700 472 }); 473 } 474 } 475 }); 476 477 })(jQuery);
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Thu Mar 24 11:18:33 2011 | Cross-referenced by PHPXref 0.7 |