@@ -550,25 +550,45 @@ void dom_child_node_remove(dom_object *context)
550550
551551void dom_child_replace_with (dom_object * context , zval * nodes , int nodesc )
552552{
553+ /* Spec link: https://dom.spec.whatwg.org/#dom-childnode-replacewith */
554+
553555 xmlNodePtr child = dom_object_get_node (context );
556+
557+ /* Spec step 1 */
554558 xmlNodePtr parentNode = child -> parent ;
559+ /* Spec step 2 */
560+ if (!parentNode ) {
561+ int stricterror = dom_get_strict_error (context -> document );
562+ php_dom_throw_error (HIERARCHY_REQUEST_ERR , stricterror );
563+ return ;
564+ }
555565
556566 int stricterror = dom_get_strict_error (context -> document );
557567 if (UNEXPECTED (dom_child_removal_preconditions (child , stricterror ) != SUCCESS )) {
558568 return ;
559569 }
560570
561- xmlNodePtr insertion_point = child -> next ;
571+ /* Spec step 3: find first following child not in nodes; otherwise null */
572+ xmlNodePtr viable_next_sibling = child -> next ;
573+ while (viable_next_sibling ) {
574+ if (!dom_is_node_in_list (nodes , nodesc , viable_next_sibling )) {
575+ break ;
576+ }
577+ viable_next_sibling = viable_next_sibling -> next ;
578+ }
562579
563580 if (UNEXPECTED (dom_sanity_check_node_list_for_insertion (context -> document , parentNode , nodes , nodesc ) != SUCCESS )) {
564581 return ;
565582 }
566583
584+ /* Spec step 4: convert nodes into fragment */
567585 xmlNodePtr fragment = dom_zvals_to_fragment (context -> document , parentNode , nodes , nodesc );
568586 if (UNEXPECTED (fragment == NULL )) {
569587 return ;
570588 }
571589
590+ /* Spec step 5: perform the replacement */
591+
572592 xmlNodePtr newchild = fragment -> children ;
573593 xmlDocPtr doc = parentNode -> doc ;
574594
@@ -580,7 +600,7 @@ void dom_child_replace_with(dom_object *context, zval *nodes, int nodesc)
580600 if (newchild ) {
581601 xmlNodePtr last = fragment -> last ;
582602
583- dom_pre_insert (insertion_point , parentNode , newchild , fragment );
603+ dom_pre_insert (viable_next_sibling , parentNode , newchild , fragment );
584604
585605 dom_fragment_assign_parent_node (parentNode , fragment );
586606 dom_reconcile_ns_list (doc , newchild , last );
0 commit comments