text: /**
   * @licstart The following is the entire license notice for the
   * Javascript code in this page
   *
   * Copyright 2021 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.
   *
   * @licend The above is the entire license notice for the
   * Javascript code in this page
   */
  "use strict";
  
  Object.defineProperty(exports, "__esModule", {
    value: true
  });
  exports.TempImageFactory = exports.PDFThumbnailView = void 0;
  
  var _ui_utils = require("./ui_utils.js");
  
  var _pdf = require("../pdf");
  
  var _pdf_rendering_queue = require("./pdf_rendering_queue.js");
  
  const DRAW_UPSCALE_FACTOR = 2;
  const MAX_NUM_SCALING_STEPS = 3;
  const THUMBNAIL_CANVAS_BORDER_WIDTH = 1;
  const THUMBNAIL_WIDTH = 98;
  
  const TempImageFactory = function TempImageFactoryClosure() {
    let tempCanvasCache = null;
    return {
      getCanvas(width, height) {
        let tempCanvas = tempCanvasCache;
  
        if (!tempCanvas) {
          tempCanvas = document.createElement("canvas");
          tempCanvasCache = tempCanvas;
        }
  
        tempCanvas.width = width;
        tempCanvas.height = height;
        tempCanvas.mozOpaque = true;
        const ctx = tempCanvas.getContext("2d", {
          alpha: false
        });
        ctx.save();
        ctx.fillStyle = "rgb(255, 255, 255)";
        ctx.fillRect(0, 0, width, height);
        ctx.restore();
        return [tempCanvas, tempCanvas.getContext("2d")];
      },
  
      destroyCanvas() {
        const tempCanvas = tempCanvasCache;
  
        if (tempCanvas) {
          tempCanvas.width = 0;
          tempCanvas.height = 0;
        }
  
        tempCanvasCache = null;
      }
  
    };
  }();
  
  exports.TempImageFactory = TempImageFactory;
  
  class PDFThumbnailView {
    constructor({
      container,
      id,
      defaultViewport,
      optionalContentConfigPromise,
      linkService,
      renderingQueue,
      checkSetImageDisabled,
      l10n
    }) {
      this.id = id;
      this.renderingId = "thumbnail" + id;
      this.pageLabel = null;
      this.pdfPage = null;
      this.rotation = 0;
      this.viewport = defaultViewport;
      this.pdfPageRotate = defaultViewport.rotation;
      this._optionalContentConfigPromise = optionalContentConfigPromise || null;
      this.linkService = linkService;
      this.renderingQueue = renderingQueue;
      this.renderTask = null;
      this.renderingState = _pdf_rendering_queue.RenderingStates.INITIAL;
      this.resume = null;
  
      this._checkSetImageDisabled = checkSetImageDisabled || function () {
        return false;
      };
  
      const pageWidth = this.viewport.width,
            pageHeight = this.viewport.height,
            pageRatio = pageWidth / pageHeight;
      this.canvasWidth = THUMBNAIL_WIDTH;
      this.canvasHeight = this.canvasWidth / pageRatio | 0;
      this.scale = this.canvasWidth / pageWidth;
      this.l10n = l10n;
      const anchor = document.createElement("a");
      anchor.href = linkService.getAnchorUrl("#page=" + id);
  
      this._thumbPageTitle.then(msg => {
        anchor.title = msg;
      });
  
      anchor.onclick = function () {
        linkService.goToPage(id);
        return false;
      };
  
      this.anchor = anchor;
      const div = document.createElement("div");
      div.className = "thumbnail";
      div.setAttribute("data-page-number", this.id);
      this.div = div;
      const ring = document.createElement("div");
      ring.className = "thumbnailSelectionRing";
      const borderAdjustment = 2 * THUMBNAIL_CANVAS_BORDER_WIDTH;
      ring.style.width = this.canvasWidth + borderAdjustment + "px";
      ring.style.height = this.canvasHeight + borderAdjustment + "px";
      this.ring = ring;
      div.appendChild(ring);
      anchor.appendChild(div);
      container.appendChild(anchor);
    }
  
    setPdfPage(pdfPage) {
      this.pdfPage = pdfPage;
      this.pdfPageRotate = pdfPage.rotate;
      const totalRotation = (this.rotation + this.pdfPageRotate) % 360;
      this.viewport = pdfPage.getViewport({
        scale: 1,
        rotation: totalRotation
      });
      this.reset();
    }
  
    reset() {
      this.cancelRendering();
      this.renderingState = _pdf_rendering_queue.RenderingStates.INITIAL;
      const pageWidth = this.viewport.width,
            pageHeight = this.viewport.height,
            pageRatio = pageWidth / pageHeight;
      this.canvasHeight = this.canvasWidth / pageRatio | 0;
      this.scale = this.canvasWidth / pageWidth;
      this.div.removeAttribute("data-loaded");
      const ring = this.ring;
      ring.textContent = "";
      const borderAdjustment = 2 * THUMBNAIL_CANVAS_BORDER_WIDTH;
      ring.style.width = this.canvasWidth + borderAdjustment + "px";
      ring.style.height = this.canvasHeight + borderAdjustment + "px";
  
      if (this.canvas) {
        this.canvas.width = 0;
        this.canvas.height = 0;
        delete this.canvas;
      }
  
      if (this.image) {
        this.image.removeAttribute("src");
        delete this.image;
      }
    }
  
    update({
      rotation = null
    }) {
      if (typeof rotation === "number") {
        this.rotation = rotation;
      }
  
      const totalRotation = (this.rotation + this.pdfPageRotate) % 360;
      this.viewport = this.viewport.clone({
        scale: 1,
        rotation: totalRotation
      });
      this.reset();
    }
  
    cancelRendering() {
      if (this.renderTask) {
        this.renderTask.cancel();
        this.renderTask = null;
      }
  
      this.resume = null;
    }
  
    _getPageDrawContext(upscaleFactor = 1) {
      const canvas = document.createElement("canvas");
      canvas.mozOpaque = true;
      const ctx = canvas.getContext("2d", {
        alpha: false
      });
      const outputScale = (0, _ui_utils.getOutputScale)(ctx);
      canvas.width = upscaleFactor * this.canvasWidth * outputScale.sx | 0;
      canvas.height = upscaleFactor * this.canvasHeight * outputScale.sy | 0;
      const transform = outputScale.scaled ? [outputScale.sx, 0, 0, outputScale.sy, 0, 0] : null;
      return {
        ctx,
        canvas,
        transform
      };
    }
  
    _convertCanvasToImage(canvas) {
      if (this.renderingState !== _pdf_rendering_queue.RenderingStates.FINISHED) {
        throw new Error("_convertCanvasToImage: Rendering has not finished.");
      }
  
      const reducedCanvas = this._reduceImage(canvas);
  
      const image = document.createElement("img");
      image.className = "thumbnailImage";
  
      this._thumbPageCanvas.then(msg => {
        image.setAttribute("aria-label", msg);
      });
  
      image.style.width = this.canvasWidth + "px";
      image.style.height = this.canvasHeight + "px";
      image.src = reducedCanvas.toDataURL();
      this.image = image;
      this.div.setAttribute("data-loaded", true);
      this.ring.appendChild(image);
      reducedCanvas.width = 0;
      reducedCanvas.height = 0;
    }
  
    draw() {
      if (this.renderingState !== _pdf_rendering_queue.RenderingStates.INITIAL) {
        console.error("Must be in new state before drawing");
        return Promise.resolve(undefined);
      }
  
      const {
        pdfPage
      } = this;
  
      if (!pdfPage) {
        this.renderingState = _pdf_rendering_queue.RenderingStates.FINISHED;
        return Promise.reject(new Error("pdfPage is not loaded"));
      }
  
      this.renderingState = _pdf_rendering_queue.RenderingStates.RUNNING;
  
      const finishRenderTask = async (error = null) => {
        if (renderTask === this.renderTask) {
          this.renderTask = null;
        }
  
        if (error instanceof _pdf.RenderingCancelledException) {
          return;
        }
  
        this.renderingState = _pdf_rendering_queue.RenderingStates.FINISHED;
  
        this._convertCanvasToImage(canvas);
  
        if (error) {
          throw error;
        }
      };
  
      const {
        ctx,
        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 = _pdf_rendering_queue.RenderingStates.PAUSED;
  
          this.resume = () => {
            this.renderingState = _pdf_rendering_queue.RenderingStates.RUNNING;
            cont();
          };
  
          return;
        }
  
        cont();
      };
  
      const renderContext = {
        canvasContext: ctx,
        transform,
        viewport: drawViewport,
        optionalContentConfigPromise: this._optionalContentConfigPromise
      };
      const renderTask = this.renderTask = pdfPage.render(renderContext);
      renderTask.onContinue = renderContinueCallback;
      const resultPromise = renderTask.promise.then(function () {
        return finishRenderTask(null);
      }, function (error) {
        return finishRenderTask(error);
      });
      resultPromise.finally(() => {
        canvas.width = 0;
        canvas.height = 0;
        const pageCached = this.linkService.isPageCached(this.id);
  
        if (!pageCached) {
          this.pdfPage?.cleanup();
        }
      });
      return resultPromise;
    }
  
    setImage(pageView) {
      if (this._checkSetImageDisabled()) {
        return;
      }
  
      if (this.renderingState !== _pdf_rendering_queue.RenderingStates.INITIAL) {
        return;
      }
  
      const {
        canvas,
        pdfPage
      } = pageView;
  
      if (!canvas) {
        return;
      }
  
      if (!this.pdfPage) {
        this.setPdfPage(pdfPage);
      }
  
      this.renderingState = _pdf_rendering_queue.RenderingStates.FINISHED;
  
      this._convertCanvasToImage(canvas);
    }
  
    _reduceImage(img) {
      const {
        ctx,
        canvas
      } = this._getPageDrawContext();
  
      if (img.width <= 2 * canvas.width) {
        ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, canvas.width, canvas.height);
        return canvas;
      }
  
      let reducedWidth = canvas.width << MAX_NUM_SCALING_STEPS;
      let reducedHeight = canvas.height << MAX_NUM_SCALING_STEPS;
      const [reducedImage, reducedImageCtx] = TempImageFactory.getCanvas(reducedWidth, reducedHeight);
  
      while (reducedWidth > img.width || reducedHeight > img.height) {
        reducedWidth >>= 1;
        reducedHeight >>= 1;
      }
  
      reducedImageCtx.drawImage(img, 0, 0, img.width, img.height, 0, 0, reducedWidth, reducedHeight);
  
      while (reducedWidth > 2 * canvas.width) {
        reducedImageCtx.drawImage(reducedImage, 0, 0, reducedWidth, reducedHeight, 0, 0, reducedWidth >> 1, reducedHeight >> 1);
        reducedWidth >>= 1;
        reducedHeight >>= 1;
      }
  
      ctx.drawImage(reducedImage, 0, 0, reducedWidth, reducedHeight, 0, 0, canvas.width, canvas.height);
      return canvas;
    }
  
    get _thumbPageTitle() {
      return this.l10n.get("thumb_page_title", {
        page: this.pageLabel ?? this.id
      });
    }
  
    get _thumbPageCanvas() {
      return this.l10n.get("thumb_page_canvas", {
        page: this.pageLabel ?? this.id
      });
    }
  
    setPageLabel(label) {
      this.pageLabel = typeof label === "string" ? label : null;
  
      this._thumbPageTitle.then(msg => {
        this.anchor.title = msg;
      });
  
      if (this.renderingState !== _pdf_rendering_queue.RenderingStates.FINISHED) {
        return;
      }
  
      this._thumbPageCanvas.then(msg => {
        this.image?.setAttribute("aria-label", msg);
      });
    }
  
  }
  
  exports.PDFThumbnailView = PDFThumbnailView;