Prevent PDFHistory._tryPushCurrentPosition() from effectively becoming a no-op if the document hash contains an invalid/non-existent destination

By using the (heuristic) `POSITION_UPDATED_THRESHOLD` constant, we can ensure that the current document position will be added to the browser history when a sufficiently "large" number of `updateviewarea` events have been dispatched.
This commit is contained in:
Jonas Jenwald 2017-08-11 13:54:30 +02:00
parent 0d58bb5512
commit 0ac1fba2f9

View File

@ -18,6 +18,8 @@ import { getGlobalEventBus } from './dom_events';
// Heuristic value used when force-resetting `this._blockHashChange`.
const HASH_CHANGE_TIMEOUT = 1000; // milliseconds
// Heuristic value used when adding the current position to the browser history.
const POSITION_UPDATED_THRESHOLD = 50;
// Heuristic value used when adding a temporary position to the browser history.
const UPDATE_VIEWAREA_TIMEOUT = 2000; // milliseconds
@ -63,12 +65,16 @@ class PDFHistory {
this._boundEvents = Object.create(null);
this._isViewerInPresentationMode = false;
this._isPagesLoaded = false;
// Ensure that we don't miss a 'presentationmodechanged' event, by
// registering the listener immediately.
// Ensure that we don't miss either a 'presentationmodechanged' or a
// 'pagesloaded' event, by registering the listeners immediately.
this.eventBus.on('presentationmodechanged', (evt) => {
this._isViewerInPresentationMode = evt.active || evt.switchInProgress;
});
this.eventBus.on('pagesloaded', (evt) => {
this._isPagesLoaded = !!evt.pagesCount;
});
}
/**
@ -97,6 +103,7 @@ class PDFHistory {
this._popStateInProgress = false;
this._blockHashChange = 0;
this._currentHash = getCurrentHash();
this._numPositionUpdates = 0;
this._currentUid = this._uid = 0;
this._destination = null;
@ -299,7 +306,9 @@ class PDFHistory {
if (this._destination.hash === position.hash) {
return; // The current document position has not changed.
}
if (!this._destination.page) {
if (!this._destination.page &&
(POSITION_UPDATED_THRESHOLD <= 0 ||
this._numPositionUpdates <= POSITION_UPDATED_THRESHOLD)) {
// `this._destination` was set through the user changing the hash of
// the document. Do not add `this._position` to the browser history,
// to avoid "flooding" it with lots of (nearly) identical entries,
@ -357,6 +366,8 @@ class PDFHistory {
this._destination = destination;
this._currentUid = uid;
this._uid = this._currentUid + 1;
// This should always be reset when `this._destination` is updated.
this._numPositionUpdates = 0;
}
/**
@ -379,6 +390,19 @@ class PDFHistory {
return;
}
if (POSITION_UPDATED_THRESHOLD > 0 && this._isPagesLoaded &&
this._destination && !this._destination.page) {
// If the current destination was set through the user changing the hash
// of the document, we will usually not try to push the current position
// to the browser history; see `this._tryPushCurrentPosition()`.
//
// To prevent `this._tryPushCurrentPosition()` from effectively being
// reduced to a no-op in this case, we will assume that the position
// *did* in fact change if the 'updateviewarea' event was dispatched
// more than `POSITION_UPDATED_THRESHOLD` times.
this._numPositionUpdates++;
}
if (UPDATE_VIEWAREA_TIMEOUT > 0) {
// When closing the browser, a 'pagehide' event will be dispatched which
// *should* allow us to push the current position to the browser history.