name = $name; $this->selectors = array(new Less_Tree_Selector(array( new Less_Tree_Element(null, $name)))); $this->params = $params; $this->condition = $condition; $this->variadic = $variadic; $this->rules = $rules; if( $params ){ $this->arity = count($params); foreach( $params as $p ){ if (! isset($p['name']) || ($p['name'] && !isset($p['value']))) { $this->required++; } } } $this->frames = $frames; $this->SetRulesetIndex(); } //function accept( $visitor ){ // $this->params = $visitor->visit($this->params); // $this->rules = $visitor->visit($this->rules); // $this->condition = $visitor->visit($this->condition); //} public function toCSS(){ return ''; } // less.js : /lib/less/tree/mixin.js : tree.mixin.Definition.evalParams public function compileParams($env, $mixinFrames, $args = array() , &$evaldArguments = array() ){ $frame = new Less_Tree_Ruleset(null, array()); $params = $this->params; $mixinEnv = null; $argsLength = 0; if( $args ){ $argsLength = count($args); for($i = 0; $i < $argsLength; $i++ ){ $arg = $args[$i]; if( $arg && $arg['name'] ){ $isNamedFound = false; foreach($params as $j => $param){ if( !isset($evaldArguments[$j]) && $arg['name'] === $params[$j]['name']) { $evaldArguments[$j] = $arg['value']->compile($env); array_unshift($frame->rules, new Less_Tree_Rule( $arg['name'], $arg['value']->compile($env) ) ); $isNamedFound = true; break; } } if ($isNamedFound) { array_splice($args, $i, 1); $i--; $argsLength--; continue; } else { throw new Less_Exception_Compiler("Named argument for " . $this->name .' '.$args[$i]['name'] . ' not found'); } } } } $argIndex = 0; foreach($params as $i => $param){ if ( isset($evaldArguments[$i]) ){ continue; } $arg = null; if( isset($args[$argIndex]) ){ $arg = $args[$argIndex]; } if (isset($param['name']) && $param['name']) { if( isset($param['variadic']) ){ $varargs = array(); for ($j = $argIndex; $j < $argsLength; $j++) { $varargs[] = $args[$j]['value']->compile($env); } $expression = new Less_Tree_Expression($varargs); array_unshift($frame->rules, new Less_Tree_Rule($param['name'], $expression->compile($env))); }else{ $val = ($arg && $arg['value']) ? $arg['value'] : false; if ($val) { $val = $val->compile($env); } else if ( isset($param['value']) ) { if( !$mixinEnv ){ $mixinEnv = new Less_Environment(); $mixinEnv->frames = array_merge( array($frame), $mixinFrames); } $val = $param['value']->compile($mixinEnv); $frame->resetCache(); } else { throw new Less_Exception_Compiler("Wrong number of arguments for " . $this->name . " (" . $argsLength . ' for ' . $this->arity . ")"); } array_unshift($frame->rules, new Less_Tree_Rule($param['name'], $val)); $evaldArguments[$i] = $val; } } if ( isset($param['variadic']) && $args) { for ($j = $argIndex; $j < $argsLength; $j++) { $evaldArguments[$j] = $args[$j]['value']->compile($env); } } $argIndex++; } ksort($evaldArguments); $evaldArguments = array_values($evaldArguments); return $frame; } public function compile($env) { if( $this->frames ){ return new Less_Tree_Mixin_Definition($this->name, $this->params, $this->rules, $this->condition, $this->variadic, $this->frames ); } return new Less_Tree_Mixin_Definition($this->name, $this->params, $this->rules, $this->condition, $this->variadic, $env->frames ); } public function evalCall($env, $args = NULL, $important = NULL) { Less_Environment::$mixin_stack++; $_arguments = array(); if( $this->frames ){ $mixinFrames = array_merge($this->frames, $env->frames); }else{ $mixinFrames = $env->frames; } $frame = $this->compileParams($env, $mixinFrames, $args, $_arguments); $ex = new Less_Tree_Expression($_arguments); array_unshift($frame->rules, new Less_Tree_Rule('@arguments', $ex->compile($env))); $ruleset = new Less_Tree_Ruleset(null, $this->rules); $ruleset->originalRuleset = $this->ruleset_id; $ruleSetEnv = new Less_Environment(); $ruleSetEnv->frames = array_merge( array($this, $frame), $mixinFrames ); $ruleset = $ruleset->compile( $ruleSetEnv ); if( $important ){ $ruleset = $ruleset->makeImportant(); } Less_Environment::$mixin_stack--; return $ruleset; } public function matchCondition($args, $env) { if( !$this->condition ){ return true; } // set array to prevent error on array_merge if(!is_array($this->frames)) { $this->frames = array(); } $frame = $this->compileParams($env, array_merge($this->frames,$env->frames), $args ); $compile_env = new Less_Environment(); $compile_env->frames = array_merge( array($frame) // the parameter variables , $this->frames // the parent namespace/mixin frames , $env->frames // the current environment frames ); $compile_env->functions = $env->functions; return (bool)$this->condition->compile($compile_env); } public function matchArgs($args, $env = NULL){ $argsLength = count($args); if( !$this->variadic ){ if( $argsLength < $this->required ){ return false; } if( $argsLength > count($this->params) ){ return false; } }else{ if( $argsLength < ($this->required - 1)){ return false; } } $len = min($argsLength, $this->arity); for( $i = 0; $i < $len; $i++ ){ if( !isset($this->params[$i]['name']) && !isset($this->params[$i]['variadic']) ){ if( $args[$i]['value']->compile($env)->toCSS() != $this->params[$i]['value']->compile($env)->toCSS() ){ return false; } } } return true; } }