Skip to content

Commit 0cdb852

Browse files
authored
Merge pull request #61 from super-dm3/fix-parent
Fix error when getting parents() for HTML elements
2 parents b5fb9e9 + 88db7da commit 0cdb852

File tree

3 files changed

+31
-21
lines changed

3 files changed

+31
-21
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ QueryPath Changelog
1313
- Fix for :nth-child(n+B) to select B-th and all following elements
1414
- Fix for :nth-child(-n+B) to select first B elements
1515
- Update PHPUnit Test Suite to use @dataProvider in testPseudoClassNthChild() to reduce code repetition
16+
- Fix error when getting parents() for HTML elements
1617

1718
# 4.0.0
1819

src/Helpers/QueryFilters.php

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -796,26 +796,7 @@ public function closest($selector): Query
796796
*/
797797
public function parent($selector = null): Query
798798
{
799-
$found = new SplObjectStorage();
800-
foreach ($this->matches as $m) {
801-
while ($m->parentNode->nodeType !== XML_DOCUMENT_NODE) {
802-
$m = $m->parentNode;
803-
// Is there any case where parent node is not an element?
804-
if ($m->nodeType === XML_ELEMENT_NODE) {
805-
if (! empty($selector)) {
806-
if (QueryPath::with($m, null, $this->options)->is($selector) > 0) {
807-
$found->attach($m);
808-
break;
809-
}
810-
} else {
811-
$found->attach($m);
812-
break;
813-
}
814-
}
815-
}
816-
}
817-
818-
return $this->inst($found, null);
799+
return $this->getParentElements($selector, true);
819800
}
820801

821802
/**
@@ -835,19 +816,45 @@ public function parent($selector = null): Query
835816
* @see siblings()
836817
*/
837818
public function parents($selector = null): Query
819+
{
820+
return $this->getParentElements($selector, false);
821+
}
822+
823+
/**
824+
* Get ancestor(s) of each element in the DOMQuery.
825+
*
826+
* If a selector is present, only matching ancestors will be retrieved.
827+
*
828+
* @param string|null $selector
829+
* A valid CSS 3 Selector.
830+
* @param bool $immediate
831+
* If function should return only the immediate parent
832+
*
833+
* @return DOMQuery
834+
* A DOMNode object containing the matching ancestors.
835+
* @throws ParseException
836+
* @throws Exception
837+
*/
838+
private function getParentElements(?string $selector, bool $immediate): Query
838839
{
839840
$found = new SplObjectStorage();
840841
foreach ($this->matches as $m) {
841-
while ($m->parentNode->nodeType !== XML_DOCUMENT_NODE) {
842+
while ($m->parentNode && $m->parentNode->nodeType !== XML_DOCUMENT_NODE) {
842843
$m = $m->parentNode;
843844
// Is there any case where parent node is not an element?
844845
if ($m->nodeType === XML_ELEMENT_NODE) {
845846
if (! empty($selector)) {
846847
if (QueryPath::with($m, null, $this->options)->is($selector) > 0) {
847848
$found->attach($m);
849+
if ($immediate) {
850+
break;
851+
}
848852
}
849853
} else {
850854
$found->attach($m);
855+
if ($immediate) {
856+
break;
857+
}
851858
}
852859
}
853860
}

tests/QueryPath/DOMQueryTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1676,6 +1676,8 @@ public function testParent()
16761676
$this->assertEquals('root', qp($file, 'unary')->parent()->tag());
16771677
$this->assertEquals('root', qp($file, 'li')->parent('root')->tag());
16781678
$this->assertEquals(2, qp($file, 'li')->parent()->count());
1679+
$this->assertEquals(0, qp(DATA_HTML_FILE, 'html')->parent()->count());
1680+
$this->assertEquals(2, qp(DATA_HTML_FILE, 'table')->parents()->count());
16791681
}
16801682

16811683
public function testClosest()

0 commit comments

Comments
 (0)