on master help sign in
Fix compression of calc() in CSS

According to Mozilla Developer Network, “The + and - operators must always be surrounded by whitespace.”.

commitc58641a1700a928dca9e94e7426904f315649c0a authorKrzysztof Jurewicz <krzysztof.jurewicz@gmail.com> dateFri 17 Nov 2017, 15:56 (9 years ago) parent7ee4e61
2 files changed+20
lib/Hakyll/Web/CompressCss.hs+18 tests/Hakyll/Web/CompressCss/Tests.hs+2
lib/Hakyll/Web/CompressCss.hs+18
@@ -1,6 +1,7 @@
11--------------------------------------------------------------------------------
22-- | Module used for CSS compression. The compression is currently in a simple
33-- state, but would typically reduce the number of bytes by about 25%.
4+{-# LANGUAGE PatternGuards #-}
45module Hakyll.Web.CompressCss
56 ( compressCssCompiler
67 , compressCss
@@ -34,6 +35,8 @@ compressSeparators :: String -> String
3435compressSeparators [] = []
3536compressSeparators str
3637 | isConstant = head str : retainConstants compressSeparators (head str) (drop 1 str)
38+ | isPrefixOf "calc( " str = "calc(" ++ compressCalcSeparators 1 (drop 6 str)
39+ | isPrefixOf "calc(" str = "calc(" ++ compressCalcSeparators 1 (drop 5 str)
3740 | stripFirst = compressSeparators (drop 1 str)
3841 | stripSecond = compressSeparators (head str : (drop 2 str))
3942 | otherwise = head str : compressSeparators (drop 1 str)
@@ -43,6 +46,21 @@ compressSeparators str
4346 stripSecond = or $ map (isOfPrefix str) $ map (\c -> c ++ " ") separators
4447 separators = [" ", "{", "}", ":", ";", ",", ">", "+", "!"]
4548
49+-- | Compresses separators when starting inside calc().
50+compressCalcSeparators :: Int -> String -> String
51+compressCalcSeparators 0 str = compressSeparators str
52+compressCalcSeparators depth str
53+ | stripFirst = compressCalcSeparators depth (tail str)
54+ | stripSecond = compressCalcSeparators depth (head str : (drop 2 str))
55+ | ('(' : xs) <- str = '(' : compressCalcSeparators (depth + 1) xs
56+ | isPrefixOf "calc( " str = compressCalcSeparators depth ("calc(" ++ (drop 6 str))
57+ | isPrefixOf "calc(" str = '(' : compressCalcSeparators (depth + 1) (drop 5 str)
58+ | (')' : xs) <- str = ')' : compressCalcSeparators (depth - 1) xs
59+ | otherwise = head str : compressCalcSeparators depth (tail str)
60+ where
61+ stripFirst = or $ map (isOfPrefix str) $ map (\c -> " " ++ c) ["*", "/", ")"]
62+ stripSecond = or $ map (isOfPrefix str) $ map (\c -> c ++ " ") ["*", "/", "("]
63+
4664--------------------------------------------------------------------------------
4765-- | Compresses all whitespace.
4866compressWhitespace :: String -> String
tests/Hakyll/Web/CompressCss/Tests.hs+2
@@ -42,6 +42,8 @@ tests = testGroup "Hakyll.Web.CompressCss.Tests" $ concat
4242 , "a>b" @=? compressCss "a > b"
4343 , "a+b" @=? compressCss "a + b"
4444 , "a!b" @=? compressCss "a ! b"
45+ -- compress calc()
46+ , "calc(1px + 100%/(5 + 3) - (3px + 2px)*5)" @=? compressCss "calc( 1px + 100% / ( 5 + 3) - calc( 3px + 2px ) * 5 )"
4547 -- compress whitespace even after this curly brace
4648 , "}" @=? compressCss "; } "
4749 -- but do not compress separators inside of constants