Beispiel #1
0
 /**
  * @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());
 }
Beispiel #2
0
 /**
  * @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);
     }
 }
Beispiel #3
0
 /**
  * @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);
 }
Beispiel #4
0
 /**
  * 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;
         }
     }
 }