diff --git a/src/i18n/index.js b/src/i18n/index.js index 1209fb054..409cfb9a3 100644 --- a/src/i18n/index.js +++ b/src/i18n/index.js @@ -28,9 +28,32 @@ * * @module I18n */ -import { keys, isUndefined, isString } from 'underscore'; +import { isUndefined, isString } from 'underscore'; import config from './config'; +const isObj = el => !Array.isArray(el) && el !== null && typeof el === 'object'; + +const deepAssign = (...args) => { + const target = { ...args[0] }; + + for (let i = 1; i < args.length; i++) { + const source = { ...args[i] }; + + for (let key in source) { + const targValue = target[key]; + const srcValue = source[key]; + + if (isObj(targValue) && isObj(srcValue)) { + target[key] = deepAssign(targValue, srcValue); + } else { + target[key] = srcValue; + } + } + } + + return target; +}; + export default () => { return { name: 'I18n', @@ -139,20 +162,7 @@ export default () => { const { em } = this; const { messages } = this.config; em && em.trigger('i18n:add', msg); - - keys(msg).forEach(lang => { - const langSet = msg[lang]; - const currentSet = messages[lang]; - - if (!currentSet) { - messages[lang] = langSet; - } else { - keys(langSet).forEach(key => { - currentSet[key] = langSet[key]; - }); - } - }); - this.setMessages(messages); // Need this for the event + this.setMessages(deepAssign(messages, msg)); return this; }, diff --git a/test/specs/i18n/index.js b/test/specs/i18n/index.js index b1ef98bde..4fba52d15 100644 --- a/test/specs/i18n/index.js +++ b/test/specs/i18n/index.js @@ -76,6 +76,44 @@ describe('I18n', () => { }); }); + test('addMessages with deep extend possibility', () => { + obj.setMessages({ + en: { + msg1: 'Msg 1', + msg2: 'Msg 2', + msg3: { + msg31: 'Msg 31', + msg32: { msg321: 'Msg 321' } + } + } + }); + obj.addMessages({ + en: { + msg2: { msg21: 'Msg 21' }, + msg3: { + msg32: { msg322: 'Msg 322' }, + msg33: 'Msg 33' + }, + msg4: 'Msg 4' + } + }); + expect(obj.getMessages()).toEqual({ + en: { + msg1: 'Msg 1', + msg2: { msg21: 'Msg 21' }, + msg3: { + msg31: 'Msg 31', + msg32: { + msg321: 'Msg 321', + msg322: 'Msg 322' + }, + msg33: 'Msg 33' + }, + msg4: 'Msg 4' + } + }); + }); + test('Translate method with global locale', () => { const msg1 = 'Msg 1'; obj.setLocale('en');