23#if defined(HAVE_LIBXML) && defined(HAVE_DOM)
36 xmlNodePtr first = nodep->children;
55 xmlNodePtr
last = nodep->last;
75 xmlNodePtr first = nodep->children;
77 while (first !=
NULL) {
91static ZEND_COLD void dom_cannot_create_temp_nodes(
void)
96static bool dom_is_node_in_list(
const zval *nodes, uint32_t nodesc,
const xmlNode *node_to_find)
98 for (uint32_t i = 0; i < nodesc; i++) {
109static xmlDocPtr dom_doc_from_context_node(xmlNodePtr contextNode)
112 return (xmlDocPtr) contextNode;
114 return contextNode->doc;
121static void dom_add_child_without_merging(xmlNodePtr parent, xmlNodePtr child)
123 if (parent->children ==
NULL) {
124 parent->children = child;
126 xmlNodePtr
last = parent->last;
130 parent->last = child;
131 child->parent = parent;
134static void dom_fragment_assign_parent_node(xmlNodePtr parentNode, xmlNodePtr fragment)
136 xmlNodePtr node = fragment->children;
138 while (node !=
NULL) {
139 node->parent = parentNode;
141 if (node == fragment->last) {
149static bool dom_fragment_common_hierarchy_check_part(xmlNodePtr node,
bool *seen_element)
152 xmlNodePtr iter = node->children;
153 *seen_element =
false;
154 while (iter !=
NULL) {
160 *seen_element =
true;
175 if (!dom_fragment_common_hierarchy_check_part(node, &seen_element)) {
201 if (!dom_fragment_common_hierarchy_check_part(node, &seen_element)) {
208 xmlNodePtr iter = parent->children;
209 while (iter !=
NULL) {
237static bool dom_is_pre_insert_valid_without_step_1(php_libxml_ref_obj *document, xmlNodePtr parentNode, xmlNodePtr node, xmlNodePtr child, xmlDocPtr documentNode)
248 if (node->doc != documentNode) {
254 if (child !=
NULL && child->parent != parentNode) {
265 || (php_dom_follow_spec_doc_ref(document) && (
271 || node->type >= XML_ELEMENT_DECL))) {
276 if (php_dom_follow_spec_doc_ref(document)) {
284 if (!parent_is_document && node->type ==
XML_DTD_NODE) {
291 if (parent_is_document) {
329static void dom_free_node_after_zval_single_node_creation(xmlNodePtr node)
334 for (xmlNodePtr child = node->children; child !=
NULL; child =
next) {
336 xmlUnlinkNode(child);
337 if (child->_private ==
NULL) {
344xmlNode* dom_zvals_to_single_node(php_libxml_ref_obj *document, xmlNode *contextNode,
zval *nodes, uint32_t nodesc)
346 xmlDoc *documentNode;
350 documentNode = dom_doc_from_context_node(contextNode);
353 xmlNodePtr node =
NULL;
366 dom_cannot_create_temp_nodes();
372 node = xmlNewDocFragment(documentNode);
374 dom_cannot_create_temp_nodes();
380 for (uint32_t i = 0; i < nodesc; i++) {
390 if (!dom_is_pre_insert_valid_without_step_1(document, node, newNode,
NULL, documentNode)) {
394 if (newNode->parent !=
NULL) {
395 xmlUnlinkNode(newNode);
402 newNode = newNode->children;
404 xmlNodePtr
next = newNode->next;
405 xmlUnlinkNode(newNode);
406 dom_add_child_without_merging(node, newNode);
410 dom_add_child_without_merging(node, newNode);
417 newNode = xmlNewDocTextLen(documentNode, BAD_CAST
Z_STRVAL(nodes[i]),
Z_STRLEN(nodes[i]));
419 dom_cannot_create_temp_nodes();
422 dom_add_child_without_merging(node, newNode);
432 dom_free_node_after_zval_single_node_creation(node);
439 for (uint32_t i = 0; i < nodesc; i++) {
444 if (!instanceof_function(ce, node_ce)) {
462static void php_dom_pre_insert_helper(xmlNodePtr insertion_point, xmlNodePtr parentNode, xmlNodePtr newchild, xmlNodePtr
last)
464 if (!insertion_point) {
466 if (parentNode->children) {
468 newchild->prev = parentNode->last;
469 parentNode->last->next = newchild;
472 parentNode->children = newchild;
474 parentNode->last =
last;
477 last->next = insertion_point;
478 if (insertion_point->prev) {
479 insertion_point->prev->next = newchild;
480 newchild->prev = insertion_point->prev;
482 insertion_point->prev =
last;
483 if (parentNode->children == insertion_point) {
484 parentNode->children = newchild;
489static void dom_insert_node_list_cleanup(xmlNodePtr node)
491 if (node->_private !=
NULL) {
496 dom_free_node_after_zval_single_node_creation(node);
508static void dom_insert_node_list_unchecked(php_libxml_ref_obj *document, xmlNodePtr node, xmlNodePtr parent, xmlNodePtr insertion_point)
515 xmlNodePtr newchild = node->children;
519 xmlNodePtr
last = node->last;
520 php_dom_pre_insert_helper(insertion_point, parent, newchild,
last);
521 dom_fragment_assign_parent_node(parent, node);
522 if (!php_dom_follow_spec_doc_ref(document)) {
526 parent->doc->intSubset = (xmlDtdPtr) newchild;
527 newchild->parent = (xmlNodePtr) parent->doc;
531 if (node->_private ==
NULL) {
534 node->children =
NULL;
540 if (insertion_point == node) {
541 insertion_point = node->next;
546 php_dom_pre_insert_helper(insertion_point, parent, node, node);
547 node->parent = parent;
549 parent->doc->intSubset = (xmlDtdPtr) node;
550 node->parent = (xmlNodePtr) parent->doc;
552 if (!php_dom_follow_spec_doc_ref(document)) {
560bool php_dom_pre_insert(php_libxml_ref_obj *document, xmlNodePtr node, xmlNodePtr parent, xmlNodePtr insertion_point)
567 if (dom_is_pre_insert_valid_without_step_1(document, parent, node, insertion_point, parent->doc)) {
568 dom_insert_node_list_unchecked(document, node, parent, insertion_point);
571 dom_insert_node_list_cleanup(node);
585 if (
UNEXPECTED(dom_sanity_check_node_list_types(nodes, nodesc, dom_get_node_ce(php_dom_follow_spec_doc_ref(
context->document))) !=
SUCCESS)) {
591 php_libxml_invalidate_node_list_cache(
context->document);
594 xmlNodePtr node = dom_zvals_to_single_node(
context->document, parentNode, nodes, nodesc);
608 if (parentNode->children ==
NULL) {
613 if (
UNEXPECTED(dom_sanity_check_node_list_types(nodes, nodesc, dom_get_node_ce(php_dom_follow_spec_doc_ref(
context->document))) !=
SUCCESS)) {
617 php_libxml_invalidate_node_list_cache(
context->document);
620 xmlNodePtr node = dom_zvals_to_single_node(
context->document, parentNode, nodes, nodesc);
632 if (
UNEXPECTED(dom_sanity_check_node_list_types(nodes, nodesc, dom_get_node_ce(php_dom_follow_spec_doc_ref(
context->document))) !=
SUCCESS)) {
639 xmlNodePtr parentNode = thisp->parent;
647 xmlNodePtr viable_next_sibling = thisp->next;
648 while (viable_next_sibling && dom_is_node_in_list(nodes, nodesc, viable_next_sibling)) {
649 viable_next_sibling = viable_next_sibling->next;
652 php_libxml_invalidate_node_list_cache(
context->document);
655 xmlNodePtr fragment = dom_zvals_to_single_node(
context->document, parentNode, nodes, nodesc);
664 if (
UNEXPECTED(dom_sanity_check_node_list_types(nodes, nodesc, dom_get_node_ce(php_dom_follow_spec_doc_ref(
context->document))) !=
SUCCESS)) {
671 xmlNodePtr parentNode = thisp->parent;
679 xmlNodePtr viable_previous_sibling = thisp->prev;
680 while (viable_previous_sibling && dom_is_node_in_list(nodes, nodesc, viable_previous_sibling)) {
681 viable_previous_sibling = viable_previous_sibling->prev;
684 php_libxml_invalidate_node_list_cache(
context->document);
687 xmlNodePtr fragment = dom_zvals_to_single_node(
context->document, parentNode, nodes, nodesc);
690 if (!viable_previous_sibling) {
691 viable_previous_sibling = parentNode->children;
693 viable_previous_sibling = viable_previous_sibling->next;
708 if (!child->parent) {
724 php_libxml_invalidate_node_list_cache(
context->document);
726 xmlUnlinkNode(child);
732 if (
UNEXPECTED(dom_sanity_check_node_list_types(nodes, nodesc, dom_get_node_ce(php_dom_follow_spec_doc_ref(
context->document))) !=
SUCCESS)) {
739 xmlNodePtr parentNode = child->parent;
747 xmlNodePtr viable_next_sibling = child->next;
748 while (viable_next_sibling && dom_is_node_in_list(nodes, nodesc, viable_next_sibling)) {
749 viable_next_sibling = viable_next_sibling->next;
756 php_libxml_invalidate_node_list_cache(
context->document);
759 xmlNodePtr node = dom_zvals_to_single_node(
context->document, parentNode, nodes, nodesc);
765 if (dom_is_pre_insert_valid_without_step_1(
context->document, parentNode, node, viable_next_sibling, parentNode->doc)) {
768 if (child->parent != node) {
769 xmlUnlinkNode(child);
772 dom_insert_node_list_unchecked(
context->document, node, parentNode, viable_next_sibling);
774 dom_insert_node_list_cleanup(node);
781 if (
UNEXPECTED(dom_sanity_check_node_list_types(nodes, nodesc, dom_get_node_ce(php_dom_follow_spec_doc_ref(
context->document))) !=
SUCCESS)) {
787 php_libxml_invalidate_node_list_cache(
context->document);
790 xmlNodePtr node = dom_zvals_to_single_node(
context->document, thisp, nodes, nodesc);
796 if (dom_is_pre_insert_valid_without_step_1(
context->document, thisp, node,
NULL, thisp->doc)) {
800 dom_insert_node_list_cleanup(node);
count(Countable|array $value, int $mode=COUNT_NORMAL)
zend_result dom_parent_node_last_element_child_read(dom_object *obj, zval *retval)
#define DOM_PROP_NODE(type, name, obj)
zend_result dom_parent_node_child_element_count(dom_object *obj, zval *retval)
zend_result dom_parent_node_first_element_child_read(dom_object *obj, zval *retval)
void php_dom_throw_error_with_message(dom_exception_code error_code, const char *error_message, bool strict_error)
void php_dom_throw_error(dom_exception_code error_code, bool strict_error)
@ NO_MODIFICATION_ALLOWED_ERR
@ INVALID_MODIFICATION_ERR
void dom_parent_node_after(dom_object *context, zval *nodes, uint32_t nodesc)
void dom_parent_node_replace_children(dom_object *context, zval *nodes, uint32_t nodesc)
bool php_dom_pre_insert_is_parent_invalid(xmlNodePtr parent)
int dom_hierarchy(xmlNodePtr parent, xmlNodePtr child)
bool php_dom_fragment_insertion_hierarchy_check_pre_insertion(xmlNodePtr parent, xmlNodePtr node, xmlNodePtr child)
void php_dom_node_append(php_libxml_ref_obj *document, xmlNodePtr node, xmlNodePtr parent)
void dom_reconcile_ns(xmlDocPtr doc, xmlNodePtr nodep)
bool dom_get_strict_error(php_libxml_ref_obj *document)
void dom_child_replace_with(dom_object *context, zval *nodes, uint32_t nodesc)
bool php_dom_pre_insert(php_libxml_ref_obj *document, xmlNodePtr node, xmlNodePtr parent, xmlNodePtr insertion_point)
void dom_parent_node_before(dom_object *context, zval *nodes, uint32_t nodesc)
bool php_dom_create_nullable_object(xmlNodePtr obj, zval *return_value, dom_object *domobj)
void dom_parent_node_append(dom_object *context, zval *nodes, uint32_t nodesc)
bool php_dom_has_sibling_following_node(xmlNodePtr node, xmlElementType type)
void dom_child_node_remove(dom_object *context)
void dom_parent_node_prepend(dom_object *context, zval *nodes, uint32_t nodesc)
bool php_dom_has_sibling_preceding_node(xmlNodePtr node, xmlElementType type)
bool php_dom_has_child_of_type(xmlNodePtr node, xmlElementType type)
int dom_node_is_read_only(const xmlNode *node)
void dom_reconcile_ns_list(xmlDocPtr doc, xmlNodePtr nodep, xmlNodePtr last)
void dom_remove_all_children(xmlNodePtr nodep)
bool php_dom_fragment_insertion_hierarchy_check_replace(xmlNodePtr parent, xmlNodePtr node, xmlNodePtr child)
const XML_HTML_DOCUMENT_NODE
const XML_CDATA_SECTION_NODE
const XML_DOCUMENT_FRAG_NODE
const XML_ENTITY_REF_NODE
php_libxml_ref_obj * document
PHP_DOM_EXPORT xmlNodePtr dom_object_get_node(dom_object *obj)
struct _dom_object dom_object
ZEND_API const char * zend_zval_type_name(const zval *arg)
ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *format,...)
ZEND_API ZEND_COLD void zend_argument_type_error(uint32_t arg_num, const char *format,...)
#define ZEND_UNREACHABLE()
#define UNEXPECTED(condition)
struct _zend_class_entry zend_class_entry
#define Z_STRVAL_P(zval_p)
#define Z_STRLEN_P(zval_p)
ZEND_RESULT_CODE zend_result