implement / fix i18n for JSX

This commit is contained in:
Florian Dold 2016-11-17 02:58:27 +01:00
parent 86fb71f563
commit 4d7d1a1008
5 changed files with 123 additions and 53 deletions

View File

@ -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>

View File

@ -198,7 +198,7 @@ export function processFile(sourceFile: ts.SourceFile) {
return e.text; return e.text;
} }
default: default:
return `%${h[0]++}s`; return `%{h[0]++}$s`;
} }
} }

View File

@ -207,16 +207,53 @@ i18n.number = function (n : number) {
return new PluralNumber (n); 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> { i18n.Translate = class extends React.Component<void,void> {
render(): JSX.Element { render(): JSX.Element {
init();
if (typeof jed !== "object") {
return <div>{this.props.children}</div>; 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>{ i18n.TranslateSwitch = class extends React.Component<TranslateSwitchProps,void>{
render(): JSX.Element { render(): JSX.Element {
let singular; let singular: React.ReactElement<TranslationProps> | undefined;
let plural; let plural: React.ReactElement<TranslationProps> | undefined;
let children = this.props.children; let children = this.props.children;
if (children) { if (children) {
React.Children.forEach(children, (child: any) => { React.Children.forEach(children, (child: any) => {
@ -232,30 +269,91 @@ i18n.TranslateSwitch = class extends React.Component<TranslateSwitchProps,void>{
console.error("translation not found"); console.error("translation not found");
return React.createElement("span", {}, ["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) { if (this.props.target == 1) {
return singular; return singular;
} else { } else {
return plural; 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 { interface TranslationProps {
/** target: number;
* Substitutions to do for the translation.
*/
subst: {[n: number]: any};
} }
i18n.TranslatePlural = class extends React.Component<TranslationProps,void>{ class TranslatePlural extends React.Component<TranslationProps,void> {
render(): JSX.Element { render(): JSX.Element {
init();
if (typeof jed !== "object") {
return <div>{this.props.children}</div>; 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 { render(): JSX.Element {
init();
if (typeof jed !== "object") {
return <div>{this.props.children}</div>; 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;

View File

@ -239,9 +239,15 @@ class WalletBalanceView extends React.Component<any, any> {
help help
</ExtensionLink> </ExtensionLink>
); );
return <div>You have no balance to show. Need some return (
<div>
<i18n.Translate>
You have no balance to show. Need some
{" "}{helpLink}{" "} {" "}{helpLink}{" "}
getting started?</div>; getting started?
</i18n.Translate>
</div>
);
} }
formatPending(entry: WalletBalanceEntry): JSX.Element { formatPending(entry: WalletBalanceEntry): JSX.Element {

View File

@ -509,7 +509,7 @@ export type PayCoinInfo = Array<{ updatedCoin: CoinRecord, sig: CoinPaySig }>;
export namespace Amounts { export namespace Amounts {
export const fractionalBase = 1e6; export const fractionalBase = 1e8;
export interface Result { export interface Result {
amount: AmountJson; amount: AmountJson;