diff --git a/ext/dom/dom_ce.h b/ext/dom/dom_ce.h index 847688ca909..4dee3430533 100644 --- a/ext/dom/dom_ce.h +++ b/ext/dom/dom_ce.h @@ -66,5 +66,6 @@ extern PHP_DOM_EXPORT zend_class_entry *dom_xpath_class_entry; extern PHP_DOM_EXPORT zend_class_entry *dom_modern_xpath_class_entry; #endif extern PHP_DOM_EXPORT zend_class_entry *dom_namespace_node_class_entry; +extern PHP_DOM_EXPORT zend_class_entry *dom_adjacent_position_class_entry; #endif /* DOM_CE_H */ diff --git a/ext/dom/element.c b/ext/dom/element.c index c20bcb01308..6a9c69d57b8 100644 --- a/ext/dom/element.c +++ b/ext/dom/element.c @@ -21,6 +21,7 @@ #include "php.h" #if defined(HAVE_LIBXML) && defined(HAVE_DOM) +#include "zend_enum.h" #include "php_dom.h" #include "namespace_compat.h" #include "internal_helpers.h" @@ -1573,17 +1574,12 @@ static xmlNodePtr dom_insert_adjacent(const zend_string *where, xmlNodePtr thisp /* {{{ URL: https://dom.spec.whatwg.org/#dom-element-insertadjacentelement Since: */ -static void dom_element_insert_adjacent_element(INTERNAL_FUNCTION_PARAMETERS, zend_class_entry *element_ce) +static void dom_element_insert_adjacent_element(INTERNAL_FUNCTION_PARAMETERS, const zend_string *where, zval *element_zval) { - zend_string *where; - zval *element_zval, *id; + zval *id; xmlNodePtr thisp, otherp; dom_object *this_intern, *other_intern; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "SO", &where, &element_zval, element_ce) != SUCCESS) { - RETURN_THROWS(); - } - DOM_GET_THIS_OBJ(thisp, id, xmlNodePtr, this_intern); DOM_GET_OBJ(otherp, element_zval, xmlNodePtr, other_intern); @@ -1599,29 +1595,39 @@ static void dom_element_insert_adjacent_element(INTERNAL_FUNCTION_PARAMETERS, ze PHP_METHOD(DOMElement, insertAdjacentElement) { - dom_element_insert_adjacent_element(INTERNAL_FUNCTION_PARAM_PASSTHRU, dom_element_class_entry); + zend_string *where; + zval *element_zval; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "SO", &where, &element_zval, dom_element_class_entry) != SUCCESS) { + RETURN_THROWS(); + } + + dom_element_insert_adjacent_element(INTERNAL_FUNCTION_PARAM_PASSTHRU, where, element_zval); } PHP_METHOD(Dom_Element, insertAdjacentElement) { - dom_element_insert_adjacent_element(INTERNAL_FUNCTION_PARAM_PASSTHRU, dom_modern_element_class_entry); + zval *element_zval, *where_zv; + + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_OBJECT_OF_CLASS(where_zv, dom_adjacent_position_class_entry) + Z_PARAM_OBJECT_OF_CLASS(element_zval, dom_modern_element_class_entry) + ZEND_PARSE_PARAMETERS_END(); + + const zend_string *where = Z_STR_P(zend_enum_fetch_case_name(Z_OBJ_P(where_zv))); + dom_element_insert_adjacent_element(INTERNAL_FUNCTION_PARAM_PASSTHRU, where, element_zval); } /* }}} end DOMElement::insertAdjacentElement */ /* {{{ URL: https://dom.spec.whatwg.org/#dom-element-insertadjacenttext Since: */ -PHP_METHOD(DOMElement, insertAdjacentText) +static void dom_element_insert_adjacent_text(INTERNAL_FUNCTION_PARAMETERS, const zend_string *where, const zend_string *data) { - zend_string *where, *data; dom_object *this_intern; zval *id; xmlNodePtr thisp; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "SS", &where, &data) == FAILURE) { - RETURN_THROWS(); - } - DOM_GET_THIS_OBJ(thisp, id, xmlNodePtr, this_intern); if (UNEXPECTED(ZEND_SIZE_T_INT_OVFL(ZSTR_LEN(data)))) { @@ -1635,6 +1641,31 @@ PHP_METHOD(DOMElement, insertAdjacentText) xmlFreeNode(otherp); } } + +PHP_METHOD(DOMElement, insertAdjacentText) +{ + zend_string *where, *data; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "SS", &where, &data) == FAILURE) { + RETURN_THROWS(); + } + + dom_element_insert_adjacent_text(INTERNAL_FUNCTION_PARAM_PASSTHRU, where, data); +} + +PHP_METHOD(Dom_Element, insertAdjacentText) +{ + zval *where_zv; + zend_string *data; + + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_OBJECT_OF_CLASS(where_zv, dom_adjacent_position_class_entry) + Z_PARAM_STR(data) + ZEND_PARSE_PARAMETERS_END(); + + const zend_string *where = Z_STR_P(zend_enum_fetch_case_name(Z_OBJ_P(where_zv))); + dom_element_insert_adjacent_text(INTERNAL_FUNCTION_PARAM_PASSTHRU, where, data); +} /* }}} end DOMElement::insertAdjacentText */ /* {{{ URL: https://dom.spec.whatwg.org/#dom-element-toggleattribute diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c index 3e90db31db7..27ec6839100 100644 --- a/ext/dom/php_dom.c +++ b/ext/dom/php_dom.c @@ -22,6 +22,7 @@ #include "php.h" #if defined(HAVE_LIBXML) && defined(HAVE_DOM) +#include "zend_enum.h" #include "php_dom.h" #include "nodelist.h" #include "html_collection.h" @@ -84,6 +85,7 @@ PHP_DOM_EXPORT zend_class_entry *dom_xpath_class_entry; PHP_DOM_EXPORT zend_class_entry *dom_modern_xpath_class_entry; #endif PHP_DOM_EXPORT zend_class_entry *dom_namespace_node_class_entry; +PHP_DOM_EXPORT zend_class_entry *dom_adjacent_position_class_entry; /* }}} */ static zend_object_handlers dom_object_handlers; @@ -729,6 +731,8 @@ PHP_MINIT_FUNCTION(dom) zend_hash_init(&classes, 0, NULL, NULL, true); + dom_adjacent_position_class_entry = register_class_Dom_AdjacentPosition(); + dom_domexception_class_entry = register_class_DOMException(zend_ce_exception); dom_parentnode_class_entry = register_class_DOMParentNode(); diff --git a/ext/dom/php_dom.stub.php b/ext/dom/php_dom.stub.php index 4f89d54bbed..50fced8c466 100644 --- a/ext/dom/php_dom.stub.php +++ b/ext/dom/php_dom.stub.php @@ -1280,6 +1280,14 @@ namespace Dom public function getIterator(): \Iterator {} } + enum AdjacentPosition : string + { + case BeforeBegin = "beforebegin"; + case AfterBegin = "afterbegin"; + case BeforeEnd = "beforeend"; + case AfterEnd = "afterend"; + } + class Element extends Node implements ParentNode, ChildNode { /** @readonly */ @@ -1330,9 +1338,8 @@ namespace Dom public function getElementsByTagName(string $qualifiedName): HTMLCollection {} public function getElementsByTagNameNS(?string $namespace, string $localName): HTMLCollection {} - public function insertAdjacentElement(string $where, Element $element): ?Element {} - /** @implementation-alias DOMElement::insertAdjacentText */ - public function insertAdjacentText(string $where, string $data): void {} + public function insertAdjacentElement(AdjacentPosition $where, Element $element): ?Element {} + public function insertAdjacentText(AdjacentPosition $where, string $data): void {} /** @readonly */ public ?Element $firstElementChild; diff --git a/ext/dom/php_dom_arginfo.h b/ext/dom/php_dom_arginfo.h index dc78cf42dd0..a9a61a4df79 100644 --- a/ext/dom/php_dom_arginfo.h +++ b/ext/dom/php_dom_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: e75e734f710ab2c18322463f348b95dde4f937b2 */ + * Stub hash: c93643bad9675fddf31ca52f82f843218f208a5d */ 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) @@ -797,11 +797,14 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_Dom_Element_getElementsByTa ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_Dom_Element_insertAdjacentElement, 0, 2, Dom\\Element, 1) - ZEND_ARG_TYPE_INFO(0, where, IS_STRING, 0) + ZEND_ARG_OBJ_INFO(0, where, Dom\\AdjacentPosition, 0) ZEND_ARG_OBJ_INFO(0, element, Dom\\Element, 0) ZEND_END_ARG_INFO() -#define arginfo_class_Dom_Element_insertAdjacentText arginfo_class_DOMElement_insertAdjacentText +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Dom_Element_insertAdjacentText, 0, 2, IS_VOID, 0) + ZEND_ARG_OBJ_INFO(0, where, Dom\\AdjacentPosition, 0) + ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0) +ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Dom_Element_setIdAttribute, 0, 2, IS_VOID, 0) ZEND_ARG_TYPE_INFO(0, qualifiedName, IS_STRING, 0) @@ -1267,6 +1270,7 @@ ZEND_METHOD(Dom_Element, removeAttributeNode); ZEND_METHOD(Dom_Element, getElementsByTagName); ZEND_METHOD(Dom_Element, getElementsByTagNameNS); ZEND_METHOD(Dom_Element, insertAdjacentElement); +ZEND_METHOD(Dom_Element, insertAdjacentText); ZEND_METHOD(Dom_Element, setIdAttributeNode); ZEND_METHOD(Dom_CharacterData, appendData); ZEND_METHOD(Dom_CharacterData, insertData); @@ -1632,6 +1636,10 @@ static const zend_function_entry class_Dom_HTMLCollection_methods[] = { ZEND_FE_END }; +static const zend_function_entry class_Dom_AdjacentPosition_methods[] = { + ZEND_FE_END +}; + static const zend_function_entry class_Dom_Element_methods[] = { ZEND_RAW_FENTRY("hasAttributes", zim_DOMNode_hasAttributes, arginfo_class_Dom_Element_hasAttributes, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_RAW_FENTRY("getAttributeNames", zim_DOMElement_getAttributeNames, arginfo_class_Dom_Element_getAttributeNames, ZEND_ACC_PUBLIC, NULL, NULL) @@ -1652,7 +1660,7 @@ static const zend_function_entry class_Dom_Element_methods[] = { ZEND_ME(Dom_Element, getElementsByTagName, arginfo_class_Dom_Element_getElementsByTagName, ZEND_ACC_PUBLIC) ZEND_ME(Dom_Element, getElementsByTagNameNS, arginfo_class_Dom_Element_getElementsByTagNameNS, ZEND_ACC_PUBLIC) ZEND_ME(Dom_Element, insertAdjacentElement, arginfo_class_Dom_Element_insertAdjacentElement, ZEND_ACC_PUBLIC) - ZEND_RAW_FENTRY("insertAdjacentText", zim_DOMElement_insertAdjacentText, arginfo_class_Dom_Element_insertAdjacentText, ZEND_ACC_PUBLIC, NULL, NULL) + ZEND_ME(Dom_Element, insertAdjacentText, arginfo_class_Dom_Element_insertAdjacentText, ZEND_ACC_PUBLIC) ZEND_RAW_FENTRY("setIdAttribute", zim_DOMElement_setIdAttribute, arginfo_class_Dom_Element_setIdAttribute, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_RAW_FENTRY("setIdAttributeNS", zim_DOMElement_setIdAttributeNS, arginfo_class_Dom_Element_setIdAttributeNS, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_ME(Dom_Element, setIdAttributeNode, arginfo_class_Dom_Element_setIdAttributeNode, ZEND_ACC_PUBLIC) @@ -2957,6 +2965,33 @@ static zend_class_entry *register_class_Dom_HTMLCollection(zend_class_entry *cla return class_entry; } +static zend_class_entry *register_class_Dom_AdjacentPosition(void) +{ + zend_class_entry *class_entry = zend_register_internal_enum("Dom\\AdjacentPosition", IS_STRING, class_Dom_AdjacentPosition_methods); + + zval enum_case_BeforeBegin_value; + zend_string *enum_case_BeforeBegin_value_str = zend_string_init("beforebegin", strlen("beforebegin"), 1); + ZVAL_STR(&enum_case_BeforeBegin_value, enum_case_BeforeBegin_value_str); + zend_enum_add_case_cstr(class_entry, "BeforeBegin", &enum_case_BeforeBegin_value); + + zval enum_case_AfterBegin_value; + zend_string *enum_case_AfterBegin_value_str = zend_string_init("afterbegin", strlen("afterbegin"), 1); + ZVAL_STR(&enum_case_AfterBegin_value, enum_case_AfterBegin_value_str); + zend_enum_add_case_cstr(class_entry, "AfterBegin", &enum_case_AfterBegin_value); + + zval enum_case_BeforeEnd_value; + zend_string *enum_case_BeforeEnd_value_str = zend_string_init("beforeend", strlen("beforeend"), 1); + ZVAL_STR(&enum_case_BeforeEnd_value, enum_case_BeforeEnd_value_str); + zend_enum_add_case_cstr(class_entry, "BeforeEnd", &enum_case_BeforeEnd_value); + + zval enum_case_AfterEnd_value; + zend_string *enum_case_AfterEnd_value_str = zend_string_init("afterend", strlen("afterend"), 1); + ZVAL_STR(&enum_case_AfterEnd_value, enum_case_AfterEnd_value_str); + zend_enum_add_case_cstr(class_entry, "AfterEnd", &enum_case_AfterEnd_value); + + return class_entry; +} + static zend_class_entry *register_class_Dom_Element(zend_class_entry *class_entry_Dom_Node, zend_class_entry *class_entry_Dom_ParentNode, zend_class_entry *class_entry_Dom_ChildNode) { zend_class_entry ce, *class_entry; diff --git a/ext/dom/tests/modern/common/Element_insertAdjacentElement.phpt b/ext/dom/tests/modern/common/Element_insertAdjacentElement.phpt new file mode 100644 index 00000000000..9926cd6d64d --- /dev/null +++ b/ext/dom/tests/modern/common/Element_insertAdjacentElement.phpt @@ -0,0 +1,37 @@ +--TEST-- +Element::insertAdjacentElement() +--EXTENSIONS-- +dom +--FILE-- +

