[api-minor] Use "data-l10n-id"/"data-l10n-args", rather than manually updating DOM-elements, to trigger translation (PR 17146 follow-up)
This patch changes almost all viewer-components[1] to use "data-l10n-id"/"data-l10n-args" for localization, which means that in many cases we no longer need to pass around the `L10n`-instance any more. One part of the code-base where the `L10n`-instance is still being used "directly" is the AnnotationEditors, however while it might be possible to convert (most of) that code as well that's not attempted in this patch. --- [1] The one exception is the `PDFDocumentProperties` dialog, since the way it's currently implemented makes that less straightforward to fix without a lot of code changes.
This commit is contained in:
		
							parent
							
								
									898cc2e399
								
							
						
					
					
						commit
						17af706070
					
				@ -218,11 +218,13 @@ pdfjs-additional-layers = Additional Layers
 | 
			
		||||
 | 
			
		||||
# Variables:
 | 
			
		||||
#   $page (Number) - the page number
 | 
			
		||||
pdfjs-thumb-page-title = Page { $page }
 | 
			
		||||
pdfjs-thumb-page-title =
 | 
			
		||||
    .title = Page { $page }
 | 
			
		||||
 | 
			
		||||
# Variables:
 | 
			
		||||
#   $page (Number) - the page number
 | 
			
		||||
pdfjs-thumb-page-canvas = Thumbnail of Page { $page }
 | 
			
		||||
pdfjs-thumb-page-canvas =
 | 
			
		||||
    .aria-label = Thumbnail of Page { $page }
 | 
			
		||||
 | 
			
		||||
## Find panel button title and messages
 | 
			
		||||
 | 
			
		||||
@ -276,7 +278,8 @@ pdfjs-page-scale-percent = { $scale }%
 | 
			
		||||
 | 
			
		||||
# Variables:
 | 
			
		||||
#   $page (Number) - the page number
 | 
			
		||||
pdfjs-page-landmark = Page { $page }
 | 
			
		||||
pdfjs-page-landmark =
 | 
			
		||||
    .aria-label = Page { $page }
 | 
			
		||||
 | 
			
		||||
