Skip to content

Commit

Permalink
Merge pull request #1280 from patricknelson/issue-1279-fix-inconsiste…
Browse files Browse the repository at this point in the history
…nt-state

FIX Inconsistent state between current URL and actual content if XHR request fails
  • Loading branch information
GuySartorelli authored Jun 14, 2022
2 parents 12ab388 + 4ca5943 commit 8f0bf9e
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 16 deletions.
2 changes: 1 addition & 1 deletion client/dist/js/bundle.js

Large diffs are not rendered by default.

57 changes: 42 additions & 15 deletions client/src/legacy/LeftAndMain.js
Original file line number Diff line number Diff line change
Expand Up @@ -572,26 +572,13 @@ $.entwine('ss', function($) {
this.setStateChangeCount(this.getStateChangeCount() + 1);

if (!this.checkCanNavigate()) {
var lastState = this.getLastState();

// Suppress panel loading while resetting state
this.setPauseState(true);

// Restore best last state
if (lastState && lastState.path) {
window.ss.router.show(lastState.path);
} else {
window.ss.router.back();
}

this.setPauseState(false);
// If the user can't navigate away, restore the last known good state
this.reverseStateChange();

// Abort loading of this panel
return;
}

this.setLastState(historyState);

// If any of the requested Pjax fragments don't exist in the current view,
// fetch the "Content" view instead, which is the "outermost" fragment
// that can be reloaded without reloading the whole window.
Expand Down Expand Up @@ -628,7 +615,17 @@ $.entwine('ss', function($) {
headers: headers,
url: historyState.path || document.URL
})
.fail((xhr, status, error) => {
// Ignoring aborts: The server request failed, so prevent a mixed UI state by rolling back to previously
// succesfully loaded URL (consistent with currently loaded content).
if (xhr.readyState !== 0) {
this.reverseStateChange();
}
})
.done((data, status, xhr) => {
// Request succeeded, so retain this state for future calls to this.reverseStateChange().
this.setLastState(historyState);

var els = self.handleAjaxResponse(data, status, xhr, historyState);
self.trigger('afterstatechange', {data: data, status: status, xhr: xhr, element: els, state: historyState});
})
Expand All @@ -643,6 +640,36 @@ $.entwine('ss', function($) {
return promise;
},

/**
* Reverts the window.history state back to the last known good state. See this.handleStateChange().
*/
reverseStateChange: function() {
// Get last known good state
var lastState = this.getLastState();

// Suppress panel loading while resetting state
this.setPauseState(true);

// Decrement state change counter
this.setStateChangeCount(this.getStateChangeCount() - 1);

// Restore best last state
if (lastState && lastState.path) {
window.ss.router.show(lastState.path);

// Can unpause state now since it's synchronous.
this.setPauseState(false);

} else {
window.ss.router.back();

// Hack: Need to use setTimeout() since, unfortunately .back() above *also* uses setTimeout().
setTimeout(() => {
this.setPauseState(false);
});
}
},

/**
* ALternative to loadPanel/submitForm.
*
Expand Down

0 comments on commit 8f0bf9e

Please sign in to comment.