diff --git a/src/__tests__/casperjs/locale_header_test.js b/src/__tests__/casperjs/locale_header_test.js index c7dc9717..57c04f5e 100644 --- a/src/__tests__/casperjs/locale_header_test.js +++ b/src/__tests__/casperjs/locale_header_test.js @@ -1,31 +1,43 @@ var CasperUtils = require('./casperUtils').CasperUtils; +var intl = require('../../js/intl/index.js'); + +var langLocaleMap = intl.langLocaleMap; + casper.start( CasperUtils.getUrl(), function() { this.test.assertTitle('Learn Git Branching'); casper.waitFor(CasperUtils.waits.jsMount) - .then(CasperUtils.multiAssert( - CasperUtils.asserts.visibleIDs([ - 'commandLineHistory', - 'terminal', - 'interfaceWrapper', - 'mainVisSpace', - 'commandLineBar' - ]), - CasperUtils.asserts.visibleSelectors([ - 'div.visBackgroundColor', - 'p.commandLine' - ]) - )) + .then(CasperUtils.asserts.visibleIDs([ + 'commandLineHistory', + ])) + .then(function() { - .waitFor(CasperUtils.waits.allCommandsFinished) - - .then( - CasperUtils.asserts.visibleSelectors(['p.finished']) - ) + Object.keys(langLocaleMap).forEach(function(lang) { + var locale = langLocaleMap[lang]; + this.test.assertEvalEquals(function(lang) { + debug_App_changeLocaleFromHeaders(lang); + return debug_Intl_getLocale(); + }, + locale, + 'Testing changing the locale from ' + lang + + ' to ' + locale, + { lang: lang } + ); + this.test.assertEvalEquals(function(lang) { + debug_App_changeLocaleFromHeaders(lang); + return debug_Intl_getLocale(); + }, + locale, + 'Testing changing the locale from ' + lang + + ' to ' + locale, + { lang: lang } + ); + }.bind(this)); + }) .then(CasperUtils.testDone); }).run(); diff --git a/src/js/__tests__/LocaleStore.spec.js b/src/js/__tests__/LocaleStore.spec.js index 6af733a2..99dbba9e 100644 --- a/src/js/__tests__/LocaleStore.spec.js +++ b/src/js/__tests__/LocaleStore.spec.js @@ -12,4 +12,24 @@ describe('LocaleStore', function() { LocaleActions.changeLocale('ja_JP'); expect(LocaleStore.getLocale()).toEqual('ja_JP'); }); + + it('changes locales from headers', function() { + var headerLocaleMap = LocaleStore.getHeaderLocaleMap(); + Object.keys(headerLocaleMap).forEach(function(header) { + LocaleActions.changeLocaleFromHeader(header); + expect(LocaleStore.getLocale()).toEqual( + headerLocaleMap[header] + ); + }); + }); + + it('changes locales from languages', function() { + var langLocaleMap = LocaleStore.getLangLocaleMap(); + Object.keys(langLocaleMap).forEach(function(lang) { + LocaleActions.changeLocaleFromHeader(lang); + expect(LocaleStore.getLocale()).toEqual( + langLocaleMap[lang] + ); + }); + }); }); diff --git a/src/js/actions/LocaleActions.js b/src/js/actions/LocaleActions.js index 282bbcba..5f17977e 100644 --- a/src/js/actions/LocaleActions.js +++ b/src/js/actions/LocaleActions.js @@ -13,6 +13,13 @@ var LocaleActions = { locale: newLocale }); }, + + changeLocaleFromHeader: function(header) { + AppDispatcher.handleViewAction({ + type: ActionTypes.CHANGE_LOCALE_FROM_HEADER, + header: header + }); + } }; module.exports = LocaleActions; diff --git a/src/js/app/index.js b/src/js/app/index.js index d7559128..4ca353ee 100644 --- a/src/js/app/index.js +++ b/src/js/app/index.js @@ -5,6 +5,8 @@ var constants = require('../util/constants'); var util = require('../util'); var intl = require('../intl'); var GlobalState = require('../util/globalState'); +var LocaleStore = require('../stores/LocaleStore'); +var LocaleActions = require('../actions/LocaleActions'); /** * Globals @@ -42,6 +44,7 @@ var init = function() { wait: true }); + LocaleStore.subscribe('change', intlRefresh); events.on('localeChanged', intlRefresh); events.on('vcsModeChange', vcsModeRefresh); @@ -250,32 +253,9 @@ function tryLocaleDetect() { } function changeLocaleFromHeaders(langString) { - try { - var languages = langString.split(','); - var desiredLocale; - for (var i = 0; i < languages.length; i++) { - var header = languages[i].split(';')[0]; - // first check the full string raw - if (intl.headerLocaleMap[header]) { - desiredLocale = intl.headerLocaleMap[header]; - break; - } - - var lang = header.slice(0, 2); - if (intl.langLocaleMap[lang]) { - desiredLocale = intl.langLocaleMap[lang]; - break; - } - } - if (!desiredLocale || desiredLocale == intl.getLocale()) { - return; - } - // actually change it here - GlobalState.locale = desiredLocale; - events.trigger('localeChanged'); - } catch (e) { - console.warn('locale change fail', e); - } + LocaleActions.changeLocaleFromHeaders(langString); + GlobalState.locale = LocaleStore.getLocale(); + events.trigger('localeChanged'); } if (require('../util').isBrowser()) { diff --git a/src/js/constants/AppConstants.js b/src/js/constants/AppConstants.js index 2604c0af..babd2001 100644 --- a/src/js/constants/AppConstants.js +++ b/src/js/constants/AppConstants.js @@ -6,7 +6,8 @@ module.exports = { ActionTypes: keyMirror({ SUBMIT_COMMAND: null, - CHANGE_LOCALE: null + CHANGE_LOCALE: null, + CHANGE_LOCALE_FROM_HEADER: null }), PayloadSources: keyMirror({ diff --git a/src/js/intl/index.js b/src/js/intl/index.js index 489b3916..eec8a5c1 100644 --- a/src/js/intl/index.js +++ b/src/js/intl/index.js @@ -25,7 +25,7 @@ var langLocaleMap = exports.langLocaleMap = { es: 'es_AR', fr: 'fr_FR', de: 'de_DE', - pt: 'pt_BR', + pt: 'pt_BR' }; var fallbackMap = { diff --git a/src/js/stores/LocaleStore.js b/src/js/stores/LocaleStore.js index 4a2d0567..3b638284 100644 --- a/src/js/stores/LocaleStore.js +++ b/src/js/stores/LocaleStore.js @@ -9,9 +9,56 @@ var assign = require('object-assign'); var ActionTypes = AppConstants.ActionTypes; var CHANGE_EVENT = 'change'; +// resolve the messy mapping between browser language +// and our supported locales +var langLocaleMap = { + en: 'en_US', + zh: 'zh_CN', + ja: 'ja', + ko: 'ko', + es: 'es_AR', + fr: 'fr_FR', + de: 'de_DE', + pt: 'pt_BR' +}; + +var headerLocaleMap = { + 'zh-CN': 'zh_CN', + 'zh-TW': 'zh_TW', + 'pt-BR': 'pt_BR' +}; + +function _getLocaleFromHeader(langString) { + var languages = langString.split(','); + var desiredLocale; + for (var i = 0; i < languages.length; i++) { + var header = languages[i].split(';')[0]; + // first check the full string raw + if (headerLocaleMap[header]) { + desiredLocale = headerLocaleMap[header]; + break; + } + + var lang = header.slice(0, 2); + if (langLocaleMap[lang]) { + desiredLocale = langLocaleMap[lang]; + break; + } + } + return desiredLocale; +} + var _locale = 'en_US'; var LocaleStore = assign({}, EventEmitter.prototype, { + getLangLocaleMap: function() { + return assign({}, langLocaleMap); + }, + + getHeaderLocaleMap: function() { + return assign({}, headerLocaleMap); + }, + subscribe: function(cb) { this.on(CHANGE_EVENT, cb); }, @@ -33,6 +80,13 @@ var LocaleStore = assign({}, EventEmitter.prototype, { _locale = action.locale; shouldInform = true; break; + case ActionTypes.CHANGE_LOCALE_FROM_HEADER: + var value = _getLocaleFromHeader(action.header); + if (value) { + _locale = value; + shouldInform = true; + } + break; } if (shouldInform) { diff --git a/src/js/util/debug.js b/src/js/util/debug.js index f649efb1..2e743d21 100644 --- a/src/js/util/debug.js +++ b/src/js/util/debug.js @@ -6,6 +6,7 @@ var toGlobalize = { Visuals: require('../visuals'), Git: require('../git'), CommandModel: require('../models/commandModel'), + LocaleStore: require('../stores/LocaleStore'), Levels: require('../graph/treeCompare'), Constants: require('../util/constants'), Commands: require('../commands'),