Beispiel #1
0
 /**
  * Converts to CSS
  *
  * @param ILess_Environment $env
  * @return string
  */
 public function toCSS(ILess_Environment $env)
 {
     $value = self::methodExists($this->key, 'toCSS') ? $this->key->toCSS($env) : $this->key;
     if ($this->operator) {
         $value .= $this->operator;
         $value .= self::methodExists($this->value, 'toCSS') ? $this->value->toCSS($env) : $this->value;
     }
     return '[' . $value . ']';
 }
Beispiel #2
0
 /**
  * Constructor
  *
  * @param string $value The comment value
  * @param boolean $silent
  */
 public function __construct($value, $silent = false, $index = 0, ILess_FileInfo $currentFileInfo = null)
 {
     parent::__construct($value);
     $this->silent = (bool) $silent;
     $this->index = $index;
     $this->currentFileInfo = $currentFileInfo;
 }
Beispiel #3
0
 /**
  * Constructor
  *
  * @param string $quotedString Whole string with quotes
  * @param string $string The string without quotes
  * @param boolean $escaped Is the string escaped?
  * @param integer $index Current index
  * @param ILess_FileInfo $currentFileInfo The current file info
  */
 public function __construct($quotedString, $string, $escaped = false, $index = 0, ILess_FileInfo $currentFileInfo = null)
 {
     parent::__construct($string ? $string : '');
     $this->escaped = $escaped;
     $this->quote = $quotedString[0];
     $this->index = $index;
     $this->currentFileInfo = $currentFileInfo;
 }
Beispiel #4
0
 /**
  * Constructor
  *
  * @param string $value The string
  */
 public function __construct($value = null)
 {
     if ($value == ' ') {
         $value = ' ';
     } else {
         $value = trim($value);
     }
     parent::__construct($value);
 }
Beispiel #5
0
 /**
  * @see ILess_Node
  */
 public function generateCSS(ILess_Environment $env, ILess_Output $output)
 {
     if ($this->css) {
         $output->add('@import ', $this->currentFileInfo, $this->index);
         $this->path->generateCSS($env, $output);
         if ($this->features) {
             $output->add(' ');
             $this->features->generateCSS($env, $output);
         }
         $output->add(';');
     }
     return $output;
 }
Beispiel #6
0
 /**
  * Constructor
  *
  * @param string $name The name
  * @param array|string $value The value
  * @param integer $index The index
  * @param array $currentFileInfo Current file info
  */
 public function __construct($name, $value, $index = 0, ILess_FileInfo $currentFileInfo = null)
 {
     $this->name = $name;
     if (is_array($value)) {
         $ruleset = new ILess_Node_Ruleset(array(), $value);
         $ruleset->allowImports = true;
         $this->rules = array($ruleset);
     } else {
         if ($value && !$value instanceof ILess_Node) {
             throw new InvalidArgumentException('Invalid value given. It should be an instance of ILess_Node');
         }
         parent::__construct($value);
     }
     $this->index = $index;
     $this->currentFileInfo = $currentFileInfo;
 }
Beispiel #7
0
 /**
  * Compiles the node
  *
  * @param ILess_Environment $env
  * @return boolean
  */
 public function compile(ILess_Environment $env, $arguments = null, $important = null)
 {
     $a = $this->lvalue->compile($env);
     $b = $this->rvalue->compile($env);
     switch ($this->op) {
         case 'and':
             $result = $a && $b;
             break;
         case 'or':
             $result = $a || $b;
             break;
         default:
             if (self::methodExists($a, 'compare')) {
                 $result = $a->compare($b);
             } elseif (self::methodExists($b, 'compare')) {
                 $result = $b->compare($a);
             } else {
                 throw new ILess_Exception_Compiler('Unable to perform the comparison', $this->index, $env->currentFileInfo);
             }
             // FIXME: Operators has beed modified. its seems that there is a bug in less.js
             // The operator "=>" is missing in case 0 and case 1
             // Less.js version:
             /*
                             switch (result) {
                case -1: return op === '<' || op === '=<' || op === '<=';
                case  0: return op === '=' || op === '>=' || op === '=<' || op === '<=';
                case  1: return op === '>' || op === '>=';
                             }
             */
             switch ($result) {
                 case -1:
                     $result = $this->op === '<' || $this->op === '=<' || $this->op === '<=';
                     break;
                 case 0:
                     $result = $this->op === '=' || $this->op === '>=' || $this->op === '=>' || $this->op === '=<' || $this->op === '<=';
                     break;
                 case 1:
                     $result = $this->op === '>' || $this->op === '>=' || $this->op === '=>';
                     break;
             }
             break;
     }
     return $this->negate ? !$result : $result;
 }
Beispiel #8
0
 /**
  * Updates the currentFileInfo object to the $value
  *
  * @param ILess_Node $node The node to update
  * @param boolean $value The value
  */
 protected function updateReferenceInCurrentFileInfo(ILess_Node $node, $value)
 {
     if (isset($node->currentFileInfo)) {
         $node->currentFileInfo->reference = $value;
     }
     if (ILess_Node::propertyExists($node, 'rules')) {
         foreach ($node->rules as $rule) {
             $this->updateReferenceInCurrentFileInfo($rule, $value);
         }
     }
 }
