%PDF- %PDF-
| Direktori : /home/q/g/b/qgbqkvz/www/wp-content/plugins/wp-scss/scssphp/src/Ast/Css/ |
| Current File : /home/q/g/b/qgbqkvz/www/wp-content/plugins/wp-scss/scssphp/src/Ast/Css/ModifiableCssNode.php |
<?php
/**
* SCSSPHP
*
* @copyright 2012-2020 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
* @link http://scssphp.github.io/scssphp
*/
namespace ScssPhp\ScssPhp\Ast\Css;
use ScssPhp\ScssPhp\Serializer\Serializer;
use ScssPhp\ScssPhp\Visitor\ModifiableCssVisitor;
/**
* A modifiable version of {@see CssNode}.
*
* Almost all CSS nodes are the modifiable classes under the covers. However,
* modification should only be done within the evaluation step, so the
* unmodifiable types are used elsewhere to enforce that constraint.
*
* @internal
*/
abstract class ModifiableCssNode implements CssNode
{
/**
* @var ModifiableCssParentNode|null
*/
private $parent;
/**
* The index of `$this` in parent's children.
*
* This makes {@see remove} more efficient.
*
* @var int|null
*/
private $indexInParent;
/**
* @var bool
*/
private $groupEnd = false;
public function getParent(): ?ModifiableCssParentNode
{
return $this->parent;
}
protected function setParent(ModifiableCssParentNode $parent, int $indexInParent): void
{
$this->parent = $parent;
$this->indexInParent = $indexInParent;
}
public function isGroupEnd(): bool
{
return $this->groupEnd;
}
public function setGroupEnd(bool $groupEnd): void
{
$this->groupEnd = $groupEnd;
}
/**
* Whether this node has a visible sibling after it.
*/
public function hasFollowingSibling(): bool
{
$parent = $this->parent;
if ($parent === null) {
return false;
}
assert($this->indexInParent !== null);
$siblings = $parent->getChildren();
for ($i = $this->indexInParent + 1; $i < \count($siblings); $i++) {
$sibling = $siblings[$i];
if (!$sibling->isInvisible()) {
return true;
}
}
return false;
}
public function isInvisible(): bool
{
return $this->accept(new IsInvisibleVisitor(true, false));
}
public function isInvisibleOtherThanBogusCombinators(): bool
{
return $this->accept(new IsInvisibleVisitor(false, false));
}
public function isInvisibleHidingComments(): bool
{
return $this->accept(new IsInvisibleVisitor(true, true));
}
/**
* Calls the appropriate visit method on $visitor.
*
* @template T
*
* @param ModifiableCssVisitor<T> $visitor
*
* @return T
*/
abstract public function accept($visitor);
/**
* Removes $this from {@see parent}'s child list.
*
* @throws \LogicException if {@see parent} is `null`.
*/
public function remove(): void
{
$parent = $this->parent;
if ($parent === null) {
throw new \LogicException("Can't remove a node without a parent.");
}
assert($this->indexInParent !== null);
$parent->removeChildAt($this->indexInParent);
$children = $parent->getChildren();
for ($i = $this->indexInParent; $i < \count($children); $i++) {
$child = $children[$i];
assert($child->indexInParent !== null);
$child->indexInParent = $child->indexInParent - 1;
}
$this->parent = null;
$this->indexInParent = null;
}
public function __toString(): string
{
return Serializer::serialize($this, true)->getCss();
}
}