diff --git a/src/display/annotation_layer.js b/src/display/annotation_layer.js index a5928dbaa..600e4199c 100644 --- a/src/display/annotation_layer.js +++ b/src/display/annotation_layer.js @@ -2597,13 +2597,25 @@ class FileAttachmentAnnotationElement extends AnnotationElement { */ class AnnotationLayer { - static #appendElement(element, id, div, accessibilityManager) { + #accessibilityManager = null; + + #annotationCanvasMap = null; + + #div = null; + + constructor({ div, accessibilityManager, annotationCanvasMap }) { + this.#div = div; + this.#accessibilityManager = accessibilityManager; + this.#annotationCanvasMap = annotationCanvasMap; + } + + #appendElement(element, id) { const contentElement = element.firstChild || element; contentElement.id = `${AnnotationPrefix}${id}`; - div.append(element); - accessibilityManager?.moveElementInDOM( - div, + this.#div.append(element); + this.#accessibilityManager?.moveElementInDOM( + this.#div, element, contentElement, /* isRemovable = */ false @@ -2616,13 +2628,14 @@ class AnnotationLayer { * @param {AnnotationLayerParameters} params * @memberof AnnotationLayer */ - static render(params) { - const { annotations, div, viewport, accessibilityManager } = params; - setLayerDimensions(div, viewport); + render(params) { + const { annotations, viewport } = params; + const layer = this.#div; + setLayerDimensions(layer, viewport); const elementParams = { data: null, - layer: div, + layer, page: params.page, viewport, linkService: params.linkService, @@ -2660,12 +2673,7 @@ class AnnotationLayer { if (Array.isArray(rendered)) { for (const renderedElement of rendered) { renderedElement.style.zIndex = zIndex++; - AnnotationLayer.#appendElement( - renderedElement, - data.id, - div, - accessibilityManager - ); + this.#appendElement(renderedElement, data.id); } } else { // The accessibility manager will move the annotation in the DOM in @@ -2678,41 +2686,37 @@ class AnnotationLayer { if (element instanceof PopupAnnotationElement) { // Popup annotation elements should not be on top of other // annotation elements to prevent interfering with mouse events. - div.prepend(rendered); + layer.prepend(rendered); } else { - AnnotationLayer.#appendElement( - rendered, - data.id, - div, - accessibilityManager - ); + this.#appendElement(rendered, data.id); } } } - this.#setAnnotationCanvasMap(div, params.annotationCanvasMap); + this.#setAnnotationCanvasMap(); } /** * Update the annotation elements on existing annotation layer. * - * @param {AnnotationLayerParameters} params + * @param {AnnotationLayerParameters} viewport * @memberof AnnotationLayer */ - static update(params) { - const { annotationCanvasMap, div, viewport } = params; - setLayerDimensions(div, { rotation: viewport.rotation }); + update({ viewport }) { + const layer = this.#div; + setLayerDimensions(layer, { rotation: viewport.rotation }); - this.#setAnnotationCanvasMap(div, annotationCanvasMap); - div.hidden = false; + this.#setAnnotationCanvasMap(); + layer.hidden = false; } - static #setAnnotationCanvasMap(div, annotationCanvasMap) { - if (!annotationCanvasMap) { + #setAnnotationCanvasMap() { + if (!this.#annotationCanvasMap) { return; } - for (const [id, canvas] of annotationCanvasMap) { - const element = div.querySelector(`[data-annotation-id="${id}"]`); + const layer = this.#div; + for (const [id, canvas] of this.#annotationCanvasMap) { + const element = layer.querySelector(`[data-annotation-id="${id}"]`); if (!element) { continue; } @@ -2726,7 +2730,7 @@ class AnnotationLayer { firstChild.before(canvas); } } - annotationCanvasMap.clear(); + this.#annotationCanvasMap.clear(); } } diff --git a/test/driver.js b/test/driver.js index 3d88918b7..ab52b13fb 100644 --- a/test/driver.js +++ b/test/driver.js @@ -224,15 +224,17 @@ class Rasterize { // Rendering annotation layer as HTML. const parameters = { viewport: annotationViewport, - div, annotations, page, linkService: new SimpleLinkService(), imageResourcesPath, renderForms, - annotationCanvasMap: annotationImageMap, }; - AnnotationLayer.render(parameters); + const annotationLayer = new AnnotationLayer({ + div, + annotationCanvasMap: annotationImageMap, + }); + annotationLayer.render(parameters); await l10n.translate(div); // Inline SVG images from text annotations. diff --git a/web/annotation_layer_builder.js b/web/annotation_layer_builder.js index 9d7e1b10d..a0fb1ce52 100644 --- a/web/annotation_layer_builder.js +++ b/web/annotation_layer_builder.js @@ -46,8 +46,6 @@ import { PresentationModeState } from "./ui_utils.js"; */ class AnnotationLayerBuilder { - #numAnnotations = 0; - #onPresentationModeChanged = null; /** @@ -82,6 +80,7 @@ class AnnotationLayerBuilder { this._annotationCanvasMap = annotationCanvasMap; this._accessibilityManager = accessibilityManager; + this.annotationLayer = null; this.div = null; this._cancelled = false; this._eventBus = linkService.eventBus; @@ -95,15 +94,13 @@ class AnnotationLayerBuilder { */ async render(viewport, intent = "display") { if (this.div) { - if (this._cancelled || this.#numAnnotations === 0) { + if (this._cancelled || !this.annotationLayer) { return; } // If an annotationLayer already exists, refresh its children's // transformation matrices. - AnnotationLayer.update({ + this.annotationLayer.update({ viewport: viewport.clone({ dontFlip: true }), - div: this.div, - annotationCanvasMap: this._annotationCanvasMap, }); return; } @@ -116,21 +113,26 @@ class AnnotationLayerBuilder { if (this._cancelled) { return; } - this.#numAnnotations = annotations.length; // Create an annotation layer div and render the annotations // if there is at least one annotation. - this.div = document.createElement("div"); - this.div.className = "annotationLayer"; - this.pageDiv.append(this.div); + const div = (this.div = document.createElement("div")); + div.className = "annotationLayer"; + this.pageDiv.append(div); - if (this.#numAnnotations === 0) { + if (annotations.length === 0) { this.hide(); return; } - AnnotationLayer.render({ + + this.annotationLayer = new AnnotationLayer({ + div, + accessibilityManager: this._accessibilityManager, + annotationCanvasMap: this._annotationCanvasMap, + }); + + this.annotationLayer.render({ viewport: viewport.clone({ dontFlip: true }), - div: this.div, annotations, page: this.pdfPage, imageResourcesPath: this.imageResourcesPath, @@ -141,10 +143,8 @@ class AnnotationLayerBuilder { enableScripting: this.enableScripting, hasJSActions, fieldObjects, - annotationCanvasMap: this._annotationCanvasMap, - accessibilityManager: this._accessibilityManager, }); - this.l10n.translate(this.div); + this.l10n.translate(div); // Ensure that interactive form elements in the annotationLayer are // disabled while PresentationMode is active (see issue 12232).