GithubHelp home page GithubHelp logo

Comments (1)

voku avatar voku commented on May 27, 2024 1

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;
    }

from htmlmin.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.