| /** |
| * @licstart The following is the entire license notice for the |
| * Javascript code in this page |
| * |
| * Copyright 2020 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.BaseViewer = void 0; |
| |
| var _ui_utils = require("./ui_utils.js"); |
| |
| var _pdf_rendering_queue = require("./pdf_rendering_queue.js"); |
| |
| var _annotation_layer_builder = require("./annotation_layer_builder.js"); |
| |
| var _pdf = require("../pdf"); |
| |
| var _pdf_page_view = require("./pdf_page_view.js"); |
| |
| var _pdf_link_service = require("./pdf_link_service.js"); |
| |
| var _text_layer_builder = require("./text_layer_builder.js"); |
| |
| const DEFAULT_CACHE_SIZE = 10; |
| |
| function PDFPageViewBuffer(size) { |
| const data = []; |
| |
| this.push = function (view) { |
| const i = data.indexOf(view); |
| |
| if (i >= 0) { |
| data.splice(i, 1); |
| } |
| |
| data.push(view); |
| |
| if (data.length > size) { |
| data.shift().destroy(); |
| } |
| }; |
| |
| this.resize = function (newSize, pagesToKeep) { |
| size = newSize; |
| |
| if (pagesToKeep) { |
| const pageIdsToKeep = new Set(); |
| |
| for (let i = 0, iMax = pagesToKeep.length; i < iMax; ++i) { |
| pageIdsToKeep.add(pagesToKeep[i].id); |
| } |
| |
| (0, _ui_utils.moveToEndOfArray)(data, function (page) { |
| return pageIdsToKeep.has(page.id); |
| }); |
| } |
| |
| while (data.length > size) { |
| data.shift().destroy(); |
| } |
| }; |
| } |
| |
| function isSameScale(oldScale, newScale) { |
| if (newScale === oldScale) { |
| return true; |
| } |
| |
| if (Math.abs(newScale - oldScale) < 1e-15) { |
| return true; |
| } |
| |
| return false; |
| } |
| |
| class BaseViewer { |
| constructor(options) { |
| if (this.constructor === BaseViewer) { |
| throw new Error("Cannot initialize BaseViewer."); |
| } |
| |
| this._name = this.constructor.name; |
| this.container = options.container; |
| this.viewer = options.viewer || options.container.firstElementChild; |
| |
| if (!(this.container instanceof HTMLDivElement && this.viewer instanceof HTMLDivElement)) { |
| throw new Error("Invalid `container` and/or `viewer` option."); |
| } |
| |
| this.eventBus = options.eventBus; |
| this.linkService = options.linkService || new _pdf_link_service.SimpleLinkService(); |
| this.downloadManager = options.downloadManager || null; |
| this.findController = options.findController || null; |
| this.removePageBorders = options.removePageBorders || false; |
| this.textLayerMode = Number.isInteger(options.textLayerMode) ? options.textLayerMode : _ui_utils.TextLayerMode.ENABLE; |
| this.imageResourcesPath = options.imageResourcesPath || ""; |
| this.renderInteractiveForms = typeof options.renderInteractiveForms === "boolean" ? options.renderInteractiveForms : true; |
| this.enablePrintAutoRotate = options.enablePrintAutoRotate || false; |
| this.renderer = options.renderer || _ui_utils.RendererType.CANVAS; |
| this.enableWebGL = options.enableWebGL || false; |
| this.useOnlyCssZoom = options.useOnlyCssZoom || false; |
| this.maxCanvasPixels = options.maxCanvasPixels; |
| this.l10n = options.l10n || _ui_utils.NullL10n; |
| this.defaultRenderingQueue = !options.renderingQueue; |
| |
| if (this.defaultRenderingQueue) { |
| this.renderingQueue = new _pdf_rendering_queue.PDFRenderingQueue(); |
| this.renderingQueue.setViewer(this); |
| } else { |
| this.renderingQueue = options.renderingQueue; |
| } |
| |
| this.scroll = (0, _ui_utils.watchScroll)(this.container, this._scrollUpdate.bind(this)); |
| this.presentationModeState = _ui_utils.PresentationModeState.UNKNOWN; |
| this._onBeforeDraw = this._onAfterDraw = null; |
| |
| this._resetView(); |
| |
| if (this.removePageBorders) { |
| this.viewer.classList.add("removePageBorders"); |
| } |
| |
| Promise.resolve().then(() => { |
| this.eventBus.dispatch("baseviewerinit", { |
| source: this |
| }); |
| }); |
| } |
| |
| get pagesCount() { |
| return this._pages.length; |
| } |
| |
| getPageView(index) { |
| return this._pages[index]; |
| } |
| |
| get pageViewsReady() { |
| if (!this._pagesCapability.settled) { |
| return false; |
| } |
| |
| return this._pages.every(function (pageView) { |
| return pageView && pageView.pdfPage; |
| }); |
| } |
| |
| get currentPageNumber() { |
| return this._currentPageNumber; |
| } |
| |
| set currentPageNumber(val) { |
| if (!Number.isInteger(val)) { |
| throw new Error("Invalid page number."); |
| } |
| |
| if (!this.pdfDocument) { |
| return; |
| } |
| |
| if (!this._setCurrentPageNumber(val, true)) { |
| console.error(`${this._name}.currentPageNumber: "${val}" is not a valid page.`); |
| } |
| } |
| |
| _setCurrentPageNumber(val, resetCurrentPageView = false) { |
| if (this._currentPageNumber === val) { |
| if (resetCurrentPageView) { |
| this._resetCurrentPageView(); |
| } |
| |
| return true; |
| } |
| |
| if (!(0 < val && val <= this.pagesCount)) { |
| return false; |
| } |
| |
| this._currentPageNumber = val; |
| this.eventBus.dispatch("pagechanging", { |
| source: this, |
| pageNumber: val, |
| pageLabel: this._pageLabels && this._pageLabels[val - 1] |
| }); |
| |
| if (resetCurrentPageView) { |
| this._resetCurrentPageView(); |
| } |
| |
| return true; |
| } |
| |
| get currentPageLabel() { |
| return this._pageLabels && this._pageLabels[this._currentPageNumber - 1]; |
| } |
| |
| set currentPageLabel(val) { |
| if (!this.pdfDocument) { |
| return; |
| } |
| |
| let page = val | 0; |
| |
| if (this._pageLabels) { |
| const i = this._pageLabels.indexOf(val); |
| |
| if (i >= 0) { |
| page = i + 1; |
| } |
| } |
| |
| if (!this._setCurrentPageNumber(page, true)) { |
| console.error(`${this._name}.currentPageLabel: "${val}" is not a valid page.`); |
| } |
| } |
| |
| get currentScale() { |
| return this._currentScale !== _ui_utils.UNKNOWN_SCALE ? this._currentScale : _ui_utils.DEFAULT_SCALE; |
| } |
| |
| set currentScale(val) { |
| if (isNaN(val)) { |
| throw new Error("Invalid numeric scale."); |
| } |
| |
| if (!this.pdfDocument) { |
| return; |
| } |
| |
| this._setScale(val, false); |
| } |
| |
| get currentScaleValue() { |
| return this._currentScaleValue; |
| } |
| |
| set currentScaleValue(val) { |
| if (!this.pdfDocument) { |
| return; |
| } |
| |
| this._setScale(val, false); |
| } |
| |
| get pagesRotation() { |
| return this._pagesRotation; |
| } |
| |
| set pagesRotation(rotation) { |
| if (!(0, _ui_utils.isValidRotation)(rotation)) { |
| throw new Error("Invalid pages rotation angle."); |
| } |
| |
| if (!this.pdfDocument) { |
| return; |
| } |
| |
| if (this._pagesRotation === rotation) { |
| return; |
| } |
| |
| this._pagesRotation = rotation; |
| const pageNumber = this._currentPageNumber; |
| |
| for (let i = 0, ii = this._pages.length; i < ii; i++) { |
| const pageView = this._pages[i]; |
| pageView.update(pageView.scale, rotation); |
| } |
| |
| if (this._currentScaleValue) { |
| this._setScale(this._currentScaleValue, true); |
| } |
| |
| this.eventBus.dispatch("rotationchanging", { |
| source: this, |
| pagesRotation: rotation, |
| pageNumber |
| }); |
| |
| if (this.defaultRenderingQueue) { |
| this.update(); |
| } |
| } |
| |
| get firstPagePromise() { |
| return this.pdfDocument ? this._firstPageCapability.promise : null; |
| } |
| |
| get onePageRendered() { |
| return this.pdfDocument ? this._onePageRenderedCapability.promise : null; |
| } |
| |
| get pagesPromise() { |
| return this.pdfDocument ? this._pagesCapability.promise : null; |
| } |
| |
| get _viewerElement() { |
| throw new Error("Not implemented: _viewerElement"); |
| } |
| |
| _onePageRenderedOrForceFetch() { |
| if (!this.container.offsetParent || this._getVisiblePages().views.length === 0) { |
| return Promise.resolve(); |
| } |
| |
| return this._onePageRenderedCapability.promise; |
| } |
| |
| setDocument(pdfDocument) { |
| if (this.pdfDocument) { |
| this._cancelRendering(); |
| |
| this._resetView(); |
| |
| if (this.findController) { |
| this.findController.setDocument(null); |
| } |
| } |
| |
| this.pdfDocument = pdfDocument; |
| |
| if (!pdfDocument) { |
| return; |
| } |
| |
| const pagesCount = pdfDocument.numPages; |
| const firstPagePromise = pdfDocument.getPage(1); |
| const annotationStorage = pdfDocument.annotationStorage; |
| const optionalContentConfigPromise = pdfDocument.getOptionalContentConfig(); |
| |
| this._pagesCapability.promise.then(() => { |
| this.eventBus.dispatch("pagesloaded", { |
| source: this, |
| pagesCount |
| }); |
| }); |
| |
| this._onBeforeDraw = evt => { |
| const pageView = this._pages[evt.pageNumber - 1]; |
| |
| if (!pageView) { |
| return; |
| } |
| |
| this._buffer.push(pageView); |
| }; |
| |
| this.eventBus._on("pagerender", this._onBeforeDraw); |
| |
| this._onAfterDraw = evt => { |
| if (evt.cssTransform || this._onePageRenderedCapability.settled) { |
| return; |
| } |
| |
| this._onePageRenderedCapability.resolve(); |
| |
| this.eventBus._off("pagerendered", this._onAfterDraw); |
| |
| this._onAfterDraw = null; |
| }; |
| |
| this.eventBus._on("pagerendered", this._onAfterDraw); |
| |
| firstPagePromise.then(firstPdfPage => { |
| this._firstPageCapability.resolve(firstPdfPage); |
| |
| this._optionalContentConfigPromise = optionalContentConfigPromise; |
| const scale = this.currentScale; |
| const viewport = firstPdfPage.getViewport({ |
| scale: scale * _ui_utils.CSS_UNITS |
| }); |
| const textLayerFactory = this.textLayerMode !== _ui_utils.TextLayerMode.DISABLE ? this : null; |
| |
| for (let pageNum = 1; pageNum <= pagesCount; ++pageNum) { |
| const pageView = new _pdf_page_view.PDFPageView({ |
| container: this._viewerElement, |
| eventBus: this.eventBus, |
| id: pageNum, |
| scale, |
| defaultViewport: viewport.clone(), |
| annotationStorage, |
| optionalContentConfigPromise, |
| renderingQueue: this.renderingQueue, |
| textLayerFactory, |
| textLayerMode: this.textLayerMode, |
| annotationLayerFactory: this, |
| imageResourcesPath: this.imageResourcesPath, |
| renderInteractiveForms: this.renderInteractiveForms, |
| renderer: this.renderer, |
| enableWebGL: this.enableWebGL, |
| useOnlyCssZoom: this.useOnlyCssZoom, |
| maxCanvasPixels: this.maxCanvasPixels, |
| l10n: this.l10n |
| }); |
| |
| this._pages.push(pageView); |
| } |
| |
| const firstPageView = this._pages[0]; |
| |
| if (firstPageView) { |
| firstPageView.setPdfPage(firstPdfPage); |
| this.linkService.cachePageRef(1, firstPdfPage.ref); |
| } |
| |
| if (this._spreadMode !== _ui_utils.SpreadMode.NONE) { |
| this._updateSpreadMode(); |
| } |
| |
| this._onePageRenderedOrForceFetch().then(() => { |
| if (this.findController) { |
| this.findController.setDocument(pdfDocument); |
| } |
| |
| if (pdfDocument.loadingParams.disableAutoFetch || pagesCount > 7500) { |
| this._pagesCapability.resolve(); |
| |
| return; |
| } |
| |
| let getPagesLeft = pagesCount - 1; |
| |
| if (getPagesLeft <= 0) { |
| this._pagesCapability.resolve(); |
| |
| return; |
| } |
| |
| for (let pageNum = 2; pageNum <= pagesCount; ++pageNum) { |
| pdfDocument.getPage(pageNum).then(pdfPage => { |
| const pageView = this._pages[pageNum - 1]; |
| |
| if (!pageView.pdfPage) { |
| pageView.setPdfPage(pdfPage); |
| } |
| |
| this.linkService.cachePageRef(pageNum, pdfPage.ref); |
| |
| if (--getPagesLeft === 0) { |
| this._pagesCapability.resolve(); |
| } |
| }, reason => { |
| console.error(`Unable to get page ${pageNum} to initialize viewer`, reason); |
| |
| if (--getPagesLeft === 0) { |
| this._pagesCapability.resolve(); |
| } |
| }); |
| } |
| }); |
| |
| this.eventBus.dispatch("pagesinit", { |
| source: this |
| }); |
| |
| if (this.defaultRenderingQueue) { |
| this.update(); |
| } |
| }).catch(reason => { |
| console.error("Unable to initialize viewer", reason); |
| }); |
| } |
| |
| setPageLabels(labels) { |
| if (!this.pdfDocument) { |
| return; |
| } |
| |
| if (!labels) { |
| this._pageLabels = null; |
| } else if (!(Array.isArray(labels) && this.pdfDocument.numPages === labels.length)) { |
| this._pageLabels = null; |
| console.error(`${this._name}.setPageLabels: Invalid page labels.`); |
| } else { |
| this._pageLabels = labels; |
| } |
| |
| for (let i = 0, ii = this._pages.length; i < ii; i++) { |
| const pageView = this._pages[i]; |
| const label = this._pageLabels && this._pageLabels[i]; |
| pageView.setPageLabel(label); |
| } |
| } |
| |
| _resetView() { |
| this._pages = []; |
| this._currentPageNumber = 1; |
| this._currentScale = _ui_utils.UNKNOWN_SCALE; |
| this._currentScaleValue = null; |
| this._pageLabels = null; |
| this._buffer = new PDFPageViewBuffer(DEFAULT_CACHE_SIZE); |
| this._location = null; |
| this._pagesRotation = 0; |
| this._optionalContentConfigPromise = null; |
| this._pagesRequests = new WeakMap(); |
| this._firstPageCapability = (0, _pdf.createPromiseCapability)(); |
| this._onePageRenderedCapability = (0, _pdf.createPromiseCapability)(); |
| this._pagesCapability = (0, _pdf.createPromiseCapability)(); |
| this._scrollMode = _ui_utils.ScrollMode.VERTICAL; |
| this._spreadMode = _ui_utils.SpreadMode.NONE; |
| |
| if (this._onBeforeDraw) { |
| this.eventBus._off("pagerender", this._onBeforeDraw); |
| |
| this._onBeforeDraw = null; |
| } |
| |
| if (this._onAfterDraw) { |
| this.eventBus._off("pagerendered", this._onAfterDraw); |
| |
| this._onAfterDraw = null; |
| } |
| |
| this.viewer.textContent = ""; |
| |
| this._updateScrollMode(); |
| } |
| |
| _scrollUpdate() { |
| if (this.pagesCount === 0) { |
| return; |
| } |
| |
| this.update(); |
| } |
| |
| _scrollIntoView({ |
| pageDiv, |
| pageSpot = null, |
| pageNumber = null |
| }) { |
| (0, _ui_utils.scrollIntoView)(pageDiv, pageSpot); |
| } |
| |
| _setScaleUpdatePages(newScale, newValue, noScroll = false, preset = false) { |
| this._currentScaleValue = newValue.toString(); |
| |
| if (isSameScale(this._currentScale, newScale)) { |
| if (preset) { |
| this.eventBus.dispatch("scalechanging", { |
| source: this, |
| scale: newScale, |
| presetValue: newValue |
| }); |
| } |
| |
| return; |
| } |
| |
| for (let i = 0, ii = this._pages.length; i < ii; i++) { |
| this._pages[i].update(newScale); |
| } |
| |
| this._currentScale = newScale; |
| |
| if (!noScroll) { |
| let page = this._currentPageNumber, |
| dest; |
| |
| if (this._location && !(this.isInPresentationMode || this.isChangingPresentationMode)) { |
| page = this._location.pageNumber; |
| dest = [null, { |
| name: "XYZ" |
| }, this._location.left, this._location.top, null]; |
| } |
| |
| this.scrollPageIntoView({ |
| pageNumber: page, |
| destArray: dest, |
| allowNegativeOffset: true |
| }); |
| } |
| |
| this.eventBus.dispatch("scalechanging", { |
| source: this, |
| scale: newScale, |
| presetValue: preset ? newValue : undefined |
| }); |
| |
| if (this.defaultRenderingQueue) { |
| this.update(); |
| } |
| } |
| |
| _setScale(value, noScroll = false) { |
| let scale = parseFloat(value); |
| |
| if (scale > 0) { |
| this._setScaleUpdatePages(scale, value, noScroll, false); |
| } else { |
| const currentPage = this._pages[this._currentPageNumber - 1]; |
| |
| if (!currentPage) { |
| return; |
| } |
| |
| const noPadding = this.isInPresentationMode || this.removePageBorders; |
| let hPadding = noPadding ? 0 : _ui_utils.SCROLLBAR_PADDING; |
| let vPadding = noPadding ? 0 : _ui_utils.VERTICAL_PADDING; |
| |
| if (!noPadding && this._isScrollModeHorizontal) { |
| [hPadding, vPadding] = [vPadding, hPadding]; |
| } |
| |
| const pageWidthScale = (this.container.clientWidth - hPadding) / currentPage.width * currentPage.scale; |
| const pageHeightScale = (this.container.clientHeight - vPadding) / currentPage.height * currentPage.scale; |
| |
| switch (value) { |
| case "page-actual": |
| scale = 1; |
| break; |
| |
| case "page-width": |
| scale = pageWidthScale; |
| break; |
| |
| case "page-height": |
| scale = pageHeightScale; |
| break; |
| |
| case "page-fit": |
| scale = Math.min(pageWidthScale, pageHeightScale); |
| break; |
| |
| case "auto": |
| const horizontalScale = (0, _ui_utils.isPortraitOrientation)(currentPage) ? pageWidthScale : Math.min(pageHeightScale, pageWidthScale); |
| scale = Math.min(_ui_utils.MAX_AUTO_SCALE, horizontalScale); |
| break; |
| |
| default: |
| console.error(`${this._name}._setScale: "${value}" is an unknown zoom value.`); |
| return; |
| } |
| |
| this._setScaleUpdatePages(scale, value, noScroll, true); |
| } |
| } |
| |
| _resetCurrentPageView() { |
| if (this.isInPresentationMode) { |
| this._setScale(this._currentScaleValue, true); |
| } |
| |
| const pageView = this._pages[this._currentPageNumber - 1]; |
| |
| this._scrollIntoView({ |
| pageDiv: pageView.div |
| }); |
| } |
| |
| scrollPageIntoView({ |
| pageNumber, |
| destArray = null, |
| allowNegativeOffset = false, |
| ignoreDestinationZoom = false |
| }) { |
| if (!this.pdfDocument) { |
| return; |
| } |
| |
| const pageView = Number.isInteger(pageNumber) && this._pages[pageNumber - 1]; |
| |
| if (!pageView) { |
| console.error(`${this._name}.scrollPageIntoView: ` + `"${pageNumber}" is not a valid pageNumber parameter.`); |
| return; |
| } |
| |
| if (this.isInPresentationMode || !destArray) { |
| this._setCurrentPageNumber(pageNumber, true); |
| |
| return; |
| } |
| |
| let x = 0, |
| y = 0; |
| let width = 0, |
| height = 0, |
| widthScale, |
| heightScale; |
| const changeOrientation = pageView.rotation % 180 !== 0; |
| const pageWidth = (changeOrientation ? pageView.height : pageView.width) / pageView.scale / _ui_utils.CSS_UNITS; |
| const pageHeight = (changeOrientation ? pageView.width : pageView.height) / pageView.scale / _ui_utils.CSS_UNITS; |
| let scale = 0; |
| |
| switch (destArray[1].name) { |
| case "XYZ": |
| x = destArray[2]; |
| y = destArray[3]; |
| scale = destArray[4]; |
| x = x !== null ? x : 0; |
| y = y !== null ? y : pageHeight; |
| break; |
| |
| case "Fit": |
| case "FitB": |
| scale = "page-fit"; |
| break; |
| |
| case "FitH": |
| case "FitBH": |
| y = destArray[2]; |
| scale = "page-width"; |
| |
| if (y === null && this._location) { |
| x = this._location.left; |
| y = this._location.top; |
| } |
| |
| break; |
| |
| case "FitV": |
| case "FitBV": |
| x = destArray[2]; |
| width = pageWidth; |
| height = pageHeight; |
| scale = "page-height"; |
| break; |
| |
| case "FitR": |
| x = destArray[2]; |
| y = destArray[3]; |
| width = destArray[4] - x; |
| height = destArray[5] - y; |
| const hPadding = this.removePageBorders ? 0 : _ui_utils.SCROLLBAR_PADDING; |
| const vPadding = this.removePageBorders ? 0 : _ui_utils.VERTICAL_PADDING; |
| widthScale = (this.container.clientWidth - hPadding) / width / _ui_utils.CSS_UNITS; |
| heightScale = (this.container.clientHeight - vPadding) / height / _ui_utils.CSS_UNITS; |
| scale = Math.min(Math.abs(widthScale), Math.abs(heightScale)); |
| break; |
| |
| default: |
| console.error(`${this._name}.scrollPageIntoView: ` + `"${destArray[1].name}" is not a valid destination type.`); |
| return; |
| } |
| |
| if (!ignoreDestinationZoom) { |
| if (scale && scale !== this._currentScale) { |
| this.currentScaleValue = scale; |
| } else if (this._currentScale === _ui_utils.UNKNOWN_SCALE) { |
| this.currentScaleValue = _ui_utils.DEFAULT_SCALE_VALUE; |
| } |
| } |
| |
| if (scale === "page-fit" && !destArray[4]) { |
| this._scrollIntoView({ |
| pageDiv: pageView.div, |
| pageNumber |
| }); |
| |
| return; |
| } |
| |
| const boundingRect = [pageView.viewport.convertToViewportPoint(x, y), pageView.viewport.convertToViewportPoint(x + width, y + height)]; |
| let left = Math.min(boundingRect[0][0], boundingRect[1][0]); |
| let top = Math.min(boundingRect[0][1], boundingRect[1][1]); |
| |
| if (!allowNegativeOffset) { |
| left = Math.max(left, 0); |
| top = Math.max(top, 0); |
| } |
| |
| this._scrollIntoView({ |
| pageDiv: pageView.div, |
| pageSpot: { |
| left, |
| top |
| }, |
| pageNumber |
| }); |
| } |
| |
| _updateLocation(firstPage) { |
| const currentScale = this._currentScale; |
| const currentScaleValue = this._currentScaleValue; |
| const normalizedScaleValue = parseFloat(currentScaleValue) === currentScale ? Math.round(currentScale * 10000) / 100 : currentScaleValue; |
| const pageNumber = firstPage.id; |
| let pdfOpenParams = "#page=" + pageNumber; |
| pdfOpenParams += "&zoom=" + normalizedScaleValue; |
| const currentPageView = this._pages[pageNumber - 1]; |
| const container = this.container; |
| const topLeft = currentPageView.getPagePoint(container.scrollLeft - firstPage.x, container.scrollTop - firstPage.y); |
| const intLeft = Math.round(topLeft[0]); |
| const intTop = Math.round(topLeft[1]); |
| pdfOpenParams += "," + intLeft + "," + intTop; |
| this._location = { |
| pageNumber, |
| scale: normalizedScaleValue, |
| top: intTop, |
| left: intLeft, |
| rotation: this._pagesRotation, |
| pdfOpenParams |
| }; |
| } |
| |
| _updateHelper(visiblePages) { |
| throw new Error("Not implemented: _updateHelper"); |
| } |
| |
| update() { |
| const visible = this._getVisiblePages(); |
| |
| const visiblePages = visible.views, |
| numVisiblePages = visiblePages.length; |
| |
| if (numVisiblePages === 0) { |
| return; |
| } |
| |
| const newCacheSize = Math.max(DEFAULT_CACHE_SIZE, 2 * numVisiblePages + 1); |
| |
| this._buffer.resize(newCacheSize, visiblePages); |
| |
| this.renderingQueue.renderHighestPriority(visible); |
| |
| this._updateHelper(visiblePages); |
| |
| this._updateLocation(visible.first); |
| |
| this.eventBus.dispatch("updateviewarea", { |
| source: this, |
| location: this._location |
| }); |
| } |
| |
| containsElement(element) { |
| return this.container.contains(element); |
| } |
| |
| focus() { |
| this.container.focus(); |
| } |
| |
| get _isScrollModeHorizontal() { |
| return this.isInPresentationMode ? false : this._scrollMode === _ui_utils.ScrollMode.HORIZONTAL; |
| } |
| |
| get isInPresentationMode() { |
| return this.presentationModeState === _ui_utils.PresentationModeState.FULLSCREEN; |
| } |
| |
| get isChangingPresentationMode() { |
| return this.presentationModeState === _ui_utils.PresentationModeState.CHANGING; |
| } |
| |
| get isHorizontalScrollbarEnabled() { |
| return this.isInPresentationMode ? false : this.container.scrollWidth > this.container.clientWidth; |
| } |
| |
| get isVerticalScrollbarEnabled() { |
| return this.isInPresentationMode ? false : this.container.scrollHeight > this.container.clientHeight; |
| } |
| |
| _getCurrentVisiblePage() { |
| if (!this.pagesCount) { |
| return { |
| views: [] |
| }; |
| } |
| |
| const pageView = this._pages[this._currentPageNumber - 1]; |
| const element = pageView.div; |
| const view = { |
| id: pageView.id, |
| x: element.offsetLeft + element.clientLeft, |
| y: element.offsetTop + element.clientTop, |
| view: pageView |
| }; |
| return { |
| first: view, |
| last: view, |
| views: [view] |
| }; |
| } |
| |
| _getVisiblePages() { |
| return (0, _ui_utils.getVisibleElements)(this.container, this._pages, true, this._isScrollModeHorizontal); |
| } |
| |
| isPageVisible(pageNumber) { |
| if (!this.pdfDocument) { |
| return false; |
| } |
| |
| if (pageNumber < 1 || pageNumber > this.pagesCount) { |
| console.error(`${this._name}.isPageVisible: "${pageNumber}" is out of bounds.`); |
| return false; |
| } |
| |
| return this._getVisiblePages().views.some(function (view) { |
| return view.id === pageNumber; |
| }); |
| } |
| |
| cleanup() { |
| for (let i = 0, ii = this._pages.length; i < ii; i++) { |
| if (this._pages[i] && this._pages[i].renderingState !== _pdf_rendering_queue.RenderingStates.FINISHED) { |
| this._pages[i].reset(); |
| } |
| } |
| } |
| |
| _cancelRendering() { |
| for (let i = 0, ii = this._pages.length; i < ii; i++) { |
| if (this._pages[i]) { |
| this._pages[i].cancelRendering(); |
| } |
| } |
| } |
| |
| _ensurePdfPageLoaded(pageView) { |
| if (pageView.pdfPage) { |
| return Promise.resolve(pageView.pdfPage); |
| } |
| |
| if (this._pagesRequests.has(pageView)) { |
| return this._pagesRequests.get(pageView); |
| } |
| |
| const promise = this.pdfDocument.getPage(pageView.id).then(pdfPage => { |
| if (!pageView.pdfPage) { |
| pageView.setPdfPage(pdfPage); |
| } |
| |
| this._pagesRequests.delete(pageView); |
| |
| return pdfPage; |
| }).catch(reason => { |
| console.error("Unable to get page for page view", reason); |
| |
| this._pagesRequests.delete(pageView); |
| }); |
| |
| this._pagesRequests.set(pageView, promise); |
| |
| return promise; |
| } |
| |
| forceRendering(currentlyVisiblePages) { |
| const visiblePages = currentlyVisiblePages || this._getVisiblePages(); |
| |
| const scrollAhead = this._isScrollModeHorizontal ? this.scroll.right : this.scroll.down; |
| const pageView = this.renderingQueue.getHighestPriority(visiblePages, this._pages, scrollAhead); |
| |
| if (pageView) { |
| this._ensurePdfPageLoaded(pageView).then(() => { |
| this.renderingQueue.renderView(pageView); |
| }); |
| |
| return true; |
| } |
| |
| return false; |
| } |
| |
| createTextLayerBuilder(textLayerDiv, pageIndex, viewport, enhanceTextSelection = false, eventBus) { |
| return new _text_layer_builder.TextLayerBuilder({ |
| textLayerDiv, |
| eventBus, |
| pageIndex, |
| viewport, |
| findController: this.isInPresentationMode ? null : this.findController, |
| enhanceTextSelection: this.isInPresentationMode ? false : enhanceTextSelection |
| }); |
| } |
| |
| createAnnotationLayerBuilder(pageDiv, pdfPage, annotationStorage = null, imageResourcesPath = "", renderInteractiveForms = false, l10n = _ui_utils.NullL10n) { |
| return new _annotation_layer_builder.AnnotationLayerBuilder({ |
| pageDiv, |
| pdfPage, |
| annotationStorage, |
| imageResourcesPath, |
| renderInteractiveForms, |
| linkService: this.linkService, |
| downloadManager: this.downloadManager, |
| l10n |
| }); |
| } |
| |
| get hasEqualPageSizes() { |
| const firstPageView = this._pages[0]; |
| |
| for (let i = 1, ii = this._pages.length; i < ii; ++i) { |
| const pageView = this._pages[i]; |
| |
| if (pageView.width !== firstPageView.width || pageView.height !== firstPageView.height) { |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| getPagesOverview() { |
| const pagesOverview = this._pages.map(function (pageView) { |
| const viewport = pageView.pdfPage.getViewport({ |
| scale: 1 |
| }); |
| return { |
| width: viewport.width, |
| height: viewport.height, |
| rotation: viewport.rotation |
| }; |
| }); |
| |
| if (!this.enablePrintAutoRotate) { |
| return pagesOverview; |
| } |
| |
| return pagesOverview.map(function (size) { |
| if ((0, _ui_utils.isPortraitOrientation)(size)) { |
| return size; |
| } |
| |
| return { |
| width: size.height, |
| height: size.width, |
| rotation: (size.rotation + 90) % 360 |
| }; |
| }); |
| } |
| |
| get optionalContentConfigPromise() { |
| if (!this.pdfDocument) { |
| return Promise.resolve(null); |
| } |
| |
| if (!this._optionalContentConfigPromise) { |
| return this.pdfDocument.getOptionalContentConfig(); |
| } |
| |
| return this._optionalContentConfigPromise; |
| } |
| |
| set optionalContentConfigPromise(promise) { |
| if (!(promise instanceof Promise)) { |
| throw new Error(`Invalid optionalContentConfigPromise: ${promise}`); |
| } |
| |
| if (!this.pdfDocument) { |
| return; |
| } |
| |
| if (!this._optionalContentConfigPromise) { |
| return; |
| } |
| |
| this._optionalContentConfigPromise = promise; |
| |
| for (const pageView of this._pages) { |
| pageView.update(pageView.scale, pageView.rotation, promise); |
| } |
| |
| this.update(); |
| this.eventBus.dispatch("optionalcontentconfigchanged", { |
| source: this, |
| promise |
| }); |
| } |
| |
| get scrollMode() { |
| return this._scrollMode; |
| } |
| |
| set scrollMode(mode) { |
| if (this._scrollMode === mode) { |
| return; |
| } |
| |
| if (!(0, _ui_utils.isValidScrollMode)(mode)) { |
| throw new Error(`Invalid scroll mode: ${mode}`); |
| } |
| |
| this._scrollMode = mode; |
| this.eventBus.dispatch("scrollmodechanged", { |
| source: this, |
| mode |
| }); |
| |
| this._updateScrollMode(this._currentPageNumber); |
| } |
| |
| _updateScrollMode(pageNumber = null) { |
| const scrollMode = this._scrollMode, |
| viewer = this.viewer; |
| viewer.classList.toggle("scrollHorizontal", scrollMode === _ui_utils.ScrollMode.HORIZONTAL); |
| viewer.classList.toggle("scrollWrapped", scrollMode === _ui_utils.ScrollMode.WRAPPED); |
| |
| if (!this.pdfDocument || !pageNumber) { |
| return; |
| } |
| |
| if (this._currentScaleValue && isNaN(this._currentScaleValue)) { |
| this._setScale(this._currentScaleValue, true); |
| } |
| |
| this._setCurrentPageNumber(pageNumber, true); |
| |
| this.update(); |
| } |
| |
| get spreadMode() { |
| return this._spreadMode; |
| } |
| |
| set spreadMode(mode) { |
| if (this._spreadMode === mode) { |
| return; |
| } |
| |
| if (!(0, _ui_utils.isValidSpreadMode)(mode)) { |
| throw new Error(`Invalid spread mode: ${mode}`); |
| } |
| |
| this._spreadMode = mode; |
| this.eventBus.dispatch("spreadmodechanged", { |
| source: this, |
| mode |
| }); |
| |
| this._updateSpreadMode(this._currentPageNumber); |
| } |
| |
| _updateSpreadMode(pageNumber = null) { |
| if (!this.pdfDocument) { |
| return; |
| } |
| |
| const viewer = this.viewer, |
| pages = this._pages; |
| viewer.textContent = ""; |
| |
| if (this._spreadMode === _ui_utils.SpreadMode.NONE) { |
| for (let i = 0, iMax = pages.length; i < iMax; ++i) { |
| viewer.appendChild(pages[i].div); |
| } |
| } else { |
| const parity = this._spreadMode - 1; |
| let spread = null; |
| |
| for (let i = 0, iMax = pages.length; i < iMax; ++i) { |
| if (spread === null) { |
| spread = document.createElement("div"); |
| spread.className = "spread"; |
| viewer.appendChild(spread); |
| } else if (i % 2 === parity) { |
| spread = spread.cloneNode(false); |
| viewer.appendChild(spread); |
| } |
| |
| spread.appendChild(pages[i].div); |
| } |
| } |
| |
| if (!pageNumber) { |
| return; |
| } |
| |
| this._setCurrentPageNumber(pageNumber, true); |
| |
| this.update(); |
| } |
| |
| } |
| |
| exports.BaseViewer = BaseViewer; |