123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664 |
- (function (ctx)
- {
- var noop = function () {}, instance;
- if (!String.prototype.trim) {
- String.prototype.trim = function () {
- return this.replace(/^\s+|\s+$/g, '');
- };
- }
- var sprintf = (function () {
- function get_type(variable) {
- return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase();
- }
- function str_repeat(input, multiplier) {
- for (var output = []; multiplier > 0; output[--multiplier] = input) {
- }
- return output.join('');
- }
- var str_format = function () {
- if (!str_format.cache.hasOwnProperty(arguments[0])) {
- str_format.cache[arguments[0]] = str_format.parse(arguments[0]);
- }
- return str_format.format.call(null, str_format.cache[arguments[0]], arguments);
- };
- str_format.format = function (parse_tree, argv) {
- var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length;
- for (i = 0; i < tree_length; i++) {
- node_type = get_type(parse_tree[i]);
- if (node_type === 'string') {
- output.push(parse_tree[i]);
- } else if (node_type === 'array') {
- match = parse_tree[i];
- if (match[2]) {
- arg = argv[cursor];
- for (k = 0; k < match[2].length; k++) {
- if (!arg.hasOwnProperty(match[2][k])) {
- throw (sprintf('[sprintf] property "%s" does not exist', match[2][k]));
- }
- arg = arg[match[2][k]];
- }
- } else if (match[1]) {
- arg = argv[match[1]];
- } else {
- arg = argv[cursor++];
- }
- if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) {
- throw (sprintf('[sprintf] expecting number but found %s', get_type(arg)));
- }
- switch (match[8]) {
- case 'b':
- arg = arg.toString(2);
- break;
- case 'c':
- arg = String.fromCharCode(arg);
- break;
- case 'd':
- arg = arg >> 0;
- break;
- case 'e':
- arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential();
- break;
- case 'f':
- arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg);
- break;
- case 'o':
- arg = arg.toString(8);
- break;
- case 's':
- arg = (( arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg);
- break;
- case 'u':
- arg = Math.abs(arg);
- break;
- case 'x':
- arg = arg.toString(16);
- break;
- case 'X':
- arg = arg.toString(16).toUpperCase();
- break;
- }
- arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+' + arg : arg);
- pad_character = match[4] ? match[4] === '0' ? '0' : match[4].charAt(1) : ' ';
- pad_length = match[6] - String(arg).length;
- pad = match[6] ? str_repeat(pad_character, pad_length) : '';
- output.push(match[5] ? arg + pad : pad + arg);
- }
- }
- return output.join('');
- };
- str_format.cache = {};
- str_format.parse = function (fmt) {
- var _fmt = fmt, match = [], parse_tree = [], arg_names = 0;
- while (_fmt) {
- if (( match = /^[^\x25]+/.exec(_fmt)) !== null) {
- parse_tree.push(match[0]);
- } else if (( match = /^\x25{2}/.exec(_fmt)) !== null) {
- parse_tree.push('%');
- } else if (( match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) {
- if (match[2]) {
- arg_names |= 1;
- var field_list = [], replacement_field = match[2], field_match = [];
- if (( field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
- field_list.push(field_match[1]);
- while (( replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
- if (( field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
- field_list.push(field_match[1]);
- } else if (( field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) {
- field_list.push(field_match[1]);
- } else {
- throw ('[sprintf] huh?');
- }
- }
- } else {
- throw ('[sprintf] huh?');
- }
- match[2] = field_list;
- } else {
- arg_names |= 2;
- }
- if (arg_names === 3) {
- throw ('[sprintf] mixing positional and named placeholders is not (yet) supported');
- }
- parse_tree.push(match);
- } else {
- throw ('[sprintf] huh?');
- }
- _fmt = _fmt.substring(match[0].length);
- }
- return parse_tree;
- };
- return str_format;
- })();
- var vsprintf = function (fmt, argv) {
- argv.unshift(fmt);
- return sprintf.apply(null, argv);
- };
- var isBrowser = function () {
- return (typeof(window) !== 'undefined' && !!document && !!document.getElementsByTagName);
- };
- var escapeString = function (val) {
- var return_value;
- if (val.constructor != String()) {
- return_value = val;
- }
- if (val.replace) {
- return_value = val
- .replace(/[\"]/g, '\\"')
- .replace(/[\\]/g, '\\')
- .replace(/[\/]/g, '\/')
- .replace(/[\b]/g, '\\b')
- .replace(/[\f]/g, '\\f')
- .replace(/[\n]/g, '\\n')
- .replace(/[\r]/g, '\\r')
- .replace(/[\t]/g, '\\t');
- }
- return return_value;
- };
- var unescapeString = function (val) {
- var return_value;
- if (!!val && !!val.replace) {
- return_value = val
- .replace("\\n", '\n')
- .replace("\\r", '\r')
- .replace("\\t", '\t')
- .replace("\\f", '\f')
- .replace("\\b", '\b')
- .replace("\\r", '\r');
- }
- return return_value;
- };
- var waitUntilReady = function (callback) {
- var itv = setInterval(function () {
- if (!!instance && !instance.waiting) {
- clearInterval(itv);
- callback.call(callback);
- }
- }, 4);
- };
- var extend = function(protoProps, staticProps) {
- var parent = this;
- var child, has = Object.prototype.hasOwnProperty;
- if (protoProps && has.call(protoProps, 'constructor')) {
- child = protoProps.constructor;
- }
- else {
- child = function(){ return parent.apply(this, arguments); };
- }
- if(staticProps)
- for(var static_prop in staticProps){
- child[static_prop] = staticProps[static_prop];
- }
- var Surrogate = function(){ this.constructor = child; };
- Surrogate.prototype = parent.prototype;
- child.prototype = new Surrogate;
- if (protoProps)
- for(var proto_prop in protoProps){
- child.prototype[proto_prop] = protoProps[proto_prop];
- }
- child.extend = extend;
- child.__super__ = parent.prototype;
- return child;
- };
- entryExists = function (hash, domain, escaped) {
- return !!hash && !!hash.contents && !!hash.contents[domain] && !!hash.contents[domain][escaped];
- };
- var Errors = {};
- Errors.Base = extend.call(Error, {
- toString: function(){
- return (this.name + ': ' + this.message);
- }
- });
- Errors.CustomError = Errors.Base.extend({
- constructor: function (message) {
- this.name = 'CustomError';
- this.message = message;
- this.stack = (new Error()).stack;
- }
- });
- Errors.CustomError.extend = extend;
- Errors.UnknownAcquisitionModeError = Errors.CustomError.extend({
- constructor: function (mode) {
- var message;
- mode = !mode ? 'None provided' : mode;
- message = 'PO files acquisition mode: "' + mode + '" is not valid.';
- Errors.CustomError.call(this, message);
- this.name = 'UnknownAcquisitionModeError';
- }
- });
- var Parser = {};
- Parser.Object = function (msg) {
- var me = this, phrase_count = 1;
- //singular by default
- for (var key in msg) {
- this[key] = msg[key];
- }
- this.setCount = function (amount) {
- phrase_count = amount >> 0;
- };
- this.toString = function () {
- var return_value, canGetPluralIndex;
- canGetPluralIndex = !this.isPlural && this.plural_forms && this.plural_forms.push && !!Parser.Object.calculatePluralIndex;
- if (canGetPluralIndex) {
- var idx = Parser.Object.calculatePluralIndex(phrase_count);
- return_value = this.plural_forms[idx];
- } else {
- return_value = this.translation;
- }
- return return_value;
- }
- };
- Parser.POFiles = {
- parse: function (text, translation_domain) {
- text = !text? '' : text;
- var getTelltale, extractHeaderInfo, isMultilinePlural, multilineExtract;
- getTelltale = function (str) {
- return str.substring(0, 12).split(' ')[0].trim();
- };
- isMultilinePlural = function (line) {
- return (!!line && line.match(/msgstr\[[0-9]\]/));
- };
- extractHeaderInfo = function (header) {
- var header_lines = header.split("\n");
- for (var i = 0, j = header_lines.length; i < j; i++) {
- var header_line = header_lines[i];
- if (header_line.indexOf('"Plural-Forms: nplurals') === 0) {
- var plural_form = header_line.substring(14).slice(0, -1);
- Parser.Object.calculatePluralIndex = function (phrase_count) {
- eval(unescapeString(plural_form));
- if (typeof(plural) === 'undefined') {
- plural = 0;
- }
- return plural;
- }
- }
- }
- };
- multilineExtract = function (part_lines) {
- var buffer = [], possible;
- while (possible = part_lines.shift()) {
- possible = possible.trim();
- if (possible.indexOf('"') === 0) {
- buffer.push(possible.substring(1).slice(0, -1));
- }
- else {
- part_lines.unshift(possible);
- break;
- }
- }
- return buffer.join("");
- };
- var parsed = {},
- has_header_info,
- header_info,
- part,
- domain = ( typeof (translation_domain) === 'undefined') ? 'messages' : translation_domain,
- counter = 0,
- text = text.replace(/\r\n|\r/g, "\n"),
- parts;
- parsed[domain] = {};
- parts = text.split(/\n\n/);
- header_info = parts.shift();
- has_header_info = extractHeaderInfo(header_info);
- if (!has_header_info) {
- parts.unshift(header_info);
- }
- else {
- Parser.header_info = extractHeaderInfo(has_header_info);
- }
- while (part = parts.shift()) {
- var message = {},
- part_lines = !!part ? part.split(/\n/) : [],
- line = '',
- escaped;
- while (line = part_lines.shift()) {
- line = line.trim();
- var next_line = part_lines.slice(0, -1)[0],
- line_telltale = getTelltale(line),
- next_line_telltale = next_line ? getTelltale(next_line) : false;
- switch (line_telltale) {
- case 'msgctxt':
- message.context = line.substring(9).slice(0, -1);
- break;
- case 'msgid_plural':
- message.isPlural = true;
- message.plural_id = line.substring(14).slice(0, -1);
- break;
- case 'msgid':
- if (line.indexOf('msgid ""') === 0) {
- var possible = next_line.trim();
- if (possible.indexOf('"') === 0) {//multiline
- message.id = multilineExtract(part_lines)
- }
- }
- else {
- if (next_line_telltale = 'msgstr') {
- message.id = line.substr(7).slice(0, -1);
- }
- }
- continue;
- case 'msgstr':
- if (line.indexOf('msgstr ""') === 0) {
- possible = next_line.trim();
- if (possible.indexOf('"') === 0) {
- message.translation = multilineExtract(part_lines);
- }
- }
- else {
- message.translation = line.substr(8).slice(0, -1);
- }
- break;
- case '#:':
- case '#.':
- case '#':
- continue;
- case '#,':
- break;
- default:
- if (isMultilinePlural(line)) {
- var cases = [];
- while (isMultilinePlural(line)) {
- cases.push(line.substring(10).slice(0, -1));
- line = part_lines.shift();
- }
- message.plural_forms = cases;
- message.translation = cases[0];
- }
- continue;
- }
- }
- if (!!message.id && !!message.translation) {
- message = new Parser.Object(message);
- escaped = escapeString(message.id);
- if (!parsed[domain][message.id]) {
- parsed[domain][escaped] = [message];
- } else {
- parsed[domain][escaped].push(message);
- }
- }
- counter++;
- }
- return parsed;
- },
- generate: function () {
- throw "Feature unimplemented";
- }
- };
- var Providers = {};
- Providers.Base = function (domain) {
- var me = this, consumer_callback = [], has = Object.prototype.hasOwnProperty;
- me.domain = domain;
- me.waiting = true;
- me.notifyConsumers = function(data){
- for(var pos in consumer_callback){
- if(has.call(consumer_callback,pos)){
- consumer_callback[pos].call(consumer_callback[pos], data);
- }
- }
- me.waiting = true;
- }
- me.done = function (callback) {
- consumer_callback.push(callback);
- var itv = setInterval(function () {
- if (!me.waiting) {
- me.notifyConsumers(me.parsed);
- clearInterval(itv);
- }
- }, 4);
- }
- };
- Providers.Base.prototype = {
- toString: function () {
- return '[object Adapter]'
- },
- getContents: function(){}
- };
- Providers.Base.extend = extend;
- Providers.String = Providers.Base.extend({
- constructor: function (literal_string, domain) {
- Providers.Base.call(this, domain);
- this.parsed = null;
- this.unparsed = '' + literal_string;
- },
- getContents: function () {
- var me = this, parsed;
- parsed = Parser.POFiles.parse(this.unparsed, this.domain);
- if(!parsed){
- throw new Errors.ParsingError(this.unparsed);
- }
- me.parsed = parsed;
- me.notifyConsumers(me.parsed);
- }
- });
- if (!isBrowser()) {
- Providers.File = Providers.Base.extend({
- constructor: function (path_to_file, domain) {
- Providers.Base.call(this, domain);
- this.path = '' + path_to_file;
- },
- getContents: function () {
- var me = this;
- instance.waiting = true;
- me.waiting = true;
- require('fs').readFile(this.path, 'utf-8', function (err, data) {
- if (!err) {
- me.parsed = Parser.POFiles.parse(data, me.domain);
- me.waiting = false;
- }
- else {
- throw new Errors.FileReaderError(err.path);
- }
- });
- }
- });
- }
- else{
- console.log('wat');
- }
- if (isBrowser()) {
- Providers.Ajax = Providers.Base.extend({
- constructor: function (url, domain) {
- Providers.Base.call(this, domain);
- this.url = url;
- },
- doRequest: function (url, success, error) {
- var request = new XMLHttpRequest(), noop = function(){};
- request.open('GET', url, true);
- success = !success ? noop : success;
- error = !error ? noop : error;
- try {
- request.onreadystatechange = function () {
- var data = {error: true};
- if (this.readyState === 4) {
- if (this.status >= 200 && this.status < 400) {
- data = this.responseText;
- success.call(success, data);
- }
- else {
- error.call(error, data);
- }
- }
- };
- request.send();
- }
- catch (Whatever) {
- error.call(error, {error: true});
- }
- request = null;
- },
- /**
- * Read all <link> elements with a type="text/x-gettext-translation" into the dictionary
- * @param domain
- * @constructor
- */
- getContents: function () {
- var domain = this.domain, me = this;
- me.waiting = true;
- this.doRequest(this.url, function (result) {
- var adapter = new Providers.String(result, domain);
- adapter.done(function(data){
- me.parsed = data;
- me.notifyConsumers(data);
- });
- adapter.getContents();
- });
- }
- });
- }
- if (isBrowser()) {
- Providers.Links = Providers.Ajax.extend({
- constructor: function(domain){
- Providers.Ajax.call(this,domain);
- this.domain = domain;
- },
- getContents: function () {
- var links = document.getElementsByTagName('link'), link, Ajax = Providers.Ajax, me = this;
- me.waiting = true;
- for (var i = 0, j = links.length; i < j; i++) {
- link = links[i];
- if (
- !!link
- && !!link.getAttribute('type')
- && !!link.getAttribute('href')
- && link.getAttribute('type') === 'text/x-gettext-translation'
- ) {
- me.waiting = true;
- this.doRequest(link.href, function (result) {
- var adapter = new Providers.String(result, me.domain);
- adapter.done(function(data){
- me.parsed = data;
- me.notifyConsumers(data);
- });
- adapter.getContents();
- });
- }
- }
- }
- });
- }
- var Pomo = function () {
- var me = this, ready_callback;
- me.storage = {};
- me.waiting = true;
- me.VERSION = '0.1.3';
- me.domain = 'messages';
- me.returnStrings = false;
- me.unescapeStrings = false;
- me.ready = function (callback) {
- ready_callback = callback;
- var itv = setInterval(function () {
- if (!me.waiting) {
- clearInterval(itv);
- ready_callback.call(ready_callback);
- }
- }, 2);
- };
- me.wipe = function(){
- me.storage = {};
- me.waiting = true;
- };
- me.load = function (resource, options) {
- options = !options ? {} : options;
- me.waiting = true;
- var mode = !!options.mode ? options.mode : false,
- translation_domain = !!options.translation_domain ? options.translation_domain : 'messages',
- provider;
- switch (mode) {
- case 'literal':
- provider = new Providers.String(resource, translation_domain);
- break;
- case 'file':
- provider = new Providers.File(resource, translation_domain);
- break;
- case 'link':
- provider = new Providers.Links(translation_domain);
- break;
- case 'ajax':
- provider = new Providers.Ajax(resource, translation_domain);
- break;
- default:
- throw new Errors.UnknownAcquisitionModeError(mode);
- break;
- }
- provider.done(function (data) {
- me.storage.contents = data;
- me.waiting = false;
- });
- provider.getContents();
- return this;
- };
- me.getText = function (msg_id, options) {
- msg_id = msg_id.split(/\n/).join('');
- options = !options ? {} : options;
- var variables = !!options.variables ? options.variables : [],
- context = !!options.context ? options.context : false,
- domain = !!options.domain ? options.domain : 'messages',
- count = !!options.count ? options.count : false,
- error_callback = !options.error? noop : options.error,
- escaped = escapeString(msg_id);
- if (!domain && !me.domain) {
- domain = me.domain = 'messages';
- }
- else if (domain && !me.domain) {
- me.domain = domain;
- }
- else {
- me.domain = domain;
- }
- if (entryExists(me.storage, domain, escaped)) {
- var entry = me.storage.contents[domain][escaped];
- if (!!context) {
- for (var i = 0, j = entry.length; i < j; i++) {
- if (entry[i].context && entry[i].context === context) {
- entry = entry[i];
- break;
- }
- }
- }
- if (entry.unshift) {
- entry = entry[0];
- }
- if (!!count) {
- entry.setCount(count);
- }
- var translation = entry,
- is_bare_string = (entry.constructor === String());
- if (me.returnStrings) {
- translation = entry.toString();
- }
- if (!!variables) {
- var bare_string = is_bare_string ? translation : translation.translation,
- translated = vsprintf(bare_string, variables);
- if (!is_bare_string) {
- translation.translation = translated;
- }
- else {
- translation = translated;
- }
- }
- if (is_bare_string && me.unescapeStrings) {
- translation = unescapeString(translation);
- }
- else if (me.unescapeStrings && !is_bare_string) {
- translation.translation = unescapeString(translation.translation);
- }
- return translation;
- }
- else {
- if(error_callback === noop){
- return escaped;
- }
- else{
- error_callback(error_callback, msg_id, domain, me.storage.contents);
- }
- }
- };
- };
- instance = new Pomo();
- if (typeof (module) !== 'undefined') {
- module.exports = instance;
- }
- else {
- window['Pomo'] = instance;
- }
- })(this);
|