Skip to content

Commit 9c89b95

Browse files
authored
Merge pull request #351 from Ruud68/retain-comments
2 parents f5c6a9c + d82e408 commit 9c89b95

16 files changed

+240
-104
lines changed

src/CSSList/AtRuleBlockList.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,14 @@ public function __toString()
6161
*/
6262
public function render(OutputFormat $oOutputFormat)
6363
{
64+
$sResult = $oOutputFormat->comments($this);
65+
$sResult .= $oOutputFormat->sBeforeAtRuleBlock;
6466
$sArgs = $this->sArgs;
6567
if ($sArgs) {
6668
$sArgs = ' ' . $sArgs;
6769
}
68-
$sResult = $oOutputFormat->sBeforeAtRuleBlock;
6970
$sResult .= "@{$this->sType}$sArgs{$oOutputFormat->spaceBeforeOpeningBrace()}{";
70-
$sResult .= parent::render($oOutputFormat);
71+
$sResult .= $this->renderListContents($oOutputFormat);
7172
$sResult .= '}';
7273
$sResult .= $oOutputFormat->sAfterAtRuleBlock;
7374
return $sResult;

src/CSSList/CSSList.php

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,9 @@ public static function parseList(ParserState $oParserState, CSSList $oList)
6969
$oParserState = new ParserState($oParserState, Settings::create());
7070
}
7171
$bLenientParsing = $oParserState->getSettings()->bLenientParsing;
72+
$aComments = [];
7273
while (!$oParserState->isEnd()) {
73-
$comments = $oParserState->consumeWhiteSpace();
74+
$aComments = array_merge($aComments, $oParserState->consumeWhiteSpace());
7475
$oListItem = null;
7576
if ($bLenientParsing) {
7677
try {
@@ -86,11 +87,12 @@ public static function parseList(ParserState $oParserState, CSSList $oList)
8687
return;
8788
}
8889
if ($oListItem) {
89-
$oListItem->setComments($comments);
90+
$oListItem->addComments($aComments);
9091
$oList->append($oListItem);
9192
}
92-
$oParserState->consumeWhiteSpace();
93+
$aComments = $oParserState->consumeWhiteSpace();
9394
}
95+
$oList->addComments($aComments);
9496
if (!$bIsRoot && !$bLenientParsing) {
9597
throw new SourceException("Unexpected end of document", $oParserState->currentLine());
9698
}
@@ -125,7 +127,7 @@ private static function parseListItem(ParserState $oParserState, CSSList $oList)
125127
$oParserState->currentLine()
126128
);
127129
}
128-
$oParserState->setCharset($oAtRule->getCharset()->getString());
130+
$oParserState->setCharset($oAtRule->getCharset());
129131
}
130132
return $oAtRule;
131133
} elseif ($oParserState->comes('}')) {
@@ -172,10 +174,10 @@ private static function parseAtRule(ParserState $oParserState)
172174
$oParserState->consumeUntil([';', ParserState::EOF], true, true);
173175
return new Import($oLocation, $sMediaQuery ?: null, $iIdentifierLineNum);
174176
} elseif ($sIdentifier === 'charset') {
175-
$sCharset = CSSString::parse($oParserState);
177+
$oCharsetString = CSSString::parse($oParserState);
176178
$oParserState->consumeWhiteSpace();
177179
$oParserState->consumeUntil([';', ParserState::EOF], true, true);
178-
return new Charset($sCharset, $iIdentifierLineNum);
180+
return new Charset($oCharsetString, $iIdentifierLineNum);
179181
} elseif (self::identifierIs($sIdentifier, 'keyframes')) {
180182
$oResult = new KeyFrame($iIdentifierLineNum);
181183
$oResult->setVendorKeyFrame($sIdentifier);
@@ -402,7 +404,7 @@ public function __toString()
402404
/**
403405
* @return string
404406
*/
405-
public function render(OutputFormat $oOutputFormat)
407+
protected function renderListContents(OutputFormat $oOutputFormat)
406408
{
407409
$sResult = '';
408410
$bIsFirst = true;

src/CSSList/Document.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ public function render(OutputFormat $oOutputFormat = null)
159159
if ($oOutputFormat === null) {
160160
$oOutputFormat = new OutputFormat();
161161
}
162-
return parent::render($oOutputFormat);
162+
return $oOutputFormat->comments($this) . $this->renderListContents($oOutputFormat);
163163
}
164164

165165
/**

src/CSSList/KeyFrame.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,9 @@ public function __toString()
7272
*/
7373
public function render(OutputFormat $oOutputFormat)
7474
{
75-
$sResult = "@{$this->vendorKeyFrame} {$this->animationName}{$oOutputFormat->spaceBeforeOpeningBrace()}{";
76-
$sResult .= parent::render($oOutputFormat);
75+
$sResult = $oOutputFormat->comments($this);
76+
$sResult .= "@{$this->vendorKeyFrame} {$this->animationName}{$oOutputFormat->spaceBeforeOpeningBrace()}{";
77+
$sResult .= $this->renderListContents($oOutputFormat);
7778
$sResult .= '}';
7879
return $sResult;
7980
}

src/OutputFormat.php

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,13 @@ class OutputFormat
143143
*/
144144
public $bIgnoreExceptions = false;
145145

146+
/**
147+
* Render comments for lists and RuleSets
148+
*
149+
* @var bool
150+
*/
151+
public $bRenderComments = false;
152+
146153
/**
147154
* @var OutputFormatter|null
148155
*/
@@ -314,8 +321,12 @@ public static function create()
314321
public static function createCompact()
315322
{
316323
$format = self::create();
317-
$format->set('Space*Rules', "")->set('Space*Blocks', "")->setSpaceAfterRuleName('')
318-
->setSpaceBeforeOpeningBrace('')->setSpaceAfterSelectorSeparator('');
324+
$format->set('Space*Rules', "")
325+
->set('Space*Blocks', "")
326+
->setSpaceAfterRuleName('')
327+
->setSpaceBeforeOpeningBrace('')
328+
->setSpaceAfterSelectorSeparator('')
329+
->setRenderComments(false);
319330
return $format;
320331
}
321332

@@ -327,8 +338,11 @@ public static function createCompact()
327338
public static function createPretty()
328339
{
329340
$format = self::create();
330-
$format->set('Space*Rules', "\n")->set('Space*Blocks', "\n")
331-
->setSpaceBetweenBlocks("\n\n")->set('SpaceAfterListArgumentSeparator', ['default' => '', ',' => ' ']);
341+
$format->set('Space*Rules', "\n")
342+
->set('Space*Blocks', "\n")
343+
->setSpaceBetweenBlocks("\n\n")
344+
->set('SpaceAfterListArgumentSeparator', ['default' => '', ',' => ' '])
345+
->setRenderComments(true);
332346
return $format;
333347
}
334348
}

