Merge pull request #15812 from calixteman/refactor_zoom
Only redraw after zooming is finished (bug 1661253)
This commit is contained in:
		
						commit
						e49dd525b0
					
				@ -28,6 +28,12 @@
 | 
				
			|||||||
      ],
 | 
					      ],
 | 
				
			||||||
      "default": 0
 | 
					      "default": 0
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "defaultZoomDelay": {
 | 
				
			||||||
 | 
					      "title": "Default zoom delay",
 | 
				
			||||||
 | 
					      "description": "Delay (in ms) to wait before redrawing the canvas.",
 | 
				
			||||||
 | 
					      "type": "integer",
 | 
				
			||||||
 | 
					      "default": 400
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "defaultZoomValue": {
 | 
					    "defaultZoomValue": {
 | 
				
			||||||
      "title": "Default zoom level",
 | 
					      "title": "Default zoom level",
 | 
				
			||||||
      "description": "Default zoom level of the viewer. Accepted values: 'auto', 'page-actual', 'page-width', 'page-height', 'page-fit', or a zoom level in percents.",
 | 
					      "description": "Default zoom level of the viewer. Accepted values: 'auto', 'page-actual', 'page-width', 'page-height', 'page-fit', or a zoom level in percents.",
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										12
									
								
								web/app.js
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								web/app.js
									
									
									
									
									
								
							@ -655,14 +655,18 @@ const PDFViewerApplication = {
 | 
				
			|||||||
    if (this.pdfViewer.isInPresentationMode) {
 | 
					    if (this.pdfViewer.isInPresentationMode) {
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    this.pdfViewer.increaseScale(steps);
 | 
					    this.pdfViewer.increaseScale(steps, {
 | 
				
			||||||
 | 
					      delay: AppOptions.get("defaultZoomDelay"),
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  zoomOut(steps) {
 | 
					  zoomOut(steps) {
 | 
				
			||||||
    if (this.pdfViewer.isInPresentationMode) {
 | 
					    if (this.pdfViewer.isInPresentationMode) {
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    this.pdfViewer.decreaseScale(steps);
 | 
					    this.pdfViewer.decreaseScale(steps, {
 | 
				
			||||||
 | 
					      delay: AppOptions.get("defaultZoomDelay"),
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  zoomReset() {
 | 
					  zoomReset() {
 | 
				
			||||||
@ -2019,9 +2023,7 @@ const PDFViewerApplication = {
 | 
				
			|||||||
      this._wheelUnusedTicks = 0;
 | 
					      this._wheelUnusedTicks = 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    this._wheelUnusedTicks += ticks;
 | 
					    this._wheelUnusedTicks += ticks;
 | 
				
			||||||
    const wholeTicks =
 | 
					    const wholeTicks = Math.trunc(this._wheelUnusedTicks);
 | 
				
			||||||
      Math.sign(this._wheelUnusedTicks) *
 | 
					 | 
				
			||||||
      Math.floor(Math.abs(this._wheelUnusedTicks));
 | 
					 | 
				
			||||||
    this._wheelUnusedTicks -= wholeTicks;
 | 
					    this._wheelUnusedTicks -= wholeTicks;
 | 
				
			||||||
    return wholeTicks;
 | 
					    return wholeTicks;
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
				
			|||||||
@ -68,6 +68,12 @@ const defaultOptions = {
 | 
				
			|||||||
    value: 0,
 | 
					    value: 0,
 | 
				
			||||||
    kind: OptionKind.VIEWER + OptionKind.PREFERENCE,
 | 
					    kind: OptionKind.VIEWER + OptionKind.PREFERENCE,
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					  defaultZoomDelay: {
 | 
				
			||||||
 | 
					    /** @type {number} */
 | 
				
			||||||
 | 
					    value:
 | 
				
			||||||
 | 
					      typeof PDFJSDev === "undefined" || !PDFJSDev.test("GENERIC") ? 400 : -1,
 | 
				
			||||||
 | 
					    kind: OptionKind.VIEWER + OptionKind.PREFERENCE,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
  defaultZoomValue: {
 | 
					  defaultZoomValue: {
 | 
				
			||||||
    /** @type {string} */
 | 
					    /** @type {string} */
 | 
				
			||||||
    value: "",
 | 
					    value: "",
 | 
				
			||||||
 | 
				
			|||||||
@ -118,6 +118,8 @@ class PDFPageView {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  #layerProperties = null;
 | 
					  #layerProperties = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  #previousRotation = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  #useThumbnailCanvas = {
 | 
					  #useThumbnailCanvas = {
 | 
				
			||||||
    initialOptionalContent: true,
 | 
					    initialOptionalContent: true,
 | 
				
			||||||
    regularAnnotations: true,
 | 
					    regularAnnotations: true,
 | 
				
			||||||
@ -227,9 +229,14 @@ class PDFPageView {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  #setDimensions() {
 | 
					  #setDimensions() {
 | 
				
			||||||
    const { div, viewport } = this;
 | 
					    const { viewport } = this;
 | 
				
			||||||
 | 
					    if (this.#previousRotation === viewport.rotation) {
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    this.#previousRotation = viewport.rotation;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    setLayerDimensions(
 | 
					    setLayerDimensions(
 | 
				
			||||||
      div,
 | 
					      this.div,
 | 
				
			||||||
      viewport,
 | 
					      viewport,
 | 
				
			||||||
      /* mustFlip = */ true,
 | 
					      /* mustFlip = */ true,
 | 
				
			||||||
      /* mustRotate = */ false
 | 
					      /* mustRotate = */ false
 | 
				
			||||||
@ -245,6 +252,7 @@ class PDFPageView {
 | 
				
			|||||||
      scale: this.scale * PixelsPerInch.PDF_TO_CSS_UNITS,
 | 
					      scale: this.scale * PixelsPerInch.PDF_TO_CSS_UNITS,
 | 
				
			||||||
      rotation: totalRotation,
 | 
					      rotation: totalRotation,
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					    this.#setDimensions();
 | 
				
			||||||
    this.reset();
 | 
					    this.reset();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -417,7 +425,6 @@ class PDFPageView {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
    this.renderingState = RenderingStates.INITIAL;
 | 
					    this.renderingState = RenderingStates.INITIAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.#setDimensions();
 | 
					 | 
				
			||||||
    const div = this.div;
 | 
					    const div = this.div;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const childNodes = div.childNodes,
 | 
					    const childNodes = div.childNodes,
 | 
				
			||||||
@ -502,7 +509,12 @@ class PDFPageView {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  update({ scale = 0, rotation = null, optionalContentConfigPromise = null }) {
 | 
					  update({
 | 
				
			||||||
 | 
					    scale = 0,
 | 
				
			||||||
 | 
					    rotation = null,
 | 
				
			||||||
 | 
					    optionalContentConfigPromise = null,
 | 
				
			||||||
 | 
					    drawingDelay = -1,
 | 
				
			||||||
 | 
					  }) {
 | 
				
			||||||
    this.scale = scale || this.scale;
 | 
					    this.scale = scale || this.scale;
 | 
				
			||||||
    if (typeof rotation === "number") {
 | 
					    if (typeof rotation === "number") {
 | 
				
			||||||
      this.rotation = rotation; // The rotation may be zero.
 | 
					      this.rotation = rotation; // The rotation may be zero.
 | 
				
			||||||
@ -528,6 +540,7 @@ class PDFPageView {
 | 
				
			|||||||
      scale: this.scale * PixelsPerInch.PDF_TO_CSS_UNITS,
 | 
					      scale: this.scale * PixelsPerInch.PDF_TO_CSS_UNITS,
 | 
				
			||||||
      rotation: totalRotation,
 | 
					      rotation: totalRotation,
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					    this.#setDimensions();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (
 | 
					    if (
 | 
				
			||||||
      (typeof PDFJSDev === "undefined" ||
 | 
					      (typeof PDFJSDev === "undefined" ||
 | 
				
			||||||
@ -572,17 +585,40 @@ class PDFPageView {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const postponeDrawing = drawingDelay >= 0 && drawingDelay < 1000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (this.canvas) {
 | 
					    if (this.canvas) {
 | 
				
			||||||
      if (
 | 
					      if (
 | 
				
			||||||
 | 
					        postponeDrawing ||
 | 
				
			||||||
        this.useOnlyCssZoom ||
 | 
					        this.useOnlyCssZoom ||
 | 
				
			||||||
        (this.hasRestrictedScaling && isScalingRestricted)
 | 
					        (this.hasRestrictedScaling && isScalingRestricted)
 | 
				
			||||||
      ) {
 | 
					      ) {
 | 
				
			||||||
 | 
					        if (
 | 
				
			||||||
 | 
					          postponeDrawing &&
 | 
				
			||||||
 | 
					          this.renderingState !== RenderingStates.FINISHED
 | 
				
			||||||
 | 
					        ) {
 | 
				
			||||||
 | 
					          this.cancelRendering({
 | 
				
			||||||
 | 
					            keepZoomLayer: true,
 | 
				
			||||||
 | 
					            keepAnnotationLayer: true,
 | 
				
			||||||
 | 
					            keepAnnotationEditorLayer: true,
 | 
				
			||||||
 | 
					            keepXfaLayer: true,
 | 
				
			||||||
 | 
					            keepTextLayer: true,
 | 
				
			||||||
 | 
					            cancelExtraDelay: drawingDelay,
 | 
				
			||||||
 | 
					          });
 | 
				
			||||||
 | 
					          // It isn't really finished, but once we have finished
 | 
				
			||||||
 | 
					          // to postpone, we'll call this.reset(...) which will set
 | 
				
			||||||
 | 
					          // the rendering state to INITIAL, hence the next call to
 | 
				
			||||||
 | 
					          // PDFViewer.update() will trigger a redraw (if it's mandatory).
 | 
				
			||||||
 | 
					          this.renderingState = RenderingStates.FINISHED;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.cssTransform({
 | 
					        this.cssTransform({
 | 
				
			||||||
          target: this.canvas,
 | 
					          target: this.canvas,
 | 
				
			||||||
          redrawAnnotationLayer: true,
 | 
					          redrawAnnotationLayer: true,
 | 
				
			||||||
          redrawAnnotationEditorLayer: true,
 | 
					          redrawAnnotationEditorLayer: true,
 | 
				
			||||||
          redrawXfaLayer: true,
 | 
					          redrawXfaLayer: true,
 | 
				
			||||||
          redrawTextLayer: true,
 | 
					          redrawTextLayer: !postponeDrawing,
 | 
				
			||||||
 | 
					          hideTextLayer: postponeDrawing,
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.eventBus.dispatch("pagerendered", {
 | 
					        this.eventBus.dispatch("pagerendered", {
 | 
				
			||||||
@ -620,9 +656,10 @@ class PDFPageView {
 | 
				
			|||||||
    keepAnnotationEditorLayer = false,
 | 
					    keepAnnotationEditorLayer = false,
 | 
				
			||||||
    keepXfaLayer = false,
 | 
					    keepXfaLayer = false,
 | 
				
			||||||
    keepTextLayer = false,
 | 
					    keepTextLayer = false,
 | 
				
			||||||
 | 
					    cancelExtraDelay = 0,
 | 
				
			||||||
  } = {}) {
 | 
					  } = {}) {
 | 
				
			||||||
    if (this.paintTask) {
 | 
					    if (this.paintTask) {
 | 
				
			||||||
      this.paintTask.cancel();
 | 
					      this.paintTask.cancel(cancelExtraDelay);
 | 
				
			||||||
      this.paintTask = null;
 | 
					      this.paintTask = null;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    this.resume = null;
 | 
					    this.resume = null;
 | 
				
			||||||
@ -662,11 +699,20 @@ class PDFPageView {
 | 
				
			|||||||
    redrawAnnotationEditorLayer = false,
 | 
					    redrawAnnotationEditorLayer = false,
 | 
				
			||||||
    redrawXfaLayer = false,
 | 
					    redrawXfaLayer = false,
 | 
				
			||||||
    redrawTextLayer = false,
 | 
					    redrawTextLayer = false,
 | 
				
			||||||
 | 
					    hideTextLayer = false,
 | 
				
			||||||
  }) {
 | 
					  }) {
 | 
				
			||||||
    // Scale target (canvas or svg), its wrapper and page container.
 | 
					    // Scale target (canvas or svg), its wrapper and page container.
 | 
				
			||||||
    const width = this.viewport.width;
 | 
					
 | 
				
			||||||
    const height = this.viewport.height;
 | 
					    if (target instanceof HTMLCanvasElement) {
 | 
				
			||||||
 | 
					      if (!target.hasAttribute("zooming")) {
 | 
				
			||||||
 | 
					        target.setAttribute("zooming", true);
 | 
				
			||||||
 | 
					        const { style } = target;
 | 
				
			||||||
 | 
					        style.width = style.height = "";
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
      const div = this.div;
 | 
					      const div = this.div;
 | 
				
			||||||
 | 
					      const { width, height } = this.viewport;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      target.style.width =
 | 
					      target.style.width =
 | 
				
			||||||
        target.parentNode.style.width =
 | 
					        target.parentNode.style.width =
 | 
				
			||||||
        div.style.width =
 | 
					        div.style.width =
 | 
				
			||||||
@ -675,18 +721,27 @@ class PDFPageView {
 | 
				
			|||||||
        target.parentNode.style.height =
 | 
					        target.parentNode.style.height =
 | 
				
			||||||
        div.style.height =
 | 
					        div.style.height =
 | 
				
			||||||
          Math.floor(height) + "px";
 | 
					          Math.floor(height) + "px";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const originalViewport = this.paintedViewportMap.get(target);
 | 
				
			||||||
 | 
					    if (this.viewport !== originalViewport) {
 | 
				
			||||||
      // The canvas may have been originally rotated; rotate relative to that.
 | 
					      // The canvas may have been originally rotated; rotate relative to that.
 | 
				
			||||||
      const relativeRotation =
 | 
					      const relativeRotation =
 | 
				
			||||||
      this.viewport.rotation - this.paintedViewportMap.get(target).rotation;
 | 
					        this.viewport.rotation - originalViewport.rotation;
 | 
				
			||||||
      const absRotation = Math.abs(relativeRotation);
 | 
					      const absRotation = Math.abs(relativeRotation);
 | 
				
			||||||
      let scaleX = 1,
 | 
					      let scaleX = 1,
 | 
				
			||||||
        scaleY = 1;
 | 
					        scaleY = 1;
 | 
				
			||||||
      if (absRotation === 90 || absRotation === 270) {
 | 
					      if (absRotation === 90 || absRotation === 270) {
 | 
				
			||||||
 | 
					        const { width, height } = this.viewport;
 | 
				
			||||||
        // Scale x and y because of the rotation.
 | 
					        // Scale x and y because of the rotation.
 | 
				
			||||||
        scaleX = height / width;
 | 
					        scaleX = height / width;
 | 
				
			||||||
        scaleY = width / height;
 | 
					        scaleY = width / height;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (absRotation !== 0) {
 | 
				
			||||||
        target.style.transform = `rotate(${relativeRotation}deg) scale(${scaleX}, ${scaleY})`;
 | 
					        target.style.transform = `rotate(${relativeRotation}deg) scale(${scaleX}, ${scaleY})`;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (redrawAnnotationLayer && this.annotationLayer) {
 | 
					    if (redrawAnnotationLayer && this.annotationLayer) {
 | 
				
			||||||
      this.#renderAnnotationLayer();
 | 
					      this.#renderAnnotationLayer();
 | 
				
			||||||
@ -697,10 +752,15 @@ class PDFPageView {
 | 
				
			|||||||
    if (redrawXfaLayer && this.xfaLayer) {
 | 
					    if (redrawXfaLayer && this.xfaLayer) {
 | 
				
			||||||
      this.#renderXfaLayer();
 | 
					      this.#renderXfaLayer();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (redrawTextLayer && this.textLayer) {
 | 
					
 | 
				
			||||||
 | 
					    if (this.textLayer) {
 | 
				
			||||||
 | 
					      if (hideTextLayer) {
 | 
				
			||||||
 | 
					        this.textLayer.hide();
 | 
				
			||||||
 | 
					      } else if (redrawTextLayer) {
 | 
				
			||||||
        this.#renderTextLayer();
 | 
					        this.#renderTextLayer();
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  get width() {
 | 
					  get width() {
 | 
				
			||||||
    return this.viewport.width;
 | 
					    return this.viewport.width;
 | 
				
			||||||
@ -933,8 +993,8 @@ class PDFPageView {
 | 
				
			|||||||
      onRenderContinue(cont) {
 | 
					      onRenderContinue(cont) {
 | 
				
			||||||
        cont();
 | 
					        cont();
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      cancel() {
 | 
					      cancel(extraDelay = 0) {
 | 
				
			||||||
        renderTask.cancel();
 | 
					        renderTask.cancel(extraDelay);
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      get separateAnnots() {
 | 
					      get separateAnnots() {
 | 
				
			||||||
        return renderTask.separateAnnots;
 | 
					        return renderTask.separateAnnots;
 | 
				
			||||||
@ -942,6 +1002,7 @@ class PDFPageView {
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const viewport = this.viewport;
 | 
					    const viewport = this.viewport;
 | 
				
			||||||
 | 
					    const { width, height } = viewport;
 | 
				
			||||||
    const canvas = document.createElement("canvas");
 | 
					    const canvas = document.createElement("canvas");
 | 
				
			||||||
    canvas.setAttribute("role", "presentation");
 | 
					    canvas.setAttribute("role", "presentation");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -968,12 +1029,12 @@ class PDFPageView {
 | 
				
			|||||||
      });
 | 
					      });
 | 
				
			||||||
      // Use a scale that makes the canvas have the originally intended size
 | 
					      // Use a scale that makes the canvas have the originally intended size
 | 
				
			||||||
      // of the page.
 | 
					      // of the page.
 | 
				
			||||||
      outputScale.sx *= actualSizeViewport.width / viewport.width;
 | 
					      outputScale.sx *= actualSizeViewport.width / width;
 | 
				
			||||||
      outputScale.sy *= actualSizeViewport.height / viewport.height;
 | 
					      outputScale.sy *= actualSizeViewport.height / height;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (this.maxCanvasPixels > 0) {
 | 
					    if (this.maxCanvasPixels > 0) {
 | 
				
			||||||
      const pixelsInViewport = viewport.width * viewport.height;
 | 
					      const pixelsInViewport = width * height;
 | 
				
			||||||
      const maxScale = Math.sqrt(this.maxCanvasPixels / pixelsInViewport);
 | 
					      const maxScale = Math.sqrt(this.maxCanvasPixels / pixelsInViewport);
 | 
				
			||||||
      if (outputScale.sx > maxScale || outputScale.sy > maxScale) {
 | 
					      if (outputScale.sx > maxScale || outputScale.sy > maxScale) {
 | 
				
			||||||
        outputScale.sx = maxScale;
 | 
					        outputScale.sx = maxScale;
 | 
				
			||||||
@ -1003,7 +1064,7 @@ class PDFPageView {
 | 
				
			|||||||
    const renderContext = {
 | 
					    const renderContext = {
 | 
				
			||||||
      canvasContext: ctx,
 | 
					      canvasContext: ctx,
 | 
				
			||||||
      transform,
 | 
					      transform,
 | 
				
			||||||
      viewport: this.viewport,
 | 
					      viewport,
 | 
				
			||||||
      annotationMode: this.#annotationMode,
 | 
					      annotationMode: this.#annotationMode,
 | 
				
			||||||
      optionalContentConfigPromise: this._optionalContentConfigPromise,
 | 
					      optionalContentConfigPromise: this._optionalContentConfigPromise,
 | 
				
			||||||
      annotationCanvasMap: this._annotationCanvasMap,
 | 
					      annotationCanvasMap: this._annotationCanvasMap,
 | 
				
			||||||
 | 
				
			|||||||
@ -143,6 +143,11 @@
 | 
				
			|||||||
  display: none;
 | 
					  display: none;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.pdfViewer .page canvas[zooming] {
 | 
				
			||||||
 | 
					  width: 100%;
 | 
				
			||||||
 | 
					  height: 100%;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.pdfViewer .page .loadingIcon {
 | 
					.pdfViewer .page .loadingIcon {
 | 
				
			||||||
  position: absolute;
 | 
					  position: absolute;
 | 
				
			||||||
  display: block;
 | 
					  display: block;
 | 
				
			||||||
 | 
				
			|||||||
@ -216,6 +216,8 @@ class PDFViewer {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  #onVisibilityChange = null;
 | 
					  #onVisibilityChange = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  #scaleTimeoutId = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * @param {PDFViewerOptions} options
 | 
					   * @param {PDFViewerOptions} options
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
@ -454,7 +456,7 @@ class PDFViewer {
 | 
				
			|||||||
    if (!this.pdfDocument) {
 | 
					    if (!this.pdfDocument) {
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    this._setScale(val, false);
 | 
					    this._setScale(val, { noScroll: false });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
@ -471,7 +473,7 @@ class PDFViewer {
 | 
				
			|||||||
    if (!this.pdfDocument) {
 | 
					    if (!this.pdfDocument) {
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    this._setScale(val, false);
 | 
					    this._setScale(val, { noScroll: false });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
@ -503,14 +505,12 @@ class PDFViewer {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    const pageNumber = this._currentPageNumber;
 | 
					    const pageNumber = this._currentPageNumber;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const updateArgs = { rotation };
 | 
					    this.refresh(true, { rotation });
 | 
				
			||||||
    for (const pageView of this._pages) {
 | 
					
 | 
				
			||||||
      pageView.update(updateArgs);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    // Prevent errors in case the rotation changes *before* the scale has been
 | 
					    // Prevent errors in case the rotation changes *before* the scale has been
 | 
				
			||||||
    // set to a non-default value.
 | 
					    // set to a non-default value.
 | 
				
			||||||
    if (this._currentScaleValue) {
 | 
					    if (this._currentScaleValue) {
 | 
				
			||||||
      this._setScale(this._currentScaleValue, true);
 | 
					      this._setScale(this._currentScaleValue, { noScroll: true });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.eventBus.dispatch("rotationchanging", {
 | 
					    this.eventBus.dispatch("rotationchanging", {
 | 
				
			||||||
@ -1080,7 +1080,11 @@ class PDFViewer {
 | 
				
			|||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _setScaleUpdatePages(newScale, newValue, noScroll = false, preset = false) {
 | 
					  _setScaleUpdatePages(
 | 
				
			||||||
 | 
					    newScale,
 | 
				
			||||||
 | 
					    newValue,
 | 
				
			||||||
 | 
					    { noScroll = false, preset = false, delay: drawingDelay = -1 }
 | 
				
			||||||
 | 
					  ) {
 | 
				
			||||||
    this._currentScaleValue = newValue.toString();
 | 
					    this._currentScaleValue = newValue.toString();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (this.#isSameScale(newScale)) {
 | 
					    if (this.#isSameScale(newScale)) {
 | 
				
			||||||
@ -1099,10 +1103,22 @@ class PDFViewer {
 | 
				
			|||||||
      newScale * PixelsPerInch.PDF_TO_CSS_UNITS
 | 
					      newScale * PixelsPerInch.PDF_TO_CSS_UNITS
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const updateArgs = { scale: newScale };
 | 
					    const mustPostponeDrawing = drawingDelay >= 0 && drawingDelay < 1000;
 | 
				
			||||||
    for (const pageView of this._pages) {
 | 
					    const updateArgs = {
 | 
				
			||||||
      pageView.update(updateArgs);
 | 
					      scale: newScale,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    if (mustPostponeDrawing) {
 | 
				
			||||||
 | 
					      updateArgs.drawingDelay = drawingDelay;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    this.refresh(true, updateArgs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (mustPostponeDrawing) {
 | 
				
			||||||
 | 
					      this.#scaleTimeoutId = setTimeout(() => {
 | 
				
			||||||
 | 
					        this.#scaleTimeoutId = null;
 | 
				
			||||||
 | 
					        this.refresh();
 | 
				
			||||||
 | 
					      }, drawingDelay);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this._currentScale = newScale;
 | 
					    this._currentScale = newScale;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!noScroll) {
 | 
					    if (!noScroll) {
 | 
				
			||||||
@ -1152,11 +1168,12 @@ class PDFViewer {
 | 
				
			|||||||
    return 1;
 | 
					    return 1;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _setScale(value, noScroll = false) {
 | 
					  _setScale(value, options) {
 | 
				
			||||||
    let scale = parseFloat(value);
 | 
					    let scale = parseFloat(value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (scale > 0) {
 | 
					    if (scale > 0) {
 | 
				
			||||||
      this._setScaleUpdatePages(scale, value, noScroll, /* preset = */ false);
 | 
					      options.preset = false;
 | 
				
			||||||
 | 
					      this._setScaleUpdatePages(scale, value, options);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      const currentPage = this._pages[this._currentPageNumber - 1];
 | 
					      const currentPage = this._pages[this._currentPageNumber - 1];
 | 
				
			||||||
      if (!currentPage) {
 | 
					      if (!currentPage) {
 | 
				
			||||||
@ -1211,7 +1228,8 @@ class PDFViewer {
 | 
				
			|||||||
          console.error(`_setScale: "${value}" is an unknown zoom value.`);
 | 
					          console.error(`_setScale: "${value}" is an unknown zoom value.`);
 | 
				
			||||||
          return;
 | 
					          return;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      this._setScaleUpdatePages(scale, value, noScroll, /* preset = */ true);
 | 
					      options.preset = true;
 | 
				
			||||||
 | 
					      this._setScaleUpdatePages(scale, value, options);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1223,7 +1241,7 @@ class PDFViewer {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    if (this.isInPresentationMode) {
 | 
					    if (this.isInPresentationMode) {
 | 
				
			||||||
      // Fixes the case when PDF has different page sizes.
 | 
					      // Fixes the case when PDF has different page sizes.
 | 
				
			||||||
      this._setScale(this._currentScaleValue, true);
 | 
					      this._setScale(this._currentScaleValue, { noScroll: true });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    this.#scrollIntoView(pageView);
 | 
					    this.#scrollIntoView(pageView);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -1725,11 +1743,7 @@ class PDFViewer {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    this._optionalContentConfigPromise = promise;
 | 
					    this._optionalContentConfigPromise = promise;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const updateArgs = { optionalContentConfigPromise: promise };
 | 
					    this.refresh(false, { optionalContentConfigPromise: promise });
 | 
				
			||||||
    for (const pageView of this._pages) {
 | 
					 | 
				
			||||||
      pageView.update(updateArgs);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    this.update();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.eventBus.dispatch("optionalcontentconfigchanged", {
 | 
					    this.eventBus.dispatch("optionalcontentconfigchanged", {
 | 
				
			||||||
      source: this,
 | 
					      source: this,
 | 
				
			||||||
@ -1792,7 +1806,7 @@ class PDFViewer {
 | 
				
			|||||||
    // Call this before re-scrolling to the current page, to ensure that any
 | 
					    // Call this before re-scrolling to the current page, to ensure that any
 | 
				
			||||||
    // changes in scale don't move the current page.
 | 
					    // changes in scale don't move the current page.
 | 
				
			||||||
    if (this._currentScaleValue && isNaN(this._currentScaleValue)) {
 | 
					    if (this._currentScaleValue && isNaN(this._currentScaleValue)) {
 | 
				
			||||||
      this._setScale(this._currentScaleValue, true);
 | 
					      this._setScale(this._currentScaleValue, { noScroll: true });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    this._setCurrentPageNumber(pageNumber, /* resetCurrentPageView = */ true);
 | 
					    this._setCurrentPageNumber(pageNumber, /* resetCurrentPageView = */ true);
 | 
				
			||||||
    this.update();
 | 
					    this.update();
 | 
				
			||||||
@ -1864,7 +1878,7 @@ class PDFViewer {
 | 
				
			|||||||
    // Call this before re-scrolling to the current page, to ensure that any
 | 
					    // Call this before re-scrolling to the current page, to ensure that any
 | 
				
			||||||
    // changes in scale don't move the current page.
 | 
					    // changes in scale don't move the current page.
 | 
				
			||||||
    if (this._currentScaleValue && isNaN(this._currentScaleValue)) {
 | 
					    if (this._currentScaleValue && isNaN(this._currentScaleValue)) {
 | 
				
			||||||
      this._setScale(this._currentScaleValue, true);
 | 
					      this._setScale(this._currentScaleValue, { noScroll: true });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    this._setCurrentPageNumber(pageNumber, /* resetCurrentPageView = */ true);
 | 
					    this._setCurrentPageNumber(pageNumber, /* resetCurrentPageView = */ true);
 | 
				
			||||||
    this.update();
 | 
					    this.update();
 | 
				
			||||||
@ -2005,29 +2019,37 @@ class PDFViewer {
 | 
				
			|||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * Increase the current zoom level one, or more, times.
 | 
					   * Increase the current zoom level one, or more, times.
 | 
				
			||||||
   * @param {number} [steps] - Defaults to zooming once.
 | 
					   * @param {number} [steps] - Defaults to zooming once.
 | 
				
			||||||
 | 
					   * @param {Object|null} [options]
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  increaseScale(steps = 1) {
 | 
					  increaseScale(steps = 1, options = null) {
 | 
				
			||||||
    let newScale = this._currentScale;
 | 
					    let newScale = this._currentScale;
 | 
				
			||||||
    do {
 | 
					    do {
 | 
				
			||||||
      newScale = (newScale * DEFAULT_SCALE_DELTA).toFixed(2);
 | 
					      newScale = (newScale * DEFAULT_SCALE_DELTA).toFixed(2);
 | 
				
			||||||
      newScale = Math.ceil(newScale * 10) / 10;
 | 
					      newScale = Math.ceil(newScale * 10) / 10;
 | 
				
			||||||
      newScale = Math.min(MAX_SCALE, newScale);
 | 
					      newScale = Math.min(MAX_SCALE, newScale);
 | 
				
			||||||
    } while (--steps > 0 && newScale < MAX_SCALE);
 | 
					    } while (--steps > 0 && newScale < MAX_SCALE);
 | 
				
			||||||
    this.currentScaleValue = newScale;
 | 
					
 | 
				
			||||||
 | 
					    options ||= Object.create(null);
 | 
				
			||||||
 | 
					    options.noScroll = false;
 | 
				
			||||||
 | 
					    this._setScale(newScale, options);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * Decrease the current zoom level one, or more, times.
 | 
					   * Decrease the current zoom level one, or more, times.
 | 
				
			||||||
   * @param {number} [steps] - Defaults to zooming once.
 | 
					   * @param {number} [steps] - Defaults to zooming once.
 | 
				
			||||||
 | 
					   * @param {Object|null} [options]
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  decreaseScale(steps = 1) {
 | 
					  decreaseScale(steps = 1, options = null) {
 | 
				
			||||||
    let newScale = this._currentScale;
 | 
					    let newScale = this._currentScale;
 | 
				
			||||||
    do {
 | 
					    do {
 | 
				
			||||||
      newScale = (newScale / DEFAULT_SCALE_DELTA).toFixed(2);
 | 
					      newScale = (newScale / DEFAULT_SCALE_DELTA).toFixed(2);
 | 
				
			||||||
      newScale = Math.floor(newScale * 10) / 10;
 | 
					      newScale = Math.floor(newScale * 10) / 10;
 | 
				
			||||||
      newScale = Math.max(MIN_SCALE, newScale);
 | 
					      newScale = Math.max(MIN_SCALE, newScale);
 | 
				
			||||||
    } while (--steps > 0 && newScale > MIN_SCALE);
 | 
					    } while (--steps > 0 && newScale > MIN_SCALE);
 | 
				
			||||||
    this.currentScaleValue = newScale;
 | 
					
 | 
				
			||||||
 | 
					    options ||= Object.create(null);
 | 
				
			||||||
 | 
					    options.noScroll = false;
 | 
				
			||||||
 | 
					    this._setScale(newScale, options);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  #updateContainerHeightCss(height = this.container.clientHeight) {
 | 
					  #updateContainerHeightCss(height = this.container.clientHeight) {
 | 
				
			||||||
@ -2098,16 +2120,21 @@ class PDFViewer {
 | 
				
			|||||||
    this.#annotationEditorUIManager.updateParams(type, value);
 | 
					    this.#annotationEditorUIManager.updateParams(type, value);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  refresh() {
 | 
					  refresh(noUpdate = false, updateArgs = Object.create(null)) {
 | 
				
			||||||
    if (!this.pdfDocument) {
 | 
					    if (!this.pdfDocument) {
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    const updateArgs = {};
 | 
					 | 
				
			||||||
    for (const pageView of this._pages) {
 | 
					    for (const pageView of this._pages) {
 | 
				
			||||||
      pageView.update(updateArgs);
 | 
					      pageView.update(updateArgs);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    if (this.#scaleTimeoutId !== null) {
 | 
				
			||||||
 | 
					      clearTimeout(this.#scaleTimeoutId);
 | 
				
			||||||
 | 
					      this.#scaleTimeoutId = null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (!noUpdate) {
 | 
				
			||||||
      this.update();
 | 
					      this.update();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export { PagesCountLimit, PDFPageViewBuffer, PDFViewer };
 | 
					export { PagesCountLimit, PDFPageViewBuffer, PDFViewer };
 | 
				
			||||||
 | 
				
			|||||||
@ -86,8 +86,8 @@ class TextLayerBuilder {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const scale = viewport.scale * (globalThis.devicePixelRatio || 1);
 | 
					    const scale = viewport.scale * (globalThis.devicePixelRatio || 1);
 | 
				
			||||||
    if (this.renderingDone) {
 | 
					 | 
				
			||||||
    const { rotation } = viewport;
 | 
					    const { rotation } = viewport;
 | 
				
			||||||
 | 
					    if (this.renderingDone) {
 | 
				
			||||||
      const mustRotate = rotation !== this.#rotation;
 | 
					      const mustRotate = rotation !== this.#rotation;
 | 
				
			||||||
      const mustRescale = scale !== this.#scale;
 | 
					      const mustRescale = scale !== this.#scale;
 | 
				
			||||||
      if (mustRotate || mustRescale) {
 | 
					      if (mustRotate || mustRescale) {
 | 
				
			||||||
@ -101,10 +101,10 @@ class TextLayerBuilder {
 | 
				
			|||||||
          mustRescale,
 | 
					          mustRescale,
 | 
				
			||||||
          mustRotate,
 | 
					          mustRotate,
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        this.show();
 | 
					 | 
				
			||||||
        this.#scale = scale;
 | 
					        this.#scale = scale;
 | 
				
			||||||
        this.#rotation = rotation;
 | 
					        this.#rotation = rotation;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					      this.show();
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -125,21 +125,26 @@ class TextLayerBuilder {
 | 
				
			|||||||
    await this.textLayerRenderTask.promise;
 | 
					    await this.textLayerRenderTask.promise;
 | 
				
			||||||
    this.#finishRendering();
 | 
					    this.#finishRendering();
 | 
				
			||||||
    this.#scale = scale;
 | 
					    this.#scale = scale;
 | 
				
			||||||
 | 
					    this.#rotation = rotation;
 | 
				
			||||||
    this.show();
 | 
					    this.show();
 | 
				
			||||||
    this.accessibilityManager?.enable();
 | 
					    this.accessibilityManager?.enable();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  hide() {
 | 
					  hide() {
 | 
				
			||||||
 | 
					    if (!this.div.hidden) {
 | 
				
			||||||
      // We turn off the highlighter in order to avoid to scroll into view an
 | 
					      // We turn off the highlighter in order to avoid to scroll into view an
 | 
				
			||||||
      // element of the text layer which could be hidden.
 | 
					      // element of the text layer which could be hidden.
 | 
				
			||||||
      this.highlighter?.disable();
 | 
					      this.highlighter?.disable();
 | 
				
			||||||
      this.div.hidden = true;
 | 
					      this.div.hidden = true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  show() {
 | 
					  show() {
 | 
				
			||||||
 | 
					    if (this.div.hidden && this.renderingDone) {
 | 
				
			||||||
      this.div.hidden = false;
 | 
					      this.div.hidden = false;
 | 
				
			||||||
      this.highlighter?.enable();
 | 
					      this.highlighter?.enable();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * Cancel rendering of the text layer.
 | 
					   * Cancel rendering of the text layer.
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user