From 28d9ed303459d08a567e40f345909d4ec8431379 Mon Sep 17 00:00:00 2001 From: Frederic Massart Date: Mon, 13 Sep 2021 15:12:25 +1200 Subject: [PATCH 1/2] Support for inserting an item in a CSSList --- src/CSSList/CSSList.php | 14 ++++++++++++++ tests/CSSList/DocumentTest.php | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/src/CSSList/CSSList.php b/src/CSSList/CSSList.php index 946740a4..92b89d8f 100644 --- a/src/CSSList/CSSList.php +++ b/src/CSSList/CSSList.php @@ -297,6 +297,20 @@ public function splice($iOffset, $iLength = null, $mReplacement = null) array_splice($this->aContents, $iOffset, $iLength, $mReplacement); } + /** + * Insert an item before its sibling. + * + * @param mixed $oItem The item. + * @param mixed $oSibling The sibling. + */ + public function insert($oItem, $oSibling) { + $iIndex = array_search($oSibling, $this->aContents); + if ($iIndex === false) { + return $this->append($oItem); + } + array_splice($this->aContents, $iIndex, 0, array($oItem)); + } + /** * Removes an item from the CSS list. * diff --git a/tests/CSSList/DocumentTest.php b/tests/CSSList/DocumentTest.php index c4071a25..d43a33be 100644 --- a/tests/CSSList/DocumentTest.php +++ b/tests/CSSList/DocumentTest.php @@ -5,6 +5,7 @@ use PHPUnit\Framework\TestCase; use Sabberworm\CSS\CSSList\Document; use Sabberworm\CSS\RuleSet\DeclarationBlock; +use Sabberworm\CSS\Parser; /** * @covers \Sabberworm\CSS\CSSList\Document @@ -67,4 +68,36 @@ public function setContentsReplacesContentsSetInPreviousCall() self::assertSame($contents2, $this->subject->getContents()); } + + public function testInsertContent() { + $sCss = '.thing { left: 10px; } .stuff { margin: 1px; } '; + $oParser = new Parser($sCss); + $oDoc = $oParser->parse(); + $aContents = $oDoc->getContents(); + $this->assertCount(2, $aContents); + + $oThing = $aContents[0]; + $oStuff = $aContents[1]; + + $oFirst = new DeclarationBlock(); + $oFirst->setSelectors('.first'); + $oBetween = new DeclarationBlock(); + $oBetween->setSelectors('.between'); + $oOrphan = new DeclarationBlock(); + $oOrphan->setSelectors('.forever-alone'); + $oNotFound = new DeclarationBlock(); + $oNotFound->setSelectors('.not-found'); + + $oDoc->insert($oFirst, $oThing); + $oDoc->insert($oBetween, $oStuff); + $oDoc->insert($oOrphan, $oNotFound); + + $aContents = $oDoc->getContents(); + $this->assertCount(5, $aContents); + $this->assertSame($oFirst, $aContents[0]); + $this->assertSame($oThing, $aContents[1]); + $this->assertSame($oBetween, $aContents[2]); + $this->assertSame($oStuff, $aContents[3]); + $this->assertSame($oOrphan, $aContents[4]); + } } From 2141f50d80ca54f27232adbed5277fca6d315a14 Mon Sep 17 00:00:00 2001 From: Simon Chester Date: Mon, 13 Sep 2021 15:12:48 +1200 Subject: [PATCH 2/2] Fix comments being omitted in the middle of a rule Also fixes comments between CSSLists. --- src/CSSList/CSSList.php | 2 +- src/Parsing/ParserState.php | 6 +++++- src/Rule/Rule.php | 2 +- tests/ParserTest.php | 13 +++++++++++++ 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/CSSList/CSSList.php b/src/CSSList/CSSList.php index 92b89d8f..8095af8a 100644 --- a/src/CSSList/CSSList.php +++ b/src/CSSList/CSSList.php @@ -89,7 +89,7 @@ public static function parseList(ParserState $oParserState, CSSList $oList) $oListItem->setComments($comments); $oList->append($oListItem); } - $oParserState->consumeWhiteSpace(); + $oParserState->consumeWhiteSpace(false); } if (!$bIsRoot && !$bLenientParsing) { throw new SourceException("Unexpected end of document", $oParserState->currentLine()); diff --git a/src/Parsing/ParserState.php b/src/Parsing/ParserState.php index e7d85ee0..cc66d5a4 100644 --- a/src/Parsing/ParserState.php +++ b/src/Parsing/ParserState.php @@ -197,18 +197,22 @@ public function parseCharacter($bIsForIdentifier) } /** + * @param bool $consumeComments * @return array|void * * @throws UnexpectedEOFException * @throws UnexpectedTokenException */ - public function consumeWhiteSpace() + public function consumeWhiteSpace($consumeComments = true) { $comments = []; do { while (preg_match('/\\s/isSu', $this->peek()) === 1) { $this->consume(1); } + if (!$consumeComments) { + return; + } if ($this->oParserSettings->bLenientParsing) { try { $oComment = $this->consumeComment(); diff --git a/src/Rule/Rule.php b/src/Rule/Rule.php index c1ea6df7..63cc4057 100644 --- a/src/Rule/Rule.php +++ b/src/Rule/Rule.php @@ -106,7 +106,7 @@ public static function parse(ParserState $oParserState) while ($oParserState->comes(';')) { $oParserState->consume(';'); } - $oParserState->consumeWhiteSpace(); + $oParserState->consumeWhiteSpace(false); return $oRule; } diff --git a/tests/ParserTest.php b/tests/ParserTest.php index ab247c3d..d4c32003 100644 --- a/tests/ParserTest.php +++ b/tests/ParserTest.php @@ -1120,6 +1120,19 @@ public function flatCommentExtracting() self::assertSame("Find Me!", $comments[0]->getComment()); } + /** + * @test + */ + public function testInnerCommentExtracting() { + $parser = new Parser('div {left:10px;/*Find Me!*/text-align:left;}'); + $doc = $parser->parse(); + $contents = $doc->getContents(); + $divRules = $contents[0]->getRules(); + $comments = $divRules[1]->getComments(); + $this->assertCount(1, $comments); + $this->assertEquals("Find Me!", $comments[0]->getComment()); + } + /** * @test */