From 745045752530819da1a83e825fd0e67328fa9dac Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Tue, 21 Jan 2025 23:26:20 +0100 Subject: [PATCH] [api-major] Change viewer component `render`-methods to take parameter objects This is nicer than a bunch of somewhat arbitrarily ordered parameters, and makes any future changes easier. --- web/annotation_editor_layer_builder.js | 12 ++++++++--- web/annotation_layer_builder.js | 17 +++++++++++----- web/draw_layer_builder.js | 10 +++++++-- web/pdf_page_view.js | 28 +++++++++++++++++--------- web/struct_tree_layer_builder.js | 14 +++++++++++++ web/text_layer_builder.js | 16 ++++++++++++--- web/xfa_layer_builder.js | 11 +++++++--- 7 files changed, 83 insertions(+), 25 deletions(-) diff --git a/web/annotation_editor_layer_builder.js b/web/annotation_editor_layer_builder.js index f6240f2c4..9709628b6 100644 --- a/web/annotation_editor_layer_builder.js +++ b/web/annotation_editor_layer_builder.js @@ -42,6 +42,12 @@ import { GenericL10n } from "web-null_l10n"; * @property {function} [onAppend] */ +/** + * @typedef {Object} AnnotationEditorLayerBuilderRenderOptions + * @property {PageViewport} viewport + * @property {string} [intent] - The default value is "display". + */ + class AnnotationEditorLayerBuilder { #annotationLayer = null; @@ -77,10 +83,10 @@ class AnnotationEditorLayerBuilder { } /** - * @param {PageViewport} viewport - * @param {string} intent (default value is 'display') + * @param {AnnotationEditorLayerBuilderRenderOptions} options + * @returns {Promise} */ - async render(viewport, intent = "display") { + async render({ viewport, intent = "display" }) { if (intent !== "display") { return; } diff --git a/web/annotation_layer_builder.js b/web/annotation_layer_builder.js index 4961d6a4b..b6e31404c 100644 --- a/web/annotation_layer_builder.js +++ b/web/annotation_layer_builder.js @@ -21,6 +21,8 @@ /** @typedef {import("./interfaces").IDownloadManager} IDownloadManager */ /** @typedef {import("./interfaces").IPDFLinkService} IPDFLinkService */ // eslint-disable-next-line max-len +/** @typedef {import("./struct_tree_layer_builder.js").StructTreeLayerBuilder} StructTreeLayerBuilder */ +// eslint-disable-next-line max-len /** @typedef {import("./text_accessibility.js").TextAccessibilityManager} TextAccessibilityManager */ // eslint-disable-next-line max-len /** @typedef {import("../src/display/editor/tools.js").AnnotationEditorUIManager} AnnotationEditorUIManager */ @@ -47,6 +49,13 @@ import { PresentationModeState } from "./ui_utils.js"; * @property {function} [onAppend] */ +/** + * @typedef {Object} AnnotationLayerBuilderRenderOptions + * @property {PageViewport} viewport + * @property {string} [intent] - The default value is "display". + * @property {StructTreeLayerBuilder} [structTreeLayer] + */ + class AnnotationLayerBuilder { #onAppend = null; @@ -91,13 +100,11 @@ class AnnotationLayerBuilder { } /** - * @param {PageViewport} viewport - * @param {Object} options - * @param {string} intent (default value is 'display') + * @param {AnnotationLayerBuilderRenderOptions} options * @returns {Promise} A promise that is resolved when rendering of the * annotations is complete. */ - async render(viewport, options, intent = "display") { + async render({ viewport, intent = "display", structTreeLayer = null }) { if (this.div) { if (this._cancelled || !this.annotationLayer) { return; @@ -137,7 +144,7 @@ class AnnotationLayerBuilder { annotationEditorUIManager: this._annotationEditorUIManager, page: this.pdfPage, viewport: viewport.clone({ dontFlip: true }), - structTreeLayer: options?.structTreeLayer || null, + structTreeLayer, }); await this.annotationLayer.render({ diff --git a/web/draw_layer_builder.js b/web/draw_layer_builder.js index 6f349b6cf..003a84e36 100644 --- a/web/draw_layer_builder.js +++ b/web/draw_layer_builder.js @@ -20,6 +20,11 @@ import { DrawLayer } from "pdfjs-lib"; * @property {number} pageIndex */ +/** + * @typedef {Object} DrawLayerBuilderRenderOptions + * @property {string} [intent] - The default value is "display". + */ + class DrawLayerBuilder { #drawLayer = null; @@ -31,9 +36,10 @@ class DrawLayerBuilder { } /** - * @param {string} intent (default value is 'display') + * @param {DrawLayerBuilderRenderOptions} options + * @returns {Promise} */ - async render(intent = "display") { + async render({ intent = "display" }) { if (intent !== "display" || this.#drawLayer || this._cancelled) { return; } diff --git a/web/pdf_page_view.js b/web/pdf_page_view.js index 963dd644b..fd33e3b76 100644 --- a/web/pdf_page_view.js +++ b/web/pdf_page_view.js @@ -396,11 +396,11 @@ class PDFPageView { async #renderAnnotationLayer() { let error = null; try { - await this.annotationLayer.render( - this.viewport, - { structTreeLayer: this.structTreeLayer }, - "display" - ); + await this.annotationLayer.render({ + viewport: this.viewport, + intent: "display", + structTreeLayer: this.structTreeLayer, + }); } catch (ex) { console.error("#renderAnnotationLayer:", ex); error = ex; @@ -412,7 +412,10 @@ class PDFPageView { async #renderAnnotationEditorLayer() { let error = null; try { - await this.annotationEditorLayer.render(this.viewport, "display"); + await this.annotationEditorLayer.render({ + viewport: this.viewport, + intent: "display", + }); } catch (ex) { console.error("#renderAnnotationEditorLayer:", ex); error = ex; @@ -423,7 +426,9 @@ class PDFPageView { async #renderDrawLayer() { try { - await this.drawLayer.render("display"); + await this.drawLayer.render({ + intent: "display", + }); } catch (ex) { console.error("#renderDrawLayer:", ex); } @@ -432,7 +437,10 @@ class PDFPageView { async #renderXfaLayer() { let error = null; try { - const result = await this.xfaLayer.render(this.viewport, "display"); + const result = await this.xfaLayer.render({ + viewport: this.viewport, + intent: "display", + }); if (result?.textDivs && this._textHighlighter) { // Given that the following method fetches the text asynchronously we // can invoke it *before* appending the xfaLayer to the DOM (below), @@ -461,7 +469,9 @@ class PDFPageView { let error = null; try { - await this.textLayer.render(this.viewport); + await this.textLayer.render({ + viewport: this.viewport, + }); } catch (ex) { if (ex instanceof AbortException) { return; diff --git a/web/struct_tree_layer_builder.js b/web/struct_tree_layer_builder.js index 72ba6bc5c..0741e598e 100644 --- a/web/struct_tree_layer_builder.js +++ b/web/struct_tree_layer_builder.js @@ -13,6 +13,8 @@ * limitations under the License. */ +/** @typedef {import("../src/display/api").PDFPageProxy} PDFPageProxy */ + import { removeNullCharacters } from "./ui_utils.js"; const PDF_ROLE_TO_HTML_ROLE = { @@ -73,6 +75,12 @@ const PDF_ROLE_TO_HTML_ROLE = { const HEADING_PATTERN = /^H(\d+)$/; +/** + * @typedef {Object} StructTreeLayerBuilderOptions + * @property {PDFPageProxy} pdfPage + * @property {Object} rawDims + */ + class StructTreeLayerBuilder { #promise; @@ -86,11 +94,17 @@ class StructTreeLayerBuilder { #elementsToAddToTextLayer = null; + /** + * @param {StructTreeLayerBuilderOptions} options + */ constructor(pdfPage, rawDims) { this.#promise = pdfPage.getStructTree(); this.#rawDims = rawDims; } + /** + * @returns {Promise} + */ async render() { if (this.#treePromise) { return this.#treePromise; diff --git a/web/text_layer_builder.js b/web/text_layer_builder.js index f642382b6..30816eef0 100644 --- a/web/text_layer_builder.js +++ b/web/text_layer_builder.js @@ -29,9 +29,16 @@ import { removeNullCharacters } from "./ui_utils.js"; * @property {TextHighlighter} [highlighter] - Optional object that will handle * highlighting text from the find controller. * @property {TextAccessibilityManager} [accessibilityManager] + * @property {boolean} [enablePermissions] * @property {function} [onAppend] */ +/** + * @typedef {Object} TextLayerBuilderRenderOptions + * @property {PageViewport} viewport + * @property {Object} [textContentParams] + */ + /** * The text layer builder provides text selection functionality for the PDF. * It does this by creating overlay divs over the PDF's text. These divs @@ -50,6 +57,9 @@ class TextLayerBuilder { static #selectionChangeAbortController = null; + /** + * @param {TextLayerBuilderOptions} options + */ constructor({ pdfPage, highlighter = null, @@ -70,10 +80,10 @@ class TextLayerBuilder { /** * Renders the text layer. - * @param {PageViewport} viewport - * @param {Object} [textContentParams] + * @param {TextLayerBuilderRenderOptions} options + * @returns {Promise} */ - async render(viewport, textContentParams = null) { + async render({ viewport, textContentParams = null }) { if (this.#renderingDone && this.#textLayer) { this.#textLayer.update({ viewport, diff --git a/web/xfa_layer_builder.js b/web/xfa_layer_builder.js index 25a521d5f..95c540b93 100644 --- a/web/xfa_layer_builder.js +++ b/web/xfa_layer_builder.js @@ -30,6 +30,12 @@ import { XfaLayer } from "pdfjs-lib"; * @property {Object} [xfaHtml] */ +/** + * @typedef {Object} XfaLayerBuilderRenderOptions + * @property {PageViewport} viewport + * @property {string} [intent] - The default value is "display". + */ + class XfaLayerBuilder { /** * @param {XfaLayerBuilderOptions} options @@ -50,13 +56,12 @@ class XfaLayerBuilder { } /** - * @param {PageViewport} viewport - * @param {string} intent (default value is 'display') + * @param {XfaLayerBuilderRenderOptions} viewport * @returns {Promise} A promise that is resolved when rendering * of the XFA layer is complete. The first rendering will return an object * with a `textDivs` property that can be used with the TextHighlighter. */ - async render(viewport, intent = "display") { + async render({ viewport, intent = "display" }) { if (intent === "print") { const parameters = { viewport: viewport.clone({ dontFlip: true }),