[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 <?php 2 3 4 class Less_Tree_Mixin_Call extends Less_Tree{ 5 6 public $selector; 7 public $arguments; 8 public $index; 9 public $currentFileInfo; 10 11 public $important; 12 public $type = 'MixinCall'; 13 14 /** 15 * less.js: tree.mixin.Call 16 * 17 */ 18 public function __construct($elements, $args, $index, $currentFileInfo, $important = false){ 19 $this->selector = new Less_Tree_Selector($elements); 20 $this->arguments = $args; 21 $this->index = $index; 22 $this->currentFileInfo = $currentFileInfo; 23 $this->important = $important; 24 } 25 26 //function accept($visitor){ 27 // $this->selector = $visitor->visit($this->selector); 28 // $this->arguments = $visitor->visit($this->arguments); 29 //} 30 31 32 public function compile($env){ 33 34 $rules = array(); 35 $match = false; 36 $isOneFound = false; 37 $candidates = array(); 38 $defaultUsed = false; 39 $conditionResult = array(); 40 41 $args = array(); 42 foreach($this->arguments as $a){ 43 $args[] = array('name'=> $a['name'], 'value' => $a['value']->compile($env) ); 44 } 45 46 foreach($env->frames as $frame){ 47 48 $mixins = $frame->find($this->selector); 49 50 if( !$mixins ){ 51 continue; 52 } 53 54 $isOneFound = true; 55 $defNone = 0; 56 $defTrue = 1; 57 $defFalse = 2; 58 59 // To make `default()` function independent of definition order we have two "subpasses" here. 60 // At first we evaluate each guard *twice* (with `default() == true` and `default() == false`), 61 // and build candidate list with corresponding flags. Then, when we know all possible matches, 62 // we make a final decision. 63 64 $mixins_len = count($mixins); 65 for( $m = 0; $m < $mixins_len; $m++ ){ 66 $mixin = $mixins[$m]; 67 68 if( $this->IsRecursive( $env, $mixin ) ){ 69 continue; 70 } 71 72 if( $mixin->matchArgs($args, $env) ){ 73 74 $candidate = array('mixin' => $mixin, 'group' => $defNone); 75 76 if( $mixin instanceof Less_Tree_Ruleset ){ 77 78 for( $f = 0; $f < 2; $f++ ){ 79 Less_Tree_DefaultFunc::value($f); 80 $conditionResult[$f] = $mixin->matchCondition( $args, $env); 81 } 82 if( $conditionResult[0] || $conditionResult[1] ){ 83 if( $conditionResult[0] != $conditionResult[1] ){ 84 $candidate['group'] = $conditionResult[1] ? $defTrue : $defFalse; 85 } 86 87 $candidates[] = $candidate; 88 } 89 }else{ 90 $candidates[] = $candidate; 91 } 92 93 $match = true; 94 } 95 } 96 97 Less_Tree_DefaultFunc::reset(); 98 99 100 $count = array(0, 0, 0); 101 for( $m = 0; $m < count($candidates); $m++ ){ 102 $count[ $candidates[$m]['group'] ]++; 103 } 104 105 if( $count[$defNone] > 0 ){ 106 $defaultResult = $defFalse; 107 } else { 108 $defaultResult = $defTrue; 109 if( ($count[$defTrue] + $count[$defFalse]) > 1 ){ 110 throw new Exception( 'Ambiguous use of `default()` found when matching for `' . $this->format($args) . '`' ); 111 } 112 } 113 114 115 $candidates_length = count($candidates); 116 $length_1 = ($candidates_length == 1); 117 118 for( $m = 0; $m < $candidates_length; $m++){ 119 $candidate = $candidates[$m]['group']; 120 if( ($candidate === $defNone) || ($candidate === $defaultResult) ){ 121 try{ 122 $mixin = $candidates[$m]['mixin']; 123 if( !($mixin instanceof Less_Tree_Mixin_Definition) ){ 124 $mixin = new Less_Tree_Mixin_Definition('', array(), $mixin->rules, null, false); 125 $mixin->originalRuleset = $mixins[$m]->originalRuleset; 126 } 127 $rules = array_merge($rules, $mixin->evalCall($env, $args, $this->important)->rules); 128 } catch (Exception $e) { 129 //throw new Less_Exception_Compiler($e->getMessage(), $e->index, null, $this->currentFileInfo['filename']); 130 throw new Less_Exception_Compiler($e->getMessage(), null, null, $this->currentFileInfo); 131 } 132 } 133 } 134 135 if( $match ){ 136 if( !$this->currentFileInfo || !isset($this->currentFileInfo['reference']) || !$this->currentFileInfo['reference'] ){ 137 Less_Tree::ReferencedArray($rules); 138 } 139 140 return $rules; 141 } 142 } 143 144 if( $isOneFound ){ 145 throw new Less_Exception_Compiler('No matching definition was found for `'.$this->Format( $args ).'`', null, $this->index, $this->currentFileInfo); 146 147 }else{ 148 throw new Less_Exception_Compiler(trim($this->selector->toCSS()) . " is undefined in ".$this->currentFileInfo['filename'], null, $this->index); 149 } 150 151 } 152 153 /** 154 * Format the args for use in exception messages 155 * 156 */ 157 private function Format($args){ 158 $message = array(); 159 if( $args ){ 160 foreach($args as $a){ 161 $argValue = ''; 162 if( $a['name'] ){ 163 $argValue .= $a['name'] . ':'; 164 } 165 if( is_object($a['value']) ){ 166 $argValue .= $a['value']->toCSS(); 167 }else{ 168 $argValue .= '???'; 169 } 170 $message[] = $argValue; 171 } 172 } 173 return implode(', ',$message); 174 } 175 176 177 /** 178 * Are we in a recursive mixin call? 179 * 180 * @return bool 181 */ 182 private function IsRecursive( $env, $mixin ){ 183 184 foreach($env->frames as $recur_frame){ 185 if( !($mixin instanceof Less_Tree_Mixin_Definition) ){ 186 187 if( $mixin === $recur_frame ){ 188 return true; 189 } 190 191 if( isset($recur_frame->originalRuleset) && $mixin->ruleset_id === $recur_frame->originalRuleset ){ 192 return true; 193 } 194 } 195 } 196 197 return false; 198 } 199 200 } 201 202
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |