@@ -550,25 +550,45 @@ void dom_child_node_remove(dom_object *context)
550
550
551
551
void dom_child_replace_with (dom_object * context , zval * nodes , int nodesc )
552
552
{
553
+ /* Spec link: https://dom.spec.whatwg.org/#dom-childnode-replacewith */
554
+
553
555
xmlNodePtr child = dom_object_get_node (context );
556
+
557
+ /* Spec step 1 */
554
558
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
+ }
555
565
556
566
int stricterror = dom_get_strict_error (context -> document );
557
567
if (UNEXPECTED (dom_child_removal_preconditions (child , stricterror ) != SUCCESS )) {
558
568
return ;
559
569
}
560
570
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
+ }
562
579
563
580
if (UNEXPECTED (dom_sanity_check_node_list_for_insertion (context -> document , parentNode , nodes , nodesc ) != SUCCESS )) {
564
581
return ;
565
582
}
566
583
584
+ /* Spec step 4: convert nodes into fragment */
567
585
xmlNodePtr fragment = dom_zvals_to_fragment (context -> document , parentNode , nodes , nodesc );
568
586
if (UNEXPECTED (fragment == NULL )) {
569
587
return ;
570
588
}
571
589
590
+ /* Spec step 5: perform the replacement */
591
+
572
592
xmlNodePtr newchild = fragment -> children ;
573
593
xmlDocPtr doc = parentNode -> doc ;
574
594
@@ -580,7 +600,7 @@ void dom_child_replace_with(dom_object *context, zval *nodes, int nodesc)
580
600
if (newchild ) {
581
601
xmlNodePtr last = fragment -> last ;
582
602
583
- dom_pre_insert (insertion_point , parentNode , newchild , fragment );
603
+ dom_pre_insert (viable_next_sibling , parentNode , newchild , fragment );
584
604
585
605
dom_fragment_assign_parent_node (parentNode , fragment );
586
606
dom_reconcile_ns_list (doc , newchild , last );
0 commit comments