Merge "Update docs/hooks.txt for ShowSearchHitTitle"
[mediawiki.git] / resources / src / mediawiki / mediawiki.confirmCloseWindow.js
blobe3a8f7b20cb10c8fbd98d37c43f92e68d3a6b4b0
1 ( function ( mw, $ ) {
2         /**
3          * Prevent the closing of a window with a confirm message (the onbeforeunload event seems to
4          * work in most browsers.)
5          *
6          * This supersedes any previous onbeforeunload handler. If there was a handler before, it is
7          * restored when you execute the returned release() function.
8          *
9          *     var allowCloseWindow = mw.confirmCloseWindow();
10          *     // ... do stuff that can't be interrupted ...
11          *     allowCloseWindow.release();
12          *
13          * The second function returned is a trigger function to trigger the check and an alert
14          * window manually, e.g.:
15          *
16          *     var allowCloseWindow = mw.confirmCloseWindow();
17          *     // ... do stuff that can't be interrupted ...
18          *     if ( allowCloseWindow.trigger() ) {
19          *         // don't do anything (e.g. destroy the input field)
20          *     } else {
21          *         // do whatever you wanted to do
22          *     }
23          *
24          * @method confirmCloseWindow
25          * @member mw
26          * @param {Object} [options]
27          * @param {string} [options.namespace] Namespace for the event registration
28          * @param {string} [options.message]
29          * @param {string} options.message.return The string message to show in the confirm dialog.
30          * @param {Function} [options.test]
31          * @param {boolean} [options.test.return=true] Whether to show the dialog to the user.
32          * @return {Object} An object of functions to work with this module
33          */
34         mw.confirmCloseWindow = function ( options ) {
35                 var savedUnloadHandler,
36                         mainEventName = 'beforeunload',
37                         showEventName = 'pageshow',
38                         message;
40                 options = $.extend( {
41                         message: mw.message( 'mwe-prevent-close' ).text(),
42                         test: function () { return true; }
43                 }, options );
45                 if ( options.namespace ) {
46                         mainEventName += '.' + options.namespace;
47                         showEventName += '.' + options.namespace;
48                 }
50                 if ( $.isFunction( options.message ) ) {
51                         message = options.message();
52                 } else {
53                         message = options.message;
54                 }
56                 $( window ).on( mainEventName, function () {
57                         if ( options.test() ) {
58                                 // remove the handler while the alert is showing - otherwise breaks caching in Firefox (3?).
59                                 // but if they continue working on this page, immediately re-register this handler
60                                 savedUnloadHandler = window.onbeforeunload;
61                                 window.onbeforeunload = null;
62                                 setTimeout( function () {
63                                         window.onbeforeunload = savedUnloadHandler;
64                                 }, 1 );
66                                 // show an alert with this message
67                                 return message;
68                         }
69                 } ).on( showEventName, function () {
70                         // Re-add onbeforeunload handler
71                         if ( !window.onbeforeunload && savedUnloadHandler ) {
72                                 window.onbeforeunload = savedUnloadHandler;
73                         }
74                 } );
76                 /**
77                  * Return the object with functions to release and manually trigger the confirm alert
78                  *
79                  * @ignore
80                  */
81                 return {
82                         /**
83                          * Remove all event listeners and don't show an alert anymore, if the user wants to leave
84                          * the page.
85                          *
86                          * @ignore
87                          */
88                         release: function () {
89                                 $( window ).off( mainEventName + ' ' + showEventName );
90                         },
91                         /**
92                          * Trigger the module's function manually: Check, if options.test() returns true and show
93                          * an alert to the user if he/she want to leave this page. Returns false, if options.test() returns
94                          * false or the user cancelled the alert window (~don't leave the page), true otherwise.
95                          *
96                          * @ignore
97                          * @return {boolean}
98                          */
99                         trigger: function () {
100                                 // use confirm to show the message to the user (if options.text() is true)
101                                 if ( options.test() && !confirm( message ) ) {
102                                         // the user want to keep the actual page
103                                         return false;
104                                 }
105                                 // otherwise return true
106                                 return true;
107                         }
108                 };
109         };
110 }( mediaWiki, jQuery ) );