1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

Implement Dom\Document::$body getter

This commit is contained in:
Niels Dossche
2024-03-23 13:54:51 +01:00
parent e7cc819bd9
commit a1485df55a
12 changed files with 153 additions and 7 deletions

View File

@@ -62,6 +62,7 @@ zend_result dom_document_substitue_entities_write(dom_object *obj, zval *newval)
/* html5 document properties */
zend_result dom_html_document_encoding_write(dom_object *obj, zval *retval);
zend_result dom_html_document_body_read(dom_object *obj, zval *retval);
/* documenttype properties */
zend_result dom_documenttype_name_read(dom_object *obj, zval *retval);

View File

@@ -1358,4 +1358,29 @@ zend_result dom_html_document_encoding_write(dom_object *obj, zval *newval)
return SUCCESS;
}
/* https://html.spec.whatwg.org/#dom-document-body */
zend_result dom_html_document_body_read(dom_object *obj, zval *retval)
{
DOM_PROP_NODE(const xmlDoc *, docp, obj);
const xmlNode *root = xmlDocGetRootElement(docp);
if (root == NULL || !(php_dom_ns_is_fast(root, php_dom_ns_is_html_magic_token) && xmlStrEqual(root->name, BAD_CAST "html"))) {
ZVAL_NULL(retval);
return SUCCESS;
}
xmlNodePtr cur = root->children;
while (cur != NULL) {
if (cur->type == XML_ELEMENT_NODE && php_dom_ns_is_fast(cur, php_dom_ns_is_html_magic_token)
&& (xmlStrEqual(cur->name, BAD_CAST "body") || xmlStrEqual(cur->name, BAD_CAST "frameset"))) {
php_dom_create_object(cur, retval, obj);
return SUCCESS;
}
cur = cur->next;
}
ZVAL_NULL(retval);
return SUCCESS;
}
#endif /* HAVE_LIBXML && HAVE_DOM */

View File

@@ -851,6 +851,7 @@ PHP_MINIT_FUNCTION(dom)
DOM_REGISTER_PROP_HANDLER(&dom_abstract_base_document_prop_handlers, "firstElementChild", dom_parent_node_first_element_child_read, NULL);
DOM_REGISTER_PROP_HANDLER(&dom_abstract_base_document_prop_handlers, "lastElementChild", dom_parent_node_last_element_child_read, NULL);
DOM_REGISTER_PROP_HANDLER(&dom_abstract_base_document_prop_handlers, "childElementCount", dom_parent_node_child_element_count, NULL);
DOM_REGISTER_PROP_HANDLER(&dom_abstract_base_document_prop_handlers, "body", dom_html_document_body_read, NULL);
zend_hash_merge(&dom_abstract_base_document_prop_handlers, &dom_modern_node_prop_handlers, NULL, false);
/* No need to register in &classes because this is an abstract class handler. */

View File

@@ -1580,6 +1580,8 @@ namespace Dom
public function replaceChildren(Node|string ...$nodes): void {}
public function importLegacyNode(\DOMNode $node, bool $deep = false): Node {}
public ?Element $body;
}
final class HTMLDocument extends Document

View File

@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: c93643bad9675fddf31ca52f82f843218f208a5d */
* Stub hash: 4d7d3a428304aa0544da0b1b57caa4e5948fa31b */
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)
@@ -3442,6 +3442,13 @@ static zend_class_entry *register_class_Dom_Document(zend_class_entry *class_ent
zend_declare_typed_property(class_entry, property_childElementCount_name, &property_childElementCount_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
zend_string_release(property_childElementCount_name);
zval property_body_default_value;
ZVAL_UNDEF(&property_body_default_value);
zend_string *property_body_name = zend_string_init("body", sizeof("body") - 1, 1);
zend_string *property_body_class_Dom_Element = zend_string_init("Dom\\Element", sizeof("Dom\\Element")-1, 1);
zend_declare_typed_property(class_entry, property_body_name, &property_body_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_body_class_Dom_Element, 0, MAY_BE_NULL));
zend_string_release(property_body_name);
return class_entry;
}

View File

