Skip to content

Commit

Permalink
Merge pull request #65 from enb-bem/refact
Browse files Browse the repository at this point in the history
Refactoring
  • Loading branch information
blond committed Aug 10, 2015
2 parents ec73026 + 7a7bbf5 commit 930267f
Show file tree
Hide file tree
Showing 15 changed files with 242 additions and 161 deletions.
2 changes: 1 addition & 1 deletion .jscs.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module.exports = {
excludeFiles: [
'node_modules',
'coverage',
'exlib/sax.js',
'exlib',
'test/fixtures/*'
],
requireSpaceAfterKeywords: ['if', 'else', 'for', 'while', 'do', 'switch', 'return', 'try', 'catch'],
Expand Down
2 changes: 1 addition & 1 deletion .jshintignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
node_modules
coverage
exlib/sax.js
exlib
test/fixtures
67 changes: 0 additions & 67 deletions lib/compile.js

This file was deleted.

67 changes: 67 additions & 0 deletions lib/compile/bem-bl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
var EOL = require('os').EOL,
tanker = require('../tanker');

/**
* Compiles code of i18n function for bem-bl localization system.
*
* Important: XML strings translates with tanker.
*
* @param {String} core — code that contains i18n core from bem-bl library.
* @param {Object} keysets — a sets of keys and their values (translations) for a language to internationalization.
* @param {String} lang — language of keysets.
* @returns {String}
*/
module.exports = function (core, keysets, lang) {
var scopes = Object.keys(keysets).sort();

return [
'(function () {',
'var __bem__ = {};',
'(function (BEM) {',
core,
'}(__bem__));',
'var i18n = __bem__.I18N;',
// initialize i18n with keysets
scopes.map(function (scope) {
var keyset = keysets[scope];

return buildCodeWithDecl(keyset, scope, lang);
}).join(EOL),
'i18n.lang(\'' + lang + '\');',
'return i18n;',
'}())'
].join(EOL);
};

/**
* Returns code with `i18n.decl` function that initializes an `i18n` instance with keyset.
*
* @param {Object} keyset — a set of keys and their values (translations) for a language to internationalization.
* @param {String} scope — scope of keyset.
* @param {String} lang — language of keyset.
* @returns {String|*}
* @private
* @example
* i18n.decl('scope', {
* key: 'translation',
* hello: function(params) { return "Hello " + params["who"] + "!" }'
* }, { lang: 'en' });
*/
function buildCodeWithDecl(keyset, scope, lang) {
var keys = Object.keys(keyset),
lastIndex = keys.length - 1;

return [
'i18n.decl(\'' + scope + '\', {',
keys.map(function (key, i) {
var rawValue = keyset[key], // value can be string with translation
// or xml code for parameterization
value = tanker.xmlToJs(rawValue), // string with translation
// or code of function for parameterization
endSymbol = i === lastIndex ? '' : ',';

return JSON.stringify(key) + ':' + value + endSymbol;
}).join(EOL),
'}, { "lang": "' + lang + '" });'
].join(EOL);
}
13 changes: 13 additions & 0 deletions lib/compile/bem-core.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
var serialize = require('serialize-javascript');

/**
* Compiles code of i18n function for bem-core localization system.
*
* @param {String} core — code that contains i18n core from bem-core library
* @param {Object} keysets — a sets of keys and their values (translations) for a language to internationalization
*
* @returns {String}
*/
module.exports = function (core, keysets) {
return '((' + core + ')()).decl(' + serialize(keysets) + ')';
};
25 changes: 25 additions & 0 deletions lib/compile/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
var compileForBemBL = require('./bem-bl'),
compileForBemCore = require('./bem-core');

/**
* Compiles code of i18n for `bem-core` or `bem-bl` localization system.
*
* Important: XML strings for `bem-bl` translates with `tanker`. `bem-core` not support XML strings.
*
* @param {String} core — code that contains i18n core from bem-core or bem-bl library.
* @param {Object} keysets — a sets of keys and their values (translations) for a language to internationalization.
* @param {Object} opts
* @param {String} opts.version — version of core: `bem-bl` or `bem-core`.
* @param {String} [opts.language] — language of keysets.
*
* @returns {String}
*/
module.exports = function (core, keysets, opts) {
if (opts.version === 'bem-core') {
return compileForBemCore(core, keysets);
}

if (opts.version === 'bem-bl') {
return compileForBemBL(core, keysets, opts.language);
}
};
35 changes: 33 additions & 2 deletions lib/keysets.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,33 @@
var path = require('path'),
asyncRequire = require('enb/lib/fs/async-require'),
dropRequireCache = require('enb/lib/fs/drop-require-cache');

/**
* Reads file with keysets.
*
* @param {String} filename — path to file with keysets.
* @param {Object} [cache] — instance of {@link Cache}.
* @param {Object} [root] — path to directory of project root.
* @returns {Promise}
*/
function read(filename, cache, root) {
var cacheKey = 'keysets-file-' + (root ? path.relative(root, filename) : filename),
needRebuildFile = cache ? cache.needRebuildFile(cacheKey, filename) : true;

if (needRebuildFile) {
dropRequireCache(require, filename);

return asyncRequire(filename)
.then(function (keysets) {
cache.cacheFileInfo(cacheKey, filename);

return keysets;
});
} else {
return asyncRequire(filename);
}
}

/**
* Parses object with keysets.
*
Expand All @@ -13,7 +43,7 @@
function parse(keysets) {
var core,
data = {},
version = 2;
version = 'bem-core';

// Pull core from source keysets
keysets && Object.keys(keysets).forEach(function (scope) {
Expand All @@ -28,7 +58,7 @@ function parse(keysets) {
} else if (scope === 'all') {
var possibleCore = keysets[scope][''];
if (possibleCore && (typeof possibleCore === 'string') && possibleCore.match(/BEM\.I18N/g)) {
version = 1;
version = 'bem-bl';
core = possibleCore;
}
} else {
Expand All @@ -47,4 +77,5 @@ function parse(keysets) {
};
}

exports.read = read;
exports.parse = parse;
2 changes: 1 addition & 1 deletion exlib/tanker.js → lib/tanker.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
var sax = require('./sax');
var sax = require('../exlib/sax');

/**
* Надстройка над функцией translate для обратной совместимости.
Expand Down
46 changes: 24 additions & 22 deletions techs/i18n-js.js → techs/i18n.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
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');

Expand Down Expand Up @@ -57,28 +54,17 @@ module.exports = require('enb/lib/build-flow').create()
.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
return this._readKeysetsFile(keysetsFilename)
.then(function (sources) {
var parsed = keysets.parse(sources);
var parsed = keysets.parse(sources),
opts = {
version: parsed.version,
language: this._lang
};

return [
'(function (global) {',
' var __i18n__ = ' + compile(parsed, this._lang) + ',',
' var __i18n__ = ' + compile(parsed.core, parsed.keysets, opts) + ',',
' defineAsGlobal = true;',
'',
' // CommonJS',
Expand All @@ -103,4 +89,20 @@ module.exports = require('enb/lib/build-flow').create()
].join(EOL);
}, this);
})
.methods({
/**
* Reads file with keysets.
*
* @param {String} filename — path to file with keysets.
* @returns {Promise}
* @private
*/
_readKeysetsFile: function (filename) {
var node = this.node,
root = node.getRootDir(),
cache = node.getNodeCache(this._target);

return keysets.read(filename, cache, root);
}
})
.createTech();
39 changes: 17 additions & 22 deletions techs/keysets-xml.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
var EOL = require('os').EOL,
path = require('path'),
domjs = require('dom-js'),
asyncRequire = require('enb/lib/fs/async-require'),
dropRequireCache = require('enb/lib/fs/drop-require-cache');
keysets = require('../lib/keysets'),
domjs = require('dom-js');