src/OutputFormatter.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Sabberworm\CSS;
44

5+
use Sabberworm\CSS\Comment\Commentable;
56
use Sabberworm\CSS\Parsing\OutputException;
67

78
class OutputFormatter
@@ -211,6 +212,28 @@ public function removeLastSemicolon($sString)
211212
return implode(';', $sString);
212213
}
213214

215+
/**
216+
*
217+
* @param array<Commentable> $aComments
218+
* @return string
219+
*/
220+
public function comments(Commentable $oCommentable)
221+
{
222+
if (!$this->oFormat->bRenderComments) {
223+
return '';
224+
}
225+
226+
$sResult = '';
227+
$aComments = $oCommentable->getComments();
228+
$iLastCommentIndex = count($aComments) - 1;
229+
230+
foreach ($aComments as $i => $oComment) {
231+
$sResult .= $oComment->render($this->oFormat);
232+
$sResult .= $i === $iLastCommentIndex ? $this->spaceAfterBlocks() : $this->spaceBetweenBlocks();
233+
}
234+
return $sResult;
235+
}
236+
214237
/**
215238
* @param string $sSpaceString
216239
*

src/Parsing/ParserState.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ public function parseCharacter($bIsForIdentifier)
204204
*/
205205
public function consumeWhiteSpace()
206206
{
207-
$comments = [];
207+
$aComments = [];
208208
do {
209209
while (preg_match('/\\s/isSu', $this->peek()) === 1) {
210210
$this->consume(1);
@@ -214,16 +214,16 @@ public function consumeWhiteSpace()
214214
$oComment = $this->consumeComment();
215215
} catch (UnexpectedEOFException $e) {
216216
$this->iCurrentPosition = $this->iLength;
217-
return;
217+
return $aComments;
218218
}
219219
} else {
220220
$oComment = $this->consumeComment();
221221
}
222222
if ($oComment !== false) {
223-
$comments[] = $oComment;
223+
$aComments[] = $oComment;
224224
}
225225
} while ($oComment !== false);
226-
return $comments;
226+
return $aComments;
227227
}
228228

