diff --git a/docs/changes/1.x/1.5.0.md b/docs/changes/1.x/1.5.0.md index b96865bada..3d3aca119e 100644 --- a/docs/changes/1.x/1.5.0.md +++ b/docs/changes/1.x/1.5.0.md @@ -7,6 +7,7 @@ ### Bug fixes - Set writeAttribute return type by [@radarhere](https://github.com/radarhere) fixing [#2204](https://github.com/PHPOffice/PHPWord/issues/2204) in [#2776](https://github.com/PHPOffice/PHPWord/pull/2776) +- Writer HTML: ListItemRun render as unordered lists by [@andomiell](https://github.com/andomiell) partially fixing [#1462](https://github.com/PHPOffice/PHPWord/issues/1462) ### Miscellaneous diff --git a/src/PhpWord/Writer/HTML/Element/Container.php b/src/PhpWord/Writer/HTML/Element/Container.php index 6e2569f3c6..06f607b4af 100644 --- a/src/PhpWord/Writer/HTML/Element/Container.php +++ b/src/PhpWord/Writer/HTML/Element/Container.php @@ -50,7 +50,22 @@ public function write() $content = ''; $elements = $container->getElements(); - foreach ($elements as $element) { + foreach ($elements as $index => $element) { + if ($element instanceof \PhpOffice\PhpWord\Element\ListItemRun) { + $prevElement = $elements[$index - 1] ?? null; + + if ($prevElement === null) { + $content .= ''; + } + } + } } return $content; diff --git a/src/PhpWord/Writer/HTML/Element/ListItemRun.php b/src/PhpWord/Writer/HTML/Element/ListItemRun.php index a708868c3d..2515d6cc55 100644 --- a/src/PhpWord/Writer/HTML/Element/ListItemRun.php +++ b/src/PhpWord/Writer/HTML/Element/ListItemRun.php @@ -36,9 +36,22 @@ public function write() return ''; } - $writer = new Container($this->parentWriter, $this->element); - $content = $writer->write() . PHP_EOL; + $content = '
  • '; - return $content; + foreach ($this->element->getElements() as $element) { + $namespace = 'PhpOffice\\PhpWord\\Writer\\HTML\\Element'; + $elementClass = get_class($element); + $writerClass = str_replace('PhpOffice\\PhpWord\\Element', $namespace, $elementClass); + + if (!class_exists($writerClass)) { + continue; + } + + /** @var AbstractElement $writer */ + $writer = new $writerClass($this->parentWriter, $element, true); + $content .= $writer->write(); + } + + return "$content
  • "; } } diff --git a/tests/PhpWordTests/Writer/HTML/ElementTest.php b/tests/PhpWordTests/Writer/HTML/ElementTest.php index 3b2580381f..d3706f7a55 100644 --- a/tests/PhpWordTests/Writer/HTML/ElementTest.php +++ b/tests/PhpWordTests/Writer/HTML/ElementTest.php @@ -20,6 +20,8 @@ use DateTime; use DOMDocument; +use DOMNode; +use DOMNodeList; use DOMXPath; use PhpOffice\PhpWord\Element\Text as TextElement; use PhpOffice\PhpWord\Element\TextRun; @@ -200,15 +202,35 @@ public function testWriteTitleTextRun(): void */ public function testListItemRun(): void { - $expected1 = 'List item run 1'; - $expected2 = 'List item run 1 in bold'; + $expected11 = 'List item run 1.1'; + $expected11InBold = 'List item run 1.1 in bold'; + $expected12 = 'List item run 1.2'; + $expected21 = 'List item run 2.1'; + $expected22 = 'List item run 2.2'; + $expected31 = 'List item run 3.1'; + $expected13 = 'List item run 1.3'; $phpWord = new PhpWord(); $section = $phpWord->addSection(); - $listItemRun = $section->addListItemRun(0, null, 'MyParagraphStyle'); - $listItemRun->addText($expected1); - $listItemRun->addText($expected2, ['bold' => true]); + $listItemRun11 = $section->addListItemRun(0, null, 'MyParagraphStyle'); + $listItemRun11->addText($expected11); + $listItemRun11->addText($expected11InBold, ['bold' => true]); + + $listItemRun12 = $section->addListItemRun(0); + $listItemRun12->addText($expected12); + + $listItemRun21 = $section->addListItemRun(1); + $listItemRun21->addText($expected21); + + $listItemRun22 = $section->addListItemRun(1); + $listItemRun22->addText($expected22); + + $listItemRun31 = $section->addListItemRun(2); + $listItemRun31->addText($expected31); + + $listItemRun13 = $section->addListItemRun(0); + $listItemRun13->addText($expected13); $htmlWriter = new HTML($phpWord); $content = $htmlWriter->getContent(); @@ -216,8 +238,32 @@ public function testListItemRun(): void $dom = new DOMDocument(); $dom->loadHTML($content); - self::assertEquals($expected1, $dom->getElementsByTagName('p')->item(0)->textContent); - self::assertEquals($expected2, $dom->getElementsByTagName('p')->item(1)->textContent); + $xpath = new DOMXPath($dom); + + /** @var DOMNodeList $list */ + $list = $xpath->query('//body/div/ul/li'); + + $item11 = $list->item(0); + $item12 = $list->item(1); + $item13 = $list->item(2); + + self::assertEquals($expected11, $item11->childNodes->item(0)->textContent); + self::assertEquals('span', $item11->childNodes->item(1)->nodeName); + self::assertEquals($expected11InBold, $item11->childNodes->item(1)->textContent); + + self::assertEquals($expected12, $item12->childNodes->item(0)->textContent); + self::assertEquals('ul', $item12->childNodes->item(1)->nodeName); + + self::assertEquals($expected21, $item12->childNodes->item(1)->childNodes->item(0)->textContent); + + $item22 = $item12->childNodes->item(1)->childNodes->item(1); + + self::assertEquals($expected22, $item22->childNodes->item(0)->textContent); + self::assertEquals('ul', $item22->childNodes->item(1)->nodeName); + + self::assertEquals($expected31, $item22->childNodes->item(1)->childNodes->item(0)->textContent); + + self::assertEquals($expected13, $item13->childNodes->item(0)->textContent); } /**