diff --git a/src/ParentNode.php b/src/ParentNode.php index 8997ee86..ac48d5e0 100644 --- a/src/ParentNode.php +++ b/src/ParentNode.php @@ -60,13 +60,18 @@ protected function __prop_get_children():HTMLCollection { * returns the appended Node object. * + Element.append() can append several nodes and strings, whereas * Node.appendChild() can only append one node. - * @param Node|Element|Text|Comment|string...$nodes + * @param Node|Element|Text|Comment|DocumentFragment|string...$nodes */ public function append(...$nodes):void { // Without this clumsy iteration, PHP 8.1 throws "free(): double free detected in tcache 2" foreach($nodes as $node) { - /** @phpstan-ignore-next-line libxml's DOMNode does not define append() */ - parent::append($node); +// And without this clumsy if/else, PHP 8.3 throws "double free or corruption (!prev)" + if(is_string($node)) { + parent::append($node); + } + else { + parent::appendChild($node); + } } } diff --git a/test/phpunit/DocumentFragmentTest.php b/test/phpunit/DocumentFragmentTest.php index 8ef87f9b..2dd91ed0 100644 --- a/test/phpunit/DocumentFragmentTest.php +++ b/test/phpunit/DocumentFragmentTest.php @@ -21,4 +21,18 @@ public function testGetElementById():void { $sut->appendChild($nodeWithId); self::assertSame($nodeWithId, $sut->getElementById("test")); } + + public function testAppendMultipleNodesThenAddToParentElement():void { + $document = new HTMLDocument(); + $sut = $document->createDocumentFragment(); + $expectedString = ""; + for($i = 0; $i < 10; $i++) { + $textNode = $document->createTextNode("Node$i"); + $sut->append($textNode); + $expectedString .= "Node$i"; + } + + $document->documentElement->append($sut); + self::assertSame($expectedString, $document->textContent); + } }