class LessFilter

Loads LESS files.

@link http://lesscss.org/ @author Kris Wallsmith <kris.wallsmith@gmail.com>

Hierarchy

Expanded class hierarchy of LessFilter

File

drupal/core/vendor/kriswallsmith/assetic/src/Assetic/Filter/LessFilter.php, line 25

Namespace

Assetic\Filter
View source
class LessFilter extends BaseNodeFilter implements DependencyExtractorInterface {
  private $nodeBin;

  /**
   * @var array
   */
  private $treeOptions;

  /**
   * @var array
   */
  private $parserOptions;

  /**
   * Load Paths
   *
   * A list of paths which less will search for includes.
   *
   * @var array
   */
  protected $loadPaths = array();

  /**
   * Constructor.
   *
   * @param string $nodeBin   The path to the node binary
   * @param array  $nodePaths An array of node paths
   */
  public function __construct($nodeBin = '/usr/bin/node', array $nodePaths = array()) {
    $this->nodeBin = $nodeBin;
    $this
      ->setNodePaths($nodePaths);
    $this->treeOptions = array();
    $this->parserOptions = array();
  }

  /**
   * @param bool $compress
   */
  public function setCompress($compress) {
    $this
      ->addTreeOption('compress', $compress);
  }
  public function setLoadPaths(array $loadPaths) {
    $this->loadPaths = $loadPaths;
  }

  /**
   * Adds a path where less will search for includes
   *
   * @param string $path Load path (absolute)
   */
  public function addLoadPath($path) {
    $this->loadPaths[] = $path;
  }

  /**
   * @param string $code
   * @param string $value
   */
  public function addTreeOption($code, $value) {
    $this->treeOptions[$code] = $value;
  }

  /**
   * @param string $code
   * @param string $value
   */
  public function addParserOption($code, $value) {
    $this->parserOptions[$code] = $value;
  }
  public function filterLoad(AssetInterface $asset) {
    static $format = <<<'EOF'
var less = require('less');
var sys  = require(process.binding('natives').util ? 'util' : 'sys');

new(less.Parser)(%s).parse(%s, function(e, tree) {
    if (e) {
        less.writeError(e);
        process.exit(2);
    }

    try {
        sys.print(tree.toCSS(%s));
    } catch (e) {
        less.writeError(e);
        process.exit(3);
    }
});

EOF;
    $root = $asset
      ->getSourceRoot();
    $path = $asset
      ->getSourcePath();

    // parser options
    $parserOptions = $this->parserOptions;
    if ($root && $path) {
      $parserOptions['paths'] = array(
        dirname($root . '/' . $path),
      );
      $parserOptions['filename'] = basename($path);
    }
    foreach ($this->loadPaths as $loadPath) {
      $parserOptions['paths'][] = $loadPath;
    }
    $pb = $this
      ->createProcessBuilder();
    $pb
      ->add($this->nodeBin)
      ->add($input = tempnam(sys_get_temp_dir(), 'assetic_less'));
    file_put_contents($input, sprintf($format, json_encode($parserOptions), json_encode($asset
      ->getContent()), json_encode($this->treeOptions)));
    $proc = $pb
      ->getProcess();
    $code = $proc
      ->run();
    unlink($input);
    if (0 !== $code) {
      throw FilterException::fromProcess($proc)
        ->setInput($asset
        ->getContent());
    }
    $asset
      ->setContent($proc
      ->getOutput());
  }
  public function filterDump(AssetInterface $asset) {
  }

  /**
   * @todo support for @import-once
   * @todo support for @import (less) "lib.css"
   */
  public function getChildren(AssetFactory $factory, $content, $loadPath = null) {
    $loadPaths = $this->loadPaths;
    if (null !== $loadPath) {
      $loadPaths[] = $loadPath;
    }
    if (empty($loadPaths)) {
      return array();
    }
    $children = array();
    foreach (LessUtils::extractImports($content) as $reference) {
      if ('.css' === substr($reference, -4)) {

        // skip normal css imports
        // todo: skip imports with media queries
        continue;
      }
      if ('.less' !== substr($reference, -5)) {
        $reference .= '.less';
      }
      foreach ($loadPaths as $loadPath) {
        if (file_exists($file = $loadPath . '/' . $reference)) {
          $coll = $factory
            ->createAsset($file, array(), array(
            'root' => $loadPath,
          ));
          foreach ($coll as $leaf) {
            $leaf
              ->ensureFilter($this);
            $children[] = $leaf;
            goto next_reference;
          }
        }
      }
      next_reference:
    }
    return $children;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
BaseNodeFilter::$nodePaths private property
BaseNodeFilter::addNodePath public function
BaseNodeFilter::createProcessBuilder protected function Creates a new process builder. Overrides BaseProcessFilter::createProcessBuilder
BaseNodeFilter::getNodePaths public function
BaseNodeFilter::setNodePaths public function
BaseProcessFilter::$timeout private property
BaseProcessFilter::mergeEnv protected function
BaseProcessFilter::setTimeout public function Set the process timeout.
LessFilter::$loadPaths protected property Load Paths
LessFilter::$nodeBin private property
LessFilter::$parserOptions private property
LessFilter::$treeOptions private property
LessFilter::addLoadPath public function Adds a path where less will search for includes
LessFilter::addParserOption public function
LessFilter::addTreeOption public function
LessFilter::filterDump public function Filters an asset just before it's dumped. Overrides FilterInterface::filterDump
LessFilter::filterLoad public function Filters an asset after it has been loaded. Overrides FilterInterface::filterLoad
LessFilter::getChildren public function @todo support for @import-once @todo support for @import (less) "lib.css" Overrides DependencyExtractorInterface::getChildren
LessFilter::setCompress public function
LessFilter::setLoadPaths public function
LessFilter::__construct public function Constructor.