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
+ });
+ });
});