[ Index ]

PHP Cross Reference of moodle-2.8

title

Body

[close]

/lib/lessphp/Tree/ -> Import.php (source)

   1  <?php
   2  
   3  /**
   4   * CSS @import node
   5   *
   6   * The general strategy here is that we don't want to wait
   7   * for the parsing to be completed, before we start importing
   8   * the file. That's because in the context of a browser,
   9   * most of the time will be spent waiting for the server to respond.
  10   *
  11   * On creation, we push the import path to our import queue, though
  12   * `import,push`, we also pass it a callback, which it'll call once
  13   * the file has been fetched, and parsed.
  14   *
  15   * @package Less
  16   * @subpackage tree
  17   */
  18  class Less_Tree_Import extends Less_Tree{
  19  
  20      public $options;
  21      public $index;
  22      public $path;
  23      public $features;
  24      public $currentFileInfo;
  25      public $css;
  26      public $skip;
  27      public $root;
  28      public $type = 'Import';
  29  
  30  	function __construct($path, $features, $options, $index, $currentFileInfo = null ){
  31          $this->options = $options;
  32          $this->index = $index;
  33          $this->path = $path;
  34          $this->features = $features;
  35          $this->currentFileInfo = $currentFileInfo;
  36  
  37          if( is_array($options) ){
  38              $this->options += array('inline'=>false);
  39  
  40              if( isset($this->options['less']) || $this->options['inline'] ){
  41                  $this->css = !isset($this->options['less']) || !$this->options['less'] || $this->options['inline'];
  42              } else {
  43                  $pathValue = $this->getPath();
  44                  if( $pathValue && preg_match('/css([\?;].*)?$/',$pathValue) ){
  45                      $this->css = true;
  46                  }
  47              }
  48          }
  49      }
  50  
  51  //
  52  // The actual import node doesn't return anything, when converted to CSS.
  53  // The reason is that it's used at the evaluation stage, so that the rules
  54  // it imports can be treated like any other rules.
  55  //
  56  // In `eval`, we make sure all Import nodes get evaluated, recursively, so
  57  // we end up with a flat structure, which can easily be imported in the parent
  58  // ruleset.
  59  //
  60  
  61  	function accept($visitor){
  62  
  63          if( $this->features ){
  64              $this->features = $visitor->visitObj($this->features);
  65          }
  66          $this->path = $visitor->visitObj($this->path);
  67  
  68          if( !$this->options['inline'] && $this->root ){
  69              $this->root = $visitor->visit($this->root);
  70          }
  71      }
  72  
  73      /**
  74       * @see Less_Tree::genCSS
  75       */
  76  	function genCSS( $output ){
  77          if( $this->css ){
  78  
  79              $output->add( '@import ', $this->currentFileInfo, $this->index );
  80  
  81              $this->path->genCSS( $output );
  82              if( $this->features ){
  83                  $output->add( ' ' );
  84                  $this->features->genCSS( $output );
  85              }
  86              $output->add( ';' );
  87          }
  88      }
  89  
  90  	function toCSS(){
  91          $features = $this->features ? ' ' . $this->features->toCSS() : '';
  92  
  93          if ($this->css) {
  94              return "@import " . $this->path->toCSS() . $features . ";\n";
  95          } else {
  96              return "";
  97          }
  98      }
  99  
 100      /**
 101       * @return string
 102       */
 103  	function getPath(){
 104          if ($this->path instanceof Less_Tree_Quoted) {
 105              $path = $this->path->value;
 106              $path = ( isset($this->css) || preg_match('/(\.[a-z]*$)|([\?;].*)$/',$path)) ? $path : $path . '.less';
 107          } else if ($this->path instanceof Less_Tree_URL) {
 108              $path = $this->path->value->value;
 109          }else{
 110              return null;
 111          }
 112  
 113          //remove query string and fragment
 114          return preg_replace('/[\?#][^\?]*$/','',$path);
 115      }
 116  
 117  	function compileForImport( $env ){
 118          return new Less_Tree_Import( $this->path->compile($env), $this->features, $this->options, $this->index, $this->currentFileInfo);
 119      }
 120  
 121  	function compilePath($env) {
 122          $path = $this->path->compile($env);
 123          $rootpath = '';
 124          if( $this->currentFileInfo && $this->currentFileInfo['rootpath'] ){
 125              $rootpath = $this->currentFileInfo['rootpath'];
 126          }
 127  
 128  
 129          if( !($path instanceof Less_Tree_URL) ){
 130              if( $rootpath ){
 131                  $pathValue = $path->value;
 132                  // Add the base path if the import is relative
 133                  if( $pathValue && Less_Environment::isPathRelative($pathValue) ){
 134                      $path->value = $this->currentFileInfo['uri_root'].$pathValue;
 135                  }
 136              }
 137              $path->value = Less_Environment::normalizePath($path->value);
 138          }
 139  
 140  
 141  
 142          return $path;
 143      }
 144  
 145  	function compile( $env ){
 146  
 147          $evald = $this->compileForImport($env);
 148  
 149          //get path & uri
 150          $path_and_uri = null;
 151          if( is_callable(Less_Parser::$options['import_callback']) ){
 152              $path_and_uri = call_user_func(Less_Parser::$options['import_callback'],$evald);
 153          }
 154  
 155          if( !$path_and_uri ){
 156              $path_and_uri = $evald->PathAndUri();
 157          }
 158  
 159          if( $path_and_uri ){
 160              list($full_path, $uri) = $path_and_uri;
 161          }else{
 162              $full_path = $uri = $evald->getPath();
 163          }
 164  
 165  
 166          //import once
 167          if( $evald->skip( $full_path, $env) ){
 168              return array();
 169          }
 170  
 171          if( $this->options['inline'] ){
 172              //todo needs to reference css file not import
 173              //$contents = new Less_Tree_Anonymous($this->root, 0, array('filename'=>$this->importedFilename), true );
 174  
 175              Less_Parser::AddParsedFile($full_path);
 176              $contents = new Less_Tree_Anonymous( file_get_contents($full_path), 0, array(), true );
 177  
 178              if( $this->features ){
 179                  return new Less_Tree_Media( array($contents), $this->features->value );
 180              }
 181  
 182              return array( $contents );
 183          }
 184  
 185  
 186          // css ?
 187          if( $evald->css ){
 188              $features = ( $evald->features ? $evald->features->compile($env) : null );
 189              return new Less_Tree_Import( $this->compilePath( $env), $features, $this->options, $this->index);
 190          }
 191  
 192  
 193          return $this->ParseImport( $full_path, $uri, $env );
 194      }
 195  
 196  
 197      /**
 198       * Using the import directories, get the full absolute path and uri of the import
 199       *
 200       * @param Less_Tree_Import $evald
 201       */
 202  	function PathAndUri(){
 203  
 204          $evald_path = $this->getPath();
 205  
 206          if( $evald_path ){
 207  
 208              $import_dirs = array();
 209  
 210              if( Less_Environment::isPathRelative($evald_path) ){
 211                  //if the path is relative, the file should be in the current directory
 212                  $import_dirs[ $this->currentFileInfo['currentDirectory'] ] = $this->currentFileInfo['uri_root'];
 213  
 214              }else{
 215                  //otherwise, the file should be relative to the server root
 216                  $import_dirs[ $this->currentFileInfo['entryPath'] ] = $this->currentFileInfo['entryUri'];
 217  
 218                  //if the user supplied entryPath isn't the actual root
 219                  $import_dirs[ $_SERVER['DOCUMENT_ROOT'] ] = '';
 220  
 221              }
 222  
 223              // always look in user supplied import directories
 224              $import_dirs = array_merge( $import_dirs, Less_Parser::$options['import_dirs'] );
 225  
 226  
 227              foreach( $import_dirs as $rootpath => $rooturi){
 228                  if( is_callable($rooturi) ){
 229                      list($path, $uri) = call_user_func($rooturi, $evald_path);
 230                      if( is_string($path) ){
 231                          $full_path = $path;
 232                          return array( $full_path, $uri );
 233                      }
 234                  }else{
 235                      $path = rtrim($rootpath,'/\\').'/'.ltrim($evald_path,'/\\');
 236  
 237                      if( file_exists($path) ){
 238                          $full_path = Less_Environment::normalizePath($path);
 239                          $uri = Less_Environment::normalizePath(dirname($rooturi.$evald_path));
 240                          return array( $full_path, $uri );
 241                      }
 242                  }
 243              }
 244          }
 245      }
 246  
 247  
 248      /**
 249       * Parse the import url and return the rules
 250       *
 251       * @return Less_Tree_Media|array
 252       */
 253  	function ParseImport( $full_path, $uri, $env ){
 254  
 255          $import_env = clone $env;
 256          if( (isset($this->options['reference']) && $this->options['reference']) || isset($this->currentFileInfo['reference']) ){
 257              $import_env->currentFileInfo['reference'] = true;
 258          }
 259  
 260          if( (isset($this->options['multiple']) && $this->options['multiple']) ){
 261              $import_env->importMultiple = true;
 262          }
 263  
 264          $parser = new Less_Parser($import_env);
 265          $root = $parser->parseFile($full_path, $uri, true);
 266  
 267  
 268          $ruleset = new Less_Tree_Ruleset(array(), $root->rules );
 269          $ruleset->evalImports($import_env);
 270  
 271          return $this->features ? new Less_Tree_Media($ruleset->rules, $this->features->value) : $ruleset->rules;
 272      }
 273  
 274  
 275      /**
 276       * Should the import be skipped?
 277       *
 278       * @return boolean|null
 279       */
 280  	private function Skip($path, $env){
 281  
 282          $path = realpath($path);
 283  
 284          if( $path && Less_Parser::FileParsed($path) ){
 285  
 286              if( isset($this->currentFileInfo['reference']) ){
 287                  return true;
 288              }
 289  
 290              return !isset($this->options['multiple']) && !$env->importMultiple;
 291          }
 292  
 293      }
 294  }
 295  


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1