Skip to content

Commit d708ff3

Browse files
committed
moveBefore() implementation fixed (mostly)
1 parent 5942b89 commit d708ff3

File tree

3 files changed

+899
-11
lines changed

3 files changed

+899
-11
lines changed

src/main/java/org/htmlunit/html/DomNode.java

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1170,7 +1170,7 @@ else if (previousSibling_ != null && previousSibling_.nextSibling_ == this) {
11701170
if (nextSibling_ != null && nextSibling_.previousSibling_ == this) {
11711171
nextSibling_.previousSibling_ = previousSibling_;
11721172
}
1173-
if (parent_ != null && this == parent_.getLastChild()) {
1173+
if (parent_ != null && parent_.getLastChild() == this) {
11741174
parent_.firstChild_.previousSibling_ = previousSibling_;
11751175
}
11761176

@@ -1330,8 +1330,16 @@ public void moveBefore(final DomNode movedDomNode, final DomNode referenceDomNod
13301330
return;
13311331
}
13321332

1333+
if (movedDomNode instanceof DomDocumentFragment) {
1334+
final DomDocumentFragment fragment = (DomDocumentFragment) movedDomNode;
1335+
for (final DomNode child : fragment.getChildren()) {
1336+
moveBefore(child, referenceDomNode);
1337+
}
1338+
return;
1339+
}
1340+
13331341
// If moving to the same position (node is already right before referenceNode), no operation needed
1334-
if (movedDomNode.getNextSibling() == referenceDomNode) {
1342+
if (referenceDomNode != null && movedDomNode.getNextSibling() == referenceDomNode) {
13351343
return;
13361344
}
13371345

@@ -1350,18 +1358,46 @@ public void moveBefore(final DomNode movedDomNode, final DomNode referenceDomNod
13501358
"State-preserving atomic move cannot be performed on nodes participating in an invalid hierarchy.");
13511359
}
13521360

1353-
// Remove the node from its current position
1354-
movedDomNode.basicRemove();
1355-
1356-
// Insert at the new position
13571361
if (referenceDomNode == null) {
1358-
// Move to the end
1359-
basicAppend(movedDomNode);
1362+
appendChild(movedDomNode);
1363+
return;
13601364
}
1361-
else {
1362-
// Insert before the reference node
1363-
referenceDomNode.basicInsertBefore(movedDomNode);
1365+
1366+
referenceDomNode.moveBefore(movedDomNode);
1367+
}
1368+
1369+
/**
1370+
* Inserts the specified node as a new child node before this node into the child relationship this node is a
1371+
* part of. If the specified node is this node, this method is a no-op.
1372+
*
1373+
* @param movedDomNode the node to move before the current node
1374+
*/
1375+
public void moveBefore(final DomNode movedDomNode) {
1376+
if (previousSibling_ == null) {
1377+
throw new IllegalStateException("Previous sibling for " + this + " is null.");
1378+
}
1379+
1380+
if (movedDomNode == this) {
1381+
return;
13641382
}
1383+
1384+
// remove movedDomNode from tree (detach() does too mutch)
1385+
if (movedDomNode.parent_ != null && movedDomNode.parent_.firstChild_ == movedDomNode) {
1386+
movedDomNode.parent_.firstChild_ = movedDomNode.nextSibling_;
1387+
}
1388+
else if (movedDomNode.previousSibling_ != null && movedDomNode.previousSibling_.nextSibling_ == movedDomNode) {
1389+
movedDomNode.previousSibling_.nextSibling_ = movedDomNode.nextSibling_;
1390+
}
1391+
if (movedDomNode.nextSibling_ != null && movedDomNode.nextSibling_.previousSibling_ == movedDomNode) {
1392+
movedDomNode.nextSibling_.previousSibling_ = movedDomNode.previousSibling_;
1393+
}
1394+
if (movedDomNode.parent_ != null && movedDomNode.parent_.getLastChild() == movedDomNode) {
1395+
movedDomNode.parent_.firstChild_.previousSibling_ = movedDomNode.previousSibling_;
1396+
}
1397+
1398+
basicInsertBefore(movedDomNode);
1399+
1400+
fireAddition(movedDomNode);
13651401
}
13661402

13671403
/**

0 commit comments

Comments
 (0)