Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/bareos/bareos-webui.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'public/js/i_gettext.js')
-rw-r--r--public/js/i_gettext.js1487
1 files changed, 0 insertions, 1487 deletions
diff --git a/public/js/i_gettext.js b/public/js/i_gettext.js
deleted file mode 100644
index bfa2c4c..0000000
--- a/public/js/i_gettext.js
+++ /dev/null
@@ -1,1487 +0,0 @@
-(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
-/*=================================================================================================================================================
- * Pure Javascript implementation of Uniforum message translation.
- * This implementation of GNU Gettext, providing internationalization support for javascript.
- * It differs from existing javascript implementations in that it will support all current Gettext features
- *(ex. plural and context support), and will also support loading language catalogs from .mo, .po, or preprocessed json files (converter included).
- * It use this [2008 - Javascript Gettext](https://sourceforge.net/projects/jsgettext.berlios/?source=navbar)
- * Thank to [Joshua I. Miller](mailto:unrtst@cpan.org) for that great work.
- *=================================================================================================================================================
-
-- The following methods are kept in:
-
- textdomain (domain)
- gettext (msgid)
- dgettext (domainname, msgid)
- dcgettext (domainname, msgid, LC_MESSAGES)
- ngettext (msgid, msgid_plural, count)
- dngettext (domainname, msgid, msgid_plural, count)
- dcngettext (domainname, msgid, msgid_plural, count, LC_MESSAGES)
- pgettext (msgctxt, msgid)
- dpgettext (domainname, msgctxt, msgid)
- dcpgettext (domainname, msgctxt, msgid, LC_MESSAGES)
- npgettext (msgctxt, msgid, msgid_plural, count)
- dnpgettext (domainname, msgctxt, msgid, msgid_plural, count)
- dcnpgettext (domainname, msgctxt, msgid, msgid_plural, count, LC_MESSAGES)
- strargs (string, args_array)
-
-- The following methods are removed
-
- get_lang_refs (link)
- isValidOject ()
- isArray (Object)
-
-- The following methods are completely rewritten
-
- new Gettext ()
- try_load_lang ()
-
-- The following methods are added
-
- setlocale (locale)
- bindtextdomaine (domain, path_to_locale, type)
- try_load_alternative_lang (domain, link)
- try_load_mo (data) //not yet ready @TODO put available when it will ready
- parse_mo (data) //not yet ready @TODO put available when it will ready
- parseHeader (data) //not yet ready @TODO put available when it will ready
-
-- Some other modifications are done for changes and updates
-
-The implementation of this library have been made to be more convenient with GNU Gettext references.
-In addition, no only "po" or "mo" files can be use to content the messages data, but also "json" files or objects.
-
-This has been tested on the following browsers. It may work on others, but these are all those to which I have access.
- FF1.5, FF2, FF3, IE6, IE7, Opera9, Opera10, Safari3.1, Chrome
- *FF = Firefox
- *IE = Internet Explorer
-
-SEE ALSO
---------
-po2json (included),
-docs/index.html,
-test/
-Locale::gettext_pp(3pm), POSIX(3pm), gettext(1), gettext(3)
-
-*/
-
-/**
- * Javascript implemenation of GNU Gettext API.
- * @class
- * @constructs iJS.Gettext
- * @returns {iJS.Gettext}
- * @example
- * //create new instance
- * var igt = new iJS.Gettext() ;
- * //set the locale in which the messages have to be translated.
- * igt.setlocale("fr_FR.utf8") ; // local can also be *fr_FR* or *fr*.
- * //Supposing that most users now have browser that support Ajax;
- * //also add or register a domain where to get the messages data.
- * igt.bindtextdomain("mydomain", "./path_to_locale", "po") ; //"po" can also be "json" or by default "mo".
- * //Always do this after a `setlocale` or a `bindtextdomain` call.
- * igt.try_load_lang() ; //will load and parse messages data from the setting catalog.
- * //Then print your messages
- * alert( igt.gettext("Hello world!") ) ;
- *
- * //Like with GNU gettext, your domain path have to be
- * // path_to_locale/LC_MESSAGES/fr_FR.utf8/mydomain.po
- * // if "fr_FR.utf8" is not found, "fr_FR" or "fr" will be use for replacement.
- * //This is just an overview. See tutoriels for more.
- *
- * //Optimum caching way to add domain is to use *<script>* tag to load it via *iJS.Gettext*’s json like file.
- * //just do this to add or register a domain where to get the messages data.
- * igt.locale_data = external_locale_data ;
- * igt.bindtextdomain("json-domain") ; //domain can be any domain in *external_locale_date*
- * /* Supposing that this declaration have be done:`<SCRIPT language="javascript" src="path_to/gettext_json_file"></SCRIPT>`
- * * and the gettext_json_file content structurate object like:
- * external_locale_data = {
- "json-domain" : {
- // po header fields
- "" : {
- "plural-forms" : "...",
- "lang" : "en",
- },
- // all the msgid strings and translations
- "msgid" : [ "msgid_plural", "translation", "plural_translation" ],
- "msgctxt\004msgid" : [ null, "msgstr" ],
- },
- "AnotherDomain" : {
- },
- };
- */
-iJS.Gettext = function () {
-
- this.domain = 'messages';
- this.domain_registry = [] ; // will content all the indicated domain and associated paths
- // locale_data will be populated when will `try_load_lang`
- this.locale_data = undefined;
- this.locale_format = null; // will indicate how the locale name is formatted
- this.locale = null;
-
- return this;
-}
-
-/**
- * @property {iJS.Gettext} i18n Defined `Gettext` object, to make *iJS gettext* functionalities to be directly use.
- * @example
- * //set the locale in which the messages will be translated
- * iJS.i18n.setlocale("en_US.utf8") ;
- * //add domain where to find messages data
- * iJS.i18n.bindtextdomain("domain_po", "./path_to_locale", "po") ;
- * //add another domain where to find messages data
- * iJS.i18n.bindtextdomain("domain_json", "./path_to_locale", "json") ;
- * //Always do this after a `setlocale` or a `bindtextdomain` call.
- * iJS.i18n.try_load_lang() ; //will load and parse messages data from the setting catalog.
- * //set the current domain
- * iJS.i18n.textdomain("domain_po") ;
- * //now print your messages
- * alert( iJS.i18n.gettext("messages to be translated") ) ;
- */
-iJS.i18n = new iJS.Gettext() ;
-
-/**
- * Easily translate your messages when use `Gettext` functionalities.<BR/>
- * Same as you call `iJS.i18n.gettext()`. See documentation of associated terms for more informations.
- * @global
- * @param {String} msgid message to be translated
- * @returns {String} translated message if is found or `msgid` if not.
- * @example
- * //set the locale in which the messages will be translated
- * iJS.i18n.setlocale("en_US.utf8") ;
- * //add domain where to find messages data
- * iJS.i18n.bindtextdomain("domain_po", "./path_to_locale", "po") ;
- * iJS.i18n.try_load_lang() ; //will load and parse messages data from the setting catalog.
- * //now print your messages
- * alert( iJS._("messages to be translated") ) ;
- */
-iJS._ = function (msgid) {
-
- return iJS.i18n.gettext( msgid ) ;
-}
-
-/**
- * Set the locale in which the messages have to be translated.
- * @memberof iJS.Gettext
- * @param {String} locale egg: "en", "en_US.utf8", "en_GB" ...
- */
-iJS.Gettext.prototype.setlocale = function (locale) {
-
- if (iJS.isString( locale )) {
-
- if (/^.._..\./.test( locale )) {
- this.locale_format = 2 ; //egg: *en_US.utf8*
-
- } else if (/^.._..$/.test( locale )) {
- this.locale_format = 1 ; //egg: *en_US*
-
- } else if (/^..$/.test( locale )) {
- this.locale_format = 0 ; //egg: *en*
-
- } else {
- this.locale_format = -1 ; //egg: *french*
- console.warn("iJS-gettext:'setlocale': It seem like locale: *"+locale+"* do not conform to the **i18n standard format**.") ;
- }
-
- this.locale = locale ;
- //alert(this.locale)
- } else {
- throw new Error("iJS-gettext:'setlocale': Invalid argument: *"+locale+"* have to be a `string`.") ;
- }
-};
-
-/**
- * Add or register a domain where to get the messages data
- * @memberof iJS.Gettext
- * @param {string} domain The Gettext domain, not www.whatev.com. If the .po file was "myapp.po", this would be "myapp".
- * @param {string} localePath Path to the locale directory where to find the domain. <BR/>
- * <U>egg:</U> "./locale" in which we can have ".locale/LC_MESSAGES/fr_FR.utf8/domain.po". <BR/>
- * If omitted, it will mean that domain will be considered in a json Object or file.
- * See tutorials for more explanation.
- * @param {string} dtype Type of domain file. Supported files are "po", "json" and "mo"(support is planned).
- * If omitted, the default value will be "mo".
- */
-iJS.Gettext.prototype.bindtextdomain = function (domain, localePath, dtype) {
-
- var new_domain, new_locale_path, new_dtype ;
-
- if (iJS.isString( domain )) {
- new_domain = domain ;
-
- } else {
- throw new Error("iJS-gettext:'bindtextdomain': a *domaine* have to be defined as argument.") ;
- }
-
- if (iJS.isString( dtype )){
-
- if ( dtype == "mo" || dtype == "po" || dtype == "json" ) {
- new_dtype = dtype ;
-
- } else {
- throw new Error("iJS-gettext:'bindtextdomain': type: *"+dtype+"* is not supported. Use *mo*, *po* or *json* files.") ;
- }
- } else {
- new_dtype = "mo" ;
- };
-
- if (iJS.isString( localePath ) ) {
- new_locale_path = localePath ;
-
- } else {
- new_locale_path = "" ;
- }
-
-
- if ( !iJS.isArray( this.domain_registry ) ) this.domain_registry = [];
-
- if (!this.domain_registry.length) { //first initialization
- this.domain_registry.push( {value: new_domain, path: new_locale_path, type: new_dtype} ) ;
-
- } else { //attempt to add new domain or reset if it’s already added.
-
- var isNewDomaine = true ;
-
- for (var d in this.domain_registry) {
-
- if (this.domain_registry[d].value == new_domain) {
-
- console.warn("iJS-gettext:'bindtextdomain': domaine: *"+new_domain+"* is already added and will just be reset") ;
- this.domain_registry[d].path = new_locale_path ;
- this.domain_registry[d].type = new_dtype ;
- isNewDomaine = false ;
- break;
- }
- }
-
- if (isNewDomaine) this.domain_registry.push( {value: new_domain, path: new_locale_path, type: new_dtype} ) ;
- }
-};
-
-/**
- * Use for some concatenation: see for example `iJS.Gettext.prototype.parse_po`.
- * @private
- * @memberof iJS.Gettext
- */
-iJS.Gettext.context_glue = "\004" ;
-/**
- * json structure of all registered domain with corresponding messages data.
- * It depend of setting locale which define the catalog that will be load.
- * It will also content messages data that are parsed from developer’s defined json'd portable object.
- * @private
- * @memberof iJS.Gettext
- */
-iJS.Gettext._locale_data = {} ;
-
-/**
- * Load and parse all the messages data from domain in the domain’s registry.
- * Data are load depending of the setting catalog or developer’s defined json’d portable object.
- * Parsed data are save in a internal json structure, to make them easily accessible, depending of the current domain.
- * This method have to be always call after a `setlocale` and `bindtextdomain` call.
- * @memberof iJS.Gettext
- */
-iJS.Gettext.prototype.try_load_lang = function () {
-
- if (iJS.isSet( this.domain_registry ) && iJS.isSet( this.locale) ) {
-
- /* @TODO execept the fact that loaded file are cached by browser,
- *so that new reload must be fast, it's better to see how to keep already load messages data;
- *and just download those which have to be loaded.
- */
- //firstly clean the locale data, assuming that it will content new parsed data.
- iJS.Gettext._locale_data = {} ;
-
- // NOTE: there will be a delay here, as this is async.
- // So, any i18n calls made right after page load may not
- // get translated.
- // XXX: we may want to see if we can "fix" this behavior
- var domain = null ,
- link = null ;
- for (var d in this.domain_registry) {
-
- domain = this.domain_registry[d] ;
- //When get *link.href* it return the absolute path, event if it initially define with *relative path*.
- //That why is more convenient to define *link* as `HTMLlinkElement` than as `string`.
- link = document.createElement("link") ;
- if (domain.type == 'json') {
-
- link.href = domain.path+"/"+this.locale+"/LC_MESSAGES/"+domain.value+".json" ;
- if (! this.try_load_lang_json(link.href) ) {
-
- this.try_load_alternative_lang(domain, link) ;
- }
- } else if (domain.type == 'po') {
-
- link.href = domain.path+"/"+this.locale+"/LC_MESSAGES/"+domain.value+".po" ;
- if (! this.try_load_lang_po(link.href) ) {
-
- this.try_load_alternative_lang(domain, link) ;
- }
- } else {
- //if `domain.path` is not define, check to see if language is statically included via a json object.
- if (domain.path == "") {
-
- if (typeof( this.locale_data ) != 'undefined') {
- // we're going to reformat it, and overwrite the variable
- var locale_data_copy = this.locale_data ;
- this.locale_data = undefined ;
- this.parse_locale_data(locale_data_copy) ;
-
- if (typeof( iJS.Gettext._locale_data[domain.value] ) == 'undefined') {
- console.error("iJS-gettext:'try_load_lang':'locale_data': does not contain the domain '"+domain.value+"'") ;
- }
- }
-
- } else {
- // TODO: implement the other types (.mo)
- /*link.href = domain.path+"/"+this.locale+"/LC_MESSAGES/"+domain.value+".mo" ;
- if (! this.try_load_lang_mo(link.href) ) {
-
- this.try_load_alternative_lang(domain, link) ;
- }//*/
- throw new Error("TODO: link type mo found, support is planned, but not implemented at this time.") ;
- }
-
- }
- }
-
- } else {
- console.warn("iJS-gettext:'try_load_lang': Not thing to do. It’s seem like no locale or domain have been register. Use `setlocale` or `bindtextdomain` for that.") ;
- }
-};
-
-/**
- * Try to load messages data from alternative catalog when associated catalog of user’s given locale can’t be found. <BR/>
- * for example for a given "en_US.UTF8" locale, if associated catalog can’t be found, this will try to find it with "en_US" or "en".
- * @private
- * @memberof iJS.Gettext
- * @param {Object} domain from domain’s registry
- * @param {HTMLLinkElement} link content the catalog’s path
- */
-iJS.Gettext.prototype.try_load_alternative_lang = function (domain, link) {
-
- if (iJS.isObject( domain ) && iJS.isHTMLLinkElement( link )) {
-
- var isCatalogOk = false ;
-
- switch (this.locale_format) {
-
- case 2: //locale name format is something like *en_US.utf8*. will try to use *en_US* or *en* format
- console.warn("iJS-gettext:'try_load_lang': domaine: *"+domain.value+"* not found with locale: *"+this.locale+"* format. Will try to use *"+this.locale.split('.')[0]+"* format...") ;
- link.href = domain.path+"/"+this.locale.split('.')[0]+"/LC_MESSAGES/"+domain.value+"."+domain.type ;
-
- if (domain.type == "json")
- isCatalogOk = (this.try_load_lang_json( link.href )) ? true : false ;
- else if (domain.type == "po")
- isCatalogOk = (this.try_load_lang_po( link.href )) ? true : false ;
- //else
- //@TODO it will be by default "mo", not supported yet but it’s plan.
-
- if (! isCatalogOk) {
-
- console.warn("iJS-gettext:'try_load_lang': domaine: *"+domain.value+"* not found with locale: *"+this.locale.split('.')[0]+"* format. Will try to use *"+this.locale.split('_')[0]+"* format...") ;
- link.href = domain.path+"/"+this.locale.split('_')[0]+"/LC_MESSAGES/"+domain.value+"."+domain.type ;
-
- if (domain.type == "json")
- isCatalogOk = (this.try_load_lang_json( link.href )) ? true : false ;
- else if (domain.type == "po")
- isCatalogOk = (this.try_load_lang_po( link.href )) ? true : false ;
- //else
- //@TODO it will be by default "mo", not supported yet but it’s plan.
- //isCatalogOk = (this.try_load_lang_mo( link.href )) ? true : false ;
-
- if (! isCatalogOk) {
-
- link.href = domain.path+"/"+this.locale+"/LC_MESSAGES/"+domain.value+"."+domain.type;
- console.warn("iJS-gettext:'try_load_lang_"+domain.type+"': failed. Unable to exec XMLHttpRequest for link ["+link.href+"]") ;
- }
- }
- break;
-
- case 1://locale name format is something like *en_US*. will try to use *en* format
- console.warn("iJS-gettext:'try_load_lang': domaine: *"+domain.value+"* not found with locale: *"+this.locale+"* format. Will try to use *"+this.locale.split('_')[0]+"* format...") ;
- link.href = domain.path+"/"+this.locale.split('_')[0]+"/LC_MESSAGES/"+domain.value+"."+domain.type ;
-
- if (domain.type == "json")
- isCatalogOk = (this.try_load_lang_json( link.href )) ? true : false ;
- else if (domain.type == "po")
- isCatalogOk = (this.try_load_lang_po( link.href )) ? true : false ;
- //else
- //@TODO it will be by default "mo", not supported yet but it’s plan.
- //isCatalogOk = (this.try_load_lang_mo( link.href )) ? true : false ;
-
- if (! isCatalogOk) {
-
- link.href = domain.path+"/"+this.locale+"/LC_MESSAGES/"+domain.value+"."+domain.type;
- console.error("iJS-gettext:'try_load_lang_"+domain.type+"': failed. Unable to exec XMLHttpRequest for link ["+link.href+"]") ;
- }
- break;
-
- default:
- console.error("iJS-gettext:'try_load_lang_"+domain.type+"': failed. Unable to exec XMLHttpRequest for link ["+link.href+"]") ;
- break;
- }
- } else {
-
- console.warn("iJS-gettext:'try_load_alternative_lang': nothing to do or invalid arguments.") ;
- }
-
-};
-
-/**
- * This takes a json’d data (a portable object variant) and moves it into an internal form,
- * for use in our lib, and puts it in our object as:
- * <PRE><CODE>
- iJS.Gettext._locale_data = {
- domain : {
- head : { headfield : headvalue },
- msgs : {
- msgid : [ msgid_plural, msgstr, msgstr_plural ],
- },
- ...
- </CODE></PRE>
- * The json’d data have to respect the library specifications for that.
- * For details see the script **po2json** in the associated binary directory.
- * Also see tutorials for more explanations.
- * @private
- * @memberof iJS.Gettext
- * @param {Object} locale_data json *portable object*
- * @returns {Object} [[Description]]
- */
-iJS.Gettext.prototype.parse_locale_data = function (locale_data) {
-
- if (typeof( iJS.Gettext._locale_data ) == 'undefined') {
- iJS.Gettext._locale_data = {};
- }
-
- // suck in every domain defined in the supplied data
- for (var domain in locale_data) {
- // skip empty specs (flexibly)
- if ((! locale_data.hasOwnProperty(domain)) || (! iJS.isSet(locale_data[domain])))
- continue;
- // skip if it has no msgid's
- var has_msgids = false;
- for (var msgid in locale_data[domain]) {
- has_msgids = true;
- break;
- }
- if (! has_msgids) continue;
-
- // grab shortcut to data
- var data = locale_data[domain];
-
- // if they specifcy a blank domain, default to "messages"
- if (domain == "") domain = "messages";
- // init the data structure
- if (! iJS.isSet( iJS.Gettext._locale_data[domain]) )
- iJS.Gettext._locale_data[domain] = { };
- if (! iJS.isSet( iJS.Gettext._locale_data[domain].head) )
- iJS.Gettext._locale_data[domain].head = { };
- if (! iJS.isSet( iJS.Gettext._locale_data[domain].msgs) )
- iJS.Gettext._locale_data[domain].msgs = { };
-
- for (var key in data) {
- if (key == "") {
- var header = data[key];
- for (var head in header) {
- var h = head.toLowerCase();
- iJS.Gettext._locale_data[domain].head[h] = header[head];
- }
- } else {
- iJS.Gettext._locale_data[domain].msgs[key] = data[key];
- }
- }
- }
-
- // build the plural forms function
- for (var domain in iJS.Gettext._locale_data) {
-
- if (iJS.isSet( iJS.Gettext._locale_data[domain].head['plural-forms'] ) &&
- typeof( iJS.Gettext._locale_data[domain].head.plural_func ) == 'undefined') {
- // untaint data
- var plural_forms = iJS.Gettext._locale_data[domain].head['plural-forms'];
- var pf_re = new RegExp('^(\\s*nplurals\\s*=\\s*[0-9]+\\s*;\\s*plural\\s*=\\s*(?:\\s|[-\\?\\|&=!<>+*/%:;a-zA-Z0-9_\(\)])+)', 'm');
- if (pf_re.test(plural_forms)) {
- //ex english: "Plural-Forms: nplurals=2; plural=(n != 1);\n"
- //pf = "nplurals=2; plural=(n != 1);";
- //ex russian: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10< =4 && (n%100<10 or n%100>=20) ? 1 : 2)
- //pf = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)";
-
- var pf = iJS.Gettext._locale_data[domain].head['plural-forms'];
- if (! /;\s*$/.test(pf)) pf = pf.concat(';');
- /* We used to use eval, but it seems IE has issues with it.
- * We now use "new Function", though it carries a slightly
- * bigger performance hit.
- var code = 'function (n) { var plural; var nplurals; '+pf+' return { "nplural" : nplurals, "plural" : (plural === true ? 1 : plural ? plural : 0) }; };';
- iJS.Gettext._locale_data[domain].head.plural_func = eval("("+code+")");
- */
- var code = 'var plural; var nplurals; '+pf+' return { "nplural" : nplurals, "plural" : (plural === true ? 1 : plural ? plural : 0) };';
- iJS.Gettext._locale_data[domain].head.plural_func = new Function("n", code);
-
- } else {
- throw new Error("iJS-gettext:'parse_locale_data': Syntax error in language file. Plural-Forms header is invalid ["+plural_forms+"]");
- }
-
- // default to english plural form
- } else if (typeof( iJS.Gettext._locale_data[domain].head.plural_func ) == 'undefined') {
- iJS.Gettext._locale_data[domain].head.plural_func = function (n) {
- var p = (n != 1) ? 1 : 0;
- return { 'nplural' : 2, 'plural' : p };
- };
- } // else, plural_func already created
- }
-
- return;
-};
-
-
-/**
- * Do an ajax call to load in a .po files, language definitions from associated catalog.
- * @private
- * @memberof iJS.Gettext
- * @param {string} uri link to the "po" files
- * @returns {number} *1* if the operation is a success, *undefined* if not.
- */
-iJS.Gettext.prototype.try_load_lang_po = function (uri) {
-
- var data = this.sjax(uri);
- if (! data) return;
- var domain = this.uri_basename(uri);
- var parsed = this.parse_po(data);
-
- var rv = {};
- // munge domain into/outof header
- if (parsed) {
- if (! parsed[""]) parsed[""] = {};
- if (! parsed[""]["domain"]) parsed[""]["domain"] = domain;
- domain = parsed[""]["domain"];
- rv[domain] = parsed;
-
- this.parse_locale_data(rv);
- }
-
- return 1;
-};
-
-/**
- * Do an ajax call to load in a .mo files, language definitions from associated catalog.
- * @NOTE not yet ready
- * @TODO put available when it will ready. For problems here see `parso_mo` implementation.
- * @private
- * @memberof iJS.Gettext
- * @param {string} uri link to the "mo" files
- * @returns {number} *1* if the operation is a success, *undefined* if not.
- */
-iJS.Gettext.prototype.try_load_lang_mo = function (uri) {
-
- var data = this.sjax(uri);
- if (! data) return;
- var domain = this.uri_basename(uri);
- var parsed = this.parse_mo(data);
-//alert(parsed);
- var rv = {};
- // munge domain into/outof header
- if (parsed) {
- if (! parsed[""]) parsed[""] = {};
- if (! parsed[""]["domain"]) parsed[""]["domain"] = domain;
- domain = parsed[""]["domain"];
- rv[domain] = parsed;
-
- this.parse_locale_data(rv);
- }
-
- return 1;
-};
-
-/**
- * Get the base name of an url.
- * Needed for know in which domain are loaded the messages data.
- * Url’s base name will be considered as domain.
- * @private
- * @memberof iJS.Gettext
- * @param {string} uri an url
- * @returns {string} the base name of the given url.
- */
-iJS.Gettext.prototype.uri_basename = function (uri) {
-
- var rv;
- if (rv = uri.match(/^(.*\/)?(.*)/)) {
- var ext_strip;
- if (ext_strip = rv[2].match(/^(.*)\..+$/))
- return ext_strip[1];
- else
- return rv[2];
- } else {
- return "";
- }
-};
-
-/**
- * Parse po data in a json structure.
- * (like the library associated **po2json** perl script).
- * @TODO ( also associate a **po2json** nodejs script).
- * @private
- * @memberof iJS.Gettext
- * @param {String} data a portable object content
- * @returns {Object} a json parsed data
- */
-iJS.Gettext.prototype.parse_po = function (data) {
-
- var rv = {};
- var buffer = {};
- var lastbuffer = "";
- var errors = [];
- var lines = data.split("\n");
-
- for (var i=0; i<lines.length; i++) {
- // chomp
- lines[i] = lines[i].replace(/(\n|\r)+$/, '');
-
- var match;
- // Empty line / End of an entry.
- if (/^$/.test(lines[i])) {
- if (typeof( buffer['msgid'] ) != 'undefined') {
- var msg_ctxt_id = (typeof( buffer['msgctxt'] ) != 'undefined' &&
- buffer['msgctxt'].length) ?
- buffer['msgctxt']+iJS.Gettext.context_glue+buffer['msgid'] :
- buffer['msgid'];
- var msgid_plural = (typeof( buffer['msgid_plural'] ) != 'undefined' &&
- buffer['msgid_plural'].length) ?
- buffer['msgid_plural'] :
- null;
-
- // find msgstr_* translations and push them on
- var trans = [];
- for (var str in buffer) {
- var match;
- if (match = str.match(/^msgstr_(\d+)/))
- trans[parseInt(match[1])] = buffer[str];
- }
- trans.unshift(msgid_plural);
-
- // only add it if we've got a translation
- // NOTE: this doesn't conform to msgfmt specs
- if (trans.length > 1) rv[msg_ctxt_id] = trans;
-
- buffer = {};
- lastbuffer = "";
- }
-
- // comments
- } else if (/^#/.test(lines[i])) {
- continue;
-
- // msgctxt
- } else if (match = lines[i].match(/^msgctxt\s+(.*)/)) {
- lastbuffer = 'msgctxt';
- buffer[lastbuffer] = this.parse_po_dequote(match[1]);
-
- // msgid
- } else if (match = lines[i].match(/^msgid\s+(.*)/)) {
- lastbuffer = 'msgid';
- buffer[lastbuffer] = this.parse_po_dequote(match[1]);
-
- // msgid_plural
- } else if (match = lines[i].match(/^msgid_plural\s+(.*)/)) {
- lastbuffer = 'msgid_plural';
- buffer[lastbuffer] = this.parse_po_dequote(match[1]);
-
- // msgstr
- } else if (match = lines[i].match(/^msgstr\s+(.*)/)) {
- lastbuffer = 'msgstr_0';
- buffer[lastbuffer] = this.parse_po_dequote(match[1]);
-
- // msgstr[0] (treak like msgstr)
- } else if (match = lines[i].match(/^msgstr\[0\]\s+(.*)/)) {
- lastbuffer = 'msgstr_0';
- buffer[lastbuffer] = this.parse_po_dequote(match[1]);
-
- // msgstr[n]
- } else if (match = lines[i].match(/^msgstr\[(\d+)\]\s+(.*)/)) {
- lastbuffer = 'msgstr_'+match[1];
- buffer[lastbuffer] = this.parse_po_dequote(match[2]);
-
- // continued string
- } else if (/^"/.test(lines[i])) {
- buffer[lastbuffer] += this.parse_po_dequote(lines[i]);
-
- // something strange
- } else {
- errors.push("Strange line ["+i+"] : "+lines[i]);
- }
- }
-
- // handle the final entry
- if (typeof( buffer['msgid'] ) != 'undefined') {
-
- var msg_ctxt_id = (typeof( buffer['msgctxt'] ) != 'undefined' && buffer['msgctxt'].length) ?
- buffer['msgctxt']+iJS.Gettext.context_glue+buffer['msgid'] : buffer['msgid'];
- var msgid_plural = (typeof( buffer['msgid_plural'] ) != 'undefined' &&
- buffer['msgid_plural'].length) ? buffer['msgid_plural'] : null;
-
- // find msgstr_* translations and push them on
- var trans = [];
- for (var str in buffer) {
- var match;
- if (match = str.match(/^msgstr_(\d+)/))
- trans[parseInt(match[1])] = buffer[str];
- }
- trans.unshift(msgid_plural);
-
- // only add it if we've got a translation
- // NOTE: this doesn't conform to msgfmt specs
- if (trans.length > 1) rv[msg_ctxt_id] = trans;
-
- buffer = {};
- lastbuffer = "";
- }
-
- // parse out the header
- if (rv[""] && rv[""][1]) {
- var cur = {};
- var hlines = rv[""][1].split(/\\n/);
- for (var i=0; i<hlines.length; i++) {
- if (! hlines.length) continue;
-
- var pos = hlines[i].indexOf(':', 0);
- if (pos != -1) {
- var key = hlines[i].substring(0, pos);
- var val = hlines[i].substring(pos +1);
- var keylow = key.toLowerCase();
-
- if (cur[keylow] && cur[keylow].length) {
- errors.push("SKIPPING DUPLICATE HEADER LINE: "+hlines[i]);
- } else if (/#-#-#-#-#/.test(keylow)) {
- errors.push("SKIPPING ERROR MARKER IN HEADER: "+hlines[i]);
- } else {
- // remove begining spaces if any
- val = val.replace(/^\s+/, '');
- cur[keylow] = val;
- }
-
- } else {
- errors.push("PROBLEM LINE IN HEADER: "+hlines[i]);
- cur[hlines[i]] = '';
- }
- }
-
- // replace header string with assoc array
- rv[""] = cur;
- } else {
- rv[""] = {};
- }
-
- // TODO: XXX: if there are errors parsing, what do we want to do?
- // GNU Gettext silently ignores errors. So will we.
- // alert( "Errors parsing po file:\n" + errors.join("\n") );
-
- return rv;
-};
-
-/**
- * Unscaled all embedded quotes in a string. Useful when parsing a po messages data.
- * @private
- * @memberof iJS.Gettext
- * @param {String} str string to analyse
- * @returns {String} formated string
- */
-iJS.Gettext.prototype.parse_po_dequote = function (str) {
-
- var match;
- if (match = str.match(/^"(.*)"/)) {
- str = match[1];
- }
- // unescale all embedded quotes (fixes bug #17504)
- str = str.replace(/\\"/g, "\"");
- return str;
-};
-
-
-/**
- * @constant {Number} Magic constant to check the endianness of the input file.
- * @memberof iJS.Gettext
- */
-iJS.Gettext.prototype.MAGIC = 314425327;
-
-/**
- * Parses a header string into an object of key-value pairs
- * @memberof iJS.Gettext
- * @private
- * @param {String} str Header string
- * @return {Object} An object of key-value pairs
- */
-iJS.Gettext.prototype.parseHeader = function (str) {
-
- var lines = (str || '').split('\n'),
- headers = {};
-
- lines.forEach(function(line) {
- var parts = line.trim().split(':'),
- key = (parts.shift() || '').trim().toLowerCase(),
- value = parts.join(':').trim();
- if (!key) {
- return;
- }
- headers[key] = value;
- });
-
- return headers;
-} ;
-
-/**
- * Normalizes charset name. Converts utf8 to utf-8, WIN1257 to windows-1257 etc.
- * @TODO see if it really necessary here.
- * @memberof iJS.Gettext
- * @private
- * @param {String} charset Charset name
- * @return {String} Normalized charset name
- */
-iJS.Gettext.prototype.formatCharset = function (charset, defaultCharset) {
-
- return (charset || 'iso-8859-1').toString().toLowerCase().
- replace(/^utf[\-_]?(\d+)$/, 'utf-$1').
- replace(/^win(?:dows)?[\-_]?(\d+)$/, 'windows-$1').
- replace(/^latin[\-_]?(\d+)$/, 'iso-8859-$1').
- replace(/^(us[\-_]?)?ascii$/, 'ascii').
- replace(/^charset$/, defaultCharset || 'iso-8859-1').
- trim();
-};
-
-
-/**
- * Parse mo data in a json structure.
- * (like the library associated **po2json** perl script).
- * @TODO ( also associate a **po2json** nodejs script).
- * @NOTE not yet ready. Base on **moparser** of [node-gettext](http://github.com/andris9/node-gettext).
- * @TODO put available when it will ready. Problems here (depending of `parso_mo` implementation)
- * are detection of magic number for *.mo* buffer and manipulating the considered buffer,
- * function of little endian or big endian structure.
- * @private
- * @memberof iJS.Gettext
- * @param {String} data a portable object content
- * @returns {Object} a json parsed data
- */
-iJS.Gettext.prototype.parse_mo = function (data, defaultCharset) {
-
- var _fileContents = new iJS.Buffer(data) ,
- _writeFunc = 'writeUInt32LE' , //Method name for writing int32 values, default littleendian
- _readFunc = 'readUInt32LE' , //Method name for reading int32 values, default littleendian
- _charset = defaultCharset || 'iso-8859-1',
-
- _table = {
- charset: _charset,
- headers: undefined,
- translations: {}
- };
-
- /**
- * Checks if number values in the input file are in big- or littleendian format.
- */
- //from mopaser _checkMagick function
- //alert (_fileContents.readUInt32LE(0))
- //alert (this.MAGIC)
- //alert (_fileContents.readUInt32LE(0) == this.MAGIC)
- if (_fileContents.readUInt32LE(0) == this.MAGIC) {
- _readFunc = 'readUInt32LE';
- _writeFunc = 'writeUInt32LE';
- //return true;
- } else if (_fileContents.readUInt32BE(0) === this.MAGIC) {
- _readFunc = 'readUInt32BE';
- _writeFunc = 'writeUInt32BE';
- //return true;
- } else {
- return false;
- }
-
- /**
- * GetText revision nr, usually 0
- */
- _revision = _fileContents[_readFunc](4);
-
- /**
- * Total count of translated strings
- */
- _total = _fileContents[_readFunc](8);
-
- /**
- * Offset position for original strings table
- */
- _offsetOriginals = _fileContents[_readFunc](12);
-
- /**
- * Offset position for translation strings table
- */
- _offsetTranslations = _fileContents[_readFunc](16);
-
- /**
- * Read the original strings and translations from the input MO file. Use the
- * first translation string in the file as the header.
- */
- // Load translations into _translationTable
- var offsetOriginals = _offsetOriginals,
- offsetTranslations = _offsetTranslations,
- position, length,
- msgid, msgstr;
-
- for (var i = 0; i < _total; i++) {
- // msgid string
- length = _fileContents[_readFunc](offsetOriginals);
- offsetOriginals += 4;
- position = _fileContents[_readFunc](offsetOriginals);
- offsetOriginals += 4;
- msgid = _fileContents.slice(position, position + length);
-
- // matching msgstr
- length = _fileContents[_readFunc](offsetTranslations);
- offsetTranslations += 4;
- position = _fileContents[_readFunc](offsetTranslations);
- offsetTranslations += 4;
- msgstr = _fileContents.slice(position, position + length);
-
- if (!i && !msgid.toString()) {
- /**
- * Detects charset for MO strings from the header
- */
- var headersStr = headers.toString(),
- match;
-
- if ((match = headersStr.match(/[; ]charset\s*=\s*([\w\-]+)/i))) {
- _charset = _table.charset = this.formatCharset(match[1], _charset);
- }
-
- //headers = encoding.convert(headers, 'utf-8', _charset).toString('utf-8');
-
- _table.headers = this.parseHeader(headersStr.toString('utf-8'));
- }
-
- //msgid = encoding.convert(msgid, 'utf-8', _charset).toString('utf-8');
- //msgstr = encoding.convert(msgstr, 'utf-8', _charset).toString('utf-8');
-
- /**
- * Adds a translation to the translation object
- */
- //form mopaser _addString(msgid, msgstr) ;
- //alert ("test")
- var translation = {},
- parts, msgctxt, msgid_plural;
-
- msgid = msgid.split('\u0004');
- if (msgid.length > 1) {
- msgctxt = msgid.shift();
- translation.msgctxt = msgctxt;
- } else {
- msgctxt = '';
- }
- msgid = msgid.join('\u0004');
-
- parts = msgid.split('\u0000');
- msgid = parts.shift();
-
- translation.msgid = msgid;
-
- if ((msgid_plural = parts.join('\u0000'))) {
- translation.msgid_plural = msgid_plural;
- }
-
- msgstr = msgstr.split('\u0000');
- translation.msgstr = [].concat(msgstr || []);
-
- if (!_table.translations[msgctxt]) {
- _table.translations[msgctxt] = {};
- }
-
- _table.translations[msgctxt][msgid] = translation;
- }
-
- // dump the file contents object
- _fileContents = null;
-
- return _table;
-
-};
-
-
-/**
- * Do an ajax call to load in a .json files, language definitions from associated catalog.
- * @private
- * @memberof iJS.Gettext
- * @param {string} uri link to the "json" files
- * @returns {number} *1* if the operation is a success, *undefined* if not.
- */
-iJS.Gettext.prototype.try_load_lang_json = function (uri) {
-
- var data = this.sjax(uri);
- if (! data) return;
-
- var rv = this.JSON(data);
- this.parse_locale_data(rv);
-
- return 1;
-};
-
-/**
- * Set domain for future `gettext()` calls. <BR/>
- * If the given domain is not NULL, the current message domain is set to it;
- * else the function returns the current message domain. <BR/>
- * A message domain is a set of translatable msgid messages. Usually,
- * every software package has its own message domain. The domain name is
- * used to determine the message catalog where a translation is looked up;
- * it must be a non-empty string.
- * @memberof iJS.Gettext
- * @param {string} domain message domain to set as current.
- * @returns {string} current message domain.
- */
-iJS.Gettext.prototype.textdomain = function (domain) {
-
- if (domain && domain.length) this.domain = domain;
- return this.domain;
-}
-
-
-/**
- * Returns the translation for **msgid**.<BR/>
- * If translation can’t be found, the unmodified **msgid** is returned.
- * @memberof iJS.Gettext
- * @param {String} msgid Message to translate
- * @returns {String} translated text or the *msgid* if not found
- */
-iJS.Gettext.prototype.gettext = function (msgid) {
-
- var msgctxt;
- var msgid_plural;
- var n;
- var category;
- return this.dcnpgettext(null, msgctxt, msgid, msgid_plural, n, category);
-};
-
-
-/**
- * Like `gettext()`, but retrieves the message for the specified
- * **TEXTDOMAIN** instead of the default domain.
- * @memberof iJS.Gettext
- * @param {String} domain Domain where translation can be found.
- * @param {String} msgid Message to translate
- * @returns {String} translated text or the *msgid* if not found
- */
-iJS.Gettext.prototype.dgettext = function (domain, msgid) {
-
- var msgctxt;
- var msgid_plural;
- var n;
- var category;
- return this.dcnpgettext(domain, msgctxt, msgid, msgid_plural, n, category);
-};
-
-/**
- * Like `dgettext()` but retrieves the message from the specified **CATEGORY**
- * instead of the default category "LC_MESSAGES". <BR/>
- * <U>NOTE:</U> the categories are really useless in javascript context. This is
- * here for GNU Gettext API compatibility. In practice, you'll never need
- * to use this. This applies to all the calls including the **CATEGORY**.
- * @memberof iJS.Gettext
- * @param {String} domain Domain where translation can be found.
- * @param {String} msgid Message to translate
- * @param {String} category (for now is will always be "LC_MESSAGES")
- * @returns {String} translated text or the *msgid* if not found
- */
-iJS.Gettext.prototype.dcgettext = function (domain, msgid, category) {
-
- var msgctxt;
- var msgid_plural;
- var n;
- return this.dcnpgettext(domain, msgctxt, msgid, msgid_plural, n, category);
-};
-
-
-/**
- * Retrieves the correct translation for **count** items.
- * @memberof iJS.Gettext
- * @param {String} msgid Message to translate
- * @param {String} msgid_plural Plural form of text to translate
- * @param {Number} n Counting number
- * @returns {String} translated text or the *msgid* if not found
- * @example
- * //In legacy software you will often find something like:
- * alert( count + " file(s) deleted.\n" );
- * //Before ngettext() was introduced, one of best practice for internationalized programs was:
- if (count == 1)
- alert( iJS._("One file deleted.\n") );
- else ...
-
- //This is a nuisance for the programmer and often still not sufficient for an adequate translation.
- //Many languages have completely different ideas on numerals. Some (French, Italian, ...) treat 0 and 1 alike,
- //others make no distinction at all (Japanese, Korean, Chinese, ...), others have two or more plural forms (Russian,
- //Latvian, Czech, Polish, ...). The solution is:
-
- alert( iJS.i18n.ngettext("One file deleted.\n", "%d files deleted.\n", count) );
- */
-iJS.Gettext.prototype.ngettext = function (msgid, msgid_plural, n) {
-
- var msgctxt;
- var category;
- return this.dcnpgettext(null, msgctxt, msgid, msgid_plural, n, category);
-};
-
-/**
- * Like `ngettext()` but retrieves the translation from the specified
- * textdomain instead of the default domain.
- * @memberof iJS.Gettext
- * @param {String} domain Domain where translation can be found.
- * @param {String} msgid Message to translate
- * @param {String} msgid_plural Plural form of text to translate
- * @param {Number} n Counting number
- * @returns {String} translated text or the *msgid* if not found
- */
-iJS.Gettext.prototype.dngettext = function (domain, msgid, msgid_plural, n) {
-
- var msgctxt;
- var category;
- return this.dcnpgettext(domain, msgctxt, msgid, msgid_plural, n, category);
-};
-
-/**
- * Like `dngettext()` but retrieves the translation from the specified
- * category, instead of the default category **LC_MESSAGES**.
- * @memberof iJS.Gettext
- * @param {String} domain Domain where translation can be found.
- * @param {String} msgid Message to translate
- * @param {String} msgid_plural Plural form of text to translate
- * @param {Number} n Counting number
- * @param {String} category (for now is will always be "LC_MESSAGES")
- * @returns {String} translated text or the *msgid* if not found
- */
-iJS.Gettext.prototype.dcngettext = function (domain, msgid, msgid_plural, n, category) {
-
- var msgctxt;
- return this.dcnpgettext(domain, msgctxt, msgid, msgid_plural, n, category, category);
-};
-
-/**
- * Returns the translation of **msgid**, given the context of **msgctxt**.<BR/>
- * Both items are used as a unique key into the message catalog.
- * This allows the translator to have two entries for words that may
- * translate to different foreign words based on their context.
- * @memberof iJS.Gettext
- * @param {String} msgctxt context of text
- * @param {String} msgid Message to translate
- * @returns {String} translated text or the *msgid* if not found
- * @example
- * // The word "View" may be a noun or a verb, which may be
- * //used in a menu as File->View or View->Source.
-
- alert( iJS.i18n.pgettext( "Verb: To View", "View" ) );
- alert( iJS.i18n.pgettext( "Noun: A View", "View" ) );
- * // The above will both lookup different entries in the message catalog.
- */
-iJS.Gettext.prototype.pgettext = function (msgctxt, msgid) {
-
- var msgid_plural;
- var n;
- var category;
- return this.dcnpgettext(null, msgctxt, msgid, msgid_plural, n, category);
-};
-
-/**
- * Like `pgettext()`, but retrieves the message for the specified
- * **domain** instead of the default domain.
- * @memberof iJS.Gettext
- * @param {String} domain Domain where translation can be found.
- * @param {String} msgctxt Context of text
- * @param {String} msgid Message to translate
- * @returns {String} translated text or the *msgid* if not found
- */
-iJS.Gettext.prototype.dpgettext = function (domain, msgctxt, msgid) {
-
- var msgid_plural;
- var n;
- var category;
- return this.dcnpgettext(domain, msgctxt, msgid, msgid_plural, n, category);
-};
-
-/**
- * Like `dpgettext()` but retrieves the message from the specified **category**
- * instead of the default category **LC_MESSAGES**.
- * @memberof iJS.Gettext
- * @param {String} domain Domain where translation can be found.
- * @param {String} msgctxt Context of text
- * @param {String} msgid Message to translate
- * @param {String} category (for now is will always be "LC_MESSAGES")
- * @returns {String} translated text or the *msgid* if not found
- */
-iJS.Gettext.prototype.dcpgettext = function (domain, msgctxt, msgid, category) {
-
- var msgid_plural;
- var n;
- return this.dcnpgettext(domain, msgctxt, msgid, msgid_plural, n, category);
-};
-
-
-/**
- * Like `ngettext()` with the addition of context as in `pgettext()`. <BR/>
- * In English, or if no translation can be found, the second argument
- * *msgid* is picked if *n* is one, the third one otherwise.
- * @memberof iJS.Gettext
- * @param {String} msgctxt Context of text
- * @param {String} msgid Message to translate
- * @param {String} msgid_plural Plural form of text to translate
- * @param {Number} n Counting number
- * @returns {String} translated text or the *msgid* if not found
- */
-iJS.Gettext.prototype.npgettext = function (msgctxt, msgid, msgid_plural, n) {
-
- var category;
- return this.dcnpgettext(null, msgctxt, msgid, msgid_plural, n, category);
-};
-
-/**
- * Like `npgettext()` but retrieves the translation from the specified
- * textdomain instead of the default domain.
- * @memberof iJS.Gettext
- * @param {String} domain Domain where translation can be found.
- * @param {String} msgctxt Context of text
- * @param {String} msgid Message to translate
- * @param {String} msgid_plural Plural form of text to translate
- * @param {Number} n Counting number
- * @returns {String} translated text or the *msgid* if not found
- */
-iJS.Gettext.prototype.dnpgettext = function (domain, msgctxt, msgid, msgid_plural, n) {
-
- var category;
- return this.dcnpgettext(domain, msgctxt, msgid, msgid_plural, n, category);
-};
-
-
-// this has all the options, so we use it for all of previous `gettext()`.
-/**
- * Like `dnpgettext()` but retrieves the translation from the specified
- * category, instead of the default category **LC_MESSAGES**.
- * @memberof iJS.Gettext
- * @param {String} domain Domain where translation can be found.
- * @param {String} msgctxt Context of text
- * @param {String} msgid Message to translate
- * @param {String} msgid_plural Plural form of text to translate
- * @param {Number} n
- * @param {String} category (for now is will always be "LC_MESSAGES")
- * @returns {String} translated text or the *msgid* if not found
- */
-iJS.Gettext.prototype.dcnpgettext = function (domain, msgctxt, msgid, msgid_plural, n, category) {
-
- if (! iJS.isSet(msgid)) return '';
-
- var plural = iJS.isSet(msgid_plural);
- var msg_ctxt_id = iJS.isSet(msgctxt) ? msgctxt+iJS.Gettext.context_glue+msgid : msgid;
-
- var domainname = iJS.isSet(domain) ? domain : iJS.isSet(this.domain) ? this.domain : 'messages';
-
- // category is always LC_MESSAGES. We ignore all else
- var category_name = 'LC_MESSAGES';
- var category = 5;
-
- var locale_data = new Array();
- if (typeof( iJS.Gettext._locale_data ) != 'undefined' &&
- iJS.isSet( iJS.Gettext._locale_data[domainname]) ) {
- locale_data.push( iJS.Gettext._locale_data[domainname] );
-
- } else if (typeof( iJS.Gettext._locale_data ) != 'undefined') {
- // didn't find domain we're looking for. Search all of them.
- for (var dom in iJS.Gettext._locale_data) {
- locale_data.push( iJS.Gettext._locale_data[dom] );
- }
- }
-
- var trans = [];
- var found = false;
- var domain_used; // so we can find plural-forms if needed
- if (locale_data.length) {
- for (var i=0; i<locale_data.length; i++) {
- var locale = locale_data[i];
- if (iJS.isSet(locale.msgs[msg_ctxt_id])) {
- // make copy of that array (cause we'll be destructive)
- for (var j=0; j<locale.msgs[msg_ctxt_id].length; j++) {
- trans[j] = locale.msgs[msg_ctxt_id][j];
- }
- trans.shift(); // throw away the msgid_plural
- domain_used = locale;
- found = true;
- // only break if found translation actually has a translation.
- if ( trans.length > 0 && trans[0].length != 0 )
- break;
- }
- }
- }
-
- // default to english if we lack a match, or match has zero length
- if ( trans.length == 0 || trans[0].length == 0 ) {
- trans = [ msgid, msgid_plural ];
- }
-
- var translation = trans[0];
- if (plural) {
- var p;
- if (found && iJS.isSet(domain_used.head.plural_func) ) {
- var rv = domain_used.head.plural_func(n);
- if (! rv.plural) rv.plural = 0;
- if (! rv.nplural) rv.nplural = 0;
- // if plurals returned is out of bound for total plural forms
- if (rv.nplural <= rv.plural) rv.plural = 0;
- p = rv.plural;
- } else {
- p = (n != 1) ? 1 : 0;
- }
- if (iJS.isSet(trans[p]))
- translation = trans[p];
- }
-
- return translation;
-};
-
-
-/**
- * This is a utility method to provide some way to support positional parameters within a string, as javascript lacks a printf() method.
- * The format is similar to printf(), but greatly simplified (ie. fewer features).<BR/>
- * Any percent signs followed by numbers are replaced with the corresponding item from the argument’s array.
- * @class
- * @constructs Strargs
- * @memberof iJS.Gettext
- * @param {String} str a string that potentially contains formatting characters
- * @param {Array} args an array of positional replacement values
- * @returns {String} The formatted text.
- * @example
- * iJS.i18n.setlocale("fr_FR.UTF8") ;
- * iJS.i18n.bindtextdomain("fr_FR.UTF8") ;
- * iJS.i18n.try_load_lang() ;
- * //One common mistake is to interpolate a variable into the string like this:
- * var translated = iJS._("Hello " + full_name); //`iJS._()` can be replace by `iJS.i18n.gettext()`
-
- * //The interpolation will happen before it's passed to gettext, and it's
- * //unlikely you'll have a translation for every "Hello Tom" and "Hello Dick"
- * //and "Hellow Harry" that may arise.
-
- * //Use `strargs()` (see below) to solve this problem:
-
- * var translated = iJS.Gettext.strargs( iJS._("Hello %1"), [full_name] );
-
- /* This is espeically useful when multiple replacements are needed, as they
- * may not appear in the same order within the translation. As an English to
- * French example:
-
- * Expected result: "This is the red ball"
- * English: "This is the %1 %2"
- * French: "C'est le %2 %1"
- * Code: iJS.Gettext.strargs( iJS._("This is the %1 %2"), ["red", "ball"] );
-
- * (The example show thing that not have to be done because neither color nor text
- * will get translated here ...).
-
- */
-iJS.Gettext.strargs = function (str, args) {
-
- // make sure args is an array
- if ( null == args || 'undefined' == typeof(args) ) {
- args = [];
- } else if (args.constructor != Array) {
- args = [args];
- }
-
- // NOTE: javascript lacks support for zero length negative look-behind
- // in regex, so we must step through w/ index.
- // The perl equiv would simply be:
- // $string =~ s/(?<!\%)\%([0-9]+)/$args[$1]/g;
- // $string =~ s/\%\%/\%/g; # restore escaped percent signs
-
- var newstr = "";
- while (true) {
- var i = str.indexOf('%');
- var match_n;
-
- // no more found. Append whatever remains
- if (i == -1) {
- newstr += str;
- break;
- }
-
- // we found it, append everything up to that
- newstr += str.substr(0, i);
-
- // check for escpaed %%
- if (str.substr(i, 2) == '%%') {
- newstr += '%';
- str = str.substr((i+2));
-
- // % followed by number
- } else if ( match_n = str.substr(i).match(/^%(\d+)/) ) {
- var arg_n = parseInt(match_n[1]);
- var length_n = match_n[1].length;
- if ( arg_n > 0 && args[arg_n -1] != null && typeof(args[arg_n -1]) != 'undefined' )
- newstr += args[arg_n -1];
- str = str.substr( (i + 1 + length_n) );
-
- // % followed by some other garbage - just remove the %
- } else {
- newstr += '%';
- str = str.substr((i+1));
- }
- }
-
- return newstr;
-}
-
-
-/**
- * instance method wrapper of strargs
- * @memberof iJS.Gettext
- * @param {String} str a string that potentially contains formatting characters
- * @param {Array} args an array of positional replacement values
- * @returns {String} The formatted text.
- */
-iJS.Gettext.prototype.strargs = function (str, args) {
-
- return iJS.Gettext.strargs(str, args);
-}
-
-/**
- * Synchronously get a response text via an ajax call to a file’s url.
- * @private
- * @memberof iJS.Gettext
- * @param {String} uri file url
- * @returns {String} a response text if succeed or *"undefined"* if not.
- */
-iJS.Gettext.prototype.sjax = function (uri) {
-
- var xmlhttp = iJS.newHTTPRequest() ;
-
- if (! xmlhttp) {
- console.error("iJS-gettext:'sjax': Your browser doesn't do Ajax. Unable to support external language files.");
-
- } else {
-
- xmlhttp.open('GET', uri, false);
- try { xmlhttp.send(null); }
- catch (e) { return; }
-
- // we consider status 200 and 0 as ok.
- // 0 happens when we request local file, allowing this to run on local files
- var sjax_status = xmlhttp.status;
- if (sjax_status == 200 || sjax_status == 0) {
- //alert(xmlhttp.responseText)
- return xmlhttp.responseText;
- } else {
- var error = xmlhttp.statusText + " (Error " + xmlhttp.status + ")";
- if (xmlhttp.responseText.length) {
- error += "\n" + xmlhttp.responseText;
- }
- console.error( error );
- return;
- }
- }
-
-}
-
-/**
- * Evaluate A string representing a JavaScript expression, statement, or sequence of statements.
- * @private
- * @param {String} data JavaScript expression
- * @returns {Object} [[Description]]
- */
-iJS.Gettext.prototype.JSON = function (data) {
- return eval('(' + data + ')');
-}
-
-},{}]},{},[1]);