1 // ========================================================================== 2 // Project: The M-Project - Mobile HTML5 Application Framework 3 // Copyright: (c) 2010 M-Way Solutions GmbH. All rights reserved. 4 // (c) 2011 panacoda GmbH. All rights reserved. 5 // Creator: Dominik 6 // Date: 29.11.2010 7 // License: Dual licensed under the MIT or GPL Version 2 licenses. 8 // http://github.com/mwaylabs/The-M-Project/blob/master/MIT-LICENSE 9 // http://github.com/mwaylabs/The-M-Project/blob/master/GPL-LICENSE 10 // ========================================================================== 11 12 m_require('core/foundation/object.js'); 13 14 /** 15 * @class 16 * 17 * M.I18N defines a prototype for internationalisation and localisation within 18 * The M-Project. It is used to set and get the application's language and to 19 * localize any string within an application. 20 * 21 * @extends M.Object 22 */ 23 M.I18N = M.Object.extend( 24 /** @scope M.I18N.prototype */ { 25 26 /** 27 * The type of this object. 28 * 29 * @type String 30 */ 31 type: 'M.I18N', 32 33 /** 34 * The system's default language. 35 * 36 * @type String 37 */ 38 defaultLanguage: 'en_us', 39 40 /** 41 * This property is used to map the navigator's language to an ISO standard 42 * if necessary. E.g. 'de' will be mapped to 'de_de'. Currently we only provide 43 * support for english and german. More languages are about to come or can be 44 * added by overwriting this property. 45 * 46 * @type Object 47 */ 48 languageMapper: { 49 de: 'de_de', 50 en: 'en_us' 51 }, 52 53 /** 54 * This method returns the localized string for the given key based on 55 * the current language. 56 * 57 * @param {String} key The key to the localized string. 58 * @returns {String} The localized string based on the current application language. 59 */ 60 l: function(key) { 61 return this.localize(key); 62 }, 63 64 /** 65 * This method returns the localized string for the given key based on 66 * the current language. It is internally used as a wrapper for l() for 67 * a better readability. 68 * 69 * @private 70 * @param {String} key The key to the localized string. 71 * @returns {String} The localized string based on the current application language. 72 */ 73 localize: function(key) { 74 if(!M.Application.currentLanguage) { 75 M.Application.currentLanguage = this.getLanguage(); 76 } 77 78 if(this[M.Application.currentLanguage] && this[M.Application.currentLanguage][key]) { 79 return this[M.Application.currentLanguage][key]; 80 } else if(this[M.Application.defaultLanguage] && this[M.Application.defaultLanguage][key]) { 81 M.Logger.log('Key \'' + key + '\' not defined for language \'' + M.Application.currentLanguage + '\', switched to default language \'' + M.Application.defaultLanguage + '\'', M.WARN); 82 return this[M.Application.defaultLanguage][key]; 83 } else if(this[this.defaultLanguage] && this[this.defaultLanguage][key]) { 84 M.Logger.log('Key \'' + key + '\' not defined for language \'' + M.Application.currentLanguage + '\', switched to system\'s default language \'' + this.defaultLanguage + '\'', M.WARN); 85 return this[this.defaultLanguage][key]; 86 } else { 87 M.Logger.log('Key \'' + key + '\' not defined for both language \'' + M.Application.currentLanguage + '\' and the system\'s default language \'' + this.defaultLanguage + '\'', M.WARN); 88 } 89 90 }, 91 92 /** 93 * This method sets the applications current language and forces it to reload. 94 * 95 * @param {String} language The language to be set. 96 */ 97 setLanguage: function(language) { 98 if(!this.isLanguageAvailable(language)) { 99 M.Logger.log('There is no language \'' + language + '\' specified (using default language \'' + this.defaultLanguage + '\' instead!', M.WARN); 100 this.setLanguage(this.defaultLanguage); 101 return; 102 } else if(language && language === M.Application.currentLanguage) { 103 M.Logger.log('Language \'' + language + '\' already selected', M.INFO); 104 return; 105 } 106 107 if(localStorage) { 108 localStorage.setItem(M.LOCAL_STORAGE_PREFIX + M.Application.name + M.LOCAL_STORAGE_SUFFIX + 'lang', language); 109 location.href = location.protocol + '//' + location.host + location.pathname; 110 } 111 }, 112 113 /** 114 * This method is used to get a language for the current user. This process is divided 115 * into three steps. If one step leads to a language, this on is returned. The steps are 116 * prioritized as follows: 117 * 118 * - get the user's language by checking his navigator 119 * - use the application's default language 120 * - use the systems's default language 121 * 122 * @param {Boolean} returnNavigatorLanguage Specify whether to return the navigator's language even if this language is not supported by this app. 123 * @returns {String} The user's language. 124 */ 125 getLanguage: function(returnNavigatorLanguage) { 126 var language = null; 127 128 if(localStorage) { 129 language = localStorage.getItem(M.LOCAL_STORAGE_PREFIX + M.Application.name + M.LOCAL_STORAGE_SUFFIX + 'lang'); 130 } 131 132 if(language) { 133 return language; 134 } else if(navigator) { 135 var regexResult = /([a-zA-Z]{2,3})[\s_.-]?([a-zA-Z]{2,3})?/.exec(navigator.language); 136 if(regexResult && this[regexResult[0]]) { 137 return regexResult[0].toLowerCase(); 138 } else if(regexResult && regexResult[1] && this.languageMapper[regexResult[1]]) { 139 var language = this.languageMapper[regexResult[1]]; 140 return language.toLowerCase(); 141 } else if(M.Application.defaultLanguage) { 142 return M.Application.defaultLanguage.toLowerCase(); 143 } else { 144 return this.defaultLanguage; 145 } 146 } else { 147 return this.defaultLanguage; 148 } 149 }, 150 151 /** 152 * This method checks if the passed language is available within the app or not. 153 * 154 * @param {String} language The language to be checked. 155 * @returns {Boolean} Indicates whether the requested language is available or not. 156 */ 157 isLanguageAvailable: function(language) { 158 if(this[language] && typeof(this[language]) === 'object') { 159 return true; 160 } else { 161 M.Logger.log('no language \'' + language + '\' specified.', M.WARN); 162 return false; 163 } 164 } 165 166 });