229229
/**

src/Property/Charset.php

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Sabberworm\CSS\Comment\Comment;
66
use Sabberworm\CSS\OutputFormat;
7+
use Sabberworm\CSS\Value\CSSString;
78

89
/**
910
* Class representing an `@charset` rule.
@@ -16,9 +17,9 @@
1617
class Charset implements AtRule
1718
{
1819
/**
19-
* @var string
20+
* @var CSSString
2021
*/
21-
private $sCharset;
22+
private $oCharset;
2223

2324
/**
2425
* @var int
@@ -31,12 +32,12 @@ class Charset implements AtRule
3132
protected $aComments;
3233

3334
/**
34-
* @param string $sCharset
35+
* @param CSSString $oCharset
3536
* @param int $iLineNo
3637
*/
37-
public function __construct($sCharset, $iLineNo = 0)
38+
public function __construct(CSSString $oCharset, $iLineNo = 0)
3839
{
39-
$this->sCharset = $sCharset;
40+
$this->oCharset = $oCharset;
4041
$this->iLineNo = $iLineNo;
4142
$this->aComments = [];
4243
}
@@ -50,21 +51,22 @@ public function getLineNo()
5051
}
5152

5253
/**
53-
* @param string $sCharset
54+
* @param string|CSSString $oCharset
5455
*
5556
* @return void
5657
*/
5758
public function setCharset($sCharset)
5859
{
59-
$this->sCharset = $sCharset;
60+
$sCharset = $sCharset instanceof CSSString ? $sCharset : new CSSString($sCharset);
61+
$this->oCharset = $sCharset;
6062
}
6163

6264
/**
6365
* @return string
6466
*/
6567
public function getCharset()
6668
{
67-
return $this->sCharset;
69+
return $this->oCharset->getString();
6870
}
6971

7072
/**
@@ -80,7 +82,7 @@ public function __toString()
8082
*/
8183
public function render(OutputFormat $oOutputFormat)
8284
{
83-
return "@charset {$this->sCharset->render($oOutputFormat)};";
85+
return "{$oOutputFormat->comments($this)}@charset {$this->oCharset->render($oOutputFormat)};";
8486
}
8587

8688
/**
@@ -96,7 +98,7 @@ public function atRuleName()
9698
*/
9799
public function atRuleArgs()
98100
{
99-
return $this->sCharset;
101+
return $this->oCharset;
100102
}
101103

102104
/**

src/Property/Import.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ public function __toString()
8383
*/
8484
public function render(OutputFormat $oOutputFormat)
8585
{
86-
return "@import " . $this->oLocation->render($oOutputFormat)
86+
return $oOutputFormat->comments($this) . "@import " . $this->oLocation->render($oOutputFormat)
8787
. ($this->sMediaQuery === null ? '' : ' ' . $this->sMediaQuery) . ';';
8888
}
8989

