Skip to content

Commit 44fb384

Browse files
committed
Fix parent check and viable next sibling search for replaceWith
1 parent bbf29b7 commit 44fb384

File tree

1 file changed

+20
-2
lines changed

1 file changed

+20
-2
lines changed

ext/dom/parentnode.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -545,21 +545,39 @@ void dom_child_node_remove(dom_object *context)
545545

546546
void dom_child_replace_with(dom_object *context, zval *nodes, int nodesc)
547547
{
548+
/* Spec link: https://dom.spec.whatwg.org/#dom-childnode-replacewith*/
549+
548550
xmlNodePtr child = dom_object_get_node(context);
551+
552+
/* Spec step 1 */
549553
xmlNodePtr parentNode = child->parent;
554+
/* Spec step 2 */
555+
if (!parentNode) {
556+
return;
557+
}
550558

551559
int stricterror = dom_get_strict_error(context->document);
552560
if (UNEXPECTED(dom_child_removal_preconditions(child, stricterror) != SUCCESS)) {
553561
return;
554562
}
555563

556-
xmlNodePtr insertion_point = child->next;
564+
/* Spec step 3: find first following child not in nodes; otherwise null */
565+
xmlNodePtr viable_next_sibling = child->next;
566+
while (viable_next_sibling) {
567+
if (!dom_is_node_in_list(nodes, nodesc, viable_next_sibling)) {
568+
break;
569+
}
570+
viable_next_sibling = viable_next_sibling->next;
571+
}
557572

573+
/* Spec step 4: convert nodes into fragment */
558574
xmlNodePtr fragment = dom_zvals_to_fragment(context->document, parentNode, nodes, nodesc);
559575
if (UNEXPECTED(fragment == NULL)) {
560576
return;
561577
}
562578

579+
/* Spec step 5: perform the replacement */
580+
563581
xmlNodePtr newchild = fragment->children;
564582
xmlDocPtr doc = parentNode->doc;
565583

@@ -571,7 +589,7 @@ void dom_child_replace_with(dom_object *context, zval *nodes, int nodesc)
571589
if (newchild) {
572590
xmlNodePtr last = fragment->last;
573591

574-
dom_pre_insert(insertion_point, parentNode, newchild, fragment);
592+
dom_pre_insert(viable_next_sibling, parentNode, newchild, fragment);
575593

576594
dom_fragment_assign_parent_node(parentNode, fragment);
577595
dom_reconcile_ns_list(doc, newchild, last);

0 commit comments

Comments
 (0)