Skip to content

Commit

Permalink
[api-minor] Move the page reference/number caching into the API
Browse files Browse the repository at this point in the history
Rather than having to handle this *manually* throughout the viewer, this functionality can instead be moved into the API which simplifies the code slightly.
  • Loading branch information
Snuffleupagus committed Apr 25, 2024
1 parent 5c3b596 commit e5e4890
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 70 deletions.
1 change: 1 addition & 0 deletions src/core/worker.js
Expand Up @@ -419,6 +419,7 @@ class WorkerMessageHandler {
return {
rotate,
ref,
refStr: ref?.toString() ?? null,
userUnit,
view,
};
Expand Down
41 changes: 34 additions & 7 deletions src/display/api.js
Expand Up @@ -561,6 +561,16 @@ function getDataProp(val) {
);
}

function isRefProxy(ref) {
return (
typeof ref === "object" &&
Number.isInteger(ref?.num) &&
ref.num >= 0 &&
Number.isInteger(ref?.gen) &&
ref.gen >= 0
);
}

/**
* @typedef {Object} OnProgressParameters
* @property {number} loaded - Currently loaded number of bytes.
Expand Down Expand Up @@ -1067,6 +1077,14 @@ class PDFDocumentProxy {
return this.loadingTask.destroy();
}

/**
* @param {RefProxy} ref - The page reference.
* @returns {number | null} The page number, if it's cached.
*/
cachedPageNumber(ref) {
return this._transport.cachedPageNumber(ref);
}

/**
* @type {DocumentInitParameters} A subset of the current
* {DocumentInitParameters}, which are needed in the viewer.
Expand Down Expand Up @@ -2341,6 +2359,8 @@ class WorkerTransport {

#pagePromises = new Map();

#pageRefCache = new Map();

#passwordCapability = null;

constructor(messageHandler, loadingTask, networkStream, params, factory) {
Expand Down Expand Up @@ -2484,6 +2504,7 @@ class WorkerTransport {
}
this.#pageCache.clear();
this.#pagePromises.clear();
this.#pageRefCache.clear();
// Allow `AnnotationStorage`-related clean-up when destroying the document.
if (this.hasOwnProperty("annotationStorage")) {
this.annotationStorage.resetModified();
Expand Down Expand Up @@ -2917,6 +2938,10 @@ class WorkerTransport {
if (this.destroyed) {
throw new Error("Transport destroyed");
}
if (pageInfo.refStr) {
this.#pageRefCache.set(pageInfo.refStr, pageNumber);
}

const page = new PDFPageProxy(
pageIndex,
pageInfo,
Expand All @@ -2931,13 +2956,7 @@ class WorkerTransport {
}

getPageIndex(ref) {
if (
typeof ref !== "object" ||
!Number.isInteger(ref?.num) ||
ref.num < 0 ||
!Number.isInteger(ref?.gen) ||
ref.gen < 0
) {
if (!isRefProxy(ref)) {
return Promise.reject(new Error("Invalid pageIndex request."));
}
return this.messageHandler.sendWithPromise("GetPageIndex", {
Expand Down Expand Up @@ -3078,6 +3097,14 @@ class WorkerTransport {
cleanupTextLayer();
}

cachedPageNumber(ref) {
if (!isRefProxy(ref)) {
return null;
}
const refStr = ref.gen === 0 ? `${ref.num}R` : `${ref.num}R${ref.gen}`;
return this.#pageRefCache.get(refStr) ?? null;
}

get loadingParams() {
const { disableAutoFetch, enableXfa } = this._params;
return shadow(this, "loadingParams", {
Expand Down
6 changes: 0 additions & 6 deletions web/interfaces.js
Expand Up @@ -106,12 +106,6 @@ class IPDFLinkService {
* @param {Object} action
*/
executeSetOCGState(action) {}

/**
* @param {number} pageNum - page number.
* @param {Object} pageRef - reference to the page.
*/
cachePageRef(pageNum, pageRef) {}
}

