Skip to content

Commit

Permalink
Refactored setting window.language.
Browse files Browse the repository at this point in the history
  • Loading branch information
dsjen committed Oct 3, 2016
1 parent d069ad8 commit 160f220
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 79 deletions.
7 changes: 6 additions & 1 deletion analytics_dashboard/static/js/load/init-page.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
/**
* Initializes page with the model and various UI elements that need JS hooks.
*/
define(['jquery', 'load/init-models', 'load/init-tooltips'], function($, models) {
define([
'jquery', 'utils/fix-language', 'load/init-models', 'load/init-tooltips'
], function($, fixLanguage, models) {
'use strict';

// set the standardized language code
window.language = fixLanguage(window.language);

// initialize tracking
require(['load/init-tracking'], function(initTracking) {
initTracking(models);
Expand Down
30 changes: 30 additions & 0 deletions analytics_dashboard/static/js/test/specs/fix-language-spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// eslint-disable-next-line import/no-unresolved
define(['utils/fix-language'], function(fixLanguages) {
'use strict';

function expectLanguages(actualLanguages, expectedLanguageCode) {
actualLanguages.forEach(function(languageCode) {
expect(fixLanguages(languageCode), expectedLanguageCode);
});
}

describe('window.language', function() {
it('should default to English if an invalid argument is provided or not known to CLDR', function() {
expectLanguages([null, '', 1, false, 'not-real'], 'en');
});

it('should return zh if the given language code is either zh-cn, zh-sg and zh-hans(-*) ', function() {
expectLanguages(['zh-cn', 'zh-sg', 'zh-hans', 'zh-hans-cn'], 'zh');
});

it('should return zh-Hant if the given language code is either zh-tw, zh-hk, zh-mo and zh-hant-* ',
function() {
expectLanguages(['zh-tw', 'zh-hk', 'zh-mo', 'zh-hant-tw'], 'zh-Hant');
}
);

it('should return correct-casing any given cased language code', function() {
expectLanguages(['en-gb', 'en-GB', 'EN-GB'], 'en-GB');
});
});
});
41 changes: 5 additions & 36 deletions analytics_dashboard/static/js/test/specs/globalization-spec.js
Original file line number Diff line number Diff line change
@@ -1,42 +1,11 @@
// eslint-disable-next-line import/no-unresolved
define(['json!cldr-data/availableLocales.json', 'utils/globalization'], function(availableLocales) {
define(['utils/globalization'], function(Globalization) {
'use strict';

var lowerLocalesMapping = {};
availableLocales.availableLocales.forEach(function(locale) {
lowerLocalesMapping[locale.toLowerCase()] = locale;
});

describe('fixLanguageCode', function() {
it('should default to English if an invalid argument is provided', function() {
expect(fixLanguageCode(null, lowerLocalesMapping)).toEqual('en');
expect(fixLanguageCode('', lowerLocalesMapping)).toEqual('en');
expect(fixLanguageCode(1, lowerLocalesMapping)).toEqual('en');
expect(fixLanguageCode(true, lowerLocalesMapping)).toEqual('en');
});

it('should return zh if the given language code is either zh-cn, zh-sg and zh-hans(-*) ', function() {
expect(fixLanguageCode('zh-cn', lowerLocalesMapping)).toEqual('zh');
expect(fixLanguageCode('zh-sg', lowerLocalesMapping)).toEqual('zh');
expect(fixLanguageCode('zh-hans', lowerLocalesMapping)).toEqual('zh');
expect(fixLanguageCode('zh-hans-cn', lowerLocalesMapping)).toEqual('zh');
});

it('should return zh-Hant if the given language code is either zh-tw, zh-hk, zh-mo and zh-hant-* ', function() {
expect(fixLanguageCode('zh-tw', lowerLocalesMapping)).toEqual('zh-Hant');
expect(fixLanguageCode('zh-hk', lowerLocalesMapping)).toEqual('zh-Hant');
expect(fixLanguageCode('zh-mo', lowerLocalesMapping)).toEqual('zh-Hant');
expect(fixLanguageCode('zh-hant-tw', lowerLocalesMapping)).toEqual('zh-Hant');
});

it('should return en if the given language code is not known to CLDR', function() {
expect(fixLanguageCode('not-real', lowerLocalesMapping)).toEqual('en');
});

it('should return correct-casing any given cased language code', function() {
expect(fixLanguageCode('en-gb', lowerLocalesMapping)).toEqual('en-GB');
expect(fixLanguageCode('en-GB', lowerLocalesMapping)).toEqual('en-GB');
expect(fixLanguageCode('EN-GB', lowerLocalesMapping)).toEqual('en-GB');
describe('Globalization', function() {
// globalization functionality (e.g. number formatting) is tested in utils-spec
it('should be returned', function() {
expect(Globalization).toBeDefined();
});
});
});
44 changes: 44 additions & 0 deletions analytics_dashboard/static/js/utils/fix-language.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**
* In order to localize numbers and dates, the language codes must made those in
* CLDR. This module standardizes language code argument so that the
* correct language settings are loaded.
*/
define([
'json!cldr-data/availableLocales.json' // eslint-disable-line import/no-unresolved
], function(availableLocales) {
'use strict';

var lowerLocalesMapping = {};
availableLocales.availableLocales.forEach(function(locale) {
lowerLocalesMapping[locale.toLowerCase()] = locale;
});

return function(languageCode) {
var fixedLanguageCode;

if (!languageCode || typeof languageCode !== 'string') {
return 'en';
}

fixedLanguageCode = languageCode.toLowerCase();

// CLDR uses zh for Simplified Chinese, while Django may use different strings.
if (fixedLanguageCode === 'zh-cn' || fixedLanguageCode === 'zh-sg' ||
fixedLanguageCode.indexOf('zh-hans') === 0) {
fixedLanguageCode = 'zh';
}
// CLDR uses zh-hant for Traditional Chinese, while Django may use different strings.
if (fixedLanguageCode === 'zh-tw' || fixedLanguageCode === 'zh-hk' ||
fixedLanguageCode === 'zh-mo' || fixedLanguageCode.indexOf('zh-hant') === 0) {
fixedLanguageCode = 'zh-hant';
}

// There doesn't seem to be an onFailure event for the text! plugin. Make sure we only pass valid language codes
// so the plugin does not attempt to load non-existent files.
if (fixedLanguageCode in lowerLocalesMapping) {
return lowerLocalesMapping[fixedLanguageCode];
}

return 'en';
};
});
49 changes: 8 additions & 41 deletions analytics_dashboard/static/js/utils/globalization.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,56 +2,23 @@ if (window.language === undefined) { // should only occur in test environments
window.language = 'en';
}

function fixLanguageCode(languageCode, lowerLocalesMapping) {
'use strict';
var fixedLanguageCode;

if (!languageCode || typeof languageCode !== 'string') {
return 'en';
}

fixedLanguageCode = languageCode.toLowerCase();

// CLDR uses zh for Simplified Chinese, while Django may use different strings.
if (fixedLanguageCode === 'zh-cn' || fixedLanguageCode === 'zh-sg' ||
fixedLanguageCode.indexOf('zh-hans') === 0) {
fixedLanguageCode = 'zh';
}
// CLDR uses zh-hant for Traditional Chinese, while Django may use different strings.
if (fixedLanguageCode === 'zh-tw' || fixedLanguageCode === 'zh-hk' ||
fixedLanguageCode === 'zh-mo' || fixedLanguageCode.indexOf('zh-hant') === 0) {
fixedLanguageCode = 'zh-hant';
}

// There doesn't seem to be an onFailure event for the text! plugin. Make sure we only pass valid language codes
// so the plugin does not attempt to load non-existent files.
if (fixedLanguageCode in lowerLocalesMapping) {
return lowerLocalesMapping[fixedLanguageCode];
}

return 'en';
}

/**
* Returns the Globalize object for localizing dates and numbers. window.language
* is expected to be standardized to those used in CLDR. See js/load/init-page.js
* for setting window.language.
*/
define([
'globalize',
'json!cldr-data/supplemental/likelySubtags.json',
'json!cldr-data/supplemental/numberingSystems.json',
'json!cldr-data/availableLocales.json', // eslint-disable-line import/no-unresolved
'json!cldr-data/main/' + window.language + '/numbers.json',
'json!cldr-data/main/' + window.language + '/numbers.json', // language fix already applied (e.g. en-gb is en-GB)
'globalize/number'
], function(Globalize, likelySubtags, numberingSystems, availableLocales, numbers) {
], function(Globalize, likelySubtags, numberingSystems, numbers) {
'use strict';

var lowerLocalesMapping = {};
availableLocales.availableLocales.forEach(function(locale) {
lowerLocalesMapping[locale.toLowerCase()] = locale;
});

window.language = fixLanguageCode(window.language, lowerLocalesMapping);

Globalize.load(numbers);
Globalize.load(likelySubtags);
Globalize.load(numberingSystems);
Globalize.load(numbers);

return Globalize(window.language);
});
7 changes: 6 additions & 1 deletion karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@ module.exports = function(config) {
{pattern: 'analytics_dashboard/static/vendor/**/*.js', included: false},
{pattern: 'analytics_dashboard/static/bower_components/**/*.js', included: false},
{pattern: 'analytics_dashboard/static/bower_components/**/*.underscore', included: false},
{pattern: 'analytics_dashboard/static/bower_components/**/*.json', included: false},
// limiting the cldr json files to load (we don't use the other ones and loading too many
// throws errors on a mac)
{pattern: 'analytics_dashboard/static/bower_components/cldr-data/supplemental/*.json', included: false},
{pattern: 'analytics_dashboard/static/bower_components/cldr-data/availableLocales.json', included: false},
{pattern: 'analytics_dashboard/static/bower_components/cldr-data/**/numbers.json', included: false},
{pattern: 'analytics_dashboard/static/js/load/*.js', included: false},
{pattern: 'analytics_dashboard/static/js/models/**/*.js', included: false},
{pattern: 'analytics_dashboard/static/js/views/**/*.js', included: false},
{pattern: 'analytics_dashboard/static/js/utils/**/*.js', included: false},
Expand Down

0 comments on commit 160f220

Please sign in to comment.