Merge "Revert "Limit searches at 500 per page""
[lhc/web/wiklou.git] / resources / mediawiki.special / mediawiki.special.preferences.js
index 03d93d0..0078724 100644 (file)
@@ -3,22 +3,45 @@
  */
 jQuery( function ( $ ) {
        var $preftoc, $preferences, $fieldsets, $legends,
-               hash,
+               hash, labelFunc,
                $tzSelect, $tzTextbox, $localtimeHolder, servertime;
 
-       $( '#prefsubmit' ).attr( 'id', 'prefcontrol' );
+       labelFunc = function () {
+               return this.id.replace( /^mw-prefsection/g, 'preftab' );
+       };
 
-       $preftoc = $('<ul id="preftoc"></ul>');
+       $( '#prefsubmit' ).attr( 'id', 'prefcontrol' );
+       $preftoc = $( '<ul id="preftoc"></ul>' )
+               .attr( 'role', 'tablist' );
        $preferences = $( '#preferences' )
                .addClass( 'jsprefs' )
                .before( $preftoc );
        $fieldsets = $preferences.children( 'fieldset' )
                .hide()
+               .attr( {
+                       role: 'tabpanel',
+                       'aria-hidden': 'true',
+                       'aria-labelledby': labelFunc
+               } )
                .addClass( 'prefsection' );
        $legends = $fieldsets
                .children( 'legend' )
                .addClass( 'mainLegend' );
 
+       // Make sure the accessibility tip is selectable so that screen reader users take notice,
+       // but hide it per default to reduce interface clutter. Also make sure it becomes visible
+       // when selected. Similar to jquery.mw-jump
+       $( '<div>' ).addClass( 'mw-navigation-hint' )
+               .text( mediaWiki.msg( 'prefs-tabs-navigation-hint' ) )
+               .attr( 'tabIndex', 0 )
+               .on( 'focus blur', function ( e ) {
+                       if ( e.type === 'blur' || e.type === 'focusout' ) {
+                               $( this ).css( 'height', '0' );
+                       } else {
+                               $( this ).css( 'height', 'auto' );
+                       }
+       } ).insertBefore( $preftoc );
+
        /**
         * It uses document.getElementById for security reasons (HTML injections in $()).
         *
@@ -36,18 +59,29 @@ jQuery( function ( $ ) {
                }
                $( window ).scrollTop( scrollTop );
 
-               $preftoc.find( 'li' ).removeClass( 'selected' );
+               $preftoc.find( 'li' ).removeClass( 'selected' )
+                       .find( 'a' ).attr( {
+                               tabIndex: -1,
+                               'aria-selected': 'false'
+                       } );
+
                $tab = $( document.getElementById( 'preftab-' + name ) );
                if ( $tab.length ) {
-                       $tab.parent().addClass( 'selected' );
-                       $preferences.children( 'fieldset' ).hide();
-                       $( document.getElementById( 'mw-prefsection-' + name ) ).show();
+                       $tab.attr( {
+                               tabIndex: 0,
+                               'aria-selected': 'true'
+                       } )
+                       .focus()
+                               .parent().addClass( 'selected' );
+
+                       $preferences.children( 'fieldset' ).hide().attr( 'aria-hidden', 'true' );
+                       $( document.getElementById( 'mw-prefsection-' + name ) ).show().attr( 'aria-hidden', 'false' );
                }
        }
 
        // Populate the prefToc
        $legends.each( function ( i, legend ) {
-               var $legend = $(legend),
+               var $legend = $( legend ),
                        ident, $li, $a;
                if ( i === 0 ) {
                        $legend.parent().show();
@@ -55,17 +89,40 @@ jQuery( function ( $ ) {
                ident = $legend.parent().attr( 'id' );
 
                $li = $( '<li>' )
+                       .attr( 'role', 'presentation' )
                        .addClass( i === 0 ? 'selected' : '' );
                $a = $( '<a>' )
                        .attr( {
                                id: ident.replace( 'mw-prefsection', 'preftab' ),
-                               href: '#' + ident
+                               href: '#' + ident,
+                               role: 'tab',
+                               tabIndex: i === 0 ? 0 : -1,
+                               'aria-selected': i === 0 ? 'true' : 'false',
+                               'aria-controls': ident
                        } )
                        .text( $legend.text() );
                $li.append( $a );
                $preftoc.append( $li );
        } );
 
+       // Enable keyboard users to use left and right keys to switch tabs
+       $preftoc.on( 'keydown', function ( event ) {
+               var keyLeft = 37,
+                       keyRight = 39,
+                       $el;
+
+               if ( event.keyCode === keyLeft ) {
+                       $el = $( '#preftoc li.selected' ).prev().find( 'a' );
+               } else if ( event.keyCode === keyRight ) {
+                       $el = $( '#preftoc li.selected' ).next().find( 'a' );
+               } else {
+                       return;
+               }
+               if ( $el.length > 0 ) {
+                       switchPrefTab( $el.attr( 'href' ).replace( '#mw-prefsection-', '' ) );
+               }
+       } );
+
        // If we've reloaded the page or followed an open-in-new-window,
        // make the selected tab visible.
        hash = window.location.hash;
@@ -82,14 +139,14 @@ jQuery( function ( $ ) {
        if ( 'onhashchange' in window &&
                ( document.documentMode === undefined || document.documentMode >= 8 )
        ) {
-               $(window).on( 'hashchange' , function () {
+               $( window ).on( 'hashchange' , function () {
                        var hash = window.location.hash;
                        if ( hash.match( /^#mw-prefsection-[\w\-]+/ ) ) {
                                switchPrefTab( hash.replace( '#mw-prefsection-', '' ) );
                        } else if ( hash === '' ) {
                                switchPrefTab( 'personal', 'noHash' );
                        }
-               });
+               } );
        // In older browsers we'll bind a click handler as fallback.
        // We must not have onhashchange *and* the click handlers, other wise
        // the click handler calls switchPrefTab() which sets the hash value,
@@ -98,7 +155,7 @@ jQuery( function ( $ ) {
                $preftoc.on( 'click', 'li a', function ( e ) {
                        switchPrefTab( $( this ).attr( 'href' ).replace( '#mw-prefsection-', '' ) );
                        e.preventDefault();
-               });
+               } );
        }
 
        /**
@@ -172,7 +229,7 @@ jQuery( function ( $ ) {
                while ( localTime >= 1440 ) {
                        localTime -= 1440;
                }
-               $localtimeHolder.text( minutesToHours( localTime ) );
+               $localtimeHolder.text( mediaWiki.language.convertNumber( minutesToHours( localTime ) ) );
        }
 
        if ( $tzSelect.length && $tzTextbox.length ) {