Skip to content

Commit ad45208

Browse files
committed
Add tidyNode::getNextSibling() and tidyNode::getPreviousSibling()
These get the next and previous sibling nodes, respectively. We can already kind of do this by using the $child array, but that's inconvenient when actually walking the tree by only using node instances. Since the class is final, there is no BC break here. Closes phpGH-15047.
1 parent a0a8624 commit ad45208

File tree

6 files changed

+91
-6
lines changed

6 files changed

+91
-6
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ PHP NEWS
5353
- Tidy:
5454
. Failures in the constructor now throw exceptions rather than emitting
5555
warnings and having a broken object. (nielsdos)
56+
. Add tidyNode::getNextSibling() and tidyNode::getPreviousSibling().
57+
(nielsdos)
5658

5759
- XSL:
5860
. Fix trampoline leak in xpath callables. (nielsdos)

UPGRADING

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,9 @@ PHP 8.4 UPGRADE NOTES
667667
array_any().
668668
RFC: https://wiki.php.net/rfc/array_find
669669

670+
- Tidy:
671+
. Added tidyNode::getNextSibling() and tidyNode::getPreviousSibling().
672+
670673
- XMLReader:
671674
. Added XMLReader::fromStream(), XMLReader::fromUri(), XMLReader::fromString().
672675
RFC: https://wiki.php.net/rfc/xmlreader_writer_streams

ext/tidy/tests/sibling_nodes.phpt

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
--TEST--
2+
getPreviousSibling() and getNextSibling()
3+
--EXTENSIONS--
4+
tidy
5+
--FILE--
6+
<?php
7+
8+
$tidy = tidy_parse_string(<<<HTML
9+
<!DOCTYPE html>
10+
<html>
11+
<body>
12+
<div>first</div>
13+
<!-- second -->
14+
<div>third</div>
15+
</body>
16+
</html>
17+
HTML);
18+
$body = $tidy->body();
19+
20+
function format($str) {
21+
if (is_null($str)) return $str;
22+
return trim($str);
23+
}
24+
25+
foreach ($body->child as $i => $child) {
26+
echo "=== From the perspective of child $i ===\n";
27+
echo "Previous: ";
28+
var_dump(format($child->getPreviousSibling()?->value));
29+
echo "Next: ";
30+
var_dump(format($child->getNextSibling()?->value));
31+
}
32+
33+
echo "=== html element has only the doctype as sibling ===\n";
34+
echo "Previous: ";
35+
var_dump(format($tidy->html()->getPreviousSibling()?->value));
36+
echo "Next: ";
37+
var_dump(format($tidy->html()->getNextSibling()?->value));
38+
39+
?>
40+
--EXPECT--
41+
=== From the perspective of child 0 ===
42+
Previous: NULL
43+
Next: string(15) "<!-- second -->"
44+
=== From the perspective of child 1 ===
45+
Previous: string(16) "<div>first</div>"
46+
Next: string(16) "<div>third</div>"
47+
=== From the perspective of child 2 ===
48+
Previous: string(15) "<!-- second -->"
49+
Next: NULL
50+
=== html element has only the doctype as sibling ===
51+
Previous: string(15) "<!DOCTYPE html>"
52+
Next: NULL

ext/tidy/tidy.c

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1599,18 +1599,34 @@ PHP_METHOD(tidyNode, isPhp)
15991599
/* {{{ Returns the parent node if available or NULL */
16001600
PHP_METHOD(tidyNode, getParent)
16011601
{
1602-
TidyNode parent_node;
16031602
TIDY_FETCH_ONLY_OBJECT;
16041603

1605-
parent_node = tidyGetParent(obj->node);
1606-
if(parent_node) {
1604+
TidyNode parent_node = tidyGetParent(obj->node);
1605+
if (parent_node) {
16071606
tidy_create_node_object(return_value, obj->ptdoc, parent_node);
1608-
} else {
1609-
ZVAL_NULL(return_value);
16101607
}
16111608
}
16121609
/* }}} */
16131610

1611+
PHP_METHOD(tidyNode, getPreviousSibling)
1612+
{
1613+
TIDY_FETCH_ONLY_OBJECT;
1614+
1615+
TidyNode previous_node = tidyGetPrev(obj->node);
1616+
if (previous_node) {
1617+
tidy_create_node_object(return_value, obj->ptdoc, previous_node);
1618+
}
1619+
}
1620+
1621+
PHP_METHOD(tidyNode, getNextSibling)
1622+
{
1623+
TIDY_FETCH_ONLY_OBJECT;
1624+
1625+
TidyNode next_node = tidyGetNext(obj->node);
1626+
if (next_node) {
1627+
tidy_create_node_object(return_value, obj->ptdoc, next_node);
1628+
}
1629+
}
16141630

16151631
/* {{{ __constructor for tidyNode. */
16161632
PHP_METHOD(tidyNode, __construct)

ext/tidy/tidy.stub.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,4 +1004,8 @@ public function isAsp(): bool {}
10041004
public function isPhp(): bool {}
10051005

10061006
public function getParent(): ?tidyNode {}
1007+
1008+
public function getPreviousSibling(): ?tidyNode {}
1009+
1010+
public function getNextSibling(): ?tidyNode {}
10071011
}

ext/tidy/tidy_arginfo.h

Lines changed: 9 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)