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