function test_it_should_return_mix() { $this->bh->match('button', function ($ctx) { $this->assertEquals(JsonCollection::normalize(['block' => 'mix']), $ctx->mix()); }); $this->bh->apply(['block' => 'button', 'mix' => ['block' => 'mix']]); }
function test_itShouldGracefulyAppendAnyObjects() { $collection = JsonCollection::normalize(['1']); $collection->append(['block' => '2']); $collection->append('3'); $collection->append([['block' => '4', 'elem' => 'a'], ['block' => '5'], '6']); $collection->append([[['block' => '7']]]); $this->assertEquals(new JsonCollection(['1', new Json(['block' => '2']), '3', new Json(['block' => '4', 'elem' => 'a']), new Json(['block' => '5']), '6', new Json(['block' => '7'])]), $collection); }
/** * Раскрывает BEMJSON, превращая его из краткого в полный. * @param Json|array $bemJson * @param string [$blockName] * @param boolean [$ignoreContent] * @throws \Exception * @return Json */ public function processBemJson($bemJson, $blockName = null, $ignoreContent = null) { if (empty($bemJson)) { return is_array($bemJson) ? '<div></div>' : ''; } // trying to parse if (is_scalar($bemJson)) { // string? like '{...}' || '[{...}]' || '([...])' if (!is_string($bemJson)) { // return as is return (string) $bemJson; } // deprecated feature: $bemJson = trim($bemJson, "\n\t\r ()\v"); $c = $bemJson[0]; $l = $bemJson[strlen($bemJson) - 1]; if ($c === '{' && $l === '}' || $c === '[' && $l === ']') { // if it looks like json object - parse and process return $this->processBemJson(weakjson_decode($bemJson)); } else { // return as is return $bemJson; } } $resultArr = JsonCollection::normalize($bemJson); if (count($resultArr) > 1) { $resultArr = new \ArrayObject([$resultArr]); } $bemJson = $resultArr[0]; $steps = []; $steps[] = new Step($bemJson, $resultArr, 0, $blockName, null); if (!$this->matcherBuilt) { $this->buildMatcher(); } $processContent = !$ignoreContent; $infiniteLoopDetection = $this->infiniteLoopDetection; $ctx = new Context($this); // js: while (node = nodes.shift()) { while ($step = array_shift($steps)) { $json = $step->json; $blockName = $step->block; $blockMods = $step->mods; if ($json instanceof JsonCollection) { $j = 0; $arr = $json; foreach ($arr as $i => $child) { if (!is_object($child)) { continue; } // walk each bem node inside collection $steps[] = new Step($child, $arr, $i, $blockName, $blockMods, ++$j, $step); } $arr->_listLength = $j; $step->arr[$step->index] = $json; continue; } $stopProcess = false; if (is_scalar($json) || empty($json)) { // skip continue; } elseif ($json->elem) { $blockName = $json->block = $json->block ?: $blockName; if (!isset($json->elemMods)) { $json->elemMods = $json->mods; $json->mods = null; } $blockMods = $json->mods = isset($json->mods) ? $json->mods : $blockMods; } elseif ($json->block) { $blockName = $json->block; $blockMods = $json->mods; } if ($json instanceof Json) { if ($infiniteLoopDetection) { $json->_matcherCalls++; $this->matcherCalls++; if ($json->_matcherCalls > 100) { throw new \Exception('Infinite json loop detected at "' . $json->block . ($json->elem ? '__' . $json->elem : '') . '".'); } if ($this->matcherCalls > 1000) { throw new \Exception('Infinite matcher loop detected at "' . $json->block . ($json->elem ? '__' . $json->elem : '') . '".'); } } if (!$json->_stop) { $ctx->node = $step; $ctx->ctx = $json; $subRes = $this->matcherImpl($ctx, $json); if ($subRes !== null) { $json = JsonCollection::normalize($subRes); $step->json = $json; $step->block = $blockName; $step->mods = $blockMods; $steps[] = $step; $stopProcess = true; } } } if (!$stopProcess && $processContent && isset($json->content) && !is_scalar($json->content)) { $content = $json->content; $j = 0; foreach ($content as $i => $child) { if (is_scalar($child) || empty($child)) { continue; } $steps[] = new Step($child, $content, $i, $blockName, $blockMods, ++$j, $step); } $content->_listLength = $j; } } return $resultArr[0]; }
function test_it_should_use_elemMods_instead_of_mods_if_collision() { $this->assertEquals(JsonCollection::normalize(['block' => 'button', 'mods' => ['valid' => true], 'elem' => 'inner', 'elemMods' => ['disabled' => 'yes']])[0], $this->bh->processBemJson(['block' => 'button', 'mods' => ['valid' => true], 'elem' => 'inner', 'elemMods' => ['disabled' => 'yes']])); }