Skip to content

Commit

Permalink
Merge a09913e into afcd573
Browse files Browse the repository at this point in the history
  • Loading branch information
tormozz48 committed Jun 4, 2015
2 parents afcd573 + a09913e commit 7096177
Show file tree
Hide file tree
Showing 13 changed files with 767 additions and 277 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
node_modules
coverage
npm-debug.log
3 changes: 2 additions & 1 deletion .jscs.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ module.exports = {
excludeFiles: [
'node_modules',
'exlib',
'coverage'
'coverage',
'test/fixtures'
],
requireSpaceAfterKeywords: ['if', 'else', 'for', 'while', 'do', 'switch', 'return', 'try', 'catch'],
requireSpaceBeforeBlockStatements: true,
Expand Down
1 change: 1 addition & 0 deletions .jshintignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
node_modules
exlib
coverage
test/fixtures
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ npm install --save-dev enb-bem-i18n
----------

* [i18n-keysets-xml](#i18n-keysets-xml)
* [i18n-lang-js](#i18n-lang-js)
* [i18n-js](#i18n-js)
* [i18n-merge-keysets](#i18n-merge-keysets)
* [i18n-bemjson-to-html](#i18n-bemjson-to-html)

### i18n-lang-js
### i18n-js

Собирает `?.lang.<язык>.js`-файлы на основе `?.keysets.<язык>.js`-файлов.

Expand All @@ -43,8 +43,8 @@ npm install --save-dev enb-bem-i18n

```javascript
nodeConfig.addTechs([
[ require('enb-bem-i18n/techs/i18n-lang-js'), { lang: 'all'} ],
[ require('enb-bem-i18n/techs/i18n-lang-js'), { lang: '{lang}'} ]
[ require('enb-bem-i18n/techs/i18n-js'), { lang: 'all'} ],
[ require('enb-bem-i18n/techs/i18n-js'), { lang: '{lang}'} ]
]);
```

Expand Down
67 changes: 67 additions & 0 deletions lib/compile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
var EOL = require('os').EOL,
format = require('util').format,
serialize = require('serialize-javascript'),
tanker = require('../exlib/tanker');

/**
* Compile code of i18n.
*
* @param {Object} parsed info from keysets file,
* @param {String} language - language of keysets,
* example: `{ scope: { key: 'val' } }`. The value can be a function,
* example: `{ scope: { key: function (params, i18n) { return 'res'; } } }`.
*
* @returns {String}
*/
module.exports = function (parsed, language) {
return parsed.version === 2 ?
'((' + parsed.core + ')()).decl(' + serialize(parsed.keysets) + ')' :
compileForVersion1(parsed.core, parsed.keysets, language);
};

/**
* Compile i18n function for bem-bl localization system
* @param {String} core - bem-core i18n core code string
* @param {Object} keysets - keysets hash
* @param {String} language - language of keysets
* @returns {String}
*/
function compileForVersion1(core, keysets, language) {
return [
'(function () {',
' var __bem__ = {};',
' (function (BEM) {',
core,
' }(__bem__));',
' var i18n = __bem__.I18N;',
Object.keys(keysets).sort().reduce(function (prev, keysetName, index) {
index === 0 && prev.push(EOL);
prev.push(_getKeysetBuildResult(keysetName, keysets[keysetName], language));
return prev;
}, []).join(EOL),
format('\ti18n.lang(\'%s\');', language),
' return i18n;',
'}())'
].join(EOL);
}

/**
* Return decl function call code string for given keyset scope
* @param {String} scopeName - name of scope
* @param {Object} scope hash object
* @param {String} lang - language option value
* @returns {string|*}
* @private
*/
function _getKeysetBuildResult(scopeName, scope, lang) {
var res = Object.keys(scope).reduce(function (prev, key, i, arr) {
tanker.xmlToJs(scope[key], function (js) {
var endSymbol = i === arr.length - 1 ? '' : ',';
prev.push(format('\t %s: %s%s', JSON.stringify(key), js, endSymbol));
});
return prev;
}, []);
res.unshift(format('\ti18n.decl(\'%s\', {', scopeName));
res.push(format('\t}, {%s\t "lang": "%s"%s\t});', EOL, lang, EOL));
return res.join(EOL);
}
51 changes: 51 additions & 0 deletions lib/keysets.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/**
* Parse object with keysets.
*
* It separates the core of i18n from other keysets. The core will be searched in the `i18n` scope with `i18n` key.
*
* @param {(Object.<String, String>|Object.<String, String, Function>)} keysets Object with keysets,
* example: `{ scope: { key: 'val' } }`. The value can be a function,
* example: `{ scope: { key: function (params, i18n) { return 'res'; } } }`.
*
* @throws Will throw an error if the core is not found.
*
* @returns {{ core: Function|String, keysets: (Object.<String, String>|Object.<String, String, Function>) }}
*/
function parse(keysets) {
var core,
data = {},
version = 2;

// Pull core from source keysets
keysets && Object.keys(keysets).forEach(function (scope) {
// Search core in `i18n:i18n`
if (scope === 'i18n') {
var keyset = keysets[scope];

if (keyset && typeof keyset.i18n === 'function') {
core = keyset.i18n;
}
// Search deprecated core in `all` scope
} else if (scope === 'all') {
var possibleCore = keysets[scope][''];
if (possibleCore && (typeof possibleCore === 'string') && possibleCore.match(/BEM\.I18N/g)) {
version = 1;
core = possibleCore;
}
} else {
data[scope] = keysets[scope];
}
});

if (!core) {
throw new Error('Core of i18n is not found!');
}

return {
core: core,
keysets: data,
version: version
};
}

exports.parse = parse;
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
},
"dependencies": {
"dom-js": "0.0.9",
"vow": "0.4.9"
"vow": "0.4.9",
"serialize-javascript": "1.0.0"
},
"devDependencies": {
"enb": ">= 0.11.0 < 1.0.0",
Expand Down
82 changes: 82 additions & 0 deletions techs/i18n-js.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/**
* i18n-js
* ============
*
* Собирает `?.lang.<язык>.js`-файлы на основе `?.keysets.<язык>.js`-файлов.
*
* Используется для локализации в JS с помощью BEM.I18N.
*
* **Опции**
*
* * *String* **target** — Результирующий таргет. По умолчанию — `?.lang.{lang}.js`.
* * *String* **lang** — Язык, для которого небходимо собрать файл.
*
* **Пример**
*
* ```javascript
* nodeConfig.addTechs([
* [ require('enb-bem-i18n/techs/i18n-js'), { lang: 'all'} ],
* [ require('enb-bem-i18n/techs/i18n-js'), { lang: '{lang}'} ],
* ]);
* ```
*/
var EOL = require('os').EOL,
path = require('path'),
asyncRequire = require('enb/lib/fs/async-require'),
dropRequireCache = require('enb/lib/fs/drop-require-cache'),
keysets = require('../lib/keysets'),
compile = require('../lib/compile');

module.exports = require('enb/lib/build-flow').create()
.name('i18n')
.target('target', '?.lang.{lang}.js')
.defineRequiredOption('lang')
.useSourceFilename('keysetsFile', '?.keysets.{lang}.js')
.builder(function (keysetsFilename) {
var cache = this.node.getNodeCache(this._target),
cacheKey = 'keysets-file-' + path.basename(keysetsFilename),
promise;

if (cache.needRebuildFile(cacheKey, keysetsFilename)) {
dropRequireCache(require, keysetsFilename);
promise = asyncRequire(keysetsFilename)
.then(function (keysets) {
cache.cacheFileInfo(cacheKey, keysetsFilename);

return keysets;
});
} else {
promise = asyncRequire(keysetsFilename);
}

return promise
.then(function (sources) {
var parsed = keysets.parse(sources);
return [
'(function () {',
' var __i18n__ = ' + compile(parsed, this._lang) + ',',
' defineAsGlobal = true;',
'',
' // CommonJS',
' if (typeof exports === "object") {',
' module.exports = __i18n__;',
' defineAsGlobal = false;',
' }',
'',
' // YModules',
' if (typeof modules === "object") {',
' modules.define("i18n", function (provide) {',
' provide(__i18n__);',
' });',
' defineAsGlobal = false;',
' }',
'',
' if (defineAsGlobal) {',
' global.BEM || (global.BEM = {});',
' global.BEM.I18N = __i18n__;',
' }',
'})();'
].join(EOL);
}, this);
})
.createTech();
86 changes: 0 additions & 86 deletions techs/i18n-lang-js.js

This file was deleted.

Loading

0 comments on commit 7096177

Please sign in to comment.