Perform edit stashing when the edit preview or diff form is requested
[mediawiki.git] / resources / src / mediawiki.action / mediawiki.action.edit.stash.js
blob71ed44ca7f6bb920411fb97d4241df578c62813a
1 /*!
2  * Scripts for pre-emptive edit preparing on action=edit
3  */
4 ( function ( mw, $ ) {
5         $( function () {
6                 var idleTimeout = 3000,
7                         api = new mw.Api(),
8                         pending = null,
9                         $form = $( '#editform' ),
10                         $text = $form.find( '#wpTextbox1' ),
11                         $summary = $form.find( '#wpSummary' ),
12                         data = {},
13                         timer = null;
15                 // Send a request to stash the edit to the API.
16                 // If a request is in progress, abort it since its payload is stale and the API
17                 // may limit concurrent stash parses.
18                 function stashEdit() {
19                         if ( pending ) {
20                                 pending.abort();
21                         }
23                         api.getToken( 'csrf' ).then( function ( token ) {
24                                 data = $form.serializeObject();
26                                 pending = api.post( {
27                                         action: 'stashedit',
28                                         token: token,
29                                         title: mw.config.get( 'wgPageName' ),
30                                         section: data.wpSection,
31                                         sectiontitle: '',
32                                         text: data.wpTextbox1,
33                                         summary: data.wpSummary,
34                                         contentmodel: data.model,
35                                         contentformat: data.format,
36                                         baserevid: data.parentRevId
37                                 } );
38                         } );
39                 }
41                 // Check if edit body text changed since the last stashEdit() call or if no edit
42                 // stash calls have yet been made
43                 function isChanged() {
44                         // Normalize line endings to CRLF, like $.fn.serializeObject does.
45                         var newText = $text.val().replace( /\r?\n/g, '\r\n' );
46                         return newText !== data.wpTextbox1;
47                 }
49                 function onTextChanged() {
50                         if ( !isChanged() ) {
51                                 return;
52                         }
54                         stashEdit();
55                 }
57                 function onTextKeyPress( e ) {
58                         // Ignore keystrokes that don't modify text, like cursor movements.
59                         // See <http://stackoverflow.com/q/2284844>.
60                         if ( e.which === 0 ) {
61                                 return;
62                         }
64                         clearTimeout( timer );
66                         if ( pending ) {
67                                 pending.abort();
68                         }
70                         timer = setTimeout( onTextChanged, idleTimeout );
71                 }
73                 function onFormLoaded() {
74                         if (
75                                 // Reverts may involve use (undo) links; stash as they review the diff.
76                                 // Since the form has a pre-filled summary, stash the edit immediately.
77                                 mw.util.getParamValue( 'undo' ) !== null
78                                 // Pressing "show changes" and "preview" also signify that the user will
79                                 // probably save the page soon
80                                 || $.inArray( $form.find( '#mw-edit-mode' ).val(), [ 'preview', 'diff' ] ) > -1
81                         ) {
82                                 stashEdit();
83                         }
84                 }
86                 // We don't attempt to stash new section edits because in such cases
87                 // the parser output varies on the edit summary (since it determines
88                 // the new section's name).
89                 if ( $form.find( 'input[name=wpSection]' ).val() === 'new' ) {
90                         return;
91                 }
93                 $text.on( { change: onTextChanged, keypress: onTextKeyPress } );
94                 $summary.on( { focus: onTextChanged } );
95                 onFormLoaded();
97         } );
98 }( mediaWiki, jQuery ) );