From: <asa...@us...> - 2017-05-31 21:12:04
|
Revision: 14519 http://sourceforge.net/p/htmlunit/code/14519 Author: asashour Date: 2017-05-31 21:12:01 +0000 (Wed, 31 May 2017) Log Message: ----------- JavaScript: implement .before(), .after() and .replaceWith() Modified Paths: -------------- trunk/htmlunit/src/changes/changes.xml trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Element.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/CharacterData.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DocumentType.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/Node.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/WebDriverTestCase.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/dom/NodeTest.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/selenium/SeleniumTest.java Modified: trunk/htmlunit/src/changes/changes.xml =================================================================== --- trunk/htmlunit/src/changes/changes.xml 2017-05-31 19:32:05 UTC (rev 14518) +++ trunk/htmlunit/src/changes/changes.xml 2017-05-31 21:12:01 UTC (rev 14519) @@ -8,6 +8,9 @@ <body> <release version="2.27" date="???" description="GAE broken, FF52, Bugfixes"> + <action type="add" dev="asashour"> + JavaScript: implement .before(), .after() and .replaceWith(). + </action> <action type="fix" dev="rbri" issue="1827"> Simulated system time zone is now configurable (BrowserVersion.setSystemTimezone()). </action> Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Element.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Element.java 2017-05-31 19:32:05 UTC (rev 14518) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Element.java 2017-05-31 21:12:01 UTC (rev 14519) @@ -1955,4 +1955,44 @@ super.remove(); } + /** + * Inserts a set of Node or DOMString objects in the children list of this ChildNode's parent, + * just before this ChildNode. + * @param context the context + * @param thisObj this object + * @param args the arguments + * @param function the function + */ + @JsxFunction({CHROME, FF}) + public static void before(final Context context, final Scriptable thisObj, final Object[] args, + final Function function) { + Node.before(context, thisObj, args, function); + } + + /** + * Inserts a set of Node or DOMString objects in the children list of this ChildNode's parent, + * just after this ChildNode. + * @param context the context + * @param thisObj this object + * @param args the arguments + * @param function the function + */ + @JsxFunction({CHROME, FF}) + public static void after(final Context context, final Scriptable thisObj, final Object[] args, + final Function function) { + Node.after(context, thisObj, args, function); + } + + /** + * Replaces the node wit a set of Node or DOMString objects. + * @param context the context + * @param thisObj this object + * @param args the arguments + * @param function the function + */ + @JsxFunction({CHROME, FF}) + public static void replaceWith(final Context context, final Scriptable thisObj, final Object[] args, + final Function function) { + Node.replaceWith(context, thisObj, args, function); + } } Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/CharacterData.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/CharacterData.java 2017-05-31 19:32:05 UTC (rev 14518) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/CharacterData.java 2017-05-31 21:12:01 UTC (rev 14519) @@ -29,6 +29,8 @@ import com.gargoylesoftware.htmlunit.javascript.host.Element; import net.sourceforge.htmlunit.corejs.javascript.Context; +import net.sourceforge.htmlunit.corejs.javascript.Function; +import net.sourceforge.htmlunit.corejs.javascript.Scriptable; /** * A JavaScript object for {@code CharacterData}. @@ -186,4 +188,44 @@ super.remove(); } + /** + * Inserts a set of Node or DOMString objects in the children list of this ChildNode's parent, + * just before this ChildNode. + * @param context the context + * @param thisObj this object + * @param args the arguments + * @param function the function + */ + @JsxFunction({CHROME, FF}) + public static void before(final Context context, final Scriptable thisObj, final Object[] args, + final Function function) { + Node.before(context, thisObj, args, function); + } + + /** + * Inserts a set of Node or DOMString objects in the children list of this ChildNode's parent, + * just after this ChildNode. + * @param context the context + * @param thisObj this object + * @param args the arguments + * @param function the function + */ + @JsxFunction({CHROME, FF}) + public static void after(final Context context, final Scriptable thisObj, final Object[] args, + final Function function) { + Node.after(context, thisObj, args, function); + } + + /** + * Replaces the node wit a set of Node or DOMString objects. + * @param context the context + * @param thisObj this object + * @param args the arguments + * @param function the function + */ + @JsxFunction({CHROME, FF}) + public static void replaceWith(final Context context, final Scriptable thisObj, final Object[] args, + final Function function) { + Node.replaceWith(context, thisObj, args, function); + } } Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DocumentType.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DocumentType.java 2017-05-31 19:32:05 UTC (rev 14518) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DocumentType.java 2017-05-31 21:12:01 UTC (rev 14519) @@ -31,6 +31,9 @@ import com.gargoylesoftware.htmlunit.javascript.configuration.JsxFunction; import com.gargoylesoftware.htmlunit.javascript.configuration.JsxGetter; +import net.sourceforge.htmlunit.corejs.javascript.Context; +import net.sourceforge.htmlunit.corejs.javascript.Function; +import net.sourceforge.htmlunit.corejs.javascript.Scriptable; import net.sourceforge.htmlunit.corejs.javascript.Undefined; /** @@ -170,4 +173,44 @@ super.remove(); } + /** + * Inserts a set of Node or DOMString objects in the children list of this ChildNode's parent, + * just before this ChildNode. + * @param context the context + * @param thisObj this object + * @param args the arguments + * @param function the function + */ + @JsxFunction({CHROME, FF}) + public static void before(final Context context, final Scriptable thisObj, final Object[] args, + final Function function) { + Node.before(context, thisObj, args, function); + } + + /** + * Inserts a set of Node or DOMString objects in the children list of this ChildNode's parent, + * just after this ChildNode. + * @param context the context + * @param thisObj this object + * @param args the arguments + * @param function the function + */ + @JsxFunction({CHROME, FF}) + public static void after(final Context context, final Scriptable thisObj, final Object[] args, + final Function function) { + Node.after(context, thisObj, args, function); + } + + /** + * Replaces the node wit a set of Node or DOMString objects. + * @param context the context + * @param thisObj this object + * @param args the arguments + * @param function the function + */ + @JsxFunction({CHROME, FF}) + public static void replaceWith(final Context context, final Scriptable thisObj, final Object[] args, + final Function function) { + Node.replaceWith(context, thisObj, args, function); + } } Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/Node.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/Node.java 2017-05-31 19:32:05 UTC (rev 14518) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/Node.java 2017-05-31 21:12:01 UTC (rev 14519) @@ -42,6 +42,7 @@ import com.gargoylesoftware.htmlunit.javascript.host.Element; import com.gargoylesoftware.htmlunit.javascript.host.event.EventTarget; import com.gargoylesoftware.htmlunit.javascript.host.html.HTMLCollection; +import com.gargoylesoftware.htmlunit.javascript.host.html.HTMLDocument; import com.gargoylesoftware.htmlunit.javascript.host.html.HTMLHtmlElement; import net.sourceforge.htmlunit.corejs.javascript.Context; @@ -795,4 +796,83 @@ }; return collection; } + + /** + * Inserts a set of Node or DOMString objects in the children list of this ChildNode's parent, + * just after this ChildNode. + * @param context the context + * @param thisObj this object + * @param args the arguments + * @param function the function + */ + protected static void after(final Context context, final Scriptable thisObj, final Object[] args, + final Function function) { + final DomNode thisDomNode = ((Node) thisObj).getDomNodeOrDie(); + final DomNode parentNode = thisDomNode.getParentNode(); + final DomNode nextSibling = thisDomNode.getNextSibling(); + for (Object arg : args) { + final Node node = toNodeOrTextNode((Node) thisObj, arg); + final DomNode newNode = node.getDomNodeOrDie(); + if (nextSibling != null) { + nextSibling.insertBefore(newNode); + } + else { + parentNode.appendChild(newNode); + } + } + } + + private static Node toNodeOrTextNode(final Node thisObj, final Object obj) { + if (obj instanceof Node) { + return (Node) obj; + } + return (Node) + ((HTMLDocument) thisObj.getOwnerDocument()).createTextNode(Context.toString(obj)); + } + + /** + * Inserts a set of Node or DOMString objects in the children list of this ChildNode's parent, + * just before this ChildNode. + * @param context the context + * @param thisObj this object + * @param args the arguments + * @param function the function + */ + protected static void before(final Context context, final Scriptable thisObj, final Object[] args, + final Function function) { + for (Object arg : args) { + final Node node = toNodeOrTextNode((Node) thisObj, arg); + ((Node) thisObj).getDomNodeOrDie().insertBefore(node.getDomNodeOrDie()); + } + } + + /** + * Replaces this ChildNode in the children list of its parent with a set of Node or DOMString objects. + * @param context the context + * @param thisObj this object + * @param args the arguments + * @param function the function + */ + protected static void replaceWith(final Context context, final Scriptable thisObj, final Object[] args, + final Function function) { + final DomNode thisDomNode = ((Node) thisObj).getDomNodeOrDie(); + final DomNode parentNode = thisDomNode.getParentNode(); + final DomNode nextSibling = thisDomNode.getNextSibling(); + boolean isFirst = true; + for (Object arg : args) { + final DomNode newNode = toNodeOrTextNode((Node) thisObj, arg).getDomNodeOrDie(); + if (isFirst) { + isFirst = false; + thisDomNode.replace(newNode); + } + else { + if (nextSibling != null) { + nextSibling.insertBefore(newNode); + } + else { + parentNode.appendChild(newNode); + } + } + } + } } Modified: trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/WebDriverTestCase.java =================================================================== --- trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/WebDriverTestCase.java 2017-05-31 19:32:05 UTC (rev 14518) +++ trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/WebDriverTestCase.java 2017-05-31 21:12:01 UTC (rev 14519) @@ -1089,7 +1089,7 @@ * This should be always 0, if {@link #isWebClientCached()} is {@code false}. */ @Before - public void before() { + public void beforeTest() { if (!isWebClientCached()) { assertTrue(getJavaScriptThreads().isEmpty()); } Modified: trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/dom/NodeTest.java =================================================================== --- trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/dom/NodeTest.java 2017-05-31 19:32:05 UTC (rev 14518) +++ trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/dom/NodeTest.java 2017-05-31 21:12:01 UTC (rev 14519) @@ -1185,4 +1185,88 @@ loadPageWithAlerts2(html); } + + /** + * @throws Exception if an error occurs + */ + @Test + @Alerts(DEFAULT = "<div><span></span>nullundefinedhello<p></p></div>", + IE = "<div><p></p></div>") + public void before() throws Exception { + final String html = + "<html><head>\n" + + " <script>\n" + + " function test() {\n" + + " var parent = document.createElement('div');\n" + + " var child = document.createElement('p');\n" + + " parent.appendChild(child);\n" + + " var span = document.createElement('span');\n" + + " if (child.before) {" + + " child.before(span, null, undefined, 'hello');\n" + + " }\n" + + " alert(parent.outerHTML);\n" + + " }\n" + + " </script>\n" + + "</head>\n" + + "<body onload='test()'></body>\n" + + "</html>"; + + loadPageWithAlerts2(html); + } + + /** + * @throws Exception if an error occurs + */ + @Test + @Alerts(DEFAULT = "<div><p></p><span></span>nullundefinedhello</div>", + IE = "<div><p></p></div>") + public void after() throws Exception { + final String html = + "<html><head>\n" + + " <script>\n" + + " function test() {\n" + + " var parent = document.createElement('div');\n" + + " var child = document.createElement('p');\n" + + " parent.appendChild(child);\n" + + " var span = document.createElement('span');\n" + + " if (child.after) {" + + " child.after(span, null, undefined, 'hello');\n" + + " }\n" + + " alert(parent.outerHTML);\n" + + " }\n" + + " </script>\n" + + "</head>\n" + + "<body onload='test()'></body>\n" + + "</html>"; + + loadPageWithAlerts2(html); + } + + /** + * @throws Exception if an error occurs + */ + @Test + @Alerts(DEFAULT = "<div><span></span>nullundefinedhello</div>", + IE = "<div><p></p></div>") + public void replaceWith() throws Exception { + final String html = + "<html><head>\n" + + " <script>\n" + + " function test() {\n" + + " var parent = document.createElement('div');\n" + + " var child = document.createElement('p');\n" + + " parent.appendChild(child);\n" + + " var span = document.createElement('span');\n" + + " if (child.replaceWith) {" + + " child.replaceWith(span, null, undefined, 'hello');\n" + + " }\n" + + " alert(parent.outerHTML);\n" + + " }\n" + + " </script>\n" + + "</head>\n" + + "<body onload='test()'></body>\n" + + "</html>"; + + loadPageWithAlerts2(html); + } } Modified: trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/selenium/SeleniumTest.java =================================================================== --- trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/selenium/SeleniumTest.java 2017-05-31 19:32:05 UTC (rev 14518) +++ trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/selenium/SeleniumTest.java 2017-05-31 21:12:01 UTC (rev 14519) @@ -31,7 +31,7 @@ */ @Override @Before - public void before() { + public void beforeTest() { try { startWebServer("src/test/resources/selenium", null, null); } |