glitch-images/scripts/models/localisationmodel.js
2015-12-30 13:38:34 +01:00

158 lines
4.0 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*global define*/
define(
[ 'config', 'util/dom', 'util/object', 'util/string', 'util/addpublishers', 'lib/reqwest' ],
function ( config, domHelper, objectHelper, stringHelper, addPublishers, reqwest ) {
function LocalisationModel () {
if ( ! ( this instanceof LocalisationModel ) ) {
return new LocalisationModel();
}
var self = this;
var publishers = addPublishers( self, 'update', 'error' );
var textElData = [ ];
var texts = '';
var currentLanguage = '';
var animationFrameId = NaN;
var languageWasLoaded = false;
var linkOptions = { links: { newTab: true } };
function setLanguage ( newLanguage ) {
if ( newLanguage !== currentLanguage && newLanguage in config.availableLanguages ) {
loadLanguage( newLanguage );
}
}
function loadLanguage ( languageName ) {
languageWasLoaded = false;
reqwest( {
url: config.language.dir + '/' + languageName + '.json',
type: 'json',
method: 'get',
error: function ( err, one, two ) {
// if this is the first language to load, that's really bad.
languageWasLoaded = true;
publishers.error.dispatch( 'I\'m really sorry. I failed to load the language file for ' + languageName + '. This is a serious error that makes the app very hard to use. Maybe you can try reloading?' );
},
success: function ( res ) {
languageLoaded( languageName, res );
}
} );
}
function languageLoaded ( newLanguageName, newTexts ) {
currentLanguage = newLanguageName;
languageWasLoaded = true;
texts = newTexts;
resetAllTexts();
updateAllTexts();
}
function updateAllTexts () {
if ( languageWasLoaded ) {
cancelAnimationFrame( animationFrameId );
animationFrameId = requestAnimationFrame( function () {
var item;
var args;
for ( var i = textElData.length - 1; i >= 0; i-- ) {
item = textElData[i];
if ( domHelper.isElement( item.el ) ) {
if ( ! item.wasUpdated ) {
if ( item.attribute === 'innerHTML' ) {
item.el.innerHTML = stringHelper.markdownToHtml( getTextForKey( item.key, item.args ), linkOptions );
} else {
item.el[item.attribute] = getTextForKey( item.key, item.args );
}
item.wasUpdated = true;
}
} else {
textElData.splice( i, 1 );
}
}
publishers.update.dispatch();
} );
}
}
function resetAllTexts () {
textElData.forEach( function ( item ) {
item.wasUpdated = false;
} );
}
function getTextForKey ( key, args ) {
var result = '';
try {
result = objectHelper.getObjectByString( key, texts );
} catch ( e ) {
if ( languageWasLoaded ) {
result = key
}
};
if ( args && args.length ) {
var regex;
args.forEach( function ( arg, index ) {
regex = new RegExp( '{\\$' + ( index + 1 ) + '}' );
result = result.replace( regex, arg );
} );
}
return result;
}
// http://mzl.la/1RDxjVO
function getArgs ( args, firstIndex ) {
firstIndex = firstIndex || 3;
var result;
if ( args.length > firstIndex ) {
result = [ ];
}
for ( var i = firstIndex, len = args.length; i < len; i++ ) {
result[result.length] = args[i];
}
return result;
}
function settingUpdated ( name, value ) {
if ( name === 'language' && value !== currentLanguage ) {
loadLanguage( value );
}
}
function localizeText ( el, attribute, key ) {
if ( el && attribute && key ) {
textElData.push( { el: el, attribute: attribute, key: key, wasUpdated: false, args: getArgs( arguments ) } );
} else {
if ( typeof el === 'string' ) {
return getTextForKey( el, getArgs( arguments, 1 ) );
}
}
updateAllTexts();
}
self.setLanguage = setLanguage;
self.localizeText = localizeText;
self.settingUpdated = settingUpdated;
}
LocalisationModel.sharedInstance = LocalisationModel();
return LocalisationModel;
}
);