Add password validation to Special:ChangeCredentials
[lhc/web/wiklou.git] / resources / src / mediawiki.special / mediawiki.special.preferences.js
index f90f859..0fa6610 100644 (file)
@@ -3,10 +3,9 @@
  */
 ( function ( mw, $ ) {
        $( function () {
-               var $preftoc, $preferences, $fieldsets,
-                       labelFunc,
-                       $tzSelect, $tzTextbox, $localtimeHolder, servertime,
-                       allowCloseWindow, notif;
+               var $preftoc, $preferences, $fieldsets, labelFunc, previousTab,
+                       $tzSelect, $tzTextbox, $localtimeHolder, servertime, allowCloseWindow,
+                       convertmessagebox = require( 'mediawiki.notification.convertmessagebox' );
 
                labelFunc = function () {
                        return this.id.replace( /^mw-prefsection/g, 'preftab' );
                        }
                }
 
-               // Check for messageboxes (.successbox, .warningbox, .errorbox) to replace with notifications
-               if ( $( '.mw-preferences-messagebox' ).length ) {
-                       // If there is a #mw-preferences-success box and javascript is enabled, use a slick notification instead!
-                       if ( $( '#mw-preferences-success' ).length ) {
-                               notif = mw.notification.notify( mw.message( 'savedprefs' ), { autoHide: false } );
-                               // 'change' event not reliable!
-                               $( '#preftoc, .prefsection' ).one( 'change keydown mousedown', function () {
-                                       if ( notif ) {
-                                               notif.close();
-                                               notif = null;
-                                       }
-                               } );
-
-                               // Remove now-unnecessary success=1 querystring to prevent reappearance of notification on reload
-                               if ( history.replaceState ) {
-                                       history.replaceState( {}, document.title, location.href.replace( /&?success=1/, '' ) );
-                               }
-                       }
-               }
+               // Check for successbox to replace with notifications
+               convertmessagebox();
 
                // Enable keyboard users to use left and right keys to switch tabs
                $preftoc.on( 'keydown', function ( event ) {
                        var minuteDiff, localTime,
                                type = $tzSelect.val();
 
-                       if ( type === 'guess' ) {
-                               // Get browser timezone & fill it in
-                               minuteDiff = -( new Date().getTimezoneOffset() );
-                               $tzTextbox.val( minutesToHours( minuteDiff ) );
-                               $tzSelect.val( 'other' );
-                               $tzTextbox.prop( 'disabled', false );
-                       } else if ( type === 'other' ) {
+                       if ( type === 'other' ) {
+                               // User specified time zone manually in <input>
                                // Grab data from the textbox, parse it.
                                minuteDiff = hoursToMinutes( $tzTextbox.val() );
                        } else {
-                               // Grab data from the $tzSelect value
-                               minuteDiff = parseInt( type.split( '|' )[ 1 ], 10 ) || 0;
-                               $tzTextbox.val( minutesToHours( minuteDiff ) );
+                               // Time zone not manually specified by user
+                               if ( type === 'guess' ) {
+                                       // Get browser timezone & fill it in
+                                       minuteDiff = -( new Date().getTimezoneOffset() );
+                                       $tzTextbox.val( minutesToHours( minuteDiff ) );
+                                       $tzSelect.val( 'other' );
+                                       $tzTextbox.prop( 'disabled', false );
+                               } else {
+                                       // Grab data from the $tzSelect value
+                                       minuteDiff = parseInt( type.split( '|' )[ 1 ], 10 ) || 0;
+                                       $tzTextbox.val( minutesToHours( minuteDiff ) );
+                               }
+
+                               // Set defaultValue prop on the generated box so we don't trigger the
+                               // unsaved preferences check
+                               $tzTextbox.prop( 'defaultValue', $tzTextbox.val() );
                        }
 
                        // Determine local time from server time and minutes difference, for display.
                        updateTimezoneSelection();
                }
 
-               // Preserve the tab after saving the preferences
-               // Not using cookies, because their deletion results are inconsistent.
-               // Not using jStorage due to its enormous size (for this feature)
-               if ( window.sessionStorage ) {
-                       if ( sessionStorage.getItem( 'mediawikiPreferencesTab' ) !== null ) {
-                               switchPrefTab( sessionStorage.getItem( 'mediawikiPreferencesTab' ), 'noHash' );
-                       }
+               // Restore the active tab after saving the preferences
+               previousTab = mw.storage.session.get( 'mwpreferences-prevTab' );
+               if ( previousTab ) {
+                       switchPrefTab( previousTab, 'noHash' );
                        // Deleting the key, the tab states should be reset until we press Save
-                       sessionStorage.removeItem( 'mediawikiPreferencesTab' );
+                       mw.storage.session.remove( previousTab );
+               }
 
-                       $( '#mw-prefs-form' ).submit( function () {
-                               var storageData = $( $preftoc ).find( 'li.selected a' ).attr( 'id' ).replace( 'preftab-', '' );
-                               sessionStorage.setItem( 'mediawikiPreferencesTab', storageData );
+               $( '#mw-prefs-form' ).on( 'submit', function () {
+                       var value = $( $preftoc ).find( 'li.selected a' ).attr( 'id' ).replace( 'preftab-', '' );
+                       mw.storage.session.set( 'mwpreferences-prevTab', value );
+               } );
+
+               // Check if all of the form values are unchanged
+               function isPrefsChanged() {
+                       var inputs = $( '#mw-prefs-form :input[name]' ),
+                               input, $input, inputType,
+                               index, optIndex,
+                               opt;
+
+                       for ( index = 0; index < inputs.length; index++ ) {
+                               input = inputs[ index ];
+                               $input = $( input );
+
+                               // Different types of inputs have different methods for accessing defaults
+                               if ( $input.is( 'select' ) ) {
+                                       // <select> has the property defaultSelected for each option
+                                       for ( optIndex = 0; optIndex < input.options.length; optIndex++ ) {
+                                               opt = input.options[ optIndex ];
+                                               if ( opt.selected !== opt.defaultSelected ) {
+                                                       return true;
+                                               }
+                                       }
+                               } else if ( $input.is( 'input' ) ) { // <input> has defaultValue or defaultChecked
+                                       inputType = input.type;
+                                       if ( inputType === 'radio' || inputType === 'checkbox' ) {
+                                               if ( input.checked !== input.defaultChecked ) {
+                                                       return true;
+                                               }
+                                       } else if ( input.value !== input.defaultValue ) {
+                                               return true;
+                                       }
+                               }
+                       }
+
+                       return false;
+               }
+
+               // Disable the button to save preferences unless preferences have changed
+               // Check if preferences have been changed before JS has finished loading
+               if ( !isPrefsChanged() ) {
+                       $( '#prefcontrol' ).prop( 'disabled', true );
+                       $( '#preferences > fieldset' ).one( 'change keydown mousedown', function () {
+                               $( '#prefcontrol' ).prop( 'disabled', false );
                        } );
                }
 
                // Set up a message to notify users if they try to leave the page without
                // saving.
-               $( '#mw-prefs-form' ).data( 'origdata', $( '#mw-prefs-form' ).serialize() );
                allowCloseWindow = mw.confirmCloseWindow( {
-                       test: function () {
-                               return $( '#mw-prefs-form' ).serialize() !== $( '#mw-prefs-form' ).data( 'origdata' );
-                       },
-
+                       test: isPrefsChanged,
                        message: mw.msg( 'prefswarning-warning', mw.msg( 'saveprefs' ) ),
                        namespace: 'prefswarning'
                } );