mirror of
https://github.com/php/php-src.git
synced 2024-11-23 18:04:36 +08:00
Fix viable next sibling search for replaceWith
Closes GH-11888.
This commit is contained in:
parent
dddd309da4
commit
815b5ad501
1
NEWS
1
NEWS
@ -20,6 +20,7 @@ PHP NEWS
|
||||
. Fix manually calling __construct() on DOM classes. (nielsdos)
|
||||
. Fixed bug GH-11830 (ParentNode methods should perform their checks
|
||||
upfront). (nielsdos)
|
||||
. Fix viable next sibling search for replaceWith. (nielsdos)
|
||||
|
||||
- FFI:
|
||||
. Fix leaking definitions when using FFI::cdef()->new(...). (ilutov)
|
||||
|
@ -550,25 +550,45 @@ void dom_child_node_remove(dom_object *context)
|
||||
|
||||
void dom_child_replace_with(dom_object *context, zval *nodes, int nodesc)
|
||||
{
|
||||
/* Spec link: https://dom.spec.whatwg.org/#dom-childnode-replacewith */
|
||||
|
||||
xmlNodePtr child = dom_object_get_node(context);
|
||||
|
||||
/* Spec step 1 */
|
||||
xmlNodePtr parentNode = child->parent;
|
||||
/* Spec step 2 */
|
||||
if (!parentNode) {
|
||||
int stricterror = dom_get_strict_error(context->document);
|
||||
php_dom_throw_error(HIERARCHY_REQUEST_ERR, stricterror);
|
||||
return;
|
||||
}
|
||||
|
||||
int stricterror = dom_get_strict_error(context->document);
|
||||
if (UNEXPECTED(dom_child_removal_preconditions(child, stricterror) != SUCCESS)) {
|
||||
return;
|
||||
}
|
||||
|
||||
xmlNodePtr insertion_point = child->next;
|
||||
/* Spec step 3: find first following child not in nodes; otherwise null */
|
||||
xmlNodePtr viable_next_sibling = child->next;
|
||||
while (viable_next_sibling) {
|
||||
if (!dom_is_node_in_list(nodes, nodesc, viable_next_sibling)) {
|
||||
break;
|
||||
}
|
||||
viable_next_sibling = viable_next_sibling->next;
|
||||
}
|
||||
|
||||
if (UNEXPECTED(dom_sanity_check_node_list_for_insertion(context->document, parentNode, nodes, nodesc) != SUCCESS)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Spec step 4: convert nodes into fragment */
|
||||
xmlNodePtr fragment = dom_zvals_to_fragment(context->document, parentNode, nodes, nodesc);
|
||||
if (UNEXPECTED(fragment == NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Spec step 5: perform the replacement */
|
||||
|
||||
xmlNodePtr newchild = fragment->children;
|
||||
xmlDocPtr doc = parentNode->doc;
|
||||
|
||||
@ -580,7 +600,7 @@ void dom_child_replace_with(dom_object *context, zval *nodes, int nodesc)
|
||||
if (newchild) {
|
||||
xmlNodePtr last = fragment->last;
|
||||
|
||||
dom_pre_insert(insertion_point, parentNode, newchild, fragment);
|
||||
dom_pre_insert(viable_next_sibling, parentNode, newchild, fragment);
|
||||
|
||||
dom_fragment_assign_parent_node(parentNode, fragment);
|
||||
dom_reconcile_ns_list(doc, newchild, last);
|
||||
|
36
ext/dom/tests/replaceWith_non_viable_next_sibling.phpt
Normal file
36
ext/dom/tests/replaceWith_non_viable_next_sibling.phpt
Normal file
@ -0,0 +1,36 @@
|
||||
--TEST--
|
||||
replaceWith() with a non-viable next sibling
|
||||
--EXTENSIONS--
|
||||
dom
|
||||
--FILE--
|
||||
<?php
|
||||
$doc = new DOMDocument;
|
||||
$doc->loadXML(<<<XML
|
||||
<?xml version="1.0"?>
|
||||
<container>
|
||||
<child>
|
||||
<alone/>
|
||||
</child>
|
||||
</container>
|
||||
XML);
|
||||
|
||||
$container = $doc->documentElement;
|
||||
$child = $container->firstElementChild;
|
||||
$alone = $child->firstElementChild;
|
||||
|
||||
$child->after($alone);
|
||||
echo $doc->saveXML();
|
||||
$child->replaceWith($alone);
|
||||
echo $doc->saveXML();
|
||||
?>
|
||||
--EXPECT--
|
||||
<?xml version="1.0"?>
|
||||
<container>
|
||||
<child>
|
||||
|
||||
</child><alone/>
|
||||
</container>
|
||||
<?xml version="1.0"?>
|
||||
<container>
|
||||
<alone/>
|
||||
</container>
|
Loading…
Reference in New Issue
Block a user