diff --git a/composer.json b/composer.json index 7f17ff5c..e9fb6bb5 100644 --- a/composer.json +++ b/composer.json @@ -27,6 +27,10 @@ "reference" : "fd4ff50eb577457c1b7b887401663e91e77625ae" } } + }, + { + "type" : "vcs", + "url" : "https://github.com/shish/php-css.git" } ], @@ -51,7 +55,8 @@ "bower-asset/js-cookie" : "^2.1", "psr/simple-cache" : "^1.0", "sabre/cache" : "^2.0.1", - "naroga/redis-cache": "dev-master" + "naroga/redis-cache": "dev-master", + "tbela99/css": "dev-relative-url" }, "require-dev" : { diff --git a/composer.lock b/composer.lock index 37110b8f..c80df12b 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,200 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b945fc1a992b5b1a449f5fe7612af514", + "content-hash": "54f37280f2cb7439ab7715d0827ad49d", "packages": [ + { + "name": "axy/backtrace", + "version": "1.0.7", + "source": { + "type": "git", + "url": "https://github.com/axypro/backtrace.git", + "reference": "c6c7d0f3497a07ae934f9e8511cbc2286db311c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/axypro/backtrace/zipball/c6c7d0f3497a07ae934f9e8511cbc2286db311c5", + "reference": "c6c7d0f3497a07ae934f9e8511cbc2286db311c5", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "axy\\backtrace\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Oleg Grigoriev", + "email": "go.vasac@gmail.com" + } + ], + "description": "Tracing in PHP", + "homepage": "https://github.com/axypro/backtrace", + "keywords": [ + "Backtrace", + "debug", + "exception", + "trace" + ], + "support": { + "issues": "https://github.com/axypro/backtrace/issues", + "source": "https://github.com/axypro/backtrace/tree/1.0.7" + }, + "time": "2019-02-02T15:52:44+00:00" + }, + { + "name": "axy/codecs-base64vlq", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/axypro/codecs-base64vlq.git", + "reference": "53a1957f2cb773c6533ac615b3f1ac59e40e13cc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/axypro/codecs-base64vlq/zipball/53a1957f2cb773c6533ac615b3f1ac59e40e13cc", + "reference": "53a1957f2cb773c6533ac615b3f1ac59e40e13cc", + "shasum": "" + }, + "require": { + "axy/errors": "~1.0.1", + "php": ">=5.4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "axy\\codecs\\base64vlq\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Oleg Grigoriev", + "email": "go.vasac@gmail.com" + } + ], + "description": "Codec for VLQ (variable-length quantity) Base64 algorithm", + "homepage": "https://github.com/axypro/codecs-base64vlq", + "keywords": [ + "Source map", + "VLQ", + "Variable length quantity", + "base64", + "codec" + ], + "support": { + "issues": "https://github.com/axypro/codecs-base64vlq/issues", + "source": "https://github.com/axypro/codecs-base64vlq/tree/master" + }, + "time": "2015-11-23T07:08:52+00:00" + }, + { + "name": "axy/errors", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/axypro/errors.git", + "reference": "2c64374ae2b9ca51304c09b6b6acc275557fc34f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/axypro/errors/zipball/2c64374ae2b9ca51304c09b6b6acc275557fc34f", + "reference": "2c64374ae2b9ca51304c09b6b6acc275557fc34f", + "shasum": "" + }, + "require": { + "axy/backtrace": "~1.0.2", + "php": ">=5.4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "axy\\errors\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Oleg Grigoriev", + "email": "go.vasac@gmail.com" + } + ], + "description": "Exceptions in PHP", + "homepage": "https://github.com/axypro/errors", + "keywords": [ + "error", + "exception" + ], + "support": { + "issues": "https://github.com/axypro/errors/issues", + "source": "https://github.com/axypro/errors/tree/1.0.5" + }, + "time": "2019-02-02T18:26:18+00:00" + }, + { + "name": "axy/sourcemap", + "version": "0.1.5", + "source": { + "type": "git", + "url": "https://github.com/axypro/sourcemap.git", + "reference": "95a52df5a08c3a011031dae2e79390134e28467c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/axypro/sourcemap/zipball/95a52df5a08c3a011031dae2e79390134e28467c", + "reference": "95a52df5a08c3a011031dae2e79390134e28467c", + "shasum": "" + }, + "require": { + "axy/codecs-base64vlq": "~1.0.0", + "axy/errors": "~1.0.1", + "ext-json": "*", + "php": ">=5.4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "axy\\sourcemap\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Oleg Grigoriev", + "email": "go.vasac@gmail.com" + } + ], + "description": "Work with JavaScript/CSS Source Map", + "homepage": "https://github.com/axypro/sourcemap", + "keywords": [ + "Source map", + "css", + "javascript", + "sourcemap" + ], + "support": { + "issues": "https://github.com/axypro/sourcemap/issues", + "source": "https://github.com/axypro/sourcemap/tree/0.1.5" + }, + "time": "2020-08-20T09:49:44+00:00" + }, { "name": "bower-asset/jquery", "version": "1.12.4", @@ -338,6 +530,72 @@ }, "time": "2021-01-25T13:15:08+00:00" }, + { + "name": "opis/closure", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/opis/closure.git", + "reference": "3d81e4309d2a927abbe66df935f4bb60082805ad" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/opis/closure/zipball/3d81e4309d2a927abbe66df935f4bb60082805ad", + "reference": "3d81e4309d2a927abbe66df935f4bb60082805ad", + "shasum": "" + }, + "require": { + "php": "^5.4 || ^7.0 || ^8.0" + }, + "require-dev": { + "jeremeamia/superclosure": "^2.0", + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0" + }, + "default-branch": true, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.6.x-dev" + } + }, + "autoload": { + "files": [ + "functions.php" + ], + "psr-4": { + "Opis\\Closure\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marius Sarca", + "email": "marius.sarca@gmail.com" + }, + { + "name": "Sorin Sarca", + "email": "sarca_sorin@hotmail.com" + } + ], + "description": "A library that can be used to serialize closures (anonymous functions) and arbitrary objects.", + "homepage": "https://opis.io/closure", + "keywords": [ + "anonymous functions", + "closure", + "function", + "serializable", + "serialization", + "serialize" + ], + "support": { + "issues": "https://github.com/opis/closure/issues", + "source": "https://github.com/opis/closure/tree/3.6.3" + }, + "time": "2022-01-27T09:35:39+00:00" + }, { "name": "predis/predis", "version": "v1.x-dev", @@ -779,6 +1037,87 @@ }, "time": "2023-08-17T16:39:06+00:00" }, + { + "name": "tbela99/css", + "version": "dev-relative-url", + "source": { + "type": "git", + "url": "https://github.com/shish/php-css.git", + "reference": "60ea6f7190782752b18ee646d06097fb666c1213" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/shish/php-css/zipball/60ea6f7190782752b18ee646d06097fb666c1213", + "reference": "60ea6f7190782752b18ee646d06097fb666c1213", + "shasum": "" + }, + "require": { + "axy/sourcemap": "^0.1.5", + "ext-json": "*", + "ext-mbstring": "*", + "opis/closure": "^3.6", + "php": ">=8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.5" + }, + "suggest": { + "ext-curl": "*", + "ext-pcntl": "*", + "ext-sockets": "*" + }, + "bin": [ + "cli/css-parser" + ], + "type": "library", + "autoload": { + "psr-4": { + "TBela\\CSS\\": "src" + } + }, + "archive": { + "exclude": [ + "*.sh", + "*.phar", + "test/", + "tool/", + "docs/", + "bin/" + ] + }, + "scripts": { + "test": [ + "./bin/runtest.sh" + ] + }, + "license": [ + "MIT", + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "Thierry Bela", + "homepage": "https://tbela.net", + "role": "Developer" + } + ], + "description": "A CSS parser and minifier written in PHP", + "homepage": "https://github.com/tbela99/css", + "keywords": [ + "Ast", + "CSS", + "PHP", + "beautifier", + "css-parser", + "minifier", + "parser", + "stylesheet" + ], + "support": { + "source": "https://github.com/shish/php-css/tree/relative-url" + }, + "time": "2023-08-18T14:13:00+00:00" + }, { "name": "webonyx/graphql-php", "version": "v15.4.0", @@ -5552,6 +5891,7 @@ "stability-flags": { "shish/gqla": 20, "naroga/redis-cache": 20, + "tbela99/css": 20, "scrutinizer/ocular": 20, "phpstan/phpstan": 20 }, diff --git a/core/basepage.php b/core/basepage.php index 52097d40..27a660d3 100644 --- a/core/basepage.php +++ b/core/basepage.php @@ -5,6 +5,8 @@ declare(strict_types=1); namespace Shimmie2; use MicroHTML\HTMLElement; +use TBela\CSS\Parser; +use TBela\CSS\Renderer; require_once "core/event.php"; @@ -391,15 +393,22 @@ class BasePage $css_md5 = md5(serialize($css_files)); $css_cache_file = data_path("cache/style/{$theme_name}.{$css_latest}.{$css_md5}.css"); if (!file_exists($css_cache_file)) { - $css_data = ""; - foreach ($css_files as $file) { - $file_data = file_get_contents($file); - $pattern = '/url[\s]*\([\s]*["\']?([^"\'\)]+)["\']?[\s]*\)/'; - $replace = 'url("../../../' . dirname($file) . '/$1")'; - $file_data = preg_replace($pattern, $replace, $file_data); - $css_data .= $file_data . "\n"; + $parser = new Parser(); + foreach($css_files as $file) { + $parser->append($file); } - file_put_contents($css_cache_file, $css_data); + $element = $parser->parse(); + + // minified output + $renderer = new Renderer([ + 'compress' => true, + 'convert_color' => 'hex', + 'css_level' => 3, + 'sourcemap' => true, + 'allow_duplicate_declarations' => false, + 'legacy_rendering' => true, // turn nested CSS into regular + ]); + $renderer->save($element, $css_cache_file); } return $css_cache_file;