Skip to content

Commit

Permalink
fix #203
Browse files Browse the repository at this point in the history
  • Loading branch information
Diablohu committed Jan 3, 2020
1 parent 9bc40fe commit 571e1b7
Show file tree
Hide file tree
Showing 6 changed files with 229 additions and 84 deletions.
10 changes: 5 additions & 5 deletions packages/koot/i18n/is-enabled.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
* @returns {Boolean}
*/
const isI18nEnabled = () => {
if (!JSON.parse(process.env.KOOT_I18N))
return false
return true
}
module.exports = isI18nEnabled
if (!process.env.KOOT_I18N || !JSON.parse(process.env.KOOT_I18N))
return false;
return true;
};
module.exports = isI18nEnabled;
10 changes: 4 additions & 6 deletions packages/koot/i18n/parse-language-list.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
/**
* 根据输入的语言列表字符串,返回语言列表array
*
*
* @param {string} langList 语言列表字符串,eg: zh-CN,zh;q=0.8,en;q=0.6
*
*
* @returns {array} 语言列表
*/
export default langList =>
langList
.split(',')
.map(value => value.split(';')[0])
module.exports = langList =>
langList.split(',').map(value => value.split(';')[0]);
166 changes: 97 additions & 69 deletions packages/koot/i18n/parse-locale-id.js
Original file line number Diff line number Diff line change
@@ -1,87 +1,115 @@
import parseLanguageList from './parse-language-list'

import availableLocaleIds from './locale-ids'

/**
* 检查单项,如果和availableLocales内的项目有匹配,返回匹配,否则返回null
* @param {string} input 检查项
* @returns 匹配的 localeId 或 null
*/
const checkItem = (input) => {
let id

// input = input.toLowerCase().replace(/_/g, '-')

availableLocaleIds.some(_localeId => {
if (_localeId == input)
id = _localeId
return id
})

const parseSeg = (id, localeId, str) => {
if (id) return id

const seg = localeId.split(str)

if (!id) {
availableLocaleIds.some(_localeId => {
if (_localeId == seg[0] + '-' + seg[seg.length - 1])
id = _localeId
return id
})
}

if (!id) {
availableLocaleIds.some(_localeId => {
if (_localeId == seg[0])
id = _localeId
return id
})
}

return id || null
}

id = parseSeg(id, input, '-')

return id || null
}
const parseLanguageList = require('./parse-language-list');
const availableLocaleIds = require('./locale-ids');

/**
* 根据输入内容返回availableLocales内匹配的语言包ID(localeId)
* 如果没有匹配,返回availableLocales的第一项
* 根据输入返回项目匹配的语言包ID (localeId)
* 如果没有匹配,返回项目语言包ID的第一项
* 注:仅为返回,没有赋值操作
*
* @param {string|array} input
*
*
* @param {string|string[]} input
* @param {string[]} [localeIds] 可选语言ID列表
* @returns 匹配的语言包ID localeId 或 availableLocaleIds[0]
*/
const parseLocaleId = (input) => {

const parseLocaleId = (input, localeIds = availableLocaleIds) => {
// 检查是否包含分号,如果是,按语言列表处理为array
// eg: zh-CN,zh;q=0.8,en;q=0.6
if (typeof input === 'string' && input.indexOf(';') > -1)
input = parseLanguageList(input)
input = parseLanguageList(input);

// 检查是否为array
if (Array.isArray(input)) {
let id
let id;

input.some(thisId => {
id = checkItem(thisId)
return id
})
id = checkItem(thisId, localeIds);
return id;
});

return id || localeIds[0];
} else if (!input && typeof navigator !== 'undefined')
return parseLocaleId(
navigator.languages ||
navigator.language ||
navigator.browserLanguage ||
navigator.systemLanguage ||
navigator.userLanguage ||
localeIds[0],
localeIds
);
else if (input) return checkItem(input, localeIds) || localeIds[0];

return localeIds[0];
};

module.exports = parseLocaleId;

// ============================================================================

return id || availableLocaleIds[0]
}
/**
* 标准化语言包ID,方便匹配
* - 全部小写
* - `_` 变为 `-`
* @param {string} input
* @returns {string}
*/
const normalize = localeId => localeId.toLowerCase().replace(/_/g, '-');

else if (!input && typeof navigator !== 'undefined')
return parseLocaleId(navigator.languages || navigator.language || navigator.browserLanguage || navigator.systemLanguage || navigator.userLanguage || availableLocaleIds[0])
/**
* 获取基础语种
* @param {string} localeId
* @param {string} [seperator='-'] 连接线,默认为 `-`
* @returns {string}
*/
const getLocaleBase = (localeId, seperator = '-') =>
localeId.split(seperator)[0];

