InlineCssMinifier::process()   A
last analyzed

Complexity

Conditions 4
Paths 5

Size

Total Lines 19
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 9
c 1
b 0
f 0
nc 5
nop 1
dl 0
loc 19
rs 9.9666
1
<?php
2
3
namespace gulch\Minify\Processor;
4
5
use gulch\Minify\Contract\ProcessorInterface;
6
7
class InlineCssMinifier implements ProcessorInterface
8
{
9
    public function process(string $buffer): string
10
    {
11
        if (\strlen($buffer) === 0) {
12
            return '';
13
        }
14
15
        $css_minified = [];
16
        \preg_match_all('{<style.+</style>}msU', $buffer, $style_blocks);
17
18
        // Minify the javascript in <script> tags.
19
        foreach ($style_blocks[0] as $block) {
20
            $css_minified[] = $this->minifyCss($block);
21
        }
22
23
        if (\sizeof($css_minified)) {
24
            $buffer = \str_replace($style_blocks[0], $css_minified, $buffer);
25
        }
26
27
        return $buffer;
28
    }
29
30
    private function minifyCss(string $buffer): string
31
    {
32
        $tags = ['close' => \strrchr($buffer, '<')];
33
        $open_length = \strpos($buffer, '>') + 1;
34
        $tags['open'] = \substr($buffer, 0, $open_length);
35
        $buffer = \substr($buffer, $open_length, -\strlen($tags['close']));
36
37
        // Strip spaces from the tags
38
        $tags = \preg_replace('/\s{2,}/', ' ', $tags);
39
40
        // Standartize new lines
41
        $buffer = \str_replace(["\r\n", "\r"], "\n", $buffer);
42
43
        $patterns = [
44
            // Remove comment(s)
45
            '#("(?:[^"\\\]++|\\\.)*+"|\'(?:[^\'\\\\]++|\\\.)*+\')|\/\*(?!\!)(?>.*?\*\/)|^\s*|\s*$#s' => '$1',
46
            // Remove unused white-space(s)
47
            '#("(?:[^"\\\]++|\\\.)*+"|\'(?:[^\'\\\\]++|\\\.)*+\'|\/\*(?>.*?\*\/))|\s*+;\s*+(})\s*+|\s*+([*$~^|]?+=|[{};,>~+]|\s*+-(?![0-9\.])|!important\b)\s*+|([[(:])\s++|\s++([])])|\s++(:)\s*+(?!(?>[^{}"\']++|"(?:[^"\\\]++|\\\.)*+"|\'(?:[^\'\\\\]++|\\\.)*+\')*+{)|^\s++|\s++\z|(\s)\s+#si' => '$1$2$3$4$5$6$7',
48
            // Replace `0(cm|em|ex|in|mm|pc|pt|px|vh|vw|%)` with `0`
49
            '#(?<=[\s:])(0)(cm|em|ex|in|mm|pc|pt|px|vh|vw|%)#si' => '$1',
50
            // Replace `:0 0 0 0` with `:0`
51
            '#:(0\s+0|0\s+0\s+0\s+0)(?=[;\}]|\!important)#i' => ':0',
52
            // Replace `background-position:0` with `background-position:0 0`
53
            '#(background-position):0(?=[;\}])#si' => '$1:0 0',
54
            // Replace `0.6` with `.6`, but only when preceded by `:`, `,`, `-` or a white-space
55
            '#(?<=[\s:,\-])0+\.(\d+)#s' => '.$1',
56
            // Minify string value
57
            '#(\/\*(?>.*?\*\/))|(?<!content\:)([\'"])([a-z_][a-z0-9\-_]*?)\2(?=[\s\{\}\];,])#si' => '$1$3',
58
            '#(\/\*(?>.*?\*\/))|(\burl\()([\'"])([^\s]+?)\3(\))#si' => '$1$2$4$5',
59
            // Minify HEX color code
60
            '#(?<=[\s:,\-]\#)([a-f0-6]+)\1([a-f0-6]+)\2([a-f0-6]+)\3#i' => '$1$2$3',
61
            // Replace `(border|outline):none` with `(border|outline):0`
62
            '#(?<=[\{;])(border|outline):none(?=[;\}\!])#' => '$1:0',
63
            // Remove empty selector(s)
64
            '#(\/\*(?>.*?\*\/))|(^|[\{\}])(?:[^\s\{\}]+)\{\}#s' => '$1$2',
65
        ];
66
67
        $buffer = \preg_replace(
68
            \array_keys($patterns),
69
            \array_values($patterns),
70
            $buffer
71
        );
72
73
        return $tags['open'] . $buffer . $tags['close'];
74
    }
75
}
76