Merge pull request #13050 from Snuffleupagus/l10n-fallback

Collect all l10n fallback strings, used in the viewer, in one helper function (PR 12981 follow-up)
This commit is contained in:
Tim van der Meij 2021-03-04 23:46:48 +01:00 committed by GitHub
commit 4b49db7c95
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 238 additions and 272 deletions

View File

@ -14,7 +14,7 @@
*/ */
import { AnnotationLayer } from "pdfjs-lib"; import { AnnotationLayer } from "pdfjs-lib";
import { NullL10n } from "./ui_utils.js"; import { NullL10n } from "./l10n_utils.js";
import { SimpleLinkService } from "./pdf_link_service.js"; import { SimpleLinkService } from "./pdf_link_service.js";
/** /**

View File

@ -260,28 +260,6 @@ const PDFViewerApplication = {
_scriptingInstance: null, _scriptingInstance: null,
_mouseState: Object.create(null), _mouseState: Object.create(null),
_localizeMessage(key, args = null) {
const DEFAULT_L10N_STRINGS = {
error_file: "File: {{file}}",
error_line: "Line: {{line}}",
error_message: "Message: {{message}}",
error_stack: "Stack: {{stack}}",
error_version_info: "PDF.js v{{version}} (build: {{build}})",
invalid_file_error: "Invalid or corrupted PDF file.",
loading_error: "An error occurred while loading the PDF.",
missing_file_error: "Missing PDF file.",
printing_not_ready: "Warning: The PDF is not fully loaded for printing.",
printing_not_supported:
"Warning: Printing is not fully supported by this browser.",
rendering_error: "An error occurred while rendering the page.",
unexpected_response_error: "Unexpected server response.",
web_fonts_disabled:
"Web fonts are disabled: unable to use embedded PDF fonts.",
};
return this.l10n.get(key || "", args, DEFAULT_L10N_STRINGS[key]);
},
// Called once when the document is loaded. // Called once when the document is loaded.
async initialize(appConfig) { async initialize(appConfig) {
this.preferences = this.externalServices.createPreferences(); this.preferences = this.externalServices.createPreferences();
@ -741,7 +719,7 @@ const PDFViewerApplication = {
this.open(file, args); this.open(file, args);
}, },
onError: err => { onError: err => {
this._localizeMessage("loading_error").then(msg => { this.l10n.get("loading_error").then(msg => {
this._documentError(msg, err); this._documentError(msg, err);
}); });
}, },
@ -973,7 +951,7 @@ const PDFViewerApplication = {
} else if (exception instanceof UnexpectedResponseException) { } else if (exception instanceof UnexpectedResponseException) {
key = "unexpected_response_error"; key = "unexpected_response_error";
} }
return this._localizeMessage(key).then(msg => { return this.l10n.get(key).then(msg => {
this._documentError(msg, { message: exception?.message }); this._documentError(msg, { message: exception?.message });
throw exception; throw exception;
}); });
@ -1128,28 +1106,28 @@ const PDFViewerApplication = {
*/ */
_otherError(message, moreInfo = null) { _otherError(message, moreInfo = null) {
const moreInfoText = [ const moreInfoText = [
this._localizeMessage("error_version_info", { this.l10n.get("error_version_info", {
version: version || "?", version: version || "?",
build: build || "?", build: build || "?",
}), }),
]; ];
if (moreInfo) { if (moreInfo) {
moreInfoText.push( moreInfoText.push(
this._localizeMessage("error_message", { message: moreInfo.message }) this.l10n.get("error_message", { message: moreInfo.message })
); );
if (moreInfo.stack) { if (moreInfo.stack) {
moreInfoText.push( moreInfoText.push(
this._localizeMessage("error_stack", { stack: moreInfo.stack }) this.l10n.get("error_stack", { stack: moreInfo.stack })
); );
} else { } else {
if (moreInfo.filename) { if (moreInfo.filename) {
moreInfoText.push( moreInfoText.push(
this._localizeMessage("error_file", { file: moreInfo.filename }) this.l10n.get("error_file", { file: moreInfo.filename })
); );
} }
if (moreInfo.lineNumber) { if (moreInfo.lineNumber) {
moreInfoText.push( moreInfoText.push(
this._localizeMessage("error_line", { line: moreInfo.lineNumber }) this.l10n.get("error_line", { line: moreInfo.lineNumber })
); );
} }
} }
@ -2021,7 +1999,7 @@ const PDFViewerApplication = {
} }
if (!this.supportsPrinting) { if (!this.supportsPrinting) {
this._localizeMessage("printing_not_supported").then(msg => { this.l10n.get("printing_not_supported").then(msg => {
this._otherError(msg); this._otherError(msg);
}); });
return; return;
@ -2030,7 +2008,7 @@ const PDFViewerApplication = {
// The beforePrint is a sync method and we need to know layout before // The beforePrint is a sync method and we need to know layout before
// returning from this method. Ensure that we can get sizes of the pages. // returning from this method. Ensure that we can get sizes of the pages.
if (!this.pdfViewer.pageViewsReady) { if (!this.pdfViewer.pageViewsReady) {
this._localizeMessage("printing_not_ready").then(msg => { this.l10n.get("printing_not_ready").then(msg => {
// eslint-disable-next-line no-alert // eslint-disable-next-line no-alert
window.alert(msg); window.alert(msg);
}); });
@ -2354,7 +2332,7 @@ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
throw new Error("file origin does not match viewer's"); throw new Error("file origin does not match viewer's");
} }
} catch (ex) { } catch (ex) {
PDFViewerApplication._localizeMessage("loading_error").then(msg => { PDFViewerApplication.l10n.get("loading_error").then(msg => {
PDFViewerApplication._documentError(msg, { message: ex?.message }); PDFViewerApplication._documentError(msg, { message: ex?.message });
}); });
throw ex; throw ex;
@ -2465,7 +2443,7 @@ function webViewerInitialized() {
if (!PDFViewerApplication.supportsDocumentFonts) { if (!PDFViewerApplication.supportsDocumentFonts) {
AppOptions.set("disableFontFace", true); AppOptions.set("disableFontFace", true);
PDFViewerApplication._localizeMessage("web_fonts_disabled").then(msg => { PDFViewerApplication.l10n.get("web_fonts_disabled").then(msg => {
console.warn(msg); console.warn(msg);
}); });
} }
@ -2497,7 +2475,7 @@ function webViewerInitialized() {
try { try {
webViewerOpenFileViaURL(file); webViewerOpenFileViaURL(file);
} catch (reason) { } catch (reason) {
PDFViewerApplication._localizeMessage("loading_error").then(msg => { PDFViewerApplication.l10n.get("loading_error").then(msg => {
PDFViewerApplication._documentError(msg, reason); PDFViewerApplication._documentError(msg, reason);
}); });
} }
@ -2568,7 +2546,7 @@ function webViewerPageRendered({ pageNumber, timestamp, error }) {
} }
if (error) { if (error) {
PDFViewerApplication._localizeMessage("rendering_error").then(msg => { PDFViewerApplication.l10n.get("rendering_error").then(msg => {
PDFViewerApplication._otherError(msg, error); PDFViewerApplication._otherError(msg, error);
}); });
} }

View File

@ -25,7 +25,6 @@ import {
isValidSpreadMode, isValidSpreadMode,
MAX_AUTO_SCALE, MAX_AUTO_SCALE,
moveToEndOfArray, moveToEndOfArray,
NullL10n,
PresentationModeState, PresentationModeState,
RendererType, RendererType,
SCROLLBAR_PADDING, SCROLLBAR_PADDING,
@ -39,6 +38,7 @@ import {
} from "./ui_utils.js"; } from "./ui_utils.js";
import { PDFRenderingQueue, RenderingStates } from "./pdf_rendering_queue.js"; import { PDFRenderingQueue, RenderingStates } from "./pdf_rendering_queue.js";
import { AnnotationLayerBuilder } from "./annotation_layer_builder.js"; import { AnnotationLayerBuilder } from "./annotation_layer_builder.js";
import { NullL10n } from "./l10n_utils.js";
import { PDFPageView } from "./pdf_page_view.js"; import { PDFPageView } from "./pdf_page_view.js";
import { SimpleLinkService } from "./pdf_link_service.js"; import { SimpleLinkService } from "./pdf_link_service.js";
import { TextLayerBuilder } from "./text_layer_builder.js"; import { TextLayerBuilder } from "./text_layer_builder.js";

View File

@ -18,6 +18,7 @@ import { DefaultExternalServices, PDFViewerApplication } from "./app.js";
import { isPdfFile, PDFDataRangeTransport, shadow } from "pdfjs-lib"; import { isPdfFile, PDFDataRangeTransport, shadow } from "pdfjs-lib";
import { BasePreferences } from "./preferences.js"; import { BasePreferences } from "./preferences.js";
import { DEFAULT_SCALE_VALUE } from "./ui_utils.js"; import { DEFAULT_SCALE_VALUE } from "./ui_utils.js";
import { getL10nFallback } from "./l10n_utils.js";
if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("MOZCENTRAL")) { if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("MOZCENTRAL")) {
throw new Error( throw new Error(
@ -200,8 +201,8 @@ class MozL10n {
return this.mozL10n.getDirection(); return this.mozL10n.getDirection();
} }
async get(property, args, fallback) { async get(key, args = null, fallback = getL10nFallback(key, args)) {
return this.mozL10n.get(property, args, fallback); return this.mozL10n.get(key, args, fallback);
} }
async translate(element) { async translate(element) {

View File

@ -14,6 +14,7 @@
*/ */
import "../external/webL10n/l10n.js"; import "../external/webL10n/l10n.js";
import { getL10nFallback } from "./l10n_utils.js";
const webL10n = document.webL10n; const webL10n = document.webL10n;
@ -37,9 +38,9 @@ class GenericL10n {
return l10n.getDirection(); return l10n.getDirection();
} }
async get(property, args, fallback) { async get(key, args = null, fallback = getL10nFallback(key, args)) {
const l10n = await this._ready; const l10n = await this._ready;
return l10n.get(property, args, fallback); return l10n.get(key, args, fallback);
} }
async translate(element) { async translate(element) {

127
web/l10n_utils.js Normal file
View File

@ -0,0 +1,127 @@
/* 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.
*/
/**
* A subset of the l10n strings in the `l10n/en-US/viewer.properties` file.
*/
const DEFAULT_L10N_STRINGS = {
of_pages: "of {{pagesCount}}",
page_of_pages: "({{pageNumber}} of {{pagesCount}})",
document_properties_kb: "{{size_kb}} KB ({{size_b}} bytes)",
document_properties_mb: "{{size_mb}} MB ({{size_b}} bytes)",
document_properties_date_string: "{{date}}, {{time}}",
document_properties_page_size_unit_inches: "in",
document_properties_page_size_unit_millimeters: "mm",
document_properties_page_size_orientation_portrait: "portrait",
document_properties_page_size_orientation_landscape: "landscape",
document_properties_page_size_name_a3: "A3",
document_properties_page_size_name_a4: "A4",
document_properties_page_size_name_letter: "Letter",
document_properties_page_size_name_legal: "Legal",
document_properties_page_size_dimension_string:
"{{width}} × {{height}} {{unit}} ({{orientation}})",
document_properties_page_size_dimension_name_string:
"{{width}} × {{height}} {{unit}} ({{name}}, {{orientation}})",
document_properties_linearized_yes: "Yes",
document_properties_linearized_no: "No",
print_progress_percent: "{{progress}}%",
"toggle_sidebar.title": "Toggle Sidebar",
"toggle_sidebar_notification2.title":
"Toggle Sidebar (document contains outline/attachments/layers)",
additional_layers: "Additional Layers",
page_canvas: "Page {{page}}",
thumb_page_title: "Page {{page}}",
thumb_page_canvas: "Thumbnail of Page {{page}}",
find_reached_top: "Reached top of document, continued from bottom",
find_reached_bottom: "Reached end of document, continued from top",
"find_match_count[one]": "{{current}} of {{total}} match",
"find_match_count[other]": "{{current}} of {{total}} matches",
"find_match_count_limit[one]": "More than {{limit}} match",
"find_match_count_limit[other]": "More than {{limit}} matches",
find_not_found: "Phrase not found",
error_version_info: "PDF.js v{{version}} (build: {{build}})",
error_message: "Message: {{message}}",
error_stack: "Stack: {{stack}}",
error_file: "File: {{file}}",
error_line: "Line: {{line}}",
rendering_error: "An error occurred while rendering the page.",
page_scale_width: "Page Width",
page_scale_fit: "Page Fit",
page_scale_auto: "Automatic Zoom",
page_scale_actual: "Actual Size",
page_scale_percent: "{{scale}}%",
loading_error: "An error occurred while loading the PDF.",
invalid_file_error: "Invalid or corrupted PDF file.",
missing_file_error: "Missing PDF file.",
unexpected_response_error: "Unexpected server response.",
printing_not_supported:
"Warning: Printing is not fully supported by this browser.",
printing_not_ready: "Warning: The PDF is not fully loaded for printing.",
web_fonts_disabled:
"Web fonts are disabled: unable to use embedded PDF fonts.",
};
function getL10nFallback(key, args) {
switch (key) {
case "find_match_count":
key = `find_match_count[${args.total === 1 ? "one" : "other"}]`;
break;
case "find_match_count_limit":
key = `find_match_count_limit[${args.limit === 1 ? "one" : "other"}]`;
break;
}
return DEFAULT_L10N_STRINGS[key] || "";
}
// Replaces {{arguments}} with their values.
function formatL10nValue(text, args) {
if (!args) {
return text;
}
return text.replace(/\{\{\s*(\w+)\s*\}\}/g, (all, name) => {
return name in args ? args[name] : "{{" + name + "}}";
});
}
/**
* No-op implementation of the localization service.
* @implements {IL10n}
*/
const NullL10n = {
async getLanguage() {
return "en-us";
},
async getDirection() {
return "ltr";
},
async get(key, args = null, fallback = getL10nFallback(key, args)) {
return formatL10nValue(fallback, args);
},
async translate(element) {},
};
export { getL10nFallback, NullL10n };

View File

@ -67,34 +67,18 @@ class PasswordPrompt {
); );
} }
open() { async open() {
this.overlayManager.open(this.overlayName).then(() => { await this.overlayManager.open(this.overlayName);
if (
!this._isViewerEmbedded ||
this.reason === PasswordResponses.INCORRECT_PASSWORD
) {
this.input.focus();
}
let promptString; const passwordIncorrect =
if (this.reason === PasswordResponses.INCORRECT_PASSWORD) { this.reason === PasswordResponses.INCORRECT_PASSWORD;
promptString = this.l10n.get(
"password_invalid",
null,
"Invalid password. Please try again."
);
} else {
promptString = this.l10n.get(
"password_label",
null,
"Enter the password to open this PDF file."
);
}
promptString.then(msg => { if (!this._isViewerEmbedded || passwordIncorrect) {
this.label.textContent = msg; this.input.focus();
}); }
}); this.label.textContent = await this.l10n.get(
`password_${passwordIncorrect ? "invalid" : "label"}`
);
} }
close() { close() {

View File

@ -255,27 +255,16 @@ class PDFDocumentProperties {
* @private * @private
*/ */
async _parseFileSize(fileSize = 0) { async _parseFileSize(fileSize = 0) {
const kb = fileSize / 1024; const kb = fileSize / 1024,
mb = kb / 1024;
if (!kb) { if (!kb) {
return undefined; return undefined;
} else if (kb < 1024) {
return this.l10n.get(
"document_properties_kb",
{
size_kb: (+kb.toPrecision(3)).toLocaleString(),
size_b: fileSize.toLocaleString(),
},
"{{size_kb}} KB ({{size_b}} bytes)"
);
} }
return this.l10n.get( return this.l10n.get(`document_properties_${mb >= 1 ? "mb" : "kb"}`, {
"document_properties_mb", size_mb: mb >= 1 && (+mb.toPrecision(3)).toLocaleString(),
{ size_kb: (+kb.toPrecision(3)).toLocaleString(),
size_mb: (+(kb / 1024).toPrecision(3)).toLocaleString(), size_b: fileSize.toLocaleString(),
size_b: fileSize.toLocaleString(), });
},
"{{size_mb}} MB ({{size_b}} bytes)"
);
} }
/** /**
@ -304,7 +293,6 @@ class PDFDocumentProperties {
height: Math.round(pageSizeInches.height * 25.4 * 10) / 10, height: Math.round(pageSizeInches.height * 25.4 * 10) / 10,
}; };
let pageName = null;
let rawName = let rawName =
getPageName(sizeInches, isPortrait, US_PAGE_NAMES) || getPageName(sizeInches, isPortrait, US_PAGE_NAMES) ||
getPageName(sizeMillimeters, isPortrait, METRIC_PAGE_NAMES); getPageName(sizeMillimeters, isPortrait, METRIC_PAGE_NAMES);
@ -345,46 +333,35 @@ class PDFDocumentProperties {
} }
} }
} }
if (rawName) {
pageName = this.l10n.get(
"document_properties_page_size_name_" + rawName.toLowerCase(),
null,
rawName
);
}
return Promise.all([ const [{ width, height }, unit, name, orientation] = await Promise.all([
this._isNonMetricLocale ? sizeInches : sizeMillimeters, this._isNonMetricLocale ? sizeInches : sizeMillimeters,
this.l10n.get( this.l10n.get(
"document_properties_page_size_unit_" + `document_properties_page_size_unit_${
(this._isNonMetricLocale ? "inches" : "millimeters"), this._isNonMetricLocale ? "inches" : "millimeters"
null, }`
this._isNonMetricLocale ? "in" : "mm"
), ),
pageName, rawName &&
this.l10n.get(
`document_properties_page_size_name_${rawName.toLowerCase()}`
),
this.l10n.get( this.l10n.get(
"document_properties_page_size_orientation_" + `document_properties_page_size_orientation_${
(isPortrait ? "portrait" : "landscape"), isPortrait ? "portrait" : "landscape"
null, }`
isPortrait ? "portrait" : "landscape"
), ),
]).then(([{ width, height }, unit, name, orientation]) => { ]);
return this.l10n.get(
"document_properties_page_size_dimension_" + return this.l10n.get(
(name ? "name_" : "") + `document_properties_page_size_dimension_${name ? "name_" : ""}string`,
"string", {
{ width: width.toLocaleString(),
width: width.toLocaleString(), height: height.toLocaleString(),
height: height.toLocaleString(), unit,
unit, name,
name, orientation,
orientation, }
}, );
"{{width}} × {{height}} {{unit}} (" +
(name ? "{{name}}, " : "") +
"{{orientation}})"
);
});
} }
/** /**
@ -395,14 +372,10 @@ class PDFDocumentProperties {
if (!dateObject) { if (!dateObject) {
return undefined; return undefined;
} }
return this.l10n.get( return this.l10n.get("document_properties_date_string", {
"document_properties_date_string", date: dateObject.toLocaleDateString(),
{ time: dateObject.toLocaleTimeString(),
date: dateObject.toLocaleDateString(), });
time: dateObject.toLocaleTimeString(),
},
"{{date}}, {{time}}"
);
} }
/** /**
@ -410,9 +383,7 @@ class PDFDocumentProperties {
*/ */
_parseLinearization(isLinearized) { _parseLinearization(isLinearized) {
return this.l10n.get( return this.l10n.get(
"document_properties_linearized_" + (isLinearized ? "yes" : "no"), `document_properties_linearized_${isLinearized ? "yes" : "no"}`
null,
isLinearized ? "Yes" : "No"
); );
} }
} }

View File

@ -103,41 +103,26 @@ class PDFFindBar {
} }
updateUIState(state, previous, matchesCount) { updateUIState(state, previous, matchesCount) {
let findMsg = ""; let findMsg = Promise.resolve("");
let status = ""; let status = "";
switch (state) { switch (state) {
case FindState.FOUND: case FindState.FOUND:
break; break;
case FindState.PENDING: case FindState.PENDING:
status = "pending"; status = "pending";
break; break;
case FindState.NOT_FOUND: case FindState.NOT_FOUND:
findMsg = this.l10n.get("find_not_found", null, "Phrase not found"); findMsg = this.l10n.get("find_not_found");
status = "notFound"; status = "notFound";
break; break;
case FindState.WRAPPED: case FindState.WRAPPED:
if (previous) { findMsg = this.l10n.get(`find_reached_${previous ? "top" : "bottom"}`);
findMsg = this.l10n.get(
"find_reached_top",
null,
"Reached top of document, continued from bottom"
);
} else {
findMsg = this.l10n.get(
"find_reached_bottom",
null,
"Reached end of document, continued from top"
);
}
break; break;
} }
this.findField.setAttribute("data-status", status); this.findField.setAttribute("data-status", status);
Promise.resolve(findMsg).then(msg => { findMsg.then(msg => {
this.findMsg.textContent = msg; this.findMsg.textContent = msg;
this._adjustWidth(); this._adjustWidth();
}); });
@ -147,54 +132,30 @@ class PDFFindBar {
updateResultsCount({ current = 0, total = 0 } = {}) { updateResultsCount({ current = 0, total = 0 } = {}) {
const limit = MATCHES_COUNT_LIMIT; const limit = MATCHES_COUNT_LIMIT;
let matchesCountMsg = ""; let matchCountMsg = Promise.resolve("");
if (total > 0) { if (total > 0) {
if (total > limit) { if (total > limit) {
let key = "find_match_count_limit";
if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("MOZCENTRAL")) { if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("MOZCENTRAL")) {
// TODO: Remove this hard-coded `[other]` form once plural support has // TODO: Remove this hard-coded `[other]` form once plural support has
// been implemented in the mozilla-central specific `l10n.js` file. // been implemented in the mozilla-central specific `l10n.js` file.
matchesCountMsg = this.l10n.get( key += "[other]";
"find_match_count_limit[other]",
{
limit,
},
"More than {{limit}} matches"
);
} else {
matchesCountMsg = this.l10n.get(
"find_match_count_limit",
{
limit,
},
"More than {{limit}} match" + (limit !== 1 ? "es" : "")
);
} }
matchCountMsg = this.l10n.get(key, { limit });
} else { } else {
let key = "find_match_count";
if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("MOZCENTRAL")) { if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("MOZCENTRAL")) {
// TODO: Remove this hard-coded `[other]` form once plural support has // TODO: Remove this hard-coded `[other]` form once plural support has
// been implemented in the mozilla-central specific `l10n.js` file. // been implemented in the mozilla-central specific `l10n.js` file.
matchesCountMsg = this.l10n.get( key += "[other]";
"find_match_count[other]",
{
current,
total,
},
"{{current}} of {{total}} matches"
);
} else {
matchesCountMsg = this.l10n.get(
"find_match_count",
{
current,
total,
},
"{{current}} of {{total}} match" + (total !== 1 ? "es" : "")
);
} }
matchCountMsg = this.l10n.get(key, { current, total });
} }
} }
Promise.resolve(matchesCountMsg).then(msg => { matchCountMsg.then(msg => {
this.findResultsCount.textContent = msg; this.findResultsCount.textContent = msg;
this.findResultsCount.classList.toggle("hidden", !total); this.findResultsCount.classList.toggle("hidden", !total);
// Since `updateResultsCount` may be called from `PDFFindController`, // Since `updateResultsCount` may be called from `PDFFindController`,

View File

@ -87,11 +87,7 @@ class PDFLayerViewer extends BaseTreeViewer {
element.textContent = this._normalizeTextContent(name); element.textContent = this._normalizeTextContent(name);
return; return;
} }
element.textContent = await this.l10n.get( element.textContent = await this.l10n.get("additional_layers");
"additional_layers",
null,
"Additional Layers"
);
element.style.fontStyle = "italic"; element.style.fontStyle = "italic";
} }

View File

@ -18,7 +18,6 @@ import {
CSS_UNITS, CSS_UNITS,
DEFAULT_SCALE, DEFAULT_SCALE,
getOutputScale, getOutputScale,
NullL10n,
RendererType, RendererType,
roundToDivide, roundToDivide,
TextLayerMode, TextLayerMode,
@ -28,6 +27,7 @@ import {
RenderingCancelledException, RenderingCancelledException,
SVGGraphics, SVGGraphics,
} from "pdfjs-lib"; } from "pdfjs-lib";
import { NullL10n } from "./l10n_utils.js";
import { RenderingStates } from "./pdf_rendering_queue.js"; import { RenderingStates } from "./pdf_rendering_queue.js";
import { viewerCompatibilityParams } from "./viewer_compatibility.js"; import { viewerCompatibilityParams } from "./viewer_compatibility.js";
@ -576,11 +576,9 @@ class PDFPageView {
const viewport = this.viewport; const viewport = this.viewport;
const canvas = document.createElement("canvas"); const canvas = document.createElement("canvas");
this.l10n this.l10n.get("page_canvas", { page: this.id }).then(msg => {
.get("page_canvas", { page: this.id }, "Page {{page}}") canvas.setAttribute("aria-label", msg);
.then(msg => { });
canvas.setAttribute("aria-label", msg);
});
// Keep the canvas hidden until the first draw callback, or until drawing // Keep the canvas hidden until the first draw callback, or until drawing
// is complete when `!this.renderingQueue`, to prevent black flickering. // is complete when `!this.renderingQueue`, to prevent black flickering.

View File

@ -308,7 +308,7 @@ function renderProgress(index, total, l10n) {
const progressBar = progressContainer.querySelector("progress"); const progressBar = progressContainer.querySelector("progress");
const progressPerc = progressContainer.querySelector(".relative-progress"); const progressPerc = progressContainer.querySelector(".relative-progress");
progressBar.value = progress; progressBar.value = progress;
l10n.get("print_progress_percent", { progress }, progress + "%").then(msg => { l10n.get("print_progress_percent", { progress }).then(msg => {
progressPerc.textContent = msg; progressPerc.textContent = msg;
}); });
} }

View File

@ -339,15 +339,9 @@ class PDFSidebar {
* @private * @private
*/ */
_showUINotification() { _showUINotification() {
this.l10n this.l10n.get("toggle_sidebar_notification2.title").then(msg => {
.get( this.toggleButton.title = msg;
"toggle_sidebar_notification2.title", });
null,
"Toggle Sidebar (document contains outline/attachments/layers)"
)
.then(msg => {
this.toggleButton.title = msg;
});
if (!this.isOpen) { if (!this.isOpen) {
// Only show the notification on the `toggleButton` if the sidebar is // Only show the notification on the `toggleButton` if the sidebar is
@ -367,11 +361,9 @@ class PDFSidebar {
} }
if (reset) { if (reset) {
this.l10n this.l10n.get("toggle_sidebar.title").then(msg => {
.get("toggle_sidebar.title", null, "Toggle Sidebar") this.toggleButton.title = msg;
.then(msg => { });
this.toggleButton.title = msg;
});
} }
} }

View File

@ -467,19 +467,15 @@ class PDFThumbnailView {
} }
get _thumbPageTitle() { get _thumbPageTitle() {
return this.l10n.get( return this.l10n.get("thumb_page_title", {
"thumb_page_title", page: this.pageLabel ?? this.id,
{ page: this.pageLabel ?? this.id }, });
"Page {{page}}"
);
} }
get _thumbPageCanvas() { get _thumbPageCanvas() {
return this.l10n.get( return this.l10n.get("thumb_page_canvas", {
"thumb_page_canvas", page: this.pageLabel ?? this.id,
{ page: this.pageLabel ?? this.id }, });
"Thumbnail of Page {{page}}"
);
} }
/** /**

View File

@ -21,10 +21,11 @@ import {
DefaultTextLayerFactory, DefaultTextLayerFactory,
TextLayerBuilder, TextLayerBuilder,
} from "./text_layer_builder.js"; } from "./text_layer_builder.js";
import { EventBus, NullL10n, ProgressBar } from "./ui_utils.js"; import { EventBus, ProgressBar } from "./ui_utils.js";
import { PDFLinkService, SimpleLinkService } from "./pdf_link_service.js"; import { PDFLinkService, SimpleLinkService } from "./pdf_link_service.js";
import { DownloadManager } from "./download_manager.js"; import { DownloadManager } from "./download_manager.js";
import { GenericL10n } from "./genericl10n.js"; import { GenericL10n } from "./genericl10n.js";
import { NullL10n } from "./l10n_utils.js";
import { PDFFindController } from "./pdf_find_controller.js"; import { PDFFindController } from "./pdf_find_controller.js";
import { PDFHistory } from "./pdf_history.js"; import { PDFHistory } from "./pdf_history.js";
import { PDFPageView } from "./pdf_page_view.js"; import { PDFPageView } from "./pdf_page_view.js";

View File

@ -177,26 +177,18 @@ class Toolbar {
items.pageNumber.type = "text"; items.pageNumber.type = "text";
} else { } else {
items.pageNumber.type = "number"; items.pageNumber.type = "number";
this.l10n this.l10n.get("of_pages", { pagesCount }).then(msg => {
.get("of_pages", { pagesCount }, "of {{pagesCount}}") items.numPages.textContent = msg;
.then(msg => { });
items.numPages.textContent = msg;
});
} }
items.pageNumber.max = pagesCount; items.pageNumber.max = pagesCount;
} }
if (this.hasPageLabels) { if (this.hasPageLabels) {
items.pageNumber.value = this.pageLabel; items.pageNumber.value = this.pageLabel;
this.l10n this.l10n.get("page_of_pages", { pageNumber, pagesCount }).then(msg => {
.get( items.numPages.textContent = msg;
"page_of_pages", });
{ pageNumber, pagesCount },
"({{pageNumber}} of {{pagesCount}})"
)
.then(msg => {
items.numPages.textContent = msg;
});
} else { } else {
items.pageNumber.value = pageNumber; items.pageNumber.value = pageNumber;
} }
@ -207,9 +199,8 @@ class Toolbar {
items.zoomOut.disabled = pageScale <= MIN_SCALE; items.zoomOut.disabled = pageScale <= MIN_SCALE;
items.zoomIn.disabled = pageScale >= MAX_SCALE; items.zoomIn.disabled = pageScale >= MAX_SCALE;
const customScale = Math.round(pageScale * 10000) / 100;
this.l10n this.l10n
.get("page_scale_percent", { scale: customScale }, "{{scale}}%") .get("page_scale_percent", { scale: Math.round(pageScale * 10000) / 100 })
.then(msg => { .then(msg => {
let predefinedValueFound = false; let predefinedValueFound = false;
for (const option of items.scaleSelect.options) { for (const option of items.scaleSelect.options) {
@ -242,10 +233,10 @@ class Toolbar {
const { items, l10n } = this; const { items, l10n } = this;
const predefinedValuesPromise = Promise.all([ const predefinedValuesPromise = Promise.all([
l10n.get("page_scale_auto", null, "Automatic Zoom"), l10n.get("page_scale_auto"),
l10n.get("page_scale_actual", null, "Actual Size"), l10n.get("page_scale_actual"),
l10n.get("page_scale_fit", null, "Page Fit"), l10n.get("page_scale_fit"),
l10n.get("page_scale_width", null, "Page Width"), l10n.get("page_scale_width"),
]); ]);
// The temporary canvas is used to measure text length in the DOM. // The temporary canvas is used to measure text length in the DOM.

View File

@ -69,36 +69,6 @@ const SpreadMode = {
// Used by `PDFViewerApplication`, and by the API unit-tests. // Used by `PDFViewerApplication`, and by the API unit-tests.
const AutoPrintRegExp = /\bprint\s*\(/; const AutoPrintRegExp = /\bprint\s*\(/;
// Replaces {{arguments}} with their values.
function formatL10nValue(text, args) {
if (!args) {
return text;
}
return text.replace(/\{\{\s*(\w+)\s*\}\}/g, (all, name) => {
return name in args ? args[name] : "{{" + name + "}}";
});
}
/**
* No-op implementation of the localization service.
* @implements {IL10n}
*/
const NullL10n = {
async getLanguage() {
return "en-us";
},
async getDirection() {
return "ltr";
},
async get(property, args, fallback) {
return formatL10nValue(fallback, args);
},
async translate(element) {},
};
/** /**
* Returns scale factor for the canvas. It makes sense for the HiDPI displays. * Returns scale factor for the canvas. It makes sense for the HiDPI displays.
* @returns {Object} The object with horizontal (sx) and vertical (sy) * @returns {Object} The object with horizontal (sx) and vertical (sy)
@ -1057,7 +1027,6 @@ export {
noContextMenuHandler, noContextMenuHandler,
normalizeWheelEventDelta, normalizeWheelEventDelta,
normalizeWheelEventDirection, normalizeWheelEventDirection,
NullL10n,
parseQueryString, parseQueryString,
PresentationModeState, PresentationModeState,
ProgressBar, ProgressBar,