Skip to content

Implement DOM Living Standard API ("Level 4") #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 26 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
0425f8e
dom: Let DOMElement implement DOM Level 4 DOMParentNode interface
beberlei Mar 3, 2019
aeade27
[dom] Have DOMDocument implement DOMParentNode.
beberlei Mar 3, 2019
5cb019f
[dom] Add DOMParentNode implementation to DOMDocumentFragment. Fix te…
beberlei Mar 3, 2019
f14238e
[dom] Add DOMNode#previousElementSibling and DOMNode#nextElementSibling.
beberlei Mar 3, 2019
f715a89
[dom] DomChildNode#remove interface and DOMElement implementation
beberlei Mar 12, 2019
d73dc24
[dom] fix parameter parsing for DomElement#remove()
beberlei Mar 12, 2019
eb714da
RETURN_NULL as proto is always void.
beberlei Mar 12, 2019
ba7158c
Test: DOM Level4 DOMNode::remove()
ThomasWeinert Mar 12, 2019
c6862c5
Test: DOM Level4 DOMNode::before()
ThomasWeinert Mar 17, 2019
be84c27
Test: DOM Level4 DOMNode::after()
ThomasWeinert Mar 17, 2019
73f90a4
Test: DOM Level4 DOMNode::replaceWith()
ThomasWeinert Mar 17, 2019
f4f1be2
Test: DOM Level4 DOMParentNode::prepend()
ThomasWeinert Mar 17, 2019
8fd82c3
Test: DOM Level4 DOMParentNode::append()
ThomasWeinert Mar 17, 2019
223132f
Add DOMParentNode::append() for DOMElement supporting strings as vari…
beberlei Mar 20, 2019
4819e63
Adopt DoMNode into fragment when passed an object.
beberlei Mar 20, 2019
6bffe98
Refactor converting zval array into dom fragment into function.
beberlei Mar 20, 2019
361eb79
Add DOMElement::prepend.
beberlei Mar 20, 2019
b8f2b41
Refactor dom_zvals_to_fragment to convert all non DOMNode zvals of an…
beberlei Mar 20, 2019
d5ad0f1
Add prepend/append to DOMParentNode interface and add dummy implement…
beberlei Mar 21, 2019
79865f7
Add docs to DOMParentNode methods.
beberlei Mar 22, 2019
6d7dbbf
Add code for DOMDocument+DOMDocumentFragment implementations of appen…
beberlei Mar 22, 2019
69c93b7
Add DOMElement::after() and ::before() stubs.
beberlei Mar 22, 2019
63957fb
Implement DOMElement::after() and DOMElement::before()
beberlei Mar 22, 2019
fddb4a4
Make DOMCharacterData implements DOMChildNode
beberlei Mar 22, 2019
acab4f4
Test: DOM Level4 node adoption and append with attributes
ThomasWeinert Mar 31, 2019
768aefc
Add namespace reconcile support for append/prepend/after/before.
beberlei Apr 7, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions ext/dom/characterdata.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,15 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_characterdata_replace_data, 0, 0, 3)
ZEND_ARG_INFO(0, count)
ZEND_ARG_INFO(0, arg)
ZEND_END_ARG_INFO();

ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_characterdata_remove, 0, 0, 0)
ZEND_END_ARG_INFO();

ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_characterdata_after, 0, 0, 0)
ZEND_END_ARG_INFO();

ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_characterdata_before, 0, 0, 0)
ZEND_END_ARG_INFO();
/* }}} */

/*
Expand All @@ -66,6 +75,9 @@ const zend_function_entry php_dom_characterdata_class_functions[] = {
PHP_FALIAS(insertData, dom_characterdata_insert_data, arginfo_dom_characterdata_insert_data)
PHP_FALIAS(deleteData, dom_characterdata_delete_data, arginfo_dom_characterdata_delete_data)
PHP_FALIAS(replaceData, dom_characterdata_replace_data, arginfo_dom_characterdata_replace_data)
PHP_ME(domcharacterdata, remove, arginfo_dom_characterdata_remove, ZEND_ACC_PUBLIC)
PHP_ME(domcharacterdata, after, arginfo_dom_characterdata_after, ZEND_ACC_PUBLIC)
PHP_ME(domcharacterdata, before, arginfo_dom_characterdata_before, ZEND_ACC_PUBLIC)
PHP_FE_END
};

Expand Down Expand Up @@ -387,4 +399,87 @@ PHP_FUNCTION(dom_characterdata_replace_data)
}
/* }}} end dom_characterdata_replace_data */

