implement / fix i18n for JSX
This commit is contained in:
parent
86fb71f563
commit
4d7d1a1008
@ -1,34 +0,0 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Spinner playground</title>
|
||||
<script src="/src/vendor/system-csp-production.src.js"></script>
|
||||
</head>
|
||||
<html>
|
||||
<div style="display: none;">
|
||||
<img src="/img/icon.png" id="taler-logo" style="display:hidden;">
|
||||
</div>
|
||||
<br />
|
||||
<div id="container"></div>
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
System.config({
|
||||
defaultJSExtensions: true,
|
||||
});
|
||||
|
||||
System.import("/src/chromeBadge")
|
||||
.then((badge) => {
|
||||
let b = new badge.ChromeBadge(window);
|
||||
window.badge = b;
|
||||
document.getElementById("container").appendChild(b.canvas);
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(e.stack);
|
||||
});
|
||||
</script>
|
||||
<br />
|
||||
<button onclick="badge.startBusy()">start</button>
|
||||
<button onclick="badge.stopBusy()">stop</button>
|
||||
</html>
|
||||
</html>
|
@ -198,7 +198,7 @@ export function processFile(sourceFile: ts.SourceFile) {
|
||||
return e.text;
|
||||
}
|
||||
default:
|
||||
return `%${h[0]++}s`;
|
||||
return `%{h[0]++}$s`;
|
||||
}
|
||||
}
|
||||
|
||||
|
114
src/i18n.tsx
114
src/i18n.tsx
@ -207,16 +207,53 @@ i18n.number = function (n : number) {
|
||||
return new PluralNumber (n);
|
||||
};
|
||||
|
||||
function stringifyChildren(children: any): string {
|
||||
let n = 1;
|
||||
let ss = React.Children.map(children, (c) => {
|
||||
if (typeof c === "string") {
|
||||
return c;
|
||||
}
|
||||
return `%${n++}$s`;
|
||||
});
|
||||
return ss.join("");
|
||||
}
|
||||
|
||||
i18n.Translate = class extends React.Component<void,void> {
|
||||
render(): JSX.Element {
|
||||
init();
|
||||
if (typeof jed !== "object") {
|
||||
return <div>{this.props.children}</div>;
|
||||
}
|
||||
let s = stringifyChildren(this.props.children);
|
||||
let tr = jed.ngettext(s, s, 1).split(/%(\d+)\$s/).filter((e: any, i: number) => i % 2 == 0);
|
||||
let childArray = React.Children.toArray(this.props.children!);
|
||||
for (let i = 0; i < childArray.length - 1; ++i) {
|
||||
if ((typeof childArray[i]) == "string" && (typeof childArray[i+1]) == "string") {
|
||||
childArray[i+i] = childArray[i] as string + childArray[i+1] as string;
|
||||
childArray.splice(i,1);
|
||||
}
|
||||
}
|
||||
let result = [];
|
||||
while (childArray.length > 0) {
|
||||
let x = childArray.shift();
|
||||
if (x === undefined) {
|
||||
continue;
|
||||
}
|
||||
if (typeof x === "string") {
|
||||
let t = tr.shift();
|
||||
result.push(t);
|
||||
} else {
|
||||
result.push(x);
|
||||
}
|
||||
}
|
||||
return <div>{result}</div>;
|
||||
}
|
||||
}
|
||||
|
||||
i18n.TranslateSwitch = class extends React.Component<TranslateSwitchProps,void>{
|
||||
render(): JSX.Element {
|
||||
let singular;
|
||||
let plural;
|
||||
let singular: React.ReactElement<TranslationProps> | undefined;
|
||||
let plural: React.ReactElement<TranslationProps> | undefined;
|
||||
let children = this.props.children;
|
||||
if (children) {
|
||||
React.Children.forEach(children, (child: any) => {
|
||||
@ -232,30 +269,91 @@ i18n.TranslateSwitch = class extends React.Component<TranslateSwitchProps,void>{
|
||||
console.error("translation not found");
|
||||
return React.createElement("span", {}, ["translation not found"]);
|
||||
}
|
||||
init();
|
||||
singular.props.target = this.props.target;
|
||||
plural.props.target = this.props.target;;
|
||||
if (typeof "jed" !== "object") {
|
||||
if (this.props.target == 1) {
|
||||
return singular;
|
||||
} else {
|
||||
return plural;
|
||||
}
|
||||
} else {
|
||||
// We're looking up the translation based on the
|
||||
// singular, even if we must use the plural form.
|
||||
return singular;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface TranslationProps {
|
||||
/**
|
||||
* Substitutions to do for the translation.
|
||||
*/
|
||||
subst: {[n: number]: any};
|
||||
target: number;
|
||||
}
|
||||
|
||||
i18n.TranslatePlural = class extends React.Component<TranslationProps,void>{
|
||||
class TranslatePlural extends React.Component<TranslationProps,void> {
|
||||
render(): JSX.Element {
|
||||
init();
|
||||
if (typeof jed !== "object") {
|
||||
return <div>{this.props.children}</div>;
|
||||
}
|
||||
let s = stringifyChildren(this.props.children);
|
||||
let tr = jed.ngettext(s, s, 1).split(/%(\d+)\$s/).filter((e: any, i: number) => i % 2 == 0);
|
||||
let childArray = React.Children.toArray(this.props.children!);
|
||||
for (let i = 0; i < childArray.length - 1; ++i) {
|
||||
if ((typeof childArray[i]) == "string" && (typeof childArray[i+1]) == "string") {
|
||||
childArray[i+i] = childArray[i] as string + childArray[i+1] as string;
|
||||
childArray.splice(i,1);
|
||||
}
|
||||
}
|
||||
let result = [];
|
||||
while (childArray.length > 0) {
|
||||
let x = childArray.shift();
|
||||
if (x === undefined) {
|
||||
continue;
|
||||
}
|
||||
if (typeof x === "string") {
|
||||
let t = tr.shift();
|
||||
result.push(t);
|
||||
} else {
|
||||
result.push(x);
|
||||
}
|
||||
}
|
||||
return <div>{result}</div>;
|
||||
}
|
||||
}
|
||||
|
||||
i18n.TranslateSingular = class extends React.Component<TranslationProps,void>{
|
||||
i18n.TranslatePlural = TranslatePlural;
|
||||
|
||||
class TranslateSingular extends React.Component<TranslationProps,void> {
|
||||
render(): JSX.Element {
|
||||
init();
|
||||
if (typeof jed !== "object") {
|
||||
return <div>{this.props.children}</div>;
|
||||
}
|
||||
let s = stringifyChildren(this.props.children);
|
||||
let tr = jed.ngettext(s, s, 1).split(/%(\d+)\$s/).filter((e: any, i: number) => i % 2 == 0);
|
||||
let childArray = React.Children.toArray(this.props.children!);
|
||||
for (let i = 0; i < childArray.length - 1; ++i) {
|
||||
if ((typeof childArray[i]) == "string" && (typeof childArray[i+1]) == "string") {
|
||||
childArray[i+i] = childArray[i] as string + childArray[i+1] as string;
|
||||
childArray.splice(i,1);
|
||||
}
|
||||
}
|
||||
let result = [];
|
||||
while (childArray.length > 0) {
|
||||
let x = childArray.shift();
|
||||
if (x === undefined) {
|
||||
continue;
|
||||
}
|
||||
if (typeof x === "string") {
|
||||
let t = tr.shift();
|
||||
result.push(t);
|
||||
} else {
|
||||
result.push(x);
|
||||
}
|
||||
}
|
||||
return <div>{result}</div>;
|
||||
}
|
||||
}
|
||||
|
||||
i18n.TranslateSingular = TranslateSingular;
|
||||
|
@ -239,9 +239,15 @@ class WalletBalanceView extends React.Component<any, any> {
|
||||
help
|
||||
</ExtensionLink>
|
||||
);
|
||||
return <div>You have no balance to show. Need some
|
||||
return (
|
||||
<div>
|
||||
<i18n.Translate>
|
||||
You have no balance to show. Need some
|
||||
{" "}{helpLink}{" "}
|
||||
getting started?</div>;
|
||||
getting started?
|
||||
</i18n.Translate>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
formatPending(entry: WalletBalanceEntry): JSX.Element {
|
||||
|
@ -509,7 +509,7 @@ export type PayCoinInfo = Array<{ updatedCoin: CoinRecord, sig: CoinPaySig }>;
|
||||
|
||||
|
||||
export namespace Amounts {
|
||||
export const fractionalBase = 1e6;
|
||||
export const fractionalBase = 1e8;
|
||||
|
||||
export interface Result {
|
||||
amount: AmountJson;
|
||||
|
Loading…
Reference in New Issue
Block a user