Skip to content

Commit

Permalink
Introduce Dom\AdjacentPosition and use it in the insert adjacent methods
Browse files Browse the repository at this point in the history
  • Loading branch information
nielsdos committed Jun 24, 2024
1 parent a068a9a commit e4250ce
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 25 deletions.
1 change: 1 addition & 0 deletions ext/dom/dom_ce.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
61 changes: 46 additions & 15 deletions ext/dom/element.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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);

Expand All @@ -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)))) {
Expand All @@ -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
Expand Down
4 changes: 4 additions & 0 deletions ext/dom/php_dom.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand Down
13 changes: 10 additions & 3 deletions ext/dom/php_dom.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -1280,6 +1280,14 @@ public function count(): int {}
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 */
Expand Down Expand Up @@ -1330,9 +1338,8 @@ public function removeAttributeNode(Attr $attr) : Attr {}
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;
Expand Down
43 changes: 39 additions & 4 deletions ext/dom/php_dom_arginfo.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

37 changes: 37 additions & 0 deletions ext/dom/tests/modern/common/Element_insertAdjacentElement.phpt
Original file line number Diff line number Diff line change
@@ -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>
6 changes: 3 additions & 3 deletions ext/dom/tests/modern/spec/Element_insertAdjacentText.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down

0 comments on commit e4250ce

Please sign in to comment.