else if (input)
return checkItem(input) || availableLocaleIds[0]
/**
* 检查单项,如果和availableLocales内的项目有匹配,返回匹配,否则返回null
* @param {string} input 检查项
* @param {string[]} [localeIds] 可选语言ID列表
* @returns 匹配的 localeId 或 null
*/
const checkItem = (input, localeIds = availableLocaleIds) => {
const inputNormalized = normalize(input);
const localeIdsNormalized = localeIds.map(normalize);

let result;

// 如果有完整匹配的项,直接返回结果
localeIdsNormalized.some((thisLocaleId, index) => {
if (thisLocaleId === inputNormalized) {
result = localeIds[index];
return true;
}
return false;
});
if (result) return result;

return availableLocaleIds[0]
}
// 之后根据基础语种进行检查

/** 基础语种 (eg: `zh-CN` 基础语种为 `zh`) */
const baseLocale = getLocaleBase(inputNormalized, '-');

// 如果可选列表中有对应的基础语种,返回该结果
localeIdsNormalized.some((thisLocaleId, index) => {
if (thisLocaleId === baseLocale) {
result = localeIds[index];
return true;
}
return false;
});
if (result) return result;

// 检查可选列表中每一项的基础语种,返回第一个匹配
localeIdsNormalized.some((thisLocaleId, index) => {
const thisBaseLocale = getLocaleBase(thisLocaleId, '-');
if (thisBaseLocale === baseLocale) {
result = localeIds[index];
return true;
}
return false;
});
if (result) return result;

