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";