Revert "Special:Preferences: Use OOjs UI" and follow-ups
[lhc/web/wiklou.git] / resources / src / mediawiki.special / mediawiki.special.preferences.tabs.js
index 9f1691c..dcfad27 100644 (file)
@@ -3,10 +3,29 @@
  */
 ( function ( mw, $ ) {
        $( function () {
-               var $preferences, tabs, wrapper, previousTab;
+               var $preftoc, $preferences, $fieldsets, labelFunc, previousTab;
 
+               labelFunc = function () {
+                       return this.id.replace( /^mw-prefsection/g, 'preftab' );
+               };
+
+               $preftoc = $( '#preftoc' );
                $preferences = $( '#preferences' );
 
+               $fieldsets = $preferences.children( 'fieldset' )
+                       .attr( {
+                               role: 'tabpanel',
+                               'aria-labelledby': labelFunc
+                       } );
+               $fieldsets.not( '#mw-prefsection-personal' )
+                       .hide()
+                       .attr( 'aria-hidden', 'true' );
+
+               // T115692: The following is kept for backwards compatibility with older skins
+               $preferences.addClass( 'jsprefs' );
+               $fieldsets.addClass( 'prefsection' );
+               $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
                                } else {
                                        $( this ).css( 'height', 'auto' );
                                }
-                       } ).prependTo( '#mw-content-text' );
-
-               tabs = new OO.ui.IndexLayout( {
-                       expanded: false,
-                       // Do not remove focus from the tabs menu after choosing a tab
-                       autoFocus: false
-               } );
-
-               mw.config.get( 'wgPreferencesTabs' ).forEach( function ( tabConfig ) {
-                       var panel, $panelContents;
-
-                       panel = new OO.ui.TabPanelLayout( tabConfig.name, {
-                               expanded: false,
-                               label: tabConfig.label
-                       } );
-                       $panelContents = $( '#mw-prefsection-' + tabConfig.name );
-
-                       // Hide the unnecessary PHP PanelLayouts
-                       // (Do not use .remove(), as that would remove event handlers for everything inside them)
-                       $panelContents.parent().detach();
-
-                       panel.$element.append( $panelContents );
-                       tabs.addTabPanels( [ panel ] );
-
-                       // Remove duplicate labels
-                       // (This must be after .addTabPanels(), otherwise the tab item doesn't exist yet)
-                       $panelContents.children( 'legend' ).remove();
-                       $panelContents.attr( 'aria-labelledby', panel.getTabItem().getElementId() );
-               } );
-
-               wrapper = new OO.ui.PanelLayout( {
-                       expanded: false,
-                       padded: false,
-                       framed: true
-               } );
-               wrapper.$element.append( tabs.$element );
-               $preferences.prepend( wrapper.$element );
-
-               function updateHash( panel ) {
-                       var scrollTop, active;
-                       // Handle hash manually to prevent jumping,
-                       // therefore save and restore scrollTop to prevent jumping.
-                       scrollTop = $( window ).scrollTop();
-                       // Changing the hash apparently causes keyboard focus to be lost?
-                       // Save and restore it. This makes no sense though.
-                       active = document.activeElement;
-                       location.hash = '#mw-prefsection-' + panel.getName();
-                       if ( active ) {
-                               active.focus();
-                       }
-                       $( window ).scrollTop( scrollTop );
-               }
-
-               tabs.on( 'set', updateHash );
+                       } ).insertBefore( $preftoc );
 
                /**
+                * It uses document.getElementById for security reasons (HTML injections in $()).
+                *
                 * @ignore
                 * @param {string} name the name of a tab without the prefix ("mw-prefsection-")
                 * @param {string} [mode] A hash will be set according to the current
-                *  open section. Set mode 'noHash' to supress this.
+                *  open section. Set mode 'noHash' to surpress this.
                 */
                function switchPrefTab( name, mode ) {
-                       if ( mode === 'noHash' ) {
-                               tabs.off( 'set', updateHash );
+                       var $tab, scrollTop;
+                       // Handle hash manually to prevent jumping,
+                       // therefore save and restore scrollTop to prevent jumping.
+                       scrollTop = $( window ).scrollTop();
+                       if ( mode !== 'noHash' ) {
+                               location.hash = '#mw-prefsection-' + name;
                        }
-                       tabs.setTabPanel( name );
-                       if ( mode === 'noHash' ) {
-                               tabs.on( 'set', updateHash );
+                       $( window ).scrollTop( scrollTop );
+
+                       $preftoc.find( 'li' ).removeClass( 'selected' )
+                               .find( 'a' ).attr( {
+                                       tabIndex: -1,
+                                       'aria-selected': 'false'
+                               } );
+
+                       $tab = $( document.getElementById( 'preftab-' + name ) );
+                       if ( $tab.length ) {
+                               $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' );
                        }
                }
 
+               // 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-', '' ) );
+                       }
+               } );
+
                // Jump to correct section as indicated by the hash.
                // This function is called onload and onhashchange.
                function detectHash() {
                        }
                }
 
-               // Handle other things that change the hash (e.g. using
+               // In browsers that support the onhashchange event we will not bind click
+               // handlers and instead let the browser do the default behavior (clicking the
+               // <a href="#.."> will naturally set the hash, handled by onhashchange.
+               // But other things that change the hash will also be caught (e.g. using
                // the Back and Forward browser navigation).
-               if ( 'onhashchange' in window ) {
+               // Note the special check for IE "compatibility" mode.
+               if ( 'onhashchange' in window &&
+                       ( document.documentMode === undefined || document.documentMode >= 8 )
+               ) {
                        $( window ).on( 'hashchange', function () {
                                var hash = location.hash;
                                if ( hash.match( /^#mw-[\w-]+/ ) ) {
                                } else if ( hash === '' ) {
                                        switchPrefTab( 'personal', 'noHash' );
                                }
+                       } )
+                               // Run the function immediately to select the proper tab on startup.
+                               .trigger( 'hashchange' );
+               // In older browsers we'll bind a click handler as fallback.
+               // We must not have onhashchange *and* the click handlers, otherwise
+               // the click handler calls switchPrefTab() which sets the hash value,
+               // which triggers onhashchange and calls switchPrefTab() again.
+               } else {
+                       $preftoc.on( 'click', 'li a', function ( e ) {
+                               switchPrefTab( $( this ).attr( 'href' ).replace( '#mw-prefsection-', '' ) );
+                               e.preventDefault();
                        } );
+                       // If we've reloaded the page or followed an open-in-new-window,
+                       // make the selected tab visible.
+                       detectHash();
                }
 
-               // If we've reloaded the page or followed an open-in-new-window,
-               // make the selected tab visible.
-               detectHash();
-
                // Restore the active tab after saving the preferences
                previousTab = mw.storage.session.get( 'mwpreferences-prevTab' );
                if ( previousTab ) {
                }
 
                $( '#mw-prefs-form' ).on( 'submit', function () {
-                       var value = tabs.getCurrentTabPanelName();
+                       var value = $( $preftoc ).find( 'li.selected a' ).attr( 'id' ).replace( 'preftab-', '' );
                        mw.storage.session.set( 'mwpreferences-prevTab', value );
                } );