mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Implement DOMNode::contains()
ref: https://dom.spec.whatwg.org/#dom-node-contains
This commit is contained in:
3
NEWS
3
NEWS
@@ -14,6 +14,9 @@ PHP NEWS
|
||||
. Added zend_call_stack_get implementation for OpenBSD. (David Carlier)
|
||||
. Fixed oss-fuzz #60411 (Fix double-compilation of arrow-functions). (ilutov)
|
||||
|
||||
- DOM:
|
||||
. Added DOMNode::contains() and DOMNameSpaceNode::contains(). (nielsdos)
|
||||
|
||||
- Intl:
|
||||
. Fix memory leak in MessageFormatter::format() on failure. (Girgias)
|
||||
|
||||
|
||||
@@ -238,6 +238,9 @@ PHP 8.3 UPGRADE NOTES
|
||||
6. New Functions
|
||||
========================================
|
||||
|
||||
- DOM:
|
||||
. Added DOMNode::contains() and DOMNameSpaceNode::contains().
|
||||
|
||||
- JSON:
|
||||
. Added json_validate(), which returns whether the json is valid for
|
||||
the given $depth and $options.
|
||||
|
||||
@@ -1782,4 +1782,40 @@ PHP_METHOD(DOMNode, getLineNo)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ URL: https://dom.spec.whatwg.org/#dom-node-contains
|
||||
Since:
|
||||
*/
|
||||
PHP_METHOD(DOMNode, contains)
|
||||
{
|
||||
zval *other, *id;
|
||||
xmlNodePtr otherp, thisp;
|
||||
dom_object *unused_intern;
|
||||
|
||||
ZEND_PARSE_PARAMETERS_START(1, 1)
|
||||
Z_PARAM_OBJECT_OR_NULL(other)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
if (other == NULL) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (UNEXPECTED(!instanceof_function(Z_OBJCE_P(other), dom_node_class_entry) && !instanceof_function(Z_OBJCE_P(other), dom_namespace_node_class_entry))) {
|
||||
zend_argument_type_error(1, "must be of type DOMNode|DOMNameSpaceNode|null, %s given", zend_zval_value_name(other));
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
DOM_GET_OBJ(otherp, other, xmlNodePtr, unused_intern);
|
||||
DOM_GET_THIS_OBJ(thisp, id, xmlNodePtr, unused_intern);
|
||||
|
||||
do {
|
||||
if (otherp == thisp) {
|
||||
RETURN_TRUE;
|
||||
}
|
||||
otherp = otherp->parent;
|
||||
} while (otherp);
|
||||
|
||||
RETURN_FALSE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
#endif
|
||||
|
||||
@@ -389,6 +389,8 @@ class DOMNode
|
||||
|
||||
/** @return DOMNode|false */
|
||||
public function replaceChild(DOMNode $node, DOMNode $child) {}
|
||||
|
||||
public function contains(DOMNode|DOMNameSpaceNode|null $other): bool {}
|
||||
}
|
||||
|
||||
/** @not-serializable */
|
||||
|
||||
8
ext/dom/php_dom_arginfo.h
generated
8
ext/dom/php_dom_arginfo.h
generated
@@ -1,5 +1,5 @@
|
||||
/* This is a generated file, edit the .stub.php file instead.
|
||||
* Stub hash: 00d59fd45c44eb14bbf8f51ee4f61e0464786d69 */
|
||||
* Stub hash: fd3acd731f178c2f1034b206b46d53c236823b9f */
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_dom_import_simplexml, 0, 1, DOMElement, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, node, IS_OBJECT, 0)
|
||||
@@ -100,6 +100,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DOMNode_replaceChild, 0, 0, 2)
|
||||
ZEND_ARG_OBJ_INFO(0, child, DOMNode, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DOMNode_contains, 0, 1, _IS_BOOL, 0)
|
||||
ZEND_ARG_OBJ_TYPE_MASK(0, other, DOMNode|DOMNameSpaceNode, MAY_BE_NULL, NULL)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_DOMImplementation_getFeature, 0, 2, IS_NEVER, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, feature, IS_STRING, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, version, IS_STRING, 0)
|
||||
@@ -512,6 +516,7 @@ ZEND_METHOD(DOMNode, lookupPrefix);
|
||||
ZEND_METHOD(DOMNode, normalize);
|
||||
ZEND_METHOD(DOMNode, removeChild);
|
||||
ZEND_METHOD(DOMNode, replaceChild);
|
||||
ZEND_METHOD(DOMNode, contains);
|
||||
ZEND_METHOD(DOMImplementation, getFeature);
|
||||
ZEND_METHOD(DOMImplementation, hasFeature);
|
||||
ZEND_METHOD(DOMImplementation, createDocumentType);
|
||||
@@ -693,6 +698,7 @@ static const zend_function_entry class_DOMNode_methods[] = {
|
||||
ZEND_ME(DOMNode, normalize, arginfo_class_DOMNode_normalize, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(DOMNode, removeChild, arginfo_class_DOMNode_removeChild, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(DOMNode, replaceChild, arginfo_class_DOMNode_replaceChild, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(DOMNode, contains, arginfo_class_DOMNode_contains, ZEND_ACC_PUBLIC)
|
||||
ZEND_FE_END
|
||||
};
|
||||
|
||||
|
||||
109
ext/dom/tests/DOMNode_contains.phpt
Normal file
109
ext/dom/tests/DOMNode_contains.phpt
Normal file
@@ -0,0 +1,109 @@
|
||||
--TEST--
|
||||
DOMNode::contains()
|
||||
--EXTENSIONS--
|
||||
dom
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$dom = new DOMDocument();
|
||||
$dom->loadXML(<<<XML
|
||||
<!DOCTYPE HTML>
|
||||
<html xmlns:test="some:ns">
|
||||
<head>
|
||||
<title>my title</title>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<p>Hello, world!</p>
|
||||
<p>Second paragraph</p>
|
||||
<div><p>container</p></div>
|
||||
<!-- comment -->
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
XML);
|
||||
|
||||
$xpath = new DOMXPath($dom);
|
||||
$head = $xpath->query("//head")[0];
|
||||
$main = $xpath->query("//main")[0];
|
||||
$div = $xpath->query("//div")[0];
|
||||
|
||||
echo "--- False edge cases ---\n";
|
||||
|
||||
var_dump($dom->documentElement->contains(null));
|
||||
|
||||
try {
|
||||
var_dump($dom->contains(new stdClass));
|
||||
} catch (TypeError $e) {
|
||||
echo $e->getMessage(), "\n";
|
||||
}
|
||||
|
||||
echo "--- True cases ---\n";
|
||||
var_dump($dom->documentElement->contains($head));
|
||||
var_dump($dom->documentElement->contains($main));
|
||||
var_dump($dom->contains($dom));
|
||||
var_dump($main->contains($main));
|
||||
var_dump($div->contains($div));
|
||||
var_dump($main->contains($div));
|
||||
var_dump($main->contains($main->firstElementChild));
|
||||
var_dump($main->contains($div->firstElementChild));
|
||||
var_dump($div->contains($div->firstElementChild));
|
||||
var_dump($main->contains($main->firstElementChild->firstChild));
|
||||
var_dump($dom->contains($dom->doctype));
|
||||
var_dump($dom->contains($dom->doctype));
|
||||
var_dump($dom->contains($dom->documentElement->getAttributeNode('xmlns:test')));
|
||||
var_dump($dom->contains($main->lastChild));
|
||||
|
||||
echo "--- False cases ---\n";
|
||||
var_dump($main->firstElementChild->contains($main));
|
||||
var_dump($main->contains($head));
|
||||
var_dump($div->contains($main));
|
||||
var_dump($main->contains($head->firstElementChild));
|
||||
var_dump($div->contains($main->firstElementChild));
|
||||
var_dump($div->contains($main->firstElementChild->nextElementSibling));
|
||||
var_dump($div->contains($main->lastChild));
|
||||
|
||||
echo "--- False, create element case ---\n";
|
||||
|
||||
$newElement = $dom->createElement('x');
|
||||
var_dump($dom->documentElement->contains($newElement));
|
||||
|
||||
echo "--- Removal case ---\n";
|
||||
|
||||
$main->remove();
|
||||
var_dump($main->contains($main));
|
||||
var_dump($dom->contains($main));
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
--- False edge cases ---
|
||||
bool(false)
|
||||
DOMNode::contains(): Argument #1 ($other) must be of type DOMNode|DOMNameSpaceNode|null, stdClass given
|
||||
--- True cases ---
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
--- False cases ---
|
||||
bool(false)
|
||||
bool(false)
|
||||
bool(false)
|
||||
bool(false)
|
||||
bool(false)
|
||||
bool(false)
|
||||
bool(false)
|
||||
--- False, create element case ---
|
||||
bool(false)
|
||||
--- Removal case ---
|
||||
bool(true)
|
||||
bool(false)
|
||||
Reference in New Issue
Block a user