Beispiel #9
0
 /**
  * Constructor
  *
  * @param array $value
  */
 public function __construct(array $value)
 {
     parent::__construct($value);
 }
Beispiel #10
0
 /**
  * Finds a selector
  *
  * @param ILess_Node $selector
  * @param ILess_Node_Ruleset $self
  * @param ILess_Environment $env
  * @return array
  */
 public function find(ILess_Node $selector, ILess_Environment $env, ILess_Node_Ruleset $self = null)
 {
     $key = $selector->toCSS($env);
     if (!$self) {
         $self = $this;
     }
     if (!array_key_exists($key, $this->lookups)) {
         $this->lookups[$key] = array();
         foreach ($this->rules as $rule) {
             if ($rule === $self) {
                 continue;
             }
             if ($rule instanceof ILess_Node_Ruleset || $rule instanceof ILess_Node_MixinDefinition) {
                 foreach ($rule->selectors as $ruleSelector) {
                     $match = $selector->match($ruleSelector);
                     if ($match) {
                         if (count($selector->elements) > $match) {
                             $this->lookups[$key] = array_merge($this->lookups[$key], $rule->find(new ILess_Node_Selector(array_slice($selector->elements, $match)), $env, $self));
                         } else {
                             $this->lookups[$key][] = $rule;
                         }
                         break;
                     }
                 }
             }
         }
     }
     return $this->lookups[$key];
 }
Beispiel #11
0
 /**
  * Constructor
  *
  * @param ILess_Node $value
  */
 public function __construct(ILess_Node $value)
 {
     parent::__construct($value);
 }
Beispiel #12
0
 /**
  * Compares with another dimension
  *
  * @param ILess_Node $other
  * @return integer
  */
 public function compare(ILess_Node $other)
 {
     if (!$other instanceof ILess_Node_Dimension) {
         return -1;
     }
     $a = $this->unify();
     $b = $other->unify();
     if ($b->value > $a->value) {
         return -1;
     } elseif ($b->value < $a->value) {
         return 1;
     } else {
         if (!$b->unit->isEmpty() && $a->unit->compare($b->unit) !== 0) {
             return -1;
         }
         return 0;
     }
 }
Beispiel #13
0
 /**
  * Visits a ruleset node
  *
  * @param ILess_Node_Ruleset $node The node
  * @param ILess_Visitor_Arguments $arguments The arguments
  * @return array|ILess_Node_Ruleset
  */
 public function visitRuleset(ILess_Node_Ruleset $node, ILess_Visitor_Arguments $arguments)
 {
     $arguments->visitDeeper = false;
     $rulesets = array();
     if ($node->firstRoot) {
         $this->checkPropertiesInRoot($node->rules);
     }
     if (!$node->root) {
         $paths = array();
         foreach ($node->paths as $p) {
             if ($p[0]->elements[0]->combinator->value === ' ') {
                 $p[0]->elements[0]->combinator = new ILess_Node_Combinator('');
             }
             if ($p[0]->getIsReferenced() && $p[0]->getIsOutput()) {
                 $paths[] = $p;
             }
         }
         $node->paths = $paths;
         // Compile rules and rulesets
         for ($i = 0, $count = count($node->rules); $i < $count;) {
             $rule = $node->rules[$i];
             //if ($rule instanceof ILess_Node_Rule || $rule instanceof ILess_Node_Ruleset) {
             //if ($rule instanceof ILess_Node_Ruleset) {
             if (ILess_Node::propertyExists($rule, 'rules')) {
                 // visit because we are moving them out from being a child
                 $rulesets[] = $this->visit($rule);
                 array_splice($node->rules, $i, 1);
                 $count--;
                 continue;
             }
             $i++;
         }
         // accept the visitor to remove rules and refactor itself
         // then we can decide now whether we want it or not
         if ($count > 0) {
             $node->accept($this);
             $count = count($node->rules);
             if ($count > 0) {
                 if ($count > 1) {
                     $this->mergeRules($node->rules);
                     $this->removeDuplicateRules($node->rules);
                 }
                 // now decide whether we keep the ruleset
                 if (count($node->paths) > 0) {
                     array_splice($rulesets, 0, 0, array($node));
                 }
             }
         } else {
             $node->rules = array();
         }
     } else {
         $node->accept($this);
         $arguments->visitDeeper = false;
         if ($node->firstRoot || count($node->rules) > 0) {
             array_splice($rulesets, 0, 0, array($node));
         }
     }
     if (count($rulesets) === 1) {
         return $rulesets[0];
     }
     return $rulesets;
 }
Beispiel #14
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 #15
0
 /**
  * Constructor
  *
  * @param ILess_Node $value
  * @param ILess_FileInfo $currentFileInfo
  */
 public function __construct(ILess_Node $value, ILess_FileInfo $currentFileInfo = null)
 {
     parent::__construct($value);
     $this->currentFileInfo = $currentFileInfo;
 }
