Skip to content

Commit

Permalink
added DomQuery::closest()
Browse files Browse the repository at this point in the history
  • Loading branch information
dg committed Jan 12, 2025
1 parent 7924225 commit c426b8d
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 0 deletions.
13 changes: 13 additions & 0 deletions src/Framework/DomQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,19 @@ public function matches(string $selector): bool
}


/**
* Returns closest ancestor matching CSS selector.
*/
public function closest(string $selector): ?self
{
if (PHP_VERSION_ID < 80400) {
throw new \LogicException('Requires PHP 8.4 or newer.');
}
$el = Dom\import_simplexml($this)->closest($selector);
return $el ? simplexml_import_dom($el, self::class) : null;
}


/**
* Converts a CSS selector into an XPath expression.
*/
Expand Down
18 changes: 18 additions & 0 deletions tests/Framework/DomQuery.fromHtml.84.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,24 @@ test('matches() checks if element matches selector', function () {
Assert::false($para->matches('.test'));
});

test('closest() finds nearest matching ancestor', function () {
$dom = DomQuery::fromHtml('
<div class="outer">
<div class="middle">
<div class="inner">
<p>Test</p>
</div>
</div>
</div>
');

$p = $dom->find('p')[0];
Assert::type(DomQuery::class, $p->closest('div'));
Assert::true($p->closest('div')->matches('.inner'));
Assert::true($p->closest('.outer')->matches('.outer'));
Assert::null($p->closest('span'));
});

test('find() returns empty array for no matches', function () {
$dom = DomQuery::fromHtml('<div></div>');
Assert::same([], $dom->find('nonexistent'));
Expand Down

0 comments on commit c426b8d

Please sign in to comment.