Fix #2052 move all charset and import statements to the beginning of concatenated CSS scripts

This commit is contained in:
Kijin Sung 2022-12-28 00:06:50 +09:00
parent a55ba4fab9
commit d34d08438f
5 changed files with 38 additions and 13 deletions

View file

@ -328,6 +328,8 @@ class Formatter
*/
public static function concatCSS($source_filename, $target_filename, $add_comment = true, &$imported_list = [])
{
$charsets = [];
$imported_urls = [];
$result = '';
if (!is_array($source_filename))
@ -353,10 +355,11 @@ class Formatter
// Convert all paths in LESS and SCSS imports, too.
$dirname = dirname($filename);
$import_type = ends_with('.scss', $filename) ? 'scss' : 'normal';
$content = preg_replace_callback('/@import\s+([^\r\n]+);(?=[\r\n$])/', function($matches) use($dirname, $filename, $target_filename, $import_type, &$imported_list) {
$content = preg_replace_callback('/@import\s+([^\r\n]+);(?=[\r\n$])/', function($matches) use($dirname, $filename, $target_filename, $import_type, &$imported_list, &$imported_urls) {
if (preg_match('!^url\([\'"]?((?:https?:)?//[^()\'"]+)!i', $matches[1], $urlmatches))
{
return '@import url("' . escape_dqstr($urlmatches[1]) . '");';
$imported_urls[] = $urlmatches[1];
return '';
}
$import_content = '';
$import_files = array_map(function($str) use($dirname, $filename, $import_type) {
@ -403,7 +406,7 @@ class Formatter
{
if (preg_match('!^(https?:)?//!i', $import_filename))
{
$import_content .= '@import url("' . escape_dqstr($import_filename) . '");';
$imported_urls[] = $import_filename;
}
elseif (file_exists($import_filename))
{
@ -434,6 +437,12 @@ class Formatter
}, $content);
unset($path_converter);
// Extract all @charset declarations.
$content = preg_replace_callback('/@charset\s+(["\'a-z0-9_-]+);[\r\n]*/i', function($matches) use (&$charsets) {
$charsets[] = trim($matches[1], '"\'');
return '';
}, $content);
// Wrap the content in a media query if there is one.
if ($media !== null)
{
@ -452,6 +461,20 @@ class Formatter
}
}
// Place all @charset and @import statements at the beginning.
if (count($imported_urls))
{
$imports = implode("\n", array_map(function($url) {
return '@import url("' . escape_dqstr($url) . '");';
}, $imported_urls));
$result = $imports . "\n" . $result;
}
if (count($charsets))
{
$charset = '@charset "' . escape_dqstr(array_first($charsets)) . '";';
$result = $charset . "\n" . $result;
}
return $result;
}

View file

@ -1,4 +1,4 @@
@charset "UTF-8";
@charset "CP949";
@import url(concat.source3.css);
@import url(//fonts.googleapis.com/earlyaccess/nanumgothic.css);
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+KR&display=swap');

View file

@ -1,19 +1,20 @@
@charset "UTF-8";
@import url("//fonts.googleapis.com/earlyaccess/nanumgothic.css");
@import url("https://fonts.googleapis.com/css2?family=Noto+Sans+KR&display=swap");
/* Original file: tests/_data/formatter/concat.source1.css */
@charset "UTF-8";
.rhymix {
background: url("../_data/formatter/foo/bar.jpg");
}
/* Original file: tests/_data/formatter/concat.source2.css */
@charset "UTF-8";
.imported {
background-image: url("../_data/_data/formatter/test.jpg");
font-family: sans-serif;
}
@import url("//fonts.googleapis.com/earlyaccess/nanumgothic.css");
@import url("https://fonts.googleapis.com/css2?family=Noto+Sans+KR&display=swap");
.wordpress {
border-radius: 4px;
}

View file

@ -1,8 +1,10 @@
@charset "UTF-8";
@import url("//fonts.googleapis.com/earlyaccess/nanumgothic.css");
@import url("https://fonts.googleapis.com/css2?family=Noto+Sans+KR&display=swap");
/* Original file: tests/_data/formatter/concat.source1.css */
@media screen and (max-width: 640px) {
@charset "UTF-8";
.rhymix {
background: url("../_data/formatter/foo/bar.jpg");
}
@ -11,13 +13,12 @@
/* Original file: tests/_data/formatter/concat.source2.css */
@charset "UTF-8";
.imported {
background-image: url("../_data/_data/formatter/test.jpg");
font-family: sans-serif;
}
@import url("//fonts.googleapis.com/earlyaccess/nanumgothic.css");
@import url("https://fonts.googleapis.com/css2?family=Noto+Sans+KR&display=swap");
.wordpress {
border-radius: 4px;
}

View file

@ -1,7 +1,7 @@
@charset "UTF-8";
/* Original file: tests/_data/formatter/scss.source1.scss */
@import url("//fonts.googleapis.com/css?family=Raleway:700,400");
@import url("https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,400;0,700;1,400;1,700&display=swap");
/* Original file: tests/_data/formatter/scss.source1.scss */
/* Original file: tests/_data/formatter/scss.source2.scss */
.inc1 {
margin: 5px;