From 776655104bf39039e4195a6d414280b225d913ac Mon Sep 17 00:00:00 2001 From: lacatoire Date: Mon, 16 Feb 2026 09:52:05 +0100 Subject: [PATCH] Fix GH-181: Empty title swallows sibling content When a self-closing element appeared in DocBook XML, transformFromMap() generated invalid HTML like <h3 class="title"/> which browsers parse as an unclosed <h3>, swallowing all sibling content. Emit a proper open+close pair (<h3 class="title"></h3>) instead. --- phpdotnet/phd/Format/Abstract/XHTML.php | 5 +++- .../package/generic/data/empty_title_001.xml | 7 +++++ tests/package/generic/empty_title_001.phpt | 29 +++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 tests/package/generic/data/empty_title_001.xml create mode 100644 tests/package/generic/empty_title_001.phpt diff --git a/phpdotnet/phd/Format/Abstract/XHTML.php b/phpdotnet/phd/Format/Abstract/XHTML.php index 12f57171..4d67268f 100644 --- a/phpdotnet/phd/Format/Abstract/XHTML.php +++ b/phpdotnet/phd/Format/Abstract/XHTML.php @@ -31,7 +31,10 @@ public function transformFromMap($open, $tag, $name, $attrs, $props) { $id = $attrs[Reader::XMLNS_XML]["id"]; $idstr = ' id="' .$id. '"'; } - return '<' .$tag. ' class="' .$name. '"' . $idstr . ($props["empty"] ? '/' : "") . '>'; + if ($props["empty"]) { + return '<' .$tag. ' class="' .$name. '"' . $idstr . '></' .$tag. '>'; + } + return '<' .$tag. ' class="' .$name. '"' . $idstr . '>'; } return '</' .$tag. '>'; } diff --git a/tests/package/generic/data/empty_title_001.xml b/tests/package/generic/data/empty_title_001.xml new file mode 100644 index 00000000..56c13c1c --- /dev/null +++ b/tests/package/generic/data/empty_title_001.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8"?> +<article xmlns="http://docbook.org/ns/docbook" xml:id="empty_title_test"> + <section xml:id="empty-title-section"> + <title/> + <simpara>Some content after empty title</simpara> + </section> +</article> diff --git a/tests/package/generic/empty_title_001.phpt b/tests/package/generic/empty_title_001.phpt new file mode 100644 index 00000000..76dfd1b1 --- /dev/null +++ b/tests/package/generic/empty_title_001.phpt @@ -0,0 +1,29 @@ +--TEST-- +GH-181 Empty title should not swallow sibling content +--FILE-- +<?php +namespace phpdotnet\phd; + +require_once __DIR__ . "/../../setup.php"; + +$xmlFile = __DIR__ . "/data/empty_title_001.xml"; + +$config->xmlFile = $xmlFile; + +$format = new TestGenericChunkedXHTML($config, $outputHandler); +$render = new TestRender(new Reader($outputHandler), $config, $format); + +$render->run(); +?> +--EXPECTF-- +Filename: empty-title-section.html +Content: +<div id="empty-title-section" class="section"> + <h2 class="title"></h2> + <p class="simpara">Some content after empty title</p> + </div> +Filename: empty_title_test.html +Content: +<div id="empty_title_test" class="article"> +%A +</div>