Skip to content

Commit

Permalink
Fixed #274: Support mod(m) and elemMod(em) without second argument
Browse files Browse the repository at this point in the history
  • Loading branch information
miripiruni committed Sep 21, 2016
1 parent 49a3e10 commit 5f5221f
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 5 deletions.
27 changes: 27 additions & 0 deletions docs/en/5-templates-syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,29 @@ The template are applied. Result:
<small class="item item_size_1"></small>
```

If second argument of `mod()` was omited then templates with any
non-empty value of modifier will be applied.

```js
block('a').mod('size').tag()('span');
```
Template will be applied to BEMJSON node if block equals to 'a' and
'size' modifier exists (equals neither to `undefined` nor to `''` nor to `false`
nor to `null`).

```js
{ block: 'a', mods: { size: 's' } },
{ block: 'a', mods: { size: 10 } },
```

But templates will not be applied to entities:
```js
{ block: 'a', mods: { size: '', theme: 'dark' } }
{ block: 'a', mods: { theme: 'dark' } },
{ block: 'a', mods: { size: undefined } },
{ block: 'a', mods: {} }
```

### elemMod

```js
Expand Down Expand Up @@ -158,6 +181,10 @@ Both templates are applied. Result:

`elemModVal` checked for compliance after converting to String. This behavior is similar to checking `modVal`.

Second argument of `elemMod()` can be omited. In this case
behavior of `elemMods()` will be the same as `mods()` without second argument.
The templates will be applied to BEMJSON nodes with modifier with any value.

### match

```js
Expand Down
31 changes: 29 additions & 2 deletions docs/ru/5-templates-syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ elem(name)
```js
/**
* @param {String} modName имя модификатора блока
* @param {String|Boolean} modVal значение модификатора блока
* @param {String|Boolean} [modVal] значение модификатора блока
*/
mod(modName, modVal)
```
Expand Down Expand Up @@ -117,12 +117,36 @@ block('item')
<small class="item item_size_1"></small>
```

Если второй аргумент `mod()` отсутствует тогда к узлу будут
применены шаблоны для соответствующего модификатора с любым значением.

```js
block('a').mod('size').tag()('span');
```
Шаблон будет применен к узлам BEMJSON-а, у которых блок равен 'a' и
присутствует модификатор 'size' (со значением отличным от `undefined`, `''`,
`false`, `null`).

```js
{ block: 'a', mods: { size: 's' } },
{ block: 'a', mods: { size: 10 } },
```

Но шаблоны не будут применены к узлам:
```js
{ block: 'a', mods: { size: '', theme: 'dark' } }
{ block: 'a', mods: { theme: 'dark' } },
{ block: 'a', mods: { size: undefined } },
{ block: 'a', mods: {} }
```


### elemMod

```js
/**
* @param {String} elemModName имя модификатора элемента
* @param {String|Boolean} elemModVal значение модификатора элемента
* @param {String|Boolean} [elemModVal] значение модификатора элемента
*/
elemMod(elemModName, elemModVal)
```
Expand Down Expand Up @@ -152,6 +176,9 @@ block('page').elem('content').elemMod('type', 'index').mix()({ block: 'mixed' })

`elemModVal` проверяются на соответствие после приведения к строке. Это поведение аналогично поведению проверки `modVal`.

Второй аргумент `elemMod()` также может отстуствовать, в этом случае поведение
аналогичное подпредикату `mod()` — шаблоны будут применены к узлам с модификатором любого значения.

### match

```js
Expand Down
8 changes: 7 additions & 1 deletion lib/bemxjst/match.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,19 @@ function MatchNested(template, pred) {

MatchNested.prototype.exec = function exec(context) {
var val = context;

for (var i = 0; i < this.keys.length - 1; i++) {
val = val[this.keys[i]];
if (!val)
return false;
}

return String(val[this.keys[i]]) === this.value;
val = val[this.keys[i]];

if (this.value === true)
return val !== undefined && val !== '' && val !== false && val !== null;

return String(val) === this.value;
};

function MatchCustom(template, pred) {
Expand Down
6 changes: 4 additions & 2 deletions lib/bemxjst/tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -367,11 +367,13 @@ Tree.prototype.mode = function mode(name) {
};

Tree.prototype.mod = function mod(name, value) {
return this.match(new PropertyMatch([ 'mods', name ], String(value)));
return this.match(new PropertyMatch([ 'mods', name ],
value === undefined ? true : String(value)));
};

Tree.prototype.elemMod = function elemMod(name, value) {
return this.match(new PropertyMatch([ 'elemMods', name ], String(value)));
return this.match(new PropertyMatch([ 'elemMods', name ],
value === undefined ? true : String(value)));
};

Tree.prototype.def = function def() {
Expand Down
22 changes: 22 additions & 0 deletions test/modes-elemmod-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,28 @@ describe('Modes elemMod(elemModName, elemModVal)', function() {
});

describe('elemModVal types', function() {
it('string should support elemMod with one argument', function() {
test(function() {
block('b').elem('e').elemMod('m').tag()('span');
},
[
{ block: 'b', elem: 'e', elemMods: { m: true } },
{ block: 'b', elem: 'e', elemMods: { m: 'test' } },
{ block: 'b', elem: 'e', elemMods: { m: 0 } },
{ block: 'b', elem: 'e', elemMods: { m: false } },
{ block: 'b', elem: 'e', elemMods: { m: null } },
{ block: 'b', elem: 'e', elemMods: { m: '' } },
{ block: 'b', elem: 'e', elemMods: { no: 'test' } }
],
'<span class="b__e b__e_m"></span>' +
'<span class="b__e b__e_m_test"></span>' +
'<span class="b__e b__e_m_0"></span>' +
'<div class="b__e"></div>' +
'<div class="b__e"></div>' +
'<div class="b__e"></div>' +
'<div class="b__e b__e_no_test"></div>');
});

it('number should match to string', function() {
test(function() {
block('b').elem('e').elemMod('em', 1).tag()('span');
Expand Down
22 changes: 22 additions & 0 deletions test/modes-mod-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,5 +83,27 @@ describe('Modes .mod(modName, modVal)', function() {
{ block: 'b', mods: { m: null } },
'<div class="b"></div>');
});

it('string should support mod with one argument', function() {
test(function() {
block('b').mod('m').tag()('span');
},
[
{ block: 'b', mods: { m: true } },
{ block: 'b', mods: { m: 'test' } },
{ block: 'b', mods: { m: 0 } },
{ block: 'b', mods: { m: false } },
{ block: 'b', mods: { m: null } },
{ block: 'b', mods: { m: '' } },
{ block: 'b', mods: { no: 'test' } }
],
'<span class="b b_m"></span>' +
'<span class="b b_m_test"></span>' +
'<span class="b b_m_0"></span>' +
'<div class="b"></div>' +
'<div class="b"></div>' +
'<div class="b"></div>' +
'<div class="b b_no_test"></div>');
});
});
});

0 comments on commit 5f5221f

Please sign in to comment.