Merge pull request #17603 from Snuffleupagus/GenericL10n-fallback
Ensure that `GenericL10n` works if the locale files cannot be loaded
This commit is contained in:
commit
9588bceff5
@ -272,7 +272,7 @@ const PDFViewerApplication = {
|
||||
});
|
||||
this.pdfLinkService = linkService;
|
||||
|
||||
this.l10n = pdfjsViewer.NullL10n;
|
||||
this.l10n = new pdfjsViewer.GenericL10n();
|
||||
|
||||
const container = document.getElementById("viewerContainer");
|
||||
const pdfViewer = new pdfjsViewer.PDFViewer({
|
||||
|
@ -272,7 +272,7 @@ function createWebpackConfig(
|
||||
"web-com": "",
|
||||
"web-download_manager": "",
|
||||
"web-external_services": "",
|
||||
"web-l10n_utils": "web/stubs.js",
|
||||
"web-null_l10n": "",
|
||||
"web-pdf_attachment_viewer": "web/pdf_attachment_viewer.js",
|
||||
"web-pdf_cursor_tools": "web/pdf_cursor_tools.js",
|
||||
"web-pdf_document_properties": "web/pdf_document_properties.js",
|
||||
@ -294,6 +294,7 @@ function createWebpackConfig(
|
||||
viewerAlias["web-com"] = "web/chromecom.js";
|
||||
viewerAlias["web-download_manager"] = "web/download_manager.js";
|
||||
viewerAlias["web-external_services"] = "web/chromecom.js";
|
||||
viewerAlias["web-null_l10n"] = "web/l10n.js";
|
||||
viewerAlias["web-preferences"] = "web/chromecom.js";
|
||||
viewerAlias["web-print_service"] = "web/pdf_print_service.js";
|
||||
} else if (bundleDefines.GENERIC) {
|
||||
@ -308,13 +309,12 @@ function createWebpackConfig(
|
||||
viewerAlias["web-com"] = "web/genericcom.js";
|
||||
viewerAlias["web-download_manager"] = "web/download_manager.js";
|
||||
viewerAlias["web-external_services"] = "web/genericcom.js";
|
||||
viewerAlias["web-l10n_utils"] = "web/l10n_utils.js";
|
||||
viewerAlias["web-null_l10n"] = "web/genericl10n.js";
|
||||
viewerAlias["web-preferences"] = "web/genericcom.js";
|
||||
viewerAlias["web-print_service"] = "web/pdf_print_service.js";
|
||||
} else if (bundleDefines.MOZCENTRAL) {
|
||||
if (bundleDefines.GECKOVIEW) {
|
||||
const gvAlias = {
|
||||
"web-l10n_utils": "web/stubs.js",
|
||||
"web-toolbar": "web/toolbar-geckoview.js",
|
||||
};
|
||||
for (const key in viewerAlias) {
|
||||
@ -324,6 +324,7 @@ function createWebpackConfig(
|
||||
viewerAlias["web-com"] = "web/firefoxcom.js";
|
||||
viewerAlias["web-download_manager"] = "web/firefoxcom.js";
|
||||
viewerAlias["web-external_services"] = "web/firefoxcom.js";
|
||||
viewerAlias["web-null_l10n"] = "web/l10n.js";
|
||||
viewerAlias["web-preferences"] = "web/firefoxcom.js";
|
||||
viewerAlias["web-print_service"] = "web/firefox_print_service.js";
|
||||
}
|
||||
@ -1616,7 +1617,7 @@ function buildLibHelper(bundleDefines, inputStream, outputDir) {
|
||||
"display-node_utils": "./node_utils.js",
|
||||
"fluent-bundle": "../../../node_modules/@fluent/bundle/esm/index.js",
|
||||
"fluent-dom": "../../../node_modules/@fluent/dom/esm/index.js",
|
||||
"web-l10n_utils": "../web/l10n_utils.js",
|
||||
"web-null_l10n": "../web/genericl10n.js",
|
||||
},
|
||||
};
|
||||
const licenseHeaderLibre = fs
|
||||
|
@ -30,8 +30,6 @@ import { AnnotationLayerBuilder } from "../../web/annotation_layer_builder.js";
|
||||
import { DownloadManager } from "../../web/download_manager.js";
|
||||
import { EventBus } from "../../web/event_utils.js";
|
||||
import { GenericL10n } from "../../web/genericl10n.js";
|
||||
import { L10n } from "../../web/l10n.js";
|
||||
import { NullL10n } from "../../web/l10n_utils.js";
|
||||
import { PDFHistory } from "../../web/pdf_history.js";
|
||||
import { PDFPageView } from "../../web/pdf_page_view.js";
|
||||
import { PDFScriptingManager } from "../../web/pdf_scripting_manager.component.js";
|
||||
@ -54,7 +52,6 @@ describe("pdfviewer_api", function () {
|
||||
FindState,
|
||||
GenericL10n,
|
||||
LinkTarget,
|
||||
NullL10n,
|
||||
parseQueryString,
|
||||
PDFFindController,
|
||||
PDFHistory,
|
||||
@ -73,14 +70,4 @@ describe("pdfviewer_api", function () {
|
||||
XfaLayerBuilder,
|
||||
});
|
||||
});
|
||||
|
||||
it("checks that `NullL10n` implements all methods", function () {
|
||||
const methods = Object.getOwnPropertyNames(NullL10n).sort();
|
||||
|
||||
const baseMethods = Object.getOwnPropertyNames(L10n.prototype)
|
||||
.filter(m => m !== "constructor" && !m.startsWith("_"))
|
||||
.sort();
|
||||
|
||||
expect(methods).toEqual(baseMethods);
|
||||
});
|
||||
});
|
||||
|
@ -30,7 +30,7 @@
|
||||
"web-com": "../../web/genericcom.js",
|
||||
"web-download_manager": "../../web/download_manager.js",
|
||||
"web-external_services": "../../web/genericcom.js",
|
||||
"web-l10n_utils": "../../web/l10n_utils.js",
|
||||
"web-null_l10n": "../../web/genericl10n.js",
|
||||
"web-pdf_attachment_viewer": "../../web/pdf_attachment_viewer.js",
|
||||
"web-pdf_cursor_tools": "../../web/pdf_cursor_tools.js",
|
||||
"web-pdf_document_properties": "../../web/pdf_document_properties.js",
|
||||
|
@ -16,7 +16,7 @@
|
||||
"display-node_utils": ["./src/display/node_utils"],
|
||||
"fluent-bundle": ["./node_modules/@fluent/bundle/esm/index.js"],
|
||||
"fluent-dom": ["./node_modules/@fluent/dom/esm/index.js"],
|
||||
"web-l10n_utils": ["./web/l10n_utils"]
|
||||
"web-null_l10n": ["../web/genericl10n.js"]
|
||||
}
|
||||
},
|
||||
"files": ["src/pdf.js", "web/pdf_viewer.component.js"]
|
||||
|
@ -25,7 +25,7 @@
|
||||
/** @typedef {import("../src/display/annotation_layer.js").AnnotationLayer} AnnotationLayer */
|
||||
|
||||
import { AnnotationEditorLayer } from "pdfjs-lib";
|
||||
import { NullL10n } from "web-l10n_utils";
|
||||
import { GenericL10n } from "web-null_l10n";
|
||||
|
||||
/**
|
||||
* @typedef {Object} AnnotationEditorLayerBuilderOptions
|
||||
@ -55,7 +55,10 @@ class AnnotationEditorLayerBuilder {
|
||||
this.pageDiv = options.pageDiv;
|
||||
this.pdfPage = options.pdfPage;
|
||||
this.accessibilityManager = options.accessibilityManager;
|
||||
this.l10n = options.l10n || NullL10n;
|
||||
this.l10n = options.l10n;
|
||||
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
|
||||
this.l10n ||= new GenericL10n();
|
||||
}
|
||||
this.annotationEditorLayer = null;
|
||||
this.div = null;
|
||||
this._cancelled = false;
|
||||
|
@ -20,22 +20,34 @@ import { DOMLocalization } from "fluent-dom";
|
||||
import { fetchData } from "pdfjs-lib";
|
||||
import { L10n } from "./l10n.js";
|
||||
|
||||
function createBundle(lang, text) {
|
||||
const resource = new FluentResource(text);
|
||||
const bundle = new FluentBundle(lang);
|
||||
const errors = bundle.addResource(resource);
|
||||
if (errors.length) {
|
||||
console.error("L10n errors", errors);
|
||||
}
|
||||
return bundle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @implements {IL10n}
|
||||
*/
|
||||
class GenericL10n extends L10n {
|
||||
constructor(lang) {
|
||||
super({ lang });
|
||||
this._setL10n(
|
||||
new DOMLocalization(
|
||||
[],
|
||||
GenericL10n.#generateBundles.bind(
|
||||
|
||||
const generateBundles = !lang
|
||||
? GenericL10n.#generateBundlesFallback.bind(
|
||||
GenericL10n,
|
||||
this.getLanguage()
|
||||
)
|
||||
: GenericL10n.#generateBundles.bind(
|
||||
GenericL10n,
|
||||
"en-us",
|
||||
this.getLanguage()
|
||||
)
|
||||
)
|
||||
);
|
||||
);
|
||||
this._setL10n(new DOMLocalization([], generateBundles));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -63,6 +75,9 @@ class GenericL10n extends L10n {
|
||||
if (bundle) {
|
||||
yield bundle;
|
||||
}
|
||||
if (lang === "en-us") {
|
||||
yield this.#createBundleFallback(lang);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,20 +89,36 @@ class GenericL10n extends L10n {
|
||||
const url = new URL(path, baseURL);
|
||||
const text = await fetchData(url, /* type = */ "text");
|
||||
|
||||
const resource = new FluentResource(text);
|
||||
const bundle = new FluentBundle(lang);
|
||||
const errors = bundle.addResource(resource);
|
||||
if (errors.length) {
|
||||
console.error("L10n errors", errors);
|
||||
}
|
||||
return bundle;
|
||||
return createBundle(lang, text);
|
||||
}
|
||||
|
||||
static async #getPaths() {
|
||||
const { href } = document.querySelector(`link[type="application/l10n"]`);
|
||||
const paths = await fetchData(href, /* type = */ "json");
|
||||
try {
|
||||
const { href } = document.querySelector(`link[type="application/l10n"]`);
|
||||
const paths = await fetchData(href, /* type = */ "json");
|
||||
|
||||
return { baseURL: href.replace(/[^/]*$/, "") || "./", paths };
|
||||
return { baseURL: href.replace(/[^/]*$/, "") || "./", paths };
|
||||
} catch {}
|
||||
return { baseURL: "./", paths: Object.create(null) };
|
||||
}
|
||||
|
||||
static async *#generateBundlesFallback(lang) {
|
||||
yield this.#createBundleFallback(lang);
|
||||
}
|
||||
|
||||
static async #createBundleFallback(lang) {
|
||||
if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("TESTING")) {
|
||||
throw new Error("Not implemented: #createBundleFallback");
|
||||
}
|
||||
const text =
|
||||
typeof PDFJSDev === "undefined"
|
||||
? await fetchData(
|
||||
new URL(`./locale/${lang}/viewer.ftl`, window.location.href),
|
||||
/* type = */ "text"
|
||||
)
|
||||
: PDFJSDev.eval("DEFAULT_FTL");
|
||||
|
||||
return createBundle(lang, text);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -117,4 +117,6 @@ class L10n {
|
||||
}
|
||||
}
|
||||
|
||||
export { L10n };
|
||||
const GenericL10n = null;
|
||||
|
||||
export { GenericL10n, L10n };
|
||||
|
@ -1,87 +0,0 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
/** @typedef {import("./interfaces").IL10n} IL10n */
|
||||
|
||||
import { fetchData, shadow } from "pdfjs-lib";
|
||||
import { FluentBundle, FluentResource } from "fluent-bundle";
|
||||
import { DOMLocalization } from "fluent-dom";
|
||||
import { L10n } from "./l10n.js";
|
||||
|
||||
/**
|
||||
* @implements {IL10n}
|
||||
*/
|
||||
class ConstL10n extends L10n {
|
||||
constructor(lang) {
|
||||
super({ lang });
|
||||
this._setL10n(
|
||||
new DOMLocalization([], ConstL10n.#generateBundles.bind(ConstL10n, lang))
|
||||
);
|
||||
}
|
||||
|
||||
static async *#generateBundles(lang) {
|
||||
const text =
|
||||
typeof PDFJSDev === "undefined"
|
||||
? await fetchData(
|
||||
new URL(`./locale/${lang}/viewer.ftl`, window.location.href),
|
||||
/* type = */ "text"
|
||||
)
|
||||
: PDFJSDev.eval("DEFAULT_FTL");
|
||||
|
||||
const resource = new FluentResource(text);
|
||||
const bundle = new FluentBundle(lang);
|
||||
const errors = bundle.addResource(resource);
|
||||
if (errors.length) {
|
||||
console.error("L10n errors", errors);
|
||||
}
|
||||
yield bundle;
|
||||
}
|
||||
|
||||
static get instance() {
|
||||
return shadow(this, "instance", new ConstL10n("en-us"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* No-op implementation of the localization service.
|
||||
* @implements {IL10n}
|
||||
*/
|
||||
const NullL10n = {
|
||||
getLanguage() {
|
||||
return ConstL10n.instance.getLanguage();
|
||||
},
|
||||
|
||||
getDirection() {
|
||||
return ConstL10n.instance.getDirection();
|
||||
},
|
||||
|
||||
async get(ids, args = null, fallback) {
|
||||
return ConstL10n.instance.get(ids, args, fallback);
|
||||
},
|
||||
|
||||
async translate(element) {
|
||||
return ConstL10n.instance.translate(element);
|
||||
},
|
||||
|
||||
pause() {
|
||||
return ConstL10n.instance.pause();
|
||||
},
|
||||
|
||||
resume() {
|
||||
return ConstL10n.instance.resume();
|
||||
},
|
||||
};
|
||||
|
||||
export { NullL10n };
|
@ -43,7 +43,7 @@ import { AnnotationEditorLayerBuilder } from "./annotation_editor_layer_builder.
|
||||
import { AnnotationLayerBuilder } from "./annotation_layer_builder.js";
|
||||
import { compatibilityParams } from "./app_options.js";
|
||||
import { DrawLayerBuilder } from "./draw_layer_builder.js";
|
||||
import { NullL10n } from "web-l10n_utils";
|
||||
import { GenericL10n } from "web-null_l10n";
|
||||
import { SimpleLinkService } from "./pdf_link_service.js";
|
||||
import { StructTreeLayerBuilder } from "./struct_tree_layer_builder.js";
|
||||
import { TextAccessibilityManager } from "./text_accessibility.js";
|
||||
@ -157,7 +157,10 @@ class PDFPageView {
|
||||
|
||||
this.eventBus = options.eventBus;
|
||||
this.renderingQueue = options.renderingQueue;
|
||||
this.l10n = options.l10n || NullL10n;
|
||||
this.l10n = options.l10n;
|
||||
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
|
||||
this.l10n ||= new GenericL10n();
|
||||
}
|
||||
|
||||
this.renderTask = null;
|
||||
this.resume = null;
|
||||
@ -214,7 +217,7 @@ class PDFPageView {
|
||||
}
|
||||
|
||||
// Ensure that Fluent is connected in e.g. the COMPONENTS build.
|
||||
if (this.l10n === NullL10n) {
|
||||
if (!options.l10n) {
|
||||
this.l10n.translate(this.div);
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,6 @@ import { AnnotationLayerBuilder } from "./annotation_layer_builder.js";
|
||||
import { DownloadManager } from "./download_manager.js";
|
||||
import { EventBus } from "./event_utils.js";
|
||||
import { GenericL10n } from "./genericl10n.js";
|
||||
import { NullL10n } from "./l10n_utils.js";
|
||||
import { PDFHistory } from "./pdf_history.js";
|
||||
import { PDFPageView } from "./pdf_page_view.js";
|
||||
import { PDFScriptingManager } from "./pdf_scripting_manager.component.js";
|
||||
@ -54,7 +53,6 @@ export {
|
||||
FindState,
|
||||
GenericL10n,
|
||||
LinkTarget,
|
||||
NullL10n,
|
||||
parseQueryString,
|
||||
PDFFindController,
|
||||
PDFHistory,
|
||||
|
@ -63,7 +63,7 @@ import {
|
||||
VERTICAL_PADDING,
|
||||
watchScroll,
|
||||
} from "./ui_utils.js";
|
||||
import { NullL10n } from "web-l10n_utils";
|
||||
import { GenericL10n } from "web-null_l10n";
|
||||
import { PDFPageView } from "./pdf_page_view.js";
|
||||
import { PDFRenderingQueue } from "./pdf_rendering_queue.js";
|
||||
import { SimpleLinkService } from "./pdf_link_service.js";
|
||||
@ -286,7 +286,10 @@ class PDFViewer {
|
||||
this.removePageBorders = options.removePageBorders || false;
|
||||
}
|
||||
this.maxCanvasPixels = options.maxCanvasPixels;
|
||||
this.l10n = options.l10n || NullL10n;
|
||||
this.l10n = options.l10n;
|
||||
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
|
||||
this.l10n ||= new GenericL10n();
|
||||
}
|
||||
this.#enablePermissions = options.enablePermissions || false;
|
||||
this.pageColors = options.pageColors || null;
|
||||
|
||||
@ -327,7 +330,7 @@ class PDFViewer {
|
||||
|
||||
if (
|
||||
(typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) &&
|
||||
this.l10n === NullL10n
|
||||
!options.l10n
|
||||
) {
|
||||
// Ensure that Fluent is connected in e.g. the COMPONENTS build.
|
||||
this.l10n.translate(this.container);
|
||||
|
18
web/stubs.js
18
web/stubs.js
@ -1,18 +0,0 @@
|
||||
/* Copyright 2023 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.
|
||||
*/
|
||||
|
||||
const NullL10n = null;
|
||||
|
||||
export { NullL10n };
|
@ -63,7 +63,7 @@ See https://github.com/adobe-type-tools/cmap-resources
|
||||
"web-com": "./genericcom.js",
|
||||
"web-download_manager": "./download_manager.js",
|
||||
"web-external_services": "./genericcom.js",
|
||||
"web-l10n_utils": "./l10n_utils.js",
|
||||
"web-null_l10n": "./genericl10n.js",
|
||||
"web-pdf_attachment_viewer": "./stubs-geckoview.js",
|
||||
"web-pdf_cursor_tools": "./stubs-geckoview.js",
|
||||
"web-pdf_document_properties": "./stubs-geckoview.js",
|
||||
|
@ -72,7 +72,7 @@ See https://github.com/adobe-type-tools/cmap-resources
|
||||
"web-com": "./genericcom.js",
|
||||
"web-download_manager": "./download_manager.js",
|
||||
"web-external_services": "./genericcom.js",
|
||||
"web-l10n_utils": "./l10n_utils.js",
|
||||
"web-null_l10n": "./genericl10n.js",
|
||||
"web-pdf_attachment_viewer": "./pdf_attachment_viewer.js",
|
||||
"web-pdf_cursor_tools": "./pdf_cursor_tools.js",
|
||||
"web-pdf_document_properties": "./pdf_document_properties.js",
|
||||
|
Loading…
Reference in New Issue
Block a user