/** * Compiles the node * * @param Context $context The context * @param array|null $arguments Array of arguments * @param boolean|null $important Important flag * @return ParenNode|ExpressionNode|Node */ public function compile(Context $context, $arguments = null, $important = null) { $inParenthesis = $this->parens && !$this->parensInOp; $doubleParen = false; if ($inParenthesis) { $context->inParenthesis(); } $count = count($this->value); if ($count > 1) { $compiled = []; foreach ($this->value as $v) { /* @var $v Node */ $compiled[] = $v->compile($context); } $return = new ExpressionNode($compiled); } elseif ($count === 1) { if (property_exists($this->value[0], 'parens') && $this->value[0]->parens && property_exists($this->value[0], 'parensInOp') && !$this->value[0]->parensInOp) { $doubleParen = true; } $return = $this->value[0]->compile($context); } else { $return = $this; } if ($inParenthesis) { $context->outOfParenthesis(); } if ($this->parens && $this->parensInOp && !$context->isMathOn() && !$doubleParen) { $return = new ParenNode($return); } return $return; }
/** * Compiles the node. * * @param Context $context The context * @param array|null $arguments Array of arguments * @param bool|null $important Important flag * * @return NegativeNode|Node */ public function compile(Context $context, $arguments = null, $important = null) { if ($context->isMathOn()) { $operation = new OperationNode('*', [new DimensionNode('-1'), $this->value]); return $operation->compile($context); } else { return new self($this->value->compile($context)); } }
/** * Sets the imported file * * @param string $pathAbsolute The absolute path * @param ImportedFile $file The imported file * @param string $path The original path to import * @param FileInfo $currentFileInfo * @return Importer */ public function setImportedFile($pathAbsolute, ImportedFile $file, $path, FileInfo $currentFileInfo) { $this->importedFiles[$pathAbsolute] = [$file, $path, $currentFileInfo]; // save for source map generation $this->context->setFileContent($pathAbsolute, $file->getContent()); return $this; }
/** * @param Context $context * * @return Node|RulesetNode */ public function callCompile(Context $context) { if ($this->frames) { return $this->ruleset->compile(Context::createCopyForCompilation($context, array_merge($this->frames, $context->frames))); } return $this->ruleset->compile($context); }
/** * @covers createCopy */ public function testNormalizePath() { $env = new Context(); $copy = Context::createCopy($env, [1]); $this->assertInstanceOf('ILess\\Context', $copy); $this->assertEquals($copy->frames, [1]); }
/** * Converts the ruleset to CSS. * * @param RulesetNode $ruleset * @param array $variables * * @return string The generated CSS code * * @throws */ protected function toCSS(RulesetNode $ruleset, array $variables) { $precision = ini_set('precision', 16); $locale = setlocale(LC_NUMERIC, 0); setlocale(LC_NUMERIC, 'C'); if (extension_loaded('xdebug')) { $level = ini_set('xdebug.max_nesting_level', PHP_INT_MAX); } $e = $css = null; try { $this->prepareVariables($this->context, $variables); // pre compilation visitors foreach ($this->getPreCompileVisitors() as $visitor) { /* @var $visitor Visitor */ $visitor->run($ruleset); } // compile the ruleset $compiled = $ruleset->compile($this->context); // post compilation visitors foreach ($this->getPostCompileVisitors() as $visitor) { /* @var $visitor Visitor */ $visitor->run($compiled); } $context = $this->getContext(); $context->numPrecision = 8; // less.js compatibility if ($context->sourceMap) { $generator = new Generator($compiled, $this->context->getContentsMap(), $this->context->sourceMapOptions); // will also save file $css = $generator->generateCSS($this->context); } else { $generator = null; $css = $compiled->toCSS($this->context); } if ($this->pluginManager) { // post process $postProcessors = $this->pluginManager->getPostProcessors(); foreach ($postProcessors as $postProcessor) { /* @var $postProcessor PostProcessorInterface */ $css = $postProcessor->process($css, ['context' => $this->context, 'source_map' => $generator, 'importer' => $this->importer]); } } if ($this->context->compress) { $css = preg_replace('/(^(\\s)+)|((\\s)+$)/', '', $css); } } catch (\Exception $e) { } // restore setlocale(LC_NUMERIC, $locale); ini_set('precision', $precision); if (extension_loaded('xdebug')) { ini_set('xdebug.max_nesting_level', $level); } if ($e) { throw $e; } return $css; }
/** * Match condition. * * @param array $arguments * @param Context $context * * @return bool */ public function matchCondition(array $arguments, Context $context) { $lastSelector = $this->selectors[count($this->selectors) - 1]; if (!$lastSelector->compiledCondition) { return false; } if ($lastSelector->condition && !$lastSelector->condition->compile(Context::createCopyForCompilation($context, $context->frames))) { return false; } return true; }
/** * Match a condition. * * @param array $arguments * @param Context $context * * @return bool */ public function matchCondition(array $arguments, Context $context) { if (!$this->condition) { return true; } $frame = $this->compileParams($context, Context::createCopyForCompilation($context, array_merge($this->frames, $context->frames)), $arguments); $compileEnv = Context::createCopyForCompilation($context, array_merge([$frame], $this->frames, $context->frames)); if (!$this->condition->compile($compileEnv)) { return false; } return true; }
/** * Visits a import node. * * @param ImportNode $node The node * @param VisitorArguments $arguments The arguments * * @return ImportNode */ public function visitImport(ImportNode $node, VisitorArguments $arguments) { if (!$node->css || $node->getOption('inline')) { $context = Context::createCopyForCompilation($this->context, $this->context->frames); $importParent = $context->frames[0]; ++$this->importCount; if ($node->isVariableImport()) { $this->sequencer->addVariableImport(function () use($node, $context, $importParent) { $this->processImportNode($node, $context, $importParent); }); } else { $this->sequencer->addImport(function () use($node, $context, $importParent) { $this->processImportNode($node, $context, $importParent); }); } } $arguments->visitDeeper = false; return $node; }
/** * @param Context $context * @param array $frames * * @return Context */ public static function createCopyForCompilation(Context $context, array $frames = []) { $copyProperties = ['compress', 'ieCompat', 'strictMath', 'strictUnits', 'sourceMap', 'importMultiple', 'dumpLineNumbers', 'urlArgs', 'importantScope', 'customVariables']; $target = new self([], $context->getFunctionRegistry()); self::copyFromOriginal($context, $target, $copyProperties); $target->frames = $frames; return $target; }