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:
commit
4b49db7c95
@ -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";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
48
web/app.js
48
web/app.js
@ -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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -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";
|
||||||
|
@ -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) {
|
||||||
|
@ -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
127
web/l10n_utils.js
Normal 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 };
|
@ -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() {
|
||||||
|
@ -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"
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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`,
|
||||||
|
@ -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";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
@ -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;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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}}"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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";
|
||||||
|
@ -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.
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user