Beispiel #16
0
 /**
  * Constructor
  *
  * @param string $key
  * @param string|ILess_INode $value
  */
 public function __construct($key, $value)
 {
     parent::__construct($value);
     $this->key = $key;
 }
Beispiel #17
0
 /**
  * Creates a SVG gradient
  *
  * @param ILess_Node $direction
  * @return ILess_Node_Url
  * @throws ILess_Exception_Compiler If the arguments are invalid
  */
 public function svggradient(ILess_Node $direction)
 {
     if (func_num_args() < 3) {
         throw new ILess_Exception_Compiler('svg-gradient expects direction, start_color [start_position], [color position,]..., end_color [end_position]');
     }
     $arguments = func_get_args();
     $stops = array_slice($arguments, 1);
     $gradientType = 'linear';
     $rectangleDimension = 'x="0" y="0" width="1" height="1"';
     $useBase64 = true;
     $renderEnv = new ILess_Environment();
     $directionValue = $direction->toCSS($renderEnv);
     switch ($directionValue) {
         case 'to bottom':
             $gradientDirectionSvg = 'x1="0%" y1="0%" x2="0%" y2="100%"';
             break;
         case 'to right':
             $gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="0%"';
             break;
         case 'to bottom right':
             $gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="100%"';
             break;
         case 'to top right':
             $gradientDirectionSvg = 'x1="0%" y1="100%" x2="100%" y2="0%"';
             break;
         case 'ellipse':
         case 'ellipse at center':
             $gradientType = 'radial';
             $gradientDirectionSvg = 'cx="50%" cy="50%" r="75%"';
             $rectangleDimension = 'x="-50" y="-50" width="101" height="101"';
             break;
         default:
             throw new ILess_Exception_Compiler("svg-gradient direction must be 'to bottom', 'to right', 'to bottom right', 'to top right' or 'ellipse at center'");
     }
     $returner = '<?xml version="1.0" ?>' . '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100%" height="100%" viewBox="0 0 1 1" preserveAspectRatio="none">' . '<' . $gradientType . 'Gradient id="gradient" gradientUnits="userSpaceOnUse" ' . $gradientDirectionSvg . '>';
     for ($i = 0; $i < count($stops); $i++) {
         if (ILess_Node::propertyExists($stops[$i], 'value') && $stops[$i]->value) {
             $color = $stops[$i]->value[0];
             $position = $stops[$i]->value[1];
         } else {
             $color = $stops[$i];
             $position = null;
         }
         if (!$color instanceof ILess_Node_Color || !(($i === 0 || $i + 1 === count($stops)) && $position === null) && !$position instanceof ILess_Node_Dimension) {
             throw new ILess_Exception_Compiler('svg-gradient expects direction, start_color [start_position], [color position,]..., end_color [end_position]');
         }
         if ($position) {
             $positionValue = $position->toCSS($renderEnv);
         } elseif ($i === 0) {
             $positionValue = '0%';
         } else {
             $positionValue = '100%';
         }
         $alpha = $color->getAlpha(true);
         $returner .= '<stop offset="' . $positionValue . '" stop-color="' . $color->getColor()->toString($this->env->compress, false) . '"' . ($alpha < 1 ? ' stop-opacity="' . $alpha . '"' : '') . '/>';
     }
     $returner .= '</' . $gradientType . 'Gradient><rect ' . $rectangleDimension . ' fill="url(#gradient)" /></svg>';
     if ($useBase64) {
         $returner = base64_encode($returner);
     }
     $returner = "'data:image/svg+xml" . ($useBase64 ? ";base64" : "") . "," . $returner . "'";
     return new ILess_Node_Url(new ILess_Node_Anonymous($returner));
 }
Beispiel #18
0
 /**
  * Visits a ruleset node
  *
  * @param ILess_Node_Ruleset $node The node
  * @param ILess_Visitor_Arguments $arguments The arguments
  */
 public function visitRuleset(ILess_Node_Ruleset $node, ILess_Visitor_Arguments $arguments)
 {
     if ($node->root) {
         return;
     }
     $allExtends = end($this->allExtendsStack);
     $pathsCount = count($node->paths);
     // look at each selector path in the ruleset, find any extend matches and then copy, find and replace
     for ($extendIndex = 0, $allExtendCount = count($allExtends); $extendIndex < $allExtendCount; $extendIndex++) {
         for ($pathIndex = 0; $pathIndex < $pathsCount; $pathIndex++) {
             $selectorPath = $node->paths[$pathIndex];
             // extending extends happens initially, before the main pass
             if (ILess_Node::propertyExists($node, 'extendOnEveryPath') && $node->extendOnEveryPath) {
                 continue;
             }
             if (end($selectorPath)->extendList) {
                 continue;
             }
             $matches = $this->findMatch($allExtends[$extendIndex], $selectorPath);
             if ($matches) {
                 foreach ($allExtends[$extendIndex]->selfSelectors as $selfSelector) {
                     $node->paths[] = $this->extendSelector($matches, $selectorPath, $selfSelector);
                 }
             }
         }
     }
 }