| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324 | 
							- /* Copyright 2012 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.
 
-  */
 
- /** @typedef {import("../src/display/api").PDFDocumentProxy} PDFDocumentProxy */
 
- /** @typedef {import("./event_utils").EventBus} EventBus */
 
- /** @typedef {import("./interfaces").IL10n} IL10n */
 
- /** @typedef {import("./interfaces").IPDFLinkService} IPDFLinkService */
 
- // eslint-disable-next-line max-len
 
- /** @typedef {import("./pdf_rendering_queue").PDFRenderingQueue} PDFRenderingQueue */
 
- import {
 
-   getVisibleElements,
 
-   isValidRotation,
 
-   RenderingStates,
 
-   scrollIntoView,
 
-   watchScroll,
 
- } from "./ui_utils.js";
 
- import { PDFThumbnailView, TempImageFactory } from "./pdf_thumbnail_view.js";
 
- const THUMBNAIL_SCROLL_MARGIN = -19;
 
- const THUMBNAIL_SELECTED_CLASS = "selected";
 
- /**
 
-  * @typedef {Object} PDFThumbnailViewerOptions
 
-  * @property {HTMLDivElement} container - The container for the thumbnail
 
-  *   elements.
 
-  * @property {EventBus} eventBus - The application event bus.
 
-  * @property {IPDFLinkService} linkService - The navigation/linking service.
 
-  * @property {PDFRenderingQueue} renderingQueue - The rendering queue object.
 
-  * @property {IL10n} l10n - Localization service.
 
-  * @property {Object} [pageColors] - Overwrites background and foreground colors
 
-  *   with user defined ones in order to improve readability in high contrast
 
-  *   mode.
 
-  */
 
- /**
 
-  * Viewer control to display thumbnails for pages in a PDF document.
 
-  */
 
- class PDFThumbnailViewer {
 
-   /**
 
-    * @param {PDFThumbnailViewerOptions} options
 
-    */
 
-   constructor({
 
-     container,
 
-     eventBus,
 
-     linkService,
 
-     renderingQueue,
 
-     l10n,
 
-     pageColors,
 
-   }) {
 
-     this.container = container;
 
-     this.linkService = linkService;
 
-     this.renderingQueue = renderingQueue;
 
-     this.l10n = l10n;
 
-     this.pageColors = pageColors || null;
 
-     if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("MOZCENTRAL")) {
 
-       if (
 
-         this.pageColors &&
 
-         !(
 
-           CSS.supports("color", this.pageColors.background) &&
 
-           CSS.supports("color", this.pageColors.foreground)
 
-         )
 
-       ) {
 
-         if (this.pageColors.background || this.pageColors.foreground) {
 
-           console.warn(
 
-             "PDFThumbnailViewer: Ignoring `pageColors`-option, since the browser doesn't support the values used."
 
-           );
 
-         }
 
-         this.pageColors = null;
 
-       }
 
-     }
 
-     this.scroll = watchScroll(this.container, this._scrollUpdated.bind(this));
 
-     this._resetView();
 
-   }
 
-   /**
 
-    * @private
 
-    */
 
-   _scrollUpdated() {
 
-     this.renderingQueue.renderHighestPriority();
 
-   }
 
-   getThumbnail(index) {
 
-     return this._thumbnails[index];
 
-   }
 
-   /**
 
-    * @private
 
-    */
 
-   _getVisibleThumbs() {
 
-     return getVisibleElements({
 
-       scrollEl: this.container,
 
-       views: this._thumbnails,
 
-     });
 
-   }
 
-   scrollThumbnailIntoView(pageNumber) {
 
-     if (!this.pdfDocument) {
 
-       return;
 
-     }
 
-     const thumbnailView = this._thumbnails[pageNumber - 1];
 
-     if (!thumbnailView) {
 
-       console.error('scrollThumbnailIntoView: Invalid "pageNumber" parameter.');
 
-       return;
 
-     }
 
-     if (pageNumber !== this._currentPageNumber) {
 
-       const prevThumbnailView = this._thumbnails[this._currentPageNumber - 1];
 
-       // Remove the highlight from the previous thumbnail...
 
-       prevThumbnailView.div.classList.remove(THUMBNAIL_SELECTED_CLASS);
 
-       // ... and add the highlight to the new thumbnail.
 
-       thumbnailView.div.classList.add(THUMBNAIL_SELECTED_CLASS);
 
-     }
 
-     const { first, last, views } = this._getVisibleThumbs();
 
-     // If the thumbnail isn't currently visible, scroll it into view.
 
-     if (views.length > 0) {
 
-       let shouldScroll = false;
 
-       if (pageNumber <= first.id || pageNumber >= last.id) {
 
-         shouldScroll = true;
 
-       } else {
 
-         for (const { id, percent } of views) {
 
-           if (id !== pageNumber) {
 
-             continue;
 
-           }
 
-           shouldScroll = percent < 100;
 
-           break;
 
-         }
 
-       }
 
-       if (shouldScroll) {
 
-         scrollIntoView(thumbnailView.div, { top: THUMBNAIL_SCROLL_MARGIN });
 
-       }
 
-     }
 
-     this._currentPageNumber = pageNumber;
 
-   }
 
-   get pagesRotation() {
 
-     return this._pagesRotation;
 
-   }
 
