mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2025-03-01 10:33:28 +00:00
Transit translation system (#309)
* update schemas * update schemas * update schemas * schema update * update translation * upd
This commit is contained in:
675
assets/webconfig/js/lib/jquery-lang.js
vendored
675
assets/webconfig/js/lib/jquery-lang.js
vendored
@@ -1,675 +0,0 @@
|
||||
/*
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Irrelon Software Limited
|
||||
http://www.irrelon.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice, url and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
Source: https://github.com/irrelon/jquery-lang-js
|
||||
|
||||
Changelog: See readme.md
|
||||
*/
|
||||
var Lang = (function () {
|
||||
"use strict";
|
||||
|
||||
var Lang = function () {
|
||||
// Enable firing events
|
||||
this._fireEvents = true;
|
||||
|
||||
// Allow storage of dynamic language pack data
|
||||
this._dynamic = {};
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialise the library with the library options.
|
||||
* @param {Object} options The options to init the library with.
|
||||
* See the readme.md for the details of the options available.
|
||||
*/
|
||||
Lang.prototype.init = function (options) {
|
||||
var self = this,
|
||||
cookieLang,
|
||||
defaultLang,
|
||||
currentLang,
|
||||
allowCookieOverride;
|
||||
|
||||
options = options || {};
|
||||
options.cookie = options.cookie || {};
|
||||
|
||||
defaultLang = options.defaultLang;
|
||||
currentLang = options.currentLang;
|
||||
allowCookieOverride = options.allowCookieOverride;
|
||||
|
||||
// Set cookie settings
|
||||
this.cookieName = options.cookie.name || 'langCookie';
|
||||
this.cookieExpiry = options.cookie.expiry || 365;
|
||||
this.cookiePath = options.cookie.path || '/';
|
||||
|
||||
// Store existing mutation methods so we can auto-run
|
||||
// translations when new data is added to the page
|
||||
this._mutationCopies = {
|
||||
append: $.fn.append,
|
||||
appendTo: $.fn.appendTo,
|
||||
prepend: $.fn.prepend,
|
||||
before: $.fn.before,
|
||||
after: $.fn.after,
|
||||
html: $.fn.html
|
||||
};
|
||||
|
||||
// Now override the existing mutation methods with our own
|
||||
$.fn.append = function () { return self._mutation(this, 'append', arguments) };
|
||||
$.fn.appendTo = function () { return self._mutation(this, 'appendTo', arguments) };
|
||||
$.fn.prepend = function () { return self._mutation(this, 'prepend', arguments) };
|
||||
$.fn.before = function () { return self._mutation(this, 'before', arguments) };
|
||||
$.fn.after = function () { return self._mutation(this, 'after', arguments) };
|
||||
$.fn.html = function () { return self._mutation(this, 'html', arguments) };
|
||||
|
||||
// Set default and current language to the default one
|
||||
// to start with
|
||||
this.defaultLang = defaultLang || 'en';
|
||||
this.currentLang = defaultLang || 'en';
|
||||
|
||||
// Check for cookie support when no current language is specified
|
||||
if ((allowCookieOverride || !currentLang) && typeof Cookies !== 'undefined') {
|
||||
// Check for an existing language cookie
|
||||
cookieLang = Cookies.get(this.cookieName);
|
||||
|
||||
if (cookieLang) {
|
||||
// We have a cookie language, set the current language
|
||||
currentLang = cookieLang;
|
||||
}
|
||||
}
|
||||
|
||||
$(function () {
|
||||
// Setup data on the language items
|
||||
self._start();
|
||||
|
||||
// Check if the current language is not the same as our default
|
||||
if (currentLang && currentLang !== self.defaultLang) {
|
||||
// Switch to the current language
|
||||
self.change(currentLang);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Object that holds the language packs.
|
||||
* @type {{}}
|
||||
*/
|
||||
Lang.prototype.pack = {};
|
||||
|
||||
/**
|
||||
* Array of translatable attributes to check for on elements.
|
||||
* @type {string[]}
|
||||
*/
|
||||
Lang.prototype.attrList = [
|
||||
'title',
|
||||
'alt',
|
||||
'placeholder',
|
||||
'href'
|
||||
];
|
||||
|
||||
/**
|
||||
* Defines a language pack that can be dynamically loaded and the
|
||||
* path to use when doing so.
|
||||
* @param {String} lang The language two-letter iso-code.
|
||||
* @param {String} path The path to the language pack js file.
|
||||
*/
|
||||
Lang.prototype.dynamic = function (lang, path) {
|
||||
if (lang !== undefined && path !== undefined) {
|
||||
this._dynamic[lang] = path;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Loads a new language pack for the given language.
|
||||
* @param {string} lang The language to load the pack for.
|
||||
* @param {Function=} callback Optional callback when the file has loaded.
|
||||
*/
|
||||
Lang.prototype.loadPack = function (lang, callback) {
|
||||
var self = this;
|
||||
|
||||
if (lang && self._dynamic[lang]) {
|
||||
$.ajax({
|
||||
dataType: "json",
|
||||
url: self._dynamic[lang],
|
||||
success: function (data) {
|
||||
self.pack[lang] = data;
|
||||
|
||||
// Process the regex list
|
||||
if (self.pack[lang].regex) {
|
||||
var packRegex = self.pack[lang].regex,
|
||||
regex,
|
||||
i;
|
||||
|
||||
for (i = 0; i < packRegex.length; i++) {
|
||||
regex = packRegex[i];
|
||||
if (regex.length === 2) {
|
||||
// String, value
|
||||
regex[0] = new RegExp(regex[0]);
|
||||
} else if (regex.length === 3) {
|
||||
// String, modifiers, value
|
||||
regex[0] = new RegExp(regex[0], regex[1]);
|
||||
|
||||
// Remove modifier
|
||||
regex.splice(1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//console.log('Loaded language pack: ' + self._dynamic[lang]);
|
||||
if (callback) { callback(false, lang, self._dynamic[lang]); }
|
||||
},
|
||||
error: function () {
|
||||
if (callback) { callback(true, lang, self._dynamic[lang]); }
|
||||
throw('Error loading language pack' + self._dynamic[lang]);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
throw('Cannot load language pack, no file path specified!');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Scans the DOM for elements with [lang] selector and saves translate data
|
||||
* for them for later use.
|
||||
* @private
|
||||
*/
|
||||
Lang.prototype._start = function (selector) {
|
||||
// Get the page HTML
|
||||
var arr = selector !== undefined ? $(selector).find('[lang]') : $(':not(html)[lang]'),
|
||||
arrCount = arr.length,
|
||||
elem;
|
||||
|
||||
while (arrCount--) {
|
||||
elem = $(arr[arrCount]);
|
||||
this._processElement(elem);
|
||||
}
|
||||
};
|
||||
|
||||
Lang.prototype._processElement = function (elem) {
|
||||
// Only store data if the element is set to our default language
|
||||
if (elem.attr('lang') === this.defaultLang) {
|
||||
// Store translatable attributes
|
||||
this._storeAttribs(elem);
|
||||
|
||||
// Store translatable content
|
||||
this._storeContent(elem);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Stores the translatable attribute values in their default language.
|
||||
* @param {object} elem The jQuery selected element.
|
||||
* @private
|
||||
*/
|
||||
Lang.prototype._storeAttribs = function (elem) {
|
||||
var attrIndex,
|
||||
attr,
|
||||
attrObj;
|
||||
|
||||
for (attrIndex = 0; attrIndex < this.attrList.length; attrIndex++) {
|
||||
attr = this.attrList[attrIndex];
|
||||
if (elem.attr(attr)) {
|
||||
// Grab the existing attribute store or create a new object
|
||||
attrObj = elem.data('lang-attr') || {};
|
||||
|
||||
// Add the attribute and value to the store
|
||||
attrObj[attr] = elem.attr(attr);
|
||||
|
||||
// Save the attribute data to the store
|
||||
elem.data('lang-attr', attrObj);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Reads the existing content from the element and stores it for
|
||||
* later use in translation.
|
||||
* @param elem
|
||||
* @private
|
||||
*/
|
||||
Lang.prototype._storeContent = function (elem) {
|
||||
// Check if the element is an input element
|
||||
if (elem.is('input')) {
|
||||
switch (elem.attr('type')) {
|
||||
case 'button':
|
||||
case 'submit':
|
||||
case 'hidden':
|
||||
case 'reset':
|
||||
elem.data('lang-val', elem.val());
|
||||
break;
|
||||
}
|
||||
} else if (elem.is('img')) {
|
||||
elem.data('lang-src', elem.attr('src'));
|
||||
} else {
|
||||
// Get the text nodes immediately inside this element
|
||||
var nodes = this._getTextNodes(elem);
|
||||
if (nodes) {
|
||||
elem.data('lang-text', nodes);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves the text nodes from an element and returns them in array wrap into
|
||||
* object with two properties:
|
||||
* - node - which corresponds to text node,
|
||||
* - langDefaultText - which remember current data of text node
|
||||
* @param elem
|
||||
* @returns {Array|*}
|
||||
* @private
|
||||
*/
|
||||
Lang.prototype._getTextNodes = function (elem) {
|
||||
var nodes = elem.contents(), nodeObjArray = [], nodeObj = {},
|
||||
nodeArr, that = this, map = Array.prototype.map;
|
||||
|
||||
$.each(nodes, function (index, node) {
|
||||
if ( node.nodeType !== 3 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
nodeObj = {
|
||||
node : node,
|
||||
langDefaultText : node.data
|
||||
};
|
||||
|
||||
nodeObjArray.push(nodeObj);
|
||||
});
|
||||
|
||||
// If element has only one text node and data-lang-token is defined
|
||||
// set langContentKey property to use as a token
|
||||
if(nodes.length == 1){
|
||||
nodeObjArray[0].langToken = elem.data('langToken');
|
||||
}
|
||||
|
||||
return nodeObjArray;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets text nodes of an element translated based on the passed language.
|
||||
* @param elem
|
||||
* @param {Array|*} nodes array of objecs with text node and defaultText returned from _getTextNodes
|
||||
* @param lang
|
||||
* @private
|
||||
*/
|
||||
Lang.prototype._setTextNodes = function (elem, nodes, lang) {
|
||||
var index,
|
||||
textNode,
|
||||
defaultText,
|
||||
translation,
|
||||
langNotDefault = lang !== this.defaultLang;
|
||||
|
||||
for (index = 0; index < nodes.length; index++) {
|
||||
textNode = nodes[index];
|
||||
|
||||
if (langNotDefault) {
|
||||
// If langToken is set, use it as a token
|
||||
defaultText = textNode.langToken || $.trim(textNode.langDefaultText);
|
||||
|
||||
if (defaultText) {
|
||||
// Translate the langDefaultText
|
||||
translation = this.translate(defaultText, lang);
|
||||
|
||||
if (translation) {
|
||||
try {
|
||||
// Replace the text with the translated version
|
||||
textNode.node.data = textNode.node.data.split($.trim(textNode.node.data)).join(translation);
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
} else {
|
||||
if (console && console.log) {
|
||||
console.log('Translation for "' + defaultText + '" not found!');
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Replace with original text
|
||||
try {
|
||||
textNode.node.data = textNode.langDefaultText;
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Translates and sets the attributes of an element to the passed language.
|
||||
* @param elem
|
||||
* @param lang
|
||||
* @private
|
||||
*/
|
||||
Lang.prototype._translateAttribs = function (elem, lang) {
|
||||
var attr,
|
||||
attrObj = elem.data('lang-attr') || {},
|
||||
translation;
|
||||
|
||||
for (attr in attrObj) {
|
||||
if (attrObj.hasOwnProperty(attr)) {
|
||||
// Check the element still has the attribute
|
||||
if (elem.attr(attr)) {
|
||||
if (lang !== this.defaultLang) {
|
||||
// Get the translated value
|
||||
translation = this.translate(attrObj[attr], lang);
|
||||
|
||||
// Check we actually HAVE a translation
|
||||
if (translation) {
|
||||
// Change the attribute to the translated value
|
||||
elem.attr(attr, translation);
|
||||
}
|
||||
} else {
|
||||
// Set default language value
|
||||
elem.attr(attr, attrObj[attr]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Translates and sets the contents of an element to the passed language.
|
||||
* @param elem
|
||||
* @param lang
|
||||
* @private
|
||||
*/
|
||||
Lang.prototype._translateContent = function (elem, lang) {
|
||||
var langNotDefault = lang !== this.defaultLang,
|
||||
translation,
|
||||
nodes;
|
||||
|
||||
// Check if the element is an input element
|
||||
if (elem.is('input')) {
|
||||
switch (elem.attr('type')) {
|
||||
case 'button':
|
||||
case 'submit':
|
||||
case 'hidden':
|
||||
case 'reset':
|
||||
if (langNotDefault) {
|
||||
// Get the translated value
|
||||
translation = this.translate(elem.data('lang-val'), lang);
|
||||
|
||||
// Check we actually HAVE a translation
|
||||
if (translation) {
|
||||
// Set translated value
|
||||
elem.val(translation);
|
||||
}
|
||||
} else {
|
||||
// Set default language value
|
||||
elem.val(elem.data('lang-val'));
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else if (elem.is('img')) {
|
||||
if (langNotDefault) {
|
||||
// Get the translated value
|
||||
translation = this.translate(elem.data('lang-src'), lang);
|
||||
|
||||
// Check we actually HAVE a translation
|
||||
if (translation) {
|
||||
// Set translated value
|
||||
elem.attr('src', translation);
|
||||
}
|
||||
} else {
|
||||
// Set default language value
|
||||
elem.attr('src', elem.data('lang-src'));
|
||||
}
|
||||
} else {
|
||||
// Set text node translated text
|
||||
nodes = elem.data('lang-text');
|
||||
if (nodes) {
|
||||
this._setTextNodes(elem, nodes, lang);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Call this to change the current language on the page.
|
||||
* @param {String} lang The new two-letter language code to change to.
|
||||
* @param {String=} selector Optional selector to find language-based
|
||||
* elements for updating.
|
||||
* @param {Function=} callback Optional callback function that will be
|
||||
* called once the language change has been successfully processed. This
|
||||
* is especially useful if you are using dynamic language pack loading
|
||||
* since you will get a callback once it has been loaded and changed.
|
||||
* Your callback will be passed three arguments, a boolean to denote if
|
||||
* there was an error (true if error), the second will be the language
|
||||
* you passed in the change call (the lang argument) and the third will
|
||||
* be the selector used in the change update.
|
||||
*/
|
||||
Lang.prototype.change = function (lang, selector, callback) {
|
||||
var self = this;
|
||||
|
||||
if (lang === this.defaultLang || this.pack[lang] || this._dynamic[lang]) {
|
||||
// Check if the language pack is currently loaded
|
||||
if (lang !== this.defaultLang) {
|
||||
if (!this.pack[lang] && this._dynamic[lang]) {
|
||||
// The language pack needs loading first
|
||||
//console.log('Loading dynamic language pack: ' + this._dynamic[lang] + '...');
|
||||
this.loadPack(lang, function (err, loadingLang, fromUrl) {
|
||||
if (!err) {
|
||||
// Process the change language request
|
||||
self.change.call(self, lang, selector, callback);
|
||||
} else {
|
||||
// Call the callback with the error
|
||||
if (callback) { callback('Language pack could not load from: ' + fromUrl, lang, selector); }
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
} else if (!this.pack[lang] && !this._dynamic[lang]) {
|
||||
// Pack not loaded and no dynamic entry
|
||||
if (callback) { callback('Language pack not defined for: ' + lang, lang, selector); }
|
||||
throw('Could not change language to ' + lang + ' because no language pack for this language exists!');
|
||||
}
|
||||
}
|
||||
|
||||
var fireAfterUpdate = false,
|
||||
currLang = this.currentLang;
|
||||
|
||||
if (this.currentLang != lang) {
|
||||
this.beforeUpdate(currLang, lang);
|
||||
fireAfterUpdate = true;
|
||||
}
|
||||
|
||||
this.currentLang = lang;
|
||||
|
||||
// Get the page HTML
|
||||
var arr = selector !== undefined ? $(selector).find('[lang]') : $(':not(html)[lang]'),
|
||||
arrCount = arr.length,
|
||||
elem;
|
||||
|
||||
while (arrCount--) {
|
||||
elem = $(arr[arrCount]);
|
||||
|
||||
if (elem.attr('lang') !== lang) {
|
||||
this._translateElement(elem, lang);
|
||||
}
|
||||
}
|
||||
|
||||
if (fireAfterUpdate) {
|
||||
this.afterUpdate(currLang, lang);
|
||||
}
|
||||
|
||||
// Check for cookie support
|
||||
if (typeof Cookies !== "undefined") {
|
||||
// Set a cookie to remember this language setting with 1 year expiry
|
||||
Cookies.set(self.cookieName, lang, {
|
||||
expires: self.cookieExpiry,
|
||||
path: self.cookiePath
|
||||
});
|
||||
}
|
||||
|
||||
if (callback) { callback(false, lang, selector); }
|
||||
} else {
|
||||
if (callback) { callback('No language pack defined for: ' + lang, lang, selector); }
|
||||
throw('Attempt to change language to "' + lang + '" but no language pack for that language is loaded!');
|
||||
}
|
||||
};
|
||||
|
||||
Lang.prototype._translateElement = function (elem, lang) {
|
||||
// Translate attributes
|
||||
this._translateAttribs(elem, lang);
|
||||
|
||||
// Translate content
|
||||
if (elem.attr('data-lang-content') != 'false') {
|
||||
this._translateContent(elem, lang);
|
||||
}
|
||||
|
||||
// Update the element's current language
|
||||
elem.attr('lang', lang);
|
||||
};
|
||||
|
||||
/**
|
||||
* Translates text from the default language into the passed language.
|
||||
* @param {String} text The text to translate.
|
||||
* @param {String} lang The two-letter language code to translate to.
|
||||
* @returns {*}
|
||||
*/
|
||||
Lang.prototype.translate = function (text, lang) {
|
||||
lang = lang || this.currentLang;
|
||||
|
||||
if (this.pack[lang]) {
|
||||
var translation = '';
|
||||
|
||||
if (lang != this.defaultLang) {
|
||||
// Check for a direct token translation
|
||||
translation = this.pack[lang].token[text];
|
||||
|
||||
if (!translation) {
|
||||
// No token translation was found, test for regex match
|
||||
translation = this._regexMatch(text, lang);
|
||||
}
|
||||
|
||||
if (!translation) {
|
||||
if (console && console.log) {
|
||||
console.log('Translation for "' + text + '" not found in language pack: ' + lang);
|
||||
}
|
||||
}
|
||||
|
||||
return translation || text;
|
||||
} else {
|
||||
return text;
|
||||
}
|
||||
} else {
|
||||
return text;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks the regex items for a match against the passed text and
|
||||
* if a match is made, translates to the given replacement.
|
||||
* @param {String} text The text to test regex matches against.
|
||||
* @param {String} lang The two-letter language code to translate to.
|
||||
* @returns {string}
|
||||
* @private
|
||||
*/
|
||||
Lang.prototype._regexMatch = function (text, lang) {
|
||||
// Loop the regex array and test them against the text
|
||||
var arr,
|
||||
arrCount,
|
||||
arrIndex,
|
||||
item,
|
||||
regex,
|
||||
expressionResult;
|
||||
|
||||
arr = this.pack[lang].regex;
|
||||
|
||||
if (arr) {
|
||||
arrCount = arr.length;
|
||||
|
||||
for (arrIndex = 0; arrIndex < arrCount; arrIndex++) {
|
||||
item = arr[arrIndex];
|
||||
regex = item[0];
|
||||
|
||||
// Test regex
|
||||
expressionResult = regex.exec(text);
|
||||
|
||||
if (expressionResult && expressionResult[0]) {
|
||||
return text.split(expressionResult[0]).join(item[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
};
|
||||
|
||||
Lang.prototype.beforeUpdate = function (currentLang, newLang) {
|
||||
if (this._fireEvents) {
|
||||
$(this).triggerHandler('beforeUpdate', [currentLang, newLang, this.pack[currentLang], this.pack[newLang]]);
|
||||
}
|
||||
};
|
||||
|
||||
Lang.prototype.afterUpdate = function (currentLang, newLang) {
|
||||
if (this._fireEvents) {
|
||||
$(this).triggerHandler('afterUpdate', [currentLang, newLang, this.pack[currentLang], this.pack[newLang]]);
|
||||
}
|
||||
};
|
||||
|
||||
Lang.prototype.refresh = function () {
|
||||
// Process refresh on the page
|
||||
this._fireEvents = false;
|
||||
this.change(this.currentLang);
|
||||
this._fireEvents = true;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
// Mutation overrides
|
||||
////////////////////////////////////////////////////
|
||||
Lang.prototype._mutation = function (context, method, args) {
|
||||
var result = this._mutationCopies[method].apply(context, args),
|
||||
currLang = this.currentLang,
|
||||
rootElem = $(context);
|
||||
|
||||
if (rootElem.attr('lang')) {
|
||||
// Switch off events for the moment
|
||||
this._fireEvents = false;
|
||||
|
||||
// Check if the root element is currently set to another language from current
|
||||
//if (rootElem.attr('lang') !== this.currentLang) {
|
||||
this._translateElement(rootElem, this.defaultLang);
|
||||
this.change(this.defaultLang, rootElem);
|
||||
|
||||
// Calling change above sets the global currentLang but this is supposed to be
|
||||
// an isolated change so reset the global value back to what it was before
|
||||
this.currentLang = currLang;
|
||||
|
||||
// Record data on the default language from the root element
|
||||
this._processElement(rootElem);
|
||||
|
||||
// Translate the root element
|
||||
this._translateElement(rootElem, this.currentLang);
|
||||
//}
|
||||
}
|
||||
|
||||
// Record data on the default language from the root's children
|
||||
this._start(rootElem);
|
||||
|
||||
// Process translation on any child elements of this element
|
||||
this.change(this.currentLang, rootElem);
|
||||
|
||||
// Switch events back on
|
||||
this._fireEvents = true;
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
return Lang;
|
||||
})();
|
168
assets/webconfig/js/lib/jquery.i18n.emitter.js
Normal file
168
assets/webconfig/js/lib/jquery.i18n.emitter.js
Normal file
@@ -0,0 +1,168 @@
|
||||
/**
|
||||
* jQuery Internationalization library
|
||||
*
|
||||
* Copyright (C) 2011-2013 Santhosh Thottingal, Neil Kandalgaonkar
|
||||
*
|
||||
* jquery.i18n is dual licensed GPLv2 or later and MIT. You don't have to do
|
||||
* anything special to choose one license or the other and you don't have to
|
||||
* notify anyone which license you are using. You are free to use
|
||||
* UniversalLanguageSelector in commercial projects as long as the copyright
|
||||
* header is left intact. See files GPL-LICENSE and MIT-LICENSE for details.
|
||||
*
|
||||
* @licence GNU General Public Licence 2.0 or later
|
||||
* @licence MIT License
|
||||
*/
|
||||
|
||||
( function ( $ ) {
|
||||
'use strict';
|
||||
|
||||
var MessageParserEmitter = function () {
|
||||
this.language = $.i18n.languages[String.locale] || $.i18n.languages['default'];
|
||||
};
|
||||
|
||||
MessageParserEmitter.prototype = {
|
||||
constructor: MessageParserEmitter,
|
||||
|
||||
/**
|
||||
* (We put this method definition here, and not in prototype, to make
|
||||
* sure it's not overwritten by any magic.) Walk entire node structure,
|
||||
* applying replacements and template functions when appropriate
|
||||
*
|
||||
* @param {Mixed} node abstract syntax tree (top node or subnode)
|
||||
* @param {Array} replacements for $1, $2, ... $n
|
||||
* @return {Mixed} single-string node or array of nodes suitable for
|
||||
* jQuery appending.
|
||||
*/
|
||||
emit: function ( node, replacements ) {
|
||||
var ret, subnodes, operation,
|
||||
messageParserEmitter = this;
|
||||
|
||||
switch ( typeof node ) {
|
||||
case 'string':
|
||||
case 'number':
|
||||
ret = node;
|
||||
break;
|
||||
case 'object':
|
||||
// node is an array of nodes
|
||||
subnodes = $.map( node.slice( 1 ), function ( n ) {
|
||||
return messageParserEmitter.emit( n, replacements );
|
||||
} );
|
||||
|
||||
operation = node[0].toLowerCase();
|
||||
|
||||
if ( typeof messageParserEmitter[operation] === 'function' ) {
|
||||
ret = messageParserEmitter[operation]( subnodes, replacements );
|
||||
} else {
|
||||
throw new Error( 'unknown operation "' + operation + '"' );
|
||||
}
|
||||
|
||||
break;
|
||||
case 'undefined':
|
||||
// Parsing the empty string (as an entire expression, or as a
|
||||
// paramExpression in a template) results in undefined
|
||||
// Perhaps a more clever parser can detect this, and return the
|
||||
// empty string? Or is that useful information?
|
||||
// The logical thing is probably to return the empty string here
|
||||
// when we encounter undefined.
|
||||
ret = '';
|
||||
break;
|
||||
default:
|
||||
throw new Error( 'unexpected type in AST: ' + typeof node );
|
||||
}
|
||||
|
||||
return ret;
|
||||
},
|
||||
|
||||
/**
|
||||
* Parsing has been applied depth-first we can assume that all nodes
|
||||
* here are single nodes Must return a single node to parents -- a
|
||||
* jQuery with synthetic span However, unwrap any other synthetic spans
|
||||
* in our children and pass them upwards
|
||||
*
|
||||
* @param {Array} nodes Mixed, some single nodes, some arrays of nodes.
|
||||
* @return String
|
||||
*/
|
||||
concat: function ( nodes ) {
|
||||
var result = '';
|
||||
|
||||
$.each( nodes, function ( i, node ) {
|
||||
// strings, integers, anything else
|
||||
result += node;
|
||||
} );
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
* Return escaped replacement of correct index, or string if
|
||||
* unavailable. Note that we expect the parsed parameter to be
|
||||
* zero-based. i.e. $1 should have become [ 0 ]. if the specified
|
||||
* parameter is not found return the same string (e.g. "$99" ->
|
||||
* parameter 98 -> not found -> return "$99" ) TODO throw error if
|
||||
* nodes.length > 1 ?
|
||||
*
|
||||
* @param {Array} nodes One element, integer, n >= 0
|
||||
* @param {Array} replacements for $1, $2, ... $n
|
||||
* @return {string} replacement
|
||||
*/
|
||||
replace: function ( nodes, replacements ) {
|
||||
var index = parseInt( nodes[0], 10 );
|
||||
|
||||
if ( index < replacements.length ) {
|
||||
// replacement is not a string, don't touch!
|
||||
return replacements[index];
|
||||
} else {
|
||||
// index not found, fallback to displaying variable
|
||||
return '$' + ( index + 1 );
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Transform parsed structure into pluralization n.b. The first node may
|
||||
* be a non-integer (for instance, a string representing an Arabic
|
||||
* number). So convert it back with the current language's
|
||||
* convertNumber.
|
||||
*
|
||||
* @param {Array} nodes List [ {String|Number}, {String}, {String} ... ]
|
||||
* @return {String} selected pluralized form according to current
|
||||
* language.
|
||||
*/
|
||||
plural: function ( nodes ) {
|
||||
var count = parseFloat( this.language.convertNumber( nodes[0], 10 ) ),
|
||||
forms = nodes.slice( 1 );
|
||||
|
||||
return forms.length ? this.language.convertPlural( count, forms ) : '';
|
||||
},
|
||||
|
||||
/**
|
||||
* Transform parsed structure into gender Usage
|
||||
* {{gender:gender|masculine|feminine|neutral}}.
|
||||
*
|
||||
* @param {Array} nodes List [ {String}, {String}, {String} , {String} ]
|
||||
* @return {String} selected gender form according to current language
|
||||
*/
|
||||
gender: function ( nodes ) {
|
||||
var gender = nodes[0],
|
||||
forms = nodes.slice( 1 );
|
||||
|
||||
return this.language.gender( gender, forms );
|
||||
},
|
||||
|
||||
/**
|
||||
* Transform parsed structure into grammar conversion. Invoked by
|
||||
* putting {{grammar:form|word}} in a message
|
||||
*
|
||||
* @param {Array} nodes List [{Grammar case eg: genitive}, {String word}]
|
||||
* @return {String} selected grammatical form according to current
|
||||
* language.
|
||||
*/
|
||||
grammar: function ( nodes ) {
|
||||
var form = nodes[0],
|
||||
word = nodes[1];
|
||||
|
||||
return word && form && this.language.convertGrammar( word, form );
|
||||
}
|
||||
};
|
||||
|
||||
$.extend( $.i18n.parser.emitter, new MessageParserEmitter() );
|
||||
}( jQuery ) );
|
186
assets/webconfig/js/lib/jquery.i18n.fallbacks.js
Normal file
186
assets/webconfig/js/lib/jquery.i18n.fallbacks.js
Normal file
@@ -0,0 +1,186 @@
|
||||
/**
|
||||
* jQuery Internationalization library
|
||||
*
|
||||
* Copyright (C) 2012 Santhosh Thottingal
|
||||
*
|
||||
* jquery.i18n is dual licensed GPLv2 or later and MIT. You don't have to do anything special to
|
||||
* choose one license or the other and you don't have to notify anyone which license you are using.
|
||||
* You are free to use UniversalLanguageSelector in commercial projects as long as the copyright
|
||||
* header is left intact. See files GPL-LICENSE and MIT-LICENSE for details.
|
||||
*
|
||||
* @licence GNU General Public Licence 2.0 or later
|
||||
* @licence MIT License
|
||||
*/
|
||||
( function ( $, undefined ) {
|
||||
'use strict';
|
||||
|
||||
$.i18n = $.i18n || {};
|
||||
$.extend( $.i18n.fallbacks, {
|
||||
ab: [ 'ru' ],
|
||||
ace: [ 'id' ],
|
||||
aln: [ 'sq' ],
|
||||
// Not so standard - als is supposed to be Tosk Albanian,
|
||||
// but in Wikipedia it's used for a Germanic language.
|
||||
als: [ 'gsw', 'de' ],
|
||||
an: [ 'es' ],
|
||||
anp: [ 'hi' ],
|
||||
arn: [ 'es' ],
|
||||
arz: [ 'ar' ],
|
||||
av: [ 'ru' ],
|
||||
ay: [ 'es' ],
|
||||
ba: [ 'ru' ],
|
||||
bar: [ 'de' ],
|
||||
'bat-smg': [ 'sgs', 'lt' ],
|
||||
bcc: [ 'fa' ],
|
||||
'be-x-old': [ 'be-tarask' ],
|
||||
bh: [ 'bho' ],
|
||||
bjn: [ 'id' ],
|
||||
bm: [ 'fr' ],
|
||||
bpy: [ 'bn' ],
|
||||
bqi: [ 'fa' ],
|
||||
bug: [ 'id' ],
|
||||
'cbk-zam': [ 'es' ],
|
||||
ce: [ 'ru' ],
|
||||
crh: [ 'crh-latn' ],
|
||||
'crh-cyrl': [ 'ru' ],
|
||||
csb: [ 'pl' ],
|
||||
cv: [ 'ru' ],
|
||||
'de-at': [ 'de' ],
|
||||
'de-ch': [ 'de' ],
|
||||
'de-formal': [ 'de' ],
|
||||
dsb: [ 'de' ],
|
||||
dtp: [ 'ms' ],
|
||||
egl: [ 'it' ],
|
||||
eml: [ 'it' ],
|
||||
ff: [ 'fr' ],
|
||||
fit: [ 'fi' ],
|
||||
'fiu-vro': [ 'vro', 'et' ],
|
||||
frc: [ 'fr' ],
|
||||
frp: [ 'fr' ],
|
||||
frr: [ 'de' ],
|
||||
fur: [ 'it' ],
|
||||
gag: [ 'tr' ],
|
||||
gan: [ 'gan-hant', 'zh-hant', 'zh-hans' ],
|
||||
'gan-hans': [ 'zh-hans' ],
|
||||
'gan-hant': [ 'zh-hant', 'zh-hans' ],
|
||||
gl: [ 'pt' ],
|
||||
glk: [ 'fa' ],
|
||||
gn: [ 'es' ],
|
||||
gsw: [ 'de' ],
|
||||
hif: [ 'hif-latn' ],
|
||||
hsb: [ 'de' ],
|
||||
ht: [ 'fr' ],
|
||||
ii: [ 'zh-cn', 'zh-hans' ],
|
||||
inh: [ 'ru' ],
|
||||
iu: [ 'ike-cans' ],
|
||||
jut: [ 'da' ],
|
||||
jv: [ 'id' ],
|
||||
kaa: [ 'kk-latn', 'kk-cyrl' ],
|
||||
kbd: [ 'kbd-cyrl' ],
|
||||
khw: [ 'ur' ],
|
||||
kiu: [ 'tr' ],
|
||||
kk: [ 'kk-cyrl' ],
|
||||
'kk-arab': [ 'kk-cyrl' ],
|
||||
'kk-latn': [ 'kk-cyrl' ],
|
||||
'kk-cn': [ 'kk-arab', 'kk-cyrl' ],
|
||||
'kk-kz': [ 'kk-cyrl' ],
|
||||
'kk-tr': [ 'kk-latn', 'kk-cyrl' ],
|
||||
kl: [ 'da' ],
|
||||
'ko-kp': [ 'ko' ],
|
||||
koi: [ 'ru' ],
|
||||
krc: [ 'ru' ],
|
||||
ks: [ 'ks-arab' ],
|
||||
ksh: [ 'de' ],
|
||||
ku: [ 'ku-latn' ],
|
||||
'ku-arab': [ 'ckb' ],
|
||||
kv: [ 'ru' ],
|
||||
lad: [ 'es' ],
|
||||
lb: [ 'de' ],
|
||||
lbe: [ 'ru' ],
|
||||
lez: [ 'ru' ],
|
||||
li: [ 'nl' ],
|
||||
lij: [ 'it' ],
|
||||
liv: [ 'et' ],
|
||||
lmo: [ 'it' ],
|
||||
ln: [ 'fr' ],
|
||||
ltg: [ 'lv' ],
|
||||
lzz: [ 'tr' ],
|
||||
mai: [ 'hi' ],
|
||||
'map-bms': [ 'jv', 'id' ],
|
||||
mg: [ 'fr' ],
|
||||
mhr: [ 'ru' ],
|
||||
min: [ 'id' ],
|
||||
mo: [ 'ro' ],
|
||||
mrj: [ 'ru' ],
|
||||
mwl: [ 'pt' ],
|
||||
myv: [ 'ru' ],
|
||||
mzn: [ 'fa' ],
|
||||
nah: [ 'es' ],
|
||||
nap: [ 'it' ],
|
||||
nds: [ 'de' ],
|
||||
'nds-nl': [ 'nl' ],
|
||||
'nl-informal': [ 'nl' ],
|
||||
no: [ 'nb' ],
|
||||
os: [ 'ru' ],
|
||||
pcd: [ 'fr' ],
|
||||
pdc: [ 'de' ],
|
||||
pdt: [ 'de' ],
|
||||
pfl: [ 'de' ],
|
||||
pms: [ 'it' ],
|
||||
pt: [ 'pt-br' ],
|
||||
'pt-br': [ 'pt' ],
|
||||
qu: [ 'es' ],
|
||||
qug: [ 'qu', 'es' ],
|
||||
rgn: [ 'it' ],
|
||||
rmy: [ 'ro' ],
|
||||
'roa-rup': [ 'rup' ],
|
||||
rue: [ 'uk', 'ru' ],
|
||||
ruq: [ 'ruq-latn', 'ro' ],
|
||||
'ruq-cyrl': [ 'mk' ],
|
||||
'ruq-latn': [ 'ro' ],
|
||||
sa: [ 'hi' ],
|
||||
sah: [ 'ru' ],
|
||||
scn: [ 'it' ],
|
||||
sg: [ 'fr' ],
|
||||
sgs: [ 'lt' ],
|
||||
sli: [ 'de' ],
|
||||
sr: [ 'sr-ec' ],
|
||||
srn: [ 'nl' ],
|
||||
stq: [ 'de' ],
|
||||
su: [ 'id' ],
|
||||
szl: [ 'pl' ],
|
||||
tcy: [ 'kn' ],
|
||||
tg: [ 'tg-cyrl' ],
|
||||
tt: [ 'tt-cyrl', 'ru' ],
|
||||
'tt-cyrl': [ 'ru' ],
|
||||
ty: [ 'fr' ],
|
||||
udm: [ 'ru' ],
|
||||
ug: [ 'ug-arab' ],
|
||||
uk: [ 'ru' ],
|
||||
vec: [ 'it' ],
|
||||
vep: [ 'et' ],
|
||||
vls: [ 'nl' ],
|
||||
vmf: [ 'de' ],
|
||||
vot: [ 'fi' ],
|
||||
vro: [ 'et' ],
|
||||
wa: [ 'fr' ],
|
||||
wo: [ 'fr' ],
|
||||
wuu: [ 'zh-hans' ],
|
||||
xal: [ 'ru' ],
|
||||
xmf: [ 'ka' ],
|
||||
yi: [ 'he' ],
|
||||
za: [ 'zh-hans' ],
|
||||
zea: [ 'nl' ],
|
||||
zh: [ 'zh-hans' ],
|
||||
'zh-classical': [ 'lzh' ],
|
||||
'zh-cn': [ 'zh-hans' ],
|
||||
'zh-hant': [ 'zh-hans' ],
|
||||
'zh-hk': [ 'zh-hant', 'zh-hans' ],
|
||||
'zh-min-nan': [ 'nan' ],
|
||||
'zh-mo': [ 'zh-hk', 'zh-hant', 'zh-hans' ],
|
||||
'zh-my': [ 'zh-sg', 'zh-hans' ],
|
||||
'zh-sg': [ 'zh-hans' ],
|
||||
'zh-tw': [ 'zh-hant', 'zh-hans' ],
|
||||
'zh-yue': [ 'yue' ]
|
||||
} );
|
||||
}( jQuery ) );
|
287
assets/webconfig/js/lib/jquery.i18n.js
Normal file
287
assets/webconfig/js/lib/jquery.i18n.js
Normal file
@@ -0,0 +1,287 @@
|
||||
/**
|
||||
* jQuery Internationalization library
|
||||
*
|
||||
* Copyright (C) 2012 Santhosh Thottingal
|
||||
*
|
||||
* jquery.i18n is dual licensed GPLv2 or later and MIT. You don't have to do
|
||||
* anything special to choose one license or the other and you don't have to
|
||||
* notify anyone which license you are using. You are free to use
|
||||
* UniversalLanguageSelector in commercial projects as long as the copyright
|
||||
* header is left intact. See files GPL-LICENSE and MIT-LICENSE for details.
|
||||
*
|
||||
* @licence GNU General Public Licence 2.0 or later
|
||||
* @licence MIT License
|
||||
*/
|
||||
|
||||
( function ( $ ) {
|
||||
'use strict';
|
||||
|
||||
var nav, I18N,
|
||||
slice = Array.prototype.slice;
|
||||
/**
|
||||
* @constructor
|
||||
* @param {Object} options
|
||||
*/
|
||||
I18N = function ( options ) {
|
||||
// Load defaults
|
||||
this.options = $.extend( {}, I18N.defaults, options );
|
||||
|
||||
this.parser = this.options.parser;
|
||||
this.locale = this.options.locale;
|
||||
this.messageStore = this.options.messageStore;
|
||||
this.languages = {};
|
||||
|
||||
this.init();
|
||||
};
|
||||
|
||||
I18N.prototype = {
|
||||
/**
|
||||
* Initialize by loading locales and setting up
|
||||
* String.prototype.toLocaleString and String.locale.
|
||||
*/
|
||||
init: function () {
|
||||
var i18n = this;
|
||||
|
||||
// Set locale of String environment
|
||||
String.locale = i18n.locale;
|
||||
|
||||
// Override String.localeString method
|
||||
String.prototype.toLocaleString = function () {
|
||||
var localeParts, localePartIndex, value, locale, fallbackIndex,
|
||||
tryingLocale, message;
|
||||
|
||||
value = this.valueOf();
|
||||
locale = i18n.locale;
|
||||
fallbackIndex = 0;
|
||||
|
||||
while ( locale ) {
|
||||
// Iterate through locales starting at most-specific until
|
||||
// localization is found. As in fi-Latn-FI, fi-Latn and fi.
|
||||
localeParts = locale.split( '-' );
|
||||
localePartIndex = localeParts.length;
|
||||
|
||||
do {
|
||||
tryingLocale = localeParts.slice( 0, localePartIndex ).join( '-' );
|
||||
message = i18n.messageStore.get( tryingLocale, value );
|
||||
|
||||
if ( message ) {
|
||||
return message;
|
||||
}
|
||||
|
||||
localePartIndex--;
|
||||
} while ( localePartIndex );
|
||||
|
||||
if ( locale === 'en' ) {
|
||||
break;
|
||||
}
|
||||
|
||||
locale = ( $.i18n.fallbacks[i18n.locale] && $.i18n.fallbacks[i18n.locale][fallbackIndex] ) ||
|
||||
i18n.options.fallbackLocale;
|
||||
$.i18n.log( 'Trying fallback locale for ' + i18n.locale + ': ' + locale );
|
||||
|
||||
fallbackIndex++;
|
||||
}
|
||||
|
||||
// key not found
|
||||
return '';
|
||||
};
|
||||
},
|
||||
|
||||
/*
|
||||
* Destroy the i18n instance.
|
||||
*/
|
||||
destroy: function () {
|
||||
$.removeData( document, 'i18n' );
|
||||
},
|
||||
|
||||
/**
|
||||
* General message loading API This can take a URL string for
|
||||
* the json formatted messages. Example:
|
||||
* <code>load('path/to/all_localizations.json');</code>
|
||||
*
|
||||
* To load a localization file for a locale:
|
||||
* <code>
|
||||
* load('path/to/de-messages.json', 'de' );
|
||||
* </code>
|
||||
*
|
||||
* To load a localization file from a directory:
|
||||
* <code>
|
||||
* load('path/to/i18n/directory', 'de' );
|
||||
* </code>
|
||||
* The above method has the advantage of fallback resolution.
|
||||
* ie, it will automatically load the fallback locales for de.
|
||||
* For most usecases, this is the recommended method.
|
||||
* It is optional to have trailing slash at end.
|
||||
*
|
||||
* A data object containing message key- message translation mappings
|
||||
* can also be passed. Example:
|
||||
* <code>
|
||||
* load( { 'hello' : 'Hello' }, optionalLocale );
|
||||
* </code>
|
||||
*
|
||||
* A source map containing key-value pair of languagename and locations
|
||||
* can also be passed. Example:
|
||||
* <code>
|
||||
* load( {
|
||||
* bn: 'i18n/bn.json',
|
||||
* he: 'i18n/he.json',
|
||||
* en: 'i18n/en.json'
|
||||
* } )
|
||||
* </code>
|
||||
*
|
||||
* If the data argument is null/undefined/false,
|
||||
* all cached messages for the i18n instance will get reset.
|
||||
*
|
||||
* @param {String|Object} source
|
||||
* @param {String} locale Language tag
|
||||
* @returns {jQuery.Promise}
|
||||
*/
|
||||
load: function ( source, locale ) {
|
||||
var fallbackLocales, locIndex, fallbackLocale, sourceMap = {};
|
||||
if ( !source && !locale ) {
|
||||
source = 'i18n/' + $.i18n().locale + '.json';
|
||||
locale = $.i18n().locale;
|
||||
}
|
||||
if ( typeof source === 'string' &&
|
||||
source.split( '.' ).pop() !== 'json'
|
||||
) {
|
||||
// Load specified locale then check for fallbacks when directory is specified in load()
|
||||
sourceMap[locale] = source + '/' + locale + '.json';
|
||||
fallbackLocales = ( $.i18n.fallbacks[locale] || [] )
|
||||
.concat( this.options.fallbackLocale );
|
||||
for ( locIndex in fallbackLocales ) {
|
||||
fallbackLocale = fallbackLocales[locIndex];
|
||||
sourceMap[fallbackLocale] = source + '/' + fallbackLocale + '.json';
|
||||
}
|
||||
return this.load( sourceMap );
|
||||
} else {
|
||||
return this.messageStore.load( source, locale );
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Does parameter and magic word substitution.
|
||||
*
|
||||
* @param {string} key Message key
|
||||
* @param {Array} parameters Message parameters
|
||||
* @return {string}
|
||||
*/
|
||||
parse: function ( key, parameters ) {
|
||||
var message = key.toLocaleString();
|
||||
// FIXME: This changes the state of the I18N object,
|
||||
// should probably not change the 'this.parser' but just
|
||||
// pass it to the parser.
|
||||
this.parser.language = $.i18n.languages[$.i18n().locale] || $.i18n.languages['default'];
|
||||
if ( message === '' ) {
|
||||
message = key;
|
||||
}
|
||||
return this.parser.parse( message, parameters );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Process a message from the $.I18N instance
|
||||
* for the current document, stored in jQuery.data(document).
|
||||
*
|
||||
* @param {string} key Key of the message.
|
||||
* @param {string} param1 [param...] Variadic list of parameters for {key}.
|
||||
* @return {string|$.I18N} Parsed message, or if no key was given
|
||||
* the instance of $.I18N is returned.
|
||||
*/
|
||||
$.i18n = function ( key, param1 ) {
|
||||
var parameters,
|
||||
i18n = $.data( document, 'i18n' ),
|
||||
options = typeof key === 'object' && key;
|
||||
|
||||
// If the locale option for this call is different then the setup so far,
|
||||
// update it automatically. This doesn't just change the context for this
|
||||
// call but for all future call as well.
|
||||
// If there is no i18n setup yet, don't do this. It will be taken care of
|
||||
// by the `new I18N` construction below.
|
||||
// NOTE: It should only change language for this one call.
|
||||
// Then cache instances of I18N somewhere.
|
||||
if ( options && options.locale && i18n && i18n.locale !== options.locale ) {
|
||||
String.locale = i18n.locale = options.locale;
|
||||
}
|
||||
|
||||
if ( !i18n ) {
|
||||
i18n = new I18N( options );
|
||||
$.data( document, 'i18n', i18n );
|
||||
}
|
||||
|
||||
if ( typeof key === 'string' ) {
|
||||
if ( param1 !== undefined ) {
|
||||
parameters = slice.call( arguments, 1 );
|
||||
} else {
|
||||
parameters = [];
|
||||
}
|
||||
|
||||
return i18n.parse( key, parameters );
|
||||
} else {
|
||||
// FIXME: remove this feature/bug.
|
||||
return i18n;
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.i18n = function () {
|
||||
var i18n = $.data( document, 'i18n' );
|
||||
|
||||
if ( !i18n ) {
|
||||
i18n = new I18N();
|
||||
$.data( document, 'i18n', i18n );
|
||||
}
|
||||
String.locale = i18n.locale;
|
||||
return this.each( function () {
|
||||
var $this = $( this ),
|
||||
messageKey = $this.data( 'i18n' );
|
||||
|
||||
if ( messageKey ) {
|
||||
$this.text( i18n.parse( messageKey ) );
|
||||
} else {
|
||||
$this.find( '[data-i18n]' ).i18n();
|
||||
}
|
||||
} );
|
||||
};
|
||||
|
||||
String.locale = String.locale || $( 'html' ).attr( 'lang' );
|
||||
|
||||
if ( !String.locale ) {
|
||||
if ( typeof window.navigator !== undefined ) {
|
||||
nav = window.navigator;
|
||||
String.locale = nav.language || nav.userLanguage || '';
|
||||
} else {
|
||||
String.locale = '';
|
||||
}
|
||||
}
|
||||
|
||||
$.i18n.languages = {};
|
||||
$.i18n.messageStore = $.i18n.messageStore || {};
|
||||
$.i18n.parser = {
|
||||
// The default parser only handles variable substitution
|
||||
parse: function ( message, parameters ) {
|
||||
return message.replace( /\$(\d+)/g, function ( str, match ) {
|
||||
var index = parseInt( match, 10 ) - 1;
|
||||
return parameters[index] !== undefined ? parameters[index] : '$' + match;
|
||||
} );
|
||||
},
|
||||
emitter: {}
|
||||
};
|
||||
$.i18n.fallbacks = {};
|
||||
$.i18n.debug = false;
|
||||
$.i18n.log = function ( /* arguments */ ) {
|
||||
if ( window.console && $.i18n.debug ) {
|
||||
window.console.log.apply( window.console, arguments );
|
||||
}
|
||||
};
|
||||
/* Static members */
|
||||
I18N.defaults = {
|
||||
locale: String.locale,
|
||||
fallbackLocale: 'en',
|
||||
parser: $.i18n.parser,
|
||||
messageStore: $.i18n.messageStore
|
||||
};
|
||||
|
||||
// Expose constructor
|
||||
$.i18n.constructor = I18N;
|
||||
}( jQuery ) );
|
472
assets/webconfig/js/lib/jquery.i18n.language.js
Normal file
472
assets/webconfig/js/lib/jquery.i18n.language.js
Normal file
@@ -0,0 +1,472 @@
|
||||
/*global pluralRuleParser */
|
||||
( function ( $ ) {
|
||||
'use strict';
|
||||
|
||||
var language = {
|
||||
// CLDR plural rules generated using
|
||||
// libs/CLDRPluralRuleParser/tools/PluralXML2JSON.html
|
||||
pluralRules: {
|
||||
ak: {
|
||||
one: 'n = 0..1'
|
||||
},
|
||||
am: {
|
||||
one: 'i = 0 or n = 1'
|
||||
},
|
||||
ar: {
|
||||
zero: 'n = 0',
|
||||
one: 'n = 1',
|
||||
two: 'n = 2',
|
||||
few: 'n % 100 = 3..10',
|
||||
many: 'n % 100 = 11..99'
|
||||
},
|
||||
be: {
|
||||
one: 'n % 10 = 1 and n % 100 != 11',
|
||||
few: 'n % 10 = 2..4 and n % 100 != 12..14',
|
||||
many: 'n % 10 = 0 or n % 10 = 5..9 or n % 100 = 11..14'
|
||||
},
|
||||
bh: {
|
||||
one: 'n = 0..1'
|
||||
},
|
||||
bn: {
|
||||
one: 'i = 0 or n = 1'
|
||||
},
|
||||
br: {
|
||||
one: 'n % 10 = 1 and n % 100 != 11,71,91',
|
||||
two: 'n % 10 = 2 and n % 100 != 12,72,92',
|
||||
few: 'n % 10 = 3..4,9 and n % 100 != 10..19,70..79,90..99',
|
||||
many: 'n != 0 and n % 1000000 = 0'
|
||||
},
|
||||
bs: {
|
||||
one: 'v = 0 and i % 10 = 1 and i % 100 != 11 or f % 10 = 1 and f % 100 != 11',
|
||||
few: 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14 or f % 10 = 2..4 and f % 100 != 12..14'
|
||||
},
|
||||
cs: {
|
||||
one: 'i = 1 and v = 0',
|
||||
few: 'i = 2..4 and v = 0',
|
||||
many: 'v != 0'
|
||||
},
|
||||
cy: {
|
||||
zero: 'n = 0',
|
||||
one: 'n = 1',
|
||||
two: 'n = 2',
|
||||
few: 'n = 3',
|
||||
many: 'n = 6'
|
||||
},
|
||||
da: {
|
||||
one: 'n = 1 or t != 0 and i = 0,1'
|
||||
},
|
||||
fa: {
|
||||
one: 'i = 0 or n = 1'
|
||||
},
|
||||
ff: {
|
||||
one: 'i = 0,1'
|
||||
},
|
||||
fil: {
|
||||
one: 'i = 0..1 and v = 0'
|
||||
},
|
||||
fr: {
|
||||
one: 'i = 0,1'
|
||||
},
|
||||
ga: {
|
||||
one: 'n = 1',
|
||||
two: 'n = 2',
|
||||
few: 'n = 3..6',
|
||||
many: 'n = 7..10'
|
||||
},
|
||||
gd: {
|
||||
one: 'n = 1,11',
|
||||
two: 'n = 2,12',
|
||||
few: 'n = 3..10,13..19'
|
||||
},
|
||||
gu: {
|
||||
one: 'i = 0 or n = 1'
|
||||
},
|
||||
guw: {
|
||||
one: 'n = 0..1'
|
||||
},
|
||||
gv: {
|
||||
one: 'n % 10 = 1',
|
||||
two: 'n % 10 = 2',
|
||||
few: 'n % 100 = 0,20,40,60'
|
||||
},
|
||||
he: {
|
||||
one: 'i = 1 and v = 0',
|
||||
two: 'i = 2 and v = 0',
|
||||
many: 'v = 0 and n != 0..10 and n % 10 = 0'
|
||||
},
|
||||
hi: {
|
||||
one: 'i = 0 or n = 1'
|
||||
},
|
||||
hr: {
|
||||
one: 'v = 0 and i % 10 = 1 and i % 100 != 11 or f % 10 = 1 and f % 100 != 11',
|
||||
few: 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14 or f % 10 = 2..4 and f % 100 != 12..14'
|
||||
},
|
||||
hy: {
|
||||
one: 'i = 0,1'
|
||||
},
|
||||
is: {
|
||||
one: 't = 0 and i % 10 = 1 and i % 100 != 11 or t != 0'
|
||||
},
|
||||
iu: {
|
||||
one: 'n = 1',
|
||||
two: 'n = 2'
|
||||
},
|
||||
iw: {
|
||||
one: 'i = 1 and v = 0',
|
||||
two: 'i = 2 and v = 0',
|
||||
many: 'v = 0 and n != 0..10 and n % 10 = 0'
|
||||
},
|
||||
kab: {
|
||||
one: 'i = 0,1'
|
||||
},
|
||||
kn: {
|
||||
one: 'i = 0 or n = 1'
|
||||
},
|
||||
kw: {
|
||||
one: 'n = 1',
|
||||
two: 'n = 2'
|
||||
},
|
||||
lag: {
|
||||
zero: 'n = 0',
|
||||
one: 'i = 0,1 and n != 0'
|
||||
},
|
||||
ln: {
|
||||
one: 'n = 0..1'
|
||||
},
|
||||
lt: {
|
||||
one: 'n % 10 = 1 and n % 100 != 11..19',
|
||||
few: 'n % 10 = 2..9 and n % 100 != 11..19',
|
||||
many: 'f != 0'
|
||||
},
|
||||
lv: {
|
||||
zero: 'n % 10 = 0 or n % 100 = 11..19 or v = 2 and f % 100 = 11..19',
|
||||
one: 'n % 10 = 1 and n % 100 != 11 or v = 2 and f % 10 = 1 and f % 100 != 11 or v != 2 and f % 10 = 1'
|
||||
},
|
||||
mg: {
|
||||
one: 'n = 0..1'
|
||||
},
|
||||
mk: {
|
||||
one: 'v = 0 and i % 10 = 1 or f % 10 = 1'
|
||||
},
|
||||
mo: {
|
||||
one: 'i = 1 and v = 0',
|
||||
few: 'v != 0 or n = 0 or n != 1 and n % 100 = 1..19'
|
||||
},
|
||||
mr: {
|
||||
one: 'i = 0 or n = 1'
|
||||
},
|
||||
mt: {
|
||||
one: 'n = 1',
|
||||
few: 'n = 0 or n % 100 = 2..10',
|
||||
many: 'n % 100 = 11..19'
|
||||
},
|
||||
naq: {
|
||||
one: 'n = 1',
|
||||
two: 'n = 2'
|
||||
},
|
||||
nso: {
|
||||
one: 'n = 0..1'
|
||||
},
|
||||
pa: {
|
||||
one: 'n = 0..1'
|
||||
},
|
||||
pl: {
|
||||
one: 'i = 1 and v = 0',
|
||||
few: 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14',
|
||||
many: 'v = 0 and i != 1 and i % 10 = 0..1 or v = 0 and i % 10 = 5..9 or v = 0 and i % 100 = 12..14'
|
||||
},
|
||||
pt: {
|
||||
one: 'i = 1 and v = 0 or i = 0 and t = 1'
|
||||
},
|
||||
// jscs:disable requireCamelCaseOrUpperCaseIdentifiers
|
||||
pt_PT: {
|
||||
one: 'n = 1 and v = 0'
|
||||
},
|
||||
// jscs:enable requireCamelCaseOrUpperCaseIdentifiers
|
||||
ro: {
|
||||
one: 'i = 1 and v = 0',
|
||||
few: 'v != 0 or n = 0 or n != 1 and n % 100 = 1..19'
|
||||
},
|
||||
ru: {
|
||||
one: 'v = 0 and i % 10 = 1 and i % 100 != 11',
|
||||
many: 'v = 0 and i % 10 = 0 or v = 0 and i % 10 = 5..9 or v = 0 and i % 100 = 11..14'
|
||||
},
|
||||
se: {
|
||||
one: 'n = 1',
|
||||
two: 'n = 2'
|
||||
},
|
||||
sh: {
|
||||
one: 'v = 0 and i % 10 = 1 and i % 100 != 11 or f % 10 = 1 and f % 100 != 11',
|
||||
few: 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14 or f % 10 = 2..4 and f % 100 != 12..14'
|
||||
},
|
||||
shi: {
|
||||
one: 'i = 0 or n = 1',
|
||||
few: 'n = 2..10'
|
||||
},
|
||||
si: {
|
||||
one: 'n = 0,1 or i = 0 and f = 1'
|
||||
},
|
||||
sk: {
|
||||
one: 'i = 1 and v = 0',
|
||||
few: 'i = 2..4 and v = 0',
|
||||
many: 'v != 0'
|
||||
},
|
||||
sl: {
|
||||
one: 'v = 0 and i % 100 = 1',
|
||||
two: 'v = 0 and i % 100 = 2',
|
||||
few: 'v = 0 and i % 100 = 3..4 or v != 0'
|
||||
},
|
||||
sma: {
|
||||
one: 'n = 1',
|
||||
two: 'n = 2'
|
||||
},
|
||||
smi: {
|
||||
one: 'n = 1',
|
||||
two: 'n = 2'
|
||||
},
|
||||
smj: {
|
||||
one: 'n = 1',
|
||||
two: 'n = 2'
|
||||
},
|
||||
smn: {
|
||||
one: 'n = 1',
|
||||
two: 'n = 2'
|
||||
},
|
||||
sms: {
|
||||
one: 'n = 1',
|
||||
two: 'n = 2'
|
||||
},
|
||||
sr: {
|
||||
one: 'v = 0 and i % 10 = 1 and i % 100 != 11 or f % 10 = 1 and f % 100 != 11',
|
||||
few: 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14 or f % 10 = 2..4 and f % 100 != 12..14'
|
||||
},
|
||||
ti: {
|
||||
one: 'n = 0..1'
|
||||
},
|
||||
tl: {
|
||||
one: 'i = 0..1 and v = 0'
|
||||
},
|
||||
tzm: {
|
||||
one: 'n = 0..1 or n = 11..99'
|
||||
},
|
||||
uk: {
|
||||
one: 'v = 0 and i % 10 = 1 and i % 100 != 11',
|
||||
few: 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14',
|
||||
many: 'v = 0 and i % 10 = 0 or v = 0 and i % 10 = 5..9 or v = 0 and i % 100 = 11..14'
|
||||
},
|
||||
wa: {
|
||||
one: 'n = 0..1'
|
||||
},
|
||||
zu: {
|
||||
one: 'i = 0 or n = 1'
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Plural form transformations, needed for some languages.
|
||||
*
|
||||
* @param count
|
||||
* integer Non-localized quantifier
|
||||
* @param forms
|
||||
* array List of plural forms
|
||||
* @return string Correct form for quantifier in this language
|
||||
*/
|
||||
convertPlural: function ( count, forms ) {
|
||||
var pluralRules,
|
||||
pluralFormIndex,
|
||||
index,
|
||||
explicitPluralPattern = new RegExp( '\\d+=', 'i' ),
|
||||
formCount,
|
||||
form;
|
||||
|
||||
if ( !forms || forms.length === 0 ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Handle for Explicit 0= & 1= values
|
||||
for ( index = 0; index < forms.length; index++ ) {
|
||||
form = forms[index];
|
||||
if ( explicitPluralPattern.test( form ) ) {
|
||||
formCount = parseInt( form.substring( 0, form.indexOf( '=' ) ), 10 );
|
||||
if ( formCount === count ) {
|
||||
return ( form.substr( form.indexOf( '=' ) + 1 ) );
|
||||
}
|
||||
forms[index] = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
forms = $.map( forms, function ( form ) {
|
||||
if ( form !== undefined ) {
|
||||
return form;
|
||||
}
|
||||
} );
|
||||
|
||||
pluralRules = this.pluralRules[$.i18n().locale];
|
||||
|
||||
if ( !pluralRules ) {
|
||||
// default fallback.
|
||||
return ( count === 1 ) ? forms[0] : forms[1];
|
||||
}
|
||||
|
||||
pluralFormIndex = this.getPluralForm( count, pluralRules );
|
||||
pluralFormIndex = Math.min( pluralFormIndex, forms.length - 1 );
|
||||
|
||||
return forms[pluralFormIndex];
|
||||
},
|
||||
|
||||
/**
|
||||
* For the number, get the plural for index
|
||||
*
|
||||
* @param number
|
||||
* @param pluralRules
|
||||
* @return plural form index
|
||||
*/
|
||||
getPluralForm: function ( number, pluralRules ) {
|
||||
var i,
|
||||
pluralForms = [ 'zero', 'one', 'two', 'few', 'many', 'other' ],
|
||||
pluralFormIndex = 0;
|
||||
|
||||
for ( i = 0; i < pluralForms.length; i++ ) {
|
||||
if ( pluralRules[pluralForms[i]] ) {
|
||||
if ( pluralRuleParser( pluralRules[pluralForms[i]], number ) ) {
|
||||
return pluralFormIndex;
|
||||
}
|
||||
|
||||
pluralFormIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
return pluralFormIndex;
|
||||
},
|
||||
|
||||
/**
|
||||
* Converts a number using digitTransformTable.
|
||||
*
|
||||
* @param {number} num Value to be converted
|
||||
* @param {boolean} integer Convert the return value to an integer
|
||||
*/
|
||||
convertNumber: function ( num, integer ) {
|
||||
var tmp, item, i,
|
||||
transformTable, numberString, convertedNumber;
|
||||
|
||||
// Set the target Transform table:
|
||||
transformTable = this.digitTransformTable( $.i18n().locale );
|
||||
numberString = String( num );
|
||||
convertedNumber = '';
|
||||
|
||||
if ( !transformTable ) {
|
||||
return num;
|
||||
}
|
||||
|
||||
// Check if the restore to Latin number flag is set:
|
||||
if ( integer ) {
|
||||
if ( parseFloat( num, 10 ) === num ) {
|
||||
return num;
|
||||
}
|
||||
|
||||
tmp = [];
|
||||
|
||||
for ( item in transformTable ) {
|
||||
tmp[transformTable[item]] = item;
|
||||
}
|
||||
|
||||
transformTable = tmp;
|
||||
}
|
||||
|
||||
for ( i = 0; i < numberString.length; i++ ) {
|
||||
if ( transformTable[numberString[i]] ) {
|
||||
convertedNumber += transformTable[numberString[i]];
|
||||
} else {
|
||||
convertedNumber += numberString[i];
|
||||
}
|
||||
}
|
||||
|
||||
return integer ? parseFloat( convertedNumber, 10 ) : convertedNumber;
|
||||
},
|
||||
|
||||
/**
|
||||
* Grammatical transformations, needed for inflected languages.
|
||||
* Invoked by putting {{grammar:form|word}} in a message.
|
||||
* Override this method for languages that need special grammar rules
|
||||
* applied dynamically.
|
||||
*
|
||||
* @param word {String}
|
||||
* @param form {String}
|
||||
* @return {String}
|
||||
*/
|
||||
convertGrammar: function ( word, form ) { /*jshint unused: false */
|
||||
return word;
|
||||
},
|
||||
|
||||
/**
|
||||
* Provides an alternative text depending on specified gender. Usage
|
||||
* {{gender:[gender|user object]|masculine|feminine|neutral}}. If second
|
||||
* or third parameter are not specified, masculine is used.
|
||||
*
|
||||
* These details may be overriden per language.
|
||||
*
|
||||
* @param gender
|
||||
* string male, female, or anything else for neutral.
|
||||
* @param forms
|
||||
* array List of gender forms
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
gender: function ( gender, forms ) {
|
||||
if ( !forms || forms.length === 0 ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
while ( forms.length < 2 ) {
|
||||
forms.push( forms[forms.length - 1] );
|
||||
}
|
||||
|
||||
if ( gender === 'male' ) {
|
||||
return forms[0];
|
||||
}
|
||||
|
||||
if ( gender === 'female' ) {
|
||||
return forms[1];
|
||||
}
|
||||
|
||||
return ( forms.length === 3 ) ? forms[2] : forms[0];
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the digit transform table for the given language
|
||||
* See http://cldr.unicode.org/translation/numbering-systems
|
||||
* @param language
|
||||
* @returns {Array|boolean} List of digits in the passed language or false
|
||||
* representation, or boolean false if there is no information.
|
||||
*/
|
||||
digitTransformTable: function ( language ) {
|
||||
var tables = {
|
||||
ar: '٠١٢٣٤٥٦٧٨٩',
|
||||
fa: '۰۱۲۳۴۵۶۷۸۹',
|
||||
ml: '൦൧൨൩൪൫൬൭൮൯',
|
||||
kn: '೦೧೨೩೪೫೬೭೮೯',
|
||||
lo: '໐໑໒໓໔໕໖໗໘໙',
|
||||
or: '୦୧୨୩୪୫୬୭୮୯',
|
||||
kh: '០១២៣៤៥៦៧៨៩',
|
||||
pa: '੦੧੨੩੪੫੬੭੮੯',
|
||||
gu: '૦૧૨૩૪૫૬૭૮૯',
|
||||
hi: '०१२३४५६७८९',
|
||||
my: '၀၁၂၃၄၅၆၇၈၉',
|
||||
ta: '௦௧௨௩௪௫௬௭௮௯',
|
||||
te: '౦౧౨౩౪౫౬౭౮౯',
|
||||
th: '๐๑๒๓๔๕๖๗๘๙', // FIXME use iso 639 codes
|
||||
bo: '༠༡༢༣༤༥༦༧༨༩' // FIXME use iso 639 codes
|
||||
};
|
||||
|
||||
if ( !tables[language] ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return tables[language].split( '' );
|
||||
}
|
||||
};
|
||||
|
||||
$.extend( $.i18n.languages, {
|
||||
'default': language
|
||||
} );
|
||||
}( jQuery ) );
|
125
assets/webconfig/js/lib/jquery.i18n.messagestore.js
Normal file
125
assets/webconfig/js/lib/jquery.i18n.messagestore.js
Normal file
@@ -0,0 +1,125 @@
|
||||
/**
|
||||
* jQuery Internationalization library - Message Store
|
||||
*
|
||||
* Copyright (C) 2012 Santhosh Thottingal
|
||||
*
|
||||
* jquery.i18n is dual licensed GPLv2 or later and MIT. You don't have to do anything special to
|
||||
* choose one license or the other and you don't have to notify anyone which license you are using.
|
||||
* You are free to use UniversalLanguageSelector in commercial projects as long as the copyright
|
||||
* header is left intact. See files GPL-LICENSE and MIT-LICENSE for details.
|
||||
*
|
||||
* @licence GNU General Public Licence 2.0 or later
|
||||
* @licence MIT License
|
||||
*/
|
||||
|
||||
( function ( $, window, undefined ) {
|
||||
'use strict';
|
||||
|
||||
var MessageStore = function () {
|
||||
this.messages = {};
|
||||
this.sources = {};
|
||||
};
|
||||
|
||||
/**
|
||||
* See https://github.com/wikimedia/jquery.i18n/wiki/Specification#wiki-Message_File_Loading
|
||||
*/
|
||||
MessageStore.prototype = {
|
||||
|
||||
/**
|
||||
* General message loading API This can take a URL string for
|
||||
* the json formatted messages.
|
||||
* <code>load('path/to/all_localizations.json');</code>
|
||||
*
|
||||
* This can also load a localization file for a locale <code>
|
||||
* load( 'path/to/de-messages.json', 'de' );
|
||||
* </code>
|
||||
* A data object containing message key- message translation mappings
|
||||
* can also be passed Eg:
|
||||
* <code>
|
||||
* load( { 'hello' : 'Hello' }, optionalLocale );
|
||||
* </code> If the data argument is
|
||||
* null/undefined/false,
|
||||
* all cached messages for the i18n instance will get reset.
|
||||
*
|
||||
* @param {String|Object} source
|
||||
* @param {String} locale Language tag
|
||||
* @return {jQuery.Promise}
|
||||
*/
|
||||
load: function ( source, locale ) {
|
||||
var key = null,
|
||||
deferred = null,
|
||||
deferreds = [],
|
||||
messageStore = this;
|
||||
|
||||
if ( typeof source === 'string' ) {
|
||||
// This is a URL to the messages file.
|
||||
$.i18n.log( 'Loading messages from: ' + source );
|
||||
deferred = jsonMessageLoader( source )
|
||||
.done( function ( localization ) {
|
||||
messageStore.set( locale, localization );
|
||||
} );
|
||||
|
||||
return deferred.promise();
|
||||
}
|
||||
|
||||
if ( locale ) {
|
||||
// source is an key-value pair of messages for given locale
|
||||
messageStore.set( locale, source );
|
||||
|
||||
return $.Deferred().resolve();
|
||||
} else {
|
||||
// source is a key-value pair of locales and their source
|
||||
for ( key in source ) {
|
||||
if ( Object.prototype.hasOwnProperty.call( source, key ) ) {
|
||||
locale = key;
|
||||
// No {locale} given, assume data is a group of languages,
|
||||
// call this function again for each language.
|
||||
deferreds.push( messageStore.load( source[key], locale ) );
|
||||
}
|
||||
}
|
||||
return $.when.apply( $, deferreds );
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Set messages to the given locale.
|
||||
* If locale exists, add messages to the locale.
|
||||
* @param locale
|
||||
* @param messages
|
||||
*/
|
||||
set: function ( locale, messages ) {
|
||||
if ( !this.messages[locale] ) {
|
||||
this.messages[locale] = messages;
|
||||
} else {
|
||||
this.messages[locale] = $.extend( this.messages[locale], messages );
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* @param locale
|
||||
* @param messageKey
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
get: function ( locale, messageKey ) {
|
||||
return this.messages[locale] && this.messages[locale][messageKey];
|
||||
}
|
||||
};
|
||||
|
||||
function jsonMessageLoader( url ) {
|
||||
var deferred = $.Deferred();
|
||||
|
||||
$.getJSON( url )
|
||||
.done( deferred.resolve )
|
||||
.fail( function ( jqxhr, settings, exception ) {
|
||||
$.i18n.log( 'Error in loading messages from ' + url + ' Exception: ' + exception );
|
||||
// Ignore 404 exception, because we are handling fallabacks explicitly
|
||||
deferred.resolve();
|
||||
} );
|
||||
|
||||
return deferred.promise();
|
||||
}
|
||||
|
||||
$.extend( $.i18n.messageStore, new MessageStore() );
|
||||
}( jQuery, window ) );
|
309
assets/webconfig/js/lib/jquery.i18n.parser.js
Normal file
309
assets/webconfig/js/lib/jquery.i18n.parser.js
Normal file
@@ -0,0 +1,309 @@
|
||||
/**
|
||||
* jQuery Internationalization library
|
||||
*
|
||||
* Copyright (C) 2011-2013 Santhosh Thottingal, Neil Kandalgaonkar
|
||||
*
|
||||
* jquery.i18n is dual licensed GPLv2 or later and MIT. You don't have to do
|
||||
* anything special to choose one license or the other and you don't have to
|
||||
* notify anyone which license you are using. You are free to use
|
||||
* UniversalLanguageSelector in commercial projects as long as the copyright
|
||||
* header is left intact. See files GPL-LICENSE and MIT-LICENSE for details.
|
||||
*
|
||||
* @licence GNU General Public Licence 2.0 or later
|
||||
* @licence MIT License
|
||||
*/
|
||||
|
||||
( function ( $ ) {
|
||||
'use strict';
|
||||
|
||||
var MessageParser = function ( options ) {
|
||||
this.options = $.extend( {}, $.i18n.parser.defaults, options );
|
||||
this.language = $.i18n.languages[String.locale] || $.i18n.languages['default'];
|
||||
this.emitter = $.i18n.parser.emitter;
|
||||
};
|
||||
|
||||
MessageParser.prototype = {
|
||||
|
||||
constructor: MessageParser,
|
||||
|
||||
simpleParse: function ( message, parameters ) {
|
||||
return message.replace( /\$(\d+)/g, function ( str, match ) {
|
||||
var index = parseInt( match, 10 ) - 1;
|
||||
|
||||
return parameters[index] !== undefined ? parameters[index] : '$' + match;
|
||||
} );
|
||||
},
|
||||
|
||||
parse: function ( message, replacements ) {
|
||||
if ( message.indexOf( '{{' ) < 0 ) {
|
||||
return this.simpleParse( message, replacements );
|
||||
}
|
||||
|
||||
this.emitter.language = $.i18n.languages[$.i18n().locale] ||
|
||||
$.i18n.languages['default'];
|
||||
|
||||
return this.emitter.emit( this.ast( message ), replacements );
|
||||
},
|
||||
|
||||
ast: function ( message ) {
|
||||
var pipe, colon, backslash, anyCharacter, dollar, digits, regularLiteral,
|
||||
regularLiteralWithoutBar, regularLiteralWithoutSpace, escapedOrLiteralWithoutBar,
|
||||
escapedOrRegularLiteral, templateContents, templateName, openTemplate,
|
||||
closeTemplate, expression, paramExpression, result,
|
||||
pos = 0;
|
||||
|
||||
// Try parsers until one works, if none work return null
|
||||
function choice( parserSyntax ) {
|
||||
return function () {
|
||||
var i, result;
|
||||
|
||||
for ( i = 0; i < parserSyntax.length; i++ ) {
|
||||
result = parserSyntax[i]();
|
||||
|
||||
if ( result !== null ) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
}
|
||||
|
||||
// Try several parserSyntax-es in a row.
|
||||
// All must succeed; otherwise, return null.
|
||||
// This is the only eager one.
|
||||
function sequence( parserSyntax ) {
|
||||
var i, res,
|
||||
originalPos = pos,
|
||||
result = [];
|
||||
|
||||
for ( i = 0; i < parserSyntax.length; i++ ) {
|
||||
res = parserSyntax[i]();
|
||||
|
||||
if ( res === null ) {
|
||||
pos = originalPos;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
result.push( res );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Run the same parser over and over until it fails.
|
||||
// Must succeed a minimum of n times; otherwise, return null.
|
||||
function nOrMore( n, p ) {
|
||||
return function () {
|
||||
var originalPos = pos,
|
||||
result = [],
|
||||
parsed = p();
|
||||
|
||||
while ( parsed !== null ) {
|
||||
result.push( parsed );
|
||||
parsed = p();
|
||||
}
|
||||
|
||||
if ( result.length < n ) {
|
||||
pos = originalPos;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
// Helpers -- just make parserSyntax out of simpler JS builtin types
|
||||
|
||||
function makeStringParser( s ) {
|
||||
var len = s.length;
|
||||
|
||||
return function () {
|
||||
var result = null;
|
||||
|
||||
if ( message.substr( pos, len ) === s ) {
|
||||
result = s;
|
||||
pos += len;
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
function makeRegexParser( regex ) {
|
||||
return function () {
|
||||
var matches = message.substr( pos ).match( regex );
|
||||
|
||||
if ( matches === null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
pos += matches[0].length;
|
||||
|
||||
return matches[0];
|
||||
};
|
||||
}
|
||||
|
||||
pipe = makeStringParser( '|' );
|
||||
colon = makeStringParser( ':' );
|
||||
backslash = makeStringParser( '\\' );
|
||||
anyCharacter = makeRegexParser( /^./ );
|
||||
dollar = makeStringParser( '$' );
|
||||
digits = makeRegexParser( /^\d+/ );
|
||||
regularLiteral = makeRegexParser( /^[^{}\[\]$\\]/ );
|
||||
regularLiteralWithoutBar = makeRegexParser( /^[^{}\[\]$\\|]/ );
|
||||
regularLiteralWithoutSpace = makeRegexParser( /^[^{}\[\]$\s]/ );
|
||||
|
||||
// There is a general pattern:
|
||||
// parse a thing;
|
||||
// if it worked, apply transform,
|
||||
// otherwise return null.
|
||||
// But using this as a combinator seems to cause problems
|
||||
// when combined with nOrMore().
|
||||
// May be some scoping issue.
|
||||
function transform( p, fn ) {
|
||||
return function () {
|
||||
var result = p();
|
||||
|
||||
return result === null ? null : fn( result );
|
||||
};
|
||||
}
|
||||
|
||||
// Used to define "literals" within template parameters. The pipe
|
||||
// character is the parameter delimeter, so by default
|
||||
// it is not a literal in the parameter
|
||||
function literalWithoutBar() {
|
||||
var result = nOrMore( 1, escapedOrLiteralWithoutBar )();
|
||||
|
||||
return result === null ? null : result.join( '' );
|
||||
}
|
||||
|
||||
function literal() {
|
||||
var result = nOrMore( 1, escapedOrRegularLiteral )();
|
||||
|
||||
return result === null ? null : result.join( '' );
|
||||
}
|
||||
|
||||
function escapedLiteral() {
|
||||
var result = sequence( [ backslash, anyCharacter ] );
|
||||
|
||||
return result === null ? null : result[1];
|
||||
}
|
||||
|
||||
choice( [ escapedLiteral, regularLiteralWithoutSpace ] );
|
||||
escapedOrLiteralWithoutBar = choice( [ escapedLiteral, regularLiteralWithoutBar ] );
|
||||
escapedOrRegularLiteral = choice( [ escapedLiteral, regularLiteral ] );
|
||||
|
||||
function replacement() {
|
||||
var result = sequence( [ dollar, digits ] );
|
||||
|
||||
if ( result === null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return [ 'REPLACE', parseInt( result[1], 10 ) - 1 ];
|
||||
}
|
||||
|
||||
templateName = transform(
|
||||
// see $wgLegalTitleChars
|
||||
// not allowing : due to the need to catch "PLURAL:$1"
|
||||
makeRegexParser( /^[ !"$&'()*,.\/0-9;=?@A-Z\^_`a-z~\x80-\xFF+\-]+/ ),
|
||||
|
||||
function ( result ) {
|
||||
return result.toString();
|
||||
}
|
||||
);
|
||||
|
||||
function templateParam() {
|
||||
var expr,
|
||||
result = sequence( [ pipe, nOrMore( 0, paramExpression ) ] );
|
||||
|
||||
if ( result === null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
expr = result[1];
|
||||
|
||||
// use a "CONCAT" operator if there are multiple nodes,
|
||||
// otherwise return the first node, raw.
|
||||
return expr.length > 1 ? [ 'CONCAT' ].concat( expr ) : expr[0];
|
||||
}
|
||||
|
||||
function templateWithReplacement() {
|
||||
var result = sequence( [ templateName, colon, replacement ] );
|
||||
|
||||
return result === null ? null : [ result[0], result[2] ];
|
||||
}
|
||||
|
||||
function templateWithOutReplacement() {
|
||||
var result = sequence( [ templateName, colon, paramExpression ] );
|
||||
|
||||
return result === null ? null : [ result[0], result[2] ];
|
||||
}
|
||||
|
||||
templateContents = choice( [
|
||||
function () {
|
||||
var res = sequence( [
|
||||
// templates can have placeholders for dynamic
|
||||
// replacement eg: {{PLURAL:$1|one car|$1 cars}}
|
||||
// or no placeholders eg:
|
||||
// {{GRAMMAR:genitive|{{SITENAME}}}
|
||||
choice( [ templateWithReplacement, templateWithOutReplacement ] ),
|
||||
nOrMore( 0, templateParam )
|
||||
] );
|
||||
|
||||
return res === null ? null : res[0].concat( res[1] );
|
||||
},
|
||||
function () {
|
||||
var res = sequence( [ templateName, nOrMore( 0, templateParam ) ] );
|
||||
|
||||
if ( res === null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return [ res[0] ].concat( res[1] );
|
||||
}
|
||||
] );
|
||||
|
||||
openTemplate = makeStringParser( '{{' );
|
||||
closeTemplate = makeStringParser( '}}' );
|
||||
|
||||
function template() {
|
||||
var result = sequence( [ openTemplate, templateContents, closeTemplate ] );
|
||||
|
||||
return result === null ? null : result[1];
|
||||
}
|
||||
|
||||
expression = choice( [ template, replacement, literal ] );
|
||||
paramExpression = choice( [ template, replacement, literalWithoutBar ] );
|
||||
|
||||
function start() {
|
||||
var result = nOrMore( 0, expression )();
|
||||
|
||||
if ( result === null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return [ 'CONCAT' ].concat( result );
|
||||
}
|
||||
|
||||
result = start();
|
||||
|
||||
/*
|
||||
* For success, the pos must have gotten to the end of the input
|
||||
* and returned a non-null.
|
||||
* n.b. This is part of language infrastructure, so we do not throw an internationalizable message.
|
||||
*/
|
||||
if ( result === null || pos !== message.length ) {
|
||||
throw new Error( 'Parse error at position ' + pos.toString() + ' in input: ' + message );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
$.extend( $.i18n.parser, new MessageParser() );
|
||||
}( jQuery ) );
|
@@ -1,145 +0,0 @@
|
||||
/*!
|
||||
* JavaScript Cookie v2.0.4
|
||||
* https://github.com/js-cookie/js-cookie
|
||||
*
|
||||
* Copyright 2006, 2015 Klaus Hartl & Fagner Brack
|
||||
* Released under the MIT license
|
||||
*/
|
||||
(function (factory) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define(factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
module.exports = factory();
|
||||
} else {
|
||||
var _OldCookies = window.Cookies;
|
||||
var api = window.Cookies = factory();
|
||||
api.noConflict = function () {
|
||||
window.Cookies = _OldCookies;
|
||||
return api;
|
||||
};
|
||||
}
|
||||
}(function () {
|
||||
function extend () {
|
||||
var i = 0;
|
||||
var result = {};
|
||||
for (; i < arguments.length; i++) {
|
||||
var attributes = arguments[ i ];
|
||||
for (var key in attributes) {
|
||||
result[key] = attributes[key];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function init (converter) {
|
||||
function api (key, value, attributes) {
|
||||
var result;
|
||||
|
||||
// Write
|
||||
|
||||
if (arguments.length > 1) {
|
||||
attributes = extend({
|
||||
path: '/'
|
||||
}, api.defaults, attributes);
|
||||
|
||||
if (typeof attributes.expires === 'number') {
|
||||
var expires = new Date();
|
||||
expires.setMilliseconds(expires.getMilliseconds() + attributes.expires * 864e+5);
|
||||
attributes.expires = expires;
|
||||
}
|
||||
|
||||
try {
|
||||
result = JSON.stringify(value);
|
||||
if (/^[\{\[]/.test(result)) {
|
||||
value = result;
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
if (!converter.write) {
|
||||
value = encodeURIComponent(String(value))
|
||||
.replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent);
|
||||
} else {
|
||||
value = converter.write(value, key);
|
||||
}
|
||||
|
||||
key = encodeURIComponent(String(key));
|
||||
key = key.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent);
|
||||
key = key.replace(/[\(\)]/g, escape);
|
||||
|
||||
return (document.cookie = [
|
||||
key, '=', value,
|
||||
attributes.expires && '; expires=' + attributes.expires.toUTCString(), // use expires attribute, max-age is not supported by IE
|
||||
attributes.path && '; path=' + attributes.path,
|
||||
attributes.domain && '; domain=' + attributes.domain,
|
||||
attributes.secure ? '; secure' : ''
|
||||
].join(''));
|
||||
}
|
||||
|
||||
// Read
|
||||
|
||||
if (!key) {
|
||||
result = {};
|
||||
}
|
||||
|
||||
// To prevent the for loop in the first place assign an empty array
|
||||
// in case there are no cookies at all. Also prevents odd result when
|
||||
// calling "get()"
|
||||
var cookies = document.cookie ? document.cookie.split('; ') : [];
|
||||
var rdecode = /(%[0-9A-Z]{2})+/g;
|
||||
var i = 0;
|
||||
|
||||
for (; i < cookies.length; i++) {
|
||||
var parts = cookies[i].split('=');
|
||||
var name = parts[0].replace(rdecode, decodeURIComponent);
|
||||
var cookie = parts.slice(1).join('=');
|
||||
|
||||
if (cookie.charAt(0) === '"') {
|
||||
cookie = cookie.slice(1, -1);
|
||||
}
|
||||
|
||||
try {
|
||||
cookie = converter.read ?
|
||||
converter.read(cookie, name) : converter(cookie, name) ||
|
||||
cookie.replace(rdecode, decodeURIComponent);
|
||||
|
||||
if (this.json) {
|
||||
try {
|
||||
cookie = JSON.parse(cookie);
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
if (key === name) {
|
||||
result = cookie;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!key) {
|
||||
result[name] = cookie;
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
api.get = api.set = api;
|
||||
api.getJSON = function () {
|
||||
return api.apply({
|
||||
json: true
|
||||
}, [].slice.call(arguments));
|
||||
};
|
||||
api.defaults = {};
|
||||
|
||||
api.remove = function (key, attributes) {
|
||||
api(key, '', extend(attributes, {
|
||||
expires: -1
|
||||
}));
|
||||
};
|
||||
|
||||
api.withConverter = init;
|
||||
|
||||
return api;
|
||||
}
|
||||
|
||||
return init(function () {});
|
||||
}));
|
@@ -245,8 +245,6 @@ JSONEditor.prototype = {
|
||||
this.root_container = this.theme.getContainer();
|
||||
this.element.appendChild(this.root_container);
|
||||
|
||||
this.translate = this.options.translate || JSONEditor.defaults.translate;
|
||||
|
||||
// Fetch all external refs via ajax
|
||||
this._loadExternalRefs(this.schema, function() {
|
||||
self._getDefinitions(self.schema);
|
||||
@@ -839,7 +837,7 @@ JSONEditor.Validator = Class.extend({
|
||||
errors.push({
|
||||
path: path,
|
||||
property: 'required',
|
||||
message: this.translate("error_notset")
|
||||
message: this.translate("edt_msg_error_notset")
|
||||
});
|
||||
|
||||
// Can't do any more validation at this point
|
||||
@@ -853,7 +851,7 @@ JSONEditor.Validator = Class.extend({
|
||||
errors.push({
|
||||
path: path,
|
||||
property: 'required',
|
||||
message: this.translate("error_notset")
|
||||
message: this.translate("edt_msg_error_notset")
|
||||
});
|
||||
}
|
||||
// Not required, no further validation needed
|
||||
@@ -872,7 +870,7 @@ JSONEditor.Validator = Class.extend({
|
||||
errors.push({
|
||||
path: path,
|
||||
property: 'enum',
|
||||
message: this.translate("error_enum")
|
||||
message: this.translate("edt_msg_error_enum")
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -904,7 +902,7 @@ JSONEditor.Validator = Class.extend({
|
||||
errors.push({
|
||||
path: path,
|
||||
property: 'anyOf',
|
||||
message: this.translate('error_anyOf')
|
||||
message: this.translate('edt_msg_error_anyOf')
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -930,7 +928,7 @@ JSONEditor.Validator = Class.extend({
|
||||
errors.push({
|
||||
path: path,
|
||||
property: 'oneOf',
|
||||
message: this.translate('error_oneOf', [valid])
|
||||
message: this.translate('edt_msg_error_oneOf', [valid])
|
||||
});
|
||||
errors = errors.concat(oneof_errors);
|
||||
}
|
||||
@@ -942,7 +940,7 @@ JSONEditor.Validator = Class.extend({
|
||||
errors.push({
|
||||
path: path,
|
||||
property: 'not',
|
||||
message: this.translate('error_not')
|
||||
message: this.translate('edt_msg_error_not')
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -962,7 +960,7 @@ JSONEditor.Validator = Class.extend({
|
||||
errors.push({
|
||||
path: path,
|
||||
property: 'type',
|
||||
message: this.translate('error_type_union')
|
||||
message: this.translate('edt_msg_error_type_union')
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -972,7 +970,7 @@ JSONEditor.Validator = Class.extend({
|
||||
errors.push({
|
||||
path: path,
|
||||
property: 'type',
|
||||
message: this.translate('error_type', [schema.type])
|
||||
message: this.translate('edt_msg_error_type', [schema.type])
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -994,7 +992,7 @@ JSONEditor.Validator = Class.extend({
|
||||
errors.push({
|
||||
path: path,
|
||||
property: 'disallow',
|
||||
message: this.translate('error_disallow_union')
|
||||
message: this.translate('edt_msg_error_disallow_union')
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1004,7 +1002,7 @@ JSONEditor.Validator = Class.extend({
|
||||
errors.push({
|
||||
path: path,
|
||||
property: 'disallow',
|
||||
message: this.translate('error_disallow', [schema.disallow])
|
||||
message: this.translate('edt_msg_error_disallow', [schema.disallow])
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1035,7 +1033,7 @@ JSONEditor.Validator = Class.extend({
|
||||
errors.push({
|
||||
path: path,
|
||||
property: schema.multipleOf? 'multipleOf' : 'divisibleBy',
|
||||
message: this.translate('error_multipleOf', [divisor])
|
||||
message: this.translate('edt_msg_error_multipleOf', [divisor])
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1062,7 +1060,7 @@ JSONEditor.Validator = Class.extend({
|
||||
path: path,
|
||||
property: 'maximum',
|
||||
message: this.translate(
|
||||
(schema.exclusiveMaximum?'error_maximum_excl':'error_maximum_incl'),
|
||||
(schema.exclusiveMaximum?'edt_msg_error_maximum_excl':'edt_msg_error_maximum_incl'),
|
||||
[schema.maximum]
|
||||
)
|
||||
});
|
||||
@@ -1091,7 +1089,7 @@ JSONEditor.Validator = Class.extend({
|
||||
path: path,
|
||||
property: 'minimum',
|
||||
message: this.translate(
|
||||
(schema.exclusiveMinimum?'error_minimum_excl':'error_minimum_incl'),
|
||||
(schema.exclusiveMinimum?'edt_msg_error_minimum_excl':'edt_msg_error_minimum_incl'),
|
||||
[schema.minimum]
|
||||
)
|
||||
});
|
||||
@@ -1106,7 +1104,7 @@ JSONEditor.Validator = Class.extend({
|
||||
errors.push({
|
||||
path: path,
|
||||
property: 'maxLength',
|
||||
message: this.translate('error_maxLength', [schema.maxLength])
|
||||
message: this.translate('edt_msg_error_maxLength', [schema.maxLength])
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1117,7 +1115,7 @@ JSONEditor.Validator = Class.extend({
|
||||
errors.push({
|
||||
path: path,
|
||||
property: 'minLength',
|
||||
message: this.translate((schema.minLength===1?'error_notempty':'error_minLength'), [schema.minLength])
|
||||
message: this.translate((schema.minLength===1?'edt_msg_error_notempty':'edt_msg_error_minLength'), [schema.minLength])
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1128,7 +1126,7 @@ JSONEditor.Validator = Class.extend({
|
||||
errors.push({
|
||||
path: path,
|
||||
property: 'pattern',
|
||||
message: this.translate('error_pattern', [schema.pattern])
|
||||
message: this.translate('edt_msg_error_pattern', [schema.pattern])
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1159,7 +1157,7 @@ JSONEditor.Validator = Class.extend({
|
||||
errors.push({
|
||||
path: path,
|
||||
property: 'additionalItems',
|
||||
message: this.translate('error_additionalItems')
|
||||
message: this.translate('edt_msg_error_additionalItems')
|
||||
});
|
||||
break;
|
||||
}
|
||||
@@ -1184,7 +1182,7 @@ JSONEditor.Validator = Class.extend({
|
||||
errors.push({
|
||||
path: path,
|
||||
property: 'maxItems',
|
||||
message: this.translate('error_maxItems', [schema.maxItems])
|
||||
message: this.translate('edt_msg_error_maxItems', [schema.maxItems])
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1195,7 +1193,7 @@ JSONEditor.Validator = Class.extend({
|
||||
errors.push({
|
||||
path: path,
|
||||
property: 'minItems',
|
||||
message: this.translate('error_minItems', [schema.minItems])
|
||||
message: this.translate('edt_msg_error_minItems', [schema.minItems])
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1209,7 +1207,7 @@ JSONEditor.Validator = Class.extend({
|
||||
errors.push({
|
||||
path: path,
|
||||
property: 'uniqueItems',
|
||||
message: this.translate('error_uniqueItems')
|
||||
message: this.translate('edt_msg_error_uniqueItems')
|
||||
});
|
||||
break;
|
||||
}
|
||||
@@ -1230,7 +1228,7 @@ JSONEditor.Validator = Class.extend({
|
||||
errors.push({
|
||||
path: path,
|
||||
property: 'maxProperties',
|
||||
message: this.translate('error_maxProperties', [schema.maxProperties])
|
||||
message: this.translate('edt_msg_error_maxProperties', [schema.maxProperties])
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1246,7 +1244,7 @@ JSONEditor.Validator = Class.extend({
|
||||
errors.push({
|
||||
path: path,
|
||||
property: 'minProperties',
|
||||
message: this.translate('error_minProperties', [schema.minProperties])
|
||||
message: this.translate('edt_msg_error_minProperties', [schema.minProperties])
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1258,7 +1256,7 @@ JSONEditor.Validator = Class.extend({
|
||||
errors.push({
|
||||
path: path,
|
||||
property: 'required',
|
||||
message: this.translate('error_required', [schema.required[i]])
|
||||
message: this.translate('edt_msg_error_required', [schema.required[i]])
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1307,7 +1305,7 @@ JSONEditor.Validator = Class.extend({
|
||||
errors.push({
|
||||
path: path,
|
||||
property: 'additionalProperties',
|
||||
message: this.translate('error_additional_properties', [i])
|
||||
message: this.translate('edt_msg_error_additional_properties', [i])
|
||||
});
|
||||
break;
|
||||
}
|
||||
@@ -1339,7 +1337,7 @@ JSONEditor.Validator = Class.extend({
|
||||
errors.push({
|
||||
path: path,
|
||||
property: 'dependencies',
|
||||
message: this.translate('error_dependency', [schema.dependencies[i][j]])
|
||||
message: this.translate('edt_msg_error_dependency', [schema.dependencies[i][j]])
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1767,7 +1765,13 @@ JSONEditor.AbstractEditor = Class.extend({
|
||||
return null;
|
||||
},
|
||||
getTitle: function() {
|
||||
return this.schema.title || this.key;
|
||||
if (this.schema.title == null)
|
||||
return this.key;
|
||||
else
|
||||
return $.i18n(this.schema.title);
|
||||
},
|
||||
getAppend: function() {
|
||||
return $.i18n(this.schema.append);
|
||||
},
|
||||
enable: function() {
|
||||
this.disabled = false;
|
||||
@@ -1938,7 +1942,7 @@ JSONEditor.defaults.editors.string = JSONEditor.AbstractEditor.extend({
|
||||
var self = this, i;
|
||||
if(!this.options.compact) this.header = this.label = this.theme.getFormInputLabel(this.getTitle());
|
||||
if(this.schema.description) this.description = this.theme.getFormInputDescription(this.schema.description);
|
||||
if(this.schema.append) this.append = this.theme.getFormInputAppend(this.schema.append);
|
||||
if(this.schema.append) this.append = this.theme.getFormInputAppend(this.getAppend());
|
||||
|
||||
this.format = this.schema.format;
|
||||
if(!this.format && this.schema.media && this.schema.media.type) {
|
||||
@@ -2764,7 +2768,7 @@ JSONEditor.defaults.editors.object = JSONEditor.AbstractEditor.extend({
|
||||
|
||||
// Show/Hide button
|
||||
this.collapsed = false;
|
||||
this.toggle_button = this.getButton('','collapse',this.translate('button_collapse'));
|
||||
this.toggle_button = this.getButton('','collapse',this.translate('edt_msg_button_collapse'));
|
||||
this.title_controls.appendChild(this.toggle_button);
|
||||
this.toggle_button.addEventListener('click',function(e) {
|
||||
e.preventDefault();
|
||||
@@ -2772,12 +2776,12 @@ JSONEditor.defaults.editors.object = JSONEditor.AbstractEditor.extend({
|
||||
if(self.collapsed) {
|
||||
self.editor_holder.style.display = '';
|
||||
self.collapsed = false;
|
||||
self.setButtonText(self.toggle_button,'','collapse',self.translate('button_collapse'));
|
||||
self.setButtonText(self.toggle_button,'','collapse',self.translate('edt_msg_button_collapse'));
|
||||
}
|
||||
else {
|
||||
self.editor_holder.style.display = 'none';
|
||||
self.collapsed = true;
|
||||
self.setButtonText(self.toggle_button,'','expand',self.translate('button_expand'));
|
||||
self.setButtonText(self.toggle_button,'','expand',self.translate('edt_msg_button_expand'));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -3376,7 +3380,10 @@ JSONEditor.defaults.editors.array = JSONEditor.AbstractEditor.extend({
|
||||
if(!this.item_title) {
|
||||
if(this.schema.items && !Array.isArray(this.schema.items)) {
|
||||
var tmp = this.jsoneditor.expandRefs(this.schema.items);
|
||||
this.item_title = tmp.title || 'item';
|
||||
if (typeof tmp.title == 'undefined')
|
||||
this.item_title = 'item';
|
||||
else
|
||||
this.item_title = $.i18n(tmp.title);
|
||||
}
|
||||
else {
|
||||
this.item_title = 'item';
|
||||
@@ -3429,7 +3436,7 @@ JSONEditor.defaults.editors.array = JSONEditor.AbstractEditor.extend({
|
||||
var item_info = this.getItemInfo(i);
|
||||
var schema = this.getItemSchema(i);
|
||||
schema = this.jsoneditor.expandRefs(schema);
|
||||
schema.title = item_info.title+' '+(i+1);
|
||||
schema.title = $.i18n(item_info.title)+' '+(i+1);
|
||||
|
||||
var editor = this.jsoneditor.getEditorClass(schema);
|
||||
|
||||
@@ -3712,7 +3719,7 @@ JSONEditor.defaults.editors.array = JSONEditor.AbstractEditor.extend({
|
||||
|
||||
// Buttons to delete row, move row up, and move row down
|
||||
if(!self.hide_delete_buttons) {
|
||||
self.rows[i].delete_button = this.getButton(self.getItemTitle(),'delete',this.translate('button_delete_row_title',[self.getItemTitle()]));
|
||||
self.rows[i].delete_button = this.getButton(self.getItemTitle(),'delete',this.translate('edt_msg_button_delete_row_title',[self.getItemTitle()]));
|
||||
self.rows[i].delete_button.className += ' delete';
|
||||
self.rows[i].delete_button.setAttribute('data-i',i);
|
||||
self.rows[i].delete_button.addEventListener('click',function(e) {
|
||||
@@ -3754,7 +3761,7 @@ JSONEditor.defaults.editors.array = JSONEditor.AbstractEditor.extend({
|
||||
}
|
||||
|
||||
if(i && !self.hide_move_buttons) {
|
||||
self.rows[i].moveup_button = this.getButton('','moveup',this.translate('button_move_up_title'));
|
||||
self.rows[i].moveup_button = this.getButton('','moveup',this.translate('edt_msg_button_move_up_title'));
|
||||
self.rows[i].moveup_button.className += ' moveup';
|
||||
self.rows[i].moveup_button.setAttribute('data-i',i);
|
||||
self.rows[i].moveup_button.addEventListener('click',function(e) {
|
||||
@@ -3781,7 +3788,7 @@ JSONEditor.defaults.editors.array = JSONEditor.AbstractEditor.extend({
|
||||
}
|
||||
|
||||
if(!self.hide_move_buttons) {
|
||||
self.rows[i].movedown_button = this.getButton('','movedown',this.translate('button_move_down_title'));
|
||||
self.rows[i].movedown_button = this.getButton('','movedown',this.translate('edt_msg_button_move_down_title'));
|
||||
self.rows[i].movedown_button.className += ' movedown';
|
||||
self.rows[i].movedown_button.setAttribute('data-i',i);
|
||||
self.rows[i].movedown_button.addEventListener('click',function(e) {
|
||||
@@ -3813,7 +3820,7 @@ JSONEditor.defaults.editors.array = JSONEditor.AbstractEditor.extend({
|
||||
var self = this;
|
||||
|
||||
this.collapsed = false;
|
||||
this.toggle_button = this.getButton('','collapse',this.translate('button_collapse'));
|
||||
this.toggle_button = this.getButton('','collapse',this.translate('edt_msg_button_collapse'));
|
||||
this.title_controls.appendChild(this.toggle_button);
|
||||
var row_holder_display = self.row_holder.style.display;
|
||||
var controls_display = self.controls.style.display;
|
||||
@@ -3826,7 +3833,7 @@ JSONEditor.defaults.editors.array = JSONEditor.AbstractEditor.extend({
|
||||
self.row_holder.style.display = row_holder_display;
|
||||
if(self.tabs_holder) self.tabs_holder.style.display = '';
|
||||
self.controls.style.display = controls_display;
|
||||
self.setButtonText(this,'','collapse',self.translate('button_collapse'));
|
||||
self.setButtonText(this,'','collapse',self.translate('edt_msg_button_collapse'));
|
||||
}
|
||||
else {
|
||||
self.collapsed = true;
|
||||
@@ -3834,7 +3841,7 @@ JSONEditor.defaults.editors.array = JSONEditor.AbstractEditor.extend({
|
||||
if(self.tabs_holder) self.tabs_holder.style.display = 'none';
|
||||
self.controls.style.display = 'none';
|
||||
if(self.panel) self.panel.style.display = 'none';
|
||||
self.setButtonText(this,'','expand',self.translate('button_expand'));
|
||||
self.setButtonText(this,'','expand',self.translate('edt_msg_button_expand'));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -3852,7 +3859,7 @@ JSONEditor.defaults.editors.array = JSONEditor.AbstractEditor.extend({
|
||||
}
|
||||
|
||||
// Add "new row" and "delete last" buttons below editor
|
||||
this.add_row_button = this.getButton(this.getItemTitle(),'add',this.translate('button_add_row_title',[this.getItemTitle()]));
|
||||
this.add_row_button = this.getButton(this.getItemTitle(),'add',this.translate('edt_msg_button_add_row_title',[this.getItemTitle()]));
|
||||
|
||||
this.add_row_button.addEventListener('click',function(e) {
|
||||
e.preventDefault();
|
||||
@@ -3875,7 +3882,7 @@ JSONEditor.defaults.editors.array = JSONEditor.AbstractEditor.extend({
|
||||
});
|
||||
self.controls.appendChild(this.add_row_button);
|
||||
|
||||
this.delete_last_row_button = this.getButton(this.translate('button_delete_last',[this.getItemTitle()]),'delete',this.translate('button_delete_last_title',[this.getItemTitle()]));
|
||||
this.delete_last_row_button = this.getButton(this.translate('edt_msg_button_delete_last',[this.getItemTitle()]),'delete',this.translate('edt_msg_button_delete_last_title',[this.getItemTitle()]));
|
||||
this.delete_last_row_button.addEventListener('click',function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
@@ -3894,7 +3901,7 @@ JSONEditor.defaults.editors.array = JSONEditor.AbstractEditor.extend({
|
||||
});
|
||||
self.controls.appendChild(this.delete_last_row_button);
|
||||
|
||||
this.remove_all_rows_button = this.getButton(this.translate('button_delete_all'),'delete',this.translate('button_delete_all_title'));
|
||||
this.remove_all_rows_button = this.getButton(this.translate('edt_msg_button_delete_all'),'delete',this.translate('edt_msg_button_delete_all_title'));
|
||||
this.remove_all_rows_button.addEventListener('click',function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
@@ -4010,7 +4017,7 @@ JSONEditor.defaults.editors.table = JSONEditor.defaults.editors.array.extend({
|
||||
this.container.appendChild(this.description);
|
||||
}
|
||||
if(this.schema.append) {
|
||||
this.append = this.theme.getAppend(this.schema.append);
|
||||
this.append = this.theme.getAppend(this.getAppend());
|
||||
this.container.appendChild(this.append);
|
||||
}
|
||||
this.panel = this.theme.getIndentedPanel();
|
||||
@@ -4284,7 +4291,7 @@ JSONEditor.defaults.editors.table = JSONEditor.defaults.editors.array.extend({
|
||||
|
||||
// Buttons to delete row, move row up, and move row down
|
||||
if(!this.hide_delete_buttons) {
|
||||
self.rows[i].delete_button = this.getButton('','delete',this.translate('button_delete_row_title_short'));
|
||||
self.rows[i].delete_button = this.getButton('','delete',this.translate('edt_msg_button_delete_row_title_short'));
|
||||
self.rows[i].delete_button.className += ' delete';
|
||||
self.rows[i].delete_button.setAttribute('data-i',i);
|
||||
self.rows[i].delete_button.addEventListener('click',function(e) {
|
||||
@@ -4307,7 +4314,7 @@ JSONEditor.defaults.editors.table = JSONEditor.defaults.editors.array.extend({
|
||||
|
||||
|
||||
if(i && !this.hide_move_buttons) {
|
||||
self.rows[i].moveup_button = this.getButton('','moveup',this.translate('button_move_up_title'));
|
||||
self.rows[i].moveup_button = this.getButton('','moveup',this.translate('edt_msg_button_move_up_title'));
|
||||
self.rows[i].moveup_button.className += ' moveup';
|
||||
self.rows[i].moveup_button.setAttribute('data-i',i);
|
||||
self.rows[i].moveup_button.addEventListener('click',function(e) {
|
||||
@@ -4328,7 +4335,7 @@ JSONEditor.defaults.editors.table = JSONEditor.defaults.editors.array.extend({
|
||||
}
|
||||
|
||||
if(!this.hide_move_buttons) {
|
||||
self.rows[i].movedown_button = this.getButton('','movedown',this.translate('button_move_down_title'));
|
||||
self.rows[i].movedown_button = this.getButton('','movedown',this.translate('edt_msg_button_move_down_title'));
|
||||
self.rows[i].movedown_button.className += ' movedown';
|
||||
self.rows[i].movedown_button.setAttribute('data-i',i);
|
||||
self.rows[i].movedown_button.addEventListener('click',function(e) {
|
||||
@@ -4353,7 +4360,7 @@ JSONEditor.defaults.editors.table = JSONEditor.defaults.editors.array.extend({
|
||||
var self = this;
|
||||
|
||||
this.collapsed = false;
|
||||
this.toggle_button = this.getButton('','collapse',this.translate('button_collapse'));
|
||||
this.toggle_button = this.getButton('','collapse',this.translate('edt_msg_button_collapse'));
|
||||
if(this.title_controls) {
|
||||
this.title_controls.appendChild(this.toggle_button);
|
||||
this.toggle_button.addEventListener('click',function(e) {
|
||||
@@ -4363,12 +4370,12 @@ JSONEditor.defaults.editors.table = JSONEditor.defaults.editors.array.extend({
|
||||
if(self.collapsed) {
|
||||
self.collapsed = false;
|
||||
self.panel.style.display = '';
|
||||
self.setButtonText(this,'','collapse',self.translate('button_collapse'));
|
||||
self.setButtonText(this,'','collapse',self.translate('edt_msg_button_collapse'));
|
||||
}
|
||||
else {
|
||||
self.collapsed = true;
|
||||
self.panel.style.display = 'none';
|
||||
self.setButtonText(this,'','expand',self.translate('button_expand'));
|
||||
self.setButtonText(this,'','expand',self.translate('edt_msg_button_expand'));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -4387,7 +4394,7 @@ JSONEditor.defaults.editors.table = JSONEditor.defaults.editors.array.extend({
|
||||
}
|
||||
|
||||
// Add "new row" and "delete last" buttons below editor
|
||||
this.add_row_button = this.getButton(this.getItemTitle(),'add',this.translate('button_add_row_title',[this.getItemTitle()]));
|
||||
this.add_row_button = this.getButton(this.getItemTitle(),'add',this.translate('edt_msg_button_add_row_title',[this.getItemTitle()]));
|
||||
this.add_row_button.addEventListener('click',function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
@@ -4399,7 +4406,7 @@ JSONEditor.defaults.editors.table = JSONEditor.defaults.editors.array.extend({
|
||||
});
|
||||
self.controls.appendChild(this.add_row_button);
|
||||
|
||||
this.delete_last_row_button = this.getButton(this.translate('button_delete_last',[this.getItemTitle()]),'delete',this.translate('button_delete_last_title',[this.getItemTitle()]));
|
||||
this.delete_last_row_button = this.getButton(this.translate('edt_msg_button_delete_last',[this.getItemTitle()]),'delete',this.translate('edt_msg_button_delete_last_title',[this.getItemTitle()]));
|
||||
this.delete_last_row_button.addEventListener('click',function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
@@ -4411,7 +4418,7 @@ JSONEditor.defaults.editors.table = JSONEditor.defaults.editors.array.extend({
|
||||
});
|
||||
self.controls.appendChild(this.delete_last_row_button);
|
||||
|
||||
this.remove_all_rows_button = this.getButton(this.translate('button_delete_all'),'delete',this.translate('button_delete_all_title'));
|
||||
this.remove_all_rows_button = this.getButton(this.translate('edt_msg_button_delete_all'),'delete',this.translate('edt_msg_button_delete_all_title'));
|
||||
this.remove_all_rows_button.addEventListener('click',function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
@@ -4998,7 +5005,7 @@ JSONEditor.defaults.editors.select = JSONEditor.AbstractEditor.extend({
|
||||
var self = this;
|
||||
if(!this.options.compact) this.header = this.label = this.theme.getFormInputLabel(this.getTitle());
|
||||
if(this.schema.description) this.description = this.theme.getFormInputDescription(this.schema.description);
|
||||
if(this.schema.append) this.append = this.theme.getFormInputAppend(this.schema.append);
|
||||
if(this.schema.append) this.append = this.theme.getFormInputAppend(this.getAppend());
|
||||
|
||||
if(this.options.compact) this.container.className += ' compact';
|
||||
|
||||
@@ -5345,7 +5352,7 @@ JSONEditor.defaults.editors.selectize = JSONEditor.AbstractEditor.extend({
|
||||
var self = this;
|
||||
if(!this.options.compact) this.header = this.label = this.theme.getFormInputLabel(this.getTitle());
|
||||
if(this.schema.description) this.description = this.theme.getFormInputDescription(this.schema.description);
|
||||
if(this.schema.append) this.append = this.theme.getFormInputAppend(this.schema.append);
|
||||
if(this.schema.append) this.append = this.theme.getFormInputAppend(this.getAppend());
|
||||
|
||||
if(this.options.compact) this.container.className += ' compact';
|
||||
|
||||
@@ -5573,7 +5580,7 @@ JSONEditor.defaults.editors.multiselect = JSONEditor.AbstractEditor.extend({
|
||||
var self = this, i;
|
||||
if(!this.options.compact) this.header = this.label = this.theme.getFormInputLabel(this.getTitle());
|
||||
if(this.schema.description) this.description = this.theme.getFormInputDescription(this.schema.description);
|
||||
if(this.schema.append) this.append = this.theme.getFormInputAppend(this.schema.append);
|
||||
if(this.schema.append) this.append = this.theme.getFormInputAppend(this.getAppend());
|
||||
|
||||
if((!this.schema.format && this.option_keys.length < 8) || this.schema.format === "checkbox") {
|
||||
this.input_type = 'checkboxes';
|
||||
@@ -6053,7 +6060,7 @@ JSONEditor.defaults.editors.arraySelectize = JSONEditor.AbstractEditor.extend({
|
||||
this.description = this.theme.getDescription(this.schema.description);
|
||||
}
|
||||
if(this.schema.append) {
|
||||
this.append = this.theme.getAppend(this.schema.append);
|
||||
this.append = this.theme.getAppend(this.getAppend());
|
||||
}
|
||||
|
||||
this.input = document.createElement('select');
|
||||
@@ -6879,200 +6886,10 @@ JSONEditor.defaults.template = 'default';
|
||||
JSONEditor.defaults.options = {};
|
||||
|
||||
// String translate function
|
||||
JSONEditor.defaults.translate = function(key, variables) {
|
||||
var lang = JSONEditor.defaults.languages[JSONEditor.defaults.language];
|
||||
if(!lang) throw "Unknown language "+JSONEditor.defaults.language;
|
||||
|
||||
var string = lang[key] || JSONEditor.defaults.languages[JSONEditor.defaults.default_language][key];
|
||||
|
||||
if(typeof string === "undefined") throw "Unknown translate string "+key;
|
||||
|
||||
if(variables) {
|
||||
for(var i=0; i<variables.length; i++) {
|
||||
string = string.replace(new RegExp('\\{\\{'+i+'}}','g'),variables[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return string;
|
||||
};
|
||||
|
||||
// Translation strings and default languages
|
||||
JSONEditor.defaults.default_language = 'en';
|
||||
JSONEditor.defaults.language = JSONEditor.defaults.default_language;
|
||||
JSONEditor.defaults.languages.en = {
|
||||
/**
|
||||
* When a property is not set
|
||||
*/
|
||||
error_notset: "Property must be set",
|
||||
/**
|
||||
* When a string must not be empty
|
||||
*/
|
||||
error_notempty: "Value required",
|
||||
/**
|
||||
* When a value is not one of the enumerated values
|
||||
*/
|
||||
error_enum: "Value must be one of the enumerated values",
|
||||
/**
|
||||
* When a value doesn't validate any schema of a 'anyOf' combination
|
||||
*/
|
||||
error_anyOf: "Value must validate against at least one of the provided schemas",
|
||||
/**
|
||||
* When a value doesn't validate
|
||||
* @variables This key takes one variable: The number of schemas the value does not validate
|
||||
*/
|
||||
error_oneOf: 'Value must validate against exactly one of the provided schemas. It currently validates against {{0}} of the schemas.',
|
||||
/**
|
||||
* When a value does not validate a 'not' schema
|
||||
*/
|
||||
error_not: "Value must not validate against the provided schema",
|
||||
/**
|
||||
* When a value does not match any of the provided types
|
||||
*/
|
||||
error_type_union: "Value must be one of the provided types",
|
||||
/**
|
||||
* When a value does not match the given type
|
||||
* @variables This key takes one variable: The type the value should be of
|
||||
*/
|
||||
error_type: "Value must be of type {{0}}",
|
||||
/**
|
||||
* When the value validates one of the disallowed types
|
||||
*/
|
||||
error_disallow_union: "Value must not be one of the provided disallowed types",
|
||||
/**
|
||||
* When the value validates a disallowed type
|
||||
* @variables This key takes one variable: The type the value should not be of
|
||||
*/
|
||||
error_disallow: "Value must not be of type {{0}}",
|
||||
/**
|
||||
* When a value is not a multiple of or divisible by a given number
|
||||
* @variables This key takes one variable: The number mentioned above
|
||||
*/
|
||||
error_multipleOf: "Value must be a multiple of {{0}}",
|
||||
/**
|
||||
* When a value is greater than it's supposed to be (exclusive)
|
||||
* @variables This key takes one variable: The maximum
|
||||
*/
|
||||
error_maximum_excl: "Value must be less than {{0}}",
|
||||
/**
|
||||
* When a value is greater than it's supposed to be (inclusive
|
||||
* @variables This key takes one variable: The maximum
|
||||
*/
|
||||
error_maximum_incl: "Value must be at most {{0}}",
|
||||
/**
|
||||
* When a value is lesser than it's supposed to be (exclusive)
|
||||
* @variables This key takes one variable: The minimum
|
||||
*/
|
||||
error_minimum_excl: "Value must be greater than {{0}}",
|
||||
/**
|
||||
* When a value is lesser than it's supposed to be (inclusive)
|
||||
* @variables This key takes one variable: The minimum
|
||||
*/
|
||||
error_minimum_incl: "Value must be at least {{0}}",
|
||||
/**
|
||||
* When a value have too many characters
|
||||
* @variables This key takes one variable: The maximum character count
|
||||
*/
|
||||
error_maxLength: "Value must be at most {{0}} characters long",
|
||||
/**
|
||||
* When a value does not have enough characters
|
||||
* @variables This key takes one variable: The minimum character count
|
||||
*/
|
||||
error_minLength: "Value must be at least {{0}} characters long",
|
||||
/**
|
||||
* When a value does not match a given pattern
|
||||
*/
|
||||
error_pattern: "Value must match the pattern {{0}}",
|
||||
/**
|
||||
* When an array has additional items whereas it is not supposed to
|
||||
*/
|
||||
error_additionalItems: "No additional items allowed in this array",
|
||||
/**
|
||||
* When there are to many items in an array
|
||||
* @variables This key takes one variable: The maximum item count
|
||||
*/
|
||||
error_maxItems: "Value must have at most {{0}} items",
|
||||
/**
|
||||
* When there are not enough items in an array
|
||||
* @variables This key takes one variable: The minimum item count
|
||||
*/
|
||||
error_minItems: "Value must have at least {{0}} items",
|
||||
/**
|
||||
* When an array is supposed to have unique items but has duplicates
|
||||
*/
|
||||
error_uniqueItems: "Array must have unique items",
|
||||
/**
|
||||
* When there are too many properties in an object
|
||||
* @variables This key takes one variable: The maximum property count
|
||||
*/
|
||||
error_maxProperties: "Object must have at most {{0}} properties",
|
||||
/**
|
||||
* When there are not enough properties in an object
|
||||
* @variables This key takes one variable: The minimum property count
|
||||
*/
|
||||
error_minProperties: "Object must have at least {{0}} properties",
|
||||
/**
|
||||
* When a required property is not defined
|
||||
* @variables This key takes one variable: The name of the missing property
|
||||
*/
|
||||
error_required: "Object is missing the required property '{{0}}'",
|
||||
/**
|
||||
* When there is an additional property is set whereas there should be none
|
||||
* @variables This key takes one variable: The name of the additional property
|
||||
*/
|
||||
error_additional_properties: "No additional properties allowed, but property {{0}} is set",
|
||||
/**
|
||||
* When a dependency is not resolved
|
||||
* @variables This key takes one variable: The name of the missing property for the dependency
|
||||
*/
|
||||
error_dependency: "Must have property {{0}}",
|
||||
/**
|
||||
* Text on Delete All buttons
|
||||
*/
|
||||
button_delete_all: "All",
|
||||
/**
|
||||
* Title on Delete All buttons
|
||||
*/
|
||||
button_delete_all_title: "Delete All",
|
||||
/**
|
||||
* Text on Delete Last buttons
|
||||
* @variable This key takes one variable: The title of object to delete
|
||||
*/
|
||||
button_delete_last: "Last {{0}}",
|
||||
/**
|
||||
* Title on Delete Last buttons
|
||||
* @variable This key takes one variable: The title of object to delete
|
||||
*/
|
||||
button_delete_last_title: "Delete Last {{0}}",
|
||||
/**
|
||||
* Title on Add Row buttons
|
||||
* @variable This key takes one variable: The title of object to add
|
||||
*/
|
||||
button_add_row_title: "Add {{0}}",
|
||||
/**
|
||||
* Title on Move Down buttons
|
||||
*/
|
||||
button_move_down_title: "Move down",
|
||||
/**
|
||||
* Title on Move Up buttons
|
||||
*/
|
||||
button_move_up_title: "Move up",
|
||||
/**
|
||||
* Title on Delete Row buttons
|
||||
* @variable This key takes one variable: The title of object to delete
|
||||
*/
|
||||
button_delete_row_title: "Delete {{0}}",
|
||||
/**
|
||||
* Title on Delete Row buttons, short version (no parameter with the object title)
|
||||
*/
|
||||
button_delete_row_title_short: "Delete",
|
||||
/**
|
||||
* Title on Collapse buttons
|
||||
*/
|
||||
button_collapse: "Collapse",
|
||||
/**
|
||||
* Title on Expand buttons
|
||||
*/
|
||||
button_expand: "Expand"
|
||||
JSONEditor.defaults.translate = function(key, variables) {
|
||||
|
||||
return $.i18n(key, variables);
|
||||
|
||||
};
|
||||
|
||||
// Miscellaneous Plugin Settings
|
||||
|
Reference in New Issue
Block a user