Skip to content

Commit

Permalink
CSS minifier: quickly fixed a bug that was breaking selectors contain…
Browse files Browse the repository at this point in the history
…ing a pseudo-class.
  • Loading branch information
Daniel Bettles committed Jan 17, 2023
1 parent 351c39f commit 7ae149f
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 13 deletions.
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

No unreleased changes.

## [2.3.3] - 2023-01-17

### Fixed

- In the CSS minifier, fixed a bug that was breaking selectors containing a pseudo-class.

## [2.3.2] - 2022-12-19

### Changed
Expand Down Expand Up @@ -64,7 +70,8 @@ No unreleased changes.

First stable release.

[unreleased]: https://github.com/danbettles/marigold/compare/v2.3.2...HEAD
[unreleased]: https://github.com/danbettles/marigold/compare/v2.3.3...HEAD
[2.3.3]: https://github.com/danbettles/marigold/compare/v2.3.2...v2.3.3
[2.3.2]: https://github.com/danbettles/marigold/compare/v2.3.1...v2.3.2
[2.3.1]: https://github.com/danbettles/marigold/compare/v2.3.0...v2.3.1
[2.3.0]: https://github.com/danbettles/marigold/compare/v2.2.1...v2.3.0
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
Marigold is a small set of tools that aims to make building simple websites easier while keeping you close to the metal and adding minimal overheads; it is not a framework.

Marigold is good for:

* Building minimal apps like [Miniblog](https://github.com/miniblog/engine).
* Transitioning unstructured code to a framework, or simply making improvements to an unruly app.
* Building basic websites using templates like those at [HTML5 UP](https://html5up.net/).
Expand Down
24 changes: 14 additions & 10 deletions src/CssMinifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,24 +42,28 @@ private function replace(
*/
public function removeSuperfluousWhitespaceFilter(string $css): string
{
//Normalize newlines.
// Normalize newlines.
$css = str_replace(["\r\n", "\r", "\n"], "\n", $css);

//Normalize horizontal whitespace.
// Normalize horizontal whitespace.
$css = str_replace("\t", ' ', $css);

//Replace multiple, contiguous occurrences of the same whitespace character with just one.
//We don't simply replace all whitespace characters with spaces - for example - because we want to retain the
//vertical structure of the CSS, so that it's just about readable after minification.
// Replace multiple, contiguous occurrences of the same whitespace character with just one.
// We don't simply replace all whitespace characters with spaces - for example - because we want to retain the
// vertical structure of the CSS, so that it's just about readable after minification.
$css = $this->replace('/([\n ])\1+/', '$1', $css);

//Remove horizontal whitespace from around delimiters.
$css = $this->replace('/[ ]*([,:;\{\}])[ ]*/', '$1', $css);
// Remove horizontal whitespace from around delimiters.
$css = $this->replace('/[ ]*([,;\{\}])[ ]*/', '$1', $css);

//Remove leading and trailing whitespace from lines.
// Remove horizontal space from after colons. We can't *easily* remove whitespace from before colons without
// risking breaking selectors containing a pseudo-class.
$css = str_replace(': ', ':', $css);

// Remove leading and trailing whitespace from lines.
$css = $this->replace('/^[ ]*(.*?)[ ]*$/m', '$1', $css);

//Remove empty lines.
// Remove empty lines.
$css = trim($this->replace('/(?<=\n)[ ]*\n|/', '', $css));

return $css;
Expand All @@ -81,7 +85,7 @@ public function removeCommentsFilter(string $css): string
*/
public function removeUnitsFromZeroesFilter(string $css): string
{
//See http://www.w3.org/TR/CSS21/grammar.html#scanner and http://www.w3schools.com/cssref/css_units.asp
// See http://www.w3.org/TR/CSS21/grammar.html#scanner and http://www.w3schools.com/cssref/css_units.asp
return $this->replace('/\b0((?:em|ex|ch|rem|vw|vh|vmin|vm|vmax|cm|mm|in|px|pt|pc)\b|%)/i', '0', $css);
}

Expand Down
23 changes: 21 additions & 2 deletions tests/src/CssMinifierTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public function providesCssWithSuperfluousWhitespaceRemoved(): array
"h1, h2 {\n font-weight: bold;\n}",
],
[
"h1,h2{font-weight:bold;}",
"h1,h2{font-weight :bold;}",
"h1 , h2 { font-weight : bold ; }",
],
];
Expand Down Expand Up @@ -180,7 +180,7 @@ public function providesCssThatHasBeenMinified(): array
[
<<<END
body{
color:#000;
color :#000;
}
h1,h2{font-weight:bold;}
.smallest{
Expand Down Expand Up @@ -211,4 +211,23 @@ public function testMinifyMinifiesTheSpecifiedCssUsingAllFilters(

$this->assertSame($expected, $minified);
}

public function testDoesNotBreakRuleSetsUsingTheWherePseudoClass(): void
{
$minified = (new CssMinifier())->minify(<<<END
:where(nav) :where(ol, ul) {
list-style-type: none;
padding: 0;
border : 0;
}
END);

$this->assertSame(<<<END
:where(nav) :where(ol,ul){
list-style-type:none;
padding:0;
border :0;
}
END, $minified);
}
}

0 comments on commit 7ae149f

Please sign in to comment.