Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor the previous history rewriting logic #6200

Merged
merged 1 commit into from Sep 27, 2015
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
88 changes: 56 additions & 32 deletions web/pdf_history.js
Expand Up @@ -75,38 +75,74 @@ var PDFHistory = (function () {

var self = this;
window.addEventListener('popstate', function pdfHistoryPopstate(evt) {
evt.preventDefault();
evt.stopPropagation();

if (!self.historyUnlocked) {
return;
}
if (evt.state) {
// Move back/forward in the history.
self._goTo(evt.state);
} else {
// Handle the user modifying the hash of a loaded document.
self.previousHash = window.location.hash.substring(1);
return;
}

// If the state is not set, then the user tried to navigate to a
// different hash by manually editing the URL and pressing Enter, or by
// clicking on an in-page link (e.g. the "current view" link).
// Save the current view state to the browser history.

// If the history is empty when the hash changes,
// update the previous entry in the browser history.
if (self.uid === 0) {
var previousParams = (self.previousHash && self.currentBookmark &&
// Note: In Firefox, history.null could also be null after an in-page
// navigation to the same URL, and without dispatching the popstate
// event: https://bugzilla.mozilla.org/show_bug.cgi?id=1183881

if (self.uid === 0) {
// Replace the previous state if it was not explicitly set.
var previousParams = (self.previousHash && self.currentBookmark &&
self.previousHash !== self.currentBookmark) ?
{hash: self.currentBookmark, page: self.currentPage} :
{page: 1};
self.historyUnlocked = false;
self.allowHashChange = false;
window.history.back();
self._pushToHistory(previousParams, false, true);
window.history.forward();
self.historyUnlocked = true;
}
self._pushToHistory({hash: self.previousHash}, false, true);
self._updatePreviousBookmark();
replacePreviousHistoryState(previousParams, function() {
updateHistoryWithCurrentHash();
});
} else {
updateHistoryWithCurrentHash();
}
}, false);


function updateHistoryWithCurrentHash() {
self.previousHash = window.location.hash.slice(1);
self._pushToHistory({hash: self.previousHash}, false, true);
self._updatePreviousBookmark();
}

function replacePreviousHistoryState(params, callback) {
// To modify the previous history entry, the following happens:
// 1. history.back()
// 2. _pushToHistory, which calls history.replaceState( ... )
// 3. history.forward()
// Because a navigation via the history API does not immediately update
// the history state, the popstate event is used for synchronization.
self.historyUnlocked = false;

// Suppress the hashchange event to avoid side effects caused by
// navigating back and forward.
self.allowHashChange = false;
window.addEventListener('popstate', rewriteHistoryAfterBack);
history.back();

function rewriteHistoryAfterBack() {
window.removeEventListener('popstate', rewriteHistoryAfterBack);
window.addEventListener('popstate', rewriteHistoryAfterForward);
self._pushToHistory(params, false, true);
history.forward();
}
function rewriteHistoryAfterForward() {
window.removeEventListener('popstate', rewriteHistoryAfterForward);
self.allowHashChange = true;
self.historyUnlocked = true;
callback();
}
}

function pdfHistoryBeforeUnload() {
var previousParams = self._getPreviousParams(null, true);
if (previousParams) {
Expand Down Expand Up @@ -178,19 +214,7 @@ var PDFHistory = (function () {
if (!this.initialized) {
return true;
}
// If the current hash changes when moving back/forward in the history,
// this will trigger a 'popstate' event *as well* as a 'hashchange' event.
// Since the hash generally won't correspond to the exact the position
// stored in the history's state object, triggering the 'hashchange' event
// can thus corrupt the browser history.
//
// When the hash changes during a 'popstate' event, we *only* prevent the
// first 'hashchange' event and immediately reset allowHashChange.
// If it is not reset, the user would not be able to change the hash.

var temp = this.allowHashChange;
this.allowHashChange = true;
return temp;
return this.allowHashChange;
},

_updatePreviousBookmark: function pdfHistory_updatePreviousBookmark() {
Expand Down