Repository: mozilla/pdf.js
File: web/pdf_thumbnail_view.js (JavaScript)

Code before:

    return { canvas, transform };
  }

  async #convertCanvasToImage(canvas) {
    if (this.renderingState !== RenderingStates.FINISHED) {
      throw new Error("#convertCanvasToImage: Rendering has not finished.");
    }
    const reducedCanvas = this.#reduceImage(canvas);
    const { image } = this;
    const { promise, resolve } = Promise.withResolvers();
    reducedCanvas.toBlob(resolve);
    const blob = await promise;
    image.src = URL.createObjectURL(blob);
    image.setAttribute("data-l10n-id", "pdfjs-thumb-page-canvas");
    image.setAttribute("data-l10n-args", this.#pageL10nArgs);
    image.classList.remove("missingThumbnailImage");
    if (!FeatureTest.isOffscreenCanvasSupported) {
      // Clean up the canvas element since it is no longer needed.
      reducedCanvas.width = reducedCanvas.height = 0;
    }
  }

  async draw() {
    if (this.renderingState !== RenderingStates.INITIAL) {
      console.error("Must be in new state before drawing");
      return;
    }
    const { pageColors, pdfPage } = this;

    if (!pdfPage) {
      this.renderingState = RenderingStates.FINISHED;
      throw new Error("pdfPage is not loaded");
    }

    this.renderingState = RenderingStates.RUNNING;

    // Render the thumbnail at a larger size and downsize the canvas (similar
    // to `setImage`), to improve consistency between thumbnails created by
    // the `draw` and `setImage` methods (fixes issue 8233).
    // NOTE: To primarily avoid increasing memory usage too much, but also to
    //   reduce downsizing overhead, we purposely limit the up-scaling factor.
    const { canvas, transform } = this.#getPageDrawContext(DRAW_UPSCALE_FACTOR);
    const drawViewport = this.viewport.clone({
      scale: DRAW_UPSCALE_FACTOR * this.scale,
    });
    const renderContinueCallback = cont => {
      if (!this.renderingQueue.isHighestPriority(this)) {
        this.renderingState = RenderingStates.PAUSED;
        this.resume = () => {
          this.renderingState = RenderingStates.RUNNING;

Review comment (suggestion):
We might be able to replace the `if` with `this.checkbox?.tabIndex` below.

Code after:
  }

  update({ rotation = null }) {
    if (typeof rotation === "number") {
      this.rotation = rotation; // The rotation may be zero.
    }
    const totalRotation = (this.rotation + this.pdfPageRotate) % 360;
    this.viewport = this.viewport.clone({
      scale: 1,
      rotation: totalRotation,
    });
    this.reset();
  }

  toggleCurrent(isCurrent) {
    const { imageContainer } = this;
    if (isCurrent) {
      imageContainer.ariaCurrent = "page";
      imageContainer.tabIndex = 0;
      if (this.checkbox) {
        this.checkbox.tabIndex = 0;
      }
    } else {
      imageContainer.ariaCurrent = false;
      imageContainer.tabIndex = -1;
      if (this.checkbox) {
        this.checkbox.tabIndex = -1;
      }
    }
  }

  /**
   * PLEASE NOTE: Most likely you want to use the `this.reset()` method,
   *              rather than calling this one directly.
   */
  cancelRendering() {
    if (this.renderTask) {
      this.renderTask.cancel();
      this.renderTask = null;
    }
    this.resume = null;
  }

  #getPageDrawContext(upscaleFactor = 1) {
    // Keep the no-thumbnail outline visible, i.e. `data-loaded === false`,
    // until rendering/image conversion is complete, to avoid display issues.
    const outputScale = new OutputScale();
    const width = upscaleFactor * this.canvasWidth,
      height = upscaleFactor * this.canvasHeight;

    outputScale.limitCanvas(