1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
<?php
/* Icinga Web 2 | (c) 2022 Icinga GmbH | GPLv2+ */
namespace Icinga\Less;
use Less_Exception_Compiler;
use Less_Tree_Call;
use Less_Tree_Color;
use Less_Tree_Keyword;
use Less_Tree_Value;
use Less_Tree_Variable;
class DeferredColorProp extends Less_Tree_Variable
{
/** @var DeferredColorProp|ColorProp */
protected $reference;
protected $resolved = false;
public function __construct($name, $variable, $index = null, $currentFileInfo = null)
{
parent::__construct($name, $index, $currentFileInfo);
if ($variable instanceof Less_Tree_Variable) {
$this->reference = self::fromVariable($variable);
}
}
public function isResolved()
{
return $this->resolved;
}
public function getName()
{
$name = $this->name;
if ($this->name[0] === '@') {
$name = substr($this->name, 1);
}
return $name;
}
public function hasReference()
{
return $this->reference !== null;
}
public function getRef()
{
return $this->reference;
}
public function setReference($ref)
{
$this->reference = $ref;
return $this;
}
public static function fromVariable(Less_Tree_Variable $variable)
{
$static = new static($variable->name, $variable->index, $variable->currentFileInfo);
$static->evaluating = $variable->evaluating;
$static->type = $variable->type;
return $static;
}
public function compile($env)
{
if (! $this->hasReference()) {
// This is never supposed to happen, however, we might have a deferred color prop
// without a reference. In this case we can simply use the parent method.
return parent::compile($env);
}
if ($this->isResolved()) {
// The dependencies are already resolved, no need to traverse the frame stack over again!
return $this;
}
if ($this->evaluating) { // Just like the parent method
throw new Less_Exception_Compiler(
"Recursive variable definition for " . $this->name,
null,
$this->index,
$this->currentFileInfo
);
}
$this->evaluating = true;
foreach ($env->frames as $frame) {
if (($v = $frame->variable($this->getRef()->name))) {
$rv = $v->value;
if ($rv instanceof Less_Tree_Value) {
$rv = $rv->compile($env);
}
// As we are at it anyway, let's cast the tree color to our color prop as well!
if ($rv instanceof Less_Tree_Color) {
$rv = ColorProp::fromColor($rv);
$rv->setName($this->getRef()->getName());
}
$this->evaluating = false;
$this->resolved = true;
$this->setReference($rv);
break;
}
}
return $this;
}
public function genCSS($output)
{
if (! $this->hasReference()) {
return; // Nothing to generate
}
$css = (new Less_Tree_Call(
'var',
[
new Less_Tree_Keyword('--' . $this->getName()),
$this->getRef() // Each of the references will be generated recursively
],
$this->index
))->toCSS();
$output->add($css);
}
}
|