<?php
namespace Sabberworm\CSS\Rule;
> use Sabberworm\CSS\Comment\Comment;
use Sabberworm\CSS\Comment\Commentable;
> use Sabberworm\CSS\OutputFormat;
use Sabberworm\CSS\Parsing\ParserState;
> use Sabberworm\CSS\Parsing\UnexpectedEOFException;
use Sabberworm\CSS\Renderable;
> use Sabberworm\CSS\Parsing\UnexpectedTokenException;
use Sabberworm\CSS\Value\RuleValueList;
use Sabberworm\CSS\Value\Value;
/**
* RuleSets contains Rule objects which always have a key and a value.
* In CSS, Rules are expressed as follows: “key: value[0][0] value[0][1], value[1][0] value[1][1];”
*/
< class Rule implements Renderable, Commentable {
<
> class Rule implements Renderable, Commentable
> {
> /**
> * @var string
> */
private $sRule;
>
private $mValue;
> /**
private $bIsImportant;
> * @var RuleValueList|null
private $aIeHack;
> */
protected $iLineNo;
>
protected $aComments;
> /**
> * @var bool
public function __construct($sRule, $iLineNo = 0) {
> */
$this->sRule = $sRule;
>
$this->mValue = null;
> /**
$this->bIsImportant = false;
> * @var array<int, int>
$this->aIeHack = array();
> */
$this->iLineNo = $iLineNo;
>
$this->aComments = array();
> /**
}
> * @var int
> */
public static function parse(ParserState $oParserState) {
>
$aComments = $oParserState->consumeWhiteSpace();
> /**
$oRule = new Rule($oParserState->parseIdentifier(), $oParserState->currentLine());
> * @var int
$oRule->setComments($aComments);
> */
$oRule->addComments($oParserState->consumeWhiteSpace());
> protected $iColNo;
$oParserState->consume(':');
>
$oValue = Value::parseValue($oParserState, self::listDelimiterForRule($oRule->getRule()));
> /**
$oRule->setValue($oValue);
> * @var array<array-key, Comment>
if ($oParserState->getSettings()->bLenientParsing) {
> */
< public function __construct($sRule, $iLineNo = 0) {
> /**
> * @param string $sRule
> * @param int $iLineNo
> * @param int $iColNo
> */
> public function __construct($sRule, $iLineNo = 0, $iColNo = 0)
> {
< $this->aIeHack = array();
> $this->aIeHack = [];
< $this->aComments = array();
> $this->iColNo = $iColNo;
> $this->aComments = [];
< public static function parse(ParserState $oParserState) {
> /**
> * @return Rule
> *
> * @throws UnexpectedEOFException
> * @throws UnexpectedTokenException
> */
> public static function parse(ParserState $oParserState)
> {
< $oRule = new Rule($oParserState->parseIdentifier(), $oParserState->currentLine());
> $oRule = new Rule(
> $oParserState->parseIdentifier(!$oParserState->comes("--")),
> $oParserState->currentLine(),
> $oParserState->currentColumn()
> );
}
$oParserState->consumeWhiteSpace();
if ($oParserState->comes('!')) {
$oParserState->consume('!');
$oParserState->consumeWhiteSpace();
$oParserState->consume('important');
$oRule->setIsImportant(true);
}
$oParserState->consumeWhiteSpace();
while ($oParserState->comes(';')) {
$oParserState->consume(';');
}
return $oRule;
}
< private static function listDelimiterForRule($sRule) {
> /**
> * @param string $sRule
> *
> * @return array<int, string>
> */
> private static function listDelimiterForRule($sRule)
> {
if (preg_match('/^font($|-)/', $sRule)) {
< return array(',', '/', ' ');
> return [',', '/', ' '];
}
< return array(',', ' ', '/');
> return [',', ' ', '/'];
}
/**
* @return int
*/
< public function getLineNo() {
> public function getLineNo()
> {
return $this->iLineNo;
}
< public function setRule($sRule) {
> /**
> * @return int
> */
> public function getColNo()
> {
> return $this->iColNo;
> }
>
> /**
> * @param int $iLine
> * @param int $iColumn
> *
> * @return void
> */
> public function setPosition($iLine, $iColumn)
> {
> $this->iColNo = $iColumn;
> $this->iLineNo = $iLine;
> }
>
> /**
> * @param string $sRule
> *
> * @return void
> */
> public function setRule($sRule)
> {
$this->sRule = $sRule;
}
< public function getRule() {
> /**
> * @return string
> */
> public function getRule()
> {
return $this->sRule;
}
< public function getValue() {
> /**
> * @return RuleValueList|null
> */
> public function getValue()
> {
return $this->mValue;
}
< public function setValue($mValue) {
> /**
> * @param RuleValueList|null $mValue
> *
> * @return void
> */
> public function setValue($mValue)
> {
$this->mValue = $mValue;
}
/**
< * @deprecated Old-Style 2-dimensional array given. Retained for (some) backwards-compatibility. Use setValue() instead and wrapp the value inside a RuleValueList if necessary.
> * @param array<array-key, array<array-key, RuleValueList>> $aSpaceSeparatedValues
> *
> * @return RuleValueList
> *
> * @deprecated will be removed in version 9.0
> * Old-Style 2-dimensional array given. Retained for (some) backwards-compatibility.
> * Use `setValue()` instead and wrap the value inside a RuleValueList if necessary.
*/
< public function setValues($aSpaceSeparatedValues) {
> public function setValues(array $aSpaceSeparatedValues)
> {
$oSpaceSeparatedList = null;
if (count($aSpaceSeparatedValues) > 1) {
$oSpaceSeparatedList = new RuleValueList(' ', $this->iLineNo);
}
foreach ($aSpaceSeparatedValues as $aCommaSeparatedValues) {
$oCommaSeparatedList = null;
if (count($aCommaSeparatedValues) > 1) {
$oCommaSeparatedList = new RuleValueList(',', $this->iLineNo);
}
foreach ($aCommaSeparatedValues as $mValue) {
if (!$oSpaceSeparatedList && !$oCommaSeparatedList) {
$this->mValue = $mValue;
return $mValue;
}
if ($oCommaSeparatedList) {
$oCommaSeparatedList->addListComponent($mValue);
} else {
$oSpaceSeparatedList->addListComponent($mValue);
}
}
if (!$oSpaceSeparatedList) {
$this->mValue = $oCommaSeparatedList;
return $oCommaSeparatedList;
} else {
$oSpaceSeparatedList->addListComponent($oCommaSeparatedList);
}
}
$this->mValue = $oSpaceSeparatedList;
return $oSpaceSeparatedList;
}
/**
< * @deprecated Old-Style 2-dimensional array returned. Retained for (some) backwards-compatibility. Use getValue() instead and check for the existance of a (nested set of) ValueList object(s).
> * @return array<int, array<int, RuleValueList>>
> *
> * @deprecated will be removed in version 9.0
> * Old-Style 2-dimensional array returned. Retained for (some) backwards-compatibility.
> * Use `getValue()` instead and check for the existence of a (nested set of) ValueList object(s).
*/
< public function getValues() {
> public function getValues()
> {
if (!$this->mValue instanceof RuleValueList) {
< return array(array($this->mValue));
> return [[$this->mValue]];
}
if ($this->mValue->getListSeparator() === ',') {
< return array($this->mValue->getListComponents());
> return [$this->mValue->getListComponents()];
}
< $aResult = array();
> $aResult = [];
foreach ($this->mValue->getListComponents() as $mValue) {
if (!$mValue instanceof RuleValueList || $mValue->getListSeparator() !== ',') {
< $aResult[] = array($mValue);
> $aResult[] = [$mValue];
continue;
}
if ($this->mValue->getListSeparator() === ' ' || count($aResult) === 0) {
< $aResult[] = array();
> $aResult[] = [];
}
foreach ($mValue->getListComponents() as $mValue) {
$aResult[count($aResult) - 1][] = $mValue;
}
}
return $aResult;
}
/**
< * Adds a value to the existing value. Value will be appended if a RuleValueList exists of the given type. Otherwise, the existing value will be wrapped by one.
> * Adds a value to the existing value. Value will be appended if a `RuleValueList` exists of the given type.
> * Otherwise, the existing value will be wrapped by one.
> *
> * @param RuleValueList|array<int, RuleValueList> $mValue
> * @param string $sType
> *
> * @return void
*/
< public function addValue($mValue, $sType = ' ') {
> public function addValue($mValue, $sType = ' ')
> {
if (!is_array($mValue)) {
< $mValue = array($mValue);
> $mValue = [$mValue];
}
if (!$this->mValue instanceof RuleValueList || $this->mValue->getListSeparator() !== $sType) {
$mCurrentValue = $this->mValue;
$this->mValue = new RuleValueList($sType, $this->iLineNo);
if ($mCurrentValue) {
$this->mValue->addListComponent($mCurrentValue);
}
}
foreach ($mValue as $mValueItem) {
$this->mValue->addListComponent($mValueItem);
}
}
< public function addIeHack($iModifier) {
> /**
> * @param int $iModifier
> *
> * @return void
> */
> public function addIeHack($iModifier)
> {
$this->aIeHack[] = $iModifier;
}
< public function setIeHack(array $aModifiers) {
> /**
> * @param array<int, int> $aModifiers
> *
> * @return void
> */
> public function setIeHack(array $aModifiers)
> {
$this->aIeHack = $aModifiers;
}
< public function getIeHack() {
> /**
> * @return array<int, int>
> */
> public function getIeHack()
> {
return $this->aIeHack;
}
< public function setIsImportant($bIsImportant) {
> /**
> * @param bool $bIsImportant
> *
> * @return void
> */
> public function setIsImportant($bIsImportant)
> {
$this->bIsImportant = $bIsImportant;
}
< public function getIsImportant() {
> /**
> * @return bool
> */
> public function getIsImportant()
> {
return $this->bIsImportant;
}
< public function __toString() {
< return $this->render(new \Sabberworm\CSS\OutputFormat());
> /**
> * @return string
> */
> public function __toString()
> {
> return $this->render(new OutputFormat());
}
< public function render(\Sabberworm\CSS\OutputFormat $oOutputFormat) {
> /**
> * @return string
> */
> public function render(OutputFormat $oOutputFormat)
> {
$sResult = "{$this->sRule}:{$oOutputFormat->spaceAfterRuleName()}";
if ($this->mValue instanceof Value) { //Can also be a ValueList
$sResult .= $this->mValue->render($oOutputFormat);
} else {
$sResult .= $this->mValue;
}
if (!empty($this->aIeHack)) {
$sResult .= ' \\' . implode('\\', $this->aIeHack);
}
if ($this->bIsImportant) {
$sResult .= ' !important';
}
$sResult .= ';';
return $sResult;
}
/**
< * @param array $aComments Array of comments.
> * @param array<array-key, Comment> $aComments
> *
> * @return void
*/
< public function addComments(array $aComments) {
> public function addComments(array $aComments)
> {
$this->aComments = array_merge($this->aComments, $aComments);
}
/**
< * @return array
> * @return array<array-key, Comment>
*/
< public function getComments() {
> public function getComments()
> {
return $this->aComments;
}
/**
< * @param array $aComments Array containing Comment objects.
> * @param array<array-key, Comment> $aComments
> *
> * @return void
*/
< public function setComments(array $aComments) {
> public function setComments(array $aComments)
> {
$this->aComments = $aComments;
}
<
}