254 lines
No EOL
8.2 KiB
JavaScript
254 lines
No EOL
8.2 KiB
JavaScript
/*
|
|
Copyright (c) Jim Garvin (http://github.com/coderifous), 2008.
|
|
Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
|
|
Written by Jim Garvin (@coderifous) for use on LMGTFY.com.
|
|
http://github.com/coderifous/jquery-localize
|
|
Based off of Keith Wood's Localisation jQuery plugin.
|
|
http://keith-wood.name/localisation.html
|
|
*/
|
|
(function ($) {
|
|
var normaliseLang;
|
|
normaliseLang = function (lang) {
|
|
lang = lang.replace(/_/, "-").toLowerCase();
|
|
if (lang.length > 3) {
|
|
lang = lang.substring(0, 3) + lang.substring(3).toUpperCase();
|
|
}
|
|
return lang;
|
|
};
|
|
$.defaultLanguage = normaliseLang(
|
|
navigator.languages && navigator.languages.length > 0
|
|
? navigator.languages[0]
|
|
: navigator.language || navigator.userLanguage
|
|
);
|
|
$.localize = function (pkg, options) {
|
|
var defaultCallback,
|
|
deferred,
|
|
fileExtension,
|
|
intermediateLangData,
|
|
jsonCall,
|
|
lang,
|
|
loadLanguage,
|
|
localizeElement,
|
|
localizeForLink,
|
|
localizeImageElement,
|
|
localizeInputElement,
|
|
localizeOptgroupElement,
|
|
notifyDelegateLanguageLoaded,
|
|
regexify,
|
|
setAttrFromValueForKey,
|
|
setTextFromValueForKey,
|
|
valueForKey,
|
|
wrappedSet;
|
|
if (options == null) {
|
|
options = {};
|
|
}
|
|
wrappedSet = this;
|
|
intermediateLangData = {};
|
|
fileExtension = options.fileExtension || "json";
|
|
deferred = $.Deferred();
|
|
loadLanguage = function (pkg, lang, level) {
|
|
var file;
|
|
if (level == null) {
|
|
level = 1;
|
|
}
|
|
switch (level) {
|
|
case 1:
|
|
intermediateLangData = {};
|
|
if (options.loadBase) {
|
|
file = pkg + ("." + fileExtension);
|
|
return jsonCall(file, pkg, lang, level);
|
|
} else {
|
|
return loadLanguage(pkg, lang, 2);
|
|
}
|
|
break;
|
|
case 2:
|
|
file = "" + pkg + "-" + lang.split("-")[0] + "." + fileExtension;
|
|
return jsonCall(file, pkg, lang, level);
|
|
case 3:
|
|
file =
|
|
"" +
|
|
pkg +
|
|
"-" +
|
|
lang.split("-").slice(0, 2).join("-") +
|
|
"." +
|
|
fileExtension;
|
|
return jsonCall(file, pkg, lang, level);
|
|
default:
|
|
return deferred.resolve();
|
|
}
|
|
};
|
|
jsonCall = function (file, pkg, lang, level) {
|
|
var ajaxOptions, errorFunc, successFunc;
|
|
if (options.pathPrefix != null) {
|
|
file = "" + options.pathPrefix + "/" + file;
|
|
}
|
|
successFunc = function (d) {
|
|
$.extend(intermediateLangData, d);
|
|
notifyDelegateLanguageLoaded(intermediateLangData);
|
|
return loadLanguage(pkg, lang, level + 1);
|
|
};
|
|
errorFunc = function (xhr, status, error) {
|
|
if (status === "error" && xhr.status === 404) {
|
|
// Le fichier n'existe pas
|
|
console.log("Le fichier " + file + " n'existe pas.");
|
|
} else if (level === 2 && lang.indexOf("-") > -1) {
|
|
return loadLanguage(pkg, lang, level + 1);
|
|
} else if (options.fallback && options.fallback !== lang) {
|
|
return loadLanguage(pkg, options.fallback);
|
|
}
|
|
};
|
|
ajaxOptions = {
|
|
url: file,
|
|
dataType: "json",
|
|
async: true,
|
|
timeout: options.timeout != null ? options.timeout : 500,
|
|
success: successFunc,
|
|
error: errorFunc,
|
|
statusCode: {
|
|
404: function () {
|
|
console.log("Le fichier " + file + " n'existe pas.");
|
|
},
|
|
},
|
|
};
|
|
if (window.location.protocol === "file:") {
|
|
ajaxOptions.error = function (xhr) {
|
|
return successFunc($.parseJSON(xhr.responseText));
|
|
};
|
|
}
|
|
return $.ajax(ajaxOptions);
|
|
};
|
|
notifyDelegateLanguageLoaded = function (data) {
|
|
if (options.callback != null) {
|
|
return options.callback(data, defaultCallback);
|
|
} else {
|
|
return defaultCallback(data);
|
|
}
|
|
};
|
|
defaultCallback = function (data) {
|
|
$.localize.data[pkg] = data;
|
|
return wrappedSet.each(function () {
|
|
var elem, key, value;
|
|
elem = $(this);
|
|
key = elem.data("localize");
|
|
key || (key = elem.attr("rel").match(/localize\[(.*?)\]/)[1]);
|
|
value = valueForKey(key, data);
|
|
if (value != null) {
|
|
return localizeElement(elem, key, value);
|
|
}
|
|
});
|
|
};
|
|
/*
|
|
This code is iterating over the elements in the DOM and calling a function to localize
|
|
them The first argument of this function is an element which we can use to determine
|
|
what type of element it is If it\'s an input or textarea then we call a different
|
|
function that will handle those two types of elements If it\'s an image then we call
|
|
another function that handles images If it\'s an optgroup then we call another one
|
|
for optgroups
|
|
*/
|
|
localizeElement = function (elem, key, value) {
|
|
if (elem.is("input")) {
|
|
localizeInputElement(elem, key, value);
|
|
} else if (elem.is("textarea")) {
|
|
localizeInputElement(elem, key, value);
|
|
} else if (elem.is("img")) {
|
|
localizeImageElement(elem, key, value);
|
|
} else if (elem.is("optgroup")) {
|
|
localizeOptgroupElement(elem, key, value);
|
|
} else if ($.isArray(value)) {
|
|
elem.empty();
|
|
for (const key in value) {
|
|
var converter = new showdown.Converter(),
|
|
text = value[key],
|
|
converted = converter.makeHtml(text);
|
|
elem.append(converted);
|
|
}
|
|
} else if (!$.isPlainObject(value)) {
|
|
elem.html(value);
|
|
}
|
|
if ($.isPlainObject(value)) {
|
|
if (elem.is("a")) {
|
|
localizeForLink(elem, key, value);
|
|
}
|
|
//TODO:make a generic object returner
|
|
return localizeForLink(elem, value);
|
|
}
|
|
};
|
|
localizeInputElement = function (elem, key, value) {
|
|
var val;
|
|
val = $.isPlainObject(value) ? value.value : value;
|
|
if (elem.is("[placeholder]")) {
|
|
return elem.attr("placeholder", val);
|
|
} else {
|
|
return elem.val(val);
|
|
}
|
|
};
|
|
localizeForLink = function (elem, value) {
|
|
setAttrFromValueForKey(elem, "title", value);
|
|
setAttrFromValueForKey(elem, "href", value);
|
|
return setTextFromValueForKey(elem, "text", value);
|
|
};
|
|
localizeOptgroupElement = function (elem, key, value) {
|
|
return elem.attr("label", value);
|
|
};
|
|
localizeImageElement = function (elem, key, value) {
|
|
setAttrFromValueForKey(elem, "alt", value);
|
|
return setAttrFromValueForKey(elem, "src", value);
|
|
};
|
|
valueForKey = function (key, data) {
|
|
var keys, value, _i, _len;
|
|
keys = key.split(/\./);
|
|
value = data;
|
|
for (_i = 0, _len = keys.length; _i < _len; _i++) {
|
|
key = keys[_i];
|
|
value = value != null ? value[key] : null;
|
|
}
|
|
return value;
|
|
};
|
|
setAttrFromValueForKey = function (elem, key, value) {
|
|
value = valueForKey(key, value);
|
|
if (value != null) {
|
|
return elem.attr(key, value);
|
|
}
|
|
};
|
|
setTextFromValueForKey = function (elem, key, value) {
|
|
value = valueForKey(key, value);
|
|
if (value != null) {
|
|
return elem.text(value);
|
|
}
|
|
};
|
|
regexify = function (string_or_regex_or_array) {
|
|
var thing;
|
|
if (typeof string_or_regex_or_array === "string") {
|
|
return "^" + string_or_regex_or_array + "$";
|
|
} else if (string_or_regex_or_array.length != null) {
|
|
return (function () {
|
|
var _i, _len, _results;
|
|
_results = [];
|
|
for (
|
|
_i = 0, _len = string_or_regex_or_array.length;
|
|
_i < _len;
|
|
_i++
|
|
) {
|
|
thing = string_or_regex_or_array[_i];
|
|
_results.push(regexify(thing));
|
|
}
|
|
return _results;
|
|
})().join("|");
|
|
} else {
|
|
return string_or_regex_or_array;
|
|
}
|
|
};
|
|
lang = normaliseLang(
|
|
options.language ? options.language : $.defaultLanguage
|
|
);
|
|
if (options.skipLanguage && lang.match(regexify(options.skipLanguage))) {
|
|
deferred.resolve();
|
|
} else {
|
|
loadLanguage(pkg, lang, 1);
|
|
}
|
|
wrappedSet.localizePromise = deferred;
|
|
return wrappedSet;
|
|
};
|
|
$.fn.localize = $.localize;
|
|
return ($.localize.data = {});
|
|
})(jQuery); |