foo

'); +$container = $dom->documentElement; +$p = $container->firstElementChild; + +var_dump($p->insertAdjacentElement(Dom\AdjacentPosition::BeforeBegin, $dom->createElement('A'))->tagName); +echo $dom->saveXML(), "\n"; + +var_dump($p->insertAdjacentElement(Dom\AdjacentPosition::AfterBegin, $dom->createElement('B'))->tagName); +echo $dom->saveXML(), "\n"; + +var_dump($p->insertAdjacentElement(Dom\AdjacentPosition::BeforeEnd, $dom->createElement('C'))->tagName); +echo $dom->saveXML(), "\n"; + +var_dump($p->insertAdjacentElement(Dom\AdjacentPosition::AfterEnd, $dom->createElement('D'))->tagName); +echo $dom->saveXML(), "\n"; + +?> +--EXPECT-- +string(1) "A" + +

foo

+string(1) "B" + +

foo

+string(1) "C" + +

foo

+string(1) "D" + +

foo

diff --git a/ext/dom/tests/modern/spec/Element_insertAdjacentText.phpt b/ext/dom/tests/modern/spec/Element_insertAdjacentText.phpt index 862d1053d8f..ef466817de8 100644 --- a/ext/dom/tests/modern/spec/Element_insertAdjacentText.phpt +++ b/ext/dom/tests/modern/spec/Element_insertAdjacentText.phpt @@ -8,13 +8,13 @@ dom $dom = Dom\HTMLDocument::createEmpty(); $foo = $dom->appendChild($dom->createElement("foo")); try { - $foo->insertAdjacentText("beforebegin", "bar"); + $foo->insertAdjacentText(Dom\AdjacentPosition::BeforeBegin, "bar"); } catch (DOMException $e) { echo $e->getMessage(), "\n"; } -$foo->insertAdjacentText("afterbegin", "bar"); -$foo->insertAdjacentText("beforeend", "baz"); +$foo->insertAdjacentText(Dom\AdjacentPosition::AfterBegin, "bar"); +$foo->insertAdjacentText(Dom\AdjacentPosition::BeforeEnd, "baz"); echo $dom->saveHtml(), "\n";