X-Git-Url: http://git.heureux-cyclage.org/?a=blobdiff_plain;f=resources%2Fsrc%2Fmediawiki.action%2Fmediawiki.action.edit.stash.js;h=6c639575da1e04cb26906ffb90e3c474301d82cd;hb=2442464754ab540163098e1f3c30b0996302bb7f;hp=2069ac5005c0be4b4b117c42d8baa5bf12dfe310;hpb=c13d8c8255f5b47418ac1e57d9e555157a1d44bf;p=lhc%2Fweb%2Fwiklou.git diff --git a/resources/src/mediawiki.action/mediawiki.action.edit.stash.js b/resources/src/mediawiki.action/mediawiki.action.edit.stash.js index 2069ac5005..6c639575da 100644 --- a/resources/src/mediawiki.action/mediawiki.action.edit.stash.js +++ b/resources/src/mediawiki.action/mediawiki.action.edit.stash.js @@ -9,66 +9,129 @@ $( function () { var idleTimeout = 3000, api = new mw.Api(), - pending = null, + timer, + pending, + lastText, + lastSummary, + lastTextHash, $form = $( '#editform' ), $text = $form.find( '#wpTextbox1' ), $summary = $form.find( '#wpSummary' ), - data = {}, - timer = null; + section = $form.find( '[name=wpSection]' ).val(), + model = $form.find( '[name=model]' ).val(), + format = $form.find( '[name=format]' ).val(), + revId = $form.find( '[name=parentRevId]' ).val(), + lastPriority = 0, + PRIORITY_LOW = 1, + PRIORITY_HIGH = 2; // Send a request to stash the edit to the API. // If a request is in progress, abort it since its payload is stale and the API // may limit concurrent stash parses. function stashEdit() { - if ( pending ) { - pending.abort(); - } - api.getToken( 'csrf' ).then( function ( token ) { - data = $form.serializeObject(); + var req, params, + textChanged = isTextChanged(), + priority = textChanged ? PRIORITY_HIGH : PRIORITY_LOW; + + if ( pending ) { + if ( lastPriority > priority ) { + // Stash request for summary change should wait on pending text change stash + pending.then( checkStash ); + return; + } + pending.abort(); + } - pending = api.post( { + // Update the "last" tracking variables + lastSummary = $summary.textSelection( 'getContents' ); + lastPriority = priority; + if ( textChanged ) { + lastText = $text.textSelection( 'getContents' ); + // Reset hash + lastTextHash = null; + } + + params = { action: 'stashedit', token: token, title: mw.config.get( 'wgPageName' ), - section: data.wpSection, + section: section, sectiontitle: '', - text: data.wpTextbox1, - summary: data.wpSummary, - contentmodel: data.model, - contentformat: data.format, - baserevid: data.parentRevId + summary: lastSummary, + contentmodel: model, + contentformat: format, + baserevid: revId + }; + if ( lastTextHash ) { + params.stashedtexthash = lastTextHash; + } else { + params.text = lastText; + } + + req = api.post( params ); + pending = req; + req.then( function ( data ) { + if ( req === pending ) { + pending = null; + } + if ( data.stashedit && data.stashedit.texthash ) { + lastTextHash = data.stashedit.texthash; + } else { + // Request failed or text hash expired; + // include the text in a future stash request. + lastTextHash = null; + } } ); } ); } - // Check if edit body text changed since the last stashEdit() call or if no edit - // stash calls have yet been made - function isChanged() { - // Normalize line endings to CRLF, like $.fn.serializeObject does. - var newText = $text.val().replace( /\r?\n/g, '\r\n' ); - return newText !== data.wpTextbox1; + // Whether the body text content changed since the last stashEdit() + function isTextChanged() { + return lastText !== $text.textSelection( 'getContents' ); + } + + // Whether the edit summary has changed since the last stashEdit() + function isSummaryChanged() { + return lastSummary !== $summary.textSelection( 'getContents' ); } - function onEditorIdle() { - if ( !isChanged() ) { + // Check whether text or summary have changed and call stashEdit() + function checkStash() { + if ( !isTextChanged() && !isSummaryChanged() ) { return; } stashEdit(); } - function onTextKeyUp( e ) { + function onKeyUp( e ) { // Ignore keystrokes that don't modify text, like cursor movements. // See and - // . We don't have to be - // exhaustive, because the cost of misfiring is low. + // . We don't have to be exhaustive, + // because the cost of misfiring is low. + // * Key code 33-40: Page Up/Down, End, Home, arrow keys. + // * Key code 16-18: Shift, Ctrl, Alt. if ( ( e.which >= 33 && e.which <= 40 ) || ( e.which >= 16 && e.which <= 18 ) ) { return; } clearTimeout( timer ); - timer = setTimeout( onEditorIdle, idleTimeout ); + timer = setTimeout( checkStash, idleTimeout ); + } + + function onSummaryFocus() { + // Summary typing is usually near the end of the workflow and involves less pausing. + // Re-stash more frequently in hopes of capturing the final summary before submission. + idleTimeout = 1000; + // Stash now since the text is likely the final version. The re-stashes based on the + // summary are targeted at caching edit checks that need the final summary. + checkStash(); + } + + function onTextFocus() { + // User returned to the text field... reset stash rate to default + idleTimeout = 3000; } function onFormLoaded() { @@ -80,20 +143,26 @@ // probably save the page soon || $.inArray( $form.find( '#mw-edit-mode' ).val(), [ 'preview', 'diff' ] ) > -1 ) { - stashEdit(); + checkStash(); } } - // We don't attempt to stash new section edits because in such cases - // the parser output varies on the edit summary (since it determines - // the new section's name). + // We don't attempt to stash new section edits because in such cases the parser output + // varies on the edit summary (since it determines the new section's name). if ( $form.find( 'input[name=wpSection]' ).val() === 'new' ) { return; } - $text.on( { change: onEditorIdle, keyup: onTextKeyUp } ); - $summary.on( { focus: onEditorIdle } ); + $text.on( { + change: checkStash, + keyup: onKeyUp, + focus: onTextFocus + } ); + $summary.on( { + focus: onSummaryFocus, + focusout: checkStash, + keyup: onKeyUp + } ); onFormLoaded(); - } ); }( mediaWiki, jQuery ) );