From 9251a90928f4b0c67855cfb4ed9756c583bd8c27 Mon Sep 17 00:00:00 2001 From: Rudy Celekli <47457359+rudycelekli@users.noreply.github.com> Date: Tue, 6 Oct 2026 10:02:13 -0400 Subject: [PATCH] fix(site): preserve CSS strings when removing comments Signed-off-by: Rudy Celekli <47457359+rudycelekli@users.noreply.github.com> --- scripts/minify_css.py | 20 ++++++-------------- tests/test_minify_css.py | 13 +++++++++++++ 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/scripts/minify_css.py b/scripts/minify_css.py index 048ea0fc..fb369c4c 100644 --- a/scripts/minify_css.py +++ b/scripts/minify_css.py @@ -19,26 +19,18 @@ import sys from pathlib import Path -_COMMENT = re.compile(r"/\*.*?\*/", flags=re.DOTALL) +_TOKEN = re.compile(r"/\*.*?\*/" r"|\"(?:\\.|[^\"\\])*\"" r"|'(?:\\.|[^'\\])*'", flags=re.DOTALL) _TRAILING_WS = re.compile(r"[ \t]+(?=\n)") _BLANK_RUN = re.compile(r"\n{3,}") -_STRING = re.compile(r'"[^"]*"') def minify_css(source: str) -> str: """Return the stylesheet with comments and blank runs removed.""" - # Hold string literals aside so a `/*` inside one is not mistaken for a - # comment (a background-image url could legally contain it). - held: list[str] = [] - - def _hold(match: re.Match[str]) -> str: - held.append(match.group(0)) - return f"__BRCSS_STRING_{len(held) - 1}__" - - protected = _STRING.sub(_hold, source) - cleaned = _COMMENT.sub("", protected) - for index, literal in enumerate(held): - cleaned = cleaned.replace(f"__BRCSS_STRING_{index}__", literal) + # Match comments and strings in one pass: quotes inside comments cannot + # hide the terminator, and comment markers inside strings remain literal. + cleaned = _TOKEN.sub( + lambda match: "" if match.group(0).startswith("/*") else match.group(0), source + ) cleaned = _TRAILING_WS.sub("", cleaned) return _BLANK_RUN.sub("\n\n", cleaned).strip() + "\n" diff --git a/tests/test_minify_css.py b/tests/test_minify_css.py index 96704811..0bfb94b6 100644 --- a/tests/test_minify_css.py +++ b/tests/test_minify_css.py @@ -51,3 +51,16 @@ def test_selectors_and_declarations_are_never_rewritten(): result = minify_css(source) assert "@media (max-width: 700px)" in result assert ".a,.b { color: rgb(1 2 3 / 50%); margin: 0 auto; }" in result + + +def test_cli_preserves_single_quoted_and_escaped_literals(tmp_path): + source = 'x { background: url(\'a/*b*/c.png\'); content: "say \\"/*literal*/\\""; }\n' + path = tmp_path / "styles.css" + path.write_text(source + "/* removable comment */\n") + assert mc.main([str(path)]) == 0 + assert path.read_text() == source + + +def test_quotes_inside_comments_do_not_hide_following_rules(): + source = '/* a " quote */\nx { color: red; }\n/* another " quote */\n' + assert minify_css(source) == "x { color: red; }\n"