2121use Sabberworm \CSS \Value \CSSString ;
2222use Sabberworm \CSS \Rule \Rule ;
2323use Sabberworm \CSS \Parsing \UnexpectedTokenException ;
24+ use Sabberworm \CSS \Comment \Comment ;
2425
2526/**
2627 * Parser class parses CSS from text into a data structure.
@@ -83,12 +84,12 @@ public function parse() {
8384 }
8485
8586 private function parseDocument (Document $ oDocument ) {
86- $ this ->consumeWhiteSpace ();
8787 $ this ->parseList ($ oDocument , true );
8888 }
8989
9090 private function parseList (CSSList $ oList , $ bIsRoot = false ) {
9191 while (!$ this ->isEnd ()) {
92+ $ comments = $ this ->consumeWhiteSpace ();
9293 $ oListItem = null ;
9394 if ($ this ->oParserSettings ->bLenientParsing ) {
9495 try {
@@ -104,9 +105,9 @@ private function parseList(CSSList $oList, $bIsRoot = false) {
104105 return ;
105106 }
106107 if ($ oListItem ) {
108+ $ oListItem ->setComments ($ comments );
107109 $ oList ->append ($ oListItem );
108110 }
109- $ this ->consumeWhiteSpace ();
110111 }
111112 if (!$ bIsRoot ) {
112113 throw new SourceException ("Unexpected end of document " , $ this ->iLineNo );
@@ -161,7 +162,6 @@ private function parseAtRule() {
161162 $ oResult = new KeyFrame ($ iIdentifierLineNum );
162163 $ oResult ->setVendorKeyFrame ($ sIdentifier );
163164 $ oResult ->setAnimationName (trim ($ this ->consumeUntil ('{ ' , false , true )));
164- $ this ->consumeWhiteSpace ();
165165 $ this ->parseList ($ oResult );
166166 return $ oResult ;
167167 } else if ($ sIdentifier === 'namespace ' ) {
@@ -182,7 +182,6 @@ private function parseAtRule() {
182182 } else {
183183 //Unknown other at rule (font-face or such)
184184 $ sArgs = trim ($ this ->consumeUntil ('{ ' , false , true ));
185- $ this ->consumeWhiteSpace ();
186185 $ bUseRuleSet = true ;
187186 foreach ($ this ->blockRules as $ sBlockRuleName ) {
188187 if ($ this ->identifierIs ($ sIdentifier , $ sBlockRuleName )) {
@@ -299,17 +298,17 @@ private function parseCharacter($bIsForIdentifier) {
299298 }
300299
301300 private function parseSelector () {
301+ $ aComments = $ this ->consumeWhiteSpace ();
302302 $ oResult = new DeclarationBlock ($ this ->iLineNo );
303303 $ oResult ->setSelector ($ this ->consumeUntil ('{ ' , false , true ));
304- $ this -> consumeWhiteSpace ( );
304+ $ oResult -> setComments ( $ aComments );
305305 $ this ->parseRuleSet ($ oResult );
306306 return $ oResult ;
307307 }
308308
309309 private function parseRuleSet ($ oRuleSet ) {
310310 while ($ this ->comes ('; ' )) {
311311 $ this ->consume ('; ' );
312- $ this ->consumeWhiteSpace ();
313312 }
314313 while (!$ this ->comes ('} ' )) {
315314 $ oRule = null ;
@@ -323,7 +322,6 @@ private function parseRuleSet($oRuleSet) {
323322 if ($ this ->streql (substr ($ sConsume , -1 ), '} ' )) {
324323 --$ this ->iCurrentPosition ;
325324 } else {
326- $ this ->consumeWhiteSpace ();
327325 while ($ this ->comes ('; ' )) {
328326 $ this ->consume ('; ' );
329327 }
@@ -339,14 +337,15 @@ private function parseRuleSet($oRuleSet) {
339337 if ($ oRule ) {
340338 $ oRuleSet ->addRule ($ oRule );
341339 }
342- $ this ->consumeWhiteSpace ();
343340 }
344341 $ this ->consume ('} ' );
345342 }
346343
347344 private function parseRule () {
345+ $ aComments = $ this ->consumeWhiteSpace ();
348346 $ oRule = new Rule ($ this ->parseIdentifier (), $ this ->iLineNo );
349- $ this ->consumeWhiteSpace ();
347+ $ oRule ->setComments ($ aComments );
348+ $ oRule ->addComments ($ this ->consumeWhiteSpace ());
350349 $ this ->consume (': ' );
351350 $ oValue = $ this ->parseValue (self ::listDelimiterForRule ($ oRule ->getRule ()));
352351 $ oRule ->setValue ($ oValue );
@@ -358,7 +357,6 @@ private function parseRule() {
358357 }
359358 while ($ this ->comes ('; ' )) {
360359 $ this ->consume ('; ' );
361- $ this ->consumeWhiteSpace ();
362360 }
363361 return $ oRule ;
364362 }
@@ -557,35 +555,53 @@ private function consumeExpression($mExpression) {
557555 }
558556
559557 private function consumeWhiteSpace () {
558+ $ comments = array ();
560559 do {
561560 while (preg_match ('/ \\s/isSu ' , $ this ->peek ()) === 1 ) {
562561 $ this ->consume (1 );
563562 }
564563 if ($ this ->oParserSettings ->bLenientParsing ) {
565564 try {
566- $ bHasComment = $ this ->consumeComment ();
565+ $ oComment = $ this ->consumeComment ();
567566 } catch (UnexpectedTokenException $ e ) {
568567 // When we can’t find the end of a comment, we assume the document is finished.
569568 $ this ->iCurrentPosition = $ this ->iLength ;
570569 return ;
571570 }
572571 } else {
573- $ bHasComment = $ this ->consumeComment ();
572+ $ oComment = $ this ->consumeComment ();
573+ }
574+ if ($ oComment !== false ) {
575+ $ comments [] = $ oComment ;
574576 }
575- } while ($ bHasComment );
577+ } while ($ oComment !== false );
578+ return $ comments ;
576579 }
577580
581+ /**
582+ * @return false|Comment
583+ */
578584 private function consumeComment () {
585+ $ mComment = false ;
579586 if ($ this ->comes ('/* ' )) {
587+ $ iLineNo = $ this ->iLineNo ;
580588 $ this ->consume (1 );
581- while ($ this ->consume (1 ) !== '' ) {
589+ $ mComment = '' ;
590+ while (($ char = $ this ->consume (1 )) !== '' ) {
591+ $ mComment .= $ char ;
582592 if ($ this ->comes ('*/ ' )) {
583593 $ this ->consume (2 );
584- return true ;
594+ break ;
585595 }
586596 }
587597 }
588- return false ;
598+
599+ if ($ mComment !== false ) {
600+ // We skip the * which was included in the comment.
601+ return new Comment (substr ($ mComment , 1 ), $ iLineNo );
602+ }
603+
604+ return $ mComment ;
589605 }
590606
591607 private function isEnd () {
0 commit comments