From: <rb...@us...> - 2014-01-26 17:41:13
|
Revision: 9068 http://sourceforge.net/p/htmlunit/code/9068 Author: rbri Date: 2014-01-26 17:41:07 +0000 (Sun, 26 Jan 2014) Log Message: ----------- Function HTMLelement.insertAdjacentText added (IE, Chrome). Two more outerHtml test added, both are failing at the moment (NYI) Modified Paths: -------------- trunk/htmlunit/src/changes/changes.xml trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/html/HTMLElement.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/html/HTMLElementTest.java Modified: trunk/htmlunit/src/changes/changes.xml =================================================================== --- trunk/htmlunit/src/changes/changes.xml 2014-01-26 07:54:37 UTC (rev 9067) +++ trunk/htmlunit/src/changes/changes.xml 2014-01-26 17:41:07 UTC (rev 9068) @@ -8,6 +8,9 @@ <body> <release version="2.14" date="???" description="FF24, Bugfixes, initial work on IE11"> + <action type="fix" dev="rbri" due-to="Frank Danek"> + JavaScript: Function HTMLelement.insertAdjacentText added (IE, Chrome). + </action> <action type="update" dev="asashour"> BrowserVersion: deprecate INTERNET_EXPLORER_8 and INTERNET_EXPLORER_9. </action> Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/html/HTMLElement.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/html/HTMLElement.java 2014-01-26 07:54:37 UTC (rev 9067) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/html/HTMLElement.java 2014-01-26 17:41:07 UTC (rev 9068) @@ -198,10 +198,10 @@ private static final Pattern PRINT_NODE_PATTERN = Pattern.compile(" "); private static final Pattern PRINT_NODE_QUOTE_PATTERN = Pattern.compile("\""); - static final String POSITION_BEFORE_BEGIN = "beforeBegin"; - static final String POSITION_AFTER_BEGIN = "afterBegin"; - static final String POSITION_BEFORE_END = "beforeEnd"; - static final String POSITION_AFTER_END = "afterEnd"; + static final String POSITION_BEFORE_BEGIN = "beforebegin"; + static final String POSITION_AFTER_BEGIN = "afterbegin"; + static final String POSITION_BEFORE_END = "beforeend"; + static final String POSITION_AFTER_END = "afterend"; /** * Static counter for {@link #uniqueID_}. @@ -1133,16 +1133,21 @@ } /** - * Inserts the given HTML text into the element at the location. - * @see <a href="http://msdn2.microsoft.com/en-us/library/ms536452.aspx"> - * MSDN documentation</a> - * @param where specifies where to insert the HTML text, using one of the following value: - * beforeBegin, afterBegin, beforeEnd, afterEnd - * @param text the HTML text to insert + * Parses the given text as HTML or XML and inserts the resulting nodes into the tree in the position given by the + * position argument. + * @param position specifies where to insert the nodes, using one of the following values (case-insensitive): + * beforebegin, afterbegin, beforeend, afterend + * @param text the text to parse + * + * @see <a href="http://www.w3.org/TR/DOM-Parsing/#methods-2">W3C Spec</a> + * @see <a href="http://domparsing.spec.whatwg.org/#dom-element-insertadjacenthtml">WhatWG Spec</a> + * @see <a href="https://developer.mozilla.org/en-US/docs/Web/API/Element.insertAdjacentHTML" + * >Mozilla Developer Network</a> + * @see <a href="http://msdn.microsoft.com/en-us/library/ie/ms536452.aspx">MSDN</a> */ - @JsxFunction({ @WebBrowser(IE), @WebBrowser(CHROME), @WebBrowser(value = FF, minVersion = 8) }) - public void insertAdjacentHTML(final String where, final String text) { - final Object[] values = getInsertAdjacentLocation(where); + @JsxFunction + public void insertAdjacentHTML(final String position, final String text) { + final Object[] values = getInsertAdjacentLocation(position); final DomNode node = (DomNode) values[0]; final boolean append = ((Boolean) values[1]).booleanValue(); @@ -1153,17 +1158,17 @@ /** * Inserts the given element into the element at the location. - * @see <a href="http://msdn2.microsoft.com/en-us/library/ms536451.aspx"> - * MSDN documentation</a> - * @param where specifies where to insert the element, using one of the following value: - * beforeBegin, afterBegin, beforeEnd, afterEnd - * @param object the element to insert + * @param where specifies where to insert the element, using one of the following values (case-insensitive): + * beforebegin, afterbegin, beforeend, afterend + * @param insertedElement the element to be inserted * @return an element object + * + * @see <a href="http://msdn.microsoft.com/en-us/library/ie/ms536451.aspx">MSDN</a> */ - @JsxFunction(@WebBrowser(IE)) - public Object insertAdjacentElement(final String where, final Object object) { - if (object instanceof Node) { - final DomNode childNode = ((Node) object).getDomNodeOrDie(); + @JsxFunction({ @WebBrowser(CHROME), @WebBrowser(IE) }) + public Object insertAdjacentElement(final String where, final Object insertedElement) { + if (insertedElement instanceof Node) { + final DomNode childNode = ((Node) insertedElement).getDomNodeOrDie(); final Object[] values = getInsertAdjacentLocation(where); final DomNode node = (DomNode) values[0]; final boolean append = ((Boolean) values[1]).booleanValue(); @@ -1174,19 +1179,42 @@ else { node.insertBefore(childNode); } - return object; + return insertedElement; } - throw Context.reportRuntimeError("Passed object is not an element: " + object); + throw Context.reportRuntimeError("Passed object is not an element: " + insertedElement); } /** + * Inserts the given text into the element at the specified location. + * @param where specifies where to insert the text, using one of the following values (case-insensitive): + * beforebegin, afterbegin, beforeend, afterend + * @param text the text to insert + * + * @see <a href="http://msdn.microsoft.com/en-us/library/ie/ms536453.aspx">MSDN</a> + */ + @JsxFunction({ @WebBrowser(CHROME), @WebBrowser(IE) }) + public void insertAdjacentText(final String where, final String text) { + final Object[] values = getInsertAdjacentLocation(where); + final DomNode node = (DomNode) values[0]; + final boolean append = ((Boolean) values[1]).booleanValue(); + + final DomText domText = new DomText(node.getPage(), text); + // add the new nodes + if (append) { + node.appendChild(domText); + } + else { + node.insertBefore(domText); + } + } + + /** * Returns where and how to add the new node. - * Used by {@link #insertAdjacentHTML(String, String)} and - * {@link #insertAdjacentElement(String, Object)}. - * - * @param where specifies where to insert the element, using one of the following value: - * beforeBegin, afterBegin, beforeEnd, afterEnd - * + * Used by {@link #insertAdjacentHTML(String, String)}, + * {@link #insertAdjacentElement(String, Object)} and + * {@link #insertAdjacentText(String, String)}. + * @param where specifies where to insert the element, using one of the following values (case-insensitive): + * beforebegin, afterbegin, beforeend, afterend * @return an array of 1-DomNode:parentNode and 2-Boolean:append */ private Object[] getInsertAdjacentLocation(final String where) { Modified: trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/html/HTMLElementTest.java =================================================================== --- trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/html/HTMLElementTest.java 2014-01-26 07:54:37 UTC (rev 9067) +++ trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/html/HTMLElementTest.java 2014-01-26 17:41:07 UTC (rev 9068) @@ -14,6 +14,7 @@ */ package com.gargoylesoftware.htmlunit.javascript.host.html; +import static com.gargoylesoftware.htmlunit.BrowserRunner.Browser.CHROME; import static com.gargoylesoftware.htmlunit.BrowserRunner.Browser.FF; import static com.gargoylesoftware.htmlunit.BrowserRunner.Browser.FF17; import static com.gargoylesoftware.htmlunit.BrowserRunner.Browser.FF24; @@ -854,6 +855,52 @@ } /** + * @throws Exception if the test fails + */ + @Test + public void setInnerHTMLExecuteJavaScript() throws Exception { + final String html = HtmlPageTest.STANDARDS_MODE_PREFIX_ + + "<html><head><title>foo</title><script>\n" + + " function test() {\n" + + " var newnode = '<scr'+'ipt>alerter();</scr'+'ipt>';\n" + + " var outernode = document.getElementById('myNode');\n" + + " outernode.innerHTML = newnode;\n" + + " }\n" + + " function alerter() {\n" + + " alert('executed');\n" + + " }\n" + + "</script></head><body onload='test()'>\n" + + " <div id='myNode'></div>\n" + + "</body></html>"; + loadPageWithAlerts2(html); + } + + /** + * @throws Exception if the test fails + */ + @Test + @Alerts("exception") + public void setInnerHTMLDeclareJavaScript() throws Exception { + final String html = HtmlPageTest.STANDARDS_MODE_PREFIX_ + + "<html><head><title>foo</title><script>\n" + + " function test() {\n" + + " var newnode = '<scr'+'ipt>function tester() { alerter(); }</scr'+'ipt>';\n" + + " var outernode = document.getElementById('myNode');\n" + + " outernode.innerHTML = newnode;\n" + + " try {\n" + + " tester();\n" + + " } catch(e) { alert('exception'); }\n" + + " }\n" + + " function alerter() {\n" + + " alert('declared');\n" + + " }\n" + + "</script></head><body onload='test()'>\n" + + " <div id='myNode'></div>\n" + + "</body></html>"; + loadPageWithAlerts2(html); + } + + /** * Verifies outerHTML, innerHTML and innerText for newly created div. * @throws Exception if the test fails */ @@ -1283,6 +1330,54 @@ } /** + * @throws Exception if the test fails + */ + @Test + @NotYetImplemented + public void setOuterHTMLExecuteJavaScript() throws Exception { + final String html = HtmlPageTest.STANDARDS_MODE_PREFIX_ + + "<html><head><title>foo</title><script>\n" + + " function test() {\n" + + " var newnode = '<scr'+'ipt>alerter();</scr'+'ipt>';\n" + + " var oldnode = document.getElementById('myNode');\n" + + " oldnode.outerHTML = newnode;\n" + + " }\n" + + " function alerter() {\n" + + " alert('executed');\n" + + " }\n" + + "</script></head><body onload='test()'>\n" + + " <div id='myNode'></div>\n" + + "</body></html>"; + loadPageWithAlerts2(html); + } + + /** + * @throws Exception if the test fails + */ + @Test + @Alerts("exception") + @NotYetImplemented + public void setOuterHTMLDeclareJavaScript() throws Exception { + final String html = HtmlPageTest.STANDARDS_MODE_PREFIX_ + + "<html><head><title>foo</title><script>\n" + + " function test() {\n" + + " var newnode = '<scr'+'ipt>function tester() { alerter(); }</scr'+'ipt>';\n" + + " var oldnode = document.getElementById('myNode');\n" + + " oldnode.outerHTML = newnode;\n" + + " try {\n" + + " tester();\n" + + " } catch(e) { alert('exception'); }\n" + + " }\n" + + " function alerter() {\n" + + " alert('declared');\n" + + " }\n" + + "</script></head><body onload='test()'>\n" + + " <div id='myNode'></div>\n" + + "</body></html>"; + loadPageWithAlerts2(html); + } + + /** * Test the <tt>#default#clientCaps</tt> default IE behavior. * * @throws Exception if the test fails @@ -4407,6 +4502,7 @@ @Alerts({ "outside", "1", "middle", "2", "3", "4", "before-begin after-begin inside before-end after-end" }) public void insertAdjacentHTML() throws Exception { + insertAdjacentHTML("beforeend", "afterend", "beforebegin", "afterbegin"); insertAdjacentHTML("beforeEnd", "afterEnd", "beforeBegin", "afterBegin"); insertAdjacentHTML("BeforeEnd", "AfterEnd", "BeFoReBeGiN", "afterbegin"); } @@ -4455,10 +4551,11 @@ * @throws Exception if the test fails */ @Test - @Browsers(IE) + @Browsers({ CHROME, IE }) @Alerts({ "outside", "1", "middle", "2", "3", "4", "before-begin after-begin inside before-end after-end" }) public void insertAdjacentElement() throws Exception { + insertAdjacentElement("beforeend", "afterend", "beforebegin", "afterbegin"); insertAdjacentElement("beforeEnd", "afterEnd", "beforeBegin", "afterBegin"); insertAdjacentElement("BeforeEnd", "AfterEnd", "BeFoReBeGiN", "afterbegin"); } @@ -4501,4 +4598,51 @@ + "</body></html>"; loadPageWithAlerts2(html); } + + /** + * @throws Exception if the test fails + */ + @Test + @Browsers({ CHROME, IE }) + @Alerts(DEFAULT = { "outside", "middle", + "before-begin after-begin inside before-end after-end" }, + IE8 = { "outside", "middle", + "before-begin after-begininside before-end after-end" }) + @NotYetImplemented(IE8) + public void insertAdjacentText() throws Exception { + insertAdjacentText("beforeend", "afterend", "beforebegin", "afterbegin"); + insertAdjacentText("beforeEnd", "afterEnd", "beforeBegin", "afterBegin"); + insertAdjacentText("BeforeEnd", "AfterEnd", "BeFoReBeGiN", "afterbegin"); + } + + private void insertAdjacentText(final String beforeEnd, + final String afterEnd, final String beforeBegin, final String afterBegin) throws Exception { + final String html = HtmlPageTest.STANDARDS_MODE_PREFIX_ + + "<html><head><title>foo</title><script>\n" + + "function test() {\n" + + " var oNode = document.getElementById('middle');\n" + + " oNode.insertAdjacentText('" + beforeEnd + "', 'before-end');\n" + + " oNode.insertAdjacentText('" + afterEnd + "', ' after-end');\n" + + " oNode.insertAdjacentText('" + beforeBegin + "', 'before-begin ');\n" + + " oNode.insertAdjacentText('" + afterBegin + "', ' after-begin');\n" + + " var coll = document.getElementsByTagName('SPAN');\n" + + " for (var i=0; i<coll.length; i++) {\n" + + " alert(coll[i].id);\n" + + " }\n" + + " var outside = document.getElementById('outside');\n" + + " var text = outside.textContent ? outside.textContent : outside.innerText;\n" + + " text = text.replace(/(\\r\\n|\\r|\\n)/gm, '');\n" + + " text = text.replace(/(\\s{2,})/g, ' ');\n" + + " text = text.replace(/^\\s+|\\s+$/g, '');\n" + + " alert(text);\n" + + "}\n" + + "</script></head><body onload='test()'>\n" + + " <span id='outside' style='color: #00ff00'>\n" + + " <span id='middle' style='color: #ff0000'>\n" + + " inside\n" + + " </span>\n" + + " </span>\n" + + "</body></html>"; + loadPageWithAlerts2(html); + } } |