From d49a3e5f83ba85d14729eecd756b4592d708f23c Mon Sep 17 00:00:00 2001 From: Jake Jackson Date: Wed, 30 Sep 2026 17:45:26 +1000 Subject: [PATCH 1/2] Remove an HTML comment without leaving a space in its place A comment between two words drew a space in the default parser mode, because the CSS reader replaced each comment with one. It now leaves nothing, as a browser does and as the body mode already did, in either cssMode. Comments and scripts are removed in document order in both parser modes, so a comment marker inside a script no longer starts a comment, and a script tag inside a comment no longer hides the text after it. Co-Authored-By: Claude Opus 5.5 --- CHANGELOG-GRAVITYPDF.md | 5 + src/Css/CommentParser.php | 20 +++- src/Mpdf.php | 13 +-- tests/Mpdf/Css/CommentParserTest.php | 48 ++++++++++ tests/Mpdf/HtmlCommentTest.php | 97 ++++++++++++++++++++ tests/Snapshots/HtmlCommentSnapshotTest.php | 81 ++++++++++++++++ tests/data/snapshots/html-comment.pdf | Bin 0 -> 68329 bytes 7 files changed, 250 insertions(+), 14 deletions(-) create mode 100644 tests/Mpdf/Css/CommentParserTest.php create mode 100644 tests/Mpdf/HtmlCommentTest.php create mode 100644 tests/Snapshots/HtmlCommentSnapshotTest.php create mode 100644 tests/data/snapshots/html-comment.pdf diff --git a/CHANGELOG-GRAVITYPDF.md b/CHANGELOG-GRAVITYPDF.md index d2c0a85c1..bfcca62db 100644 --- a/CHANGELOG-GRAVITYPDF.md +++ b/CHANGELOG-GRAVITYPDF.md @@ -173,6 +173,9 @@ Bugfixes * A byte order mark at the start of a stylesheet, as `WriteHTML(file_get_contents('style.css'), HTMLParserMode::HEADER_CSS)` passes one on, no longer spoils the first rule. * An `@import` is loaded only from the stylesheet's own rules, not from a comment, a string or a block. * A `style` attribute is split the same way, so `style="font-family: 'a;b', serif; color: red"` applies both, and a value may run over several lines. +* An HTML comment between two words drew a space: `Bookkeeper` read "Book keeper", and `

` held a space. A comment now leaves nothing in its place, as in a browser and as `HTMLParserMode::HTML_BODY` already had it, in either `cssMode`. A document that relied on the space can put one next to the comment. [#636] [#637] + * In the default parser mode, a ` markers and all HTML comments. + * Removes the markers, keeping what is between them, then every HTML comment, leaving nothing + * in its place, as a browser does. A ab', 'ab'], + 'a script tag in a comment' => ['ab', 'ab'], + 'no comment' => ['

a b

', '

a b

'], + ]; + } + +} diff --git a/tests/Mpdf/HtmlCommentTest.php b/tests/Mpdf/HtmlCommentTest.php new file mode 100644 index 000000000..8824ca924 --- /dev/null +++ b/tests/Mpdf/HtmlCommentTest.php @@ -0,0 +1,97 @@ +draw($html, $mode, $cssMode); + + $this->assertNotEmpty($drawn[0]); + $this->assertSame($this->draw($asRead, $mode, $cssMode), $drawn); + } + + /** + * Each document with a comment, and the same document as a browser reads it, in each parser mode and CSS mode + * + * @return array[] Each [html, as read, parser mode, CSS mode] + */ + public function comments() + { + $documents = [ + 'between two words' => ['

ab

', '

ab

'], + 'at the start of a text run' => ['

ab

', '

ab

'], + 'at the end of a text run' => ['

ab

', '

ab

'], + 'between inline elements' => ['

ab

', '

ab

'], + 'over several lines' => ["

ab

", '

ab

'], + 'with line breaks around it' => ["

a\n\nb

", "

a\nb

"], + 'inside pre, between two words' => ["
ab\nc
", "
ab\nc
"], + 'inside pre, keeping the line breaks around it' => ["
a\n\nb
", "
a\n\nb
"], + 'inside a table cell' => ['
ab
', '
ab
'], + 'mPDF content, whose markers go and whose content stays' => ['

ac

', '

a b c

'], + 'a comment inside mPDF content' => ['

ac mpdf-->d

', '

