SpecialPreferences: Use real OOUI PHP layouts
[lhc/web/wiklou.git] / resources / src / mediawiki.special.preferences.ooui / tabs.js
1 /*!
2 * JavaScript for Special:Preferences: Tab navigation.
3 */
4 ( function () {
5 $( function () {
6 var tabs, previousTab, switchingNoHash;
7
8 // Make sure the accessibility tip is focussable so that keyboard users take notice,
9 // but hide it by default to reduce visual clutter.
10 // Make sure it becomes visible when focused.
11 $( '<div>' ).addClass( 'mw-navigation-hint' )
12 .text( mw.msg( 'prefs-tabs-navigation-hint' ) )
13 .attr( {
14 tabIndex: 0,
15 'aria-hidden': 'true'
16 } )
17 .insertBefore( '.mw-htmlform-ooui-wrapper' );
18
19 tabs = OO.ui.infuse( $( '.mw-prefs-tabs' ) );
20
21 tabs.$element.addClass( 'mw-prefs-tabs-infused' );
22
23 function enhancePanel( panel ) {
24 if ( !panel.$element.data( 'mw-section-infused' ) ) {
25 panel.$element.removeClass( 'mw-htmlform-autoinfuse-lazy' );
26 mw.hook( 'htmlform.enhance' ).fire( panel.$element );
27 panel.$element.data( 'mw-section-infused', true );
28 }
29 }
30
31 function onTabPanelSet( panel ) {
32 var scrollTop, active;
33
34 if ( switchingNoHash ) {
35 return;
36 }
37 // Handle hash manually to prevent jumping,
38 // therefore save and restore scrollTop to prevent jumping.
39 scrollTop = $( window ).scrollTop();
40 // Changing the hash apparently causes keyboard focus to be lost?
41 // Save and restore it. This makes no sense though.
42 active = document.activeElement;
43 location.hash = '#' + panel.getName();
44 if ( active ) {
45 active.focus();
46 }
47 $( window ).scrollTop( scrollTop );
48 }
49
50 tabs.on( 'set', onTabPanelSet );
51
52 /**
53 * @ignore
54 * @param {string} name The name of a tab
55 * @param {boolean} [noHash] A hash will be set according to the current
56 * open section. Use this flag to suppress this.
57 */
58 function switchPrefTab( name, noHash ) {
59 if ( noHash ) {
60 switchingNoHash = true;
61 }
62 tabs.setTabPanel( name );
63 enhancePanel( tabs.getCurrentTabPanel() );
64 if ( noHash ) {
65 switchingNoHash = false;
66 }
67 }
68
69 // Jump to correct section as indicated by the hash.
70 // This function is called onload and onhashchange.
71 function detectHash() {
72 var hash = location.hash,
73 matchedElement, parentSection;
74 if ( hash.match( /^#mw-prefsection-[\w]+$/ ) ) {
75 mw.storage.session.remove( 'mwpreferences-prevTab' );
76 switchPrefTab( hash.slice( 1 ) );
77 } else if ( hash.match( /^#mw-[\w-]+$/ ) ) {
78 matchedElement = document.getElementById( hash.slice( 1 ) );
79 parentSection = $( matchedElement ).parent().closest( '[id^="mw-prefsection-"]' );
80 if ( parentSection.length ) {
81 mw.storage.session.remove( 'mwpreferences-prevTab' );
82 // Switch to proper tab and scroll to selected item.
83 switchPrefTab( parentSection.attr( 'id' ), true );
84 matchedElement.scrollIntoView();
85 }
86 }
87 }
88
89 $( window ).on( 'hashchange', function () {
90 var hash = location.hash;
91 if ( hash.match( /^#mw-[\w-]+/ ) ) {
92 detectHash();
93 } else if ( hash === '' ) {
94 switchPrefTab( 'mw-prefsection-personal', true );
95 }
96 } )
97 // Run the function immediately to select the proper tab on startup.
98 .trigger( 'hashchange' );
99
100 // Restore the active tab after saving the preferences
101 previousTab = mw.storage.session.get( 'mwpreferences-prevTab' );
102 if ( previousTab ) {
103 switchPrefTab( previousTab, true );
104 // Deleting the key, the tab states should be reset until we press Save
105 mw.storage.session.remove( 'mwpreferences-prevTab' );
106 }
107
108 $( '#mw-prefs-form' ).on( 'submit', function () {
109 var value = tabs.getCurrentTabPanelName();
110 mw.storage.session.set( 'mwpreferences-prevTab', value );
111 } );
112
113 } );
114 }() );