mirror of
https://github.com/php/php-src.git
synced 2025-08-15 13:38:49 +02:00
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 GH-15047.
This commit is contained in:
parent
a0a8624346
commit
ad452086d9
6 changed files with 91 additions and 6 deletions
2
NEWS
2
NEWS
|
@ -53,6 +53,8 @@ PHP NEWS
|
|||
- Tidy:
|
||||
. Failures in the constructor now throw exceptions rather than emitting
|
||||
warnings and having a broken object. (nielsdos)
|
||||
. Add tidyNode::getNextSibling() and tidyNode::getPreviousSibling().
|
||||
(nielsdos)
|
||||
|
||||
- XSL:
|
||||
. Fix trampoline leak in xpath callables. (nielsdos)
|
||||
|
|
|
@ -667,6 +667,9 @@ PHP 8.4 UPGRADE NOTES
|
|||
array_any().
|
||||
RFC: https://wiki.php.net/rfc/array_find
|
||||
|
||||
- Tidy:
|
||||
. Added tidyNode::getNextSibling() and tidyNode::getPreviousSibling().
|
||||
|
||||
- XMLReader:
|
||||
. Added XMLReader::fromStream(), XMLReader::fromUri(), XMLReader::fromString().
|
||||
RFC: https://wiki.php.net/rfc/xmlreader_writer_streams
|
||||
|
|
52
ext/tidy/tests/sibling_nodes.phpt
Normal file
52
ext/tidy/tests/sibling_nodes.phpt
Normal file
|
@ -0,0 +1,52 @@
|
|||
--TEST--
|
||||
getPreviousSibling() and getNextSibling()
|
||||
--EXTENSIONS--
|
||||
tidy
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$tidy = tidy_parse_string(<<<HTML
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<div>first</div>
|
||||
<!-- second -->
|
||||
<div>third</div>
|
||||
</body>
|
||||
</html>
|
||||
HTML);
|
||||
$body = $tidy->body();
|
||||
|
||||
function format($str) {
|
||||
if (is_null($str)) return $str;
|
||||
return trim($str);
|
||||
}
|
||||
|
||||
foreach ($body->child as $i => $child) {
|
||||
echo "=== From the perspective of child $i ===\n";
|
||||
echo "Previous: ";
|
||||
var_dump(format($child->getPreviousSibling()?->value));
|
||||
echo "Next: ";
|
||||
var_dump(format($child->getNextSibling()?->value));
|
||||
}
|
||||
|
||||
echo "=== html element has only the doctype as sibling ===\n";
|
||||
echo "Previous: ";
|
||||
var_dump(format($tidy->html()->getPreviousSibling()?->value));
|
||||
echo "Next: ";
|
||||
var_dump(format($tidy->html()->getNextSibling()?->value));
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
=== From the perspective of child 0 ===
|
||||
Previous: NULL
|
||||
Next: string(15) "<!-- second -->"
|
||||
=== From the perspective of child 1 ===
|
||||
Previous: string(16) "<div>first</div>"
|
||||
Next: string(16) "<div>third</div>"
|
||||
=== From the perspective of child 2 ===
|
||||
Previous: string(15) "<!-- second -->"
|
||||
Next: NULL
|
||||
=== html element has only the doctype as sibling ===
|
||||
Previous: string(15) "<!DOCTYPE html>"
|
||||
Next: NULL
|
|
@ -1599,18 +1599,34 @@ PHP_METHOD(tidyNode, isPhp)
|
|||
/* {{{ Returns the parent node if available or NULL */
|
||||
PHP_METHOD(tidyNode, getParent)
|
||||
{
|
||||
TidyNode parent_node;
|
||||
TIDY_FETCH_ONLY_OBJECT;
|
||||
|
||||
parent_node = tidyGetParent(obj->node);
|
||||
if(parent_node) {
|
||||
TidyNode parent_node = tidyGetParent(obj->node);
|
||||
if (parent_node) {
|
||||
tidy_create_node_object(return_value, obj->ptdoc, parent_node);
|
||||
} else {
|
||||
ZVAL_NULL(return_value);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
PHP_METHOD(tidyNode, getPreviousSibling)
|
||||
{
|
||||
TIDY_FETCH_ONLY_OBJECT;
|
||||
|
||||
TidyNode previous_node = tidyGetPrev(obj->node);
|
||||
if (previous_node) {
|
||||
tidy_create_node_object(return_value, obj->ptdoc, previous_node);
|
||||
}
|
||||
}
|
||||
|
||||
PHP_METHOD(tidyNode, getNextSibling)
|
||||
{
|
||||
TIDY_FETCH_ONLY_OBJECT;
|
||||
|
||||
TidyNode next_node = tidyGetNext(obj->node);
|
||||
if (next_node) {
|
||||
tidy_create_node_object(return_value, obj->ptdoc, next_node);
|
||||
}
|
||||
}
|
||||
|
||||
/* {{{ __constructor for tidyNode. */
|
||||
PHP_METHOD(tidyNode, __construct)
|
||||
|
|
|
@ -1004,4 +1004,8 @@ final class tidyNode
|
|||
public function isPhp(): bool {}
|
||||
|
||||
public function getParent(): ?tidyNode {}
|
||||
|
||||
public function getPreviousSibling(): ?tidyNode {}
|
||||
|
||||
public function getNextSibling(): ?tidyNode {}
|
||||
}
|
||||
|
|
10
ext/tidy/tidy_arginfo.h
generated
10
ext/tidy/tidy_arginfo.h
generated
|
@ -1,5 +1,5 @@
|
|||
/* This is a generated file, edit the .stub.php file instead.
|
||||
* Stub hash: 5efa4f23774fac9610f05d895d8f8c6f481cc5a6 */
|
||||
* Stub hash: 0e6561410a63658f76011c1ddcecdd1e68757f0a */
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_tidy_parse_string, 0, 1, tidy, MAY_BE_FALSE)
|
||||
ZEND_ARG_TYPE_INFO(0, string, IS_STRING, 0)
|
||||
|
@ -183,6 +183,10 @@ ZEND_END_ARG_INFO()
|
|||
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_tidyNode_getParent, 0, 0, tidyNode, 1)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_tidyNode_getPreviousSibling arginfo_class_tidyNode_getParent
|
||||
|
||||
#define arginfo_class_tidyNode_getNextSibling arginfo_class_tidyNode_getParent
|
||||
|
||||
ZEND_FUNCTION(tidy_parse_string);
|
||||
ZEND_FUNCTION(tidy_get_error_buffer);
|
||||
ZEND_FUNCTION(tidy_get_output);
|
||||
|
@ -222,6 +226,8 @@ ZEND_METHOD(tidyNode, isJste);
|
|||
ZEND_METHOD(tidyNode, isAsp);
|
||||
ZEND_METHOD(tidyNode, isPhp);
|
||||
ZEND_METHOD(tidyNode, getParent);
|
||||
ZEND_METHOD(tidyNode, getPreviousSibling);
|
||||
ZEND_METHOD(tidyNode, getNextSibling);
|
||||
|
||||
static const zend_function_entry ext_functions[] = {
|
||||
ZEND_FE(tidy_parse_string, arginfo_tidy_parse_string)
|
||||
|
@ -289,6 +295,8 @@ static const zend_function_entry class_tidyNode_methods[] = {
|
|||
ZEND_ME(tidyNode, isAsp, arginfo_class_tidyNode_isAsp, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(tidyNode, isPhp, arginfo_class_tidyNode_isPhp, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(tidyNode, getParent, arginfo_class_tidyNode_getParent, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(tidyNode, getPreviousSibling, arginfo_class_tidyNode_getPreviousSibling, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(tidyNode, getNextSibling, arginfo_class_tidyNode_getNextSibling, ZEND_ACC_PUBLIC)
|
||||
ZEND_FE_END
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue