| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612 | /** * @licstart The following is the entire license notice for the * Javascript code in this page * * Copyright 2019 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. * * @licend The above is the entire license notice for the * Javascript code in this page */"use strict";Object.defineProperty(exports, "__esModule", {  value: true});exports.isDestHashesEqual = isDestHashesEqual;exports.isDestArraysEqual = isDestArraysEqual;exports.PDFHistory = void 0;var _ui_utils = require("./ui_utils");function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a 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); } }function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }var HASH_CHANGE_TIMEOUT = 1000;var POSITION_UPDATED_THRESHOLD = 50;var UPDATE_VIEWAREA_TIMEOUT = 1000;function getCurrentHash() {  return document.location.hash;}function parseCurrentHash(linkService) {  var hash = unescape(getCurrentHash()).substring(1);  var params = (0, _ui_utils.parseQueryString)(hash);  var page = params.page | 0;  if (!(Number.isInteger(page) && page > 0 && page <= linkService.pagesCount)) {    page = null;  }  return {    hash: hash,    page: page,    rotation: linkService.rotation  };}var PDFHistory =/*#__PURE__*/function () {  function PDFHistory(_ref) {    var _this = this;    var linkService = _ref.linkService,        eventBus = _ref.eventBus;    _classCallCheck(this, PDFHistory);    this.linkService = linkService;    this.eventBus = eventBus || (0, _ui_utils.getGlobalEventBus)();    this.initialized = false;    this.initialBookmark = null;    this.initialRotation = null;    this._boundEvents = Object.create(null);    this._isViewerInPresentationMode = false;    this._isPagesLoaded = false;    this.eventBus.on('presentationmodechanged', function (evt) {      _this._isViewerInPresentationMode = evt.active || evt.switchInProgress;    });    this.eventBus.on('pagesloaded', function (evt) {      _this._isPagesLoaded = !!evt.pagesCount;    });  }  _createClass(PDFHistory, [{    key: "initialize",    value: function initialize(_ref2) {      var fingerprint = _ref2.fingerprint,          _ref2$resetHistory = _ref2.resetHistory,          resetHistory = _ref2$resetHistory === void 0 ? false : _ref2$resetHistory,          _ref2$updateUrl = _ref2.updateUrl,          updateUrl = _ref2$updateUrl === void 0 ? false : _ref2$updateUrl;      if (!fingerprint || typeof fingerprint !== 'string') {        console.error('PDFHistory.initialize: The "fingerprint" must be a non-empty string.');        return;      }      var reInitialized = this.initialized && this.fingerprint !== fingerprint;      this.fingerprint = fingerprint;      this._updateUrl = updateUrl === true;      if (!this.initialized) {        this._bindEvents();      }      var state = window.history.state;      this.initialized = true;      this.initialBookmark = null;      this.initialRotation = null;      this._popStateInProgress = false;      this._blockHashChange = 0;      this._currentHash = getCurrentHash();      this._numPositionUpdates = 0;      this._uid = this._maxUid = 0;      this._destination = null;      this._position = null;      if (!this._isValidState(state, true) || resetHistory) {        var _parseCurrentHash = parseCurrentHash(this.linkService),            hash = _parseCurrentHash.hash,            page = _parseCurrentHash.page,            rotation = _parseCurrentHash.rotation;        if (!hash || reInitialized || resetHistory) {          this._pushOrReplaceState(null, true);          return;        }        this._pushOrReplaceState({          hash: hash,          page: page,          rotation: rotation        }, true);        return;      }      var destination = state.destination;      this._updateInternalState(destination, state.uid, true);      if (this._uid > this._maxUid) {        this._maxUid = this._uid;      }      if (destination.rotation !== undefined) {        this.initialRotation = destination.rotation;      }      if (destination.dest) {        this.initialBookmark = JSON.stringify(destination.dest);        this._destination.page = null;      } else if (destination.hash) {        this.initialBookmark = destination.hash;      } else if (destination.page) {        this.initialBookmark = "page=".concat(destination.page);      }    }  }, {    key: "push",    value: function push(_ref3) {      var _this2 = this;      var _ref3$namedDest = _ref3.namedDest,          namedDest = _ref3$namedDest === void 0 ? null : _ref3$namedDest,          explicitDest = _ref3.explicitDest,          pageNumber = _ref3.pageNumber;      if (!this.initialized) {        return;      }      if (namedDest && typeof namedDest !== 'string') {        console.error('PDFHistory.push: ' + "\"".concat(namedDest, "\" is not a valid namedDest parameter."));        return;      } else if (!Array.isArray(explicitDest)) {        console.error('PDFHistory.push: ' + "\"".concat(explicitDest, "\" is not a valid explicitDest parameter."));        return;      } else if (!(Number.isInteger(pageNumber) && pageNumber > 0 && pageNumber <= this.linkService.pagesCount)) {        if (pageNumber !== null || this._destination) {          console.error('PDFHistory.push: ' + "\"".concat(pageNumber, "\" is not a valid pageNumber parameter."));          return;        }      }      var hash = namedDest || JSON.stringify(explicitDest);      if (!hash) {        return;      }      var forceReplace = false;      if (this._destination && (isDestHashesEqual(this._destination.hash, hash) || isDestArraysEqual(this._destination.dest, explicitDest))) {        if (this._destination.page) {          return;        }        forceReplace = true;      }      if (this._popStateInProgress && !forceReplace) {        return;      }      this._pushOrReplaceState({        dest: explicitDest,        hash: hash,        page: pageNumber,        rotation: this.linkService.rotation      }, forceReplace);      if (!this._popStateInProgress) {        this._popStateInProgress = true;        Promise.resolve().then(function () {          _this2._popStateInProgress = false;        });      }    }  }, {    key: "pushCurrentPosition",    value: function pushCurrentPosition() {      if (!this.initialized || this._popStateInProgress) {        return;      }      this._tryPushCurrentPosition();    }  }, {    key: "back",    value: function back() {      if (!this.initialized || this._popStateInProgress) {        return;      }      var state = window.history.state;      if (this._isValidState(state) && state.uid > 0) {        window.history.back();      }    }  }, {    key: "forward",    value: function forward() {      if (!this.initialized || this._popStateInProgress) {        return;      }      var state = window.history.state;      if (this._isValidState(state) && state.uid < this._maxUid) {        window.history.forward();      }    }  }, {    key: "_pushOrReplaceState",    value: function _pushOrReplaceState(destination) {      var forceReplace = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;      var shouldReplace = forceReplace || !this._destination;      var newState = {        fingerprint: this.fingerprint,        uid: shouldReplace ? this._uid : this._uid + 1,        destination: destination      };      this._updateInternalState(destination, newState.uid);      var newUrl;      if (this._updateUrl && destination && destination.hash) {        var baseUrl = document.location.href.split('#')[0];        if (!baseUrl.startsWith('file://')) {          newUrl = "".concat(baseUrl, "#").concat(destination.hash);        }      }      if (shouldReplace) {        if (newUrl) {          window.history.replaceState(newState, '', newUrl);        } else {          window.history.replaceState(newState, '');        }      } else {        this._maxUid = this._uid;        if (newUrl) {          window.history.pushState(newState, '', newUrl);        } else {          window.history.pushState(newState, '');        }      }    }  }, {    key: "_tryPushCurrentPosition",    value: function _tryPushCurrentPosition() {      var temporary = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;      if (!this._position) {        return;      }      var position = this._position;      if (temporary) {        position = Object.assign(Object.create(null), this._position);        position.temporary = true;      }      if (!this._destination) {        this._pushOrReplaceState(position);        return;      }      if (this._destination.temporary) {        this._pushOrReplaceState(position, true);        return;      }      if (this._destination.hash === position.hash) {        return;      }      if (!this._destination.page && (POSITION_UPDATED_THRESHOLD <= 0 || this._numPositionUpdates <= POSITION_UPDATED_THRESHOLD)) {        return;      }      var forceReplace = false;      if (this._destination.page >= position.first && this._destination.page <= position.page) {        if (this._destination.dest || !this._destination.first) {          return;        }        forceReplace = true;      }      this._pushOrReplaceState(position, forceReplace);    }  }, {    key: "_isValidState",    value: function _isValidState(state) {      var checkReload = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;      if (!state) {        return false;      }      if (state.fingerprint !== this.fingerprint) {        if (checkReload) {          if (typeof state.fingerprint !== 'string' || state.fingerprint.length !== this.fingerprint.length) {            return false;          }          var _performance$getEntri = performance.getEntriesByType('navigation'),              _performance$getEntri2 = _slicedToArray(_performance$getEntri, 1),              perfEntry = _performance$getEntri2[0];          if (!perfEntry || perfEntry.type !== 'reload') {            return false;          }        } else {          return false;        }      }      if (!Number.isInteger(state.uid) || state.uid < 0) {        return false;      }      if (state.destination === null || _typeof(state.destination) !== 'object') {        return false;      }      return true;    }  }, {    key: "_updateInternalState",    value: function _updateInternalState(destination, uid) {      var removeTemporary = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;      if (this._updateViewareaTimeout) {        clearTimeout(this._updateViewareaTimeout);        this._updateViewareaTimeout = null;      }      if (removeTemporary && destination && destination.temporary) {        delete destination.temporary;      }      this._destination = destination;      this._uid = uid;      this._numPositionUpdates = 0;    }  }, {    key: "_updateViewarea",    value: function _updateViewarea(_ref4) {      var _this3 = this;      var location = _ref4.location;      if (this._updateViewareaTimeout) {        clearTimeout(this._updateViewareaTimeout);        this._updateViewareaTimeout = null;      }      this._position = {        hash: this._isViewerInPresentationMode ? "page=".concat(location.pageNumber) : location.pdfOpenParams.substring(1),        page: this.linkService.page,        first: location.pageNumber,        rotation: location.rotation      };      if (this._popStateInProgress) {        return;      }      if (POSITION_UPDATED_THRESHOLD > 0 && this._isPagesLoaded && this._destination && !this._destination.page) {        this._numPositionUpdates++;      }      if (UPDATE_VIEWAREA_TIMEOUT > 0) {        this._updateViewareaTimeout = setTimeout(function () {          if (!_this3._popStateInProgress) {            _this3._tryPushCurrentPosition(true);          }          _this3._updateViewareaTimeout = null;        }, UPDATE_VIEWAREA_TIMEOUT);      }    }  }, {    key: "_popState",    value: function _popState(_ref5) {      var _this4 = this;      var state = _ref5.state;      var newHash = getCurrentHash(),          hashChanged = this._currentHash !== newHash;      this._currentHash = newHash;      if (!state || false) {        this._uid++;        var _parseCurrentHash2 = parseCurrentHash(this.linkService),            hash = _parseCurrentHash2.hash,            page = _parseCurrentHash2.page,            rotation = _parseCurrentHash2.rotation;        this._pushOrReplaceState({          hash: hash,          page: page,          rotation: rotation        }, true);        return;      }      if (!this._isValidState(state)) {        return;      }      this._popStateInProgress = true;      if (hashChanged) {        this._blockHashChange++;        (0, _ui_utils.waitOnEventOrTimeout)({          target: window,          name: 'hashchange',          delay: HASH_CHANGE_TIMEOUT        }).then(function () {          _this4._blockHashChange--;        });      }      var destination = state.destination;      this._updateInternalState(destination, state.uid, true);      if (this._uid > this._maxUid) {        this._maxUid = this._uid;      }      if ((0, _ui_utils.isValidRotation)(destination.rotation)) {        this.linkService.rotation = destination.rotation;      }      if (destination.dest) {        this.linkService.navigateTo(destination.dest);      } else if (destination.hash) {        this.linkService.setHash(destination.hash);      } else if (destination.page) {        this.linkService.page = destination.page;      }      Promise.resolve().then(function () {        _this4._popStateInProgress = false;      });    }  }, {    key: "_bindEvents",    value: function _bindEvents() {      var _this5 = this;      var _boundEvents = this._boundEvents,          eventBus = this.eventBus;      _boundEvents.updateViewarea = this._updateViewarea.bind(this);      _boundEvents.popState = this._popState.bind(this);      _boundEvents.pageHide = function (evt) {        if (!_this5._destination || _this5._destination.temporary) {          _this5._tryPushCurrentPosition();        }      };      eventBus.on('updateviewarea', _boundEvents.updateViewarea);      window.addEventListener('popstate', _boundEvents.popState);      window.addEventListener('pagehide', _boundEvents.pageHide);    }  }, {    key: "popStateInProgress",    get: function get() {      return this.initialized && (this._popStateInProgress || this._blockHashChange > 0);    }  }]);  return PDFHistory;}();exports.PDFHistory = PDFHistory;function isDestHashesEqual(destHash, pushHash) {  if (typeof destHash !== 'string' || typeof pushHash !== 'string') {    return false;  }  if (destHash === pushHash) {    return true;  }  var _parseQueryString = (0, _ui_utils.parseQueryString)(destHash),      nameddest = _parseQueryString.nameddest;  if (nameddest === pushHash) {    return true;  }  return false;}function isDestArraysEqual(firstDest, secondDest) {  function isEntryEqual(first, second) {    if (_typeof(first) !== _typeof(second)) {      return false;    }    if (Array.isArray(first) || Array.isArray(second)) {      return false;    }    if (first !== null && _typeof(first) === 'object' && second !== null) {      if (Object.keys(first).length !== Object.keys(second).length) {        return false;      }      for (var key in first) {        if (!isEntryEqual(first[key], second[key])) {          return false;        }      }      return true;    }    return first === second || Number.isNaN(first) && Number.isNaN(second);  }  if (!(Array.isArray(firstDest) && Array.isArray(secondDest))) {    return false;  }  if (firstDest.length !== secondDest.length) {    return false;  }  for (var i = 0, ii = firstDest.length; i < ii; i++) {    if (!isEntryEqual(firstDest[i], secondDest[i])) {      return false;    }  }  return true;}
 |