src/Rule/Rule.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -346,8 +346,8 @@ public function __toString()
346346
*/
347347
public function render(OutputFormat $oOutputFormat)
348348
{
349-
$sResult = "{$this->sRule}:{$oOutputFormat->spaceAfterRuleName()}";
350-
if ($this->mValue instanceof Value) { //Can also be a ValueList
349+
$sResult = "{$oOutputFormat->comments($this)}{$this->sRule}:{$oOutputFormat->spaceAfterRuleName()}";
350+
if ($this->mValue instanceof Value) { // Can also be a ValueList
351351
$sResult .= $this->mValue->render($oOutputFormat);
352352
} else {
353353
$sResult .= $this->mValue;

src/RuleSet/AtRuleSet.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,13 @@ public function __toString()
6161
*/
6262
public function render(OutputFormat $oOutputFormat)
6363
{
64+
$sResult = $oOutputFormat->comments($this);
6465
$sArgs = $this->sArgs;
6566
if ($sArgs) {
6667
$sArgs = ' ' . $sArgs;
6768
}
68-
$sResult = "@{$this->sType}$sArgs{$oOutputFormat->spaceBeforeOpeningBrace()}{";
69-
$sResult .= parent::render($oOutputFormat);
69+
$sResult .= "@{$this->sType}$sArgs{$oOutputFormat->spaceBeforeOpeningBrace()}{";
70+
$sResult .= $this->renderRules($oOutputFormat);
7071
$sResult .= '}';
7172
return $sResult;
7273
}

src/RuleSet/DeclarationBlock.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -812,18 +812,19 @@ public function __toString()
812812
*/
813813
public function render(OutputFormat $oOutputFormat)
814814
{
815+
$sResult = $oOutputFormat->comments($this);
815816
if (count($this->aSelectors) === 0) {
816817
// If all the selectors have been removed, this declaration block becomes invalid
817818
throw new OutputException("Attempt to print declaration block with missing selector", $this->iLineNo);
818819
}
819-
$sResult = $oOutputFormat->sBeforeDeclarationBlock;
820+
$sResult .= $oOutputFormat->sBeforeDeclarationBlock;
820821
$sResult .= $oOutputFormat->implode(
821822
$oOutputFormat->spaceBeforeSelectorSeparator() . ',' . $oOutputFormat->spaceAfterSelectorSeparator(),
822823
$this->aSelectors
823824
);
824825
$sResult .= $oOutputFormat->sAfterDeclarationBlockSelectors;
825826
$sResult .= $oOutputFormat->spaceBeforeOpeningBrace() . '{';
826-
$sResult .= parent::render($oOutputFormat);
827+
$sResult .= $this->renderRules($oOutputFormat);
827828
$sResult .= '}';
828829
$sResult .= $oOutputFormat->sAfterDeclarationBlock;
829830
return $sResult;

src/RuleSet/RuleSet.php

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -266,23 +266,24 @@ public function __toString()
266266
/**
267267
* @return string
268268
*/
269-
public function render(OutputFormat $oOutputFormat)
269+
protected function renderRules(OutputFormat $oOutputFormat)
270270
{
271271
$sResult = '';
272272
$bIsFirst = true;
273+
$oNextLevel = $oOutputFormat->nextLevel();
273274
foreach ($this->aRules as $aRules) {
274275
foreach ($aRules as $oRule) {
275-
$sRendered = $oOutputFormat->safely(function () use ($oRule, $oOutputFormat) {
276-
return $oRule->render($oOutputFormat->nextLevel());
276+
$sRendered = $oNextLevel->safely(function () use ($oRule, $oNextLevel) {
277+
return $oRule->render($oNextLevel);
277278
});
278279
if ($sRendered === null) {
279280
continue;
280281
}
281282
if ($bIsFirst) {
282283
$bIsFirst = false;
283-
$sResult .= $oOutputFormat->nextLevel()->spaceBeforeRules();
284+
$sResult .= $oNextLevel->spaceBeforeRules();
284285
} else {
285-
$sResult .= $oOutputFormat->nextLevel()->spaceBetweenRules();
286+
$sResult .= $oNextLevel->spaceBetweenRules();
286287
}
287288
$sResult .= $sRendered;
288289
}

0 commit comments

Comments
 (0)