| 
									
										
										
										
											2020-05-03 18:59:26 +02:00
										 |  |  | /* global translations */ | 
					
						
							| 
									
										
										
										
											2020-04-21 07:36:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-21 01:03:26 +02:00
										 |  |  | /* Magic Mirror | 
					
						
							|  |  |  |  * Translator (l10n) | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2020-04-28 23:05:28 +02:00
										 |  |  |  * By Christopher Fenner https://github.com/CFenner
 | 
					
						
							| 
									
										
										
										
											2016-04-21 01:03:26 +02:00
										 |  |  |  * MIT Licensed. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2020-05-11 22:22:32 +02:00
										 |  |  | var Translator = (function () { | 
					
						
							| 
									
										
										
										
											2020-07-27 14:24:30 +02:00
										 |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2016-05-11 12:38:41 +02:00
										 |  |  | 	 * Load a JSON file via XHR. | 
					
						
							|  |  |  | 	 * | 
					
						
							| 
									
										
										
										
											2020-07-27 14:24:30 +02:00
										 |  |  | 	 * @param {string} file Path of the file we want to load. | 
					
						
							|  |  |  | 	 * @param {Function} callback Function called when done. | 
					
						
							| 
									
										
										
										
											2016-05-11 12:38:41 +02:00
										 |  |  | 	 */ | 
					
						
							|  |  |  | 	function loadJSON(file, callback) { | 
					
						
							|  |  |  | 		var xhr = new XMLHttpRequest(); | 
					
						
							|  |  |  | 		xhr.overrideMimeType("application/json"); | 
					
						
							|  |  |  | 		xhr.open("GET", file, true); | 
					
						
							|  |  |  | 		xhr.onreadystatechange = function () { | 
					
						
							| 
									
										
										
										
											2019-06-05 08:55:17 +02:00
										 |  |  | 			if (xhr.readyState === 4 && xhr.status === 200) { | 
					
						
							| 
									
										
										
										
											2020-10-04 12:13:08 -05:00
										 |  |  | 				// needs error handler try/catch at least
 | 
					
						
							|  |  |  | 				let fileinfo = null; | 
					
						
							|  |  |  | 				try { | 
					
						
							|  |  |  | 					fileinfo = JSON.parse(xhr.responseText); | 
					
						
							|  |  |  | 				} catch (exception) { | 
					
						
							|  |  |  | 					// nothing here, but don't die
 | 
					
						
							| 
									
										
										
										
											2020-10-05 10:45:07 -05:00
										 |  |  | 					Log.error(" loading json file =" + file + " failed"); | 
					
						
							| 
									
										
										
										
											2020-10-04 12:13:08 -05:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				callback(fileinfo); | 
					
						
							| 
									
										
										
										
											2016-05-11 12:38:41 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 		xhr.send(null); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-21 01:03:26 +02:00
										 |  |  | 	return { | 
					
						
							| 
									
										
										
										
											2016-05-11 12:38:41 +02:00
										 |  |  | 		coreTranslations: {}, | 
					
						
							|  |  |  | 		coreTranslationsFallback: {}, | 
					
						
							| 
									
										
										
										
											2016-04-21 01:03:26 +02:00
										 |  |  | 		translations: {}, | 
					
						
							| 
									
										
										
										
											2016-05-11 12:38:41 +02:00
										 |  |  | 		translationsFallback: {}, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-27 14:26:01 +02:00
										 |  |  | 		/** | 
					
						
							| 
									
										
										
										
											2016-04-21 01:03:26 +02:00
										 |  |  | 		 * Load a translation for a given key for a given module. | 
					
						
							|  |  |  | 		 * | 
					
						
							| 
									
										
										
										
											2020-08-01 16:31:42 +02:00
										 |  |  | 		 * @param {Module} module The module to load the translation for. | 
					
						
							| 
									
										
										
										
											2020-07-27 14:26:01 +02:00
										 |  |  | 		 * @param {string} key The key of the text to translate. | 
					
						
							|  |  |  | 		 * @param {object} variables The variables to use within the translation template (optional) | 
					
						
							|  |  |  | 		 * @returns {string} the translated key | 
					
						
							| 
									
										
										
										
											2016-04-21 01:03:26 +02:00
										 |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2020-05-11 22:22:32 +02:00
										 |  |  | 		translate: function (module, key, variables) { | 
					
						
							| 
									
										
										
										
											2017-04-25 23:15:34 +03:00
										 |  |  | 			variables = variables || {}; //Empty object by default
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-27 14:24:30 +02:00
										 |  |  | 			/** | 
					
						
							|  |  |  | 			 * Combines template and variables like: | 
					
						
							|  |  |  | 			 * template: "Please wait for {timeToWait} before continuing with {work}." | 
					
						
							|  |  |  | 			 * variables: {timeToWait: "2 hours", work: "painting"} | 
					
						
							|  |  |  | 			 * to: "Please wait for 2 hours before continuing with painting." | 
					
						
							|  |  |  | 			 * | 
					
						
							| 
									
										
										
										
											2020-07-27 14:26:01 +02:00
										 |  |  | 			 * @param {string} template Text with placeholder | 
					
						
							|  |  |  | 			 * @param {object} variables Variables for the placeholder | 
					
						
							|  |  |  | 			 * @returns {string} the template filled with the variables | 
					
						
							| 
									
										
										
										
											2020-07-27 14:24:30 +02:00
										 |  |  | 			 */ | 
					
						
							| 
									
										
										
										
											2017-04-25 23:15:34 +03:00
										 |  |  | 			function createStringFromTemplate(template, variables) { | 
					
						
							| 
									
										
										
										
											2020-05-11 22:22:32 +02:00
										 |  |  | 				if (Object.prototype.toString.call(template) !== "[object String]") { | 
					
						
							| 
									
										
										
										
											2018-02-23 11:51:59 +01:00
										 |  |  | 					return template; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2020-05-11 22:22:32 +02:00
										 |  |  | 				if (variables.fallback && !template.match(new RegExp("{.+}"))) { | 
					
						
							| 
									
										
										
										
											2017-04-25 23:15:34 +03:00
										 |  |  | 					template = variables.fallback; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2020-05-11 22:22:32 +02:00
										 |  |  | 				return template.replace(new RegExp("{([^}]+)}", "g"), function (_unused, varName) { | 
					
						
							|  |  |  | 					return variables[varName] || "{" + varName + "}"; | 
					
						
							| 
									
										
										
										
											2017-04-25 23:15:34 +03:00
										 |  |  | 				}); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2016-05-11 12:38:41 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-11 22:22:32 +02:00
										 |  |  | 			if (this.translations[module.name] && key in this.translations[module.name]) { | 
					
						
							| 
									
										
										
										
											2016-05-11 12:38:41 +02:00
										 |  |  | 				// Log.log("Got translation for " + key + " from module translation: ");
 | 
					
						
							| 
									
										
										
										
											2017-04-25 23:15:34 +03:00
										 |  |  | 				return createStringFromTemplate(this.translations[module.name][key], variables); | 
					
						
							| 
									
										
										
										
											2016-04-21 01:03:26 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2016-05-11 12:38:41 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			if (key in this.coreTranslations) { | 
					
						
							|  |  |  | 				// Log.log("Got translation for " + key + " from core translation.");
 | 
					
						
							| 
									
										
										
										
											2017-04-25 23:15:34 +03:00
										 |  |  | 				return createStringFromTemplate(this.coreTranslations[key], variables); | 
					
						
							| 
									
										
										
										
											2016-05-11 12:38:41 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (this.translationsFallback[module.name] && key in this.translationsFallback[module.name]) { | 
					
						
							|  |  |  | 				// Log.log("Got translation for " + key + " from module translation fallback.");
 | 
					
						
							| 
									
										
										
										
											2017-04-25 23:15:34 +03:00
										 |  |  | 				return createStringFromTemplate(this.translationsFallback[module.name][key], variables); | 
					
						
							| 
									
										
										
										
											2016-05-11 12:38:41 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (key in this.coreTranslationsFallback) { | 
					
						
							|  |  |  | 				// Log.log("Got translation for " + key + " from core translation fallback.");
 | 
					
						
							| 
									
										
										
										
											2017-04-25 23:15:34 +03:00
										 |  |  | 				return createStringFromTemplate(this.coreTranslationsFallback[key], variables); | 
					
						
							| 
									
										
										
										
											2016-05-11 12:38:41 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return key; | 
					
						
							| 
									
										
										
										
											2016-04-21 01:03:26 +02:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2019-06-04 09:33:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-27 14:26:01 +02:00
										 |  |  | 		/** | 
					
						
							| 
									
										
										
										
											2016-04-21 01:03:26 +02:00
										 |  |  | 		 * Load a translation file (json) and remember the data. | 
					
						
							|  |  |  | 		 * | 
					
						
							| 
									
										
										
										
											2020-08-01 16:31:42 +02:00
										 |  |  | 		 * @param {Module} module The module to load the translation file for. | 
					
						
							| 
									
										
										
										
											2020-07-27 14:26:01 +02:00
										 |  |  | 		 * @param {string} file Path of the file we want to load. | 
					
						
							|  |  |  | 		 * @param {boolean} isFallback Flag to indicate fallback translations. | 
					
						
							|  |  |  | 		 * @param {Function} callback Function called when done. | 
					
						
							| 
									
										
										
										
											2016-04-21 01:03:26 +02:00
										 |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2020-05-11 22:22:32 +02:00
										 |  |  | 		load: function (module, file, isFallback, callback) { | 
					
						
							| 
									
										
										
										
											2016-05-11 12:38:41 +02:00
										 |  |  | 			if (!isFallback) { | 
					
						
							|  |  |  | 				Log.log(module.name + " - Load translation: " + file); | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				Log.log(module.name + " - Load translation fallback: " + file); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-21 01:03:26 +02:00
										 |  |  | 			var self = this; | 
					
						
							| 
									
										
										
										
											2020-05-11 22:22:32 +02:00
										 |  |  | 			if (!this.translationsFallback[module.name]) { | 
					
						
							|  |  |  | 				loadJSON(module.file(file), function (json) { | 
					
						
							| 
									
										
										
										
											2016-05-11 12:38:41 +02:00
										 |  |  | 					if (!isFallback) { | 
					
						
							|  |  |  | 						self.translations[module.name] = json; | 
					
						
							|  |  |  | 					} else { | 
					
						
							|  |  |  | 						self.translationsFallback[module.name] = json; | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2016-04-21 01:03:26 +02:00
										 |  |  | 					callback(); | 
					
						
							|  |  |  | 				}); | 
					
						
							| 
									
										
										
										
											2016-04-23 16:57:02 +02:00
										 |  |  | 			} else { | 
					
						
							|  |  |  | 				callback(); | 
					
						
							| 
									
										
										
										
											2016-04-21 01:03:26 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2016-05-11 12:38:41 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-27 14:26:01 +02:00
										 |  |  | 		/** | 
					
						
							| 
									
										
										
										
											2016-05-11 12:38:41 +02:00
										 |  |  | 		 * Load the core translations. | 
					
						
							| 
									
										
										
										
											2016-04-21 01:03:26 +02:00
										 |  |  | 		 * | 
					
						
							| 
									
										
										
										
											2020-07-27 14:26:01 +02:00
										 |  |  | 		 * @param {string} lang The language identifier of the core language. | 
					
						
							| 
									
										
										
										
											2016-04-21 01:03:26 +02:00
										 |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2020-05-11 22:22:32 +02:00
										 |  |  | 		loadCoreTranslations: function (lang) { | 
					
						
							| 
									
										
										
										
											2016-05-11 12:38:41 +02:00
										 |  |  | 			var self = this; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (lang in translations) { | 
					
						
							|  |  |  | 				Log.log("Loading core translation file: " + translations[lang]); | 
					
						
							| 
									
										
										
										
											2020-05-11 22:22:32 +02:00
										 |  |  | 				loadJSON(translations[lang], function (translations) { | 
					
						
							| 
									
										
										
										
											2016-05-11 12:38:41 +02:00
										 |  |  | 					self.coreTranslations = translations; | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				Log.log("Configured language not found in core translations."); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			self.loadCoreTranslationsFallback(); | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-27 14:26:01 +02:00
										 |  |  | 		/** | 
					
						
							| 
									
										
										
										
											2016-05-11 12:38:41 +02:00
										 |  |  | 		 * Load the core translations fallback. | 
					
						
							|  |  |  | 		 * The first language defined in translations.js will be used. | 
					
						
							|  |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2020-05-11 22:22:32 +02:00
										 |  |  | 		loadCoreTranslationsFallback: function () { | 
					
						
							| 
									
										
										
										
											2016-05-11 12:38:41 +02:00
										 |  |  | 			var self = this; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// The variable `first` will contain the first
 | 
					
						
							|  |  |  | 			// defined translation after the following line.
 | 
					
						
							| 
									
										
										
										
											2020-05-11 22:22:32 +02:00
										 |  |  | 			for (var first in translations) { | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2016-05-11 12:38:41 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-11 09:07:41 +01:00
										 |  |  | 			if (first) { | 
					
						
							| 
									
										
										
										
											2018-02-13 07:17:46 +01:00
										 |  |  | 				Log.log("Loading core translation fallback file: " + translations[first]); | 
					
						
							| 
									
										
										
										
											2020-05-11 22:22:32 +02:00
										 |  |  | 				loadJSON(translations[first], function (translations) { | 
					
						
							| 
									
										
										
										
											2018-02-13 07:17:46 +01:00
										 |  |  | 					self.coreTranslationsFallback = translations; | 
					
						
							|  |  |  | 				}); | 
					
						
							| 
									
										
										
										
											2018-02-11 09:07:41 +01:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2020-05-11 22:22:32 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-04-21 01:03:26 +02:00
										 |  |  | 	}; | 
					
						
							|  |  |  | })(); |