-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Benjamin Strauß
committed
Jan 24, 2018
1 parent
e7d3ca4
commit 8b82ffd
Showing
7 changed files
with
247 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
goog.module('clulib.l10n.ResourceManager'); | ||
|
||
const ResourceBundle = goog.require('clulib.l10n.ResourceBundle'); | ||
|
||
/** | ||
* Manages multiple ResourceBundles for multiple locales. | ||
* | ||
* Loads json localization files via pattern `baseUrl/locale/id.json`. | ||
*/ | ||
class ResourceManager { | ||
/** | ||
* @param {Array<string>} bundleIds | ||
* @param {Array<string>} locales | ||
* @param {string} baseUrl | ||
*/ | ||
constructor (bundleIds, locales, baseUrl) { | ||
/** | ||
* @type {Array<string>} | ||
* @private | ||
*/ | ||
this.bundleIds_ = bundleIds; | ||
|
||
/** | ||
* @type {Array<string>} | ||
* @private | ||
*/ | ||
this.locales_ = locales; | ||
|
||
/** | ||
* @type {string} | ||
* @private | ||
*/ | ||
this.baseUrl_ = baseUrl; | ||
|
||
/** | ||
* @type {?string} | ||
* @private | ||
*/ | ||
this.currentLocale_ = null; | ||
|
||
/** | ||
* @type {Map<string, Map<string, ResourceBundle>>} | ||
* @private | ||
*/ | ||
this.bundles_ = new Map(); | ||
|
||
locales.forEach(locale => { | ||
const localeMap = new Map(); | ||
|
||
bundleIds.forEach(bundleId => { | ||
localeMap.set(bundleId, new ResourceBundle(bundleId, locale, baseUrl)); | ||
}); | ||
|
||
this.bundles_.set(locale, localeMap); | ||
}); | ||
} | ||
|
||
/** | ||
* @returns {?string} | ||
*/ | ||
get currentLocale () { | ||
return this.currentLocale_; | ||
} | ||
|
||
/** | ||
* Checks if the locale is valid for this ResourceManager | ||
* | ||
* @param {string} locale | ||
* @returns {boolean} | ||
*/ | ||
isLocaleValid (locale) { | ||
return this.locales_.includes(locale); | ||
} | ||
|
||
// eslint-disable-next-line valid-jsdoc | ||
/** | ||
* Changes the current locale, loads the resource files if necessary. | ||
* | ||
* @param {string} locale | ||
* @returns {Promise<void>} | ||
*/ | ||
async changeLocale (locale) { | ||
if (!this.isLocaleValid(locale)) | ||
throw new Error(`Locale '${locale}' is not registered with this ResourceManager.`); | ||
|
||
const bundleLoaders = Array.from(this.bundles_.get(locale).values()) | ||
.map(bundle => bundle.load()); | ||
|
||
await Promise.all(bundleLoaders); | ||
|
||
this.currentLocale_ = locale; | ||
} | ||
|
||
/** | ||
* Gets a specific bundle for the current locale. | ||
* | ||
* @param {string} bundleId | ||
* @returns {ResourceBundle} | ||
*/ | ||
getBundle (bundleId) { | ||
if (this.currentLocale_ == null) | ||
throw new Error('No locale set!'); | ||
|
||
return this.bundles_.get(/** @type {!string} */ (this.currentLocale_)).get(bundleId); | ||
} | ||
|
||
/** | ||
* Checks if a bundle contains a localization key. | ||
* | ||
* @param {string} bundleId | ||
* @param {string} key | ||
* @returns {boolean} | ||
*/ | ||
contains (bundleId, key) { | ||
return this.getBundle(bundleId).contains(key); | ||
} | ||
|
||
/** | ||
* Gets an object from the json localization file of the current bundle. | ||
* | ||
* @param {string} bundleId | ||
* @param {string} key | ||
* @returns {Object} | ||
*/ | ||
getObject (bundleId, key) { | ||
return this.getBundle(bundleId).getObject(key); | ||
} | ||
|
||
/** | ||
* Gets an array from the json localization file of the current bundle. | ||
* | ||
* @param {string} bundleId | ||
* @param {string} key | ||
* @returns {Array} | ||
*/ | ||
getArray (bundleId, key) { | ||
return this.getBundle(bundleId).getArray(key); | ||
} | ||
|
||
/** | ||
* Gets a boolean from the json localization file of the current bundle. | ||
* | ||
* @param {string} bundleId | ||
* @param {string} key | ||
* @returns {boolean} | ||
*/ | ||
getBoolean (bundleId, key) { | ||
return this.getBundle(bundleId).getBoolean(key); | ||
} | ||
|
||
/** | ||
* Gets a number from the json localization file of the current bundle. | ||
* | ||
* @param {string} bundleId | ||
* @param {string} key | ||
* @returns {number} | ||
*/ | ||
getNumber (bundleId, key) { | ||
return this.getBundle(bundleId).getNumber(key); | ||
} | ||
|
||
/** | ||
* Gets a string from the json localization file of the current bundle. | ||
* | ||
* Takes an optional `replaceObject` which will replace placeholder keys in the string. | ||
* An object with key `foo` will replace all placeholders `{foo}`. | ||
* | ||
* @param {string} bundleId | ||
* @param {string} key | ||
* @param {Object=} replaceObject | ||
* @returns {string} | ||
*/ | ||
getString (bundleId, key, replaceObject = null) { | ||
return this.getBundle(bundleId).getString(key, replaceObject); | ||
} | ||
} | ||
|
||
exports = ResourceManager; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,16 @@ | ||
{ | ||
"string": "Hello, world!", | ||
"string": "Hallo, Welt!", | ||
"array": [ | ||
0, | ||
1, | ||
2 | ||
], | ||
"object": { | ||
"one": 1, | ||
"two": 2, | ||
"three": 3 | ||
"eins": 1, | ||
"zwei": 2, | ||
"drei": 3 | ||
}, | ||
"number": 10, | ||
"boolean": false, | ||
"string-placeholder": "Hello {to}, my name is {from}." | ||
"string-placeholder": "Hallo {to}, mein name ist {from}." | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"string": "Hello, world!", | ||
"array": [ | ||
0, | ||
1, | ||
2 | ||
], | ||
"object": { | ||
"one": 1, | ||
"two": 2, | ||
"three": 3 | ||
}, | ||
"number": 10, | ||
"boolean": false, | ||
"string-placeholder": "Hello {to}, my name is {from}." | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
goog.module('test.clulib.l10n.ResourceManager'); | ||
|
||
const ResourceManager = goog.require('clulib.l10n.ResourceManager'); | ||
const env = goog.require('testing.environment'); | ||
|
||
const base = `${env.basePath}/test-assets/l10n`; | ||
|
||
exports = function () { | ||
describe('clulib.l10n.ResourceManager', () => { | ||
it('should load resource files in different languages', async () => { | ||
const manager = new ResourceManager(['test'], ['de-DE', 'en-GB'], base); | ||
|
||
expect(manager.currentLocale).toBe(null); | ||
|
||
await manager.changeLocale('de-DE'); | ||
|
||
expect(manager.contains('test', 'string-placeholder')).toBe(true); | ||
|
||
expect(manager.getArray('test', 'array')).toEqual([0, 1, 2]); | ||
expect(manager.getBoolean('test', 'boolean')).toBe(false); | ||
expect(manager.getNumber('test', 'number')).toBe(10); | ||
expect(manager.getString('test', 'string')).toBe('Hallo, Welt!'); | ||
expect(manager.getObject('test', 'object')).toEqual({'eins': 1, 'zwei': 2, 'drei': 3}); | ||
|
||
expect(manager.getString('test', 'string-placeholder', {'from': 'Bob', 'to': 'Max'})) | ||
.toBe('Hallo Max, mein name ist Bob.'); | ||
|
||
await manager.changeLocale('en-GB'); | ||
|
||
expect(manager.contains('test', 'string-placeholder')).toBe(true); | ||
|
||
expect(manager.getArray('test', 'array')).toEqual([0, 1, 2]); | ||
expect(manager.getBoolean('test', 'boolean')).toBe(false); | ||
expect(manager.getNumber('test', 'number')).toBe(10); | ||
expect(manager.getString('test', 'string')).toBe('Hello, world!'); | ||
expect(manager.getObject('test', 'object')).toEqual({'one': 1, 'two': 2, 'three': 3}); | ||
|
||
expect(manager.getString('test', 'string-placeholder', {'from': 'Bob', 'to': 'Max'})) | ||
.toBe('Hello Max, my name is Bob.'); | ||
}); | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters