Something went wrong. Try again.
A privacy-first, self-hosted, fully open source personal knowledge management software, written in typescript and golang. (PERSONAL FORK)
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213/* 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("./interfaces").IRenderableView} IRenderableView *//** @typedef {import("./pdf_viewer").PDFViewer} PDFViewer */// eslint-disable-next-line max-len/** @typedef {import("./pdf_thumbnail_viewer").PDFThumbnailViewer} PDFThumbnailViewer */
import { RenderingCancelledException } from "./pdfjs";import { RenderingStates } from "./ui_utils.js";
const CLEANUP_TIMEOUT = 30000;
/** * Controls rendering of the views for pages and thumbnails. */class PDFRenderingQueue { constructor() { this.pdfViewer = null; this.pdfThumbnailViewer = null; this.onIdle = null; this.highestPriorityPage = null; /** @type {number} */ this.idleTimeout = null; this.printing = false; this.isThumbnailViewEnabled = false;
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) { Object.defineProperty(this, "hasViewer", { value: () => !!this.pdfViewer, }); } }
/** * @param {PDFViewer} pdfViewer */ setViewer(pdfViewer) { this.pdfViewer = pdfViewer; }
/** * @param {PDFThumbnailViewer} pdfThumbnailViewer */ setThumbnailViewer(pdfThumbnailViewer) { this.pdfThumbnailViewer = pdfThumbnailViewer; }
/** * @param {IRenderableView} view * @returns {boolean} */ isHighestPriority(view) { return this.highestPriorityPage === view.renderingId; }
/** * @param {Object} currentlyVisiblePages */ renderHighestPriority(currentlyVisiblePages) { if (this.idleTimeout) { clearTimeout(this.idleTimeout); this.idleTimeout = null; }
// Pages have a higher priority than thumbnails, so check them first. if (this.pdfViewer.forceRendering(currentlyVisiblePages)) { return; } // No pages needed rendering, so check thumbnails. if ( this.isThumbnailViewEnabled && this.pdfThumbnailViewer?.forceRendering() ) { return; }
if (this.printing) { // If printing is currently ongoing do not reschedule cleanup. return; }
if (this.onIdle) { this.idleTimeout = setTimeout(this.onIdle.bind(this), CLEANUP_TIMEOUT); } }
/** * @param {Object} visible * @param {Array} views * @param {boolean} scrolledDown * @param {boolean} [preRenderExtra] */ getHighestPriority(visible, views, scrolledDown, preRenderExtra = false) { /** * The state has changed. Figure out which page has the highest priority to * render next (if any). * * Priority: * 1. visible pages * 2. if last scrolled down, the page after the visible pages, or * if last scrolled up, the page before the visible pages */ const visibleViews = visible.views, numVisible = visibleViews.length;
if (numVisible === 0) { return null; } for (let i = 0; i < numVisible; i++) { const view = visibleViews[i].view; if (!this.isViewFinished(view)) { return view; } } const firstId = visible.first.id, lastId = visible.last.id;
// All the visible views have rendered; try to handle any "holes" in the // page layout (can happen e.g. with spreadModes at higher zoom levels). if (lastId - firstId + 1 > numVisible) { const visibleIds = visible.ids; for (let i = 1, ii = lastId - firstId; i < ii; i++) { const holeId = scrolledDown ? firstId + i : lastId - i; if (visibleIds.has(holeId)) { continue; } const holeView = views[holeId - 1]; if (!this.isViewFinished(holeView)) { return holeView; } } }
// All the visible views have rendered; try to render next/previous page. // (IDs start at 1, so no need to add 1 when `scrolledDown === true`.) let preRenderIndex = scrolledDown ? lastId : firstId - 2; let preRenderView = views[preRenderIndex];
if (preRenderView && !this.isViewFinished(preRenderView)) { return preRenderView; } if (preRenderExtra) { preRenderIndex += scrolledDown ? 1 : -1; preRenderView = views[preRenderIndex];
if (preRenderView && !this.isViewFinished(preRenderView)) { return preRenderView; } } // Everything that needs to be rendered has been. return null; }
/** * @param {IRenderableView} view * @returns {boolean} */ isViewFinished(view) { return view.renderingState === RenderingStates.FINISHED; }
/** * Render a page or thumbnail view. This calls the appropriate function * based on the views state. If the view is already rendered it will return * `false`. * * @param {IRenderableView} view */ renderView(view) { switch (view.renderingState) { case RenderingStates.FINISHED: return false; case RenderingStates.PAUSED: this.highestPriorityPage = view.renderingId; view.resume(); break; case RenderingStates.RUNNING: this.highestPriorityPage = view.renderingId; break; case RenderingStates.INITIAL: this.highestPriorityPage = view.renderingId; view .draw() .finally(() => { this.renderHighestPriority(); }) .catch(reason => { if (reason instanceof RenderingCancelledException) { return; } console.error(`renderView: "${reason}"`); }); break; } return true; }}
export { PDFRenderingQueue };