Copied from UploadWizard, removed there in I9411a6d33.
Change-Id: I5d35b6fddd73cf56371eeda299ee0779cb40397a
'mediawiki.content.json' => array(
'styles' => 'resources/src/mediawiki/mediawiki.content.json.css',
),
+ 'mediawiki.confirmCloseWindow' => array(
+ 'scripts' => array(
+ 'resources/src/mediawiki/mediawiki.confirmCloseWindow.js',
+ ),
+ ),
'mediawiki.debug' => array(
'scripts' => array(
'resources/src/mediawiki/mediawiki.debug.js',
'scripts' => 'resources/src/mediawiki.action/mediawiki.action.edit.editWarning.js',
'dependencies' => array(
'jquery.textSelection',
- 'mediawiki.jqueryMsg'
+ 'mediawiki.jqueryMsg',
+ 'mediawiki.confirmCloseWindow',
),
'messages' => array(
'editwarning-warning',
'use strict';
$( function () {
- var savedWindowOnBeforeUnload,
- $wpTextbox1 = $( '#wpTextbox1' ),
- $wpSummary = $( '#wpSummary' );
+ var allowCloseWindow,
+ $textBox = $( '#wpTextbox1' ),
+ $summary = $( '#wpSummary' ),
+ $both = $textBox.add( $summary );
+
// Check if EditWarning is enabled and if we need it
- if ( $wpTextbox1.length === 0 ) {
+ if ( !mw.user.options.get( 'useeditwarning' ) ) {
return true;
}
- // Get the original values of some form elements
- $wpTextbox1.add( $wpSummary ).each( function () {
- $( this ).data( 'origtext', $( this ).val() );
+
+ // Save the original value of the text fields
+ $both.each( function ( index, element ) {
+ var $element = $( element );
+ $element.data( 'origtext', $element.textSelection( 'getContents' ) );
} );
- $( window )
- .on( 'beforeunload.editwarning', function () {
- var retval;
- // Check if the current values of some form elements are the same as
- // the original values
- if (
- mw.config.get( 'wgAction' ) === 'submit' ||
- $wpTextbox1.data( 'origtext' ) !== $wpTextbox1.textSelection( 'getContents' ) ||
- $wpSummary.data( 'origtext' ) !== $wpSummary.textSelection( 'getContents' )
- ) {
- // Return our message
- retval = mw.msg( 'editwarning-warning' );
- }
+ allowCloseWindow = mw.confirmCloseWindow( {
+ test: function () {
+ // We use .textSelection, because editors might not have updated the form yet.
+ return mw.config.get( 'wgAction' ) === 'submit' ||
+ $textBox.data( 'origtext' ) !== $textBox.textSelection( 'getContents' ) ||
+ $summary.data( 'origtext' ) !== $summary.textSelection( 'getContents' );
+ },
- // 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.editwarning', function () {
- // Re-add onbeforeunload handler
- if ( !window.onbeforeunload ) {
- window.onbeforeunload = savedWindowOnBeforeUnload;
- }
- } );
+ message: mw.msg( 'editwarning-warning' ),
+ namespace: 'editwarning'
+ } );
// Add form submission handler
$( '#editform' ).submit( function () {
- // Unbind our handlers
- $( window ).off( '.editwarning' );
+ allowCloseWindow();
} );
} );
--- /dev/null
+( function ( mw, $ ) {
+ /**
+ * @method confirmCloseWindow
+ * @member mw
+ *
+ * Prevent the closing of a window with a confirm message (the onbeforeunload event seems to
+ * work in most browsers.)
+ *
+ * This supersedes any previous onbeforeunload handler. If there was a handler before, it is
+ * restored when you execute the returned function.
+ *
+ * var allowCloseWindow = mw.confirmCloseWindow();
+ * // ... do stuff that can't be interrupted ...
+ * allowCloseWindow();
+ *
+ * @param {Object} [options]
+ * @param {string} [options.namespace] Namespace for the event registration
+ * @param {string} [options.message]
+ * @param {string} options.message.return The string message to show in the confirm dialog.
+ * @param {Function} [options.test]
+ * @param {boolean} [options.test.return=true] Whether to show the dialog to the user.
+ * @return {Function} Execute this when you want to allow the user to close the window
+ */
+ mw.confirmCloseWindow = function ( options ) {
+ var savedUnloadHandler,
+ mainEventName = 'beforeunload',
+ showEventName = 'pageshow';
+
+ options = $.extend( {
+ message: mw.message( 'mwe-prevent-close' ).text(),
+ test: function () { return true; }
+ }, options );
+
+ if ( options.namespace ) {
+ mainEventName += '.' + options.namespace;
+ showEventName += '.' + options.namespace;
+ }
+
+ $( window ).on( mainEventName, function () {
+ if ( options.test() ) {
+ // remove the handler while the alert is showing - otherwise breaks caching in Firefox (3?).
+ // but if they continue working on this page, immediately re-register this handler
+ savedUnloadHandler = window.onbeforeunload;
+ window.onbeforeunload = null;
+ setTimeout( function () {
+ window.onbeforeunload = savedUnloadHandler;
+ }, 1 );
+
+ // show an alert with this message
+ return options.message;
+ }
+ } ).on( showEventName, function () {
+ // Re-add onbeforeunload handler
+ if ( !window.onbeforeunload && savedUnloadHandler ) {
+ window.onbeforeunload = savedUnloadHandler;
+ }
+ } );
+
+ // return the function they can use to stop this
+ return function () {
+ $( window ).off( mainEventName + ' ' + showEventName );
+ };
+ };
+} )( mediaWiki, jQuery );