[ Index ] |
PHP Cross Reference of WordPress |
[Summary view] [Print] [Text view]
1 /*! 2 * jQuery UI Accordion 1.13.1 3 * http://jqueryui.com 4 * 5 * Copyright jQuery Foundation and other contributors 6 * Released under the MIT license. 7 * http://jquery.org/license 8 */ 9 10 //>>label: Accordion 11 //>>group: Widgets 12 /* eslint-disable max-len */ 13 //>>description: Displays collapsible content panels for presenting information in a limited amount of space. 14 /* eslint-enable max-len */ 15 //>>docs: http://api.jqueryui.com/accordion/ 16 //>>demos: http://jqueryui.com/accordion/ 17 //>>css.structure: ../../themes/base/core.css 18 //>>css.structure: ../../themes/base/accordion.css 19 //>>css.theme: ../../themes/base/theme.css 20 21 ( function( factory ) { 22 "use strict"; 23 24 if ( typeof define === "function" && define.amd ) { 25 26 // AMD. Register as an anonymous module. 27 define( [ 28 "jquery", 29 "./core" 30 ], factory ); 31 } else { 32 33 // Browser globals 34 factory( jQuery ); 35 } 36 } )( function( $ ) { 37 "use strict"; 38 39 return $.widget( "ui.accordion", { 40 version: "1.13.1", 41 options: { 42 active: 0, 43 animate: {}, 44 classes: { 45 "ui-accordion-header": "ui-corner-top", 46 "ui-accordion-header-collapsed": "ui-corner-all", 47 "ui-accordion-content": "ui-corner-bottom" 48 }, 49 collapsible: false, 50 event: "click", 51 header: function( elem ) { 52 return elem.find( "> li > :first-child" ).add( elem.find( "> :not(li)" ).even() ); 53 }, 54 heightStyle: "auto", 55 icons: { 56 activeHeader: "ui-icon-triangle-1-s", 57 header: "ui-icon-triangle-1-e" 58 }, 59 60 // Callbacks 61 activate: null, 62 beforeActivate: null 63 }, 64 65 hideProps: { 66 borderTopWidth: "hide", 67 borderBottomWidth: "hide", 68 paddingTop: "hide", 69 paddingBottom: "hide", 70 height: "hide" 71 }, 72 73 showProps: { 74 borderTopWidth: "show", 75 borderBottomWidth: "show", 76 paddingTop: "show", 77 paddingBottom: "show", 78 height: "show" 79 }, 80 81 _create: function() { 82 var options = this.options; 83 84 this.prevShow = this.prevHide = $(); 85 this._addClass( "ui-accordion", "ui-widget ui-helper-reset" ); 86 this.element.attr( "role", "tablist" ); 87 88 // Don't allow collapsible: false and active: false / null 89 if ( !options.collapsible && ( options.active === false || options.active == null ) ) { 90 options.active = 0; 91 } 92 93 this._processPanels(); 94 95 // handle negative values 96 if ( options.active < 0 ) { 97 options.active += this.headers.length; 98 } 99 this._refresh(); 100 }, 101 102 _getCreateEventData: function() { 103 return { 104 header: this.active, 105 panel: !this.active.length ? $() : this.active.next() 106 }; 107 }, 108 109 _createIcons: function() { 110 var icon, children, 111 icons = this.options.icons; 112 113 if ( icons ) { 114 icon = $( "<span>" ); 115 this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header ); 116 icon.prependTo( this.headers ); 117 children = this.active.children( ".ui-accordion-header-icon" ); 118 this._removeClass( children, icons.header ) 119 ._addClass( children, null, icons.activeHeader ) 120 ._addClass( this.headers, "ui-accordion-icons" ); 121 } 122 }, 123 124 _destroyIcons: function() { 125 this._removeClass( this.headers, "ui-accordion-icons" ); 126 this.headers.children( ".ui-accordion-header-icon" ).remove(); 127 }, 128 129 _destroy: function() { 130 var contents; 131 132 // Clean up main element 133 this.element.removeAttr( "role" ); 134 135 // Clean up headers 136 this.headers 137 .removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" ) 138 .removeUniqueId(); 139 140 this._destroyIcons(); 141 142 // Clean up content panels 143 contents = this.headers.next() 144 .css( "display", "" ) 145 .removeAttr( "role aria-hidden aria-labelledby" ) 146 .removeUniqueId(); 147 148 if ( this.options.heightStyle !== "content" ) { 149 contents.css( "height", "" ); 150 } 151 }, 152 153 _setOption: function( key, value ) { 154 if ( key === "active" ) { 155 156 // _activate() will handle invalid values and update this.options 157 this._activate( value ); 158 return; 159 } 160 161 if ( key === "event" ) { 162 if ( this.options.event ) { 163 this._off( this.headers, this.options.event ); 164 } 165 this._setupEvents( value ); 166 } 167 168 this._super( key, value ); 169 170 // Setting collapsible: false while collapsed; open first panel 171 if ( key === "collapsible" && !value && this.options.active === false ) { 172 this._activate( 0 ); 173 } 174 175 if ( key === "icons" ) { 176 this._destroyIcons(); 177 if ( value ) { 178 this._createIcons(); 179 } 180 } 181 }, 182 183 _setOptionDisabled: function( value ) { 184 this._super( value ); 185 186 this.element.attr( "aria-disabled", value ); 187 188 // Support: IE8 Only 189 // #5332 / #6059 - opacity doesn't cascade to positioned elements in IE 190 // so we need to add the disabled class to the headers and panels 191 this._toggleClass( null, "ui-state-disabled", !!value ); 192 this._toggleClass( this.headers.add( this.headers.next() ), null, "ui-state-disabled", 193 !!value ); 194 }, 195 196 _keydown: function( event ) { 197 if ( event.altKey || event.ctrlKey ) { 198 return; 199 } 200 201 var keyCode = $.ui.keyCode, 202 length = this.headers.length, 203 currentIndex = this.headers.index( event.target ), 204 toFocus = false; 205 206 switch ( event.keyCode ) { 207 case keyCode.RIGHT: 208 case keyCode.DOWN: 209 toFocus = this.headers[ ( currentIndex + 1 ) % length ]; 210 break; 211 case keyCode.LEFT: 212 case keyCode.UP: 213 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; 214 break; 215 case keyCode.SPACE: 216 case keyCode.ENTER: 217 this._eventHandler( event ); 218 break; 219 case keyCode.HOME: 220 toFocus = this.headers[ 0 ]; 221 break; 222 case keyCode.END: 223 toFocus = this.headers[ length - 1 ]; 224 break; 225 } 226 227 if ( toFocus ) { 228 $( event.target ).attr( "tabIndex", -1 ); 229 $( toFocus ).attr( "tabIndex", 0 ); 230 $( toFocus ).trigger( "focus" ); 231 event.preventDefault(); 232 } 233 }, 234 235 _panelKeyDown: function( event ) { 236 if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { 237 $( event.currentTarget ).prev().trigger( "focus" ); 238 } 239 }, 240 241 refresh: function() { 242 var options = this.options; 243 this._processPanels(); 244 245 // Was collapsed or no panel 246 if ( ( options.active === false && options.collapsible === true ) || 247 !this.headers.length ) { 248 options.active = false; 249 this.active = $(); 250 251 // active false only when collapsible is true 252 } else if ( options.active === false ) { 253 this._activate( 0 ); 254 255 // was active, but active panel is gone 256 } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 257 258 // all remaining panel are disabled 259 if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) { 260 options.active = false; 261 this.active = $(); 262 263 // activate previous panel 264 } else { 265 this._activate( Math.max( 0, options.active - 1 ) ); 266 } 267 268 // was active, active panel still exists 269 } else { 270 271 // make sure active index is correct 272 options.active = this.headers.index( this.active ); 273 } 274 275 this._destroyIcons(); 276 277 this._refresh(); 278 }, 279 280 _processPanels: function() { 281 var prevHeaders = this.headers, 282 prevPanels = this.panels; 283 284 if ( typeof this.options.header === "function" ) { 285 this.headers = this.options.header( this.element ); 286 } else { 287 this.headers = this.element.find( this.options.header ); 288 } 289 this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed", 290 "ui-state-default" ); 291 292 this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide(); 293 this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" ); 294 295 // Avoid memory leaks (#10056) 296 if ( prevPanels ) { 297 this._off( prevHeaders.not( this.headers ) ); 298 this._off( prevPanels.not( this.panels ) ); 299 } 300 }, 301 302 _refresh: function() { 303 var maxHeight, 304 options = this.options, 305 heightStyle = options.heightStyle, 306 parent = this.element.parent(); 307 308 this.active = this._findActive( options.active ); 309 this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" ) 310 ._removeClass( this.active, "ui-accordion-header-collapsed" ); 311 this._addClass( this.active.next(), "ui-accordion-content-active" ); 312 this.active.next().show(); 313 314 this.headers 315 .attr( "role", "tab" ) 316 .each( function() { 317 var header = $( this ), 318 headerId = header.uniqueId().attr( "id" ), 319 panel = header.next(), 320 panelId = panel.uniqueId().attr( "id" ); 321 header.attr( "aria-controls", panelId ); 322 panel.attr( "aria-labelledby", headerId ); 323 } ) 324 .next() 325 .attr( "role", "tabpanel" ); 326 327 this.headers 328 .not( this.active ) 329 .attr( { 330 "aria-selected": "false", 331 "aria-expanded": "false", 332 tabIndex: -1 333 } ) 334 .next() 335 .attr( { 336 "aria-hidden": "true" 337 } ) 338 .hide(); 339 340 // Make sure at least one header is in the tab order 341 if ( !this.active.length ) { 342 this.headers.eq( 0 ).attr( "tabIndex", 0 ); 343 } else { 344 this.active.attr( { 345 "aria-selected": "true", 346 "aria-expanded": "true", 347 tabIndex: 0 348 } ) 349 .next() 350 .attr( { 351 "aria-hidden": "false" 352 } ); 353 } 354 355 this._createIcons(); 356 357 this._setupEvents( options.event ); 358 359 if ( heightStyle === "fill" ) { 360 maxHeight = parent.height(); 361 this.element.siblings( ":visible" ).each( function() { 362 var elem = $( this ), 363 position = elem.css( "position" ); 364 365 if ( position === "absolute" || position === "fixed" ) { 366 return; 367 } 368 maxHeight -= elem.outerHeight( true ); 369 } ); 370 371 this.headers.each( function() { 372 maxHeight -= $( this ).outerHeight( true ); 373 } ); 374 375 this.headers.next() 376 .each( function() { 377 $( this ).height( Math.max( 0, maxHeight - 378 $( this ).innerHeight() + $( this ).height() ) ); 379 } ) 380 .css( "overflow", "auto" ); 381 } else if ( heightStyle === "auto" ) { 382 maxHeight = 0; 383 this.headers.next() 384 .each( function() { 385 var isVisible = $( this ).is( ":visible" ); 386 if ( !isVisible ) { 387 $( this ).show(); 388 } 389 maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); 390 if ( !isVisible ) { 391 $( this ).hide(); 392 } 393 } ) 394 .height( maxHeight ); 395 } 396 }, 397 398 _activate: function( index ) { 399 var active = this._findActive( index )[ 0 ]; 400 401 // Trying to activate the already active panel 402 if ( active === this.active[ 0 ] ) { 403 return; 404 } 405 406 // Trying to collapse, simulate a click on the currently active header 407 active = active || this.active[ 0 ]; 408 409 this._eventHandler( { 410 target: active, 411 currentTarget: active, 412 preventDefault: $.noop 413 } ); 414 }, 415 416 _findActive: function( selector ) { 417 return typeof selector === "number" ? this.headers.eq( selector ) : $(); 418 }, 419 420 _setupEvents: function( event ) { 421 var events = { 422 keydown: "_keydown" 423 }; 424 if ( event ) { 425 $.each( event.split( " " ), function( index, eventName ) { 426 events[ eventName ] = "_eventHandler"; 427 } ); 428 } 429 430 this._off( this.headers.add( this.headers.next() ) ); 431 this._on( this.headers, events ); 432 this._on( this.headers.next(), { keydown: "_panelKeyDown" } ); 433 this._hoverable( this.headers ); 434 this._focusable( this.headers ); 435 }, 436 437 _eventHandler: function( event ) { 438 var activeChildren, clickedChildren, 439 options = this.options, 440 active = this.active, 441 clicked = $( event.currentTarget ), 442 clickedIsActive = clicked[ 0 ] === active[ 0 ], 443 collapsing = clickedIsActive && options.collapsible, 444 toShow = collapsing ? $() : clicked.next(), 445 toHide = active.next(), 446 eventData = { 447 oldHeader: active, 448 oldPanel: toHide, 449 newHeader: collapsing ? $() : clicked, 450 newPanel: toShow 451 }; 452 453 event.preventDefault(); 454 455 if ( 456 457 // click on active header, but not collapsible 458 ( clickedIsActive && !options.collapsible ) || 459 460 // allow canceling activation 461 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 462 return; 463 } 464 465 options.active = collapsing ? false : this.headers.index( clicked ); 466 467 // When the call to ._toggle() comes after the class changes 468 // it causes a very odd bug in IE 8 (see #6720) 469 this.active = clickedIsActive ? $() : clicked; 470 this._toggle( eventData ); 471 472 // Switch classes 473 // corner classes on the previously active header stay after the animation 474 this._removeClass( active, "ui-accordion-header-active", "ui-state-active" ); 475 if ( options.icons ) { 476 activeChildren = active.children( ".ui-accordion-header-icon" ); 477 this._removeClass( activeChildren, null, options.icons.activeHeader ) 478 ._addClass( activeChildren, null, options.icons.header ); 479 } 480 481 if ( !clickedIsActive ) { 482 this._removeClass( clicked, "ui-accordion-header-collapsed" ) 483 ._addClass( clicked, "ui-accordion-header-active", "ui-state-active" ); 484 if ( options.icons ) { 485 clickedChildren = clicked.children( ".ui-accordion-header-icon" ); 486 this._removeClass( clickedChildren, null, options.icons.header ) 487 ._addClass( clickedChildren, null, options.icons.activeHeader ); 488 } 489 490 this._addClass( clicked.next(), "ui-accordion-content-active" ); 491 } 492 }, 493 494 _toggle: function( data ) { 495 var toShow = data.newPanel, 496 toHide = this.prevShow.length ? this.prevShow : data.oldPanel; 497 498 // Handle activating a panel during the animation for another activation 499 this.prevShow.add( this.prevHide ).stop( true, true ); 500 this.prevShow = toShow; 501 this.prevHide = toHide; 502 503 if ( this.options.animate ) { 504 this._animate( toShow, toHide, data ); 505 } else { 506 toHide.hide(); 507 toShow.show(); 508 this._toggleComplete( data ); 509 } 510 511 toHide.attr( { 512 "aria-hidden": "true" 513 } ); 514 toHide.prev().attr( { 515 "aria-selected": "false", 516 "aria-expanded": "false" 517 } ); 518 519 // if we're switching panels, remove the old header from the tab order 520 // if we're opening from collapsed state, remove the previous header from the tab order 521 // if we're collapsing, then keep the collapsing header in the tab order 522 if ( toShow.length && toHide.length ) { 523 toHide.prev().attr( { 524 "tabIndex": -1, 525 "aria-expanded": "false" 526 } ); 527 } else if ( toShow.length ) { 528 this.headers.filter( function() { 529 return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0; 530 } ) 531 .attr( "tabIndex", -1 ); 532 } 533 534 toShow 535 .attr( "aria-hidden", "false" ) 536 .prev() 537 .attr( { 538 "aria-selected": "true", 539 "aria-expanded": "true", 540 tabIndex: 0 541 } ); 542 }, 543 544 _animate: function( toShow, toHide, data ) { 545 var total, easing, duration, 546 that = this, 547 adjust = 0, 548 boxSizing = toShow.css( "box-sizing" ), 549 down = toShow.length && 550 ( !toHide.length || ( toShow.index() < toHide.index() ) ), 551 animate = this.options.animate || {}, 552 options = down && animate.down || animate, 553 complete = function() { 554 that._toggleComplete( data ); 555 }; 556 557 if ( typeof options === "number" ) { 558 duration = options; 559 } 560 if ( typeof options === "string" ) { 561 easing = options; 562 } 563 564 // fall back from options to animation in case of partial down settings 565 easing = easing || options.easing || animate.easing; 566 duration = duration || options.duration || animate.duration; 567 568 if ( !toHide.length ) { 569 return toShow.animate( this.showProps, duration, easing, complete ); 570 } 571 if ( !toShow.length ) { 572 return toHide.animate( this.hideProps, duration, easing, complete ); 573 } 574 575 total = toShow.show().outerHeight(); 576 toHide.animate( this.hideProps, { 577 duration: duration, 578 easing: easing, 579 step: function( now, fx ) { 580 fx.now = Math.round( now ); 581 } 582 } ); 583 toShow 584 .hide() 585 .animate( this.showProps, { 586 duration: duration, 587 easing: easing, 588 complete: complete, 589 step: function( now, fx ) { 590 fx.now = Math.round( now ); 591 if ( fx.prop !== "height" ) { 592 if ( boxSizing === "content-box" ) { 593 adjust += fx.now; 594 } 595 } else if ( that.options.heightStyle !== "content" ) { 596 fx.now = Math.round( total - toHide.outerHeight() - adjust ); 597 adjust = 0; 598 } 599 } 600 } ); 601 }, 602 603 _toggleComplete: function( data ) { 604 var toHide = data.oldPanel, 605 prev = toHide.prev(); 606 607 this._removeClass( toHide, "ui-accordion-content-active" ); 608 this._removeClass( prev, "ui-accordion-header-active" ) 609 ._addClass( prev, "ui-accordion-header-collapsed" ); 610 611 // Work around for rendering bug in IE (#5421) 612 if ( toHide.length ) { 613 toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className; 614 } 615 this._trigger( "activate", null, data ); 616 } 617 } ); 618 619 } );
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Nov 21 01:00:03 2024 | Cross-referenced by PHPXref 0.7.1 |