PHP-CSS-Parser icon indicating copy to clipboard operation
PHP-CSS-Parser copied to clipboard

Remove empty blocks

Open reardestani opened this issue 6 years ago • 2 comments

I need to remove blocks without values. The codes work but when the block is inside @media it does not work as expected.

Is it a bug or I am missing sth?

Sample:

$content = 'body{color: green;}
.post {}
@media (max-width: 767.98px) {.title {}}'

$parser = new Sabberworm\CSS\Parser( $content );
$parser = $parser->parse();

foreach ( $parser->getAllDeclarationBlocks() as $block ) {
	if ( ! empty ( $block->getRules() ) ) {
	 	continue;
	}
	$parser->removeDeclarationBlockBySelector( $block );
}

Result:

body{color: green;}
@media (max-width: 767.98px) {.title {}}

Expectation:

body{color: green;}

reardestani avatar Nov 06 '18 10:11 reardestani

It’s most likely a bug. But there may be other ways of doing what you want. getAllDeclarationBlocks and removeDeclarationBlockBySelector are both essentially convenience methods that do the recursion for you.

sabberworm avatar Nov 06 '18 13:11 sabberworm

@reardestani That's because removeDeclarationBlockBySelector doesn't recurse. However what you are doing is dangerous anyway, because there might be non-empty blocks with the same selector. You should do it like this:

function removeBlanks($oList) {
    foreach ($oList->getContents() as $oBlock) {
        if ($oBlock instanceof Sabberworm\CSS\RuleSet\DeclarationBlock) {
            if ( empty ( $oBlock->getRules() ) ) {
                $oList->remove( $oBlock );
            }
        } else if ($oBlock instanceof Sabberworm\CSS\CSSList\CSSBlockList) {
            removeBlanks($oBlock);
            /* Uncomment if you want to remove empty @media blocks as well
            if (empty($oBlock->getContents())) {
                $oList->remove($oBlock);
            }
            */
        }
    }
}
removeBlanks($parser);

raxbg avatar Nov 13 '19 19:11 raxbg