jquery.makeCollapsible: Togglers keyboard accessibility
authorMatmaRex <matma.rex@gmail.com>
Tue, 9 Jul 2013 12:31:08 +0000 (14:31 +0200)
committerMatmaRex <matma.rex@gmail.com>
Tue, 9 Jul 2013 12:31:08 +0000 (14:31 +0200)
Handle keypresses where e.which is 13 (Enter key) in addition to clicks.

Followup to If59590de.

Bug: 17616
Change-Id: Ib86833dbbbe8d5e4109090c70f1949ba97b9d119

resources/jquery/jquery.makeCollapsible.js

index 3a6c1b1..5ca0b12 100644 (file)
        }
 
        /**
-        * Handles clicking on the collapsible element toggle and other
+        * Handles clicking/keypressing on the collapsible element toggle and other
         * situations where a collapsible element is toggled (e.g. the initial
         * toggle for collapsed ones).
         *
                }
 
                if ( e ) {
-                       // Don't fire if a link was clicked, if requested  (for premade togglers by default)
-                       if ( options.linksPassthru && $.nodeName( e.target, 'a' ) ) {
+                       if ( e.type === 'click' && options.linksPassthru && $.nodeName( e.target, 'a' ) ) {
+                               // Don't fire if a link was clicked, if requested  (for premade togglers by default)
+                               return;
+                       } else if ( e.type === 'keypress' && e.which !== 13 ) {
+                               // Only handle keypresses on the "Enter" key
                                return;
                        } else {
                                e.preventDefault();
                }
 
                return this.each( function () {
-                       var $collapsible, collapseText, expandText, $toggle, clickHandler, buildDefaultToggleLink,
+                       var $collapsible, collapseText, expandText, $toggle, actionHandler, buildDefaultToggleLink,
                                premadeToggleHandler, $toggleLink, $firstItem, collapsibleId, $customTogglers, firstval;
 
                        // Ensure class "mw-collapsible" is present in case .makeCollapsible()
                        collapseText = options.collapseText || $collapsible.attr( 'data-collapsetext' ) || mw.msg( 'collapsible-collapse' );
                        expandText = options.expandText || $collapsible.attr( 'data-expandtext' ) || mw.msg( 'collapsible-expand' );
 
-                       // Default click handler and toggle link to use when none is present
-                       clickHandler = function ( e, opts ) {
+                       // Default click/keypress handler and toggle link to use when none is present
+                       actionHandler = function ( e, opts ) {
                                var defaultOpts = {
                                        toggleClasses: true,
                                        toggleText: { collapseText: collapseText, expandText: expandText }
                                                .parent()
                                                .prepend( '&nbsp;[' )
                                                .append( ']&nbsp;' )
-                                               .on( 'click.mw-collapsible', clickHandler );
+                                               .on( 'click.mw-collapsible keypress.mw-collapsible', actionHandler );
                        };
 
                        // Default handler for clicking on premade toggles
 
                        // Bind the togglers
                        if ( $customTogglers && $customTogglers.length ) {
-                               clickHandler = function ( e, opts ) {
+                               actionHandler = function ( e, opts ) {
                                        var defaultOpts = {};
                                        opts = $.extend( defaultOpts, options, opts );
                                        togglingHandler( $( this ), $collapsible, e, opts );
                                };
 
                                $toggleLink = $customTogglers;
-                               $toggleLink.on( 'click.mw-collapsible', clickHandler );
+                               $toggleLink.on( 'click.mw-collapsible keypress.mw-collapsible', actionHandler );
 
                        } else {
                                // If this is not a custom case, do the default: wrap the
                                        if ( !$toggle.length ) {
                                                $toggleLink = buildDefaultToggleLink().prependTo( $firstItem.eq( -1 ) );
                                        } else {
-                                               clickHandler = premadeToggleHandler;
-                                               $toggleLink = $toggle.on( 'click.mw-collapsible', clickHandler );
+                                               actionHandler = premadeToggleHandler;
+                                               $toggleLink = $toggle.on( 'click.mw-collapsible keypress.mw-collapsible', actionHandler );
                                        }
 
                                } else if ( $collapsible.is( 'ul' ) || $collapsible.is( 'ol' ) ) {
                                                $toggleLink = buildDefaultToggleLink();
                                                $toggleLink.wrap( '<li class="mw-collapsible-toggle-li"></li>' ).parent().prependTo( $collapsible );
                                        } else {
-                                               clickHandler = premadeToggleHandler;
-                                               $toggleLink = $toggle.on( 'click.mw-collapsible', clickHandler );
+                                               actionHandler = premadeToggleHandler;
+                                               $toggleLink = $toggle.on( 'click.mw-collapsible keypress.mw-collapsible', actionHandler );
                                        }
 
                                } else { // <div>, <p> etc.
                                        if ( !$toggle.length ) {
                                                $toggleLink = buildDefaultToggleLink().prependTo( $collapsible );
                                        } else {
-                                               clickHandler = premadeToggleHandler;
-                                               $toggleLink = $toggle.on( 'click.mw-collapsible', clickHandler );
+                                               actionHandler = premadeToggleHandler;
+                                               $toggleLink = $toggle.on( 'click.mw-collapsible keypress.mw-collapsible', actionHandler );
                                        }
                                }
                        }
                                $collapsible.removeClass( 'mw-collapsed' );
                                // One toggler can hook to multiple elements, and one element can have
                                // multiple togglers. This is the sanest way to handle that.
-                               clickHandler.call( $toggleLink.get( 0 ), null, { instantHide: true } );
+                               actionHandler.call( $toggleLink.get( 0 ), null, { instantHide: true } );
                        }
                } );
        };