mirror of
				https://github.com/MichMich/MagicMirror.git
				synced 2025-10-31 10:48:10 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			211 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			211 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /* exported Translator */
 | |
| /* Magic Mirror
 | |
|  * Translator (l10n)
 | |
|  *
 | |
|  * By Christopher Fenner http://github.com/CFenner
 | |
|  * MIT Licensed.
 | |
|  */
 | |
| var Translator = (function() {
 | |
| 
 | |
| 	/* loadJSON(file, callback)
 | |
| 	 * Load a JSON file via XHR.
 | |
| 	 *
 | |
| 	 * argument file string - Path of the file we want to load.
 | |
| 	 * argument callback function - Function called when done.
 | |
| 	 */
 | |
| 	function loadJSON(file, callback) {
 | |
| 		var xhr = new XMLHttpRequest();
 | |
| 		xhr.overrideMimeType("application/json");
 | |
| 		xhr.open("GET", file, true);
 | |
| 		xhr.onreadystatechange = function () {
 | |
| 			if (xhr.readyState == 4 && xhr.status == "200") {
 | |
| 				callback(JSON.parse(stripComments(xhr.responseText)));
 | |
| 			}
 | |
| 		};
 | |
| 		xhr.send(null);
 | |
| 	}
 | |
| 
 | |
| 	/* loadJSON(str, options)
 | |
| 	 * Remove any commenting from a json file so it can be parsed.
 | |
| 	 *
 | |
| 	 * argument str string - The string that contains json with comments.
 | |
| 	 * argument opts function - Strip options.
 | |
| 	 *
 | |
| 	 * return the stripped string.
 | |
| 	 */
 | |
| 	function stripComments(str, opts) {
 | |
| 		// strip comments copied from: https://github.com/sindresorhus/strip-json-comments
 | |
| 
 | |
| 		var singleComment = 1;
 | |
| 		var multiComment = 2;
 | |
| 
 | |
| 		function stripWithoutWhitespace() {
 | |
| 			return "";
 | |
| 		}
 | |
| 
 | |
| 		function stripWithWhitespace(str, start, end) {
 | |
| 			return str.slice(start, end).replace(/\S/g, " ");
 | |
| 		}
 | |
| 
 | |
| 		opts = opts || {};
 | |
| 
 | |
| 		var currentChar;
 | |
| 		var nextChar;
 | |
| 		var insideString = false;
 | |
| 		var insideComment = false;
 | |
| 		var offset = 0;
 | |
| 		var ret = "";
 | |
| 		var strip = opts.whitespace === false ? stripWithoutWhitespace : stripWithWhitespace;
 | |
| 
 | |
| 		for (var i = 0; i < str.length; i++) {
 | |
| 			currentChar = str[i];
 | |
| 			nextChar = str[i + 1];
 | |
| 
 | |
| 			if (!insideComment && currentChar === "\"") {
 | |
| 				var escaped = str[i - 1] === "\\" && str[i - 2] !== "\\";
 | |
| 				if (!escaped) {
 | |
| 					insideString = !insideString;
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			if (insideString) {
 | |
| 				continue;
 | |
| 			}
 | |
| 
 | |
| 			if (!insideComment && currentChar + nextChar === "//") {
 | |
| 				ret += str.slice(offset, i);
 | |
| 				offset = i;
 | |
| 				insideComment = singleComment;
 | |
| 				i++;
 | |
| 			} else if (insideComment === singleComment && currentChar + nextChar === "\r\n") {
 | |
| 				i++;
 | |
| 				insideComment = false;
 | |
| 				ret += strip(str, offset, i);
 | |
| 				offset = i;
 | |
| 				continue;
 | |
| 			} else if (insideComment === singleComment && currentChar === "\n") {
 | |
| 				insideComment = false;
 | |
| 				ret += strip(str, offset, i);
 | |
| 				offset = i;
 | |
| 			} else if (!insideComment && currentChar + nextChar === "/*") {
 | |
| 				ret += str.slice(offset, i);
 | |
| 				offset = i;
 | |
| 				insideComment = multiComment;
 | |
| 				i++;
 | |
| 				continue;
 | |
| 			} else if (insideComment === multiComment && currentChar + nextChar === "*/") {
 | |
| 				i++;
 | |
| 				insideComment = false;
 | |
| 				ret += strip(str, offset, i + 1);
 | |
| 				offset = i + 1;
 | |
| 				continue;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		return ret + (insideComment ? strip(str.substr(offset)) : str.substr(offset));
 | |
| 	}
 | |
| 
 | |
| 	return {
 | |
| 		coreTranslations: {},
 | |
| 		coreTranslationsFallback: {},
 | |
| 		translations: {},
 | |
| 		translationsFallback: {},
 | |
| 
 | |
| 		/* translate(module, key)
 | |
| 		 * Load a translation for a given key for a given module.
 | |
| 		 *
 | |
| 		 * argument module Module - The module to load the translation for.
 | |
| 		 * argument key string - The key of the text to translate.
 | |
| 		 */
 | |
| 		translate: function(module, key) {
 | |
| 
 | |
| 			if(this.translations[module.name] && key in this.translations[module.name]) {
 | |
| 				// Log.log("Got translation for " + key + " from module translation: ");
 | |
| 				return this.translations[module.name][key];
 | |
| 			}
 | |
| 
 | |
| 			if (key in this.coreTranslations) {
 | |
| 				// Log.log("Got translation for " + key + " from core translation.");
 | |
| 				return this.coreTranslations[key];
 | |
| 			}
 | |
| 
 | |
| 			if (this.translationsFallback[module.name] && key in this.translationsFallback[module.name]) {
 | |
| 				// Log.log("Got translation for " + key + " from module translation fallback.");
 | |
| 				return this.translationsFallback[module.name][key];
 | |
| 			}
 | |
| 
 | |
| 			if (key in this.coreTranslationsFallback) {
 | |
| 				// Log.log("Got translation for " + key + " from core translation fallback.");
 | |
| 				return this.coreTranslationsFallback[key];
 | |
| 			}
 | |
| 
 | |
| 			return key;
 | |
| 		},
 | |
| 		/* load(module, file, callback)
 | |
| 		 * Load a translation file (json) and remember the data.
 | |
| 		 *
 | |
| 		 * argument module Module - The module to load the translation file for.
 | |
| 		 * argument file string - Path of the file we want to load.
 | |
| 		 * argument callback function - Function called when done.
 | |
| 		 */
 | |
| 		load: function(module, file, isFallback, callback) {
 | |
| 			if (!isFallback) {
 | |
| 				Log.log(module.name + " - Load translation: " + file);
 | |
| 			} else {
 | |
| 				Log.log(module.name + " - Load translation fallback: " + file);
 | |
| 			}
 | |
| 
 | |
| 			var self = this;
 | |
| 			if(!this.translationsFallback[module.name]) {
 | |
| 				loadJSON(module.file(file), function(json) {
 | |
| 					if (!isFallback) {
 | |
| 						self.translations[module.name] = json;
 | |
| 					} else {
 | |
| 						self.translationsFallback[module.name] = json;
 | |
| 					}
 | |
| 					callback();
 | |
| 				});
 | |
| 			} else {
 | |
| 				callback();
 | |
| 			}
 | |
| 		},
 | |
| 
 | |
| 		/* loadCoreTranslations(lang)
 | |
| 		 * Load the core translations.
 | |
| 		 *
 | |
| 		 * argument lang String - The language identifier of the core language.
 | |
| 		 */
 | |
| 		loadCoreTranslations: function(lang) {
 | |
| 			var self = this;
 | |
| 
 | |
| 			if (lang in translations) {
 | |
| 				Log.log("Loading core translation file: " + translations[lang]);
 | |
| 				loadJSON(translations[lang], function(translations) {
 | |
| 					self.coreTranslations = translations;
 | |
| 				});
 | |
| 			} else {
 | |
| 				Log.log("Configured language not found in core translations.");
 | |
| 			}
 | |
| 
 | |
| 			self.loadCoreTranslationsFallback();
 | |
| 		},
 | |
| 
 | |
| 		/* loadCoreTranslationsFallback()
 | |
| 		 * Load the core translations fallback.
 | |
| 		 * The first language defined in translations.js will be used.
 | |
| 		 */
 | |
| 		loadCoreTranslationsFallback: function() {
 | |
| 			var self = this;
 | |
| 
 | |
| 			// The variable `first` will contain the first
 | |
| 			// defined translation after the following line.
 | |
| 			for (var first in translations) {break;}
 | |
| 
 | |
| 			Log.log("Loading core translation fallback file: " + translations[first]);
 | |
| 			loadJSON(translations[first], function(translations) {
 | |
| 				self.coreTranslationsFallback = translations;
 | |
| 			});
 | |
| 		},
 | |
| 	};
 | |
| })();
 |