0.05: Inline locale details - faster, less memory overhead

Add correct scaling for speed/distance/temperature
master
Gordon Williams 2020-04-02 14:16:54 +01:00
parent f14772f3a9
commit 3cb109f487
4 changed files with 117 additions and 39 deletions

View File

@ -65,7 +65,7 @@
{ "id": "locale", { "id": "locale",
"name": "Languages", "name": "Languages",
"icon": "locale.png", "icon": "locale.png",
"version":"0.04", "version":"0.05",
"description": "Translations for different countries", "description": "Translations for different countries",
"tags": "tool,system,locale,translate", "tags": "tool,system,locale,translate",
"type": "locale", "type": "locale",

View File

@ -2,3 +2,5 @@
0.02: Fix locale.currencySym 0.02: Fix locale.currencySym
0.03: Fix global 'locale' variable 0.03: Fix global 'locale' variable
0.04: Add function meridian 0.04: Add function meridian
0.05: Inline locale details - faster, less memory overhead
Add correct scaling for speed/distance/temperature

View File

@ -15,6 +15,45 @@
<script src="locales.js"></script> <script src="locales.js"></script>
<script> <script>
/*
eg. the built-in en_GB is:
exports = { name : "en_GB", currencySym:"£",
translate : str=>str, // as-is
date : (d,short) => short?("0"+d.getDate()).substr(-2)+"/"+("0"+(d.getMonth()+1)).substr(-2)+"/"+d.getFullYear():d.toString().substr(4,11), // Date to "Feb 28 2020" or "28/02/2020"(short)
time : (d,short) => { // Date to "4:15.28 pm" or "15:42"(short)
if (short)
return d.toString().substr(16,5);
else {
var h = d.getHours(), m = d.getMinutes(), r = "am";
if (h==0) { h=12; }
else if (h>=12) {
if (h>12) h-=12;
r = "pm";
}
return (" "+h).substr(-2)+":"+("0"+m).substr(-2)+"."+("0"+d.getSeconds()).substr(-2)+" "+r;
}
},
dow : (d,short) => short?d.toString().substr(0,3):"Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday".split(",")[d.getDay()], // Date to "Monday" or "Mon"(short)
month : (d,short) => short?d.toString().substr(4,3):"January,February,March,April,May,June,July,August,September,October,November,December".split(",")[d.getMonth()], // Date to "February" or "Feb"(short)
number : n => n.toString(), // more fancy?
currency : n => "£"+n.toFixed(2), // number to "£1.00"
distance : m => (m<1000)?Math.round(m)+"m":Math.round(m/160.934)/10+"mi", // meters to "123m" or "1.2mi" depending on size
speed : s => Math.round(s*0.621371)+"mph",// kph to "123mph"
temp : t => Math.round(t)+"'C" // degrees C to degrees C
meridian: d => (d.getHours() <= 12) ? "am":"pm",
};
*/
// do some sanity checks
Object.keys(locales).forEach(function(localeName) {
var locale = locales[localeName];
if (distanceUnits[locale.distance[0]]===undefined) console.error(localeName+": Unknown distance unit "+locale.distance[0]);
if (distanceUnits[locale.distance[1]]===undefined) console.error(localeName+": Unknown distance unit "+locale.distance[1]);
if (speedUnits[locale.speed]===undefined) console.error(localeName+": Unknown speed unit "+locale.speed);
});
var languageSelector = document.getElementById("languages"); var languageSelector = document.getElementById("languages");
languageSelector.innerHTML = Object.keys(locales).map(l=>`<option value="${l}">${l}</option>`).join("\n"); languageSelector.innerHTML = Object.keys(locales).map(l=>`<option value="${l}">${l}</option>`).join("\n");
@ -30,22 +69,25 @@
return; return;
} }
function js(x) { return JSON.stringify(x); }
var replaceList = { var replaceList = {
"%Y": "${d.getFullYear()}", "%Y": "d.getFullYear()",
"%y": "${(d.getFullYear().toString()).substr(-2)}", "%y": "(d.getFullYear().toString()).substr(-2)",
"%m": "${('0'+(d.getMonth()+1).toString()).substr(-2)}", "%m": "('0'+(d.getMonth()+1).toString()).substr(-2)",
"%-m": "${d.getMonth()+1}", "%-m": "d.getMonth()+1",
"%d": "${('0'+d.getDate()).substr(-2)}", "%d": "('0'+d.getDate()).substr(-2)",
"%-d": "${d.getDate()}", "%-d": "d.getDate()",
"%HH": "${('0'+d.getHours()).substr(-2)}", "%HH": "('0'+d.getHours()).substr(-2)",
"%MM": "${('0'+d.getMinutes()).substr(-2)}", "%MM": "('0'+d.getMinutes()).substr(-2)",
"%SS": "${('0'+d.getSeconds()).substr(-2)}", "%SS": "('0'+d.getSeconds()).substr(-2)",
"%A": "${locale.day.split(',')[d.getDay()]}", "%A": "l.day.split(',')[d.getDay()]",
"%a": "${locale.abday.split(',')[d.getDay()]}", "%a": "l.abday.split(',')[d.getDay()]",
"%B": "${locale.month.split(',')[d.getMonth()]}", "%B": "l.month.split(',')[d.getMonth()]",
"%b": "${locale.abmonth.split(',')[d.getMonth()]}", "%b": "l.abmonth.split(',')[d.getMonth()]",
"%p": "${(d.getHours()<12)?locale.ampm[0].toUpperCase():locale.ampm[1].toUpperCase()}", "%p": `(d.getHours()<12)?${js(locale.ampm[0].toUpperCase())}:${js(locale.ampm[1].toUpperCase())}`,
"%P": "${(d.getHours()<12)?locale.ampm[0].toLowerCase():locale.ampm[1].toLowerCase()}" "%P": `(d.getHours()<12)?${js(locale.ampm[0].toLowerCase())}:${js(locale.ampm[1].toLowerCase())}`
}; };
var timeN = locales[lang].timePattern[0]; var timeN = locales[lang].timePattern[0];
@ -53,33 +95,51 @@
var dateN = locales[lang].datePattern[0]; var dateN = locales[lang].datePattern[0];
var dateS = locales[lang].datePattern[1]; var dateS = locales[lang].datePattern[1];
Object.keys(replaceList).forEach(e => { Object.keys(replaceList).forEach(e => {
timeN = timeN.replace(e,replaceList[e]); timeN = timeN.replace(e,"${"+replaceList[e]+"}");
timeS = timeS.replace(e,replaceList[e]); timeS = timeS.replace(e,"${"+replaceList[e]+"}");
dateN = dateN.replace(e,replaceList[e]); dateN = dateN.replace(e,"${"+replaceList[e]+"}");
dateS = dateS.replace(e,replaceList[e]); dateS = dateS.replace(e,"${"+replaceList[e]+"}");
}); });
var currency = locale.currency_first ?
`${js(locale.currency_symbol)} + n.toFixed(2)`:
`n.toFixed(2) + ${js(locale.currency_symbol)}`;
var temperature;
if (locale.temperature=='°C') temperature="t";
else if (locale.temperature=='°F') temperature="(t*9/5)+32";
else throw new Error("Unknown temperature unit "+locale.temperature);
var localeModule = `var l = ${JSON.stringify({
var app = `var locale = ${JSON.stringify(locales[lang])}; abday : locale.abday,
day : locale.day,
abmonth : locale.abmonth,
month : locale.month,
})};
exports = { exports = {
lang: locale.lang, name: ${js(locale.lang)},
currencySym: locale.currency_symbol, currencySym: ${js(locale.currency_symbol)},
dow: (d,short) => {day = d.getDay();return (short) ? locale.abday.split(",")[day] : locale.day.split(",")[day];}, dow: (d,short) => {day = d.getDay();return (short) ? l.abday.split(",")[day] : l.day.split(",")[day];},
month: (d,short) => { month = d.getMonth(); return (short) ? locale.abmonth.split(",")[month] : locale.month.split(",")[month];}, month: (d,short) => { month = d.getMonth(); return (short) ? l.abmonth.split(",")[month] : l.month.split(",")[month];},
number: n => n.toString().replace(locale.thousands_sep, locale.decimal_point), number: n => n.toString(),
currency: n => n.toFixed(2).replace(locale.thousands_sep, locale.decimal_point) + locale.currency_symbol, currency: n => ${currency},
distance: n => (n < 1000) ? Math.round(n) + locale.distance[0] : Math.round(n/1000) + locale.distance[1], distance: n => (n < ${distanceUnits[locale.distance[1]]}) ? Math.round(n/${distanceUnits[locale.distance[0]]}) + ${js(locale.distance[0])} : Math.round(n/${distanceUnits[locale.distance[1]]}) + ${js(locale.distance[1])},
speed: s => Math.round(s) +locale.speed, speed: s => Math.round(s/${speedUnits[locale.speed]}) + ${js(locale.speed)},
temp: t => Math.round(t) + locale.temperature, temp: t => Math.round(${temperature}) + ${js(locale.temperature)},
translate: s => {s=""+s;return locale.trans[s]||locale.trans[s.toLowerCase()]||s;}, translate: s => {var t=${js(locale.trans)};s=""+s;return t[s]||t[s.toLowerCase()]||s;},
date: (d,short) => (short) ? \`${dateS}\`: \`${dateN}\`, date: (d,short) => (short) ? \`${dateS}\`: \`${dateN}\`,
time: (d,short) => (short) ? \`${timeS}\`: \`${timeN}\`, time: (d,short) => (short) ? \`${timeS}\`: \`${timeN}\`,
meridian: d => (d.getHours() <= 12) ? locale.ampm[0]:locale.ampm[1], meridian: d => (d.getHours() <= 12) ? ${js(locale.ampm[0])}:${js(locale.ampm[1])},
};`; };`;
console.log("Locale Module is:",localeModule);
/*
FIXME:
* Number/Currency need to add thousands separators: .replace(${js(locale.thousands_sep)}, ${js(locale.decimal_point)}) won't cut it as toString doesn't add separators itself
* distance (and speed) should probably use 1 decimal point for numbers less than 10
*/
sendCustomizedApp({ sendCustomizedApp({
storage:[ storage:[
{name:"locale", content:app} {name:"locale", content:localeModule}
] ]
}); });
}); });

View File

@ -1,4 +1,20 @@
const distanceUnits = { // how many meters per X?
"m" : 1,
"yd" : 0.9144,
"mi" : 1609.34,
"km" : 1000,
"kmi" : 1000
};
const speedUnits = { // how many kph per X?
"kmh" : 1,
"kph" : 1,
"mph" : 1.60934
};
/* /*
timePattern / datePattern:
%Y year four digits %Y year four digits
%y last two digits of year (00..99) %y last two digits of year (00..99)
%m month (01..12) %m month (01..12)
@ -21,10 +37,10 @@ var locales = {
lang: "en_GB", lang: "en_GB",
decimal_point: ".", decimal_point: ".",
thousands_sep: ",", thousands_sep: ",",
currency_symbol: "£", currency_symbol: "£", currency_first:true,
int_curr_symbol: "GBP", int_curr_symbol: "GBP",
speed: 'mph', speed: 'mph',
distance: { "0": "mi", "1": "kmi" }, distance: { "0": "yd", "1": "mi" },
temperature: '°C', temperature: '°C',
ampm: {0:"am",1:"pm"}, ampm: {0:"am",1:"pm"},
timePattern: { 0: "%HH:%MM:%SS ", 1: "%HH:%MM" }, timePattern: { 0: "%HH:%MM:%SS ", 1: "%HH:%MM" },
@ -55,10 +71,10 @@ var locales = {
lang: "en_US", lang: "en_US",
decimal_point: ".", decimal_point: ".",
thousands_sep: ",", thousands_sep: ",",
currency_symbol: "$", currency_symbol: "$", currency_first:true,
int_curr_symbol: "USD", int_curr_symbol: "USD",
speed: "mph", speed: "mph",
distance: { 0: "mi", 1: "kmi" }, distance: { 0: "yd", 1: "mi" },
temperature: "°F", temperature: "°F",
ampm: {0:"am",1:"pm"}, ampm: {0:"am",1:"pm"},
timePattern: { 0: "%HH:%MM:%SS ", 1: "%HH:%MM" }, timePattern: { 0: "%HH:%MM:%SS ", 1: "%HH:%MM" },