Fix #2352 automatically convert relative paths in CSS url() function, only in template v2

This commit is contained in:
Kijin Sung 2024-05-25 01:34:47 +09:00
parent 1d42b6bde4
commit 5f47ddeb53
2 changed files with 51 additions and 1 deletions

View file

@ -236,7 +236,7 @@ class TemplateParser_v2
// Convert all src and srcset attributes.
$regexp = '#(<(?:img|audio|video|script|input|source|link)\s[^>]*)(src|srcset|poster)="([^"]+)"#';
return preg_replace_callback($regexp, function($match) use ($basepath) {
$content = preg_replace_callback($regexp, function($match) use ($basepath) {
if ($match[2] !== 'srcset')
{
$src = trim($match[3]);
@ -253,6 +253,21 @@ class TemplateParser_v2
return $match[1] . sprintf('srcset="%s"', implode(', ', $result));
}
}, $content);
// Convert relative paths in CSS url() function.
$regexp = ['#\b(style=")([^"]+)(")#', '#(<style\b)(.*?)(</style>)#s'];
$content = preg_replace_callback($regexp, function($match) use ($basepath) {
$regexp = '#\b(url\([\'"]?)([^\'"\(\)]+)([\'"]?\))#';
$match[2] = preg_replace_callback($regexp, function($match) use ($basepath) {
if ($this->template->isRelativePath($match[2] = trim($match[2])))
{
$match[2] = $this->template->convertPath($match[2], $basepath);
}
return $match[1] . $match[2] . $match[3];
}, $match[2]);
return $match[1] . $match[2] . $match[3];
}, $content);
return $content;
}
/**

View file

@ -600,6 +600,41 @@ class TemplateParserV2Test extends \Codeception\Test\Unit
$source = '<img srcset="bar/foo@4x.png 4x, ../foo@2x.png 2x ,./foo.jpg" />';
$target = '<img srcset="' . $this->baseurl . 'tests/_data/template/bar/foo@4x.png 4x, ' . $this->baseurl . 'tests/_data/foo@2x.png 2x, ' . $this->baseurl . 'tests/_data/template/foo.jpg" />';
$this->assertEquals($target, $this->_parse($source));
// url() conversion in style sttribute
$source = '<div style="background-image: url(img/foo.jpg)"></div>';
$target = '<div style="background-image: url(' . $this->baseurl . 'tests/_data/template/img/foo.jpg)"></div>';
$this->assertEquals($target, $this->_parse($source));
$source = '<div style="border-image: url(\'img/foo.jpg\')"></div>';
$target = '<div style="border-image: url(\'' . $this->baseurl . 'tests/_data/template/img/foo.jpg\')"></div>';
$this->assertEquals($target, $this->_parse($source));
$source = '<div style="mask-image: image(url(foo/bar.svg), blue, linear-gradient(rgb(0 0 0 / 100%), transparent))"></div>';
$target = '<div style="mask-image: image(url(' . $this->baseurl . 'tests/_data/template/foo/bar.svg), blue, linear-gradient(rgb(0 0 0 / 100%), transparent))"></div>';
$this->assertEquals($target, $this->_parse($source));
$source = '<div style="content: url(\'https://foo.com/bar.png\')"></div>';
$target = '<div style="content: url(\'https://foo.com/bar.png\')"></div>';
$this->assertEquals($target, $this->_parse($source));
$source = '<div style="content: url(data:image/png,base64)" other-attribute="cursor: url(img/foo.jpg)"></div>';
$target = '<div style="content: url(data:image/png,base64)" other-attribute="cursor: url(img/foo.jpg)"></div>';
$this->assertEquals($target, $this->_parse($source));
// url() conversion in <style> tag
$source = '<style> .foo { background-image: url("img/foo.jpg"); } </style>';
$target = '<style> .foo { background-image: url("' . $this->baseurl . 'tests/_data/template/img/foo.jpg"); } </style>';
$this->assertEquals($target, $this->_parse($source));
// No url() conversion in other tags or attributes
$source = '<other-tag> .foo { list-style-image: url(img/foo.jpg); } </other-tag>';
$target = '<other-tag> .foo { list-style-image: url(img/foo.jpg); } </other-tag>';
$this->assertEquals($target, $this->_parse($source));
$source = '<p class="url(foo.svg)" style="url(../foo.jpg)"> url(img/foo.jpg); } </p>';
$target = '<p class="url(foo.svg)" style="url(' . $this->baseurl . 'tests/_data/foo.jpg)"> url(img/foo.jpg); } </p>';
$this->assertEquals($target, $this->_parse($source));
}
public function testBlockConditions()