2 * Copyright 2010-2013 Ben Birch
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this software except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 * provides text formatting and i18n key storage features<br>
19 * implements most of the Sun Java MessageFormat functionality.
20 * @see <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/text/MessageFormat.html" target="sun">Sun's Documentation</a>
25 var format = function(message, args) {
26 var substitute = function() {
27 var format = arguments[1].split(',');
28 var substr = escape(args[format.shift()]);
29 if(format.length === 0) {
30 return substr; // simple substitution eg {0}
32 switch(format.shift()) {
33 case "number" : return (new Number(substr)).toLocaleString();
34 case "date" : return (new Date(+substr)).toLocaleDateString(); // date and time require milliseconds since epoch
35 case "time" : return (new Date(+substr)).toLocaleTimeString(); // eg i18n.text("Key", +(new Date())); for current time
37 var styles = format.join("").split("|").map(function(style) {
38 return style.match(/(-?[\.\d]+)(#|<)([^{}]*)/);
40 var match = styles[0][3];
41 for(var i=0; i<styles.length; i++) {
42 if((styles[i][2] === "#" && (+styles[i][1]) === (+substr)) ||
43 (styles[i][2] === "<" && ((+styles[i][1]) < (+substr)))) {
50 return message && message.replace(/'(')|'([^']+)'|([^{']+)|([^']+)/g, function(x, sq, qs, ss, sub) {
51 do {} while(sub && (sub !== (sub = (sub.replace(/\{([^{}]+)\}/, substitute)))));
52 return sq || qs || ss || unescape(sub);
58 setKeys: function(strings) {
59 for(var key in strings) {
60 keys[key] = strings[key];
65 var args = Array.prototype.slice.call(arguments),
66 key = keys[args.shift()];
67 if(args.length === 0) {
70 return format(key, args);
74 var args = Array.prototype.slice.call(arguments),
75 key = keys[args.shift()],
77 replacer = function(x, pt, sub) { ret.push(pt || args[+sub]); return ""; };
78 do {} while(key && key !== (key = key.replace(/([^{]+)|\{(\d+)\}/, replacer )));
87 var nav = window.navigator;
88 var userLang = ( nav.languages && nav.languages[0] ) || nav.language || nav.userLanguage;
89 var scripts = document.getElementsByTagName('script');
90 var data = scripts[ scripts.length - 1].dataset;
91 if( ! data["langs"] ) {
94 var langs = data["langs"].split(/\s*,\s*/);
95 var script0 = scripts[0];
96 function install( lang ) {
97 var s = document.createElement("script");
98 s.src = data["basedir"] + "/" + lang + '_strings.js';
100 script0.parentNode.appendChild(s);
104 install( langs.shift() ); // always install primary language
106 .filter( function( lang ) { return userLang.indexOf( lang ) === 0; } )