%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(); } }