diff --git a/lib/bemhtml/compiler.js b/lib/bemhtml/compiler.js index e495ee79..448f2bda 100644 --- a/lib/bemhtml/compiler.js +++ b/lib/bemhtml/compiler.js @@ -10,7 +10,7 @@ function Compiler(options) { this.options = options || {}; this.matches = { - match: true, block: true, elem: true, mode: true, + match: true, block: true, elem: true, mode: true, mod: true, def: true, tag: true, attrs: true, cls: true, js: true, jsAttr: true, bem: true, mix: true, content: true }; @@ -133,6 +133,31 @@ Compiler.prototype.getBinop = function getBinop(name, args) { rhs = args[0]; assert.equal(args.length, 1, 'block/elem/mode predicates must have only one argument'); + } else if (name === 'mod') { + assert.equal(args.length, 2, + 'mod() predicates must have two arguments'); + // Modificator predicate + return [{ + type: 'MemberExpression', + computed: false, + object: { type: 'ThisExpression' }, + property: { type: 'Identifier', name: 'mods' } + }, { + type: 'BinaryExpression', + operator: '===', + left: { + type: 'MemberExpression', + computed: true, + object: { + type: 'MemberExpression', + computed: false, + object: { type: 'ThisExpression' }, + property: { type: 'Identifier', name: 'mods' } + }, + property: args[0] + }, + right: args[1] + }]; } else { // Mode predicates assert.equal(args.length, 0, @@ -142,7 +167,7 @@ Compiler.prototype.getBinop = function getBinop(name, args) { } assert(lhs && rhs); - return { + return [{ type: 'BinaryExpression', operator: '===', left: { @@ -152,7 +177,7 @@ Compiler.prototype.getBinop = function getBinop(name, args) { property: { type: 'Identifier', name: lhs } }, right: rhs - }; + }]; }; Compiler.prototype.replaceCustom = function replaceCustom(ast) { @@ -172,7 +197,7 @@ Compiler.prototype.replaceCustom = function replaceCustom(ast) { return { type: 'CallExpression', callee: { type: 'Identifier', name: 'match' }, - arguments: [this.getBinop(name, ast.arguments)], + arguments: this.getBinop(name, ast.arguments), bemMarked: true }; } else if (callee.type === 'MemberExpression') { @@ -193,7 +218,7 @@ Compiler.prototype.replaceCustom = function replaceCustom(ast) { object: callee.object, property: { type: 'Identifier', name: 'match' } }, - arguments: [this.getBinop(name, ast.arguments)], + arguments: this.getBinop(name, ast.arguments), bemMarked: true }; } diff --git a/lib/bemhtml/runtime.js b/lib/bemhtml/runtime.js index 0c56c905..8b116c47 100644 --- a/lib/bemhtml/runtime.js +++ b/lib/bemhtml/runtime.js @@ -50,6 +50,7 @@ module.exports = function() { fn.block = block; fn.elem = elem; fn.mode = mode; + fn.mod = mod; fn.def = def; fn.tag = tag; fn.attrs = attrs; @@ -81,6 +82,10 @@ module.exports = function() { return match.call(this, __$that._mode === name); }; + function mod(name, value) { + return match.call(this, __$that.mods, __$that.mods[name] === value); + } + function def() { return mode.call(this, 'default'); }; function tag() { return mode.call(this, 'tag'); }; function attrs() { return mode.call(this,'attrs'); }; diff --git a/package.json b/package.json index e2f6d51e..4a0dbeae 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "esprima": "~1.0.2", "ometajs": "~3.2.2", "uglify-js": "~2.3.2", - "xjst": "~0.7.0" + "xjst": "~0.7.1" }, "devDependencies": { "mocha": "~1.9.0", diff --git a/test/api-test.js b/test/api-test.js index a8a66582..aca1b733 100644 --- a/test/api-test.js +++ b/test/api-test.js @@ -51,4 +51,13 @@ describe('BEM.js compiler', function() { ibem: false }); }); + + it('should understand mod()', function() { + test(function() { + match()('not ok'); + block('b1').mod('a', 'b')('ok'); + }, { block: 'b1', mods: { a: 'b' } }, 'ok', { + ibem: false + }); + }); });