mirror of
https://github.com/Pomax/BezierInfo-2.git
synced 2025-09-02 21:02:49 +02:00
better localization
This commit is contained in:
@@ -102,18 +102,42 @@ drawCurveCoordinates() {
|
||||
}
|
||||
|
||||
onKeyDown() {
|
||||
this.mark = false;
|
||||
if (this.keyboard[`ArrowDown`]) {
|
||||
this.step--;
|
||||
if (this.step < 10) this.step = 10;
|
||||
this.stepDown();
|
||||
}
|
||||
if (this.keyboard[`ArrowUp`]) {
|
||||
this.step++;
|
||||
if (this.step > 90) this.step = 90;
|
||||
this.stepUp();
|
||||
}
|
||||
redraw();
|
||||
}
|
||||
|
||||
stepDown(value = 1) {
|
||||
this.step -= value;
|
||||
if (this.step < 10) this.step = 10;
|
||||
}
|
||||
|
||||
stepUp(value = 1) {
|
||||
this.step += value;
|
||||
if (this.step > 90) this.step = 90;
|
||||
}
|
||||
|
||||
onMouseDown() {
|
||||
this.mark = this.cursor.y;
|
||||
}
|
||||
|
||||
onMouseUp() {
|
||||
this.mark = false;
|
||||
}
|
||||
|
||||
onMouseMove() {
|
||||
this.curve.update();
|
||||
|
||||
if (this.mark) {
|
||||
let diff = this.mark - this.cursor.y,
|
||||
mapped = map(diff, -this.height/2, this.height/2, 10, 90, true);
|
||||
this.step = mapped | 0;
|
||||
}
|
||||
|
||||
redraw();
|
||||
}
|
@@ -279,6 +279,58 @@ class GraphicsAPI extends BaseAPI {
|
||||
this.line({ x: 0, y }, { x: this.width, y });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* math functions
|
||||
*/
|
||||
floor(v) {
|
||||
return Math.floor(v);
|
||||
}
|
||||
|
||||
ceil(v) {
|
||||
return Math.ceil(v);
|
||||
}
|
||||
|
||||
round(v) {
|
||||
return Math.round(v);
|
||||
}
|
||||
|
||||
abs(v) {
|
||||
return Math.abs(v);
|
||||
}
|
||||
|
||||
sin(v) {
|
||||
return Math.sin(v);
|
||||
}
|
||||
|
||||
cos(v) {
|
||||
return Math.cos(v);
|
||||
}
|
||||
|
||||
tan(v) {
|
||||
return Math.tan(v);
|
||||
}
|
||||
|
||||
sqrt(v) {
|
||||
return Math.sqrt(v);
|
||||
}
|
||||
|
||||
atan2(dy, dx) {
|
||||
return Math.atan2(dy, dx);
|
||||
}
|
||||
|
||||
pow(v, p) {
|
||||
return Math.pow(v, p);
|
||||
}
|
||||
|
||||
map(v, s, e, ns, ne, constrain = false) {
|
||||
const i1 = e - s,
|
||||
i2 = ne - ns,
|
||||
p = v - s;
|
||||
let r = ns + (p * i2) / i1;
|
||||
if (constrain) r = r < ns ? ns : r > ne ? ne : r;
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
export { GraphicsAPI, Bezier, Vector };
|
||||
|
@@ -1,53 +0,0 @@
|
||||
export default {
|
||||
"defaultLocale": "en-GB",
|
||||
"title": {
|
||||
"en-GB": "A Primer on Bézier Curves",
|
||||
"ja-JP": "ベジェ曲線入門",
|
||||
"zh-CN": "贝塞尔曲线底漆"
|
||||
},
|
||||
"subtitle": {
|
||||
"en-GB": "A free, online book for when you really need to know how to do Bézier things.",
|
||||
"ja-JP": "A free, online book for when you really need to know how to do Bézier things.",
|
||||
"zh-CN": "A free, online book for when you really need to know how to do Bézier things."
|
||||
},
|
||||
"description": {
|
||||
"en-GB": "A detailed explanation of Bézier curves, and how to do the many things that we commonly want to do with them.",
|
||||
"ja-JP": "A detailed explanation of Bézier curves, and how to do the many things that we commonly want to do with them.",
|
||||
"zh-CN": "A detailed explanation of Bézier curves, and how to do the many things that we commonly want to do with them."
|
||||
},
|
||||
"tocLabel": {
|
||||
"en-GB": "Table of Contents",
|
||||
"ja-JP": "目次",
|
||||
"zh-CN": "目录"
|
||||
},
|
||||
"localeName": {
|
||||
"en-GB": "English",
|
||||
"zh-CN": "中文",
|
||||
"ja-JP": "日本語"
|
||||
},
|
||||
"langSwitchLabel": {
|
||||
"en-GB": "Read this in your own language:",
|
||||
"zh-CN": "Read this in your own language:",
|
||||
"ja-JP": "Read this in your own language:"
|
||||
},
|
||||
"langHelpLabel": {
|
||||
"en-GB": "Don't see your language listed? <a href=\"https://github.com/Pomax/BezierInfo-2/wiki/localize\">Help translate this content!</a>",
|
||||
"zh-CN": "Don't see your language listed? <a href=\"https://github.com/Pomax/BezierInfo-2/wiki/localize\">Help translate this content!</a>",
|
||||
"ja-JP": "Don't see your language listed? <a href=\"https://github.com/Pomax/BezierInfo-2/wiki/localize\">Help translate this content!</a>"
|
||||
},
|
||||
"disabledMessage": {
|
||||
"en-GB": "Scripts are disabled. Showing fallback image.",
|
||||
"zh-CN": "Scripts are disabled. Showing fallback image.",
|
||||
"ja-JP": "Scripts are disabled. Showing fallback image."
|
||||
},
|
||||
"changelogTitle": {
|
||||
"en-GB": "What's new?",
|
||||
"zh-CN": "What's new?",
|
||||
"ja-JP": "What's new?"
|
||||
},
|
||||
"changelogDescription": {
|
||||
"en-GB": "This primer is a living document, and so depending on when you last look at it, there may be new content. Click the following link to expand this section to have a look at what got added, when.",
|
||||
"zh-CN": "This primer is a living document, and so depending on when you last look at it, there may be new content. Click the following link to expand this section to have a look at what got added, when.",
|
||||
"ja-JP": "This primer is a living document, and so depending on when you last look at it, there may be new content. Click the following link to expand this section to have a look at what got added, when."
|
||||
}
|
||||
}
|
@@ -14,7 +14,8 @@
|
||||
"url": "https://github.com/Pomax/bezierinfo/issues"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "run-s build",
|
||||
"start": "run-s lint build",
|
||||
"lint": "prettier ./tools --write",
|
||||
"build": "node ./tools/build.js",
|
||||
"test": "run-p server browser",
|
||||
"server": "http-server -p 8000 --cors",
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import LocaleStrings from "./locale-strings.js";
|
||||
import getAllChapterFiles from "./build/get-all-chapter-files.js";
|
||||
import processLocale from "./build/process-locale.js";
|
||||
import createIndexPages from "./build/create-index-page.js";
|
||||
@@ -9,9 +10,9 @@ import createIndexPages from "./build/create-index-page.js";
|
||||
*/
|
||||
getAllChapterFiles().then((chapterFiles) => {
|
||||
const languageCodes = Object.keys(chapterFiles);
|
||||
|
||||
languageCodes.forEach(async (locale) => {
|
||||
const chapters = await processLocale(locale, chapterFiles);
|
||||
createIndexPages(locale, chapters, languageCodes);
|
||||
const localeStrings = new LocaleStrings(locale);
|
||||
const chapters = await processLocale(locale, localeStrings, chapterFiles);
|
||||
createIndexPages(locale, localeStrings, chapters);
|
||||
});
|
||||
});
|
||||
|
@@ -8,14 +8,18 @@ nunjucks.configure(".", { autoescape: false });
|
||||
/**
|
||||
* ...docs go here...
|
||||
*/
|
||||
export default async function convertMarkDown(chapter, locale, markdown) {
|
||||
markdown = injectGraphicsFallback(chapter, locale, markdown);
|
||||
export default async function convertMarkDown(
|
||||
chapter,
|
||||
localeStrings,
|
||||
markdown
|
||||
) {
|
||||
markdown = injectGraphicsFallback(chapter, localeStrings, markdown);
|
||||
|
||||
const { data, latex } = extractLaTeX(markdown);
|
||||
|
||||
await Promise.all(
|
||||
Object.keys(latex).map(async (key, pos) => {
|
||||
const svg = await latexToSVG(latex[key], chapter, locale, pos + 1);
|
||||
const svg = await latexToSVG(latex[key], chapter, localeStrings, pos + 1);
|
||||
return (latex[key] = svg);
|
||||
})
|
||||
);
|
||||
|
@@ -3,28 +3,23 @@ import path from "path";
|
||||
import prettier from "prettier";
|
||||
import generateLangSwitcher from "./generate-lang-switcher.js";
|
||||
import nunjucks from "nunjucks";
|
||||
import localeStrings from "../../locale-strings.js";
|
||||
import sectionOrder from "../../chapters/toc.js";
|
||||
import changelog from "../../changelog.js";
|
||||
|
||||
const defaultLocale = localeStrings.defaultLocale;
|
||||
|
||||
nunjucks.configure(".", { autoescape: false });
|
||||
|
||||
/**
|
||||
* ...docs go here...
|
||||
*/
|
||||
export default async function createIndexPages(locale, chapters, languages) {
|
||||
let base = ``;
|
||||
|
||||
if (locale !== defaultLocale) {
|
||||
base = `<base href="..">`;
|
||||
}
|
||||
|
||||
const langSwitcher = generateLangSwitcher(locale, languages, defaultLocale);
|
||||
|
||||
export default async function createIndexPages(
|
||||
locale,
|
||||
localeStrings,
|
||||
chapters
|
||||
) {
|
||||
const defaultLocale = localeStrings.getDefaultLocale();
|
||||
const base = locale !== defaultLocale ? `<base href="..">` : ``;
|
||||
const langSwitcher = generateLangSwitcher(localeStrings);
|
||||
const toc = {};
|
||||
|
||||
const preface = `<section id="preface">${
|
||||
chapters[sectionOrder[0]]
|
||||
}</section>`;
|
||||
@@ -40,10 +35,12 @@ export default async function createIndexPages(locale, chapters, languages) {
|
||||
});
|
||||
|
||||
let changeLogHTML = [];
|
||||
Object.keys(changelog).forEach(period => {
|
||||
let changes = changelog[period].map(change => `<li>${change}</li>`).join(`\n`);
|
||||
Object.keys(changelog).forEach((period) => {
|
||||
let changes = changelog[period]
|
||||
.map((change) => `<li>${change}</li>`)
|
||||
.join(`\n`);
|
||||
changeLogHTML.push(`<h2>${period}</h2><ul>${changes}</ul>`);
|
||||
})
|
||||
});
|
||||
|
||||
// Set up the templating context
|
||||
const context = {
|
||||
@@ -57,11 +54,7 @@ export default async function createIndexPages(locale, chapters, languages) {
|
||||
};
|
||||
|
||||
// And inject all the relevant locale strings
|
||||
Object.keys(localeStrings).forEach((key) => {
|
||||
if (localeStrings[key][locale]) {
|
||||
context[key] = localeStrings[key][locale];
|
||||
}
|
||||
});
|
||||
localeStrings.extendContext(context);
|
||||
|
||||
const index = nunjucks.render(`index.template.html`, context);
|
||||
|
||||
|
@@ -1,9 +1,8 @@
|
||||
import localeStrings from "../../locale-strings.js";
|
||||
export default function generateLangSwitcher(localeStrings) {
|
||||
const defaultLocale = localeStrings.getDefaultLocale();
|
||||
|
||||
const defaultLocale = localeStrings.defaultLocale;
|
||||
|
||||
export default function generateLangSwitcher(currentLocale, allLocales) {
|
||||
return allLocales
|
||||
return localeStrings
|
||||
.getAllLocaleCodes()
|
||||
.map((locale) => {
|
||||
let link;
|
||||
if (locale === defaultLocale) {
|
||||
@@ -11,7 +10,8 @@ export default function generateLangSwitcher(currentLocale, allLocales) {
|
||||
} else {
|
||||
link = `./${locale}/index.html`;
|
||||
}
|
||||
return `<li><a href="${link}">${localeStrings.localeName[locale]}</a></li>`;
|
||||
let localeName = localeStrings.getLocaleName(locale);
|
||||
return `<li><a href="${link}">${localeName}</a></li>`;
|
||||
})
|
||||
.join(`\n`);
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import fs from "fs-extra";
|
||||
import path from "path";
|
||||
import rewriteGraphicsElement from "./rewrite-graphics-element.js";
|
||||
import localeStrings from "../../locale-strings.js";
|
||||
import localeStrings from "../locale-strings.js";
|
||||
|
||||
const defaultLocale = localeStrings.defaultLocale;
|
||||
|
||||
@@ -29,7 +29,9 @@ export default async function generatePlaceHolders(locale, markdown) {
|
||||
} while (pos !== -1);
|
||||
|
||||
const keys = Object.keys(elements);
|
||||
const sourcePaths = keys.map(key => elements[key].match(/src="([^"]+)"/)[1]);
|
||||
const sourcePaths = keys.map(
|
||||
(key) => elements[key].match(/src="([^"]+)"/)[1]
|
||||
);
|
||||
|
||||
await Promise.all(
|
||||
sourcePaths.map(async (srcPath, i) => {
|
||||
@@ -61,8 +63,9 @@ export default async function generatePlaceHolders(locale, markdown) {
|
||||
// console.log(`Writing placeholder to ${filename}`);
|
||||
fs.ensureDirSync(path.dirname(destPath));
|
||||
fs.writeFileSync(filename, imageData);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
catch (e) { console.error(e); }
|
||||
})
|
||||
);
|
||||
}
|
||||
|
@@ -11,7 +11,6 @@ const BASEDIR = path.join(__dirname, "..", "..");
|
||||
*/
|
||||
export default /* async */ function getAllChapterFiles() {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
glob(path.join(BASEDIR, `chapters/**/content*md`), (err, files) => {
|
||||
if (err) reject(err);
|
||||
|
||||
|
@@ -1,15 +1,19 @@
|
||||
export default function cleanUp(latex) {
|
||||
// strip any \[ and \], which is a block-level LaTeX markup indicator for MathJax:
|
||||
latex = latex.replace(/^'/,'').replace(/'$/,'').replace('\\[','').replace('\\]','');
|
||||
latex = latex
|
||||
.replace(/^'/, "")
|
||||
.replace(/'$/, "")
|
||||
.replace("\\[", "")
|
||||
.replace("\\]", "");
|
||||
|
||||
// wrap some known functor words in italics markup
|
||||
['Bézier'].forEach(term => {
|
||||
latex = latex.replace(new RegExp(term, 'g'), '\\textit{' + term + '}');
|
||||
["Bézier"].forEach((term) => {
|
||||
latex = latex.replace(new RegExp(term, "g"), "\\textit{" + term + "}");
|
||||
});
|
||||
|
||||
// also unindent the LaTeX.
|
||||
var indent = false;
|
||||
var lines = latex.split('\n').filter(line => !!line.trim());
|
||||
var lines = latex.split("\n").filter((line) => !!line.trim());
|
||||
var clean = function (line, idx) {
|
||||
if (!indent) {
|
||||
var matched = line.match(/^(\s+)/);
|
||||
@@ -18,10 +22,10 @@ export default function cleanUp(latex) {
|
||||
}
|
||||
}
|
||||
if (indent) {
|
||||
lines[idx] = line.replace(indent,'').trim();
|
||||
lines[idx] = line.replace(indent, "").trim();
|
||||
}
|
||||
}
|
||||
lines.forEach(clean);
|
||||
latex = lines.join('\n');
|
||||
return latex;
|
||||
};
|
||||
lines.forEach(clean);
|
||||
latex = lines.join("\n");
|
||||
return latex;
|
||||
}
|
||||
|
@@ -47,7 +47,7 @@ export default async function latexToSVG(latex, chapter, locale, block) {
|
||||
"\\usepackage{xeCJK}",
|
||||
"\\xeCJKsetup{CJKmath=true}",
|
||||
"\\setCJKmainfont{gbsn00lp.ttf}",
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
// The same goes for Japanese, although we obviously want a different
|
||||
@@ -69,13 +69,16 @@ export default async function latexToSVG(latex, chapter, locale, block) {
|
||||
`\\usepackage{color}`,
|
||||
`\\usepackage{amsmath}`,
|
||||
`\\usepackage{unicode-math}`,
|
||||
].concat(fonts).concat([
|
||||
]
|
||||
.concat(fonts)
|
||||
.concat([
|
||||
`\\begin{document}`,
|
||||
`\\[`,
|
||||
cleanUp(latex),
|
||||
`\\]`,
|
||||
`\\end{document}`,
|
||||
]).join(`\n`)
|
||||
])
|
||||
.join(`\n`)
|
||||
);
|
||||
|
||||
// Finally: run the conversion
|
||||
|
@@ -1,9 +1,13 @@
|
||||
import localeStrings from "../../../locale-strings.js";
|
||||
|
||||
/**
|
||||
* ...docs go here...
|
||||
*/
|
||||
export default function injectGraphicsFallback(chapter, locale, markdown) {
|
||||
export default function injectGraphicsFallback(
|
||||
chapter,
|
||||
localeStrings,
|
||||
markdown
|
||||
) {
|
||||
const translate = localeStrings.translate;
|
||||
|
||||
let pos = -1,
|
||||
data = markdown,
|
||||
startmark = `<graphics-element`,
|
||||
@@ -22,7 +26,7 @@ export default function injectGraphicsFallback(chapter, locale, markdown) {
|
||||
return `width="${width}" height="${height}" src="${src}">
|
||||
<fallback-image>
|
||||
<img width="${width}px" height="${height}px" src="${img}" loading="lazy">
|
||||
${localeStrings.disabledMessage[locale]}
|
||||
${translate`disabledMessage`}
|
||||
</fallback-image>`;
|
||||
}
|
||||
);
|
||||
|
@@ -4,12 +4,10 @@ import convertMarkDown from "./convert-markdown.js";
|
||||
import generatePlaceHolders from "./generate-placeholders.js";
|
||||
import nunjucks from "nunjucks";
|
||||
import toc from "../../chapters/toc.js";
|
||||
import localeStrings from "../../locale-strings.js";
|
||||
|
||||
const moduleURL = new URL(import.meta.url);
|
||||
const __dirname = path.dirname(moduleURL.href.replace(`file:///`, ``));
|
||||
|
||||
const defaultLocale = localeStrings.defaultLocale;
|
||||
const sectionList = toc.map((v) =>
|
||||
path.posix.join(
|
||||
__dirname.split(path.sep).join(path.posix.sep),
|
||||
@@ -25,7 +23,14 @@ nunjucks.configure(".", { autoescape: false });
|
||||
/**
|
||||
* ...docs go here...
|
||||
*/
|
||||
export default async function processLocale(locale, chapterFiles) {
|
||||
export default async function processLocale(
|
||||
locale,
|
||||
localeStrings,
|
||||
chapterFiles
|
||||
) {
|
||||
const defaultLocale = localeStrings.getDefaultLocale();
|
||||
const translate = localeStrings.translate;
|
||||
|
||||
const localeFiles = chapterFiles[locale];
|
||||
let localized = 0;
|
||||
let missing = 0;
|
||||
@@ -53,10 +58,7 @@ export default async function processLocale(locale, chapterFiles) {
|
||||
localeFiles.map(async (file) => {
|
||||
const chapter = file.match(/chapters\/([^/]+)\/content./)[1];
|
||||
const markdown = fs.readFileSync(file).toString("utf8");
|
||||
const replaced = nunjucks.renderString(markdown, {
|
||||
disableMessage: `<span>${localeStrings.disabledMessage[locale]}</span>`,
|
||||
});
|
||||
const converted = await convertMarkDown(chapter, locale, replaced);
|
||||
const converted = await convertMarkDown(chapter, localeStrings, markdown);
|
||||
chapters[chapter] = converted;
|
||||
generatePlaceHolders(locale, converted); // ← this is super fancy functionality.
|
||||
})
|
||||
|
@@ -3,12 +3,12 @@ import performCodeSurgery from "../../lib/custom-element/lib/perform-code-surger
|
||||
import prettier from "prettier";
|
||||
|
||||
export default function rewriteGraphicsElement(code, width, height) {
|
||||
|
||||
const split = splitCodeSections(code);
|
||||
const globalCode = split.quasiGlobal;
|
||||
const classCode = performCodeSurgery(split.classCode);
|
||||
|
||||
return prettier.format(`
|
||||
return prettier.format(
|
||||
`
|
||||
import CanvasBuilder from 'canvas';
|
||||
import { GraphicsAPI, Bezier, Vector } from "../../lib/custom-element/api/graphics-api.js";
|
||||
|
||||
@@ -33,5 +33,7 @@ export default function rewriteGraphicsElement(code, width, height) {
|
||||
const canvas = example.canvas;
|
||||
|
||||
export { canvas };
|
||||
`, { parser: `babel` });
|
||||
};
|
||||
`,
|
||||
{ parser: `babel` }
|
||||
);
|
||||
}
|
||||
|
110
tools/locale-strings.js
Normal file
110
tools/locale-strings.js
Normal file
@@ -0,0 +1,110 @@
|
||||
const defaultLocale = "en-GB";
|
||||
|
||||
const localeStringData = {
|
||||
title: {
|
||||
"en-GB": "A Primer on Bézier Curves",
|
||||
"ja-JP": "ベジェ曲線入門",
|
||||
"zh-CN": "贝塞尔曲线底漆",
|
||||
},
|
||||
subtitle: {
|
||||
"en-GB":
|
||||
"A free, online book for when you really need to know how to do Bézier things.",
|
||||
},
|
||||
description: {
|
||||
"en-GB":
|
||||
"A detailed explanation of Bézier curves, and how to do the many things that we commonly want to do with them.",
|
||||
},
|
||||
tocLabel: {
|
||||
"en-GB": "Table of Contents",
|
||||
"ja-JP": "目次",
|
||||
"zh-CN": "目录",
|
||||
},
|
||||
localeName: {
|
||||
"en-GB": "English",
|
||||
"zh-CN": "中文",
|
||||
"ja-JP": "日本語",
|
||||
},
|
||||
langSwitchLabel: {
|
||||
"en-GB": "Read this in your own language:",
|
||||
},
|
||||
langHelpLabel: {
|
||||
"en-GB":
|
||||
'Don\'t see your language listed? <a href="https://github.com/Pomax/BezierInfo-2/wiki/localize">Help translate this content!</a>',
|
||||
},
|
||||
disabledMessage: {
|
||||
"en-GB": "Scripts are disabled. Showing fallback image.",
|
||||
},
|
||||
changelogTitle: {
|
||||
"en-GB": "What's new?",
|
||||
},
|
||||
changelogDescription: {
|
||||
"en-GB":
|
||||
"This primer is a living document, and so depending on when you last look at it, there may be new content. Click the following link to expand this section to have a look at what got added, when.",
|
||||
},
|
||||
};
|
||||
|
||||
class LocaleStrings {
|
||||
constructor(locale) {
|
||||
this.currentLocale = locale;
|
||||
const strings = (this.strings = {});
|
||||
|
||||
Object.keys(localeStringData).forEach((id) => {
|
||||
const map = localeStringData[id];
|
||||
if (typeof map !== "object") return;
|
||||
const value = map[locale] ?? map[defaultLocale];
|
||||
if (!value) throw new Error(`unknown locale string id "${id}".`);
|
||||
strings[id] = value;
|
||||
|
||||
// temporary bug catcher:
|
||||
Object.defineProperty(this, id, {
|
||||
get: () => {
|
||||
throw new Error(`cannot get localestring ${id} via property access`);
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
// templating tags:
|
||||
|
||||
get translate() {
|
||||
return this.get.bind(this);
|
||||
}
|
||||
|
||||
// functions:
|
||||
|
||||
get(id) {
|
||||
return this.strings[id];
|
||||
}
|
||||
|
||||
getDefaultLocale() {
|
||||
return defaultLocale;
|
||||
}
|
||||
|
||||
getCurrentLocale() {
|
||||
return this.currentLocale;
|
||||
}
|
||||
|
||||
getLocaleName(locale) {
|
||||
const name = localeStringData.localeName[locale];
|
||||
if (!name) {
|
||||
throw new Error(`Unknown locale "${locale}"`);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
getAllLocaleCodes() {
|
||||
return Object.keys(localeStringData.title);
|
||||
}
|
||||
|
||||
extendContext(context) {
|
||||
const strings = this.strings;
|
||||
|
||||
Object.keys(strings).forEach((key) => {
|
||||
if (context[key]) {
|
||||
throw new Error(`Context already has key "${key}"!`);
|
||||
}
|
||||
context[key] = strings[key];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default LocaleStrings;
|
Reference in New Issue
Block a user