}
return this.each( function () {
- var $collapsible, collapseText, expandText, $toggle, clickHandler, $defaultToggleLink,
+ var $collapsible, collapseText, expandText, $toggle, clickHandler, buildDefaultToggleLink,
premadeToggleHandler, $toggleLink, $firstItem, collapsibleId, $customTogglers, firstval;
// Ensure class "mw-collapsible" is present in case .makeCollapsible()
opts = $.extend( defaultOpts, options, opts );
togglingHandler( $( this ), $collapsible, e, opts );
};
- $defaultToggleLink =
- $( '<a href="#"></a>' )
+ // Default toggle link. Only build it when needed to avoid jQuery memory leaks (event data).
+ buildDefaultToggleLink = function () {
+ return $( '<a href="#"></a>' )
.text( collapseText )
.wrap( '<span class="mw-collapsible-toggle"></span>' )
.parent()
.prepend( ' [' )
.append( '] ' )
.on( 'click.mw-collapsible', clickHandler );
+ };
// Default handler for clicking on premade toggles
premadeToggleHandler = function ( e, opts ) {
// If theres no toggle link, add it to the last cell
if ( !$toggle.length ) {
- $toggleLink = $defaultToggleLink.prependTo( $firstItem.eq( -1 ) );
+ $toggleLink = buildDefaultToggleLink().prependTo( $firstItem.eq( -1 ) );
} else {
clickHandler = premadeToggleHandler;
$toggleLink = $toggle.on( 'click.mw-collapsible', clickHandler );
if ( firstval === undefined || !firstval || firstval === '-1' || firstval === -1 ) {
$firstItem.attr( 'value', '1' );
}
- $toggleLink = $defaultToggleLink;
+ $toggleLink = buildDefaultToggleLink();
$toggleLink.wrap( '<li class="mw-collapsible-toggle-li"></li>' ).parent().prependTo( $collapsible );
} else {
clickHandler = premadeToggleHandler;
// If theres no toggle link, add it
if ( !$toggle.length ) {
- $toggleLink = $defaultToggleLink.prependTo( $collapsible );
+ $toggleLink = buildDefaultToggleLink().prependTo( $collapsible );
} else {
clickHandler = premadeToggleHandler;
$toggleLink = $toggle.on( 'click.mw-collapsible', clickHandler );
}
}
+ // Attributes for accessibility. This isn't necessary when the toggler is already
+ // an <a> or a <button> etc., but it doesn't hurt either, and it's consistent.
+ $toggleLink.prop( 'tabIndex', 0 ).attr( 'role', 'button' );
+
// Initial state
if ( options.collapsed || $collapsible.hasClass( 'mw-collapsed' ) ) {
// Remove here so that the toggler goes in the right direction (the class is re-added)