2 * Scripts for pre-emptive edit preparing on action=edit
5 if ( !mw
.config
.get( 'wgAjaxEditStash' ) ) {
10 var idleTimeout
= 3000,
13 $form
= $( '#editform' ),
14 $text
= $form
.find( '#wpTextbox1' ),
15 $summary
= $form
.find( '#wpSummary' ),
16 section
= $form
.find( '[name=wpSection]' ).val(),
17 model
= $form
.find( '[name=model]' ).val(),
18 format
= $form
.find( '[name=format]' ).val(),
19 revId
= $form
.find( '[name=parentRevId]' ).val(),
20 lastText
= $text
.textSelection( 'getContents' ),
21 lastSummary
= $summary
.textSelection( 'getContents' ),
24 origSummary
= lastSummary
,
29 // Send a request to stash the edit to the API.
30 // If a request is in progress, abort it since its payload is stale and the API
31 // may limit concurrent stash parses.
32 function stashEdit( priority
, hashForReuse
) {
38 api
.getToken( 'csrf' ).then( function ( token
) {
39 // If applicable, just send the hash key to reuse the last text server-side
42 // Update tracking of the last text/summary sent out
43 lastText
= $text
.textSelection( 'getContents' );
44 lastSummary
= $summary
.textSelection( 'getContents' );
45 lastPriority
= priority
;
46 lastTextHash
= null; // "failed" until proven successful
51 title
: mw
.config
.get( 'wgPageName' ),
56 contentformat
: format
,
60 params
.stashedtexthash
= hashForReuse
;
62 params
.text
= lastText
;
65 req
= api
.post( params
);
67 req
.then( function ( data
) {
68 if ( req
=== pending
) {
71 if ( data
.stashedit
&& data
.stashedit
.texthash
) {
72 lastTextHash
= data
.stashedit
.texthash
;
78 // Check if edit body text changed since the last stashEdit() call or if no edit
79 // stash calls have yet been made
80 function isTextChanged() {
81 var newText
= $text
.textSelection( 'getContents' );
82 return newText
!== lastText
;
85 // Check if summary changed since the last stashEdit() call or if no edit
86 // stash calls have yet been made
87 function isSummaryChanged() {
88 var newSummary
= $summary
.textSelection( 'getContents' );
89 return newSummary
!== lastSummary
;
92 function onEditorIdle() {
93 var textChanged
= isTextChanged(),
94 summaryChanged
= isSummaryChanged(),
95 priority
= textChanged
? PRIORITY_HIGH
: PRIORITY_LOW
;
97 if ( !textChanged
&& !summaryChanged
) {
98 return; // nothing to do
101 if ( pending
&& lastPriority
> priority
) {
102 // Stash requests for summary changes should wait on pending text change stashes
103 pending
.then( onEditorIdle
);
107 stashEdit( priority
, textChanged
? null : lastTextHash
);
110 function onKeyUp( e
) {
111 // Ignore keystrokes that don't modify text, like cursor movements.
112 // See <http://www.javascripter.net/faq/keycodes.htm> and
113 // <http://www.quirksmode.org/js/keys.html>. We don't have to be exhaustive,
114 // because the cost of misfiring is low.
115 // * Key code 33-40: Page Up/Down, End, Home, arrow keys.
116 // * Key code 16-18: Shift, Ctrl, Alt.
117 if ( ( e
.which
>= 33 && e
.which
<= 40 ) || ( e
.which
>= 16 && e
.which
<= 18 ) ) {
121 clearTimeout( timer
);
122 timer
= setTimeout( onEditorIdle
, idleTimeout
);
125 function onSummaryFocus() {
126 // Summary typing is usually near the end of the workflow and involves less pausing.
127 // Re-stash frequently in hopes of capturing the final summary before submission.
129 // Stash now since the text is likely the final version. The re-stashes based on the
130 // summary are targeted at caching edit checks that need the final summary.
134 function onTextFocus() {
135 // User returned to the text field...
136 if ( $summary
.textSelection( 'getContents' ) === origSummary
) {
137 idleTimeout
= 3000; // no summary yet; reset stash rate to default
141 function onFormLoaded() {
143 // Reverts may involve use (undo) links; stash as they review the diff.
144 // Since the form has a pre-filled summary, stash the edit immediately.
145 mw
.util
.getParamValue( 'undo' ) !== null
146 // Pressing "show changes" and "preview" also signify that the user will
147 // probably save the page soon
148 || $.inArray( $form
.find( '#mw-edit-mode' ).val(), [ 'preview', 'diff' ] ) > -1
150 stashEdit( PRIORITY_HIGH
, null );
154 // We don't attempt to stash new section edits because in such cases the parser output
155 // varies on the edit summary (since it determines the new section's name).
156 if ( $form
.find( 'input[name=wpSection]' ).val() === 'new' ) {
161 change
: onEditorIdle
,
166 focus
: onSummaryFocus
,
167 focusout
: onEditorIdle
,
172 }( mediaWiki
, jQuery
) );