Added function to load translations from JS

For apps that support async translation loading, a new function
OC.L10N.load() can be used to asynchronously load the translations
for a given app.
This commit is contained in:
Vincent Petry 2014-11-18 12:13:44 +01:00
parent af7688ec17
commit 152da9796b
3 changed files with 111 additions and 2 deletions

View File

@ -252,6 +252,17 @@ var OC={
}
},
/**
* Loads translations for the given app asynchronously.
*
* @param {String} app app name
* @param {Function} callback callback to call after loading
* @return {Promise}
*/
addTranslations: function(app, callback) {
return OC.L10N.load(app, callback);
},
/**
* Returns the base name of the given path.
* For example for "/abc/somefile.txt" it will return "somefile.txt"
@ -475,6 +486,15 @@ var OC={
return window.matchMedia(media);
}
return false;
},
/**
* Returns the user's locale
*
* @return {String} locale string
*/
getLocale: function() {
return $('html').prop('lang');
}
};
@ -869,9 +889,9 @@ function object(o) {
function initCore() {
/**
* Set users local to moment.js as soon as possible
* Set users locale to moment.js as soon as possible
*/
moment.locale($('html').prop('lang'));
moment.locale(OC.getLocale());
/**

View File

@ -26,6 +26,47 @@ OC.L10N = {
*/
_pluralFunctions: {},
/**
* Load an app's translation bundle if not loaded already.
*
* @param {String} appName name of the app
* @param {Function} callback callback to be called when
* the translations are loaded
* @return {Promise} promise
*/
load: function(appName, callback) {
// already available ?
if (this._bundles[appName] || OC.getLocale() === 'en') {
if (callback) {
callback();
}
return;
}
var self = this;
var deferred = $.Deferred();
var url = OC.generateUrl(
'apps/{app}/l10n/{locale}.json',
{app: appName, locale: OC.getLocale()}
);
var url = OC.filePath(appName, 'l10n', OC.getLocale() + '.json');
// load JSON translation bundle per AJAX
$.get(url,
function(result) {
if (result.translations) {
self.register(appName, result.translations, result.pluralForm);
}
if (callback) {
callback();
deferred.resolve();
}
}
);
return deferred.promise();
},
/**
* Register an app's translation bundle.
*

View File

@ -11,8 +11,12 @@
describe('OC.L10N tests', function() {
var TEST_APP = 'jsunittestapp';
beforeEach(function() {
OC.appswebroots[TEST_APP] = OC.webroot + '/apps3/jsunittestapp';
});
afterEach(function() {
delete OC.L10N._bundles[TEST_APP];
delete OC.appswebroots[TEST_APP];
});
describe('text translation', function() {
@ -98,4 +102,48 @@ describe('OC.L10N tests', function() {
checkPlurals();
});
});
describe('async loading of translations', function() {
it('loads bundle for given app and calls callback', function() {
var localeStub = sinon.stub(OC, 'getLocale').returns('zh_CN');
var callbackStub = sinon.stub();
var promiseStub = sinon.stub();
OC.L10N.load(TEST_APP, callbackStub).then(promiseStub);
expect(callbackStub.notCalled).toEqual(true);
expect(promiseStub.notCalled).toEqual(true);
expect(fakeServer.requests.length).toEqual(1);
var req = fakeServer.requests[0];
expect(req.url).toEqual(
OC.webroot + '/apps3/' + TEST_APP + '/l10n/zh_CN.json'
);
req.respond(
200,
{ 'Content-Type': 'application/json' },
JSON.stringify({
translations: {'Hello world!': '你好世界!'},
pluralForm: 'nplurals=2; plural=(n != 1);'
})
);
expect(callbackStub.calledOnce).toEqual(true);
expect(promiseStub.calledOnce).toEqual(true);
expect(t(TEST_APP, 'Hello world!')).toEqual('你好世界!');
localeStub.restore();
});
it('calls callback if translation already available', function() {
var callbackStub = sinon.stub();
OC.L10N.register(TEST_APP, {
'Hello world!': 'Hallo Welt!'
});
OC.L10N.load(TEST_APP, callbackStub);
expect(callbackStub.calledOnce).toEqual(true);
expect(fakeServer.requests.length).toEqual(0);
});
it('calls callback if locale is en', function() {
var localeStub = sinon.stub(OC, 'getLocale').returns('en');
var callbackStub = sinon.stub();
OC.L10N.load(TEST_APP, callbackStub);
expect(callbackStub.calledOnce).toEqual(true);
expect(fakeServer.requests.length).toEqual(0);
});
});
});