@@ -547,27 +547,47 @@ void dom_child_node_remove(dom_object *context)
547
547
548
548
void dom_child_replace_with (dom_object * context , zval * nodes , uint32_t nodesc )
549
549
{
550
+ /* Spec link: https://dom.spec.whatwg.org/#dom-childnode-replacewith */
551
+
550
552
xmlNodePtr child = dom_object_get_node (context );
553
+
554
+ /* Spec step 1 */
551
555
xmlNodePtr parentNode = child -> parent ;
556
+ /* Spec step 2 */
557
+ if (!parentNode ) {
558
+ int stricterror = dom_get_strict_error (context -> document );
559
+ php_dom_throw_error (HIERARCHY_REQUEST_ERR , stricterror );
560
+ return ;
561
+ }
552
562
553
563
int stricterror = dom_get_strict_error (context -> document );
554
564
if (UNEXPECTED (dom_child_removal_preconditions (child , stricterror ) != SUCCESS )) {
555
565
return ;
556
566
}
557
567
558
- php_libxml_invalidate_node_list_cache_from_doc (context -> document -> ptr );
559
-
560
- xmlNodePtr insertion_point = child -> next ;
568
+ /* Spec step 3: find first following child not in nodes; otherwise null */
569
+ xmlNodePtr viable_next_sibling = child -> next ;
570
+ while (viable_next_sibling ) {
571
+ if (!dom_is_node_in_list (nodes , nodesc , viable_next_sibling )) {
572
+ break ;
573
+ }
574
+ viable_next_sibling = viable_next_sibling -> next ;
575
+ }
561
576
562
577
if (UNEXPECTED (dom_sanity_check_node_list_for_insertion (context -> document , parentNode , nodes , nodesc ) != SUCCESS )) {
563
578
return ;
564
579
}
565
580
581
+ php_libxml_invalidate_node_list_cache_from_doc (context -> document -> ptr );
582
+
583
+ /* Spec step 4: convert nodes into fragment */
566
584
xmlNodePtr fragment = dom_zvals_to_fragment (context -> document , parentNode , nodes , nodesc );
567
585
if (UNEXPECTED (fragment == NULL )) {
568
586
return ;
569
587
}
570
588
589
+ /* Spec step 5: perform the replacement */
590
+
571
591
xmlNodePtr newchild = fragment -> children ;
572
592
xmlDocPtr doc = parentNode -> doc ;
573
593
@@ -580,7 +600,7 @@ void dom_child_replace_with(dom_object *context, zval *nodes, uint32_t 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