a bc d

'], + 'a conditional comment' => ['

ab

', '

ab

'], + 'a conditional comment that shows its content' => ['

abc

', '

abc

'], + 'a comment marker in a script' => ['

ab

', '

ab

'], + 'a script tag in a comment' => ['

ab

c

', '

ab

c

'], + ]; + + $cases = []; + foreach ($documents as $name => $document) { + foreach ($this->modes() as $modeName => $mode) { + $cases[$name . ', ' . $modeName] = array_merge($document, $mode); + } + } + + return $cases; + } + + /** + * Each parser mode that reads a document, with each CSS mode + * + * @return array[] Each [parser mode, CSS mode] + */ + private function modes() + { + return [ + 'default mode, standard' => [HTMLParserMode::DEFAULT_MODE, CssMode::STANDARD], + 'default mode, legacy' => [HTMLParserMode::DEFAULT_MODE, CssMode::LEGACY], + 'body mode, standard' => [HTMLParserMode::HTML_BODY, CssMode::STANDARD], + 'body mode, legacy' => [HTMLParserMode::HTML_BODY, CssMode::LEGACY], + ]; + } + + /** + * @param string $html + * @param int $mode The parser mode, an HTMLParserMode constant + * @param string $cssMode + * + * @return array[] The text of each line drawn, and the page, left and right edges and top of each + */ + private function draw($html, $mode, $cssMode) + { + $mpdf = new TextRecordingMpdf(['mode' => 'c', 'cssMode' => $cssMode]); + $mpdf->WriteHTML($html, $mode); + + return [$mpdf->drawnText, $mpdf->drawnBoxes]; + } + +} diff --git a/tests/Snapshots/HtmlCommentSnapshotTest.php b/tests/Snapshots/HtmlCommentSnapshotTest.php new file mode 100644 index 000000000..a2b24aafc --- /dev/null +++ b/tests/Snapshots/HtmlCommentSnapshotTest.php @@ -0,0 +1,81 @@ + + body { font-size: 11pt; } + h1 { font-size: 15pt; margin: 0 0 2mm 0; } + h2 { margin: 5mm 0 1mm 0; font-size: 10pt; } + p.caption { margin: 0 0 2mm 0; font-size: 8pt; color: #606060; } + div.case { border: 0.2mm solid #999999; padding: 1mm 2mm; } + div.case p { margin: 1mm 0; } + pre { margin: 1mm 0; } + table { border-collapse: collapse; } + td { border: 0.2mm solid #999999; padding: 1mm 3mm; } + + +

HTML comments

+ +

Between two words

+

Reads "Bookkeeper", with no space.

+

Bookkeeper

+ +

Between inline elements

+

Reads "Bookkeeper", with "Book" in bold and "keeper" in italics, and no space between them.

+

Bookkeeper

+ +

In a table cell

+

The cell reads "Bookkeeper", with no space.

+
Bookkeeper
+ +

In preformatted text

+

Three lines: "Bookkeeper" with no space, an empty line, and "keeper".

+
Bookkeeper
+
+keeper
+ +

A conditional comment

+

Reads "Bookkeeper", with no space and no "hidden".

+

Bookkeeper

+ +

A comment marker in a script

+

Reads "Bookkeeper", with no space and none of the script.

+ +

Bookkeeper

+ +

mPDF content

+

Reads "Shown only by mPDF, and Bookkeeper": the markers go and their content stays, and the comment inside it leaves no space.

+
keeper