/**
Expand Down
39 changes: 2 additions & 37 deletions web/pdf_link_service.js
Expand Up @@ -98,8 +98,6 @@ function addLinkAttributes(link, { url, target, rel, enabled = true } = {}) {
* @implements {IPDFLinkService}
*/
class PDFLinkService {
#pagesRefCache = new Map();

/**
* @param {PDFLinkServiceOptions} options
*/
Expand All @@ -124,7 +122,6 @@ class PDFLinkService {
setDocument(pdfDocument, baseUrl = null) {
this.baseUrl = baseUrl;
this.pdfDocument = pdfDocument;
this.#pagesRefCache.clear();
}

setViewer(pdfViewer) {
Expand Down Expand Up @@ -203,15 +200,14 @@ class PDFLinkService {
// Dest array looks like that: <page-ref> </XYZ|/FitXXX> <args..>
const [destRef] = explicitDest;

if (typeof destRef === "object" && destRef !== null) {
pageNumber = this._cachedPageNumber(destRef);
if (destRef && typeof destRef === "object") {
pageNumber = this.pdfDocument.cachedPageNumber(destRef);

if (!pageNumber) {
// Fetch the page reference if it's not yet available. This could
// only occur during loading, before all pages have been resolved.
try {
pageNumber = (await this.pdfDocument.getPageIndex(destRef)) + 1;
this.cachePageRef(pageNumber, destRef);
} catch {
console.error(
`goToDestination: "${destRef}" is not a valid page reference, for dest="${dest}".`
Expand Down Expand Up @@ -509,31 +505,6 @@ class PDFLinkService {
);
}

/**
* @param {number} pageNum - page number.
* @param {Object} pageRef - reference to the page.
*/
cachePageRef(pageNum, pageRef) {
if (!pageRef) {
return;
}
const refStr =
pageRef.gen === 0 ? `${pageRef.num}R` : `${pageRef.num}R${pageRef.gen}`;
this.#pagesRefCache.set(refStr, pageNum);
}

/**
* @ignore
*/
_cachedPageNumber(pageRef) {
if (!pageRef) {
return null;
}
const refStr =
pageRef.gen === 0 ? `${pageRef.num}R` : `${pageRef.num}R${pageRef.gen}`;
return this.#pagesRefCache.get(refStr) || null;
}

static #isValidExplicitDest(dest) {
if (!Array.isArray(dest) || dest.length < 2) {
return false;
Expand Down Expand Up @@ -683,12 +654,6 @@ class SimpleLinkService {
* @param {Object} action
*/
executeSetOCGState(action) {}

/**
* @param {number} pageNum - page number.
* @param {Object} pageRef - reference to the page.
*/
cachePageRef(pageNum, pageRef) {}
}

export { LinkTarget, PDFLinkService, SimpleLinkService };
19 changes: 4 additions & 15 deletions web/pdf_outline_viewer.js
Expand Up @@ -325,21 +325,10 @@ class PDFOutlineViewer extends BaseTreeViewer {
if (Array.isArray(explicitDest)) {
const [destRef] = explicitDest;

if (typeof destRef === "object" && destRef !== null) {
pageNumber = this.linkService._cachedPageNumber(destRef);

if (!pageNumber) {
try {
pageNumber = (await pdfDocument.getPageIndex(destRef)) + 1;

if (pdfDocument !== this._pdfDocument) {
return null; // The document was closed while the data resolved.
}
this.linkService.cachePageRef(pageNumber, destRef);
} catch {
// Invalid page reference, ignore it and continue parsing.
}
}
if (destRef && typeof destRef === "object") {
// The page reference must be available, since the current method
// won't be invoked until all pages have been loaded.
pageNumber = pdfDocument.cachedPageNumber(destRef);
} else if (Number.isInteger(destRef)) {
pageNumber = destRef + 1;
}
Expand Down
5 changes: 0 additions & 5 deletions web/pdf_viewer.js
Expand Up @@ -938,7 +938,6 @@ class PDFViewer {
const firstPageView = this._pages[0];
if (firstPageView) {
firstPageView.setPdfPage(firstPdfPage);
this.linkService.cachePageRef(1, firstPdfPage.ref);
}

if (this._scrollMode === ScrollMode.PAGE) {
Expand Down Expand Up @@ -994,7 +993,6 @@ class PDFViewer {
if (!pageView.pdfPage) {
pageView.setPdfPage(pdfPage);
}
this.linkService.cachePageRef(pageNum, pdfPage.ref);
if (--getPagesLeft === 0) {
this._pagesCapability.resolve();
}
Expand Down Expand Up @@ -1718,9 +1716,6 @@ class PDFViewer {
if (!pageView.pdfPage) {
pageView.setPdfPage(pdfPage);
}
if (!this.linkService._cachedPageNumber?.(pdfPage.ref)) {
this.linkService.cachePageRef(pageView.id, pdfPage.ref);
}
return pdfPage;
} catch (reason) {
console.error("Unable to get page for page view", reason);
Expand Down

0 comments on commit e5e4890

Please sign in to comment.