PHP_METHOD(domcharacterdata, remove)
{
zval *id;
xmlNodePtr children, child;
dom_object *intern;
int stricterror;

id = ZEND_THIS;
if (zend_parse_parameters_none() == FAILURE) {
return;
}

DOM_GET_OBJ(child, id, xmlNodePtr, intern);

if (dom_node_children_valid(child) == FAILURE) {
RETURN_NULL();
}

stricterror = dom_get_strict_error(intern->document);

if (dom_node_is_read_only(child) == SUCCESS ||
(child->parent != NULL && dom_node_is_read_only(child->parent) == SUCCESS)) {
php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, stricterror);
RETURN_NULL();
}

if (!child->parent) {
php_dom_throw_error(NOT_FOUND_ERR, stricterror);
RETURN_NULL();
}

children = child->parent->children;
if (!children) {
php_dom_throw_error(NOT_FOUND_ERR, stricterror);
RETURN_NULL();
}

while (children) {
if (children == child) {
xmlUnlinkNode(child);
RETURN_NULL();
}
children = children->next;
}

php_dom_throw_error(NOT_FOUND_ERR, stricterror);
RETURN_NULL();
}

PHP_METHOD(domcharacterdata, after)
{
int argc;
zval *args, *id;
dom_object *intern;
xmlNode *context;

if (zend_parse_parameters(ZEND_NUM_ARGS(), "+", &args, &argc) == FAILURE) {
return;
}

id = ZEND_THIS;
DOM_GET_OBJ(context, id, xmlNodePtr, intern);

dom_parent_node_after(intern, args, argc);
}

PHP_METHOD(domcharacterdata, before)
{
int argc;
zval *args, *id;
dom_object *intern;
xmlNode *context;

if (zend_parse_parameters(ZEND_NUM_ARGS(), "+", &args, &argc) == FAILURE) {
return;
}

id = ZEND_THIS;
DOM_GET_OBJ(context, id, xmlNodePtr, intern);

dom_parent_node_before(intern, args, argc);
}

#endif
1 change: 1 addition & 0 deletions ext/dom/config.m4
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ if test "$PHP_DOM" != "no"; then
AC_DEFINE(HAVE_DOM,1,[ ])
PHP_NEW_EXTENSION(dom, [php_dom.c attr.c document.c domerrorhandler.c \
domstringlist.c domexception.c namelist.c \
parentnode.c \
processinginstruction.c cdatasection.c \
documentfragment.c domimplementation.c \
element.c node.c string_extend.c characterdata.c \
Expand Down
1 change: 1 addition & 0 deletions ext/dom/config.w32
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ if (PHP_DOM == "yes") {
) {
EXTENSION("dom", "php_dom.c attr.c document.c domerrorhandler.c \
domstringlist.c domexception.c namelist.c processinginstruction.c \
parentnode.c \
cdatasection.c documentfragment.c domimplementation.c element.c \
node.c string_extend.c characterdata.c documenttype.c \
domimplementationlist.c entity.c nodelist.c text.c comment.c \
Expand Down
56 changes: 56 additions & 0 deletions ext/dom/document.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,12 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_registernodeclass, 0, 0, 2)
ZEND_ARG_INFO(0, baseClass)
ZEND_ARG_INFO(0, extendedClass)
ZEND_END_ARG_INFO();

ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_append, 0, 0, 0)
ZEND_END_ARG_INFO();

ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_prepend, 0, 0, 0)
ZEND_END_ARG_INFO();
/* }}} */

/*
Expand Down Expand Up @@ -230,6 +236,8 @@ const zend_function_entry php_dom_document_class_functions[] = { /* {{{ */
PHP_FALIAS(relaxNGValidateSource, dom_document_relaxNG_validate_xml, arginfo_dom_document_relaxNG_validate_xml)
#endif
PHP_ME(domdocument, registerNodeClass, arginfo_dom_document_registernodeclass, ZEND_ACC_PUBLIC)
PHP_ME(domdocument, append, arginfo_dom_document_append, ZEND_ACC_PUBLIC)
PHP_ME(domdocument, prepend, arginfo_dom_document_prepend, ZEND_ACC_PUBLIC)
PHP_FE_END
};
/* }}} */
Expand Down Expand Up @@ -2272,4 +2280,52 @@ PHP_METHOD(domdocument, registerNodeClass)
}
/* }}} */

