From f84a21d3554f26f379c67c8cc6ea10650d37f469 Mon Sep 17 00:00:00 2001 From: karimJWP Date: Thu, 27 Sep 2018 18:24:27 -0400 Subject: [PATCH] introduce normalization and merge helpers --- karma.conf.js | 3 +-- src/js/api/config.js | 2 +- src/js/api/setup-steps.js | 2 +- src/js/utils/language.js | 52 ++++++++++++++++++++++----------------- 4 files changed, 32 insertions(+), 27 deletions(-) diff --git a/karma.conf.js b/karma.conf.js index 67e93cc6e8..0bf21d820c 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -142,8 +142,7 @@ module.exports = function(config) { files: [ { pattern: './node_modules/intersection-observer/intersection-observer.js' }, { pattern: './test/index.js' }, - { pattern: './test/files/*', included: false }, - { pattern: './test/files/translations/*', included: false }, + { pattern: './test/files/**', included: false }, { pattern: './src/js/*', included: false } ], diff --git a/src/js/api/config.js b/src/js/api/config.js index 7b283b01d2..6d8eb68b4a 100644 --- a/src/js/api/config.js +++ b/src/js/api/config.js @@ -69,7 +69,7 @@ const Config = function(options, persisted) { const language = getLanguage(); const { localization, intl } = allOptions; const customLocalization = getCustomLocalization(localization, intl, language); - allOptions.localization = applyTranslation({}, customLocalization); + allOptions.localization = applyTranslation(en, customLocalization); let config = Object.assign({}, Defaults, allOptions); if (config.base === '.') { diff --git a/src/js/api/setup-steps.js b/src/js/api/setup-steps.js index 52ae5eda93..c17e75046d 100644 --- a/src/js/api/setup-steps.js +++ b/src/js/api/setup-steps.js @@ -105,7 +105,7 @@ export function loadTranslations(_model) { return new Promise(resolve => { return loadJsonTranslation(base, language) .then(({ response }) => { - if (destroyed(_model)) { + if (destroyed(_model) || !response) { return; } attributes.localization = applyTranslation(response, customLocalization); diff --git a/src/js/utils/language.js b/src/js/utils/language.js index 87ca8d2ec0..035416ee53 100644 --- a/src/js/utils/language.js +++ b/src/js/utils/language.js @@ -23,10 +23,23 @@ const codeToLang = { const langToCode = invert(codeToLang); -function formatLanguageCode(language) { +function normalizeLanguageCode(language) { return language.substring(0, 2).toLowerCase(); } +function normalizeLanguageAndCountryCode(language) { + return language.toLowerCase().replace('-', '_'); +} + +function normalizeIntl(intl) { + // TODO: Country codes are generally seen in upper case, but we have yet to find documentation confirming that this is the standard. + // When the documentation is found, remove lower case support and update our docs with reference to standards. + return Object.keys(intl).reduce((obj, key) => { + obj[normalizeLanguageAndCountryCode(key)] = intl[key]; + return obj; + }, {}); +} + export function getLabel(language) { if (!language) { return; @@ -37,7 +50,7 @@ export function getLabel(language) { return language; } - return codeToLang[formatLanguageCode(language)] || language; + return codeToLang[normalizeLanguageCode(language)] || language; } export function getCode(language) { @@ -63,19 +76,12 @@ export function getLanguage() { export const translatedLanguageCodes = ['ar', 'da', 'de', 'es', 'fr', 'it', 'ja', 'nb', 'nl', 'pt', 'ro', 'sv', 'tr', 'zh']; export function isTranslationAvailable(language) { - return translatedLanguageCodes.indexOf(formatLanguageCode(language)) >= 0; + return translatedLanguageCodes.indexOf(normalizeLanguageCode(language)) >= 0; } export function getCustomLocalization(localization, intl, languageAndCountryCode) { - localization = localization || {}; - intl = intl || {}; - const languageCode = formatLanguageCode(languageAndCountryCode); - const languageAndCountryCustomization = languageCode === languageAndCountryCode ? {} : - intl[languageAndCountryCode] || intl[languageAndCountryCode.toLowerCase()] || - intl[languageAndCountryCode.replace('-', '_')] || intl[languageAndCountryCode.toLowerCase().replace('-', '_')]; - // TODO: Country codes are generally seen in upper case, but we have yet to find documentation enforcing this format. - // When the documentation is found, remove lower case support and update our docs with reference to standards. - return Object.assign({}, localization, intl[languageCode], languageAndCountryCustomization); + intl = normalizeIntl(intl || {}); + return Object.assign({}, localization || {}, intl[normalizeLanguageCode(languageAndCountryCode)], intl[normalizeLanguageAndCountryCode(languageAndCountryCode)]); } export function isLocalizationComplete(customLocalization) { @@ -83,21 +89,21 @@ export function isLocalizationComplete(customLocalization) { } export function loadJsonTranslation(base, languageCode) { - const url = `${base}translations/${formatLanguageCode(languageCode)}.json`; + const url = `${base}translations/${normalizeLanguageCode(languageCode)}.json`; return new Promise((resolve, reject) => { - const oncomplete = (result) => resolve(result); - const onerror = () => reject(); - ajax({ url, oncomplete, onerror, responseType: 'json' }); + ajax({ url, resolve, reject, responseType: 'json' }); }); } -export function applyTranslation(translationJson, customization) { - translationJson = translationJson || {}; - const localization = Object.assign({}, en, translationJson, customization); - localization.errors = Object.assign({}, en.errors, translationJson.errors, customization.errors); - localization.related = Object.assign({}, en.related, translationJson.related, customization.related); - localization.sharing = Object.assign({}, en.sharing, translationJson.sharing, customization.sharing); - localization.advertising = Object.assign({}, en.advertising, translationJson.advertising, customization.advertising); +export function applyTranslation(baseLocalization, customization) { + const localization = Object.assign({}, baseLocalization, customization); + merge(localization, 'errors', baseLocalization, customization); + merge(localization, 'related', baseLocalization, customization); + merge(localization, 'sharing', baseLocalization, customization); + merge(localization, 'advertising', baseLocalization, customization); return localization; +} +function merge(z, prop, a, b) { + z[prop] = Object.assign({}, a[prop], b[prop]); }