diff --git a/CHANGELOG-GRAVITYPDF.md b/CHANGELOG-GRAVITYPDF.md index 93ba5d15b..0b62148b4 100644 --- a/CHANGELOG-GRAVITYPDF.md +++ b/CHANGELOG-GRAVITYPDF.md @@ -136,6 +136,7 @@ Bugfixes * A declaration mPDF cannot read replaced the value before it. A `calc()`, `min()`, `max()`, `clamp()` or `var()` length became 0, so `margin: calc(…)` removed the default margins, and a colour mPDF does not know, or one written with `var()`, drew the text black. Such a declaration is now dropped, as a browser drops it, so the earlier declaration, the default or the inherited value applies. [#552] [#565] * `vw`, `vh`, `vmin`, `vmax`, `Q` and `ch` were read as pixels, `+5mm` and `1e+1mm` as 0, and `1,5mm` as 1mm. The units are now resolved against the page and the font size, the numbers are read, and `1,5mm` is dropped. [#552] [#565] * `line-height: 0` gave lines a normal height. Lines now have no height, as in a browser. A line height well below the font size, such as `0.5` or `1mm`, was stretched down to the baseline; it is now kept. A negative `line-height`, which shrank lines to odd heights, is now ignored. [#552] [#567] +* A `list-style-image` whose URL had capitals, such as `url(img/List-Bullet.png)`, drew no marker on a case-sensitive disk or server, because the URL was lowercased before the image was fetched. The URL now keeps its case. [#552] [#571] * The rule after an `@supports`, `@layer`, `@keyframes`, `@container` or other block at-rule was lost, and so were the rules inside `@supports` and `@layer`. The rule after `@charset`, `@namespace` or `@import` was lost too. `@supports` and `@layer` blocks are now unwrapped as `@media` blocks are, except `@supports not`, and other at-rules are removed whole. [#524] [#566] * A percentage `width`, `min-width` or `max-width` on an image in a table cell was resolved against the block around the table, not the cell. In a 60mm cell, `max-width: 20%` came out as 36mm. [#223] [#505] * An `@page :left` or `@page :right` rule was ignored unless the style sheet also had a plain `@page` rule. With one, the margins of a `:right` rule were applied to left pages too. [#555] [#556] @@ -742,5 +743,6 @@ These changes do not change output. [#563]: https://github.com/GravityPDF/mpdf/pull/563 [#565]: https://github.com/GravityPDF/mpdf/pull/565 [#567]: https://github.com/GravityPDF/mpdf/pull/567 +[#571]: https://github.com/GravityPDF/mpdf/pull/571 [#566]: https://github.com/GravityPDF/mpdf/pull/566 [#615]: https://github.com/GravityPDF/mpdf/pull/615 diff --git a/src/Css/NormalizeProperties.php b/src/Css/NormalizeProperties.php index 8baf9673f..61d1897a0 100644 --- a/src/Css/NormalizeProperties.php +++ b/src/Css/NormalizeProperties.php @@ -88,7 +88,7 @@ public function normalize($prop) $this->properties = []; foreach ($prop as $k => $v) { - if ($k !== 'BACKGROUND-IMAGE' && $k !== 'BACKGROUND' && $k !== 'ODD-HEADER-NAME' && $k !== 'EVEN-HEADER-NAME' && $k !== 'ODD-FOOTER-NAME' && $k !== 'EVEN-FOOTER-NAME' && $k !== 'HEADER' && $k !== 'FOOTER') { + if ($k !== 'BACKGROUND-IMAGE' && $k !== 'BACKGROUND' && $k !== 'ODD-HEADER-NAME' && $k !== 'EVEN-HEADER-NAME' && $k !== 'ODD-FOOTER-NAME' && $k !== 'EVEN-FOOTER-NAME' && $k !== 'HEADER' && $k !== 'FOOTER' && $k !== 'LIST-STYLE' && $k !== 'LIST-STYLE-IMAGE') { $v = strtolower($v); } @@ -1126,7 +1126,7 @@ protected function processListStyleProperty($v) } if (preg_match('/url\([\'\"]{0,1}(.*?)[\'\"]{0,1}\)/i', $v, $m)) { - $this->properties['LIST-STYLE-IMAGE'] = strtolower(trim($m[1])); + $this->properties['LIST-STYLE-IMAGE'] = trim($m[1]); } } } diff --git a/src/Mpdf.php b/src/Mpdf.php index f9f689862..420a75d06 100644 --- a/src/Mpdf.php +++ b/src/Mpdf.php @@ -16507,7 +16507,7 @@ function _setListMarker($listitemtype, $listitemimage, $listitemposition) $spacer = ' '; // IMAGE if ($listitemimage && $listitemimage != 'none') { - $listitemimage = trim(preg_replace('/url\(["\']*(.*?)["\']*\)/', '\\1', $listitemimage)); + $listitemimage = trim(preg_replace('/url\(["\']*(.*?)["\']*\)/i', '\\1', $listitemimage)); // ? Restrict maximum height/width of list marker?? $maxWidth = 100; @@ -19376,7 +19376,7 @@ function setCSS($arrayaux, $type = '', $tag = '') $this->blk[$this->blklvl]['list_style_type'] = strtolower($v); break; case 'LIST-STYLE-IMAGE': - $this->blk[$this->blklvl]['list_style_image'] = strtolower($v); + $this->blk[$this->blklvl]['list_style_image'] = strtolower($v) === 'none' ? 'none' : $v; break; case 'LIST-STYLE-POSITION': $this->blk[$this->blklvl]['list_style_position'] = strtolower($v); diff --git a/tests/Mpdf/ListMarkerRecordingMpdf.php b/tests/Mpdf/ListMarkerRecordingMpdf.php new file mode 100644 index 000000000..72f8282c8 --- /dev/null +++ b/tests/Mpdf/ListMarkerRecordingMpdf.php @@ -0,0 +1,27 @@ +markerImages[] = $listitemimage; + + return parent::_setListMarker($listitemtype, $listitemimage, $listitemposition); + } + +} diff --git a/tests/Mpdf/ListStyleImageCaseTest.php b/tests/Mpdf/ListStyleImageCaseTest.php new file mode 100644 index 000000000..06f1bebaf --- /dev/null +++ b/tests/Mpdf/ListStyleImageCaseTest.php @@ -0,0 +1,67 @@ +WriteHTML(''); + + $this->assertSame([$image], $mpdf->markerImages); + } + + /** + * @return array[] List rules and the image their marker should be given + */ + public function providerImages() + { + return [ + 'longhand' => ['ul { list-style-image: url(/Some/Path/Bullet.PNG) }', "url('/Some/Path/Bullet.PNG')"], + 'longhand, quoted' => ['ul { list-style-image: url("/Some/Path/Bullet.PNG") }', "url('/Some/Path/Bullet.PNG')"], + 'shorthand' => ['ul { list-style: square url(/Some/Path/Bullet.PNG) inside }', '/Some/Path/Bullet.PNG'], + 'longhand none in capitals' => ['ul { list-style-image: NONE }', 'none'], + 'shorthand none in capitals' => ['ul { list-style: NONE }', 'none'], + ]; + } + + /** + * The image is drawn when its file name has capitals + * + * @dataProvider providerDrawnImages + * + * @param string $value The list's list-style-image + */ + public function testImageWithCapitalsIsDrawn($value) + { + $mpdf = new ListMarkerRecordingMpdf(); + $mpdf->SetBasePath(__DIR__ . '/../data'); + $mpdf->WriteHTML(''); + + $this->assertCount(1, $mpdf->images); + } + + /** + * @return array[] Ways of naming an image whose file name has capitals + */ + public function providerDrawnImages() + { + return [ + 'url()' => ['url(img/List-Bullet.png)'], + 'URL() in capitals' => ['URL(img/List-Bullet.png)'], + ]; + } + +} diff --git a/tests/Snapshots/ListStyleImageCaseSnapshotTest.php b/tests/Snapshots/ListStyleImageCaseSnapshotTest.php new file mode 100644 index 000000000..d1ea0d7e5 --- /dev/null +++ b/tests/Snapshots/ListStyleImageCaseSnapshotTest.php @@ -0,0 +1,71 @@ + + + +

List marker images with capitals in the file name

+ +

list-style-image: url(img/List-Bullet.png). Each item's marker is a small blue square with a red centre, not a disc.

+ + +

list-style: square url(img/List-Bullet.png) inside. The same marker, inside the text, not a black square.

+ + +

list-style-image: URL(img/List-Bullet.png), with URL in capitals. The same marker as the first list.

+ + mpdf = $this->createMpdf(); + $this->mpdf->SetBasePath(__DIR__ . '/../data'); + + $this->mpdf->WriteHTML($html); + } + +} diff --git a/tests/data/img/List-Bullet.png b/tests/data/img/List-Bullet.png new file mode 100644 index 000000000..0c3ec7bda Binary files /dev/null and b/tests/data/img/List-Bullet.png differ diff --git a/tests/data/snapshots/list-style-image-case.pdf b/tests/data/snapshots/list-style-image-case.pdf new file mode 100644 index 000000000..0238aa3b9 Binary files /dev/null and b/tests/data/snapshots/list-style-image-case.pdf differ