voku / HtmlMin

:clamp: HtmlMin: HTML Compressor and Minifier via PHP

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

what option to make css on single line

HaxorGaruda opened this issue · comments

hello .. what option to make css to be one line ? other is work fine except css still on default style, not compressed... thanks..

This is an HTML only solution, but it's quite simple to use this in combination with some JS / CSS minifier.

e.g. via Observer: https://github.com/WyriHaximus/HtmlCompress/blob/master/src/HtmlMinObserver.php

... or via regex:

    /**
     * HTML Minifier
     *
     * @param string $input
     *
     * @return string
     */
    function minify_html(string $input): string
    {
        if (!$input || \trim($input) === '') {
            return $input;
        }

        // Minify HTML
        $htmlMin = new HtmlMin();
        $input = $htmlMin->minify($input);

        // Minify inline CSS declaration(s)
        if (\strpos($input, ' style=') !== false) {
            $input = (string) \preg_replace_callback(
                '#<([^<]+?)\s+style=([\'"])(.*?)\2(?=[\/\s>])#s',
                static function ($matches) {
                    return '<' . $matches[1] . ' style=' . $matches[2] . minify_css($matches[3]) . $matches[2];
                },
                $input
            );
        }

        if (\strpos($input, '</style>') !== false) {
            $input = (string) \preg_replace_callback(
                '#<style(.*?)>(.*?)</style>#is',
                static function ($matches) {
                    return '<style' . $matches[1] . '>' . minify_css($matches[2]) . '</style>';
                },
                $input
            );
        }

        if (\strpos($input, '</script>') !== false) {
            $input = (string) \preg_replace_callback(
                '#<script(.*?)>(.*?)</script>#is',
                static function ($matches) {
                    return '<script' . $matches[1] . '>' . minify_js($matches[2]) . '</script>';
                },
                $input
            );
        }

        return $input;
    }

    /**
     * CSS Minifier => http://ideone.com/Q5USEF + improvement(s)
     *
     * Based on `https://github.com/mecha-cms/mecha-cms/blob/master/system/kernel/converter.php`
     * -> https://gist.github.com/Rodrigo54/93169db48194d470188f
     *
     * @param string $input
     * @param bool   $useCache
     *
     * @return string
     */
    function minify_css(string $input, bool $useCache = true): string
    {
        if (!$input || \trim($input) === '') {
            return $input;
        }

        if ($useCache === true) {
            $cache = new Cache();
            $cacheKey = 'minify_css::' . \md5($input);
            if (
                $cache->getCacheIsReady() === true
                &&
                $cache->existsItem($cacheKey) === true
            ) {
                return $cache->getItem($cacheKey);
            }
        }

        $output = \preg_replace(
            [
                // Remove comment(s)
                '#("(?:[^"\\\]++|\\\.)*+"|\'(?:[^\'\\\\]++|\\\.)*+\')|\/\*(?!\!)(?>.*?\*\/)|^\s*|\s*$#s',
                // Remove unused white-space(s)
                '#("(?:[^"\\\]++|\\\.)*+"|\'(?:[^\'\\\\]++|\\\.)*+\'|\/\*(?>.*?\*\/))|\s*+;\s*+(})\s*+|\s*+([*$~^|]?+=|[{};,>~+]|\s*+-(?![0-9\.])|!important\b)\s*+|([[(:])\s++|\s++([])])|\s++(:)\s*+(?!(?>[^{}"\']++|"(?:[^"\\\]++|\\\.)*+"|\'(?:[^\'\\\\]++|\\\.)*+\')*+{)|^\s++|\s++\z|(\s)\s+#si',
                // Replace `0(cm|em|ex|in|mm|pc|pt|px|vh|vw|%)` with `0`
                '#(?<=[\s:])(0)(cm|em|ex|in|mm|pc|pt|px|vh|vw|%)#si',
                // Replace `:0 0 0 0` with `:0`
                '#:(0\s+0|0\s+0\s+0\s+0)(?=[;\}]|\!important)#i',
                // Replace `background-position:0` with `background-position:0 0`
                '#(background-position):0(?=[;\}])#si',
                // Replace `0.6` with `.6`, but only when preceded by `:`, `,`, `-` or a white-space
                '#(?<=[\s:,\-])0+\.(\d+)#s',
                // Minify string value
                '#(\/\*(?>.*?\*\/))|(?<!content\:)([\'"])([a-z_][a-z0-9\-_]*?)\2(?=[\s\{\}\];,])#si',
                '#(\/\*(?>.*?\*\/))|(\burl\()([\'"])([^\s]+?)\3(\))#si',
                // Minify HEX color code
                '#(?<=[\s:,\-]\#)([a-f0-6]+)\1([a-f0-6]+)\2([a-f0-6]+)\3#i',
                // Replace `(border|outline):none` with `(border|outline):0`
                '#(?<=[\{;])(border|outline):none(?=[;\}\!])#',
                // Remove empty selector(s)
                '#(\/\*(?>.*?\*\/))|(^|[\{\}])(?:[^\s\{\}]+)\{\}#s',
            ],
            [
                '$1',
                '$1$2$3$4$5$6$7',
                '$1',
                ':0',
                '$1:0 0',
                '.$1',
                '$1$3',
                '$1$2$4$5',
                '$1$2$3',
                '$1:0',
                '$1$2',
            ],
            $input
        );

        if ($useCache === true) {
            if ($cache->getCacheIsReady() === true) {
                $cache->setItem($cacheKey, $output);
            }
        }

        return $output;
    }

    /**
     * JavaScript Minifier
     *
     * @param string $input
     * @param bool   $useCache
     *
     * @return string
     */
    function minify_js(string $input, bool $useCache = true): string
    {
        if (!$input || \trim($input) === '') {
            return $input;
        }

        if ($useCache === true) {
            $cache = new Cache();
            $cacheKey = 'minify_js::' . \md5($input);
            if (
                $cache->getCacheIsReady() === true
                &&
                $cache->existsItem($cacheKey) === true
            ) {
                return $cache->getItem($cacheKey);
            }
        }

        $output = \JShrink\Minifier::minify($input);

        if ($useCache === true) {
            if ($cache->getCacheIsReady() === true) {
                $cache->setItem($cacheKey, $output);
            }
        }

        return $output;
    }