/* {{{ proto void domdocument::append(string|DOMNode ...$nodes)
URL: https://dom.spec.whatwg.org/#dom-parentnode-append
Since: DOM Living Standard (DOM4)
*/
PHP_METHOD(domdocument, append)
{
int argc;
zval *args, *id;
dom_object *intern;
xmlNode *context;

if (zend_parse_parameters(ZEND_NUM_ARGS(), "+", &args, &argc) == FAILURE) {
return;
}

id = ZEND_THIS;
DOM_GET_OBJ(context, id, xmlNodePtr, intern);

dom_parent_node_append(intern, args, argc);
}
/* }}} */

/* {{{ proto void domdocument::prepend(string|DOMNode ...$nodes)
URL: https://dom.spec.whatwg.org/#dom-parentnode-prepend
Since: DOM Living Standard (DOM4)
*/
PHP_METHOD(domdocument, prepend)
{
int argc;
zval *args, *id;
dom_object *intern;
xmlNode *context;

if (zend_parse_parameters(ZEND_NUM_ARGS(), "+", &args, &argc) == FAILURE) {
return;
}

id = ZEND_THIS;
DOM_GET_OBJ(context, id, xmlNodePtr, intern);

if (context->children == NULL) {
dom_parent_node_append(intern, args, argc);
} else {
dom_parent_node_prepend(intern, args, argc);
}
}
/* }}} */

#endif /* HAVE_LIBXML && HAVE_DOM */
56 changes: 56 additions & 0 deletions ext/dom/documentfragment.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ ZEND_END_ARG_INFO();
ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_documentfragement_appendXML, 0, 0, 1)
ZEND_ARG_INFO(0, data)
ZEND_END_ARG_INFO();

ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_documentfragment_append, 0, 0, 0)
ZEND_END_ARG_INFO();

ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_documentfragment_prepend, 0, 0, 0)
ZEND_END_ARG_INFO();
/* }}} */

/*
Expand All @@ -44,6 +50,8 @@ ZEND_END_ARG_INFO();
const zend_function_entry php_dom_documentfragment_class_functions[] = {
PHP_ME(domdocumentfragment, __construct, arginfo_dom_documentfragement_construct, ZEND_ACC_PUBLIC)
PHP_ME(domdocumentfragment, appendXML, arginfo_dom_documentfragement_appendXML, ZEND_ACC_PUBLIC)
PHP_ME(domdocumentfragment, append, arginfo_dom_documentfragment_append, ZEND_ACC_PUBLIC)
PHP_ME(domdocumentfragment, prepend, arginfo_dom_documentfragment_prepend, ZEND_ACC_PUBLIC)
PHP_FE_END
};

Expand Down Expand Up @@ -147,4 +155,52 @@ PHP_METHOD(domdocumentfragment, appendXML) {
}
/* }}} */

/* {{{ proto void domdocumentfragment::append(string|DOMNode ...$nodes)
URL: https://dom.spec.whatwg.org/#dom-parentnode-append
Since: DOM Living Standard (DOM4)
*/
PHP_METHOD(domdocumentfragment, append)
{
int argc;
zval *args, *id;
dom_object *intern;
xmlNode *context;

if (zend_parse_parameters(ZEND_NUM_ARGS(), "+", &args, &argc) == FAILURE) {
return;
}

id = ZEND_THIS;
DOM_GET_OBJ(context, id, xmlNodePtr, intern);

dom_parent_node_append(intern, args, argc);
}
/* }}} */

/* {{{ proto void domdocumentfragment::prepend(string|DOMNode ...$nodes)
URL: https://dom.spec.whatwg.org/#dom-parentnode-prepend
Since: DOM Living Standard (DOM4)
*/
PHP_METHOD(domdocumentfragment, prepend)
{
int argc;
zval *args, *id;
dom_object *intern;
xmlNode *context;

if (zend_parse_parameters(ZEND_NUM_ARGS(), "+", &args, &argc) == FAILURE) {
return;
}

id = ZEND_THIS;
DOM_GET_OBJ(context, id, xmlNodePtr, intern);

if (context->children == NULL) {
dom_parent_node_append(intern, args, argc);
} else {
dom_parent_node_prepend(intern, args, argc);
}
}
/* }}} */

