Generic build of PDF.js library.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

315 lines
11 KiB

/* Copyright 2017 Mozilla Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.PDFHistory = undefined;
var _dom_events = require('./dom_events');
function PDFHistory(options) {
this.linkService = options.linkService;
this.eventBus = options.eventBus || (0, _dom_events.getGlobalEventBus)();
this.initialized = false;
this.initialDestination = null;
this.initialBookmark = null;
}
PDFHistory.prototype = {
initialize: function pdfHistoryInitialize(fingerprint) {
this.initialized = true;
this.reInitialized = false;
this.allowHashChange = true;
this.historyUnlocked = true;
this.isViewerInPresentationMode = false;
this.previousHash = window.location.hash.substring(1);
this.currentBookmark = '';
this.currentPage = 0;
this.updatePreviousBookmark = false;
this.previousBookmark = '';
this.previousPage = 0;
this.nextHashParam = '';
this.fingerprint = fingerprint;
this.currentUid = this.uid = 0;
this.current = {};
var state = window.history.state;
if (this._isStateObjectDefined(state)) {
if (state.target.dest) {
this.initialDestination = state.target.dest;
} else {
this.initialBookmark = state.target.hash;
}
this.currentUid = state.uid;
this.uid = state.uid + 1;
this.current = state.target;
} else {
if (state && state.fingerprint && this.fingerprint !== state.fingerprint) {
this.reInitialized = true;
}
this._pushOrReplaceState({ fingerprint: this.fingerprint }, true);
}
var self = this;
window.addEventListener('popstate', function pdfHistoryPopstate(evt) {
if (!self.historyUnlocked) {
return;
}
if (evt.state) {
self._goTo(evt.state);
return;
}
if (self.uid === 0) {
var previousParams = self.previousHash && self.currentBookmark && self.previousHash !== self.currentBookmark ? {
hash: self.currentBookmark,
page: self.currentPage
} : { page: 1 };
replacePreviousHistoryState(previousParams, function () {
updateHistoryWithCurrentHash();
});
} else {
updateHistoryWithCurrentHash();
}
});
function updateHistoryWithCurrentHash() {
self.previousHash = window.location.hash.slice(1);
self._pushToHistory({ hash: self.previousHash }, false, true);
self._updatePreviousBookmark();
}
function replacePreviousHistoryState(params, callback) {
self.historyUnlocked = false;
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) {
var replacePrevious = !self.current.dest && self.current.hash !== self.previousHash;
self._pushToHistory(previousParams, false, replacePrevious);
self._updatePreviousBookmark();
}
window.removeEventListener('beforeunload', pdfHistoryBeforeUnload);
}
window.addEventListener('beforeunload', pdfHistoryBeforeUnload);
window.addEventListener('pageshow', function pdfHistoryPageShow(evt) {
window.addEventListener('beforeunload', pdfHistoryBeforeUnload);
});
self.eventBus.on('presentationmodechanged', function (e) {
self.isViewerInPresentationMode = e.active;
});
},
clearHistoryState: function pdfHistory_clearHistoryState() {
this._pushOrReplaceState(null, true);
},
_isStateObjectDefined: function pdfHistory_isStateObjectDefined(state) {
return state && state.uid >= 0 && state.fingerprint && this.fingerprint === state.fingerprint && state.target && state.target.hash ? true : false;
},
_pushOrReplaceState: function pdfHistory_pushOrReplaceState(stateObj, replace) {
if (replace) {
window.history.replaceState(stateObj, '', document.URL);
} else {
window.history.pushState(stateObj, '', document.URL);
}
},
get isHashChangeUnlocked() {
if (!this.initialized) {
return true;
}
return this.allowHashChange;
},
_updatePreviousBookmark: function pdfHistory_updatePreviousBookmark() {
if (this.updatePreviousBookmark && this.currentBookmark && this.currentPage) {
this.previousBookmark = this.currentBookmark;
this.previousPage = this.currentPage;
this.updatePreviousBookmark = false;
}
},
updateCurrentBookmark: function pdfHistoryUpdateCurrentBookmark(bookmark, pageNum) {
if (this.initialized) {
this.currentBookmark = bookmark.substring(1);
this.currentPage = pageNum | 0;
this._updatePreviousBookmark();
}
},
updateNextHashParam: function pdfHistoryUpdateNextHashParam(param) {
if (this.initialized) {
this.nextHashParam = param;
}
},
push: function pdfHistoryPush(params, isInitialBookmark) {
if (!(this.initialized && this.historyUnlocked)) {
return;
}
if (params.dest && !params.hash) {
params.hash = this.current.hash && this.current.dest && this.current.dest === params.dest ? this.current.hash : this.linkService.getDestinationHash(params.dest).split('#')[1];
}
if (params.page) {
params.page |= 0;
}
if (isInitialBookmark) {
var target = window.history.state.target;
if (!target) {
this._pushToHistory(params, false);
this.previousHash = window.location.hash.substring(1);
}
this.updatePreviousBookmark = this.nextHashParam ? false : true;
if (target) {
this._updatePreviousBookmark();
}
return;
}
if (this.nextHashParam) {
if (this.nextHashParam === params.hash) {
this.nextHashParam = null;
this.updatePreviousBookmark = true;
return;
}
this.nextHashParam = null;
}
if (params.hash) {
if (this.current.hash) {
if (this.current.hash !== params.hash) {
this._pushToHistory(params, true);
} else {
if (!this.current.page && params.page) {
this._pushToHistory(params, false, true);
}
this.updatePreviousBookmark = true;
}
} else {
this._pushToHistory(params, true);
}
} else if (this.current.page && params.page && this.current.page !== params.page) {
this._pushToHistory(params, true);
}
},
_getPreviousParams: function pdfHistory_getPreviousParams(onlyCheckPage, beforeUnload) {
if (!(this.currentBookmark && this.currentPage)) {
return null;
} else if (this.updatePreviousBookmark) {
this.updatePreviousBookmark = false;
}
if (this.uid > 0 && !(this.previousBookmark && this.previousPage)) {
return null;
}
if (!this.current.dest && !onlyCheckPage || beforeUnload) {
if (this.previousBookmark === this.currentBookmark) {
return null;
}
} else if (this.current.page || onlyCheckPage) {
if (this.previousPage === this.currentPage) {
return null;
}
} else {
return null;
}
var params = {
hash: this.currentBookmark,
page: this.currentPage
};
if (this.isViewerInPresentationMode) {
params.hash = null;
}
return params;
},
_stateObj: function pdfHistory_stateObj(params) {
return {
fingerprint: this.fingerprint,
uid: this.uid,
target: params
};
},
_pushToHistory: function pdfHistory_pushToHistory(params, addPrevious, overwrite) {
if (!this.initialized) {
return;
}
if (!params.hash && params.page) {
params.hash = 'page=' + params.page;
}
if (addPrevious && !overwrite) {
var previousParams = this._getPreviousParams();
if (previousParams) {
var replacePrevious = !this.current.dest && this.current.hash !== this.previousHash;
this._pushToHistory(previousParams, false, replacePrevious);
}
}
this._pushOrReplaceState(this._stateObj(params), overwrite || this.uid === 0);
this.currentUid = this.uid++;
this.current = params;
this.updatePreviousBookmark = true;
},
_goTo: function pdfHistory_goTo(state) {
if (!(this.initialized && this.historyUnlocked && this._isStateObjectDefined(state))) {
return;
}
if (!this.reInitialized && state.uid < this.currentUid) {
var previousParams = this._getPreviousParams(true);
if (previousParams) {
this._pushToHistory(this.current, false);
this._pushToHistory(previousParams, false);
this.currentUid = state.uid;
window.history.back();
return;
}
}
this.historyUnlocked = false;
if (state.target.dest) {
this.linkService.navigateTo(state.target.dest);
} else {
this.linkService.setHash(state.target.hash);
}
this.currentUid = state.uid;
if (state.uid > this.uid) {
this.uid = state.uid;
}
this.current = state.target;
this.updatePreviousBookmark = true;
var currentHash = window.location.hash.substring(1);
if (this.previousHash !== currentHash) {
this.allowHashChange = false;
}
this.previousHash = currentHash;
this.historyUnlocked = true;
},
back: function pdfHistoryBack() {
this.go(-1);
},
forward: function pdfHistoryForward() {
this.go(1);
},
go: function pdfHistoryGo(direction) {
if (this.initialized && this.historyUnlocked) {
var state = window.history.state;
if (direction === -1 && state && state.uid > 0) {
window.history.back();
} else if (direction === 1 && state && state.uid < this.uid - 1) {
window.history.forward();
}
}
}
};
exports.PDFHistory = PDFHistory;