You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
241 lines
6.2 KiB
241 lines
6.2 KiB
<?php
|
|
|
|
class Less_Tree_Mixin_Definition extends Less_Tree_Ruleset{
|
|
public $name;
|
|
public $selectors;
|
|
public $params;
|
|
public $arity = 0;
|
|
public $rules;
|
|
public $lookups = array();
|
|
public $required = 0;
|
|
public $frames = array();
|
|
public $condition;
|
|
public $variadic;
|
|
public $type = 'MixinDefinition';
|
|
|
|
|
|
// less.js : /lib/less/tree/mixin.js : tree.mixin.Definition
|
|
public function __construct($name, $params, $rules, $condition, $variadic = false, $frames = array() ){
|
|
$this->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;
|
|
}
|
|
|
|
}
|
|
|