add Locale.js, update Format.js
This commit is contained in:
parent
7d42aaedd8
commit
b68b827d7b
2 changed files with 170 additions and 26 deletions
|
@ -26,8 +26,9 @@ Ox.formatCount <f> Returns a string like "2 items", "1 item" or "no items".
|
||||||
'1,000 cities'
|
'1,000 cities'
|
||||||
@*/
|
@*/
|
||||||
Ox.formatCount = function(number, singular, plural) {
|
Ox.formatCount = function(number, singular, plural) {
|
||||||
return (number === 0 ? 'no' : Ox.formatNumber(number)) + ' '
|
plural = (plural || singular + 's') + (number === 2 ? '{2}' : '');
|
||||||
+ (number === 1 ? singular : plural || singular + 's');
|
return (number === 0 ? Ox._('no') : Ox.formatNumber(number))
|
||||||
|
+ ' ' + Ox._(number === 1 ? singular : plural);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
|
@ -44,7 +45,8 @@ Ox.formatDate <f> Formats a date according to a format string
|
||||||
See
|
See
|
||||||
<a href="http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/strftime.3.html">strftime</a>
|
<a href="http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/strftime.3.html">strftime</a>
|
||||||
and <a href="http://en.wikipedia.org/wiki/ISO_8601">ISO 8601</a>.
|
and <a href="http://en.wikipedia.org/wiki/ISO_8601">ISO 8601</a>.
|
||||||
'%Q' (quarter) and '%X'/'%x' (year with 'BC'/'AD') are non-standard
|
'E*%' (localized date and time), %Q' (quarter) and '%X'/'%x'
|
||||||
|
(year with 'BC'/'AD') are non-standard.
|
||||||
(string) -> <s> formatted date
|
(string) -> <s> formatted date
|
||||||
(date, string) -> <s> formatted date
|
(date, string) -> <s> formatted date
|
||||||
(date, string, utc) -> <s> formatted date
|
(date, string, utc) -> <s> formatted date
|
||||||
|
@ -71,6 +73,26 @@ Ox.formatDate <f> Formats a date according to a format string
|
||||||
'01/02/05'
|
'01/02/05'
|
||||||
> Ox.formatDate(Ox.test.date, '%d') // Zero-padded day of the month
|
> Ox.formatDate(Ox.test.date, '%d') // Zero-padded day of the month
|
||||||
'02'
|
'02'
|
||||||
|
> Ox.formatDate(Ox.test.date, '%ED') // Localized date and time with seconds
|
||||||
|
'01/02/2005 00:03:04'
|
||||||
|
> Ox.formatDate(Ox.test.date, '%Ed') // Localized date and time without seconds
|
||||||
|
'01/02/2005 00:03
|
||||||
|
> Ox.formatDate(Ox.test.date, '%EL') // Long localized date with weekday
|
||||||
|
'Sunday, January 2, 2005'
|
||||||
|
> Ox.formatDate(Ox.test.date, '%El') // Long localized date without weekday
|
||||||
|
'January 2, 2005'
|
||||||
|
> Ox.formatDate(Ox.test.date, '%EM') // Medium localized date with weekday
|
||||||
|
'Sun, Jan 2, 2005'
|
||||||
|
> Ox.formatDate(Ox.test.date, '%Em') // Medium localized date without weekday
|
||||||
|
'Jan 2, 2005'
|
||||||
|
> Ox.formatDate(Ox.test.date, '%ES') // Short localized date with century
|
||||||
|
'01/02/2005'
|
||||||
|
> Ox.formatDate(Ox.test.date, '%Es') // Short localized date without century
|
||||||
|
'01/02/05'
|
||||||
|
> Ox.formatDate(Ox.test.date, '%ET') // Localized time with seconds
|
||||||
|
'12:03:04 AM'
|
||||||
|
> Ox.formatDate(Ox.test.date, '%Et') // Localized time without seconds
|
||||||
|
'12:03 AM'
|
||||||
> Ox.formatDate(Ox.test.date, '%e') // Space-padded day of the month
|
> Ox.formatDate(Ox.test.date, '%e') // Space-padded day of the month
|
||||||
' 2'
|
' 2'
|
||||||
> Ox.formatDate(Ox.test.date, '%F') // Date
|
> Ox.formatDate(Ox.test.date, '%F') // Date
|
||||||
|
@ -155,6 +177,36 @@ Ox.formatDate <f> Formats a date according to a format string
|
||||||
['D', function() {
|
['D', function() {
|
||||||
return '%m/%d/%y';
|
return '%m/%d/%y';
|
||||||
}],
|
}],
|
||||||
|
['ED', function() {
|
||||||
|
return '%ES %T';
|
||||||
|
}],
|
||||||
|
['Ed', function() {
|
||||||
|
return '%ES %R';
|
||||||
|
}],
|
||||||
|
['EL', function() {
|
||||||
|
return Ox._('%A, %B %e, %Y');
|
||||||
|
}],
|
||||||
|
['El', function() {
|
||||||
|
return Ox._('%B %e, %Y');
|
||||||
|
}],
|
||||||
|
['EM', function() {
|
||||||
|
return Ox._('%a, %b %e, %Y');
|
||||||
|
}],
|
||||||
|
['Em', function() {
|
||||||
|
return Ox._('%b %e, %Y');
|
||||||
|
}],
|
||||||
|
['ES', function() {
|
||||||
|
return Ox._('%m/%d/%Y');
|
||||||
|
}],
|
||||||
|
['Es', function() {
|
||||||
|
return Ox._('%m/%d/%y');
|
||||||
|
}],
|
||||||
|
['ET', function() {
|
||||||
|
return Ox._('%I:%M:%S %p');
|
||||||
|
}],
|
||||||
|
['Et', function() {
|
||||||
|
return Ox._('%I:%M %p');
|
||||||
|
}],
|
||||||
['F', function() {
|
['F', function() {
|
||||||
return '%Y-%m-%d';
|
return '%Y-%m-%d';
|
||||||
}],
|
}],
|
||||||
|
@ -177,16 +229,16 @@ Ox.formatDate <f> Formats a date according to a format string
|
||||||
return '%a %b %e %H:%M:%S %Z %Y';
|
return '%a %b %e %H:%M:%S %Z %Y';
|
||||||
}],
|
}],
|
||||||
['A', function(date, utc) {
|
['A', function(date, utc) {
|
||||||
return Ox.WEEKDAYS[(Ox.getDay(date, utc) + 6) % 7];
|
return Ox._(Ox.WEEKDAYS[(Ox.getDay(date, utc) + 6) % 7]);
|
||||||
}],
|
}],
|
||||||
['a', function(date, utc) {
|
['a', function(date, utc) {
|
||||||
return Ox.SHORT_WEEKDAYS[(Ox.getDay(date, utc) + 6) % 7];
|
return Ox._(Ox.SHORT_WEEKDAYS[(Ox.getDay(date, utc) + 6) % 7]);
|
||||||
}],
|
}],
|
||||||
['B', function(date, utc) {
|
['B', function(date, utc) {
|
||||||
return Ox.MONTHS[Ox.getMonth(date, utc)];
|
return Ox._(Ox.MONTHS[Ox.getMonth(date, utc)]);
|
||||||
}],
|
}],
|
||||||
['b', function(date, utc) {
|
['b', function(date, utc) {
|
||||||
return Ox.SHORT_MONTHS[Ox.getMonth(date, utc)];
|
return Ox._(Ox.SHORT_MONTHS[Ox.getMonth(date, utc)]);
|
||||||
}],
|
}],
|
||||||
['C', function(date, utc) {
|
['C', function(date, utc) {
|
||||||
return Math.floor(Ox.getFullYear(date, utc) / 100).toString();
|
return Math.floor(Ox.getFullYear(date, utc) / 100).toString();
|
||||||
|
@ -225,7 +277,7 @@ Ox.formatDate <f> Formats a date according to a format string
|
||||||
return Ox.pad((Ox.getMonth(date, utc) + 1), 2);
|
return Ox.pad((Ox.getMonth(date, utc) + 1), 2);
|
||||||
}],
|
}],
|
||||||
['p', function(date, utc) {
|
['p', function(date, utc) {
|
||||||
return Ox.AMPM[Math.floor(Ox.getHours(date, utc) / 12)];
|
return Ox._(Ox.AMPM[Math.floor(Ox.getHours(date, utc) / 12)]);
|
||||||
}],
|
}],
|
||||||
['Q', function(date, utc) {
|
['Q', function(date, utc) {
|
||||||
return Math.floor(Ox.getMonth(date, utc) / 4) + 1;
|
return Math.floor(Ox.getMonth(date, utc) / 4) + 1;
|
||||||
|
@ -256,11 +308,13 @@ Ox.formatDate <f> Formats a date according to a format string
|
||||||
}],
|
}],
|
||||||
['X', function(date, utc) {
|
['X', function(date, utc) {
|
||||||
var y = Ox.getFullYear(date, utc);
|
var y = Ox.getFullYear(date, utc);
|
||||||
return Math.abs(y) + ' ' + Ox.BCAD[y < 0 ? 0 : 1];
|
return Math.abs(y) + ' ' + Ox._(Ox.BCAD[y < 0 ? 0 : 1]);
|
||||||
}],
|
}],
|
||||||
['x', function(date, utc) {
|
['x', function(date, utc) {
|
||||||
var y = Ox.getFullYear(date, utc);
|
var y = Ox.getFullYear(date, utc);
|
||||||
return Math.abs(y) + (y < 1000 ? ' ' + Ox.BCAD[y < 0 ? 0 : 1] : '');
|
return Math.abs(y) + (
|
||||||
|
y < 1000 ? ' ' + Ox._(Ox.BCAD[y < 0 ? 0 : 1]) : ''
|
||||||
|
);
|
||||||
}],
|
}],
|
||||||
['Y', function(date, utc) {
|
['Y', function(date, utc) {
|
||||||
return Ox.getFullYear(date, utc);
|
return Ox.getFullYear(date, utc);
|
||||||
|
@ -569,8 +623,11 @@ Ox.formatDuration = function(seconds/*, decimals, format*/) {
|
||||||
if (format == 'none') {
|
if (format == 'none') {
|
||||||
ret = Ox.pad(value, 'left', pad[index], '0');
|
ret = Ox.pad(value, 'left', pad[index], '0');
|
||||||
} else if (Ox.isNumber(value) ? value : parseFloat(value)) {
|
} else if (Ox.isNumber(value) ? value : parseFloat(value)) {
|
||||||
ret = value + (format == 'long' ? ' ' : '') + string[index]
|
ret = value + (format == 'long' ? ' ' : '') + Ox._(string[index] + (
|
||||||
+ (format == 'long' && value != 1 ? 's' : '');
|
format == 'long'
|
||||||
|
? (value == 1 ? '' : value == 2 ? 's{2}' : 's')
|
||||||
|
: ''
|
||||||
|
));
|
||||||
} else {
|
} else {
|
||||||
ret = '';
|
ret = '';
|
||||||
}
|
}
|
||||||
|
@ -598,8 +655,8 @@ Ox.formatNumber = function(number, decimals) {
|
||||||
array.unshift(split[0].slice(-3));
|
array.unshift(split[0].slice(-3));
|
||||||
split[0] = split[0].slice(0, -3);
|
split[0] = split[0].slice(0, -3);
|
||||||
}
|
}
|
||||||
split[0] = array.join(',');
|
split[0] = array.join(Ox._(','));
|
||||||
return (number < 0 ? '-' : '') + split.join('.');
|
return (number < 0 ? '-' : '') + split.join(Ox._('.'));
|
||||||
};
|
};
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
|
@ -623,15 +680,18 @@ Ox.formatOrdinal = function(number) {
|
||||||
var string = Ox.formatNumber(number),
|
var string = Ox.formatNumber(number),
|
||||||
length = string.length,
|
length = string.length,
|
||||||
last = string[length - 1],
|
last = string[length - 1],
|
||||||
ten = length > 1 && string[length - 2] == '1';
|
ten = length > 1 && string[length - 2] == '1',
|
||||||
|
twenty = length > 1 && !ten;
|
||||||
if (last == '1' && !ten) {
|
if (last == '1' && !ten) {
|
||||||
string += 'st';
|
string += Ox._('st' + (twenty ? '{21}' : ''));
|
||||||
} else if (last == '2' && !ten) {
|
} else if (last == '2' && !ten) {
|
||||||
string += 'nd';
|
string += Ox._('nd' + (twenty ? '{22}' : ''));
|
||||||
} else if (last == '3' && !ten) {
|
} else if (last == '3' && !ten) {
|
||||||
string += 'rd';
|
string += Ox._('rd' + (twenty ? '{23}' : ''));
|
||||||
} else {
|
} else {
|
||||||
string += 'th';
|
string += Ox._(
|
||||||
|
'th' + (Ox.contains('123', last) && ten ? '{1' + last + '}' : '')
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return string;
|
return string;
|
||||||
};
|
};
|
||||||
|
@ -642,7 +702,7 @@ Ox.formatPercent <f> Formats the relation of two numbers as a percentage
|
||||||
"0.10%"
|
"0.10%"
|
||||||
@*/
|
@*/
|
||||||
Ox.formatPercent = function(number, total, decimals) {
|
Ox.formatPercent = function(number, total, decimals) {
|
||||||
return Ox.formatNumber(number / total * 100, decimals) + '%'
|
return Ox.formatNumber(number / total * 100, decimals) + Ox._('%');
|
||||||
};
|
};
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
|
@ -686,18 +746,29 @@ Ox.formatString <f> Basic string formatting
|
||||||
'foobar'
|
'foobar'
|
||||||
> Ox.formatString('{a\\.b}', {'a.b': 'foobar'})
|
> Ox.formatString('{a\\.b}', {'a.b': 'foobar'})
|
||||||
'foobar'
|
'foobar'
|
||||||
|
> Ox.formatString('{1}', ['foobar'])
|
||||||
|
'{1}'
|
||||||
|
> Ox.formatString('{b}', {a: 'foobar'}, true)
|
||||||
|
''
|
||||||
@*/
|
@*/
|
||||||
Ox.formatString = function(string, collection) {
|
Ox.formatString = function(string, collection, removeUnmatched) {
|
||||||
return string.replace(/\{([^}]+)\}/g, function(string, match) {
|
return string.replace(/\{([^}]+)\}/g, function(string, match) {
|
||||||
// make sure to not split at escaped dots ('\.')
|
// make sure to not split at escaped dots ('\.')
|
||||||
var keys = match.replace(/\\\./g, '\n').split('.').map(function(key) {
|
var key,
|
||||||
return key.replace(/\n/g, '.')
|
keys = match.replace(/\\\./g, '\n').split('.').map(function(key) {
|
||||||
|
return key.replace(/\n/g, '.');
|
||||||
}),
|
}),
|
||||||
value = collection;
|
value = collection || {};
|
||||||
while (keys.length) {
|
while (keys.length) {
|
||||||
value = value[keys.shift()];
|
key = keys.shift();
|
||||||
|
if (value[key]) {
|
||||||
|
value = value[key];
|
||||||
|
} else {
|
||||||
|
value = null;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return value;
|
}
|
||||||
|
return value || (removeUnmatched ? '' : '{' + match + '}');
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
73
source/Ox/js/Locale.js
Normal file
73
source/Ox/js/Locale.js
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
var log, translations = {};
|
||||||
|
|
||||||
|
/*@
|
||||||
|
Ox.setLocale <f> Sets locale
|
||||||
|
(locale[, url], callback)
|
||||||
|
locale <s> Locale (like 'de' or 'fr')
|
||||||
|
url <s> URL of JSON file with additional translations
|
||||||
|
callback <f> Callback function
|
||||||
|
success <b> If true, locale has been set
|
||||||
|
@*/
|
||||||
|
Ox.setLocale = function(locale, url, callback) {
|
||||||
|
var isValidLocale = Ox.contains(Object.keys(Ox.LOCALES), locale);
|
||||||
|
if (arguments.length == 2) {
|
||||||
|
callback = arguments[1];
|
||||||
|
url = null;
|
||||||
|
}
|
||||||
|
if (locale != Ox.LOCALE && isValidLocale) {
|
||||||
|
Ox.LOCALE = locale;
|
||||||
|
if (locale == 'en') {
|
||||||
|
translations = {};
|
||||||
|
callback(true);
|
||||||
|
} else {
|
||||||
|
Ox.getJSON(
|
||||||
|
Ox.PATH + 'Ox/json/locale.' + locale + '.json',
|
||||||
|
function(data) {
|
||||||
|
translations = data;
|
||||||
|
if (url) {
|
||||||
|
Ox.getJSON(url, function(data) {
|
||||||
|
Ox.extend(translations, data);
|
||||||
|
callback(true);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
callback(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
callback(isValidLocale);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*@
|
||||||
|
Ox._ <f> Localizes a string
|
||||||
|
(string[, options]) -> <s> Localized string
|
||||||
|
string <s> English string
|
||||||
|
options <o> Options passed to Ox.formatString
|
||||||
|
@*/
|
||||||
|
Ox._ = function(value, options) {
|
||||||
|
var translation = translations[value];
|
||||||
|
log && log(value, translation);
|
||||||
|
translation = translation || value;
|
||||||
|
return options
|
||||||
|
? Ox.formatString(translation, options, true)
|
||||||
|
: translation
|
||||||
|
};
|
||||||
|
|
||||||
|
/*@
|
||||||
|
Ox._.log <f> Registers a logging function
|
||||||
|
(callback) -> <u> undefined
|
||||||
|
callback <f> Callback function
|
||||||
|
english <s> English string
|
||||||
|
translation <s> Translated string
|
||||||
|
@*/
|
||||||
|
Ox._.log = function(callback) {
|
||||||
|
log = callback;
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
Loading…
Reference in a new issue