From 9084a3a1aaa6a0782142a02e870936bf4b75dcdb Mon Sep 17 00:00:00 2001 From: Brad Jorsch Date: Wed, 30 Oct 2013 14:28:17 -0400 Subject: [PATCH] Add "unsaved changes" warning to Special:Preferences Much like the similar warning on the edit page, it has been requested that we display a warning if the user has made changes on Special:Preferences and attempts to leave without saving. This adapts the code from resources/mediawiki.action/mediawiki.action.edit.editWarning.js to do so. Bug: 55966 Change-Id: Idb00f50ad8148cd80bd0af81b4cd06a0eb217d96 --- includes/Preferences.php | 6 ++- languages/i18n/en.json | 1 + languages/i18n/qqq.json | 1 + resources/Resources.php | 4 ++ .../mediawiki.special.preferences.js | 41 ++++++++++++++++++- 5 files changed, 51 insertions(+), 2 deletions(-) diff --git a/includes/Preferences.php b/includes/Preferences.php index cb978b1d10..84cf5af0f0 100644 --- a/includes/Preferences.php +++ b/includes/Preferences.php @@ -1540,7 +1540,11 @@ class PreferencesForm extends HTMLForm { */ function getButtons() { global $wgUseMediaWikiUIEverywhere; - $attrs = $wgUseMediaWikiUIEverywhere ? array( 'class' => 'mw-ui-button mw-ui-quiet' ) : array(); + + $attrs = array( 'id' => 'mw-prefs-restoreprefs' ); + if ( $wgUseMediaWikiUIEverywhere ) { + $attrs['class'] = 'mw-ui-button mw-ui-quiet'; + } if ( !$this->getModifiedUser()->isAllowedAny( 'editmyprivateinfo', 'editmyoptions' ) ) { return ''; diff --git a/languages/i18n/en.json b/languages/i18n/en.json index e56789a99e..a89003f6da 100644 --- a/languages/i18n/en.json +++ b/languages/i18n/en.json @@ -1016,6 +1016,7 @@ "prefs-tokenwatchlist": "Token", "prefs-diffs": "Diffs", "prefs-help-prefershttps": "This preference will take effect on your next login.", + "prefswarning-warning": "You've made changes to your preferences that have not been saved yet.\nIf you leave this page without clicking \"$1\" your preferences will not be updated.", "prefs-tabs-navigation-hint": "Tip: You can use the left and right arrow keys to navigate between the tabs in the tabs list.", "email-address-validity-valid": "Email address appears valid", "email-address-validity-invalid": "Enter a valid email address", diff --git a/languages/i18n/qqq.json b/languages/i18n/qqq.json index 5c5683ab16..baa1b39c73 100644 --- a/languages/i18n/qqq.json +++ b/languages/i18n/qqq.json @@ -1178,6 +1178,7 @@ "prefs-tokenwatchlist": "Section heading.\nUsed in [[Special:Preferences]], tab \"Watchlist\".\n{{Identical|Token}}", "prefs-diffs": "Used in [[Special:Preferences]], tab \"Misc\".", "prefs-help-prefershttps": "Used as help text for the checkbox in [[Special:Preferences]].\n\nThe checkbox has the label {{msg-mw|Tog-prefershttps}}.\n\nSee example: [[mw:Special:Preferences]].", + "prefswarning-warning": "Warning shown (except in Firefox) when attempting to leave [[Special:Preferences]] with unsaved changes.\n\nParameters:\n* $1 - Text of {{msg-mw|saveprefs}}, as {{int:saveprefs}} cannot be used directly.", "prefs-tabs-navigation-hint": "Hint message that explains the arrow key navigation for the tabs on [[Special:Preferences]] to screenreader users.", "email-address-validity-valid": "Used as hint for {{msg-mw|changeemail-newemail}} field in [[Special:ChangeEmail]], when the provided E-mail address is valid.", "email-address-validity-invalid": "Used as warning for {{msg-mw|changeemail-newemail}} field in [[Special:ChangeEmail]], when the provided E-mail address is invalid.", diff --git a/resources/Resources.php b/resources/Resources.php index 9f64da48c1..9186d46f7c 100644 --- a/resources/Resources.php +++ b/resources/Resources.php @@ -1300,6 +1300,10 @@ return array( 'dependencies' => array( 'mediawiki.language', ), + 'messages' => array( + 'prefswarning-warning', + 'saveprefs', + ), ), 'mediawiki.special.recentchanges' => array( 'scripts' => 'resources/src/mediawiki.special/mediawiki.special.recentchanges.js', diff --git a/resources/src/mediawiki.special/mediawiki.special.preferences.js b/resources/src/mediawiki.special/mediawiki.special.preferences.js index e553f449d6..1f6429b2e6 100644 --- a/resources/src/mediawiki.special/mediawiki.special.preferences.js +++ b/resources/src/mediawiki.special/mediawiki.special.preferences.js @@ -5,7 +5,7 @@ jQuery( function ( $ ) { var $preftoc, $preferences, $fieldsets, $legends, hash, labelFunc, $tzSelect, $tzTextbox, $localtimeHolder, servertime, - $checkBoxes; + $checkBoxes, savedWindowOnBeforeUnload; labelFunc = function () { return this.id.replace( /^mw-prefsection/g, 'preftab' ); @@ -263,4 +263,43 @@ jQuery( function ( $ ) { $( '#mw-input-wpsearcheverything' ).change( function () { $checkBoxes.prop( 'disabled', $( this ).prop( 'checked' ) ); } ); + + // 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() ); + $( window ) + .on( 'beforeunload.prefswarning', function () { + var retval; + + // Check if anything changed + if ( $( '#mw-prefs-form' ).serialize() !== $( '#mw-prefs-form' ).data( 'origdata' ) ) { + // Return our message + retval = mediaWiki.msg( 'prefswarning-warning', mediaWiki.msg( 'saveprefs' ) ); + } + + // Unset the onbeforeunload handler so we don't break page caching in Firefox + savedWindowOnBeforeUnload = window.onbeforeunload; + window.onbeforeunload = null; + if ( retval !== undefined ) { + // ...but if the user chooses not to leave the page, we need to rebind it + setTimeout( function () { + window.onbeforeunload = savedWindowOnBeforeUnload; + }, 1 ); + return retval; + } + } ) + .on( 'pageshow.prefswarning', function () { + // Re-add onbeforeunload handler + if ( !window.onbeforeunload ) { + window.onbeforeunload = savedWindowOnBeforeUnload; + } + } ); + $( '#mw-prefs-form' ).submit( function () { + // Unbind our beforeunload handler + $( window ).off( '.prefswarning' ); + } ); + $( '#mw-prefs-restoreprefs' ).click( function () { + // Unbind our beforeunload handler + $( window ).off( '.prefswarning' ); + } ); } ); -- 2.20.1