-   set pagesRotation(rotation) {
 
-     if (!isValidRotation(rotation)) {
 
-       throw new Error("Invalid thumbnails rotation angle.");
 
-     }
 
-     if (!this.pdfDocument) {
 
-       return;
 
-     }
 
-     if (this._pagesRotation === rotation) {
 
-       return; // The rotation didn't change.
 
-     }
 
-     this._pagesRotation = rotation;
 
-     const updateArgs = { rotation };
 
-     for (const thumbnail of this._thumbnails) {
 
-       thumbnail.update(updateArgs);
 
-     }
 
-   }
 
-   cleanup() {
 
-     for (const thumbnail of this._thumbnails) {
 
-       if (thumbnail.renderingState !== RenderingStates.FINISHED) {
 
-         thumbnail.reset();
 
-       }
 
-     }
 
-     TempImageFactory.destroyCanvas();
 
-   }
 
-   /**
 
-    * @private
 
-    */
 
-   _resetView() {
 
-     this._thumbnails = [];
 
-     this._currentPageNumber = 1;
 
-     this._pageLabels = null;
 
-     this._pagesRotation = 0;
 
-     // Remove the thumbnails from the DOM.
 
-     this.container.textContent = "";
 
-   }
 
-   /**
 
-    * @param {PDFDocumentProxy} pdfDocument
 
-    */
 
-   setDocument(pdfDocument) {
 
-     if (this.pdfDocument) {
 
-       this._cancelRendering();
 
-       this._resetView();
 
-     }
 
-     this.pdfDocument = pdfDocument;
 
-     if (!pdfDocument) {
 
-       return;
 
-     }
 
-     const firstPagePromise = pdfDocument.getPage(1);
 
-     const optionalContentConfigPromise = pdfDocument.getOptionalContentConfig();
 
-     firstPagePromise
 
-       .then(firstPdfPage => {
 
-         const pagesCount = pdfDocument.numPages;
 
-         const viewport = firstPdfPage.getViewport({ scale: 1 });
 
-         for (let pageNum = 1; pageNum <= pagesCount; ++pageNum) {
 
-           const thumbnail = new PDFThumbnailView({
 
-             container: this.container,
 
-             id: pageNum,
 
-             defaultViewport: viewport.clone(),
 
-             optionalContentConfigPromise,
 
-             linkService: this.linkService,
 
-             renderingQueue: this.renderingQueue,
 
-             l10n: this.l10n,
 
-             pageColors: this.pageColors,
 
-           });
 
-           this._thumbnails.push(thumbnail);
 
-         }
 
-         // Set the first `pdfPage` immediately, since it's already loaded,
 
-         // rather than having to repeat the `PDFDocumentProxy.getPage` call in
 
-         // the `this.#ensurePdfPageLoaded` method before rendering can start.
 
-         this._thumbnails[0]?.setPdfPage(firstPdfPage);
 
-         // Ensure that the current thumbnail is always highlighted on load.
 
-         const thumbnailView = this._thumbnails[this._currentPageNumber - 1];
 
-         thumbnailView.div.classList.add(THUMBNAIL_SELECTED_CLASS);
 
-       })
 
-       .catch(reason => {
 
-         console.error("Unable to initialize thumbnail viewer", reason);
 
-       });
 
-   }
 
-   /**
 
-    * @private
 
-    */
 
-   _cancelRendering() {
 
-     for (const thumbnail of this._thumbnails) {
 
-       thumbnail.cancelRendering();
 
-     }
 
-   }
 
-   /**
 
-    * @param {Array|null} labels
 
-    */
 
-   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("PDFThumbnailViewer_setPageLabels: Invalid page labels.");
 
-     } else {
 
-       this._pageLabels = labels;
 
-     }
 
-     // Update all the `PDFThumbnailView` instances.
 
-     for (let i = 0, ii = this._thumbnails.length; i < ii; i++) {
 
-       this._thumbnails[i].setPageLabel(this._pageLabels?.[i] ?? null);
 
-     }
 
-   }
 
-   /**
 
-    * @param {PDFThumbnailView} thumbView
 
-    * @returns {Promise<PDFPageProxy | null>}
 
-    */
 
-   async #ensurePdfPageLoaded(thumbView) {
 
-     if (thumbView.pdfPage) {
 
-       return thumbView.pdfPage;
 
-     }
 
-     try {
 
-       const pdfPage = await this.pdfDocument.getPage(thumbView.id);
 
-       if (!thumbView.pdfPage) {
 
-         thumbView.setPdfPage(pdfPage);
 
-       }
 
-       return pdfPage;
 
-     } catch (reason) {
 
-       console.error("Unable to get page for thumb view", reason);
 
-       return null; // Page error -- there is nothing that can be done.
 
-     }
 
-   }
 
-   #getScrollAhead(visible) {
 
-     if (visible.first?.id === 1) {
 
-       return true;
 
-     } else if (visible.last?.id === this._thumbnails.length) {
 
-       return false;
 
-     }
 
-     return this.scroll.down;
 
-   }
 
-   forceRendering() {
 
-     const visibleThumbs = this._getVisibleThumbs();
 
-     const scrollAhead = this.#getScrollAhead(visibleThumbs);
 
-     const thumbView = this.renderingQueue.getHighestPriority(
 
-       visibleThumbs,
 
-       this._thumbnails,
 
-       scrollAhead
 
-     );
 
-     if (thumbView) {
 
-       this.#ensurePdfPageLoaded(thumbView).then(() => {
 
-         this.renderingQueue.renderView(thumbView);
 
-       });
 
-       return true;
 
-     }
 
-     return false;
 
-   }
 
- }
 
- export { PDFThumbnailViewer };
 
 
  |