mirror of
https://github.com/php/php-src.git
synced 2025-08-15 13:38:49 +02:00
Introduce Dom\AdjacentPosition and use it in the insert adjacent methods
See https://wiki.php.net/rfc/dom_additions_84#allowing_php-specific_developer_experience_improvements
This commit is contained in:
parent
a068a9a5bb
commit
e4250cec79
7 changed files with 140 additions and 25 deletions
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
43
ext/dom/php_dom_arginfo.h
generated
43
ext/dom/php_dom_arginfo.h
generated
|
@ -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;
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
--TEST--
|
||||
Element::insertAdjacentElement()
|
||||
--EXTENSIONS--
|
||||
dom
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$dom = Dom\XMLDocument::createFromString('<?xml version="1.0"?><container><p>foo</p></container>');
|
||||
$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"
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<container><A/><p>foo</p></container>
|
||||
string(1) "B"
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<container><A/><p><B/>foo</p></container>
|
||||
string(1) "C"
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<container><A/><p><B/>foo<C/></p></container>
|
||||
string(1) "D"
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<container><A/><p><B/>foo<C/></p><D/></container>
|
|
@ -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";
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue