From 6e4d1f2846a91e57927cc039208f859efafd2119 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Fri, 23 Jul 2021 11:37:38 +0200 Subject: [PATCH] [api-minor] XFA - Remove the `xfaLayer` from the DOM when resetting pages (bug 1721977, PR 13427 follow-up) Originally the `xfaLayer` wasn't implemented in such a way that it supported being removed from the DOM when pages were evicted from the cache, however this limitation was lifted in PR 13427 and the `xfaLayer` should thus be handled similar to e.g. the `annotationLayer`. In addition to removing the `xfaLayer` from the DOM, this patch *also* implements proper rendering/hiding-handling for it (mirroring the `annotationLayer`-code). *Please note:* This patch is tagged API-minor just in case[1], since it changes the signatures of a couple of `PDFPageView`-methods to improve readability of the code. --- [1] Although users are *hopefully* not directly accessing any of the affected methods, and are rather using e.g. `PDFViewer` in which case none of these changes will matter. --- web/pdf_page_view.js | 76 +++++++++++++++++++++++++++++++------------- 1 file changed, 54 insertions(+), 22 deletions(-) diff --git a/web/pdf_page_view.js b/web/pdf_page_view.js index a5d5a138507bfb..e5b777fc2afa48 100644 --- a/web/pdf_page_view.js +++ b/web/pdf_page_view.js @@ -207,25 +207,29 @@ class PDFPageView { this.zoomLayer = null; } - reset(keepZoomLayer = false, keepAnnotations = false) { - this.cancelRendering(keepAnnotations); + reset({ + keepZoomLayer = false, + keepAnnotationLayer = false, + keepXfaLayer = false, + } = {}) { + this.cancelRendering({ keepAnnotationLayer, keepXfaLayer }); this.renderingState = RenderingStates.INITIAL; const div = this.div; div.style.width = Math.floor(this.viewport.width) + "px"; div.style.height = Math.floor(this.viewport.height) + "px"; - const childNodes = div.childNodes; - const currentZoomLayerNode = (keepZoomLayer && this.zoomLayer) || null; - const currentAnnotationNode = - (keepAnnotations && this.annotationLayer?.div) || null; - const currentXfaLayerNode = this.xfaLayer?.div || null; + const childNodes = div.childNodes, + zoomLayerNode = (keepZoomLayer && this.zoomLayer) || null, + annotationLayerNode = + (keepAnnotationLayer && this.annotationLayer?.div) || null, + xfaLayerNode = (keepXfaLayer && this.xfaLayer?.div) || null; for (let i = childNodes.length - 1; i >= 0; i--) { const node = childNodes[i]; if ( - currentZoomLayerNode === node || - currentAnnotationNode === node || - currentXfaLayerNode === node + zoomLayerNode === node || + annotationLayerNode === node || + xfaLayerNode === node ) { continue; } @@ -233,7 +237,7 @@ class PDFPageView { } div.removeAttribute("data-loaded"); - if (currentAnnotationNode) { + if (annotationLayerNode) { // Hide the annotation layer until all elements are resized // so they are not displayed on the already resized page. this.annotationLayer.hide(); @@ -242,7 +246,16 @@ class PDFPageView { this.annotationLayer = null; } - if (!currentZoomLayerNode) { + if (xfaLayerNode) { + // Hide the XFA layer until all elements are resized + // so they are not displayed on the already resized page. + this.xfaLayer.hide(); + } else if (this.xfaLayer) { + this.xfaLayer.cancel(); + this.xfaLayer = null; + } + + if (!zoomLayerNode) { if (this.canvas) { this.paintedViewportMap.delete(this.canvas); // Zeroing the width and height causes Firefox to release graphics @@ -284,7 +297,11 @@ class PDFPageView { }); if (this.svg) { - this.cssTransform(this.svg, true); + this.cssTransform({ + target: this.svg, + redrawAnnotationLayer: true, + redrawXfaLayer: true, + }); this.eventBus.dispatch("pagerendered", { source: this, @@ -313,7 +330,11 @@ class PDFPageView { this.useOnlyCssZoom || (this.hasRestrictedScaling && isScalingRestricted) ) { - this.cssTransform(this.canvas, true); + this.cssTransform({ + target: this.canvas, + redrawAnnotationLayer: true, + redrawXfaLayer: true, + }); this.eventBus.dispatch("pagerendered", { source: this, @@ -330,16 +351,20 @@ class PDFPageView { } } if (this.zoomLayer) { - this.cssTransform(this.zoomLayer.firstChild); + this.cssTransform({ target: this.zoomLayer.firstChild }); } - this.reset(/* keepZoomLayer = */ true, /* keepAnnotations = */ true); + this.reset({ + keepZoomLayer: true, + keepAnnotationLayer: true, + keepXfaLayer: true, + }); } /** * PLEASE NOTE: Most likely you want to use the `this.reset()` method, * rather than calling this one directly. */ - cancelRendering(keepAnnotations = false) { + cancelRendering({ keepAnnotationLayer = false, keepXfaLayer = false } = {}) { if (this.paintTask) { this.paintTask.cancel(); this.paintTask = null; @@ -350,17 +375,25 @@ class PDFPageView { this.textLayer.cancel(); this.textLayer = null; } - if (!keepAnnotations && this.annotationLayer) { + if (!keepAnnotationLayer && this.annotationLayer) { this.annotationLayer.cancel(); this.annotationLayer = null; } + if (!keepXfaLayer && this.xfaLayer) { + this.xfaLayer.cancel(); + this.xfaLayer = null; + } if (this._onTextLayerRendered) { this.eventBus._off("textlayerrendered", this._onTextLayerRendered); this._onTextLayerRendered = null; } } - cssTransform(target, redrawAnnotations = false) { + cssTransform({ + target, + redrawAnnotationLayer = false, + redrawXfaLayer = false, + }) { // Scale target (canvas or svg), its wrapper and page container. const width = this.viewport.width; const height = this.viewport.height; @@ -429,11 +462,10 @@ class PDFPageView { textLayerDiv.style.transformOrigin = "0% 0%"; } - if (redrawAnnotations && this.annotationLayer) { + if (redrawAnnotationLayer && this.annotationLayer) { this._renderAnnotationLayer(); } - - if (this.xfaLayer) { + if (redrawXfaLayer && this.xfaLayer) { this._renderXfaLayer(); } }