2 * JavaScript for Special:Preferences
4 jQuery( document
).ready( function ( $ ) {
5 $( '#prefsubmit' ).attr( 'id', 'prefcontrol' );
6 var $preftoc
= $('<ul id="preftoc"></ul>');
7 var $preferences
= $( '#preferences' )
11 var $fieldsets
= $preferences
.children( 'fieldset' )
13 .addClass( 'prefsection' );
15 var $legends
= $fieldsets
.children( 'legend' )
16 .addClass( 'mainLegend' );
19 * It uses document.getElementById for security reasons (html injections in
22 * @param String name: the name of a tab without the prefix ("mw-prefsection-")
23 * @param String mode: [optional] A hash will be set according to the current
24 * open section. Set mode 'noHash' to surpress this.
26 function switchPrefTab( name
, mode
) {
28 // Handle hash manually to prevent jumping,
29 // therefore save and restore scrollTop to prevent jumping.
30 scrollTop
= $( window
).scrollTop();
31 if ( mode
!== 'noHash' ) {
32 window
.location
.hash
= '#mw-prefsection-' + name
;
34 $( window
).scrollTop( scrollTop
);
36 $preftoc
.find( 'li' ).removeClass( 'selected' );
37 $tab
= $( document
.getElementById( 'preftab-' + name
) );
39 $tab
.parent().addClass( 'selected' );
40 $preferences
.children( 'fieldset' ).hide();
41 $( document
.getElementById( 'mw-prefsection-' + name
) ).show();
45 // Populate the prefToc
46 $legends
.each( function ( i
, legend
) {
47 var $legend
= $(legend
);
49 $legend
.parent().show();
51 var ident
= $legend
.parent().attr( 'id' );
53 var $li
= $( '<li/>', {
54 'class' : ( i
=== 0 ) ? 'selected' : null
57 text
: $legend
.text(),
58 id
: ident
.replace( 'mw-prefsection', 'preftab' ),
62 $preftoc
.append( $li
);
65 // If we've reloaded the page or followed an open-in-new-window,
66 // make the selected tab visible.
67 var hash
= window
.location
.hash
;
68 if ( hash
.match( /^#mw-prefsection-[\w-]+/ ) ) {
69 switchPrefTab( hash
.replace( '#mw-prefsection-' , '' ) );
72 // In browsers that support the onhashchange event we will not bind click
73 // handlers and instead let the browser do the default behavior (clicking the
74 // <a href="#.."> will naturally set the hash, handled by onhashchange.
75 // But other things that change the hash will also be catched (e.g. using
76 // the Back and Forward browser navigation).
77 if ( 'onhashchange' in window
) {
78 $(window
).on( 'hashchange' , function () {
79 var hash
= window
.location
.hash
;
80 if ( hash
.match( /^#mw-prefsection-[\w-]+/ ) ) {
81 switchPrefTab( hash
.replace( '#mw-prefsection-', '' ) );
82 } else if ( hash
=== '' ) {
83 switchPrefTab( 'personal', 'noHash' );
86 // In older browsers we'll bind a click handler as fallback.
87 // We must not have onhashchange *and* the click handlers, other wise
88 // the click handler calls switchPrefTab() which sets the hash value,
89 // which triggers onhashcange and calls switchPrefTab() again.
91 $preftoc
.on( 'click', 'li a', function ( e
) {
92 switchPrefTab( $( this ).attr( 'href' ).replace( '#mw-prefsection-', '' ) );
99 * Guesses Timezone from browser and updates fields onchange
102 var $tzSelect
= $( '#mw-input-wptimecorrection' );
103 var $tzTextbox
= $( '#mw-input-wptimecorrection-other' );
105 var $localtimeHolder
= $( '#wpLocalTime' );
106 var servertime
= parseInt( $( 'input[name=wpServerTime]' ).val(), 10 );
109 var minutesToHours = function ( min
) {
110 var tzHour
= Math
.floor( Math
.abs( min
) / 60 );
111 var tzMin
= Math
.abs( min
) % 60;
112 var tzString
= ( ( min
>= 0 ) ? '' : '-' ) + ( ( tzHour
< 10 ) ? '0' : '' ) + tzHour
+
113 ':' + ( ( tzMin
< 10 ) ? '0' : '' ) + tzMin
;
117 var hoursToMinutes = function ( hour
) {
118 var arr
= hour
.split( ':' );
119 arr
[0] = parseInt( arr
[0], 10 );
122 if ( arr
.length
== 1 ) {
123 // Specification is of the form [-]XX
124 minutes
= arr
[0] * 60;
126 // Specification is of the form [-]XX:XX
127 minutes
= Math
.abs( arr
[0] ) * 60 + parseInt( arr
[1], 10 );
132 // Gracefully handle non-numbers.
133 if ( isNaN( minutes
) ) {
140 var updateTimezoneSelection = function () {
141 var type
= $tzSelect
.val();
142 if ( type
== 'guess' ) {
143 // Get browser timezone & fill it in
144 minuteDiff
= -new Date().getTimezoneOffset();
145 $tzTextbox
.val( minutesToHours( minuteDiff
) );
146 $tzSelect
.val( 'other' );
147 $tzTextbox
.get( 0 ).disabled
= false;
148 } else if ( type
== 'other' ) {
149 // Grab data from the textbox, parse it.
150 minuteDiff
= hoursToMinutes( $tzTextbox
.val() );
152 // Grab data from the $tzSelect value
153 minuteDiff
= parseInt( type
.split( '|' )[1], 10 ) || 0;
154 $tzTextbox
.val( minutesToHours( minuteDiff
) );
157 // Determine local time from server time and minutes difference, for display.
158 var localTime
= servertime
+ minuteDiff
;
160 // Bring time within the [0,1440) range.
161 while ( localTime
< 0 ) {
164 while ( localTime
>= 1440 ) {
167 $localtimeHolder
.text( minutesToHours( localTime
) );
170 if ( $tzSelect
.length
&& $tzTextbox
.length
) {
171 $tzSelect
.change( function () { updateTimezoneSelection(); } );
172 $tzTextbox
.blur( function () { updateTimezoneSelection(); } );
173 updateTimezoneSelection();