Use <a> instead of <a href="#"> for JavaScript click events
authorFomafix <fomafix@googlemail.com>
Mon, 16 Jun 2014 08:30:17 +0000 (08:30 +0000)
committerBartosz Dziewoński <matma.rex@gmail.com>
Tue, 11 Oct 2016 15:53:43 +0000 (15:53 +0000)
* No status line with URL and "#".
* No new tab on middle click.

a { cursor: pointer; } ensures to have a pointer as mouse cursor on hover.

tabindex="0" ensures to have a normal tab order.

role="button" according to
https://www.mediawiki.org/wiki/Accessibility_guide_for_developers

Change-Id: I5903901752ffb52e778f3582c7da0f820dc305c8

resources/src/jquery/jquery.makeCollapsible.js
resources/src/mediawiki.action/mediawiki.action.view.metadata.js
resources/src/mediawiki.skinning/elements.css
resources/src/mediawiki/mediawiki.jqueryMsg.js
resources/src/mediawiki/mediawiki.toc.js
tests/qunit/suites/resources/mediawiki/mediawiki.jqueryMsg.test.js

index ac60e8f..eef3846 100644 (file)
                        };
                        // Default toggle link. Only build it when needed to avoid jQuery memory leaks (event data).
                        buildDefaultToggleLink = function () {
-                               return $( '<a href="#"></a>' )
+                               return $( '<a>' )
+                                       .attr( {
+                                               role: 'button',
+                                               tabindex: 0
+                                       } )
                                        .text( collapseText )
                                        .wrap( '<span class="mw-collapsible-toggle"></span>' )
                                                .parent()
index 4c75e33..a3a82d5 100644 (file)
 
                $link = $( '<a>' )
                .text( showText )
-               .attr( 'href', '#' )
-               .click( function () {
-                       if ( $table.hasClass( 'collapsed' ) ) {
-                               $( this ).text( hideText );
-                       } else {
-                               $( this ).text( showText );
+               .attr( {
+                       role: 'button',
+                       tabindex: 0
+               } )
+               .on( 'click keypress', function ( e ) {
+                       if (
+                               e.type === 'click' ||
+                               e.type === 'keypress' && e.which === 13
+                       ) {
+                               if ( $table.hasClass( 'collapsed' ) ) {
+                                       $( this ).text( hideText );
+                               } else {
+                                       $( this ).text( showText );
+                               }
+                               $table.toggleClass( 'expanded collapsed' );
                        }
-                       $table.toggleClass( 'expanded collapsed' );
-                       return false;
                } );
 
                $col.append( $link );
index 7b0b071..5fbfb85 100644 (file)
@@ -11,6 +11,7 @@ a {
        text-decoration: none;
        color: #0645ad;
        background: none;
+       cursor: pointer; /* Always cursor:pointer even without href */
 }
 
 a:visited {
index 44b9117..2646cff 100644 (file)
                        } else {
                                $el = $( '<a>' );
                                if ( typeof arg === 'function' ) {
-                                       $el.attr( 'href', '#' )
-                                       .click( function ( e ) {
-                                               e.preventDefault();
+                                       $el.attr( {
+                                               role: 'button',
+                                               tabindex: 0
                                        } )
-                                       .click( arg );
+                                       .on( 'click keypress', function ( e ) {
+                                               if (
+                                                       e.type === 'click' ||
+                                                       e.type === 'keypress' && e.which === 13
+                                               ) {
+                                                       arg.call( this, e );
+                                               }
+                                       } );
                                } else {
                                        $el.attr( 'href', textify( arg ) );
                                }
index 7bf73b6..0955c23 100644 (file)
@@ -10,8 +10,7 @@
                $tocList = $toc.find( 'ul' ).eq( 0 );
 
                // Hide/show the table of contents element
-               function toggleToc( e ) {
-                       e.preventDefault();
+               function toggleToc() {
                        if ( $tocList.is( ':hidden' ) ) {
                                $tocList.slideDown( 'fast' );
                                $tocToggleLink.text( mw.msg( 'hidetoc' ) );
                if ( $toc.length && $tocTitle.length && $tocList.length && !$tocToggleLink.length ) {
                        hideToc = mw.cookie.get( 'hidetoc' ) === '1';
 
-                       $tocToggleLink = $( '<a href="#" id="togglelink"></a>' )
+                       $tocToggleLink = $( '<a role="button" tabindex="0" id="togglelink"></a>' )
                                .text( mw.msg( hideToc ? 'showtoc' : 'hidetoc' ) )
-                               .click( toggleToc );
+                               .on( 'click keypress', function ( e ) {
+                                       if (
+                                               e.type === 'click' ||
+                                               e.type === 'keypress' && e.which === 13
+                                       ) {
+                                               toggleToc();
+                                       }
+                               } );
 
                        $tocTitle.append(
                                $tocToggleLink
index 7133039..caaef83 100644 (file)
                );
                assert.htmlEqual(
                        formatParse( 'external-link-replace', function () {} ),
-                       'Foo <a href="#">bar</a>',
+                       'Foo <a role="button" tabindex="0">bar</a>',
                        'External link message processed as function when format is \'parse\''
                );