1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 | 'use strict';
|
23 |
|
24 | Object.defineProperty(exports, "__esModule", {
|
25 | value: true
|
26 | });
|
27 | exports.isDestArraysEqual = exports.isDestHashesEqual = exports.PDFHistory = undefined;
|
28 |
|
29 | var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
30 |
|
31 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
32 |
|
33 | var _ui_utils = require('./ui_utils');
|
34 |
|
35 | var _dom_events = require('./dom_events');
|
36 |
|
37 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
38 |
|
39 | var HASH_CHANGE_TIMEOUT = 1000;
|
40 | var POSITION_UPDATED_THRESHOLD = 50;
|
41 | var UPDATE_VIEWAREA_TIMEOUT = 1000;
|
42 | function getCurrentHash() {
|
43 | return document.location.hash;
|
44 | }
|
45 | function parseCurrentHash(linkService) {
|
46 | var hash = unescape(getCurrentHash()).substring(1);
|
47 | var params = (0, _ui_utils.parseQueryString)(hash);
|
48 | var page = params.page | 0;
|
49 | if (!(Number.isInteger(page) && page > 0 && page <= linkService.pagesCount)) {
|
50 | page = null;
|
51 | }
|
52 | return {
|
53 | hash: hash,
|
54 | page: page,
|
55 | rotation: linkService.rotation
|
56 | };
|
57 | }
|
58 |
|
59 | var PDFHistory = function () {
|
60 | function PDFHistory(_ref) {
|
61 | var _this = this;
|
62 |
|
63 | var linkService = _ref.linkService,
|
64 | eventBus = _ref.eventBus;
|
65 |
|
66 | _classCallCheck(this, PDFHistory);
|
67 |
|
68 | this.linkService = linkService;
|
69 | this.eventBus = eventBus || (0, _dom_events.getGlobalEventBus)();
|
70 | this.initialized = false;
|
71 | this.initialBookmark = null;
|
72 | this.initialRotation = null;
|
73 | this._boundEvents = Object.create(null);
|
74 | this._isViewerInPresentationMode = false;
|
75 | this._isPagesLoaded = false;
|
76 | this.eventBus.on('presentationmodechanged', function (evt) {
|
77 | _this._isViewerInPresentationMode = evt.active || evt.switchInProgress;
|
78 | });
|
79 | this.eventBus.on('pagesloaded', function (evt) {
|
80 | _this._isPagesLoaded = !!evt.pagesCount;
|
81 | });
|
82 | }
|
83 |
|
84 | _createClass(PDFHistory, [{
|
85 | key: 'initialize',
|
86 | value: function initialize(fingerprint) {
|
87 | var resetHistory = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
88 |
|
89 | if (!fingerprint || typeof fingerprint !== 'string') {
|
90 | console.error('PDFHistory.initialize: The "fingerprint" must be a non-empty string.');
|
91 | return;
|
92 | }
|
93 | var reInitialized = this.initialized && this.fingerprint !== fingerprint;
|
94 | this.fingerprint = fingerprint;
|
95 | if (!this.initialized) {
|
96 | this._bindEvents();
|
97 | }
|
98 | var state = window.history.state;
|
99 | this.initialized = true;
|
100 | this.initialBookmark = null;
|
101 | this.initialRotation = null;
|
102 | this._popStateInProgress = false;
|
103 | this._blockHashChange = 0;
|
104 | this._currentHash = getCurrentHash();
|
105 | this._numPositionUpdates = 0;
|
106 | this._uid = this._maxUid = 0;
|
107 | this._destination = null;
|
108 | this._position = null;
|
109 | if (!this._isValidState(state) || resetHistory) {
|
110 | var _parseCurrentHash = parseCurrentHash(this.linkService),
|
111 | hash = _parseCurrentHash.hash,
|
112 | page = _parseCurrentHash.page,
|
113 | rotation = _parseCurrentHash.rotation;
|
114 |
|
115 | if (!hash || reInitialized || resetHistory) {
|
116 | this._pushOrReplaceState(null, true);
|
117 | return;
|
118 | }
|
119 | this._pushOrReplaceState({
|
120 | hash: hash,
|
121 | page: page,
|
122 | rotation: rotation
|
123 | }, true);
|
124 | return;
|
125 | }
|
126 | var destination = state.destination;
|
127 | this._updateInternalState(destination, state.uid, true);
|
128 | if (this._uid > this._maxUid) {
|
129 | this._maxUid = this._uid;
|
130 | }
|
131 | if (destination.rotation !== undefined) {
|
132 | this.initialRotation = destination.rotation;
|
133 | }
|
134 | if (destination.dest) {
|
135 | this.initialBookmark = JSON.stringify(destination.dest);
|
136 | this._destination.page = null;
|
137 | } else if (destination.hash) {
|
138 | this.initialBookmark = destination.hash;
|
139 | } else if (destination.page) {
|
140 | this.initialBookmark = 'page=' + destination.page;
|
141 | }
|
142 | }
|
143 | }, {
|
144 | key: 'push',
|
145 | value: function push(_ref2) {
|
146 | var _this2 = this;
|
147 |
|
148 | var namedDest = _ref2.namedDest,
|
149 | explicitDest = _ref2.explicitDest,
|
150 | pageNumber = _ref2.pageNumber;
|
151 |
|
152 | if (!this.initialized) {
|
153 | return;
|
154 | }
|
155 | if (namedDest && typeof namedDest !== 'string' || !(explicitDest instanceof Array) || !(Number.isInteger(pageNumber) && pageNumber > 0 && pageNumber <= this.linkService.pagesCount)) {
|
156 | console.error('PDFHistory.push: Invalid parameters.');
|
157 | return;
|
158 | }
|
159 | var hash = namedDest || JSON.stringify(explicitDest);
|
160 | if (!hash) {
|
161 | return;
|
162 | }
|
163 | var forceReplace = false;
|
164 | if (this._destination && (isDestHashesEqual(this._destination.hash, hash) || isDestArraysEqual(this._destination.dest, explicitDest))) {
|
165 | if (this._destination.page) {
|
166 | return;
|
167 | }
|
168 | forceReplace = true;
|
169 | }
|
170 | if (this._popStateInProgress && !forceReplace) {
|
171 | return;
|
172 | }
|
173 | this._pushOrReplaceState({
|
174 | dest: explicitDest,
|
175 | hash: hash,
|
176 | page: pageNumber,
|
177 | rotation: this.linkService.rotation
|
178 | }, forceReplace);
|
179 | if (!this._popStateInProgress) {
|
180 | this._popStateInProgress = true;
|
181 | Promise.resolve().then(function () {
|
182 | _this2._popStateInProgress = false;
|
183 | });
|
184 | }
|
185 | }
|
186 | }, {
|
187 | key: 'pushCurrentPosition',
|
188 | value: function pushCurrentPosition() {
|
189 | if (!this.initialized || this._popStateInProgress) {
|
190 | return;
|
191 | }
|
192 | this._tryPushCurrentPosition();
|
193 | }
|
194 | }, {
|
195 | key: 'back',
|
196 | value: function back() {
|
197 | if (!this.initialized || this._popStateInProgress) {
|
198 | return;
|
199 | }
|
200 | var state = window.history.state;
|
201 | if (this._isValidState(state) && state.uid > 0) {
|
202 | window.history.back();
|
203 | }
|
204 | }
|
205 | }, {
|
206 | key: 'forward',
|
207 | value: function forward() {
|
208 | if (!this.initialized || this._popStateInProgress) {
|
209 | return;
|
210 | }
|
211 | var state = window.history.state;
|
212 | if (this._isValidState(state) && state.uid < this._maxUid) {
|
213 | window.history.forward();
|
214 | }
|
215 | }
|
216 | }, {
|
217 | key: '_pushOrReplaceState',
|
218 | value: function _pushOrReplaceState(destination) {
|
219 | var forceReplace = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
220 |
|
221 | var shouldReplace = forceReplace || !this._destination;
|
222 | var newState = {
|
223 | fingerprint: this.fingerprint,
|
224 | uid: shouldReplace ? this._uid : this._uid + 1,
|
225 | destination: destination
|
226 | };
|
227 | this._updateInternalState(destination, newState.uid);
|
228 | if (shouldReplace) {
|
229 | window.history.replaceState(newState, '');
|
230 | } else {
|
231 | this._maxUid = this._uid;
|
232 | window.history.pushState(newState, '');
|
233 | }
|
234 | }
|
235 | }, {
|
236 | key: '_tryPushCurrentPosition',
|
237 | value: function _tryPushCurrentPosition() {
|
238 | var temporary = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
239 |
|
240 | if (!this._position) {
|
241 | return;
|
242 | }
|
243 | var position = this._position;
|
244 | if (temporary) {
|
245 | position = (0, _ui_utils.cloneObj)(this._position);
|
246 | position.temporary = true;
|
247 | }
|
248 | if (!this._destination) {
|
249 | this._pushOrReplaceState(position);
|
250 | return;
|
251 | }
|
252 | if (this._destination.temporary) {
|
253 | this._pushOrReplaceState(position, true);
|
254 | return;
|
255 | }
|
256 | if (this._destination.hash === position.hash) {
|
257 | return;
|
258 | }
|
259 | if (!this._destination.page && (POSITION_UPDATED_THRESHOLD <= 0 || this._numPositionUpdates <= POSITION_UPDATED_THRESHOLD)) {
|
260 | return;
|
261 | }
|
262 | var forceReplace = false;
|
263 | if (this._destination.page === position.first || this._destination.page === position.page) {
|
264 | if (this._destination.dest || !this._destination.first) {
|
265 | return;
|
266 | }
|
267 | forceReplace = true;
|
268 | }
|
269 | this._pushOrReplaceState(position, forceReplace);
|
270 | }
|
271 | }, {
|
272 | key: '_isValidState',
|
273 | value: function _isValidState(state) {
|
274 | if (!state) {
|
275 | return false;
|
276 | }
|
277 | if (state.fingerprint !== this.fingerprint) {
|
278 | return false;
|
279 | }
|
280 | if (!Number.isInteger(state.uid) || state.uid < 0) {
|
281 | return false;
|
282 | }
|
283 | if (state.destination === null || _typeof(state.destination) !== 'object') {
|
284 | return false;
|
285 | }
|
286 | return true;
|
287 | }
|
288 | }, {
|
289 | key: '_updateInternalState',
|
290 | value: function _updateInternalState(destination, uid) {
|
291 | var removeTemporary = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
292 |
|
293 | if (this._updateViewareaTimeout) {
|
294 | clearTimeout(this._updateViewareaTimeout);
|
295 | this._updateViewareaTimeout = null;
|
296 | }
|
297 | if (removeTemporary && destination && destination.temporary) {
|
298 | delete destination.temporary;
|
299 | }
|
300 | this._destination = destination;
|
301 | this._uid = uid;
|
302 | this._numPositionUpdates = 0;
|
303 | }
|
304 | }, {
|
305 | key: '_updateViewarea',
|
306 | value: function _updateViewarea(_ref3) {
|
307 | var _this3 = this;
|
308 |
|
309 | var location = _ref3.location;
|
310 |
|
311 | if (this._updateViewareaTimeout) {
|
312 | clearTimeout(this._updateViewareaTimeout);
|
313 | this._updateViewareaTimeout = null;
|
314 | }
|
315 | this._position = {
|
316 | hash: this._isViewerInPresentationMode ? 'page=' + location.pageNumber : location.pdfOpenParams.substring(1),
|
317 | page: this.linkService.page,
|
318 | first: location.pageNumber,
|
319 | rotation: location.rotation
|
320 | };
|
321 | if (this._popStateInProgress) {
|
322 | return;
|
323 | }
|
324 | if (POSITION_UPDATED_THRESHOLD > 0 && this._isPagesLoaded && this._destination && !this._destination.page) {
|
325 | this._numPositionUpdates++;
|
326 | }
|
327 | if (UPDATE_VIEWAREA_TIMEOUT > 0) {
|
328 | this._updateViewareaTimeout = setTimeout(function () {
|
329 | if (!_this3._popStateInProgress) {
|
330 | _this3._tryPushCurrentPosition(true);
|
331 | }
|
332 | _this3._updateViewareaTimeout = null;
|
333 | }, UPDATE_VIEWAREA_TIMEOUT);
|
334 | }
|
335 | }
|
336 | }, {
|
337 | key: '_popState',
|
338 | value: function _popState(_ref4) {
|
339 | var _this4 = this;
|
340 |
|
341 | var state = _ref4.state;
|
342 |
|
343 | var newHash = getCurrentHash(),
|
344 | hashChanged = this._currentHash !== newHash;
|
345 | this._currentHash = newHash;
|
346 | if (!state || false) {
|
347 | this._uid++;
|
348 |
|
349 | var _parseCurrentHash2 = parseCurrentHash(this.linkService),
|
350 | hash = _parseCurrentHash2.hash,
|
351 | page = _parseCurrentHash2.page,
|
352 | rotation = _parseCurrentHash2.rotation;
|
353 |
|
354 | this._pushOrReplaceState({
|
355 | hash: hash,
|
356 | page: page,
|
357 | rotation: rotation
|
358 | }, true);
|
359 | return;
|
360 | }
|
361 | if (!this._isValidState(state)) {
|
362 | return;
|
363 | }
|
364 | this._popStateInProgress = true;
|
365 | if (hashChanged) {
|
366 | this._blockHashChange++;
|
367 | (0, _ui_utils.waitOnEventOrTimeout)({
|
368 | target: window,
|
369 | name: 'hashchange',
|
370 | delay: HASH_CHANGE_TIMEOUT
|
371 | }).then(function () {
|
372 | _this4._blockHashChange--;
|
373 | });
|
374 | }
|
375 | var destination = state.destination;
|
376 | this._updateInternalState(destination, state.uid, true);
|
377 | if (this._uid > this._maxUid) {
|
378 | this._maxUid = this._uid;
|
379 | }
|
380 | if ((0, _ui_utils.isValidRotation)(destination.rotation)) {
|
381 | this.linkService.rotation = destination.rotation;
|
382 | }
|
383 | if (destination.dest) {
|
384 | this.linkService.navigateTo(destination.dest);
|
385 | } else if (destination.hash) {
|
386 | this.linkService.setHash(destination.hash);
|
387 | } else if (destination.page) {
|
388 | this.linkService.page = destination.page;
|
389 | }
|
390 | Promise.resolve().then(function () {
|
391 | _this4._popStateInProgress = false;
|
392 | });
|
393 | }
|
394 | }, {
|
395 | key: '_bindEvents',
|
396 | value: function _bindEvents() {
|
397 | var _this5 = this;
|
398 |
|
399 | var _boundEvents = this._boundEvents,
|
400 | eventBus = this.eventBus;
|
401 |
|
402 | _boundEvents.updateViewarea = this._updateViewarea.bind(this);
|
403 | _boundEvents.popState = this._popState.bind(this);
|
404 | _boundEvents.pageHide = function (evt) {
|
405 | if (!_this5._destination || _this5._destination.temporary) {
|
406 | _this5._tryPushCurrentPosition();
|
407 | }
|
408 | };
|
409 | eventBus.on('updateviewarea', _boundEvents.updateViewarea);
|
410 | window.addEventListener('popstate', _boundEvents.popState);
|
411 | window.addEventListener('pagehide', _boundEvents.pageHide);
|
412 | }
|
413 | }, {
|
414 | key: 'popStateInProgress',
|
415 | get: function get() {
|
416 | return this.initialized && (this._popStateInProgress || this._blockHashChange > 0);
|
417 | }
|
418 | }]);
|
419 |
|
420 | return PDFHistory;
|
421 | }();
|
422 |
|
423 | function isDestHashesEqual(destHash, pushHash) {
|
424 | if (typeof destHash !== 'string' || typeof pushHash !== 'string') {
|
425 | return false;
|
426 | }
|
427 | if (destHash === pushHash) {
|
428 | return true;
|
429 | }
|
430 |
|
431 | var _parseQueryString = (0, _ui_utils.parseQueryString)(destHash),
|
432 | nameddest = _parseQueryString.nameddest;
|
433 |
|
434 | if (nameddest === pushHash) {
|
435 | return true;
|
436 | }
|
437 | return false;
|
438 | }
|
439 | function isDestArraysEqual(firstDest, secondDest) {
|
440 | function isEntryEqual(first, second) {
|
441 | if ((typeof first === 'undefined' ? 'undefined' : _typeof(first)) !== (typeof second === 'undefined' ? 'undefined' : _typeof(second))) {
|
442 | return false;
|
443 | }
|
444 | if (first instanceof Array || second instanceof Array) {
|
445 | return false;
|
446 | }
|
447 | if (first !== null && (typeof first === 'undefined' ? 'undefined' : _typeof(first)) === 'object' && second !== null) {
|
448 | if (Object.keys(first).length !== Object.keys(second).length) {
|
449 | return false;
|
450 | }
|
451 | for (var key in first) {
|
452 | if (!isEntryEqual(first[key], second[key])) {
|
453 | return false;
|
454 | }
|
455 | }
|
456 | return true;
|
457 | }
|
458 | return first === second || Number.isNaN(first) && Number.isNaN(second);
|
459 | }
|
460 | if (!(firstDest instanceof Array && secondDest instanceof Array)) {
|
461 | return false;
|
462 | }
|
463 | if (firstDest.length !== secondDest.length) {
|
464 | return false;
|
465 | }
|
466 | for (var i = 0, ii = firstDest.length; i < ii; i++) {
|
467 | if (!isEntryEqual(firstDest[i], secondDest[i])) {
|
468 | return false;
|
469 | }
|
470 | }
|
471 | return true;
|
472 | }
|
473 | exports.PDFHistory = PDFHistory;
|
474 | exports.isDestHashesEqual = isDestHashesEqual;
|
475 | exports.isDestArraysEqual = isDestArraysEqual; |
\ | No newline at end of file |