/** * @covers generateCss */ public function testGenerateCss() { $env = new ILess_Environment(); $output = new ILess_Output(); $s = new ILess_Node_Selector(array(new ILess_Node_Element(' ', 'foobar')), array()); $s->generateCss($env, $output); $this->assertEquals(" foobar", $output->toString()); }
/** * @see ILess_Node::compile */ public function compile(ILess_Environment $env, $arguments = null, $important = null) { $rules = array(); $match = false; $isOneFound = false; $args = array(); foreach ($this->arguments as $a) { $args[] = array('name' => $a['name'], 'value' => $a['value']->compile($env)); } foreach ($env->frames as $frame) { $mixins = $frame->find($this->selector, $env); if (!$mixins) { continue; } $isOneFound = true; for ($m = 0; $m < count($mixins); $m++) { $mixin = $mixins[$m]; $isRecursive = false; foreach ($env->frames as $recurFrame) { if (!$mixin instanceof ILess_Node_MixinDefinition) { if (isset($recurFrame->originalRulesetId) && $mixin->rulesetId === $recurFrame->originalRulesetId || $mixin === $recurFrame) { $isRecursive = true; break; } } } if ($isRecursive) { continue; } if ($mixin->matchArgs($args, $env)) { if (!ILess_Node::methodExists($mixin, 'matchCondition') || $mixin->matchCondition($args, $env)) { try { if (!$mixin instanceof ILess_Node_MixinDefinition) { $mixin = new ILess_Node_MixinDefinition('', array(), $mixin->rules, null, false); $mixin->originalRulesetId = $mixins[$m]->originalRulesetId ? $mixins[$m]->originalRulesetId : $mixin->originalRulesetId; } $rules = array_merge($rules, $mixin->compile($env, $args, $this->important)->rules); } catch (Exception $e) { throw new ILess_Exception_Compiler($e->getMessage(), $this->index, $this->currentFileInfo, $e); } } $match = true; } } if ($match) { if (!$this->currentFileInfo || !$this->currentFileInfo->reference) { foreach ($rules as $rule) { if ($rule instanceof ILess_Node_MarkableAsReferencedInterface) { $rule->markReferenced(); } } } return $rules; } } if ($isOneFound) { $message = array(); if ($args) { foreach ($args as $a) { $argValue = ''; if ($a['name']) { $argValue .= $a['name'] . ':'; } if (ILess_Node::methodExists($a['value'], 'toCSS')) { $argValue .= $a['value']->toCSS($env); } else { $argValue .= '???'; } $message[] = $argValue; } } throw new ILess_Exception_Compiler(sprintf('No matching definition was found for `%s(%s)`', trim($this->selector->toCSS($env)), join(',', $message)), $this->index, $this->currentFileInfo); } else { throw new ILess_Exception_Compiler(sprintf('%s is undefined.', trim($this->selector->toCSS($env))), $this->index, $this->currentFileInfo); } }
/** * @see ILess_Node */ public function compile(ILess_Environment $env, $arguments = null, $important = null) { return new ILess_Node_Extend($this->selector->compile($env), $this->option, $this->index); }
/** * Joins a selector * * @param array $paths * @param array $context * @param ILess_Node_Selector $selector The selector */ protected function joinSelector(array &$paths, array $context, ILess_Node_Selector $selector) { $hasParentSelector = false; foreach ($selector->elements as $el) { if ($el->value === '&') { $hasParentSelector = true; } } if (!$hasParentSelector) { if (count($context) > 0) { foreach ($context as $contextEl) { $paths[] = array_merge($contextEl, array($selector)); } } else { $paths[] = array($selector); } return; } // The paths are [[Selector]] // The first list is a list of comma seperated selectors // The inner list is a list of inheritance seperated selectors // e.g. // .a, .b { // .c { // } // } // == [[.a] [.c]] [[.b] [.c]] // // the elements from the current selector so far $currentElements = array(); // the current list of new selectors to add to the path. // We will build it up. We initiate it with one empty selector as we "multiply" the new selectors // by the parents $newSelectors = array(array()); foreach ($selector->elements as $el) { // non parent reference elements just get added if ($el->value !== '&') { $currentElements[] = $el; } else { // the new list of selectors to add $selectorsMultiplied = array(); // merge the current list of non parent selector elements // on to the current list of selectors to add if (count($currentElements) > 0) { $this->mergeElementsOnToSelectors($currentElements, $newSelectors); } // loop through our current selectors foreach ($newSelectors as $sel) { // if we don't have any parent paths, the & might be in a mixin so that it can be used // whether there are parents or not if (!count($context)) { // the combinator used on el should now be applied to the next element instead so that // it is not lost if (count($sel) > 0) { $sel[0]->elements = array_slice($sel[0]->elements, 0); $sel[0]->elements[] = new ILess_Node_Element($el->combinator, '', $el->index, $el->currentFileInfo); } $selectorsMultiplied[] = $sel; } else { // and the parent selectors foreach ($context as $parentSel) { // We need to put the current selectors // then join the last selector's elements on to the parents selectors // our new selector path $newSelectorPath = array(); // selectors from the parent after the join $afterParentJoin = array(); $newJoinedSelectorEmpty = true; //construct the joined selector - if & is the first thing this will be empty, // if not newJoinedSelector will be the last set of elements in the selector if (count($sel) > 0) { $newSelectorPath = $sel; $lastSelector = array_pop($newSelectorPath); $newJoinedSelector = $selector->createDerived(array_slice($lastSelector->elements, 0)); $newJoinedSelectorEmpty = false; } else { $newJoinedSelector = $selector->createDerived(array()); } //put together the parent selectors after the join if (count($parentSel) > 1) { $afterParentJoin = array_merge($afterParentJoin, array_slice($parentSel, 1)); } if (count($parentSel) > 0) { $newJoinedSelectorEmpty = false; // join the elements so far with the first part of the parent $newJoinedSelector->elements[] = new ILess_Node_Element($el->combinator, $parentSel[0]->elements[0]->value, $el->index, $el->currentFileInfo); $newJoinedSelector->elements = array_merge($newJoinedSelector->elements, array_slice($parentSel[0]->elements, 1)); } if (!$newJoinedSelectorEmpty) { // now add the joined selector $newSelectorPath[] = $newJoinedSelector; } // and the rest of the parent $newSelectorPath = array_merge($newSelectorPath, $afterParentJoin); // add that to our new set of selectors $selectorsMultiplied[] = $newSelectorPath; } } } // our new selectors has been multiplied, so reset the state $newSelectors = $selectorsMultiplied; $currentElements = array(); } } // if we have any elements left over (e.g. .a& .b == .b) // add them on to all the current selectors if (count($currentElements) > 0) { $this->mergeElementsOnToSelectors($currentElements, $newSelectors); } foreach ($newSelectors as $newSel) { if (count($newSel)) { $paths[] = $newSel; } } }