@@ -0,0 +1,98 @@
--TEST--
Test Dom\Document::$body
--EXTENSIONS--
dom
--FILE--
<?php
echo "--- From parsing ---\n";
$dom = Dom\HTMLDocument::createFromString("<p>foo</p>", LIBXML_NOERROR);
var_dump($dom->body?->nodeName);
echo "--- After body removal ---\n";
$dom->body->remove();
var_dump($dom->body?->nodeName);
echo "--- body in no namespace ---\n";
$tmp = $dom->documentElement->appendChild($dom->createElementNS("", "body"));
var_dump($dom->body?->nodeName);
$tmp->remove();
echo "--- frameset in no namespace ---\n";
$tmp = $dom->documentElement->appendChild($dom->createElementNS("", "frameset"));
var_dump($dom->body?->nodeName);
$tmp->remove();
echo "--- body in right namespace ---\n";
$tmp = $dom->documentElement->appendChild($dom->createElementNS("http://www.w3.org/1999/xhtml", "body"));
var_dump($dom->body?->nodeName);
$tmp->remove();
echo "--- frameset in right namespace ---\n";
$tmp = $dom->documentElement->appendChild($dom->createElementNS("http://www.w3.org/1999/xhtml", "frameset"));
var_dump($dom->body?->nodeName);
$tmp->remove();
echo "--- prefixed body in right namespace ---\n";
$tmp = $dom->documentElement->appendChild($dom->createElementNS("http://www.w3.org/1999/xhtml", "prefix:body"));
var_dump($dom->body?->nodeName);
$tmp->remove();
echo "--- prefixed frameset in right namespace ---\n";
$tmp = $dom->documentElement->appendChild($dom->createElementNS("http://www.w3.org/1999/xhtml", "prefix:frameset"));
var_dump($dom->body?->nodeName);
$tmp->remove();
echo "--- multiple body-like elements in right namespace ---\n";
$tmp1 = $dom->documentElement->appendChild($dom->createElementNS("http://www.w3.org/1999/xhtml", "prefix1:body"));
var_dump($dom->body?->nodeName);
$tmp2 = $dom->documentElement->appendChild($dom->createElementNS("http://www.w3.org/1999/xhtml", "prefix2:frameset"));
var_dump($dom->body?->nodeName);
$tmp1->remove();
var_dump($dom->body?->nodeName);
$tmp2->remove();
var_dump($dom->body?->nodeName);
echo "--- html element in no namespace ---\n";
$dom = Dom\XMLDocument::createFromString(<<<XML
<html xmlns="">
<body/>
</html>
XML);
var_dump($dom->body);
?>
--EXPECT--
--- From parsing ---
string(4) "BODY"
--- After body removal ---
NULL
--- body in no namespace ---
NULL
--- frameset in no namespace ---
NULL
--- body in right namespace ---
string(4) "BODY"
--- frameset in right namespace ---
string(8) "FRAMESET"
--- prefixed body in right namespace ---
string(11) "PREFIX:BODY"
--- prefixed frameset in right namespace ---
string(15) "PREFIX:FRAMESET"
--- multiple body-like elements in right namespace ---
string(12) "PREFIX1:BODY"
string(12) "PREFIX1:BODY"
string(16) "PREFIX2:FRAMESET"
NULL
--- html element in no namespace ---
NULL

View File

@@ -23,7 +23,7 @@ var_dump(get_class($dom->getElementsByTagName("p")->item(0)));
?>
--EXPECT--
object(Dom\HTMLDocument)#1 (25) {
object(Dom\HTMLDocument)#1 (26) {
["implementation"]=>
string(22) "(object value omitted)"
["URL"]=>
@@ -46,6 +46,8 @@ object(Dom\HTMLDocument)#1 (25) {
string(22) "(object value omitted)"
["childElementCount"]=>
int(1)
["body"]=>
string(22) "(object value omitted)"
["nodeType"]=>
int(13)
["nodeName"]=>

View File

@@ -23,7 +23,7 @@ var_dump(get_class($dom->getElementsByTagName("p")->item(0)));
?>
--EXPECT--
object(Dom\HTMLDocument)#1 (25) {
object(Dom\HTMLDocument)#1 (26) {
["implementation"]=>
string(22) "(object value omitted)"
["URL"]=>
@@ -46,6 +46,8 @@ object(Dom\HTMLDocument)#1 (25) {
string(22) "(object value omitted)"
["childElementCount"]=>
int(1)
["body"]=>
string(22) "(object value omitted)"
["nodeType"]=>
int(13)
["nodeName"]=>

View File

@@ -37,7 +37,7 @@ echo $dom->implementation->createDocument(null, "", $dtd)->saveXml(), "\n";
?>
--EXPECT--
--- (null, "") ---
object(Dom\XMLDocument)#3 (29) {
object(Dom\XMLDocument)#3 (30) {
["xmlEncoding"]=>
string(5) "UTF-8"
["xmlStandalone"]=>
@@ -68,6 +68,8 @@ object(Dom\XMLDocument)#3 (29) {
NULL
["childElementCount"]=>
int(0)
["body"]=>
NULL
["nodeType"]=>
int(9)
["nodeName"]=>

View File

@@ -10,7 +10,7 @@ var_dump($dom);
?>
--EXPECT--
object(Dom\XMLDocument)#1 (29) {
object(Dom\XMLDocument)#1 (30) {
["xmlEncoding"]=>
string(5) "UTF-8"
["xmlStandalone"]=>
@@ -41,6 +41,8 @@ object(Dom\XMLDocument)#1 (29) {
NULL
["childElementCount"]=>
int(0)
["body"]=>
NULL
["nodeType"]=>
int(9)
["nodeName"]=>

View File

@@ -10,7 +10,7 @@ var_dump($dom);
?>
--EXPECT--
object(Dom\XMLDocument)#1 (29) {
object(Dom\XMLDocument)#1 (30) {
["xmlEncoding"]=>
string(5) "UTF-8"
["xmlStandalone"]=>
@@ -41,6 +41,8 @@ object(Dom\XMLDocument)#1 (29) {
NULL
["childElementCount"]=>
int(0)
["body"]=>
NULL
["nodeType"]=>
int(9)
["nodeName"]=>

View File

@@ -13,7 +13,7 @@ var_dump($element->ownerDocument);
?>
--EXPECTF--
object(Dom\XMLDocument)#1 (29) {
object(Dom\XMLDocument)#1 (30) {
["xmlEncoding"]=>
string(5) "UTF-8"
["xmlStandalone"]=>
@@ -44,6 +44,8 @@ object(Dom\XMLDocument)#1 (29) {
string(22) "(object value omitted)"
["childElementCount"]=>
int(1)
["body"]=>
NULL
["nodeType"]=>
int(9)
["nodeName"]=>