StashEdit: Refactor and simplify edit.stash.js
authorTimo Tijhof <krinklemail@gmail.com>
Mon, 8 Aug 2016 23:03:39 +0000 (16:03 -0700)
committerAaron Schulz <aschulz@wikimedia.org>
Thu, 11 Aug 2016 01:13:48 +0000 (01:13 +0000)
* Reduce call sites for stashEdit() to only inside checkStash().

* Update onFormLoaded() to not call stashEdit() directly but instead
  call checkStash(). This avoids hardcoding the priority and
  simplifies code by ensuring isTextChanged() and isSummaryChanged()
  are always checked before stashEdit() is called.

* Move texthash and priority handling to stashEdit().

* Don't clear lastTextHash if text hasn't changed.

* Remove check for 'origSummary' in onTextFocus. Have stash rate
  always be 3s for the textarea, and always 1s for the summary.

Change-Id: I3f049df6ee2e1c218e8b3c1c397ff0bc50e58c8e

resources/src/mediawiki.action/mediawiki.action.edit.stash.js

index 704287a..6c63957 100644 (file)
@@ -9,7 +9,11 @@
        $( 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' ),
                        model = $form.find( '[name=model]' ).val(),
                        format = $form.find( '[name=format]' ).val(),
                        revId = $form.find( '[name=parentRevId]' ).val(),
-                       lastText = $text.textSelection( 'getContents' ),
-                       lastSummary = $summary.textSelection( 'getContents' ),
-                       lastTextHash = null,
                        lastPriority = 0,
-                       origSummary = lastSummary,
-                       timer = null,
                        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( priority, hashForReuse ) {
-                       if ( pending ) {
-                               pending.abort();
-                               pending = null;
-                       }
-
+               function stashEdit() {
                        api.getToken( 'csrf' ).then( function ( token ) {
-                               // If applicable, just send the hash key to reuse the last text server-side
-                               var req, params;
+                               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();
+                               }
 
-                               // Update tracking of the last text/summary sent out
-                               lastText = $text.textSelection( 'getContents' );
+                               // Update the "last" tracking variables
                                lastSummary = $summary.textSelection( 'getContents' );
                                lastPriority = priority;
-                               lastTextHash = null; // "failed" until proven successful
+                               if ( textChanged ) {
+                                       lastText = $text.textSelection( 'getContents' );
+                                       // Reset hash
+                                       lastTextHash = null;
+                               }
 
                                params = {
                                        action: 'stashedit',
@@ -56,8 +63,8 @@
                                        contentformat: format,
                                        baserevid: revId
                                };
-                               if ( hashForReuse ) {
-                                       params.stashedtexthash = hashForReuse;
+                               if ( lastTextHash ) {
+                                       params.stashedtexthash = lastTextHash;
                                } else {
                                        params.text = lastText;
                                }
                                        }
                                        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
+               // Whether the body text content changed since the last stashEdit()
                function isTextChanged() {
-                       var newText = $text.textSelection( 'getContents' );
-                       return newText !== lastText;
+                       return lastText !== $text.textSelection( 'getContents' );
                }
 
-               // Check if summary changed since the last stashEdit() call or if no edit
-               // stash calls have yet been made
+               // Whether the edit summary has changed since the last stashEdit()
                function isSummaryChanged() {
-                       var newSummary = $summary.textSelection( 'getContents' );
-                       return newSummary !== lastSummary;
+                       return lastSummary !== $summary.textSelection( 'getContents' );
                }
 
-               function onEditorIdle() {
-                       var textChanged = isTextChanged(),
-                               summaryChanged = isSummaryChanged(),
-                               priority = textChanged ? PRIORITY_HIGH : PRIORITY_LOW;
-
-                       if ( !textChanged && !summaryChanged ) {
-                               return; // nothing to do
-                       }
-
-                       if ( pending && lastPriority > priority ) {
-                               // Stash requests for summary changes should wait on pending text change stashes
-                               pending.then( onEditorIdle );
+               // Check whether text or summary have changed and call stashEdit()
+               function checkStash() {
+                       if ( !isTextChanged() && !isSummaryChanged() ) {
                                return;
                        }
 
-                       stashEdit( priority, textChanged ? null : lastTextHash );
+                       stashEdit();
                }
 
                function onKeyUp( e ) {
                        }
 
                        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 frequently in hopes of capturing the final summary before submission.
+                       // 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.
-                       onEditorIdle();
+                       checkStash();
                }
 
                function onTextFocus() {
-                       // User returned to the text field...
-                       if ( $summary.textSelection( 'getContents' ) === origSummary ) {
-                               idleTimeout = 3000; // no summary yet; reset stash rate to default
-                       }
+                       // User returned to the text field... reset stash rate to default
+                       idleTimeout = 3000;
                }
 
                function onFormLoaded() {
                                // probably save the page soon
                                || $.inArray( $form.find( '#mw-edit-mode' ).val(), [ 'preview', 'diff' ] ) > -1
                        ) {
-                               stashEdit( PRIORITY_HIGH, null );
+                               checkStash();
                        }
                }
 
                }
 
                $text.on( {
-                       change: onEditorIdle,
+                       change: checkStash,
                        keyup: onKeyUp,
                        focus: onTextFocus
                } );
                $summary.on( {
                        focus: onSummaryFocus,
-                       focusout: onEditorIdle,
+                       focusout: checkStash,
                        keyup: onKeyUp
                } );
                onFormLoaded();