diff --git a/composer.json b/composer.json index 65fd84f..1b1e413 100644 --- a/composer.json +++ b/composer.json @@ -5,7 +5,7 @@ "require": { "php": ">=8.1", "ext-dom": "*", - "phpgt/dom": "^v4.0.0" + "phpgt/dom": "dev-master" }, "require-dev": { "phpstan/phpstan": "v1.8.0", diff --git a/composer.lock b/composer.lock index 7c2a90a..4118dda 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5f5f2ae66e96eed9fdf142cf445d1c50", + "content-hash": "2363e2449ce3294ab2ec1b1e51657ba4", "packages": [ { "name": "phpgt/cssxpath", @@ -62,16 +62,16 @@ }, { "name": "phpgt/dom", - "version": "v4.0.0", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/PhpGt/Dom.git", - "reference": "e27378f0fefe1952353fcd082e4189243ebfcfee" + "reference": "6d802e8ed4b3bf42887d1ea23a10ebf29094d492" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PhpGt/Dom/zipball/e27378f0fefe1952353fcd082e4189243ebfcfee", - "reference": "e27378f0fefe1952353fcd082e4189243ebfcfee", + "url": "https://api.github.com/repos/PhpGt/Dom/zipball/6d802e8ed4b3bf42887d1ea23a10ebf29094d492", + "reference": "6d802e8ed4b3bf42887d1ea23a10ebf29094d492", "shasum": "" }, "require": { @@ -87,6 +87,7 @@ "phpstan/phpstan": "v1.8.0", "phpunit/phpunit": "v9.5.21" }, + "default-branch": true, "type": "library", "autoload": { "psr-4": { @@ -148,7 +149,7 @@ "description": "The modern DOM API for PHP projects.", "support": { "issues": "https://github.com/PhpGt/Dom/issues", - "source": "https://github.com/PhpGt/Dom/tree/v4.0.0" + "source": "https://github.com/PhpGt/Dom/tree/master" }, "funding": [ { @@ -156,7 +157,7 @@ "type": "github" } ], - "time": "2022-07-01T11:24:27+00:00" + "time": "2022-07-12T15:19:44+00:00" }, { "name": "phpgt/propfunc", @@ -2342,7 +2343,9 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "phpgt/dom": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { @@ -2350,5 +2353,5 @@ "ext-dom": "*" }, "platform-dev": [], - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.2.0" } diff --git a/src/PlaceholderBinder.php b/src/PlaceholderBinder.php index 5a9065e..cc087a8 100644 --- a/src/PlaceholderBinder.php +++ b/src/PlaceholderBinder.php @@ -28,6 +28,7 @@ public function bind( $context ); + $placeholderTextList = []; foreach($xpathResult as $attributeOrText) { /** @var Text|Attr $text */ $text = $attributeOrText; @@ -49,6 +50,10 @@ public function bind( continue; } + array_push($placeholderTextList, $placeholderText); + } + + foreach($placeholderTextList as $placeholderText) { $placeholderText->setValue($value); } } diff --git a/src/PlaceholderText.php b/src/PlaceholderText.php index 9525965..ce2669f 100644 --- a/src/PlaceholderText.php +++ b/src/PlaceholderText.php @@ -1,6 +1,7 @@ process(); } @@ -44,10 +45,43 @@ public function setValue(mixed $value):void { $stringValue = (string)$value; if(strlen($stringValue) === 0) { - $this->originalText->data = $this->default ?: ""; + $stringValue = $this->default ?: ""; } - else { - $this->originalText->data = $stringValue; + $this->originalText->data = $stringValue; + + $parent = $this->originalText->parentNode; +/** @phpstan-ignore-next-line */ + if($parent instanceof Attr) { + $this->originalText->normalize(); + $qualifiedName = $parent->name; + $wholeText = $this->originalText->wholeText; + /** @var Element $ownerElement */ + $ownerElement = $parent->ownerElement; +// https://bugs.php.net/bug.php?id=81506 + $ownerElement->setAttribute("data-temp-$qualifiedName", $wholeText); + + /** + * @var string $attrName + * @var Attr $attr + */ + foreach($ownerElement->attributes as $attrName => $attr) { + if($attrName !== $qualifiedName) { + continue; + } + +// Workaround for PHP bug 81506 (don't lose reference to text) +// https://bugs.php.net/bug.php?id=81506 + $attr->appendChild($this->originalText); + } + if($qualifiedName === "id") { + $ownerElement->id = $wholeText; + } + else { + $ownerElement->setAttribute($qualifiedName, $wholeText); + } + +// https://bugs.php.net/bug.php?id=81506 + $ownerElement->removeAttribute("data-temp-$qualifiedName"); } } } diff --git a/test/phpunit/DocumentBinderTest.php b/test/phpunit/DocumentBinderTest.php index 0bc86cc..0078717 100644 --- a/test/phpunit/DocumentBinderTest.php +++ b/test/phpunit/DocumentBinderTest.php @@ -960,6 +960,33 @@ public function testBindList_twoListsWithSamePath():void { } } + public function testBindList_readOnlyProperties():void { + $userObject1 = new class(1, "g105b", 3) { + public function __construct( + public readonly int $userId, + public readonly string $username, + public readonly int $orderCount, + ) {} + }; + $userObject2 = new class(2, "codyboy", 21) { + public function __construct( + public readonly int $userId, + public readonly string $username, + public readonly int $orderCount, + ) {} + }; + + $document = new HTMLDocument(DocumentTestFactory::HTML_USER_ORDER_LIST); + $sut = new DocumentBinder($document); + $sut->bindList([$userObject1, $userObject2]); + + $li1 = $document->getElementById("user-1"); + $li2 = $document->getElementById("user-2"); + self::assertNotSame($li1, $li2); + self::assertSame($userObject1->username, $li1->querySelector("h2 span")->textContent); + self::assertSame($userObject2->username, $li2->querySelector("h2 span")->textContent); + } + public function test_onlyBindOnce():void { $document = new HTMLDocument(DocumentTestFactory::HTML_BIND_KEY_REUSED); $sut = new DocumentBinder($document); diff --git a/test/phpunit/ListBinderTest.php b/test/phpunit/ListBinderTest.php index a01c9c1..717d8d9 100644 --- a/test/phpunit/ListBinderTest.php +++ b/test/phpunit/ListBinderTest.php @@ -225,7 +225,6 @@ public function testBindListData_kvpList_array():void { $sut->bindListData($kvpList, $orderList); foreach($orderList->children as $i => $li) { - /** @var HTMLLiElement $li */ self::assertEquals($kvpList[$i]["userId"], $li->querySelector("h3 span")->textContent); self::assertEquals($kvpList[$i]["username"], $li->querySelector("h2 span")->textContent); self::assertEquals($kvpList[$i]["orderCount"], $li->querySelector("p span")->textContent); @@ -251,7 +250,6 @@ public function testBindListData_kvpList_object():void { $sut->bindListData($kvpList, $orderList); foreach($orderList->children as $i => $li) { - /** @var HTMLLiElement $li */ self::assertEquals($kvpList[$i]->{"userId"}, $li->querySelector("h3 span")->textContent); self::assertEquals($kvpList[$i]->{"username"}, $li->querySelector("h2 span")->textContent); self::assertEquals($kvpList[$i]->{"orderCount"}, $li->querySelector("p span")->textContent); @@ -277,7 +275,6 @@ public function testBindListData_kvpList_instanceObject():void { $sut->bindListData($kvpList, $orderList); foreach($orderList->children as $i => $li) { - /** @var HTMLLiElement $li */ self::assertEquals($kvpList[$i]->{"userId"}, $li->querySelector("h3 span")->textContent); self::assertEquals($kvpList[$i]->{"username"}, $li->querySelector("h2 span")->textContent); self::assertEquals($kvpList[$i]->{"orderCount"}, $li->querySelector("p span")->textContent); diff --git a/test/phpunit/phpunit.xml b/test/phpunit/phpunit.xml index cf95bea..ac4b065 100644 --- a/test/phpunit/phpunit.xml +++ b/test/phpunit/phpunit.xml @@ -1,5 +1,5 @@ - + ../../src @@ -15,4 +15,4 @@ - \ No newline at end of file +