Skip to content

Commit a7ee911

Browse files
author
Alexej Yaroshevich
committed
v4.0.0 fixes
- Added global matcher support: `beforeEach` and `afterEach` (bem/bh#121). - Added `ctx.process` method (bem/bh#135). - Add `i-bem` class to element with `js` (bem/bh#122). - No-base modifier classes supported (bem/bh#132). - `processBemJson` now return standart BEMJSON (bem/bh#96). Changelog bem/bh@ee446ea
1 parent 72d9e08 commit a7ee911

16 files changed

+504
-171
lines changed

src/BH.php

+136-81
Large diffs are not rendered by default.

src/Context.php

+11-15
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ function tParam ($key, $value = null, $force = false) {
180180
* @param BemJson $bemJson
181181
* @return array
182182
*/
183-
function apply ($bemJson) {
183+
function process ($bemJson) {
184184
$prevCtx = $this->ctx;
185185
$prevNode = $this->node;
186186
$res = $this->bh->processBemJson($bemJson, $prevCtx->block);
@@ -214,19 +214,15 @@ function applyBase () {
214214
$node = $this->node;
215215
$json = $node->json;
216216

217-
if (!$json->elem && isset($json->mods)) {
218-
$json->blockMods = $json->mods;
219-
}
220-
221217
$block = $json->block;
222-
$blockMods = $json->blockMods;
218+
$blockMods = $json->mods;
223219

224220
$fm = $this->bh->getMatcher();
225221
$subRes = $fm($this, $json);
226222
if ($subRes !== null) {
227223
$this->ctx = $node->arr[$node->index] = $node->json = JsonCollection::normalize($subRes);
228-
$node->blockName = $block; // need check
229-
$node->blockMods = $blockMods;
224+
$node->block = $block; // need check
225+
$node->mods = $blockMods;
230226
}
231227

232228
return $this;
@@ -279,13 +275,14 @@ function generateId () {
279275
* @return string|null|Context
280276
*/
281277
function mod ($key, $value = null, $force = false) {
278+
$field = $this->ctx->elem ? 'elemMods' : 'mods';
282279
if (func_num_args() > 1) {
283-
$mods = $this->ctx->mods;
280+
$mods = $this->ctx->$field;
284281
$mods->$key = !key_exists($key, $mods) || $force ? $value : $mods->$key;
285282
return $this;
286283
}
287-
return isset($this->ctx->mods) && key_exists($key, $this->ctx->mods)
288-
? $this->ctx->mods->$key : null;
284+
return isset($this->ctx->$field) && key_exists($key, $this->ctx->$field)
285+
? $this->ctx->$field->$key : null;
289286
}
290287

291288
/**
@@ -304,16 +301,15 @@ function mod ($key, $value = null, $force = false) {
304301
* @return array|Context
305302
*/
306303
function mods ($values = null, $force = false) {
307-
$mods = $this->ctx->mods;
304+
$field = $this->ctx->elem ? 'elemMods' : 'mods';
305+
$mods = $this->ctx->$field;
308306
if ($values === null) {
309307
return $mods;
310308
}
311309

312-
// d(compact('mods', 'values', 'force'));
313-
$this->ctx->mods = $force ?
310+
$this->ctx->$field = $force ?
314311
$this->extend($mods, $values) :
315312
$this->extend(is_object($values) ? $values : new Mods($values), $mods);
316-
// d('res', $this->ctx->mods, "\n", (array)($this->ctx->mods));
317313

318314
return $this;
319315
}

src/Json.php

+5-6
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,6 @@ class Json {
4545
/** @var Mods */
4646
protected $mods;
4747
/** @var Mods */
48-
protected $blockMods;
49-
/** @var Mods */
5048
protected $elemMods;
5149

5250
public $_stop = false;
@@ -82,7 +80,7 @@ public function setContent ($content) {
8280
}
8381

8482
public function __get ($name) {
85-
if ($name === 'mods' || $name === 'blockMods' || $name === 'elemMods') {
83+
if ($name === 'mods' || $name === 'elemMods') {
8684
if (is_null($this->$name)) {
8785
$this->$name = new Mods();
8886
}
@@ -92,15 +90,16 @@ public function __get ($name) {
9290
}
9391

9492
public function __set ($name, $value) {
95-
if ($name === 'mods' || $name === 'blockMods' || $name === 'elemMods') {
96-
$this->$name = is_array($value) ? new Mods($value) : $value;
93+
if ($name === 'mods' || $name === 'elemMods') {
94+
$this->$name = empty($value) ? null
95+
: is_array($value) ? new Mods($value) : $value;
9796
} else {
9897
$this->$name = $value;
9998
}
10099
}
101100

102101
public function __isset ($name) {
103-
if ($name === 'mods' || $name === 'blockMods' || $name === 'elemMods') {
102+
if ($name === 'mods' || $name === 'elemMods') {
104103
return !empty($this->$name);
105104
}
106105
return isset($this->$name);

src/Step.php

+4-4
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ class Step {
77
public $json;
88
public $arr;
99
public $index;
10-
public $blockName;
11-
public $blockMods;
10+
public $block;
11+
public $mods;
1212
public $position;
1313
public $parentNode;
1414

@@ -21,8 +21,8 @@ function __construct ($json, $arr, $index, $blockName, $blockMods, $position = 0
2121
$this->json = $json;
2222
$this->arr = $arr;
2323
$this->index = $index;
24-
$this->blockName = $blockName;
25-
$this->blockMods = $blockMods;
24+
$this->block = $blockName;
25+
$this->mods = $blockMods;
2626
$this->position = $position;
2727
$this->parentNode = $parentNode;
2828
}

tests/apply.test.php

+34-34
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
use BEM\BH;
44

5-
class applyTest extends PHPUnit_Framework_TestCase {
5+
class bhApplyTest extends PHPUnit_Framework_TestCase {
66

77
/**
88
* @before
@@ -26,38 +26,38 @@ function test_it_should_return_empty_string_on_falsy_template_result () {
2626
$this->bh->apply(['block' => 'link']));
2727
}
2828

29-
function test_it_should_return_valid_processed_element () {
30-
$this->bh->match('button', function ($ctx) {
31-
$inner = $ctx->apply(['block' => 'button', 'elem' => 'inner']);
32-
// \BEM\d($inner);
33-
$this->assertEquals($inner->tag, 'span');
34-
$ctx->content($inner);
35-
});
36-
$this->bh->match('button__inner', function ($ctx) {
37-
$ctx->tag('span');
38-
// \BEM\d($ctx);
39-
});
40-
$this->assertEquals(
41-
'<div class="button">' .
42-
'<span class="button__inner"></span>' .
43-
'</div>',
44-
$this->bh->apply(['block' => 'button'])
45-
);
46-
}
29+
// function test_it_should_return_valid_processed_element () {
30+
// $this->bh->match('button', function ($ctx) {
31+
// $inner = $ctx->apply(['block' => 'button', 'elem' => 'inner']);
32+
// // \BEM\d($inner);
33+
// $this->assertEquals($inner->tag, 'span');
34+
// $ctx->content($inner);
35+
// });
36+
// $this->bh->match('button__inner', function ($ctx) {
37+
// $ctx->tag('span');
38+
// // \BEM\d($ctx);
39+
// });
40+
// $this->assertEquals(
41+
// '<div class="button">' .
42+
// '<span class="button__inner"></span>' .
43+
// '</div>',
44+
// $this->bh->apply(['block' => 'button'])
45+
// );
46+
// }
4747

48-
function test_it_should_return_valid_processed_element_with_no_block_name () {
49-
$this->bh->match('button', function ($ctx) {
50-
$inner = $ctx->apply(['elem' => 'inner']);
51-
$this->assertEquals($inner->tag, 'span');
52-
$ctx->content($inner);
53-
});
54-
$this->bh->match('button__inner', function ($ctx) {
55-
$ctx->tag('span');
56-
});
57-
$this->assertEquals(
58-
'<div class="button">' .
59-
'<span class="button__inner"></span>' .
60-
'</div>',
61-
$this->bh->apply(['block' => 'button']));
62-
}
48+
// function test_it_should_return_valid_processed_element_with_no_block_name () {
49+
// $this->bh->match('button', function ($ctx) {
50+
// $inner = $ctx->apply(['elem' => 'inner']);
51+
// $this->assertEquals($inner->tag, 'span');
52+
// $ctx->content($inner);
53+
// });
54+
// $this->bh->match('button__inner', function ($ctx) {
55+
// $ctx->tag('span');
56+
// });
57+
// $this->assertEquals(
58+
// '<div class="button">' .
59+
// '<span class="button__inner"></span>' .
60+
// '</div>',
61+
// $this->bh->apply(['block' => 'button']));
62+
// }
6363
}

tests/applyBase.test.php

+14
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,20 @@ function test_it_should_apply_templates_for_new_mod () {
2525
);
2626
}
2727

28+
function test_it_should_apply_base_matcher_for_element () {
29+
$this->bh->match('button__control', function ($ctx) {
30+
$ctx->mod('type', 'span');
31+
$ctx->applyBase();
32+
});
33+
$this->bh->match('button__control_type_span', function ($ctx) {
34+
$ctx->tag('span');
35+
});
36+
$this->assertEquals(
37+
'<span class="button__control button__control_disabled button__control_type_span"></span>',
38+
$this->bh->apply([ 'block' => 'button', 'elem' => 'control', 'mods' => [ 'disabled' => true ] ])
39+
);
40+
}
41+
2842
function test_it_should_apply_base_matcher_for_content () {
2943
$this->bh->match('button', function ($ctx) {
3044
$ctx->content([

tests/match.test.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ function test_it_should_match_string_mods () {
9090
);
9191
}
9292

93-
function it_should_match_new_mods () {
93+
function test_it_should_match_new_mods () {
9494
$this->bh->match('button_disabled', function($ctx) {
9595
$ctx->tag('span');
9696
});
@@ -103,7 +103,7 @@ function it_should_match_new_mods () {
103103
$this->bh->apply([ 'block' => 'button' ]));
104104
}
105105

106-
function it_should_match_new_mods2 () {
106+
function test_it_should_match_new_mods2 () {
107107
$this->bh->match('button_visible', function($ctx) {
108108
$ctx->tag('a');
109109
});

tests/matchGlobal.test.php

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
<?php
2+
3+
use BEM\BH;
4+
5+
class bhMatchGlobalTest extends PHPUnit_Framework_TestCase {
6+
7+
/**
8+
* @before
9+
*/
10+
function setupBhInstance () {
11+
$this->bh = new BH();
12+
}
13+
14+
function test_it_should_apply_beforeEach_template () {
15+
$this->bh->beforeEach(function($ctx) {
16+
$ctx->tag('b');
17+
$ctx->bem(false);
18+
});
19+
$this->assertEquals(
20+
'<b>foo</b><b></b><b></b>',
21+
$this->bh->apply([
22+
[ 'content' => 'foo' ],
23+
[ 'block' => 'button' ],
24+
[ 'block' => 'input', 'elem' => 'control' ]
25+
])
26+
);
27+
}
28+
29+
function test_it_should_match_beforeEach_before_other_template () {
30+
$this->bh->match('button', function($ctx) {
31+
$ctx->tag('button');
32+
});
33+
$this->bh->beforeEach(function($ctx) {
34+
$ctx->tag('span');
35+
});
36+
$this->bh->match('button', function($ctx) {
37+
$ctx->tag('strong');
38+
});
39+
$this->assertEquals(
40+
'<span class="button"></span>',
41+
$this->bh->apply([ 'block' => 'button' ])
42+
);
43+
}
44+
45+
function test_it_should_apply_several_beforeEach_templates_in_proper_order () {
46+
$this->bh->beforeEach(function($ctx, $json) {
47+
$json->cls .= '2';
48+
});
49+
$this->bh->beforeEach(function($ctx, $json) {
50+
$json->cls .= '1';
51+
});
52+
$this->assertEquals(
53+
'<div class="button foo12"></div>',
54+
$this->bh->apply([ 'block' => 'button', 'cls' => 'foo' ])
55+
);
56+
}
57+
58+
59+
function test_it_should_apply_afterEach_template () {
60+
$this->bh->afterEach(function ($ctx) {
61+
$ctx->tag('b');
62+
$ctx->bem(false);
63+
});
64+
$this->assertEquals(
65+
'<b>foo</b><b></b><b></b>',
66+
$this->bh->apply([
67+
[ 'content' => 'foo' ],
68+
[ 'block' => 'button' ],
69+
[ 'block' => 'input', 'elem' => 'control' ]
70+
])
71+
);
72+
}
73+
74+
function test_it_should_match_afterEach_after_other_template () {
75+
$this->bh->match('button', function ($ctx) {
76+
$ctx->tag('button', true);
77+
});
78+
$this->bh->afterEach(function ($ctx) {
79+
$ctx->tag('span', true);
80+
});
81+
$this->bh->match('button', function ($ctx) {
82+
$ctx->tag('strong', true);
83+
});
84+
85+
$this->assertEquals(
86+
'<span class="button"></span>',
87+
$this->bh->apply([ 'block' => 'button' ])
88+
);
89+
}
90+
91+
function test_it_should_apply_several_afterEach_templates_in_proper_order () {
92+
$this->bh->afterEach(function ($ctx, $json) {
93+
$json->cls .= '2';
94+
});
95+
$this->bh->afterEach(function ($ctx, $json) {
96+
$json->cls .= '1';
97+
});
98+
$this->assertEquals(
99+
'<div class="button foo12"></div>',
100+
$this->bh->apply([ 'block' => 'button', 'cls' => 'foo' ])
101+
);
102+
}
103+
}

0 commit comments

Comments
 (0)