## Loading indicator messages
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -983,8 +983,11 @@ class TextAnnotationElement extends AnnotationElement {
 | 
			
		||||
      "annotation-" +
 | 
			
		||||
      this.data.name.toLowerCase() +
 | 
			
		||||
      ".svg";
 | 
			
		||||
    image.dataset.l10nId = "pdfjs-text-annotation-type";
 | 
			
		||||
    image.dataset.l10nArgs = JSON.stringify({ type: this.data.name });
 | 
			
		||||
    image.setAttribute("data-l10n-id", "pdfjs-text-annotation-type");
 | 
			
		||||
    image.setAttribute(
 | 
			
		||||
      "data-l10n-args",
 | 
			
		||||
      JSON.stringify({ type: this.data.name })
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    if (!this.data.popupRef && this.hasPopupData) {
 | 
			
		||||
      this._createPopup();
 | 
			
		||||
@ -2158,11 +2161,17 @@ class PopupElement {
 | 
			
		||||
    if (this.#dateObj) {
 | 
			
		||||
      const modificationDate = document.createElement("span");
 | 
			
		||||
      modificationDate.classList.add("popupDate");
 | 
			
		||||
      modificationDate.dataset.l10nId = "pdfjs-annotation-date-string";
 | 
			
		||||
      modificationDate.dataset.l10nArgs = JSON.stringify({
 | 
			
		||||
      modificationDate.setAttribute(
 | 
			
		||||
        "data-l10n-id",
 | 
			
		||||
        "pdfjs-annotation-date-string"
 | 
			
		||||
      );
 | 
			
		||||
      modificationDate.setAttribute(
 | 
			
		||||
        "data-l10n-args",
 | 
			
		||||
        JSON.stringify({
 | 
			
		||||
          date: this.#dateObj.toLocaleDateString(),
 | 
			
		||||
          time: this.#dateObj.toLocaleTimeString(),
 | 
			
		||||
      });
 | 
			
		||||
        })
 | 
			
		||||
      );
 | 
			
		||||
      header.append(modificationDate);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -2889,14 +2898,12 @@ class AnnotationLayer {
 | 
			
		||||
    div,
 | 
			
		||||
    accessibilityManager,
 | 
			
		||||
    annotationCanvasMap,
 | 
			
		||||
    l10n,
 | 
			
		||||
    page,
 | 
			
		||||
    viewport,
 | 
			
		||||
  }) {
 | 
			
		||||
    this.div = div;
 | 
			
		||||
    this.#accessibilityManager = accessibilityManager;
 | 
			
		||||
    this.#annotationCanvasMap = annotationCanvasMap;
 | 
			
		||||
    this.l10n = l10n;
 | 
			
		||||
    this.page = page;
 | 
			
		||||
    this.viewport = viewport;
 | 
			
		||||
    this.zIndex = 0;
 | 
			
		||||
 | 
			
		||||
@ -25,8 +25,7 @@ const {
 | 
			
		||||
  shadow,
 | 
			
		||||
  XfaLayer,
 | 
			
		||||
} = pdfjsLib;
 | 
			
		||||
const { GenericL10n, NullL10n, parseQueryString, SimpleLinkService } =
 | 
			
		||||
  pdfjsViewer;
 | 
			
		||||
const { GenericL10n, parseQueryString, SimpleLinkService } = pdfjsViewer;
 | 
			
		||||
 | 
			
		||||
const WAITING_TIME = 100; // ms
 | 
			
		||||
const CMAP_URL = "/build/generic/web/cmaps/";
 | 
			
		||||
@ -215,8 +214,7 @@ class Rasterize {
 | 
			
		||||
    annotationCanvasMap,
 | 
			
		||||
    page,
 | 
			
		||||
    imageResourcesPath,
 | 
			
		||||
    renderForms = false,
 | 
			
		||||
    l10n = NullL10n
 | 
			
		||||
    renderForms = false
 | 
			
		||||
  ) {
 | 
			
		||||
    try {
 | 
			
		||||
      const { svg, foreignObject, style, div } = this.createContainer(viewport);
 | 
			
		||||
@ -248,7 +246,6 @@ class Rasterize {
 | 
			
		||||
        div,
 | 
			
		||||
        annotationCanvasMap: annotationImageMap,
 | 
			
		||||
        page,
 | 
			
		||||
        l10n,
 | 
			
		||||
        viewport: annotationViewport,
 | 
			
		||||
      });
 | 
			
		||||
      await annotationLayer.render(parameters);
 | 
			
		||||
@ -356,6 +353,8 @@ class Driver {
 | 
			
		||||
    // Configure the global worker options.
 | 
			
		||||
    GlobalWorkerOptions.workerSrc = WORKER_SRC;
 | 
			
		||||
 | 
			
		||||
    // We only need to initialize the `L10n`-instance here, since translation is
 | 
			
		||||
    // triggered by a `MutationObserver`; see e.g. `Rasterize.annotationLayer`.
 | 
			
		||||
    this._l10n = new GenericL10n(VIEWER_LOCALE);
 | 
			
		||||
 | 
			
		||||
    // Set the passed options
 | 
			
		||||
@ -879,8 +878,7 @@ class Driver {
 | 
			
		||||
                      annotationCanvasMap,
 | 
			
		||||
                      page,
 | 
			
		||||
                      IMAGE_RESOURCES_PATH,
 | 
			
		||||
                      renderForms,
 | 
			
		||||
                      this._l10n
 | 
			
		||||
                      renderForms
 | 
			
		||||
                    ).then(() => {
 | 
			
		||||
                      completeRender(false);
 | 
			
		||||
                    });
 | 
			
		||||
 | 
			
		||||
@ -19,13 +19,11 @@
 | 
			
		||||
// eslint-disable-next-line max-len
 | 
			
		||||
/** @typedef {import("../src/display/annotation_storage").AnnotationStorage} AnnotationStorage */
 | 
			
		||||
/** @typedef {import("./interfaces").IDownloadManager} IDownloadManager */
 | 
			
		||||
/** @typedef {import("./interfaces").IL10n} IL10n */
 | 
			
		||||
/** @typedef {import("./interfaces").IPDFLinkService} IPDFLinkService */
 | 
			
		||||
// eslint-disable-next-line max-len
 | 
			
		||||
/** @typedef {import("./text_accessibility.js").TextAccessibilityManager} TextAccessibilityManager */
 | 
			
		||||
 | 
			
		||||
import { AnnotationLayer } from "pdfjs-lib";
 | 
			
		||||
import { NullL10n } from "web-l10n_utils";
 | 
			
		||||
import { PresentationModeState } from "./ui_utils.js";
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -38,7 +36,6 @@ import { PresentationModeState } from "./ui_utils.js";
 | 
			
		||||
 * @property {boolean} renderForms
 | 
			
		||||
 * @property {IPDFLinkService} linkService
 | 
			
		||||
 * @property {IDownloadManager} [downloadManager]
 | 
			
		||||
 * @property {IL10n} l10n - Localization service.
 | 
			
		||||
 * @property {boolean} [enableScripting]
 | 
			
		||||
 * @property {Promise<boolean>} [hasJSActionsPromise]
 | 
			
		||||
 * @property {Promise<Object<string, Array<Object>> | null>}
 | 
			
		||||
@ -61,7 +58,6 @@ class AnnotationLayerBuilder {
 | 
			
		||||
    annotationStorage = null,
 | 
			
		||||
    imageResourcesPath = "",
 | 
			
		||||
    renderForms = true,
 | 
			
		||||
    l10n = NullL10n,
 | 
			
		||||
    enableScripting = false,
 | 
			
		||||
    hasJSActionsPromise = null,
 | 
			
		||||
    fieldObjectsPromise = null,
 | 
			
		||||
@ -74,7 +70,6 @@ class AnnotationLayerBuilder {
 | 
			
		||||
    this.downloadManager = downloadManager;
 | 
			
		||||
    this.imageResourcesPath = imageResourcesPath;
 | 
			
		||||
    this.renderForms = renderForms;
 | 
			
		||||
    this.l10n = l10n;
 | 
			
		||||
    this.annotationStorage = annotationStorage;
 | 
			
		||||
    this.enableScripting = enableScripting;
 | 
			
		||||
    this._hasJSActionsPromise = hasJSActionsPromise || Promise.resolve(false);
 | 
			
		||||
@ -131,7 +126,6 @@ class AnnotationLayerBuilder {
 | 
			
		||||
      div,
 | 
			
		||||
      accessibilityManager: this._accessibilityManager,
 | 
			
		||||
      annotationCanvasMap: this._annotationCanvasMap,
 | 
			
		||||
      l10n: this.l10n,
 | 
			
		||||
      page: this.pdfPage,
 | 
			
		||||
      viewport: viewport.clone({ dontFlip: true }),
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										11
									
								
								web/app.js
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								web/app.js
									
									
									
									
									
								
							@ -521,7 +521,6 @@ const PDFViewerApplication = {
 | 
			
		||||
        eventBus,
 | 
			
		||||
        renderingQueue: pdfRenderingQueue,
 | 
			
		||||
        linkService: pdfLinkService,
 | 
			
		||||
        l10n,
 | 
			
		||||
        pageColors,
 | 
			
		||||
      });
 | 
			
		||||
      pdfRenderingQueue.setThumbnailViewer(this.pdfThumbnailViewer);
 | 
			
		||||
@ -538,7 +537,7 @@ const PDFViewerApplication = {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!this.supportsIntegratedFind && appConfig.findBar) {
 | 
			
		||||
      this.findBar = new PDFFindBar(appConfig.findBar, eventBus, l10n);
 | 
			
		||||
      this.findBar = new PDFFindBar(appConfig.findBar, eventBus);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (appConfig.annotationEditorParams) {
 | 
			
		||||
@ -587,11 +586,10 @@ const PDFViewerApplication = {
 | 
			
		||||
        this.toolbar = new Toolbar(
 | 
			
		||||
          appConfig.toolbar,
 | 
			
		||||
          eventBus,
 | 
			
		||||
          l10n,
 | 
			
		||||
          await this._nimbusDataPromise
 | 
			
		||||
        );
 | 
			
		||||
      } else {
 | 
			
		||||
        this.toolbar = new Toolbar(appConfig.toolbar, eventBus, l10n);
 | 
			
		||||
        this.toolbar = new Toolbar(appConfig.toolbar, eventBus);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -617,7 +615,6 @@ const PDFViewerApplication = {
 | 
			
		||||
      this.passwordPrompt = new PasswordPrompt(
 | 
			
		||||
        appConfig.passwordOverlay,
 | 
			
		||||
        this.overlayManager,
 | 
			
		||||
        l10n,
 | 
			
		||||
        this.isViewerEmbedded
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
@ -643,7 +640,6 @@ const PDFViewerApplication = {
 | 
			
		||||
      this.pdfLayerViewer = new PDFLayerViewer({
 | 
			
		||||
        container: appConfig.sidebar.layersView,
 | 
			
		||||
        eventBus,
 | 
			
		||||
        l10n,
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -1848,8 +1844,7 @@ const PDFViewerApplication = {
 | 
			
		||||
      printContainer,
 | 
			
		||||
      printResolution,
 | 
			
		||||
      optionalContentConfigPromise,
 | 
			
		||||
      this._printAnnotationStoragePromise,
 | 
			
		||||
      this.l10n
 | 
			
		||||
      this._printAnnotationStoragePromise
 | 
			
		||||
    );
 | 
			
		||||
    this.printService = printService;
 | 
			
		||||
    this.forceRendering();
 | 
			
		||||
 | 
			
		||||
@ -18,13 +18,12 @@
 | 
			
		||||
import { FluentBundle, FluentResource } from "fluent-bundle";
 | 
			
		||||
import { DOMLocalization } from "fluent-dom";
 | 
			
		||||
import { L10n } from "./l10n.js";
 | 
			
		||||
import { shadow } from "pdfjs-lib";
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @implements {IL10n}
 | 
			
		||||
 */
 | 
			
		||||
class ConstL10n extends L10n {
 | 
			
		||||
  static #instance;
 | 
			
		||||
 | 
			
		||||
  constructor(lang) {
 | 
			
		||||
    super({ lang });
 | 
			
		||||
    this.setL10n(
 | 
			
		||||
@ -51,7 +50,7 @@ class ConstL10n extends L10n {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static get instance() {
 | 
			
		||||
    return (this.#instance ||= new ConstL10n("en-US"));
 | 
			
		||||
    return shadow(this, "instance", new ConstL10n("en-US"));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -37,18 +37,16 @@ class PasswordPrompt {
 | 
			
		||||
  /**
 | 
			
		||||
   * @param {PasswordPromptOptions} options
 | 
			
		||||
   * @param {OverlayManager} overlayManager - Manager for the viewer overlays.
 | 
			
		||||
   * @param {IL10n} l10n - Localization service.
 | 
			
		||||
   * @param {boolean} [isViewerEmbedded] - If the viewer is embedded, in e.g.
 | 
			
		||||
   *   an <iframe> or an <object>. The default value is `false`.
 | 
			
		||||
   */
 | 
			
		||||
  constructor(options, overlayManager, l10n, isViewerEmbedded = false) {
 | 
			
		||||
  constructor(options, overlayManager, isViewerEmbedded = false) {
 | 
			
		||||
    this.dialog = options.dialog;
 | 
			
		||||
    this.label = options.label;
 | 
			
		||||
    this.input = options.input;
 | 
			
		||||
    this.submitButton = options.submitButton;
 | 
			
		||||
    this.cancelButton = options.cancelButton;
 | 
			
		||||
    this.overlayManager = overlayManager;
 | 
			
		||||
    this.l10n = l10n;
 | 
			
		||||
    this._isViewerEmbedded = isViewerEmbedded;
 | 
			
		||||
 | 
			
		||||
    // Attach the event listeners.
 | 
			
		||||
@ -84,7 +82,8 @@ class PasswordPrompt {
 | 
			
		||||
    if (!this._isViewerEmbedded || passwordIncorrect) {
 | 
			
		||||
      this.input.focus();
 | 
			
		||||
    }
 | 
			
		||||
    this.label.textContent = await this.l10n.get(
 | 
			
		||||
    this.label.setAttribute(
 | 
			
		||||
      "data-l10n-id",
 | 
			
		||||
      `pdfjs-password-${passwordIncorrect ? "invalid" : "label"}`
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -27,7 +27,7 @@ const MATCHES_COUNT_LIMIT = 1000;
 | 
			
		||||
class PDFFindBar {
 | 
			
		||||
  #resizeObserver = new ResizeObserver(this.#resizeObserverCallback.bind(this));
 | 
			
		||||
 | 
			
		||||
  constructor(options, eventBus, l10n) {
 | 
			
		||||
  constructor(options, eventBus) {
 | 
			
		||||
    this.opened = false;
 | 
			
		||||
 | 
			
		||||
    this.bar = options.bar;
 | 
			
		||||
@ -42,7 +42,6 @@ class PDFFindBar {
 | 
			
		||||
    this.findPreviousButton = options.findPreviousButton;
 | 
			
		||||
    this.findNextButton = options.findNextButton;
 | 
			
		||||
    this.eventBus = eventBus;
 | 
			
		||||
    this.l10n = l10n;
 | 
			
		||||
 | 
			
		||||
    // Add event listeners to the DOM elements.
 | 
			
		||||
    this.toggleButton.addEventListener("click", () => {
 | 
			
		||||
@ -109,8 +108,9 @@ class PDFFindBar {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  updateUIState(state, previous, matchesCount) {
 | 
			
		||||
    let findMsg = Promise.resolve("");
 | 
			
		||||
    let status = "";
 | 
			
		||||
    const { findField, findMsg } = this;
 | 
			
		||||
    let findMsgId = "",
 | 
			
		||||
      status = "";
 | 
			
		||||
 | 
			
		||||
    switch (state) {
 | 
			
		||||
      case FindState.FOUND:
 | 
			
		||||
@ -119,39 +119,46 @@ class PDFFindBar {
 | 
			
		||||
        status = "pending";
 | 
			
		||||
        break;
 | 
			
		||||
      case FindState.NOT_FOUND:
 | 
			
		||||
        findMsg = this.l10n.get("pdfjs-find-not-found");
 | 
			
		||||
        findMsgId = "pdfjs-find-not-found";
 | 
			
		||||
        status = "notFound";
 | 
			
		||||
        break;
 | 
			
		||||
      case FindState.WRAPPED:
 | 
			
		||||
        findMsg = this.l10n.get(
 | 
			
		||||
          `pdfjs-find-reached-${previous ? "top" : "bottom"}`
 | 
			
		||||
        );
 | 
			
		||||
        findMsgId = `pdfjs-find-reached-${previous ? "top" : "bottom"}`;
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    this.findField.setAttribute("data-status", status);
 | 
			
		||||
    this.findField.setAttribute("aria-invalid", state === FindState.NOT_FOUND);
 | 
			
		||||
    findField.setAttribute("data-status", status);
 | 
			
		||||
    findField.setAttribute("aria-invalid", state === FindState.NOT_FOUND);
 | 
			
		||||
 | 
			
		||||
    findMsg.then(msg => {
 | 
			
		||||
      this.findMsg.setAttribute("data-status", status);
 | 
			
		||||
      this.findMsg.textContent = msg;
 | 
			
		||||
    });
 | 
			
		||||
    findMsg.setAttribute("data-status", status);
 | 
			
		||||
    if (findMsgId) {
 | 
			
		||||
      findMsg.setAttribute("data-l10n-id", findMsgId);
 | 
			
		||||
    } else {
 | 
			
		||||
      findMsg.removeAttribute("data-l10n-id");
 | 
			
		||||
      findMsg.textContent = "";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this.updateResultsCount(matchesCount);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  updateResultsCount({ current = 0, total = 0 } = {}) {
 | 
			
		||||
    const limit = MATCHES_COUNT_LIMIT;
 | 
			
		||||
    let matchCountMsg = Promise.resolve("");
 | 
			
		||||
    const { findResultsCount } = this;
 | 
			
		||||
 | 
			
		||||
    if (total > 0) {
 | 
			
		||||
      matchCountMsg =
 | 
			
		||||
        total > limit
 | 
			
		||||
          ? this.l10n.get("pdfjs-find-match-count-limit", { limit })
 | 
			
		||||
          : this.l10n.get("pdfjs-find-match-count", { current, total });
 | 
			
		||||
      const limit = MATCHES_COUNT_LIMIT,
 | 
			
		||||
        isLimited = total > limit;
 | 
			
		||||
 | 
			
		||||
      findResultsCount.setAttribute(
 | 
			
		||||
        "data-l10n-id",
 | 
			
		||||
        `pdfjs-find-match-count${isLimited ? "-limit" : ""}`
 | 
			
		||||
      );
 | 
			
		||||
      findResultsCount.setAttribute(
 | 
			
		||||
        "data-l10n-args",
 | 
			
		||||
        JSON.stringify(isLimited ? { limit } : { current, total })
 | 
			
		||||
      );
 | 
			
		||||
    } else {
 | 
			
		||||
      findResultsCount.removeAttribute("data-l10n-id");
 | 
			
		||||
      findResultsCount.textContent = "";
 | 
			
		||||
    }
 | 
			
		||||
    matchCountMsg.then(msg => {
 | 
			
		||||
      this.findResultsCount.textContent = msg;
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  open() {
 | 
			
		||||
 | 
			
		||||
@ -19,7 +19,6 @@ import { BaseTreeViewer } from "./base_tree_viewer.js";
 | 
			
		||||
 * @typedef {Object} PDFLayerViewerOptions
 | 
			
		||||
 * @property {HTMLDivElement} container - The viewer element.
 | 
			
		||||
 * @property {EventBus} eventBus - The application event bus.
 | 
			
		||||
 * @property {IL10n} l10n - Localization service.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -32,7 +31,6 @@ import { BaseTreeViewer } from "./base_tree_viewer.js";
 | 
			
		||||
class PDFLayerViewer extends BaseTreeViewer {
 | 
			
		||||
  constructor(options) {
 | 
			
		||||
    super(options);
 | 
			
		||||
    this.l10n = options.l10n;
 | 
			
		||||
 | 
			
		||||
    this.eventBus._on("optionalcontentconfigchanged", evt => {
 | 
			
		||||
      this.#updateLayers(evt.promise);
 | 
			
		||||
@ -89,7 +87,7 @@ class PDFLayerViewer extends BaseTreeViewer {
 | 
			
		||||
  /**
 | 
			
		||||
   * @private
 | 
			
		||||
   */
 | 
			
		||||
  async _setNestedName(element, { name = null }) {
 | 
			
		||||
  _setNestedName(element, { name = null }) {
 | 
			
		||||
    if (typeof name === "string") {
 | 
			
		||||
      element.textContent = this._normalizeTextContent(name);
 | 
			
		||||
      return;
 | 
			
		||||
 | 
			
		||||
@ -182,9 +182,8 @@ class PDFPageView {
 | 
			
		||||
    div.className = "page";
 | 
			
		||||
    div.setAttribute("data-page-number", this.id);
 | 
			
		||||
    div.setAttribute("role", "region");
 | 
			
		||||
    this.l10n.get("pdfjs-page-landmark", { page: this.id }).then(msg => {
 | 
			
		||||
      div.setAttribute("aria-label", msg);
 | 
			
		||||
    });
 | 
			
		||||
    div.setAttribute("data-l10n-id", "pdfjs-page-landmark");
 | 
			
		||||
    div.setAttribute("data-l10n-args", JSON.stringify({ page: this.id }));
 | 
			
		||||
    this.div = div;
 | 
			
		||||
 | 
			
		||||
    this.#setDimensions();
 | 
			
		||||
@ -878,7 +877,6 @@ class PDFPageView {
 | 
			
		||||
        renderForms: this.#annotationMode === AnnotationMode.ENABLE_FORMS,
 | 
			
		||||
        linkService,
 | 
			
		||||
        downloadManager,
 | 
			
		||||
        l10n,
 | 
			
		||||
        enableScripting,
 | 
			
		||||
        hasJSActionsPromise,
 | 
			
		||||
        fieldObjectsPromise,
 | 
			
		||||
 | 
			
		||||
@ -69,8 +69,7 @@ class PDFPrintService {
 | 
			
		||||
    printContainer,
 | 
			
		||||
    printResolution,
 | 
			
		||||
    optionalContentConfigPromise = null,
 | 
			
		||||
    printAnnotationStoragePromise = null,
 | 
			
		||||
    l10n
 | 
			
		||||
    printAnnotationStoragePromise = null
 | 
			
		||||
  ) {
 | 
			
		||||
    this.pdfDocument = pdfDocument;
 | 
			
		||||
    this.pagesOverview = pagesOverview;
 | 
			
		||||
@ -80,7 +79,6 @@ class PDFPrintService {
 | 
			
		||||
      optionalContentConfigPromise || pdfDocument.getOptionalContentConfig();
 | 
			
		||||
    this._printAnnotationStoragePromise =
 | 
			
		||||
      printAnnotationStoragePromise || Promise.resolve();
 | 
			
		||||
    this.l10n = l10n;
 | 
			
		||||
    this.currentPage = -1;
 | 
			
		||||
    // The temporary canvas where renderPage paints one page at a time.
 | 
			
		||||
    this.scratchCanvas = document.createElement("canvas");
 | 
			
		||||
@ -151,12 +149,12 @@ class PDFPrintService {
 | 
			
		||||
    const renderNextPage = (resolve, reject) => {
 | 
			
		||||
      this.throwIfInactive();
 | 
			
		||||
      if (++this.currentPage >= pageCount) {
 | 
			
		||||
        renderProgress(pageCount, pageCount, this.l10n);
 | 
			
		||||
        renderProgress(pageCount, pageCount);
 | 
			
		||||
        resolve();
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      const index = this.currentPage;
 | 
			
		||||
      renderProgress(index, pageCount, this.l10n);
 | 
			
		||||
      renderProgress(index, pageCount);
 | 
			
		||||
      renderPage(
 | 
			
		||||
        this,
 | 
			
		||||
        this.pdfDocument,
 | 
			
		||||
@ -288,7 +286,7 @@ function abort() {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function renderProgress(index, total, l10n) {
 | 
			
		||||
function renderProgress(index, total) {
 | 
			
		||||
  if (typeof PDFJSDev === "undefined" && window.isGECKOVIEW) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
@ -297,9 +295,7 @@ function renderProgress(index, total, l10n) {
 | 
			
		||||
  const progressBar = dialog.querySelector("progress");
 | 
			
		||||
  const progressPerc = dialog.querySelector(".relative-progress");
 | 
			
		||||
  progressBar.value = progress;
 | 
			
		||||
  l10n.get("pdfjs-print-progress-percent", { progress }).then(msg => {
 | 
			
		||||
    progressPerc.textContent = msg;
 | 
			
		||||
  });
 | 
			
		||||
  progressPerc.setAttribute("data-l10n-args", JSON.stringify({ progress }));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
window.addEventListener(
 | 
			
		||||
@ -368,8 +364,7 @@ PDFPrintServiceFactory.instance = {
 | 
			
		||||
    printContainer,
 | 
			
		||||
    printResolution,
 | 
			
		||||
    optionalContentConfigPromise,
 | 
			
		||||
    printAnnotationStoragePromise,
 | 
			
		||||
    l10n
 | 
			
		||||
    printAnnotationStoragePromise
 | 
			
		||||
  ) {
 | 
			
		||||
    if (activeService) {
 | 
			
		||||
      throw new Error("The print service is created and active.");
 | 
			
		||||
@ -380,8 +375,7 @@ PDFPrintServiceFactory.instance = {
 | 
			
		||||
      printContainer,
 | 
			
		||||
      printResolution,
 | 
			
		||||
      optionalContentConfigPromise,
 | 
			
		||||
      printAnnotationStoragePromise,
 | 
			
		||||
      l10n
 | 
			
		||||
      printAnnotationStoragePromise
 | 
			
		||||
    );
 | 
			
		||||
    return activeService;
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
@ -111,7 +111,6 @@ class PDFSidebar {
 | 
			
		||||
    this._currentOutlineItemButton = elements.currentOutlineItemButton;
 | 
			
		||||
 | 
			
		||||
    this.eventBus = eventBus;
 | 
			
		||||
    this.l10n = l10n;
 | 
			
		||||
 | 
			
		||||
    this.#isRTL = l10n.getDirection() === "rtl";
 | 
			
		||||
    this.#addEventListeners();
 | 
			
		||||
 | 
			
		||||
@ -18,7 +18,6 @@
 | 
			
		||||
// eslint-disable-next-line max-len
 | 
			
		||||
/** @typedef {import("../src/display/display_utils").PageViewport} PageViewport */
 | 
			
		||||
/** @typedef {import("./event_utils").EventBus} EventBus */
 | 
			
		||||
/** @typedef {import("./interfaces").IL10n} IL10n */
 | 
			
		||||
/** @typedef {import("./interfaces").IPDFLinkService} IPDFLinkService */
 | 
			
		||||
/** @typedef {import("./interfaces").IRenderableView} IRenderableView */
 | 
			
		||||
// eslint-disable-next-line max-len
 | 
			
		||||
@ -42,7 +41,6 @@ const THUMBNAIL_WIDTH = 98; // px
 | 
			
		||||
 *   The default value is `null`.
 | 
			
		||||
 * @property {IPDFLinkService} linkService - The navigation/linking service.
 | 
			
		||||
 * @property {PDFRenderingQueue} renderingQueue - The rendering queue object.
 | 
			
		||||
 * @property {IL10n} l10n - Localization service.
 | 
			
		||||
 * @property {Object} [pageColors] - Overwrites background and foreground colors
 | 
			
		||||
 *   with user defined ones in order to improve readability in high contrast
 | 
			
		||||
 *   mode.
 | 
			
		||||
@ -93,7 +91,6 @@ class PDFThumbnailView {
 | 
			
		||||
    optionalContentConfigPromise,
 | 
			
		||||
    linkService,
 | 
			
		||||
    renderingQueue,
 | 
			
		||||
    l10n,
 | 
			
		||||
    pageColors,
 | 
			
		||||
  }) {
 | 
			
		||||
    this.id = id;
 | 
			
		||||
@ -114,13 +111,11 @@ class PDFThumbnailView {
 | 
			
		||||
    this.renderTask = null;
 | 
			
		||||
    this.renderingState = RenderingStates.INITIAL;
 | 
			
		||||
    this.resume = null;
 | 
			
		||||
    this.l10n = l10n;
 | 
			
		||||
 | 
			
		||||
    const anchor = document.createElement("a");
 | 
			
		||||
    anchor.href = linkService.getAnchorUrl("#page=" + id);
 | 
			
		||||
    this._thumbPageTitle.then(msg => {
 | 
			
		||||
      anchor.title = msg;
 | 
			
		||||
    });
 | 
			
		||||
    anchor.setAttribute("data-l10n-id", "pdfjs-thumb-page-title");
 | 
			
		||||
    anchor.setAttribute("data-l10n-args", this.#pageL10nArgs);
 | 
			
		||||
    anchor.onclick = function () {
 | 
			
		||||
      linkService.goToPage(id);
 | 
			
		||||
      return false;
 | 
			
		||||
@ -232,9 +227,8 @@ class PDFThumbnailView {
 | 
			
		||||
 | 
			
		||||
    const image = document.createElement("img");
 | 
			
		||||
    image.className = "thumbnailImage";
 | 
			
		||||
    this._thumbPageCanvas.then(msg => {
 | 
			
		||||
      image.setAttribute("aria-label", msg);
 | 
			
		||||
    });
 | 
			
		||||
    image.setAttribute("data-l10n-id", "pdfjs-thumb-page-canvas");
 | 
			
		||||
    image.setAttribute("data-l10n-args", this.#pageL10nArgs);
 | 
			
		||||
    image.src = reducedCanvas.toDataURL();
 | 
			
		||||
    this.image = image;
 | 
			
		||||
 | 
			
		||||
@ -423,16 +417,8 @@ class PDFThumbnailView {
 | 
			
		||||
    return canvas;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  get _thumbPageTitle() {
 | 
			
		||||
    return this.l10n.get("pdfjs-thumb-page-title", {
 | 
			
		||||
      page: this.pageLabel ?? this.id,
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  get _thumbPageCanvas() {
 | 
			
		||||
    return this.l10n.get("pdfjs-thumb-page-canvas", {
 | 
			
		||||
      page: this.pageLabel ?? this.id,
 | 
			
		||||
    });
 | 
			
		||||
  get #pageL10nArgs() {
 | 
			
		||||
    return JSON.stringify({ page: this.pageLabel ?? this.id });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
@ -441,17 +427,12 @@ class PDFThumbnailView {
 | 
			
		||||
  setPageLabel(label) {
 | 
			
		||||
    this.pageLabel = typeof label === "string" ? label : null;
 | 
			
		||||
 | 
			
		||||
    this._thumbPageTitle.then(msg => {
 | 
			
		||||
      this.anchor.title = msg;
 | 
			
		||||
    });
 | 
			
		||||
    this.anchor.setAttribute("data-l10n-args", this.#pageL10nArgs);
 | 
			
		||||
 | 
			
		||||
    if (this.renderingState !== RenderingStates.FINISHED) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this._thumbPageCanvas.then(msg => {
 | 
			
		||||
      this.image?.setAttribute("aria-label", msg);
 | 
			
		||||
    });
 | 
			
		||||
    this.image?.setAttribute("data-l10n-args", this.#pageL10nArgs);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -16,7 +16,6 @@
 | 
			
		||||
/** @typedef {import("../src/display/api").PDFDocumentProxy} PDFDocumentProxy */
 | 
			
		||||
/** @typedef {import("../src/display/api").PDFPageProxy} PDFPageProxy */
 | 
			
		||||
/** @typedef {import("./event_utils").EventBus} EventBus */
 | 
			
		||||
/** @typedef {import("./interfaces").IL10n} IL10n */
 | 
			
		||||
/** @typedef {import("./interfaces").IPDFLinkService} IPDFLinkService */
 | 
			
		||||
// eslint-disable-next-line max-len
 | 
			
		||||
/** @typedef {import("./pdf_rendering_queue").PDFRenderingQueue} PDFRenderingQueue */
 | 
			
		||||
@ -40,7 +39,6 @@ const THUMBNAIL_SELECTED_CLASS = "selected";
 | 
			
		||||
 * @property {EventBus} eventBus - The application event bus.
 | 
			
		||||
 * @property {IPDFLinkService} linkService - The navigation/linking service.
 | 
			
		||||
 * @property {PDFRenderingQueue} renderingQueue - The rendering queue object.
 | 
			
		||||
 * @property {IL10n} l10n - Localization service.
 | 
			
		||||
 * @property {Object} [pageColors] - Overwrites background and foreground colors
 | 
			
		||||
 *   with user defined ones in order to improve readability in high contrast
 | 
			
		||||
 *   mode.
 | 
			
		||||
@ -58,14 +56,12 @@ class PDFThumbnailViewer {
 | 
			
		||||
    eventBus,
 | 
			
		||||
    linkService,
 | 
			
		||||
    renderingQueue,
 | 
			
		||||
    l10n,
 | 
			
		||||
    pageColors,
 | 
			
		||||
  }) {
 | 
			
		||||
    this.container = container;
 | 
			
		||||
    this.eventBus = eventBus;
 | 
			
		||||
    this.linkService = linkService;
 | 
			
		||||
    this.renderingQueue = renderingQueue;
 | 
			
		||||
    this.l10n = l10n;
 | 
			
		||||
    this.pageColors = pageColors || null;
 | 
			
		||||
 | 
			
		||||
    this.scroll = watchScroll(this.container, this._scrollUpdated.bind(this));
 | 
			
		||||
@ -209,7 +205,6 @@ class PDFThumbnailViewer {
 | 
			
		||||
            optionalContentConfigPromise,
 | 
			
		||||
            linkService: this.linkService,
 | 
			
		||||
            renderingQueue: this.renderingQueue,
 | 
			
		||||
            l10n: this.l10n,
 | 
			
		||||
            pageColors: this.pageColors,
 | 
			
		||||
          });
 | 
			
		||||
          this._thumbnails.push(thumbnail);
 | 
			
		||||
 | 
			
		||||
@ -28,10 +28,9 @@ class Toolbar {
 | 
			
		||||
  /**
 | 
			
		||||
   * @param {ToolbarOptions} options
 | 
			
		||||
   * @param {EventBus} eventBus
 | 
			
		||||
   * @param {IL10n} _l10n - Localization service.
 | 
			
		||||
   * @param {Object} nimbusData - Nimbus configuration.
 | 
			
		||||
   */
 | 
			
		||||
  constructor(options, eventBus, _l10n, nimbusData) {
 | 
			
		||||
  constructor(options, eventBus, nimbusData) {
 | 
			
		||||
    this.#eventBus = eventBus;
 | 
			
		||||
    const buttons = [
 | 
			
		||||
      {
 | 
			
		||||
 | 
			
		||||
@ -49,12 +49,10 @@ class Toolbar {
 | 
			
		||||
  /**
 | 
			
		||||
   * @param {ToolbarOptions} options
 | 
			
		||||
   * @param {EventBus} eventBus
 | 
			
		||||
   * @param {IL10n} l10n - Localization service.
 | 
			
		||||
   */
 | 
			
		||||
  constructor(options, eventBus, l10n) {
 | 
			
		||||
  constructor(options, eventBus) {
 | 
			
		||||
    this.toolbar = options.container;
 | 
			
		||||
    this.eventBus = eventBus;
 | 
			
		||||
    this.l10n = l10n;
 | 
			
		||||
    this.buttons = [
 | 
			
		||||
      { element: options.previous, eventName: "previouspage" },
 | 
			
		||||
      { element: options.next, eventName: "nextpage" },
 | 
			
		||||
@ -252,22 +250,27 @@ class Toolbar {
 | 
			
		||||
    if (resetNumPages) {
 | 
			
		||||
      if (this.hasPageLabels) {
 | 
			
		||||
        items.pageNumber.type = "text";
 | 
			
		||||
 | 
			
		||||
        items.numPages.setAttribute("data-l10n-id", "pdfjs-page-of-pages");
 | 
			
		||||
      } else {
 | 
			
		||||
        items.pageNumber.type = "number";
 | 
			
		||||
        this.l10n.get("pdfjs-of-pages", { pagesCount }).then(msg => {
 | 
			
		||||
          items.numPages.textContent = msg;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        items.numPages.setAttribute("data-l10n-id", "pdfjs-of-pages");
 | 
			
		||||
        items.numPages.setAttribute(
 | 
			
		||||
          "data-l10n-args",
 | 
			
		||||
          JSON.stringify({ pagesCount })
 | 
			
		||||
        );
 | 
			
		||||
      }
 | 
			
		||||
      items.pageNumber.max = pagesCount;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (this.hasPageLabels) {
 | 
			
		||||
      items.pageNumber.value = this.pageLabel;
 | 
			
		||||
      this.l10n
 | 
			
		||||
        .get("pdfjs-page-of-pages", { pageNumber, pagesCount })
 | 
			
		||||
        .then(msg => {
 | 
			
		||||
          items.numPages.textContent = msg;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
      items.numPages.setAttribute(
 | 
			
		||||
        "data-l10n-args",
 | 
			
		||||
        JSON.stringify({ pageNumber, pagesCount })
 | 
			
		||||
      );
 | 
			
		||||
    } else {
 | 
			
		||||
      items.pageNumber.value = pageNumber;
 | 
			
		||||
    }
 | 
			
		||||
@ -278,11 +281,6 @@ class Toolbar {
 | 
			
		||||
    items.zoomOut.disabled = pageScale <= MIN_SCALE;
 | 
			
		||||
    items.zoomIn.disabled = pageScale >= MAX_SCALE;
 | 
			
		||||
 | 
			
		||||
    this.l10n
 | 
			
		||||
      .get("pdfjs-page-scale-percent", {
 | 
			
		||||
        scale: Math.round(pageScale * 10000) / 100,
 | 
			
		||||
      })
 | 
			
		||||
      .then(msg => {
 | 
			
		||||
    let predefinedValueFound = false;
 | 
			
		||||
    for (const option of items.scaleSelect.options) {
 | 
			
		||||
      if (option.value !== pageScaleValue) {
 | 
			
		||||
@ -293,10 +291,14 @@ class Toolbar {
 | 
			
		||||
      predefinedValueFound = true;
 | 
			
		||||
    }
 | 
			
		||||
    if (!predefinedValueFound) {
 | 
			
		||||
          items.customScaleOption.textContent = msg;
 | 
			
		||||
      items.customScaleOption.selected = true;
 | 
			
		||||
      items.customScaleOption.setAttribute(
 | 
			
		||||
        "data-l10n-args",
 | 
			
		||||
        JSON.stringify({
 | 
			
		||||
          scale: Math.round(pageScale * 10000) / 100,
 | 
			
		||||
        })
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
      });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  updateLoadingIndicatorState(loading = false) {
 | 
			
		||||
 | 
			
		||||
@ -379,7 +379,7 @@ See https://github.com/adobe-type-tools/cmap-resources
 | 
			
		||||
                    <option id="pageActualOption" title="" value="page-actual" data-l10n-id="pdfjs-page-scale-actual">Actual Size</option>
 | 
			
		||||
                    <option id="pageFitOption" title="" value="page-fit" data-l10n-id="pdfjs-page-scale-fit">Page Fit</option>
 | 
			
		||||
                    <option id="pageWidthOption" title="" value="page-width" data-l10n-id="pdfjs-page-scale-width">Page Width</option>
 | 
			
		||||
                    <option id="customScaleOption" title="" value="custom" disabled="disabled" hidden="true"></option>
 | 
			
		||||
                    <option id="customScaleOption" title="" value="custom" disabled="disabled" hidden="true" data-l10n-id="pdfjs-page-scale-percent" data-l10n-args='{ "scale": 0 }'>0%</option>
 | 
			
		||||
                    <option title="" value="0.5" data-l10n-id="pdfjs-page-scale-percent" data-l10n-args='{ "scale": 50 }'>50%</option>
 | 
			
		||||
                    <option title="" value="0.75" data-l10n-id="pdfjs-page-scale-percent" data-l10n-args='{ "scale": 75 }'>75%</option>
 | 
			
		||||
                    <option title="" value="1" data-l10n-id="pdfjs-page-scale-percent" data-l10n-args='{ "scale": 100 }'>100%</option>
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user