Skip to content

Fixes #203 #204

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Nov 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions lib/Sabberworm/CSS/Parsing/ParserState.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ public function currentLine() {
return $this->iLineNo;
}

public function currentColumn() {
return $this->iCurrentPosition;
}

public function getSettings() {
return $this->oParserSettings;
}
Expand Down
18 changes: 16 additions & 2 deletions lib/Sabberworm/CSS/Rule/Rule.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,22 @@ class Rule implements Renderable, Commentable {
private $bIsImportant;
private $aIeHack;
protected $iLineNo;
protected $iColNo;
protected $aComments;

public function __construct($sRule, $iLineNo = 0) {
public function __construct($sRule, $iLineNo = 0, $iColNo = 0) {
$this->sRule = $sRule;
$this->mValue = null;
$this->bIsImportant = false;
$this->aIeHack = array();
$this->iLineNo = $iLineNo;
$this->iColNo = $iColNo;
$this->aComments = array();
}

public static function parse(ParserState $oParserState) {
$aComments = $oParserState->consumeWhiteSpace();
$oRule = new Rule($oParserState->parseIdentifier(!$oParserState->comes("--")), $oParserState->currentLine());
$oRule = new Rule($oParserState->parseIdentifier(!$oParserState->comes("--")), $oParserState->currentLine(), $oParserState->currentColumn());
$oRule->setComments($aComments);
$oRule->addComments($oParserState->consumeWhiteSpace());
$oParserState->consume(':');
Expand Down Expand Up @@ -75,6 +77,18 @@ public function getLineNo() {
return $this->iLineNo;
}

/**
* @return int
*/
public function getColNo() {
return $this->iColNo;
}

public function setPosition($iLine, $iColumn) {
$this->iColNo = $iColumn;
$this->iLineNo = $iLine;
}

public function setRule($sRule) {
$this->sRule = $sRule;
}
Expand Down
22 changes: 12 additions & 10 deletions lib/Sabberworm/CSS/RuleSet/DeclarationBlock.php
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ public function expandBorderShorthand() {
$sNewRuleName = $sBorderRule . "-style";
}
}
$oNewRule = new Rule($sNewRuleName, $this->iLineNo);
$oNewRule = new Rule($sNewRuleName, $oRule->getLineNo(), $oRule->getColNo());
$oNewRule->setIsImportant($oRule->getIsImportant());
$oNewRule->addValue(array($mNewValue));
$this->addRule($oNewRule);
Expand Down Expand Up @@ -245,7 +245,7 @@ public function expandDimensionsShorthand() {
break;
}
foreach (array('top', 'right', 'bottom', 'left') as $sPosition) {
$oNewRule = new Rule(sprintf($sExpanded, $sPosition), $this->iLineNo);
$oNewRule = new Rule(sprintf($sExpanded, $sPosition), $oRule->getLineNo(), $oRule->getColNo());
$oNewRule->setIsImportant($oRule->getIsImportant());
$oNewRule->addValue(${$sPosition});
$this->addRule($oNewRule);
Expand Down Expand Up @@ -310,7 +310,7 @@ public function expandFontShorthand() {
}
}
foreach ($aFontProperties as $sProperty => $mValue) {
$oNewRule = new Rule($sProperty, $this->iLineNo);
$oNewRule = new Rule($sProperty, $oRule->getLineNo(), $oRule->getColNo());
$oNewRule->addValue($mValue);
$oNewRule->setIsImportant($oRule->getIsImportant());
$this->addRule($oNewRule);
Expand Down Expand Up @@ -344,7 +344,7 @@ public function expandBackgroundShorthand() {
}
if (count($aValues) == 1 && $aValues[0] == 'inherit') {
foreach ($aBgProperties as $sProperty => $mValue) {
$oNewRule = new Rule($sProperty, $this->iLineNo);
$oNewRule = new Rule($sProperty, $oRule->getLineNo(), $oRule->getColNo());
$oNewRule->addValue('inherit');
$oNewRule->setIsImportant($oRule->getIsImportant());
$this->addRule($oNewRule);
Expand Down Expand Up @@ -378,7 +378,7 @@ public function expandBackgroundShorthand() {
}
}
foreach ($aBgProperties as $sProperty => $mValue) {
$oNewRule = new Rule($sProperty, $this->iLineNo);
$oNewRule = new Rule($sProperty, $oRule->getLineNo(), $oRule->getColNo());
$oNewRule->setIsImportant($oRule->getIsImportant());
$oNewRule->addValue($mValue);
$this->addRule($oNewRule);
Expand Down Expand Up @@ -414,7 +414,7 @@ public function expandListStyleShorthand() {
}
if (count($aValues) == 1 && $aValues[0] == 'inherit') {
foreach ($aListProperties as $sProperty => $mValue) {
$oNewRule = new Rule($sProperty, $this->iLineNo);
$oNewRule = new Rule($sProperty, $oRule->getLineNo(), $oRule->getColNo());
$oNewRule->addValue('inherit');
$oNewRule->setIsImportant($oRule->getIsImportant());
$this->addRule($oNewRule);
Expand All @@ -435,7 +435,7 @@ public function expandListStyleShorthand() {
}
}
foreach ($aListProperties as $sProperty => $mValue) {
$oNewRule = new Rule($sProperty, $this->iLineNo);
$oNewRule = new Rule($sProperty, $oRule->getLineNo(), $oRule->getColNo());
$oNewRule->setIsImportant($oRule->getIsImportant());
$oNewRule->addValue($mValue);
$this->addRule($oNewRule);
Expand Down Expand Up @@ -465,7 +465,7 @@ public function createShorthandProperties(array $aProperties, $sShorthand) {
}
}
if (count($aNewValues)) {
$oNewRule = new Rule($sShorthand, $this->iLineNo);
$oNewRule = new Rule($sShorthand, $oRule->getLineNo(), $oRule->getColNo());
foreach ($aNewValues as $mValue) {
$oNewRule->addValue($mValue);
}
Expand Down Expand Up @@ -538,7 +538,7 @@ public function createDimensionsShorthand() {
}
$aValues[$sPosition] = $aRuleValues;
}
$oNewRule = new Rule($sProperty, $this->iLineNo);
$oNewRule = new Rule($sProperty, $oRule->getLineNo(), $oRule->getColNo());
if ((string) $aValues['left'][0] == (string) $aValues['right'][0]) {
if ((string) $aValues['top'][0] == (string) $aValues['bottom'][0]) {
if ((string) $aValues['top'][0] == (string) $aValues['left'][0]) {
Expand Down Expand Up @@ -583,7 +583,9 @@ public function createFontShorthand() {
if (!isset($aRules['font-size']) || !isset($aRules['font-family'])) {
return;
}
$oNewRule = new Rule('font', $this->iLineNo);
$oOldRule = isset($aRules['font-size']) ? $aRules['font-size'] : $aRules['font-family'];
$oNewRule = new Rule('font', $oOldRule->getLineNo(), $oOldRule->getColNo());
unset($oOldRule);
foreach (array('font-style', 'font-variant', 'font-weight') as $sProperty) {
if (isset($aRules[$sProperty])) {
$oRule = $aRules[$sProperty];
Expand Down
16 changes: 16 additions & 0 deletions lib/Sabberworm/CSS/RuleSet/RuleSet.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,16 @@ public function addRule(Rule $oRule, Rule $oSibling = null) {
$iSiblingPos = array_search($oSibling, $this->aRules[$sRule], true);
if ($iSiblingPos !== false) {
$iPosition = $iSiblingPos;
$oRule->setPosition($oSibling->getLineNo(), $oSibling->getColNo() - 1);
}
}
if ($oRule->getLineNo() === 0 && $oRule->getColNo() === 0) {
//this node is added manually, give it the next best line
$rules = $this->getRules();
$pos = count($rules);
if ($pos > 0) {
$last = $rules[$pos - 1];
$oRule->setPosition($last->getLineNo() + 1, 0);
}
}

Expand All @@ -102,6 +112,12 @@ public function getRules($mRule = null) {
$aResult = array_merge($aResult, $aRules);
}
}
usort($aResult, function (Rule $first, Rule $second) {
if ($first->getLineNo() === $second->getLineNo()) {
return $first->getColNo() - $second->getColNo();
}
return $first->getLineNo() - $second->getLineNo();
});
return $aResult;
}

Expand Down
23 changes: 23 additions & 0 deletions tests/Sabberworm/CSS/RuleSet/DeclarationBlockTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -264,4 +264,27 @@ public function testRuleInsertion() {
$this->assertSame('.wrapper {left: 16em;left: 10px;text-align: 1;text-align: left;border-bottom-width: 1px;}', $oDoc->render());
}

public function testOrderOfElementsMatchingOriginalOrderAfterExpandingShorthands()
{
$sCss = '.rule{padding:5px;padding-top: 20px}';
$oParser = new Parser($sCss);
$oDoc = $oParser->parse();
$aDocs = $oDoc->getAllDeclarationBlocks();

$this->assertCount(1, $aDocs);

$oDeclaration = array_pop($aDocs);
$oDeclaration->expandShorthands();

$this->assertEquals(
array(
'padding-top' => 'padding-top: 20px;',
'padding-right' => 'padding-right: 5px;',
'padding-bottom' => 'padding-bottom: 5px;',
'padding-left' => 'padding-left: 5px;',
),
array_map('strval', $oDeclaration->getRulesAssoc())
);
}

}