Skip to content

Commit 5942b89

Browse files
committed
moveBefore() simplified and the implementation moved to the correct place
1 parent 6cca44f commit 5942b89

File tree

6 files changed

+113
-67
lines changed

6 files changed

+113
-67
lines changed

src/main/java/org/htmlunit/javascript/host/Element.java

Lines changed: 1 addition & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -838,47 +838,7 @@ public void insertAdjacentHTML(final String position, final String text) {
838838
@JsxFunction({CHROME, EDGE, FF})
839839
public static void moveBefore(final Context context, final Scriptable scope,
840840
final Scriptable thisObj, final Object[] args, final Function function) {
841-
((HTMLElement) thisObj).moveBeforeImpl(args);
842-
}
843-
844-
/**
845-
* Add a DOM node as a child to this node before the referenced node.
846-
* If the referenced node is null, append to the end.
847-
* @param args the arguments
848-
* @throws DOMException in case of problems
849-
*/
850-
protected void moveBeforeImpl(final Object[] args) throws org.w3c.dom.DOMException {
851-
if (args.length < 2) {
852-
throw JavaScriptEngine.typeError(
853-
"Failed to execute 'moveBefore' on 'Element': 2 arguments required, but only 0 present.");
854-
}
855-
856-
final Object movedNodeObject = args[0];
857-
if (!(movedNodeObject instanceof Node)) {
858-
throw JavaScriptEngine.typeError(
859-
"Failed to execute 'moveBefore' on 'Element': parameter 1 is not of type 'Node'.");
860-
}
861-
final Object referenceNodeObject = args[1];
862-
if (referenceNodeObject != null && !(referenceNodeObject instanceof Node)) {
863-
throw JavaScriptEngine.typeError(
864-
"Failed to execute 'moveBefore' on 'Element': parameter 2 is not of type 'Node'.");
865-
}
866-
867-
try {
868-
if (referenceNodeObject == null) {
869-
getDomNodeOrDie().moveBefore(((Node) movedNodeObject).getDomNodeOrDie(), null);
870-
return;
871-
}
872-
873-
getDomNodeOrDie().moveBefore(
874-
((Node) movedNodeObject).getDomNodeOrDie(), ((Node) referenceNodeObject).getDomNodeOrDie());
875-
}
876-
catch (final org.w3c.dom.DOMException e) {
877-
throw JavaScriptEngine.asJavaScriptException(
878-
getWindow(),
879-
"Failed to execute 'moveChild' on '" + this + ": " + e.getMessage(),
880-
e.code);
881-
}
841+
Node.moveBefore(context, scope, thisObj, args, function);
882842
}
883843

884844
/**

src/main/java/org/htmlunit/javascript/host/dom/DocumentFragment.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414
*/
1515
package org.htmlunit.javascript.host.dom;
1616

17+
import static org.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
18+
import static org.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
19+
import static org.htmlunit.javascript.configuration.SupportedBrowser.FF;
20+
1721
import org.htmlunit.corejs.javascript.Context;
1822
import org.htmlunit.corejs.javascript.Function;
1923
import org.htmlunit.corejs.javascript.Scriptable;
@@ -101,6 +105,21 @@ public static void replaceChildren(final Context context, final Scriptable scope
101105
Node.replaceChildren(context, thisObj, args, function);
102106
}
103107

108+
/**
109+
* Moves a given Node inside the invoking node as a direct child, before a given reference node.
110+
*
111+
* @param context the JavaScript context
112+
* @param scope the scope
113+
* @param thisObj the scriptable
114+
* @param args the arguments passed into the method
115+
* @param function the function
116+
*/
117+
@JsxFunction({CHROME, EDGE, FF})
118+
public static void moveBefore(final Context context, final Scriptable scope,
119+
final Scriptable thisObj, final Object[] args, final Function function) {
120+
Node.moveBefore(context, scope, thisObj, args, function);
121+
}
122+
104123
/**
105124
* Retrieves all element nodes from descendants of the starting element node that match any selector
106125
* within the supplied selector strings.

src/main/java/org/htmlunit/javascript/host/dom/Node.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,51 @@ public Node replaceChild(final Object newChildObject, final Object oldChildObjec
471471
return null;
472472
}
473473

474+
/**
475+
* Moves a given Node inside the invoking node as a direct child, before a given reference node.
476+
*
477+
* @param context the JavaScript context
478+
* @param scope the scope
479+
* @param thisObj the scriptable
480+
* @param args the arguments passed into the method
481+
* @param function the function
482+
*/
483+
public static void moveBefore(final Context context, final Scriptable scope,
484+
final Scriptable thisObj, final Object[] args, final Function function) {
485+
if (args.length < 2) {
486+
throw JavaScriptEngine.typeError(
487+
"Failed to execute 'moveBefore' on 'Element': 2 arguments required, but only 0 present.");
488+
}
489+
490+
final Object movedNodeObject = args[0];
491+
if (!(movedNodeObject instanceof Node)) {
492+
throw JavaScriptEngine.typeError(
493+
"Failed to execute 'moveBefore' on 'Element': parameter 1 is not of type 'Node'.");
494+
}
495+
final Object referenceNodeObject = args[1];
496+
if (referenceNodeObject != null && !(referenceNodeObject instanceof Node)) {
497+
throw JavaScriptEngine.typeError(
498+
"Failed to execute 'moveBefore' on 'Element': parameter 2 is not of type 'Node'.");
499+
}
500+
501+
final Node node = (Node) thisObj;
502+
try {
503+
if (referenceNodeObject == null) {
504+
node.getDomNodeOrDie().moveBefore(((Node) movedNodeObject).getDomNodeOrDie(), null);
505+
return;
506+
}
507+
508+
node.getDomNodeOrDie().moveBefore(
509+
((Node) movedNodeObject).getDomNodeOrDie(), ((Node) referenceNodeObject).getDomNodeOrDie());
510+
}
511+
catch (final org.w3c.dom.DOMException e) {
512+
throw JavaScriptEngine.asJavaScriptException(
513+
node.getWindow(),
514+
"Failed to execute 'moveChild' on '" + node + ": " + e.getMessage(),
515+
e.code);
516+
}
517+
}
518+
474519
/**
475520
* Clones this node.
476521
* @param deep if {@code true}, recursively clones all descendants

src/main/java/org/htmlunit/javascript/host/html/HTMLDocument.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
package org.htmlunit.javascript.host.html;
1616

1717
import static org.htmlunit.BrowserVersionFeatures.HTMLDOCUMENT_ELEMENTS_BY_NAME_EMPTY;
18+
import static org.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
19+
import static org.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
1820
import static org.htmlunit.javascript.configuration.SupportedBrowser.FF;
1921
import static org.htmlunit.javascript.configuration.SupportedBrowser.FF_ESR;
2022

@@ -160,6 +162,21 @@ private static String concatArgsAsString(final Object[] args) {
160162
return builder.toString();
161163
}
162164

165+
/**
166+
* Moves a given Node inside the invoking node as a direct child, before a given reference node.
167+
*
168+
* @param context the JavaScript context
169+
* @param scope the scope
170+
* @param thisObj the scriptable
171+
* @param args the arguments passed into the method
172+
* @param function the function
173+
*/
174+
@JsxFunction({CHROME, EDGE, FF})
175+
public static void moveBefore(final Context context, final Scriptable scope,
176+
final Scriptable thisObj, final Object[] args, final Function function) {
177+
Node.moveBefore(context, scope, thisObj, args, function);
178+
}
179+
163180
/**
164181
* JavaScript function "writeln" may accept a variable number of arguments.
165182
* @param context the JavaScript context

src/test/java/org/htmlunit/general/ElementOwnPropertiesTest.java

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,8 @@ public void htmlElement() throws Exception {
629629
+ "getAttributeNodeNS(),getAttributeNS(),getBoundingClientRect(),getClientRects(),"
630630
+ "getElementsByClassName(),getElementsByTagName(),getElementsByTagNameNS(),getHTML(),"
631631
+ "hasAttribute(),hasAttributeNS(),hasAttributes(),id[GSCE],innerHTML[GSCE],insertAdjacentElement(),"
632-
+ "insertAdjacentHTML(),insertAdjacentText(),lastElementChild[GCE],localName[GCE],matches(),"
632+
+ "insertAdjacentHTML(),insertAdjacentText(),lastElementChild[GCE],localName[GCE],"
633+
+ "matches(),moveBefore(),"
633634
+ "namespaceURI[GCE],nextElementSibling[GCE],onbeforecopy[GSCE],onbeforecut[GSCE],onbeforepaste[GSCE],"
634635
+ "onsearch[GSCE],onwebkitfullscreenchange[GSCE],onwebkitfullscreenerror[GSCE],outerHTML[GSCE],"
635636
+ "prefix[GCE],prepend(),previousElementSibling[GCE],querySelector(),querySelectorAll(),remove(),"
@@ -644,7 +645,8 @@ public void htmlElement() throws Exception {
644645
+ "getAttributeNodeNS(),getAttributeNS(),getBoundingClientRect(),getClientRects(),"
645646
+ "getElementsByClassName(),getElementsByTagName(),getElementsByTagNameNS(),getHTML(),"
646647
+ "hasAttribute(),hasAttributeNS(),hasAttributes(),id[GSCE],innerHTML[GSCE],insertAdjacentElement(),"
647-
+ "insertAdjacentHTML(),insertAdjacentText(),lastElementChild[GCE],localName[GCE],matches(),"
648+
+ "insertAdjacentHTML(),insertAdjacentText(),lastElementChild[GCE],localName[GCE],"
649+
+ "matches(),moveBefore(),"
648650
+ "namespaceURI[GCE],nextElementSibling[GCE],onbeforecopy[GSCE],onbeforecut[GSCE],onbeforepaste[GSCE],"
649651
+ "onsearch[GSCE],onwebkitfullscreenchange[GSCE],onwebkitfullscreenerror[GSCE],outerHTML[GSCE],"
650652
+ "prefix[GCE],prepend(),previousElementSibling[GCE],querySelector(),querySelectorAll(),remove(),"
@@ -660,7 +662,8 @@ public void htmlElement() throws Exception {
660662
+ "getElementsByTagName(),getElementsByTagNameNS(),"
661663
+ "getHTML(),hasAttribute(),hasAttributeNS(),hasAttributes(),"
662664
+ "id[GSCE],innerHTML[GSCE],insertAdjacentElement(),insertAdjacentHTML(),insertAdjacentText(),"
663-
+ "lastElementChild[GCE],localName[GCE],matches(),mozMatchesSelector(),namespaceURI[GCE],"
665+
+ "lastElementChild[GCE],localName[GCE],matches(),moveBefore(),"
666+
+ "mozMatchesSelector(),namespaceURI[GCE],"
664667
+ "nextElementSibling[GCE],outerHTML[GSCE],prefix[GCE],prepend(),previousElementSibling[GCE],"
665668
+ "querySelector(),querySelectorAll(),releaseCapture(),remove(),removeAttribute(),"
666669
+ "removeAttributeNode(),removeAttributeNS(),replaceChildren(),replaceWith(),"
@@ -827,7 +830,7 @@ public void element() throws Exception {
827830
+ "getElementsByTagName(),getElementsByTagNameNS(),getHTML(),"
828831
+ "hasAttribute(),hasAttributeNS(),"
829832
+ "hasAttributes(),id[GSCE],innerHTML[GSCE],insertAdjacentElement(),insertAdjacentHTML(),"
830-
+ "insertAdjacentText(),lastElementChild[GCE],localName[GCE],matches(),namespaceURI[GCE],"
833+
+ "insertAdjacentText(),lastElementChild[GCE],localName[GCE],matches(),moveBefore(),namespaceURI[GCE],"
831834
+ "nextElementSibling[GCE],onbeforecopy[GSCE],onbeforecut[GSCE],onbeforepaste[GSCE],onsearch[GSCE],"
832835
+ "onwebkitfullscreenchange[GSCE],onwebkitfullscreenerror[GSCE],outerHTML[GSCE],prefix[GCE],prepend(),"
833836
+ "previousElementSibling[GCE],querySelector(),querySelectorAll(),remove(),removeAttribute(),"
@@ -845,7 +848,7 @@ public void element() throws Exception {
845848
+ "getElementsByTagName(),getElementsByTagNameNS(),getHTML(),"
846849
+ "hasAttribute(),hasAttributeNS(),"
847850
+ "hasAttributes(),id[GSCE],innerHTML[GSCE],insertAdjacentElement(),insertAdjacentHTML(),"
848-
+ "insertAdjacentText(),lastElementChild[GCE],localName[GCE],matches(),namespaceURI[GCE],"
851+
+ "insertAdjacentText(),lastElementChild[GCE],localName[GCE],matches(),moveBefore(),namespaceURI[GCE],"
849852
+ "nextElementSibling[GCE],onbeforecopy[GSCE],onbeforecut[GSCE],onbeforepaste[GSCE],onsearch[GSCE],"
850853
+ "onwebkitfullscreenchange[GSCE],onwebkitfullscreenerror[GSCE],outerHTML[GSCE],prefix[GCE],prepend(),"
851854
+ "previousElementSibling[GCE],querySelector(),querySelectorAll(),remove(),removeAttribute(),"
@@ -863,7 +866,8 @@ public void element() throws Exception {
863866
+ "getElementsByTagName(),getElementsByTagNameNS(),getHTML(),hasAttribute(),hasAttributeNS(),"
864867
+ "hasAttributes(),id[GSCE],innerHTML[GSCE],insertAdjacentElement(),insertAdjacentHTML(),"
865868
+ "insertAdjacentText(),lastElementChild[GCE],localName[GCE],"
866-
+ "matches(),mozMatchesSelector(),namespaceURI[GCE],"
869+
+ "matches(),moveBefore(),"
870+
+ "mozMatchesSelector(),namespaceURI[GCE],"
867871
+ "nextElementSibling[GCE],outerHTML[GSCE],prefix[GCE],prepend(),"
868872
+ "previousElementSibling[GCE],querySelector(),querySelectorAll(),releaseCapture(),"
869873
+ "remove(),removeAttribute(),"
@@ -15494,12 +15498,12 @@ public void document() throws Exception {
1549415498
FF = "constructor()",
1549515499
FF_ESR = "constructor()")
1549615500
@HtmlUnitNYI(CHROME = "constructor(),dispatchEvent(),documentElement[GCE],getElementById(),"
15497-
+ "open(),write(),writeln()",
15501+
+ "moveBefore(),open(),write(),writeln()",
1549815502
EDGE = "constructor(),dispatchEvent(),documentElement[GCE],getElementById(),"
15499-
+ "open(),write(),writeln()",
15500-
FF_ESR = "close(),constructor(),dispatchEvent(),documentElement[GCE],getElementById(),"
15501-
+ "open(),write(),writeln()",
15503+
+ "moveBefore(),open(),write(),writeln()",
1550215504
FF = "close(),constructor(),dispatchEvent(),documentElement[GCE],getElementById(),"
15505+
+ "moveBefore(),open(),write(),writeln()",
15506+
FF_ESR = "close(),constructor(),dispatchEvent(),documentElement[GCE],getElementById(),"
1550315507
+ "open(),write(),writeln()")
1550415508
public void htmlDocument() throws Exception {
1550515509
testString("", "document");
@@ -15786,13 +15790,13 @@ public void range() throws Exception {
1578615790
+ "getElementById(),lastElementChild[GCE],prepend(),querySelector(),querySelectorAll(),"
1578715791
+ "replaceChildren()")
1578815792
@HtmlUnitNYI(CHROME = "append(),childElementCount[GCE],children[GCE],constructor(),firstElementChild[GCE],"
15789-
+ "getElementById(),lastElementChild[GCE],prepend(),querySelector(),querySelectorAll(),"
15793+
+ "getElementById(),lastElementChild[GCE],moveBefore(),prepend(),querySelector(),querySelectorAll(),"
1579015794
+ "replaceChildren()",
1579115795
EDGE = "append(),childElementCount[GCE],children[GCE],constructor(),firstElementChild[GCE],"
15792-
+ "getElementById(),lastElementChild[GCE],prepend(),querySelector(),querySelectorAll(),"
15796+
+ "getElementById(),lastElementChild[GCE],moveBefore(),prepend(),querySelector(),querySelectorAll(),"
1579315797
+ "replaceChildren()",
1579415798
FF = "append(),childElementCount[GCE],children[GCE],constructor(),firstElementChild[GCE],"
15795-
+ "getElementById(),lastElementChild[GCE],prepend(),querySelector(),querySelectorAll(),"
15799+
+ "getElementById(),lastElementChild[GCE],moveBefore(),prepend(),querySelector(),querySelectorAll(),"
1579615800
+ "replaceChildren()")
1579715801
public void documentFragment() throws Exception {
1579815802
testString("", "document.createDocumentFragment()");

0 commit comments

Comments
 (0)