mpdf-->
+ '; + + $this->mpdf = $this->createMpdf(); + + $this->mpdf->WriteHTML($html); + } + +} diff --git a/tests/data/snapshots/html-comment.pdf b/tests/data/snapshots/html-comment.pdf new file mode 100644 index 0000000000000000000000000000000000000000..42b04fd58bf8e88f79796fc05a0d538efe0cfe90 GIT binary patch literal 68329 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௺h$7U4d9ZpRIbl*zM7|YEdyti?_qqLx@c`zAjK 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 Date: Wed, 30 Sep 2026 20:17:16 +1000 Subject: [PATCH 2/2] Match :empty on an element that holds only an HTML comment A comment no longer leaves a space in its place, so an element holding only a comment is empty, as in a browser. Update the :empty test case, its docblock and #634's changelog note to match. Co-Authored-By: Claude Opus 5.5 --- CHANGELOG-GRAVITYPDF.md | 2 +- src/TracksOpenElements.php | 3 +-- tests/Mpdf/LookAheadSelectorTest.php | 14 +++++++------- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/CHANGELOG-GRAVITYPDF.md b/CHANGELOG-GRAVITYPDF.md index bfcca62db..b598c9e6e 100644 --- a/CHANGELOG-GRAVITYPDF.md +++ b/CHANGELOG-GRAVITYPDF.md @@ -113,7 +113,7 @@ New features * **`:not()`, `:is()` and `:where()`.** Each takes a selector list whose selectors may have combinators, such as `p:not(.note, div > p)` or `:is(h2, h3) + p`. `:is()` and `:where()` leave out a selector they cannot read, as browsers do. `:not()` and `:is()` weigh as their most specific argument, and `:where()` as nothing. Rules using them were dropped before. [#538] [#628] * **Pseudo-classes that look at what follows an element.** `:last-child`, `:nth-last-child()`, `:only-child`, `:last-of-type`, `:nth-last-of-type()`, `:only-of-type` and `:empty` match in the flow, in tables, headers and footers, and positioned blocks. Rules using them were dropped before, so a document that has them changes. Set `'cssMode' => \Mpdf\CssMode::LEGACY` to keep dropping them. [#537] [#634] * `WriteHTML()` reads ahead through the HTML it is given to count each element's children. An element still open at the end of a call that leaves it open is not known in full, so these do not match its children in that call, and nor does `:not()` of them. - * `:empty` matches as in browsers: an element holding white space is not empty. In the default mode mPDF's CSS reader turns each HTML comment into a space, so an element holding only a comment is not empty either. A table cell holding only white space is empty, as mPDF strips it. + * `:empty` matches as in browsers: an element holding white space is not empty, and one holding only a comment is. A table cell holding only white space is empty, as mPDF strips it. Performance ----------- diff --git a/src/TracksOpenElements.php b/src/TracksOpenElements.php index b235fec4d..6370bd044 100644 --- a/src/TracksOpenElements.php +++ b/src/TracksOpenElements.php @@ -324,8 +324,7 @@ private function readAhead(array $tokens, $floor, $standIn, $close) foreach ($tokens as $i => $token) { if ($i % 2 === 0) { - // White space is text, as browsers have it. Comments are gone by now, though the CSS reader leaves a space - // for each + // White space is text, as browsers have it. Comments are gone by now if ($token !== '') { $this->openElements[count($this->openElements) - 1]['empty'] = false; } diff --git a/tests/Mpdf/LookAheadSelectorTest.php b/tests/Mpdf/LookAheadSelectorTest.php index 5110f0d51..3338390fc 100644 --- a/tests/Mpdf/LookAheadSelectorTest.php +++ b/tests/Mpdf/LookAheadSelectorTest.php @@ -239,10 +239,10 @@ public function testTheKeptBlockUnwindsForEveryCase() } /** - * :empty matches an element with no child elements and no text, as browsers have it: white space is text. A - * comment is not, but in the default mode the CSS reader turns each comment into a space before the HTML is read, - * so an element holding one is not empty; the body mode, which does not read CSS, drops comments outright. The - * white space at the end of a table cell is stripped before the HTML is read, so a cell holding only that is empty + * :empty matches an element with no child elements and no text, as browsers have it: white space is text, and a + * comment is not, so an element holding only a comment is empty and one holding comments and white space is not. + * The white space at the end of a table cell is stripped before the HTML is read, so a cell holding only that is + * empty * * @dataProvider emptyElements * @@ -257,8 +257,8 @@ public function testWhatCountsAsEmpty($element, $empty) } /** - * HTML written in the body mode does not go through the CSS reader, so a comment is dropped and the element that - * held only the comment is empty, as in a browser + * HTML written in the body mode drops a comment too, so the element that held only the comment is empty, as in a + * browser */ public function testAnElementHoldingOnlyACommentInTheBodyMode() { @@ -280,7 +280,7 @@ public function emptyElements() 'nothing in it' => ['

', true], 'a space' => ['

', false], 'line breaks and tabs' => ["

\n\t\n

", false], - 'a comment, which the CSS reader turns into a space' => ['

', false], + 'a comment, which leaves nothing in its place' => ['

', true], 'comments and white space' => ['

', false], 'a closed start tag' => ['
', true], 'a void element' => ['
', true],