#endif
14 changes: 14 additions & 0 deletions ext/dom/dom_fe.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
extern const zend_function_entry php_dom_domexception_class_functions[];
extern const zend_function_entry php_dom_domstringlist_class_functions[];
extern const zend_function_entry php_dom_namelist_class_functions[];
extern const zend_function_entry php_dom_parent_node_class_functions[];
extern const zend_function_entry php_dom_child_node_class_functions[];
extern const zend_function_entry php_dom_domimplementationlist_class_functions[];
extern const zend_function_entry php_dom_domimplementationsource_class_functions[];
extern const zend_function_entry php_dom_domimplementation_class_functions[];
Expand Down Expand Up @@ -102,6 +104,8 @@ PHP_METHOD(domimplementation, getFeature);
/* domdocumentfragment methods */
PHP_METHOD(domdocumentfragment, __construct);
PHP_METHOD(domdocumentfragment, appendXML);
PHP_METHOD(domdocumentfragment, append);
PHP_METHOD(domdocumentfragment, prepend);

/* domdocument methods */
PHP_FUNCTION(dom_document_create_element);
Expand Down Expand Up @@ -130,6 +134,8 @@ PHP_FUNCTION(dom_document_savexml);
PHP_FUNCTION(dom_document_validate);
PHP_FUNCTION(dom_document_xinclude);
PHP_METHOD(domdocument, registerNodeClass);
PHP_METHOD(domdocument, append);
PHP_METHOD(domdocument, prepend);

#if defined(LIBXML_HTML_ENABLED)
PHP_METHOD(domdocument, loadHTML);
Expand Down Expand Up @@ -189,6 +195,9 @@ PHP_FUNCTION(dom_characterdata_append_data);
PHP_FUNCTION(dom_characterdata_insert_data);
PHP_FUNCTION(dom_characterdata_delete_data);
PHP_FUNCTION(dom_characterdata_replace_data);
PHP_METHOD(domcharacterdata, remove);
PHP_METHOD(domcharacterdata, after);
PHP_METHOD(domcharacterdata, before);

/* domattr methods */
PHP_FUNCTION(dom_attr_is_id);
Expand All @@ -214,6 +223,11 @@ PHP_FUNCTION(dom_element_set_id_attribute);
PHP_FUNCTION(dom_element_set_id_attribute_ns);
PHP_FUNCTION(dom_element_set_id_attribute_node);
PHP_METHOD(domelement, __construct);
PHP_METHOD(domelement, remove);
PHP_METHOD(domelement, after);
PHP_METHOD(domelement, before);
PHP_METHOD(domelement, append);
PHP_METHOD(domelement, prepend);

/* domtext methods */
PHP_FUNCTION(dom_text_split_text);
Expand Down
7 changes: 7 additions & 0 deletions ext/dom/dom_properties.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,11 @@ int dom_namednodemap_length_read(dom_object *obj, zval *retval);
/* namelist properties */
int dom_namelist_length_read(dom_object *obj, zval *retval);

/* parent node properties */
int dom_parent_node_first_element_child_read(dom_object *obj, zval *retval);
int dom_parent_node_last_element_child_read(dom_object *obj, zval *retval);
int dom_parent_node_child_element_count(dom_object *obj, zval *retval);

/* node properties */
int dom_node_node_name_read(dom_object *obj, zval *retval);
int dom_node_node_value_read(dom_object *obj, zval *retval);
Expand All @@ -124,6 +129,8 @@ int dom_node_first_child_read(dom_object *obj, zval *retval);
int dom_node_last_child_read(dom_object *obj, zval *retval);
int dom_node_previous_sibling_read(dom_object *obj, zval *retval);
int dom_node_next_sibling_read(dom_object *obj, zval *retval);
int dom_node_previous_element_sibling_read(dom_object *obj, zval *retval);
int dom_node_next_element_sibling_read(dom_object *obj, zval *retval);
int dom_node_attributes_read(dom_object *obj, zval *retval);
int dom_node_owner_document_read(dom_object *obj, zval *retval);
int dom_node_namespace_uri_read(dom_object *obj, zval *retval);
Expand Down
Loading