/**
* @class KeysetsXMLTech
Expand Down Expand Up @@ -56,24 +54,7 @@ module.exports = require('enb/lib/build-flow').create()
.defineRequiredOption('lang')
.useSourceFilename('keysetsTarget', '?.keysets.{lang}.js')
.builder(function (keysetsFilename) {
var node = this.node,
cache = node.getNodeCache(this._target),
basename = path.basename(keysetsFilename),
cacheKey = 'keysets-file-' + basename,
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 (keysets) {
return this._readKeysetsFile(keysetsFilename).then(function (keysets) {
var lang = this._lang,
res = Object.keys(keysets).sort().reduce(function (prev, keysetName) {
var keyset = keysets[keysetName];
Expand Down Expand Up @@ -105,6 +86,20 @@ module.exports = require('enb/lib/build-flow').create()
},
getAppendXml: function () {
return EOL + '</tanker>';
},
/**
* Reads file with keysets.
*
* @param {String} filename — path to file with keysets.
* @returns {Promise}
* @private
*/
_readKeysetsFile: function (filename) {
var node = this.node,
root = node.getRootDir(),
cache = node.getNodeCache(this._target);

return keysets.read(filename, cache, root);
}
})
.createTech();
Loading

0 comments on commit 930267f

Please sign in to comment.