export default parseLocaleId
return null;
};
24 changes: 20 additions & 4 deletions packages/koot/utils/webpack-optimization-prod.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ module.exports = (options = {}) => {
'redux',
'redux-thunk',
// // babel, webpack & other tools
// babel, webpack & other tools
// 'regenerator-runtime',
// // common libraries
// common libraries
// 'axios',
// 'classnames',
// 'history',
Expand All @@ -48,9 +48,25 @@ module.exports = (options = {}) => {
reuseExistingChunk: true,
test: new RegExp(
`[\\\\/]node_modules[\\\\/](${[
'@ant-design',
'antd',
'moments',
'@antd\\\\/icons'
'moment',
'rc-align',
'rc-animate',
'rc-calendar',
'rc-checkbox',
'rc-form',
'rc-menu',
'rc-notification',
'rc-pagination',
'rc-progress',
'rc-resize-observer',
'rc-select',
'rc-tabs',
'rc-tooltip',
'rc-trigger',
'rc-upload',
'rc-util'
].join('|')})[\\\\/]`
)
},
Expand Down
98 changes: 98 additions & 0 deletions test/cases/i18n/match-locale-id.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
const parseLocaleId = require('../../../packages/koot/i18n/parse-locale-id');

describe(`测试: i18n/根据输入的语种或语言列表,匹配项目语言包ID`, () => {
test(`有完整匹配时,结果正确`, async () => {
expect(parseLocaleId('zh-CN', ['en-US', 'zh-CN'])).toBe('zh-CN');
expect(parseLocaleId('zh-CN', ['zh_CN', 'en-US'])).toBe('zh_CN');
expect(parseLocaleId('zh-CN', ['zh-CN'])).toBe('zh-CN');
expect(parseLocaleId('zh', ['zh-CN', 'zh'])).toBe('zh');
expect(
parseLocaleId('ja,zh-CN;q=0.8,en;q=0.6', ['en-US', 'zh-CN'])
).toBe('zh-CN');
expect(
parseLocaleId('ja,zh-CN;q=0.8,en;q=0.6', ['zh-CN', 'en-US'])
).toBe('zh-CN');
expect(parseLocaleId('ja,zh-CN;q=0.8,en;q=0.6', ['zh-CN'])).toBe(
'zh-CN'
);
expect(
parseLocaleId('zh-CN,zh;q=0.8,en;q=0.6', ['en-US', 'zh-CN'])
).toBe('zh-CN');
expect(
parseLocaleId('zh-CN,zh;q=0.8,en;q=0.6', ['zh-CN', 'en-US'])
).toBe('zh-CN');
expect(parseLocaleId('zh-CN,zh;q=0.8,en;q=0.6', ['zh-CN'])).toBe(
'zh-CN'
);
expect(parseLocaleId(['ja', 'zh-CN'], ['en-US', 'zh-CN'])).toBe(
'zh-CN'
);
expect(parseLocaleId(['ja', 'zh-CN'], ['zh-CN', 'en-US'])).toBe(
'zh-CN'
);
expect(parseLocaleId(['ja', 'zh-CN'], ['zh-CN'])).toBe('zh-CN');
expect(parseLocaleId(['zh-CN', 'ja'], ['en-US', 'zh-CN'])).toBe(
'zh-CN'
);
expect(parseLocaleId(['zh-CN', 'ja'], ['zh-CN', 'en-US'])).toBe(
'zh-CN'
);
expect(parseLocaleId(['zh-CN', 'ja'], ['zh-CN'])).toBe('zh-CN');
});
test(`没有完整匹配时,结果正确`, async () => {
expect(parseLocaleId('zh', ['en-US', 'zh-CN'])).toBe('zh-CN');
expect(parseLocaleId('zh', ['zh-CN', 'en-US'])).toBe('zh-CN');
expect(parseLocaleId('zh', ['zh-CN'])).toBe('zh-CN');
expect(parseLocaleId('zh', ['en-US', 'zh-CN', 'zh-TW'])).toBe('zh-CN');
expect(parseLocaleId('zh', ['zh_TW', 'zh-CN', 'en-US'])).toBe('zh_TW');
expect(parseLocaleId('zh-CN', ['en-US', 'zh'])).toBe('zh');
expect(parseLocaleId('zh-CN', ['zh', 'en-US'])).toBe('zh');
expect(parseLocaleId('zh-CN', ['zh'])).toBe('zh');
expect(parseLocaleId('zh-CN', ['en-US', 'zh-TW'])).toBe('zh-TW');
expect(parseLocaleId('zh-CN', ['zh-TW', 'en-US'])).toBe('zh-TW');
expect(parseLocaleId('zh-CN', ['zh-TW'])).toBe('zh-TW');
});
test(`之前的条件,大小写混用,连接线混用,结果正确`, async () => {
expect(parseLocaleId('zh-CN', ['en-US', 'zH-cn'])).toBe('zH-cn');
expect(parseLocaleId('zh-CN', ['zh-cn', 'en-US'])).toBe('zh-cn');
expect(parseLocaleId('zh-CN', ['zh-Cn'])).toBe('zh-Cn');
expect(
parseLocaleId('ja,zh-CN;q=0.8,en;q=0.6', ['en-US', 'Zh-CN'])
).toBe('Zh-CN');
expect(
parseLocaleId('ja,zh-cn;q=0.8,en;q=0.6', ['zH-CN', 'en-US'])
).toBe('zH-CN');
expect(parseLocaleId('ja,zh-cn;q=0.8,en;q=0.6', ['zh-cN'])).toBe(
'zh-cN'
);
expect(
parseLocaleId('zh-cn,zh;q=0.8,en;q=0.6', ['en-US', 'zh-CN'])
).toBe('zh-CN');
expect(
parseLocaleId('zh-cn,zh;q=0.8,en;q=0.6', ['zh-CN', 'en-US'])
).toBe('zh-CN');
expect(parseLocaleId('zh-cn,zh;q=0.8,en;q=0.6', ['zh_CN'])).toBe(
'zh_CN'
);
expect(parseLocaleId(['ja', 'zh-CN'], ['en-US', 'ZH-CN'])).toBe(
'ZH-CN'
);
expect(parseLocaleId(['ja', 'zh-CN'], ['ZH-CN', 'en-US'])).toBe(
'ZH-CN'
);
expect(parseLocaleId(['ja', 'zh-CN'], ['ZH-CN'])).toBe('ZH-CN');
expect(parseLocaleId(['zh-CN', 'ja'], ['en-US', 'zH-CN'])).toBe(
'zH-CN'
);
expect(parseLocaleId(['zh-CN', 'ja'], ['zH-CN', 'en-US'])).toBe(
'zH-CN'
);
expect(parseLocaleId(['zh-CN', 'ja'], ['zH-CN'])).toBe('zH-CN');
expect(parseLocaleId('zh', ['zh_Tw', 'zh-CN', 'en-US'])).toBe('zh_Tw');
});
test(`没有匹配时,结果正确`, async () => {
expect(parseLocaleId('ja', ['en-US', 'zh-CN'])).toBe('en-US');
expect(parseLocaleId('ja,zh-CN;q=0.8', ['en-US'])).toBe('en-US');
expect(parseLocaleId(['ja', 'zh-CN'], ['en-US'])).toBe('en-US');
});
});
5 changes: 5 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ const run = async () => {
name: 'Lib: koot-css-loader',
value: './test/cases/libs/koot-css-loader'
},
new inquirer.Separator(),
{
name: 'Functions: koot/i18n',
value: './test/cases/i18n'
},
new inquirer.Separator()
],
default: 'full'
Expand Down

0 comments on commit 571e1b7

Please sign in to comment.