Merge pull request #15811 from Snuffleupagus/rm-web-default-factory

[api-minor] Remove the default factories, used to initialize various layers, in the viewer
This commit is contained in:
Tim van der Meij 2022-12-18 14:22:13 +01:00 committed by GitHub
commit 6a9a567670
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 186 additions and 613 deletions

View File

@ -51,6 +51,21 @@ const loadingTask = pdfjsLib.getDocument({
const pdfDocument = await loadingTask.promise; const pdfDocument = await loadingTask.promise;
// Document loaded, retrieving the page. // Document loaded, retrieving the page.
const pdfPage = await pdfDocument.getPage(PAGE_TO_VIEW); const pdfPage = await pdfDocument.getPage(PAGE_TO_VIEW);
const match = /^(\d+)\.(\d+)\.(\d+)$/.exec(pdfjsLib.version);
if (match && (match[1] | 0) >= 3 && (match[2] | 0) >= 2) {
// Creating the page view with default parameters.
const pdfPageView = new pdfjsViewer.PDFPageView({
container,
id: PAGE_TO_VIEW,
scale: SCALE,
defaultViewport: pdfPage.getViewport({ scale: SCALE }),
eventBus,
});
// Associate the actual page with the view, and draw it.
pdfPageView.setPdfPage(pdfPage);
return pdfPageView.draw();
}
// Creating the page view with default parameters. // Creating the page view with default parameters.
const pdfPageView = new pdfjsViewer.PDFPageView({ const pdfPageView = new pdfjsViewer.PDFPageView({
container, container,

View File

@ -783,7 +783,7 @@ class PDFDocumentProxy {
* @type {boolean} True if only XFA form. * @type {boolean} True if only XFA form.
*/ */
get isPureXfa() { get isPureXfa() {
return !!this._transport._htmlForXfa; return shadow(this, "isPureXfa", !!this._transport._htmlForXfa);
} }
/** /**
@ -1343,6 +1343,13 @@ class PDFPageProxy {
)); ));
} }
/**
* @type {boolean} True if only XFA form.
*/
get isPureXfa() {
return shadow(this, "isPureXfa", !!this._transport._htmlForXfa);
}
/** /**
* @returns {Promise<Object | null>} A promise that is resolved with * @returns {Promise<Object | null>} A promise that is resolved with
* an {Object} with a fake DOM object (a tree structure where elements * an {Object} with a fake DOM object (a tree structure where elements

View File

@ -30,7 +30,7 @@ import { NullL10n } from "./l10n_utils.js";
* @property {AnnotationEditorUIManager} [uiManager] * @property {AnnotationEditorUIManager} [uiManager]
* @property {HTMLDivElement} pageDiv * @property {HTMLDivElement} pageDiv
* @property {PDFPageProxy} pdfPage * @property {PDFPageProxy} pdfPage
* @property {IL10n} l10n * @property {IL10n} [l10n]
* @property {TextAccessibilityManager} [accessibilityManager] * @property {TextAccessibilityManager} [accessibilityManager]
*/ */

View File

@ -1,207 +0,0 @@
/* Copyright 2014 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").PDFPageProxy} PDFPageProxy */
// eslint-disable-next-line max-len
/** @typedef {import("../src/display/display_utils").PageViewport} PageViewport */
/** @typedef {import("./event_utils").EventBus} EventBus */
/** @typedef {import("./interfaces").IDownloadManager} IDownloadManager */
/** @typedef {import("./interfaces").IL10n} IL10n */
// eslint-disable-next-line max-len
/** @typedef {import("./interfaces").IPDFAnnotationLayerFactory} IPDFAnnotationLayerFactory */
// eslint-disable-next-line max-len
/** @typedef {import("./interfaces").IPDFAnnotationEditorLayerFactory} IPDFAnnotationEditorLayerFactory */
/** @typedef {import("./interfaces").IPDFLinkService} IPDFLinkService */
// eslint-disable-next-line max-len
/** @typedef {import("./interfaces").IPDFStructTreeLayerFactory} IPDFStructTreeLayerFactory */
// eslint-disable-next-line max-len
/** @typedef {import("./interfaces").IPDFTextLayerFactory} IPDFTextLayerFactory */
/** @typedef {import("./interfaces").IPDFXfaLayerFactory} IPDFXfaLayerFactory */
/** @typedef {import("./text_highlighter").TextHighlighter} TextHighlighter */
// eslint-disable-next-line max-len
/** @typedef {import("./text_accessibility.js").TextAccessibilityManager} TextAccessibilityManager */
import { AnnotationEditorLayerBuilder } from "./annotation_editor_layer_builder.js";
import { AnnotationLayerBuilder } from "./annotation_layer_builder.js";
import { NullL10n } from "./l10n_utils.js";
import { SimpleLinkService } from "./pdf_link_service.js";
import { StructTreeLayerBuilder } from "./struct_tree_layer_builder.js";
import { TextLayerBuilder } from "./text_layer_builder.js";
import { XfaLayerBuilder } from "./xfa_layer_builder.js";
/**
* @implements IPDFAnnotationLayerFactory
*/
class DefaultAnnotationLayerFactory {
/**
* @typedef {Object} CreateAnnotationLayerBuilderParameters
* @property {HTMLDivElement} pageDiv
* @property {PDFPageProxy} pdfPage
* @property {AnnotationStorage} [annotationStorage] - Storage for annotation
* data in forms.
* @property {string} [imageResourcesPath] - Path for image resources, mainly
* for annotation icons. Include trailing slash.
* @property {boolean} renderForms
* @property {IL10n} l10n
* @property {boolean} [enableScripting]
* @property {Promise<boolean>} [hasJSActionsPromise]
* @property {Promise<Object<string, Array<Object>> | null>}
* [fieldObjectsPromise]
* @property {Map<string, HTMLCanvasElement>} [annotationCanvasMap] - Map some
* annotation ids with canvases used to render them.
* @property {TextAccessibilityManager} [accessibilityManager]
*/
/**
* @param {CreateAnnotationLayerBuilderParameters}
* @returns {AnnotationLayerBuilder}
*/
createAnnotationLayerBuilder({
pageDiv,
pdfPage,
annotationStorage = null,
imageResourcesPath = "",
renderForms = true,
l10n = NullL10n,
enableScripting = false,
hasJSActionsPromise = null,
fieldObjectsPromise = null,
annotationCanvasMap = null,
accessibilityManager = null,
}) {
return new AnnotationLayerBuilder({
pageDiv,
pdfPage,
imageResourcesPath,
renderForms,
linkService: new SimpleLinkService(),
l10n,
annotationStorage,
enableScripting,
hasJSActionsPromise,
fieldObjectsPromise,
annotationCanvasMap,
accessibilityManager,
});
}
}
/**
* @implements IPDFAnnotationEditorLayerFactory
*/
class DefaultAnnotationEditorLayerFactory {
/**
* @typedef {Object} CreateAnnotationEditorLayerBuilderParameters
* @property {AnnotationEditorUIManager} [uiManager]
* @property {HTMLDivElement} pageDiv
* @property {PDFPageProxy} pdfPage
* @property {IL10n} l10n
* @property {TextAccessibilityManager} [accessibilityManager]
*/
/**
* @param {CreateAnnotationEditorLayerBuilderParameters}
* @returns {AnnotationEditorLayerBuilder}
*/
createAnnotationEditorLayerBuilder({
uiManager = null,
pageDiv,
pdfPage,
accessibilityManager = null,
l10n,
}) {
return new AnnotationEditorLayerBuilder({
uiManager,
pageDiv,
pdfPage,
accessibilityManager,
l10n,
});
}
}
/**
* @implements IPDFStructTreeLayerFactory
*/
class DefaultStructTreeLayerFactory {
/**
* @returns {StructTreeLayerBuilder}
*/
createStructTreeLayerBuilder() {
return new StructTreeLayerBuilder();
}
}
/**
* @implements IPDFTextLayerFactory
*/
class DefaultTextLayerFactory {
/**
* @typedef {Object} CreateTextLayerBuilderParameters
* @property {TextHighlighter} highlighter
* @property {TextAccessibilityManager} [accessibilityManager]
* @property {boolean} [isOffscreenCanvasSupported]
*/
/**
* @param {CreateTextLayerBuilderParameters}
* @returns {TextLayerBuilder}
*/
createTextLayerBuilder({
highlighter,
accessibilityManager = null,
isOffscreenCanvasSupported = true,
}) {
return new TextLayerBuilder({
highlighter,
accessibilityManager,
isOffscreenCanvasSupported,
});
}
}
/**
* @implements IPDFXfaLayerFactory
*/
class DefaultXfaLayerFactory {
/**
* @typedef {Object} CreateXfaLayerBuilderParameters
* @property {HTMLDivElement} pageDiv
* @property {PDFPageProxy} pdfPage
* @property {AnnotationStorage} [annotationStorage] - Storage for annotation
* data in forms.
*/
/**
* @param {CreateXfaLayerBuilderParameters}
* @returns {XfaLayerBuilder}
*/
createXfaLayerBuilder({ pageDiv, pdfPage, annotationStorage = null }) {
return new XfaLayerBuilder({
pageDiv,
pdfPage,
annotationStorage,
linkService: new SimpleLinkService(),
});
}
}
export {
DefaultAnnotationEditorLayerFactory,
DefaultAnnotationLayerFactory,
DefaultStructTreeLayerFactory,
DefaultTextLayerFactory,
DefaultXfaLayerFactory,
};

View File

@ -17,19 +17,7 @@
/** @typedef {import("../src/display/api").PDFPageProxy} PDFPageProxy */ /** @typedef {import("../src/display/api").PDFPageProxy} PDFPageProxy */
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
/** @typedef {import("../src/display/display_utils").PageViewport} PageViewport */ /** @typedef {import("../src/display/display_utils").PageViewport} PageViewport */
// eslint-disable-next-line max-len
/** @typedef {import("./annotation_layer_builder").AnnotationLayerBuilder} AnnotationLayerBuilder */
// eslint-disable-next-line max-len
/** @typedef {import("./annotation_editor_layer_builder").AnnotationEditorLayerBuilder} AnnotationEditorLayerBuilder */
// eslint-disable-next-line max-len
/** @typedef {import("./struct_tree_builder").StructTreeLayerBuilder} StructTreeLayerBuilder */
/** @typedef {import("./text_highlighter").TextHighlighter} TextHighlighter */
// eslint-disable-next-line max-len
/** @typedef {import("./text_layer_builder").TextLayerBuilder} TextLayerBuilder */
/** @typedef {import("./ui_utils").RenderingStates} RenderingStates */ /** @typedef {import("./ui_utils").RenderingStates} RenderingStates */
/** @typedef {import("./xfa_layer_builder").XfaLayerBuilder} XfaLayerBuilder */
// eslint-disable-next-line max-len
/** @typedef {import("./text_accessibility.js").TextAccessibilityManager} TextAccessibilityManager */
/** /**
* @interface * @interface
@ -161,125 +149,6 @@ class IRenderableView {
draw() {} draw() {}
} }
/**
* @interface
*/
class IPDFTextLayerFactory {
/**
* @typedef {Object} CreateTextLayerBuilderParameters
* @property {TextHighlighter} highlighter
* @property {TextAccessibilityManager} [accessibilityManager]
* @property {boolean} [isOffscreenCanvasSupported]
*/
/**
* @param {CreateTextLayerBuilderParameters}
* @returns {TextLayerBuilder}
*/
createTextLayerBuilder({
highlighter,
accessibilityManager,
isOffscreenCanvasSupported,
}) {}
}
/**
* @interface
*/
class IPDFAnnotationLayerFactory {
/**
* @typedef {Object} CreateAnnotationLayerBuilderParameters
* @property {HTMLDivElement} pageDiv
* @property {PDFPageProxy} pdfPage
* @property {AnnotationStorage} [annotationStorage] - Storage for annotation
* data in forms.
* @property {string} [imageResourcesPath] - Path for image resources, mainly
* for annotation icons. Include trailing slash.
* @property {boolean} renderForms
* @property {IL10n} l10n
* @property {boolean} [enableScripting]
* @property {Promise<boolean>} [hasJSActionsPromise]
* @property {Promise<Object<string, Array<Object>> | null>}
* [fieldObjectsPromise]
* @property {Map<string, HTMLCanvasElement>} [annotationCanvasMap] - Map some
* annotation ids with canvases used to render them.
* @property {TextAccessibilityManager} [accessibilityManager]
*/
/**
* @param {CreateAnnotationLayerBuilderParameters}
* @returns {AnnotationLayerBuilder}
*/
createAnnotationLayerBuilder({
pageDiv,
pdfPage,
annotationStorage = null,
imageResourcesPath = "",
renderForms = true,
l10n = undefined,
enableScripting = false,
hasJSActionsPromise = null,
fieldObjectsPromise = null,
annotationCanvasMap = null,
accessibilityManager = null,
}) {}
}
/**
* @interface
*/
class IPDFAnnotationEditorLayerFactory {
/**
* @typedef {Object} CreateAnnotationEditorLayerBuilderParameters
* @property {AnnotationEditorUIManager} [uiManager]
* @property {HTMLDivElement} pageDiv
* @property {PDFPageProxy} pdfPage
* @property {IL10n} l10n
* @property {TextAccessibilityManager} [accessibilityManager]
*/
/**
* @param {CreateAnnotationEditorLayerBuilderParameters}
* @returns {AnnotationEditorLayerBuilder}
*/
createAnnotationEditorLayerBuilder({
uiManager = null,
pageDiv,
pdfPage,
l10n,
accessibilityManager,
}) {}
}
/**
* @interface
*/
class IPDFXfaLayerFactory {
/**
* @typedef {Object} CreateXfaLayerBuilderParameters
* @property {HTMLDivElement} pageDiv
* @property {PDFPageProxy} pdfPage
* @property {AnnotationStorage} [annotationStorage] - Storage for annotation
* data in forms.
*/
/**
* @param {CreateXfaLayerBuilderParameters}
* @returns {XfaLayerBuilder}
*/
createXfaLayerBuilder({ pageDiv, pdfPage, annotationStorage = null }) {}
}
/**
* @interface
*/
class IPDFStructTreeLayerFactory {
/**
* @returns {StructTreeLayerBuilder}
*/
createStructTreeLayerBuilder() {}
}
/** /**
* @interface * @interface
*/ */
@ -346,14 +215,4 @@ class IL10n {
async translate(element) {} async translate(element) {}
} }
export { export { IDownloadManager, IL10n, IPDFLinkService, IRenderableView };
IDownloadManager,
IL10n,
IPDFAnnotationEditorLayerFactory,
IPDFAnnotationLayerFactory,
IPDFLinkService,
IPDFStructTreeLayerFactory,
IPDFTextLayerFactory,
IPDFXfaLayerFactory,
IRenderableView,
};

View File

@ -19,15 +19,6 @@
/** @typedef {import("../src/display/optional_content_config").OptionalContentConfig} OptionalContentConfig */ /** @typedef {import("../src/display/optional_content_config").OptionalContentConfig} OptionalContentConfig */
/** @typedef {import("./event_utils").EventBus} EventBus */ /** @typedef {import("./event_utils").EventBus} EventBus */
/** @typedef {import("./interfaces").IL10n} IL10n */ /** @typedef {import("./interfaces").IL10n} IL10n */
// eslint-disable-next-line max-len
/** @typedef {import("./interfaces").IPDFAnnotationLayerFactory} IPDFAnnotationLayerFactory */
// eslint-disable-next-line max-len
/** @typedef {import("./interfaces").IPDFAnnotationEditorLayerFactory} IPDFAnnotationEditorLayerFactory */
// eslint-disable-next-line max-len
/** @typedef {import("./interfaces").IPDFStructTreeLayerFactory} IPDFStructTreeLayerFactory */
// eslint-disable-next-line max-len
/** @typedef {import("./interfaces").IPDFTextLayerFactory} IPDFTextLayerFactory */
/** @typedef {import("./interfaces").IPDFXfaLayerFactory} IPDFXfaLayerFactory */
/** @typedef {import("./interfaces").IRenderableView} IRenderableView */ /** @typedef {import("./interfaces").IRenderableView} IRenderableView */
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
/** @typedef {import("./pdf_rendering_queue").PDFRenderingQueue} PDFRenderingQueue */ /** @typedef {import("./pdf_rendering_queue").PDFRenderingQueue} PDFRenderingQueue */
@ -52,9 +43,16 @@ import {
roundToDivide, roundToDivide,
TextLayerMode, TextLayerMode,
} from "./ui_utils.js"; } from "./ui_utils.js";
import { AnnotationEditorLayerBuilder } from "./annotation_editor_layer_builder.js";
import { AnnotationLayerBuilder } from "./annotation_layer_builder.js";
import { compatibilityParams } from "./app_options.js"; import { compatibilityParams } from "./app_options.js";
import { NullL10n } from "./l10n_utils.js"; import { NullL10n } from "./l10n_utils.js";
import { SimpleLinkService } from "./pdf_link_service.js";
import { StructTreeLayerBuilder } from "./struct_tree_layer_builder.js";
import { TextAccessibilityManager } from "./text_accessibility.js"; import { TextAccessibilityManager } from "./text_accessibility.js";
import { TextHighlighter } from "./text_highlighter.js";
import { TextLayerBuilder } from "./text_layer_builder.js";
import { XfaLayerBuilder } from "./xfa_layer_builder.js";
/** /**
* @typedef {Object} PDFPageViewOptions * @typedef {Object} PDFPageViewOptions
@ -67,7 +65,6 @@ import { TextAccessibilityManager } from "./text_accessibility.js";
* A promise that is resolved with an {@link OptionalContentConfig} instance. * A promise that is resolved with an {@link OptionalContentConfig} instance.
* The default value is `null`. * The default value is `null`.
* @property {PDFRenderingQueue} [renderingQueue] - The rendering queue object. * @property {PDFRenderingQueue} [renderingQueue] - The rendering queue object.
* @property {IPDFTextLayerFactory} [textLayerFactory]
* @property {number} [textLayerMode] - Controls if the text layer used for * @property {number} [textLayerMode] - Controls if the text layer used for
* selection and searching is created. The constants from {TextLayerMode} * selection and searching is created. The constants from {TextLayerMode}
* should be used. The default value is `TextLayerMode.ENABLE`. * should be used. The default value is `TextLayerMode.ENABLE`.
@ -76,11 +73,6 @@ import { TextAccessibilityManager } from "./text_accessibility.js";
* being rendered. The constants from {@link AnnotationMode} should be used; * being rendered. The constants from {@link AnnotationMode} should be used;
* see also {@link RenderParameters} and {@link GetOperatorListParameters}. * see also {@link RenderParameters} and {@link GetOperatorListParameters}.
* The default value is `AnnotationMode.ENABLE_FORMS`. * The default value is `AnnotationMode.ENABLE_FORMS`.
* @property {IPDFAnnotationLayerFactory} [annotationLayerFactory]
* @property {IPDFAnnotationEditorLayerFactory} [annotationEditorLayerFactory]
* @property {IPDFXfaLayerFactory} [xfaLayerFactory]
* @property {IPDFStructTreeLayerFactory} [structTreeLayerFactory]
* @property {Object} [textHighlighterFactory]
* @property {string} [imageResourcesPath] - Path for image resources, mainly * @property {string} [imageResourcesPath] - Path for image resources, mainly
* for annotation icons. Include trailing slash. * for annotation icons. Include trailing slash.
* @property {boolean} [useOnlyCssZoom] - Enables CSS only zooming. The default * @property {boolean} [useOnlyCssZoom] - Enables CSS only zooming. The default
@ -94,16 +86,36 @@ import { TextAccessibilityManager } from "./text_accessibility.js";
* with user defined ones in order to improve readability in high contrast * with user defined ones in order to improve readability in high contrast
* mode. * mode.
* @property {IL10n} [l10n] - Localization service. * @property {IL10n} [l10n] - Localization service.
* @property {function} [layerProperties] - The function that is used to lookup
* the necessary layer-properties.
*/ */
const MAX_CANVAS_PIXELS = compatibilityParams.maxCanvasPixels || 16777216; const MAX_CANVAS_PIXELS = compatibilityParams.maxCanvasPixels || 16777216;
const DEFAULT_LAYER_PROPERTIES = () => {
if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("COMPONENTS")) {
return null;
}
return {
annotationEditorUIManager: null,
annotationStorage: null,
downloadManager: null,
enableScripting: false,
fieldObjectsPromise: null,
findController: null,
hasJSActionsPromise: null,
linkService: new SimpleLinkService(),
};
};
/** /**
* @implements {IRenderableView} * @implements {IRenderableView}
*/ */
class PDFPageView { class PDFPageView {
#annotationMode = AnnotationMode.ENABLE_FORMS; #annotationMode = AnnotationMode.ENABLE_FORMS;
#layerProperties = null;
#useThumbnailCanvas = { #useThumbnailCanvas = {
initialOptionalContent: true, initialOptionalContent: true,
regularAnnotations: true, regularAnnotations: true,
@ -118,6 +130,7 @@ class PDFPageView {
this.id = options.id; this.id = options.id;
this.renderingId = "page" + this.id; this.renderingId = "page" + this.id;
this.#layerProperties = options.layerProperties || DEFAULT_LAYER_PROPERTIES;
this.pdfPage = null; this.pdfPage = null;
this.pageLabel = null; this.pageLabel = null;
@ -140,12 +153,6 @@ class PDFPageView {
this.eventBus = options.eventBus; this.eventBus = options.eventBus;
this.renderingQueue = options.renderingQueue; this.renderingQueue = options.renderingQueue;
this.textLayerFactory = options.textLayerFactory;
this.annotationLayerFactory = options.annotationLayerFactory;
this.annotationEditorLayerFactory = options.annotationEditorLayerFactory;
this.xfaLayerFactory = options.xfaLayerFactory;
this._textHighlighterFactory = options.textHighlighterFactory;
this.structTreeLayerFactory = options.structTreeLayerFactory;
if ( if (
typeof PDFJSDev === "undefined" || typeof PDFJSDev === "undefined" ||
PDFJSDev.test("!PRODUCTION || GENERIC") PDFJSDev.test("!PRODUCTION || GENERIC")
@ -248,9 +255,10 @@ class PDFPageView {
return shadow( return shadow(
this, this,
"_textHighlighter", "_textHighlighter",
this._textHighlighterFactory?.createTextHighlighter({ new TextHighlighter({
pageIndex: this.id - 1, pageIndex: this.id - 1,
eventBus: this.eventBus, eventBus: this.eventBus,
findController: this.#layerProperties().findController,
}) })
); );
} }
@ -336,9 +344,7 @@ class PDFPageView {
error, error,
}); });
if (this.structTreeLayerFactory) { this.#renderStructTreeLayer();
this.#renderStructTreeLayer();
}
} }
/** /**
@ -352,8 +358,7 @@ class PDFPageView {
if (!this.textLayer) { if (!this.textLayer) {
return; return;
} }
this.structTreeLayer ||= this.structTreeLayer ||= new StructTreeLayerBuilder();
this.structTreeLayerFactory.createStructTreeLayerBuilder();
const tree = await (!this.structTreeLayer.renderingDone const tree = await (!this.structTreeLayer.renderingDone
? this.pdfPage.getStructTree() ? this.pdfPage.getStructTree()
@ -753,11 +758,11 @@ class PDFPageView {
if ( if (
!this.textLayer && !this.textLayer &&
this.textLayerMode !== TextLayerMode.DISABLE && this.textLayerMode !== TextLayerMode.DISABLE &&
this.textLayerFactory !pdfPage.isPureXfa
) { ) {
this._accessibilityManager ||= new TextAccessibilityManager(); this._accessibilityManager ||= new TextAccessibilityManager();
this.textLayer = this.textLayerFactory.createTextLayerBuilder({ this.textLayer = new TextLayerBuilder({
highlighter: this._textHighlighter, highlighter: this._textHighlighter,
accessibilityManager: this._accessibilityManager, accessibilityManager: this._accessibilityManager,
isOffscreenCanvasSupported: this.isOffscreenCanvasSupported, isOffscreenCanvasSupported: this.isOffscreenCanvasSupported,
@ -766,20 +771,34 @@ class PDFPageView {
} }
if ( if (
this.#annotationMode !== AnnotationMode.DISABLE && !this.annotationLayer &&
this.annotationLayerFactory this.#annotationMode !== AnnotationMode.DISABLE
) { ) {
const {
annotationStorage,
downloadManager,
enableScripting,
fieldObjectsPromise,
hasJSActionsPromise,
linkService,
} = this.#layerProperties();
this._annotationCanvasMap ||= new Map(); this._annotationCanvasMap ||= new Map();
this.annotationLayer ||= this.annotationLayer = new AnnotationLayerBuilder({
this.annotationLayerFactory.createAnnotationLayerBuilder({ pageDiv: div,
pageDiv: div, pdfPage,
pdfPage, annotationStorage,
imageResourcesPath: this.imageResourcesPath, imageResourcesPath: this.imageResourcesPath,
renderForms: this.#annotationMode === AnnotationMode.ENABLE_FORMS, renderForms: this.#annotationMode === AnnotationMode.ENABLE_FORMS,
l10n: this.l10n, linkService,
annotationCanvasMap: this._annotationCanvasMap, downloadManager,
accessibilityManager: this._accessibilityManager, l10n: this.l10n,
}); enableScripting,
hasJSActionsPromise,
fieldObjectsPromise,
annotationCanvasMap: this._annotationCanvasMap,
accessibilityManager: this._accessibilityManager,
});
} }
if (this.xfaLayer?.div) { if (this.xfaLayer?.div) {
@ -852,25 +871,28 @@ class PDFPageView {
const resultPromise = paintTask.promise.then( const resultPromise = paintTask.promise.then(
() => { () => {
return finishPaintTask(null).then(() => { return finishPaintTask(null).then(async () => {
this.#renderTextLayer(); this.#renderTextLayer();
if (this.annotationLayer) { if (this.annotationLayer) {
this.#renderAnnotationLayer().then(() => { await this.#renderAnnotationLayer();
if (this.annotationEditorLayerFactory) { }
this.annotationEditorLayer ||=
this.annotationEditorLayerFactory.createAnnotationEditorLayerBuilder( if (!this.annotationEditorLayer) {
{ const { annotationEditorUIManager } = this.#layerProperties();
pageDiv: div,
pdfPage, if (!annotationEditorUIManager) {
l10n: this.l10n, return;
accessibilityManager: this._accessibilityManager, }
} this.annotationEditorLayer = new AnnotationEditorLayerBuilder({
); uiManager: annotationEditorUIManager,
this.#renderAnnotationEditorLayer(); pageDiv: div,
} pdfPage,
l10n: this.l10n,
accessibilityManager: this._accessibilityManager,
}); });
} }
this.#renderAnnotationEditorLayer();
}); });
}, },
function (reason) { function (reason) {
@ -878,11 +900,17 @@ class PDFPageView {
} }
); );
if (this.xfaLayerFactory) { if (pdfPage.isPureXfa) {
this.xfaLayer ||= this.xfaLayerFactory.createXfaLayerBuilder({ if (!this.xfaLayer) {
pageDiv: div, const { annotationStorage, linkService } = this.#layerProperties();
pdfPage,
}); this.xfaLayer = new XfaLayerBuilder({
pageDiv: div,
pdfPage,
annotationStorage,
linkService,
});
}
this.#renderXfaLayer(); this.#renderXfaLayer();
} }

View File

@ -13,12 +13,6 @@
* limitations under the License. * limitations under the License.
*/ */
import {
DefaultAnnotationLayerFactory,
DefaultStructTreeLayerFactory,
DefaultTextLayerFactory,
DefaultXfaLayerFactory,
} from "./default_factory.js";
import { import {
LinkTarget, LinkTarget,
PDFLinkService, PDFLinkService,
@ -51,6 +45,45 @@ const pdfjsVersion = PDFJSDev.eval("BUNDLE_VERSION");
// eslint-disable-next-line no-unused-vars // eslint-disable-next-line no-unused-vars
const pdfjsBuild = PDFJSDev.eval("BUNDLE_BUILD"); const pdfjsBuild = PDFJSDev.eval("BUNDLE_BUILD");
class DefaultAnnotationLayerFactory {
constructor() {
throw new Error(
"The `DefaultAnnotationLayerFactory` has been removed, " +
"please use the `annotationMode` option when initializing " +
"the `PDFPageView`-instance to control AnnotationLayer rendering."
);
}
}
class DefaultStructTreeLayerFactory {
constructor() {
throw new Error(
"The `DefaultStructTreeLayerFactory` has been removed, " +
"this functionality is automatically enabled when the TextLayer is used."
);
}
}
class DefaultTextLayerFactory {
constructor() {
throw new Error(
"The `DefaultTextLayerFactory` has been removed, " +
"please use the `textLayerMode` option when initializing " +
"the `PDFPageView`-instance to control TextLayer rendering."
);
}
}
class DefaultXfaLayerFactory {
constructor() {
throw new Error(
"The `DefaultXfaLayerFactory` has been removed, " +
"please use the `enableXfa` option when calling " +
"the `getDocument`-function to control XfaLayer rendering."
);
}
}
export { export {
AnnotationLayerBuilder, AnnotationLayerBuilder,
DefaultAnnotationLayerFactory, DefaultAnnotationLayerFactory,

View File

@ -22,18 +22,7 @@
/** @typedef {import("./event_utils").EventBus} EventBus */ /** @typedef {import("./event_utils").EventBus} EventBus */
/** @typedef {import("./interfaces").IDownloadManager} IDownloadManager */ /** @typedef {import("./interfaces").IDownloadManager} IDownloadManager */
/** @typedef {import("./interfaces").IL10n} IL10n */ /** @typedef {import("./interfaces").IL10n} IL10n */
// eslint-disable-next-line max-len
/** @typedef {import("./interfaces").IPDFAnnotationLayerFactory} IPDFAnnotationLayerFactory */
// eslint-disable-next-line max-len
/** @typedef {import("./interfaces").IPDFAnnotationEditorLayerFactory} IPDFAnnotationEditorLayerFactory */
/** @typedef {import("./interfaces").IPDFLinkService} IPDFLinkService */ /** @typedef {import("./interfaces").IPDFLinkService} IPDFLinkService */
// eslint-disable-next-line max-len
/** @typedef {import("./interfaces").IPDFStructTreeLayerFactory} IPDFStructTreeLayerFactory */
// eslint-disable-next-line max-len
/** @typedef {import("./interfaces").IPDFTextLayerFactory} IPDFTextLayerFactory */
/** @typedef {import("./interfaces").IPDFXfaLayerFactory} IPDFXfaLayerFactory */
// eslint-disable-next-line max-len
/** @typedef {import("./text_accessibility.js").TextAccessibilityManager} TextAccessibilityManager */
import { import {
AnnotationEditorType, AnnotationEditorType,
@ -69,16 +58,10 @@ import {
VERTICAL_PADDING, VERTICAL_PADDING,
watchScroll, watchScroll,
} from "./ui_utils.js"; } from "./ui_utils.js";
import { AnnotationEditorLayerBuilder } from "./annotation_editor_layer_builder.js";
import { AnnotationLayerBuilder } from "./annotation_layer_builder.js";
import { NullL10n } from "./l10n_utils.js"; import { NullL10n } from "./l10n_utils.js";
import { PDFPageView } from "./pdf_page_view.js"; import { PDFPageView } from "./pdf_page_view.js";
import { PDFRenderingQueue } from "./pdf_rendering_queue.js"; import { PDFRenderingQueue } from "./pdf_rendering_queue.js";
import { SimpleLinkService } from "./pdf_link_service.js"; import { SimpleLinkService } from "./pdf_link_service.js";
import { StructTreeLayerBuilder } from "./struct_tree_layer_builder.js";
import { TextHighlighter } from "./text_highlighter.js";
import { TextLayerBuilder } from "./text_layer_builder.js";
import { XfaLayerBuilder } from "./xfa_layer_builder.js";
const DEFAULT_CACHE_SIZE = 10; const DEFAULT_CACHE_SIZE = 10;
const ENABLE_PERMISSIONS_CLASS = "enablePermissions"; const ENABLE_PERMISSIONS_CLASS = "enablePermissions";
@ -211,12 +194,6 @@ class PDFPageViewBuffer {
/** /**
* Simple viewer control to display PDF content/pages. * Simple viewer control to display PDF content/pages.
*
* @implements {IPDFAnnotationLayerFactory}
* @implements {IPDFAnnotationEditorLayerFactory}
* @implements {IPDFStructTreeLayerFactory}
* @implements {IPDFTextLayerFactory}
* @implements {IPDFXfaLayerFactory}
*/ */
class PDFViewer { class PDFViewer {
#buffer = null; #buffer = null;
@ -559,6 +536,36 @@ class PDFViewer {
return this.pdfDocument ? this._pagesCapability.promise : null; return this.pdfDocument ? this._pagesCapability.promise : null;
} }
#layerProperties() {
const self = this;
return {
get annotationEditorUIManager() {
return self.#annotationEditorUIManager;
},
get annotationStorage() {
return self.pdfDocument?.annotationStorage;
},
get downloadManager() {
return self.downloadManager;
},
get enableScripting() {
return !!self._scriptingManager;
},
get fieldObjectsPromise() {
return self.pdfDocument?.getFieldObjects();
},
get findController() {
return self.findController;
},
get hasJSActionsPromise() {
return self.pdfDocument?.hasJSActions();
},
get linkService() {
return self.linkService;
},
};
}
/** /**
* Currently only *some* permissions are supported. * Currently only *some* permissions are supported.
* @returns {Object} * @returns {Object}
@ -658,7 +665,6 @@ class PDFViewer {
if (!pdfDocument) { if (!pdfDocument) {
return; return;
} }
const isPureXfa = pdfDocument.isPureXfa;
const pagesCount = pdfDocument.numPages; const pagesCount = pdfDocument.numPages;
const firstPagePromise = pdfDocument.getPage(1); const firstPagePromise = pdfDocument.getPage(1);
// Rendering (potentially) depends on this, hence fetching it immediately. // Rendering (potentially) depends on this, hence fetching it immediately.
@ -732,13 +738,13 @@ class PDFViewer {
if (annotationEditorMode !== AnnotationEditorType.DISABLE) { if (annotationEditorMode !== AnnotationEditorType.DISABLE) {
const mode = annotationEditorMode; const mode = annotationEditorMode;
if (isPureXfa) { if (pdfDocument.isPureXfa) {
console.warn("Warning: XFA-editing is not implemented."); console.warn("Warning: XFA-editing is not implemented.");
} else if (isValidAnnotationEditorMode(mode)) { } else if (isValidAnnotationEditorMode(mode)) {
this.#annotationEditorUIManager = new AnnotationEditorUIManager( this.#annotationEditorUIManager = new AnnotationEditorUIManager(
this.container, this.container,
this.eventBus, this.eventBus,
this.pdfDocument?.annotationStorage pdfDocument?.annotationStorage
); );
if (mode !== AnnotationEditorType.NONE) { if (mode !== AnnotationEditorType.NONE) {
this.#annotationEditorUIManager.updateMode(mode); this.#annotationEditorUIManager.updateMode(mode);
@ -748,6 +754,7 @@ class PDFViewer {
} }
} }
const layerProperties = this.#layerProperties.bind(this);
const viewerElement = const viewerElement =
this._scrollMode === ScrollMode.PAGE ? null : this.viewer; this._scrollMode === ScrollMode.PAGE ? null : this.viewer;
const scale = this.currentScale; const scale = this.currentScale;
@ -758,15 +765,6 @@ class PDFViewer {
// see issue 15795. // see issue 15795.
docStyle.setProperty("--scale-factor", viewport.scale); docStyle.setProperty("--scale-factor", viewport.scale);
const textLayerFactory =
textLayerMode !== TextLayerMode.DISABLE && !isPureXfa ? this : null;
const annotationLayerFactory =
annotationMode !== AnnotationMode.DISABLE ? this : null;
const xfaLayerFactory = isPureXfa ? this : null;
const annotationEditorLayerFactory = this.#annotationEditorUIManager
? this
: null;
for (let pageNum = 1; pageNum <= pagesCount; ++pageNum) { for (let pageNum = 1; pageNum <= pagesCount; ++pageNum) {
const pageView = new PDFPageView({ const pageView = new PDFPageView({
container: viewerElement, container: viewerElement,
@ -776,14 +774,8 @@ class PDFViewer {
defaultViewport: viewport.clone(), defaultViewport: viewport.clone(),
optionalContentConfigPromise, optionalContentConfigPromise,
renderingQueue: this.renderingQueue, renderingQueue: this.renderingQueue,
textLayerFactory,
textLayerMode, textLayerMode,
annotationLayerFactory,
annotationMode, annotationMode,
xfaLayerFactory,
annotationEditorLayerFactory,
textHighlighterFactory: this,
structTreeLayerFactory: this,
imageResourcesPath: this.imageResourcesPath, imageResourcesPath: this.imageResourcesPath,
renderer: renderer:
typeof PDFJSDev === "undefined" || typeof PDFJSDev === "undefined" ||
@ -795,6 +787,7 @@ class PDFViewer {
maxCanvasPixels: this.maxCanvasPixels, maxCanvasPixels: this.maxCanvasPixels,
pageColors: this.pageColors, pageColors: this.pageColors,
l10n: this.l10n, l10n: this.l10n,
layerProperties,
}); });
this._pages.push(pageView); this._pages.push(pageView);
} }
@ -1656,161 +1649,6 @@ class PDFViewer {
return false; return false;
} }
/**
* @typedef {Object} CreateTextLayerBuilderParameters
* @property {TextHighlighter} highlighter
* @property {TextAccessibilityManager} [accessibilityManager]
* @property {boolean} [isOffscreenCanvasSupported]
*/
/**
* @param {CreateTextLayerBuilderParameters}
* @returns {TextLayerBuilder}
*/
createTextLayerBuilder({
highlighter,
accessibilityManager = null,
isOffscreenCanvasSupported = true,
}) {
return new TextLayerBuilder({
highlighter,
accessibilityManager,
isOffscreenCanvasSupported,
});
}
/**
* @typedef {Object} CreateTextHighlighterParameters
* @property {number} pageIndex
* @property {EventBus} eventBus
*/
/**
* @param {CreateTextHighlighterParameters}
* @returns {TextHighlighter}
*/
createTextHighlighter({ pageIndex, eventBus }) {
return new TextHighlighter({
eventBus,
pageIndex,
findController: this.findController,
});
}
/**
* @typedef {Object} CreateAnnotationLayerBuilderParameters
* @property {HTMLDivElement} pageDiv
* @property {PDFPageProxy} pdfPage
* @property {AnnotationStorage} [annotationStorage] - Storage for annotation
* data in forms.
* @property {string} [imageResourcesPath] - Path for image resources, mainly
* for annotation icons. Include trailing slash.
* @property {boolean} renderForms
* @property {IL10n} l10n
* @property {boolean} [enableScripting]
* @property {Promise<boolean>} [hasJSActionsPromise]
* @property {Promise<Object<string, Array<Object>> | null>}
* [fieldObjectsPromise]
* @property {Map<string, HTMLCanvasElement>} [annotationCanvasMap] - Map some
* annotation ids with canvases used to render them.
* @property {TextAccessibilityManager} [accessibilityManager]
*/
/**
* @param {CreateAnnotationLayerBuilderParameters}
* @returns {AnnotationLayerBuilder}
*/
createAnnotationLayerBuilder({
pageDiv,
pdfPage,
annotationStorage = this.pdfDocument?.annotationStorage,
imageResourcesPath = "",
renderForms = true,
l10n = NullL10n,
enableScripting = this.enableScripting,
hasJSActionsPromise = this.pdfDocument?.hasJSActions(),
fieldObjectsPromise = this.pdfDocument?.getFieldObjects(),
annotationCanvasMap = null,
accessibilityManager = null,
}) {
return new AnnotationLayerBuilder({
pageDiv,
pdfPage,
annotationStorage,
imageResourcesPath,
renderForms,
linkService: this.linkService,
downloadManager: this.downloadManager,
l10n,
enableScripting,
hasJSActionsPromise,
fieldObjectsPromise,
annotationCanvasMap,
accessibilityManager,
});
}
/**
* @typedef {Object} CreateAnnotationEditorLayerBuilderParameters
* @property {AnnotationEditorUIManager} [uiManager]
* @property {HTMLDivElement} pageDiv
* @property {PDFPageProxy} pdfPage
* @property {IL10n} l10n
* @property {TextAccessibilityManager} [accessibilityManager]
*/
/**
* @param {CreateAnnotationEditorLayerBuilderParameters}
* @returns {AnnotationEditorLayerBuilder}
*/
createAnnotationEditorLayerBuilder({
uiManager = this.#annotationEditorUIManager,
pageDiv,
pdfPage,
accessibilityManager = null,
l10n,
}) {
return new AnnotationEditorLayerBuilder({
uiManager,
pageDiv,
pdfPage,
accessibilityManager,
l10n,
});
}
/**
* @typedef {Object} CreateXfaLayerBuilderParameters
* @property {HTMLDivElement} pageDiv
* @property {PDFPageProxy} pdfPage
* @property {AnnotationStorage} [annotationStorage] - Storage for annotation
* data in forms.
*/
/**
* @param {CreateXfaLayerBuilderParameters}
* @returns {XfaLayerBuilder}
*/
createXfaLayerBuilder({
pageDiv,
pdfPage,
annotationStorage = this.pdfDocument?.annotationStorage,
}) {
return new XfaLayerBuilder({
pageDiv,
pdfPage,
annotationStorage,
linkService: this.linkService,
});
}
/**
* @returns {StructTreeLayerBuilder}
*/
createStructTreeLayerBuilder() {
return new StructTreeLayerBuilder();
}
/** /**
* @type {boolean} Whether all pages of the PDF document have identical * @type {boolean} Whether all pages of the PDF document have identical
* widths and heights. * widths and heights.