From: <sd...@us...> - 2008-02-28 01:33:48
|
Revision: 2488 http://htmlunit.svn.sourceforge.net/htmlunit/?rev=2488&view=rev Author: sdanig Date: 2008-02-27 17:33:41 -0800 (Wed, 27 Feb 2008) Log Message: ----------- Add temporary body element when one is missing and document.write() is called. Modified Paths: -------------- trunk/htmlunit/src/changes/changes.xml trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/html/DefaultElementFactory.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/html/DomNode.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/html/HTMLParser.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBody.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlPage.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Document.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Window.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/XMLDocument.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/DocumentTest.java Modified: trunk/htmlunit/src/changes/changes.xml =================================================================== --- trunk/htmlunit/src/changes/changes.xml 2008-02-28 01:17:03 UTC (rev 2487) +++ trunk/htmlunit/src/changes/changes.xml 2008-02-28 01:33:41 UTC (rev 2488) @@ -20,6 +20,9 @@ Upgrade Log4j to 1.2.15. </action> <action type="fix" dev="sdanig"> + Add temporary body element when one is missing and document.write() is called. + </action> + <action type="fix" dev="sdanig"> Add implicit body element when one is missing and there is no content to trigger addition by NekoHTML. </action> <action type="fix" dev="sdanig"> Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/html/DefaultElementFactory.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/html/DefaultElementFactory.java 2008-02-28 01:17:03 UTC (rev 2487) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/html/DefaultElementFactory.java 2008-02-28 01:33:41 UTC (rev 2488) @@ -112,7 +112,7 @@ element = new HtmlBlockQuote(namespaceURI, qualifiedName, page, attributeMap); } else if (tagName.equals(HtmlBody.TAG_NAME)) { - element = new HtmlBody(namespaceURI, qualifiedName, page, attributeMap); + element = new HtmlBody(namespaceURI, qualifiedName, page, attributeMap, false); } else if (tagName.equals(HtmlBreak.TAG_NAME)) { element = new HtmlBreak(namespaceURI, qualifiedName, page, attributeMap); Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/html/DomNode.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/html/DomNode.java 2008-02-28 01:17:03 UTC (rev 2487) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/html/DomNode.java 2008-02-28 01:33:41 UTC (rev 2488) @@ -820,7 +820,7 @@ } /** - * append a child node to the end of the current list + * Appends a child node to this node. * @param node the node to append * @return the node added */ @@ -832,26 +832,14 @@ } } else { - //clean up the new node, in case it is being moved + // clean up the new node, in case it is being moved if (node != this) { node.basicRemove(); } - if (firstChild_ == null) { - firstChild_ = node; - firstChild_.previousSibling_ = node; - } - else { - final DomNode last = getLastDomChild(); - - last.nextSibling_ = node; - node.previousSibling_ = last; - node.nextSibling_ = null; //safety first - firstChild_.previousSibling_ = node; //new last node - } - node.parent_ = this; - - if (!(this instanceof DomDocumentFragment) - && (getPage() instanceof HtmlPage || this instanceof HtmlPage)) { + // move the node + basicAppend(node); + // trigger events + if (!(this instanceof DomDocumentFragment) && (getPage() instanceof HtmlPage || this instanceof HtmlPage)) { ((HtmlPage) getPage()).notifyNodeAdded(node); } fireNodeAdded(this, node); @@ -860,6 +848,45 @@ } /** + * Quietly removes this node and moves its children to the specified destination. "Quietly" means + * that no node events are fired. This method is not appropriate for most use cases. It should + * only be used in specific cases for HTML parsing hackery. + * + * @param destination the node to which this node's children should be moved before this node is removed + */ + void quietlyRemoveAndMoveChildrenTo(final DomNode destination) { + if (destination.getPage() != getPage()) { + throw new RuntimeException("Cannot perform quiet move on nodes from different pages."); + } + for (DomNode child : getChildren()) { + child.basicRemove(); + destination.basicAppend(child); + } + basicRemove(); + } + + /** + * Appends the specified node to the end of this node's children, assuming the specified + * node is clean (doesn't have preexisting relationships to other nodes. + * + * @param node the node to append to this node's children + */ + private void basicAppend(final DomNode node) { + if (firstChild_ == null) { + firstChild_ = node; + firstChild_.previousSibling_ = node; + } + else { + final DomNode last = getLastDomChild(); + last.nextSibling_ = node; + node.previousSibling_ = last; + node.nextSibling_ = null; // safety first + firstChild_.previousSibling_ = node; // new last node + } + node.parent_ = this; + } + + /** * Check for insertion errors for a new child node. This is overridden by derived * classes to enforce which types of children are allowed. * @@ -1367,5 +1394,5 @@ } } } - + } Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/html/HTMLParser.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/html/HTMLParser.java 2008-02-28 01:17:03 UTC (rev 2487) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/html/HTMLParser.java 2008-02-28 01:33:41 UTC (rev 2488) @@ -262,7 +262,7 @@ throw new RuntimeException("Failed parsing content from " + webResponse.getUrl(), origin); } - // TODO: addBodyToPageIfNecessary(page, true); + addBodyToPageIfNecessary(page, true); return page; } @@ -293,7 +293,7 @@ // If the document does not have a body, add it. if (!hasBody) { - final HtmlBody body = new HtmlBody(null, "body", page, null); + final HtmlBody body = new HtmlBody(null, "body", page, null, false); doc.appendChild(body); } @@ -435,12 +435,28 @@ stack_.push(currentNode_); } + // If we're adding a body element, keep track of any temporary synthetic ones + // that we may have had to create earlier (for document.write(), for example). + HtmlBody oldBody = null; + if (tagLower.equals("body") && page_.getBody() instanceof HtmlBody) { + oldBody = (HtmlBody) page_.getBody(); + } + + // Add the new node. final IElementFactory factory = getElementFactory(tagLower); final HtmlElement newElement = factory.createElement(page_, tagLower, atts); newElement.setStartLocation(locator_.getLineNumber(), locator_.getColumnNumber()); currentNode_.appendDomChild(newElement); + + // If we had an old synthetic body and we just added a real body element, quietly + // remove the old body and move its children to the real body element we just added. + if (oldBody != null) { + oldBody.quietlyRemoveAndMoveChildrenTo(newElement); + } + currentNode_ = newElement; stack_.push(currentNode_); + } /** @inheritDoc ContentHandler@endElement(String,String,String) */ Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBody.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBody.java 2008-02-28 01:17:03 UTC (rev 2487) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBody.java 2008-02-28 01:33:41 UTC (rev 2488) @@ -50,24 +50,33 @@ */ public class HtmlBody extends ClickableElement { + /** Serial version UID. */ private static final long serialVersionUID = -4133102076637734903L; - /** the HTML tag represented by this element */ + /** The HTML tag represented by this element. */ public static final String TAG_NAME = "body"; + /** Whether or not this body is temporary (created because the <tt>body</tt> tag has not yet been parsed). */ + private final boolean temporary_; + /** - * Create an instance of HtmlBody + * Creates an instance of HtmlBody. * * @param namespaceURI the URI that identifies an XML namespace. * @param qualifiedName The qualified name of the element type to instantiate * @param page The HtmlPage that contains this element. * @param attributes the initial attributes + * @param temporary whether or not this body is temporary (created because the <tt>body</tt> + * tag does not exist or has not yet been parsed) */ - HtmlBody(final String namespaceURI, final String qualifiedName, final HtmlPage page, - final Map<String, HtmlAttr> attributes) { + public HtmlBody(final String namespaceURI, final String qualifiedName, final HtmlPage page, + final Map<String, HtmlAttr> attributes, final boolean temporary) { + super(namespaceURI, qualifiedName, page, attributes); - - // force script object creation now to forward onXXX handlers to window + + temporary_ = temporary; + + // Force script object creation now to forward onXXX handlers to window. getScriptObject(); } @@ -166,4 +175,16 @@ public final String getAlinkAttribute() { return getAttributeValue("alink"); } + + /** + * Returns <tt>true</tt> if this body is temporary (created because the <tt>body</tt> tag + * has not yet been parsed). + * + * @return <tt>true</tt> if this body is temporary (created because the <tt>body</tt> tag + * has not yet been parsed) + */ + public final boolean isTemporary() { + return temporary_; + } + } Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlPage.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlPage.java 2008-02-28 01:17:03 UTC (rev 2487) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlPage.java 2008-02-28 01:33:41 UTC (rev 2488) @@ -194,6 +194,26 @@ } /** + * Returns the <tt>body</tt> element (or <tt>frameset</tt> element), or <tt>null</tt> if it does not yet exist. + * @return the <tt>body</tt> element (or <tt>frameset</tt> element), or <tt>null</tt> if it does not yet exist + */ + public HtmlElement getBody() { + + final HtmlElement doc = getDocumentHtmlElement(); + if (doc == null) { + return null; + } + + final List<String> tagNames = Arrays.asList(new String[] {"body", "frameset"}); + final List< ? extends HtmlElement> elements = doc.getHtmlElementsByTagNames(tagNames); + if (elements.isEmpty()) { + return null; + } + + return elements.get(0); + } + + /** * {@inheritDoc} */ @Override Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Document.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Document.java 2008-02-28 01:17:03 UTC (rev 2487) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Document.java 2008-02-28 01:33:41 UTC (rev 2488) @@ -74,6 +74,7 @@ import com.gargoylesoftware.htmlunit.html.DomNode; import com.gargoylesoftware.htmlunit.html.DomText; import com.gargoylesoftware.htmlunit.html.HTMLParser; +import com.gargoylesoftware.htmlunit.html.HtmlBody; import com.gargoylesoftware.htmlunit.html.HtmlDivision; import com.gargoylesoftware.htmlunit.html.HtmlElement; import com.gargoylesoftware.htmlunit.html.HtmlForm; @@ -348,45 +349,70 @@ } /** - * javascript function "write". + * JavaScript function "write". * @param content the content to write */ protected void write(final String content) { + getLog().debug("write: " + content); writeBuffer_.append(content); + // If open() was called; don't write to doc yet -- wait for call to close(). if (!writeInCurrentDocument_) { - getLog().debug("written content added to buffer"); + getLog().debug("wrote content to buffer"); + return; } - else { - // open() hasn't been called - final String bufferedContent = writeBuffer_.toString(); - if (canAlreadyBeParsed(bufferedContent)) { - writeBuffer_.setLength(0); - getLog().debug("parsing buffered content: " + bufferedContent); - final HtmlPage page = (HtmlPage) getDomNodeOrDie(); - // get the node at which end the parsed content should be added - HtmlElement current = getLastHtmlElement(page.getDocumentHtmlElement()); - getLog().debug("current: " + current); + // If the buffered content isn't complete and wellformed; don't write to doc yet. + final String bufferedContent = writeBuffer_.toString(); + if (!canAlreadyBeParsed(bufferedContent)) { + getLog().debug("write: not enough content to parsed it now"); + return; + } - // quick and dirty workaround as long as IFRAME JS object aren't an HTMLElement - if (current instanceof HtmlInlineFrame) { - current = (HtmlElement) current.getParentDomNode(); - } - ((HTMLElement) getJavaScriptNode(current)) - .jsxFunction_insertAdjacentHTML(HTMLElement.POSITION_BEFORE_END, bufferedContent); + // Let the user know that we can (and will) go ahead and write to the document. + getLog().debug("parsing buffered content: " + bufferedContent); + + // Clear the buffer. + writeBuffer_.setLength(0); + + // Get the node at which the parsed content should be added. + HtmlElement current; + final HtmlPage page = (HtmlPage) getDomNodeOrDie(); + final HtmlElement doc = page.getDocumentHtmlElement(); + HtmlElement body = page.getBody(); + if (body == null) { + // The body doesn't exist yet! Add it. + body = new HtmlBody(null, "body", page, null, true); + doc.appendChild(body); + current = body; + } + else { + if (body instanceof HtmlBody && ((HtmlBody) body).isTemporary()) { + // Add inside the (temporary) body. + current = body; } else { - getLog().debug("write: not enough content to parsed it now"); + // Add inside the current / last element. + current = getLastHtmlElement(doc); } } + + // Quick and dirty workaround for target (IFRAME JS object aren't an HTMLElement). + if (current instanceof HtmlInlineFrame) { + current = (HtmlElement) current.getParentDomNode(); + } + + // Append the new content. + ((HTMLElement) getJavaScriptNode(current)).jsxFunction_insertAdjacentHTML(HTMLElement.POSITION_BEFORE_END, + bufferedContent); } /** - * Indicates if the content is a well formed html snippet that can already be parsed to be added - * to the dom + * Indicates if the content is a well formed HTML snippet that can already be parsed to be added + * to the DOM. + * * @param content the html snippet * @return <code>false</code> if it not well formed */ @@ -724,6 +750,35 @@ } /** + * {@inheritDoc} + */ + @Override + public Object jsxFunction_appendChild(final Object childObject) { + if (limitAppendChildToIE() && !getBrowserVersion().isIE()) { + // Firefox does not allow insertion at the document level. + throw new RuntimeException("Node cannot be inserted at the specified point in the hierarchy."); + } + else { + // We're emulating IE; we can allow insertion. + return super.jsxFunction_appendChild(childObject); + } + } + + /** + * Returns <tt>true</tt> if this document only allows <tt>appendChild</tt> to be called on + * it when emulating IE. + * + * @return <tt>true</tt> if this document only allows <tt>appendChild</tt> to be called on + * it when emulating IE + * + * @see Document#limitAppendChildToIE() + * @see XMLDocument#limitAppendChildToIE() + */ + protected boolean limitAppendChildToIE() { + return true; + } + + /** * Create a new HTML element with the given tag name. * * @param tagName The tag name @@ -1037,15 +1092,12 @@ * @return this document's <tt>body</tt> element */ public Object jsxGet_body() { - final List<String> tagNames = Arrays.asList("body", "frameset"); - final List< ? extends HtmlElement> list = - getHtmlPage().getDocumentHtmlElement().getHtmlElementsByTagNames(tagNames); - if (list.isEmpty()) { - return null; + final HtmlElement body = getHtmlPage().getBody(); + if (body != null) { + return body.getScriptObject(); } else { - final DomNode bodyElement = list.get(0); - return getScriptableFor(bodyElement); + return null; } } Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Window.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Window.java 2008-02-28 01:17:03 UTC (rev 2487) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Window.java 2008-02-28 01:33:41 UTC (rev 2488) @@ -40,10 +40,8 @@ import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; -import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; -import java.util.List; import java.util.Map; import org.apache.commons.collections.Transformer; @@ -744,11 +742,9 @@ if (onload == null) { // NB: for IE, the onload of window is the one of the body element but not for Mozilla. final HtmlPage page = (HtmlPage) webWindow_.getEnclosedPage(); - final List<String> listTagNames = Arrays.asList(new String[] {"body", "frameset"}); - final List< ? extends HtmlElement> listElements = - page.getDocumentHtmlElement().getHtmlElementsByTagNames(listTagNames); - if (!listElements.isEmpty()) { - return listElements.get(0).getEventHandler("onload"); + final HtmlElement body = page.getBody(); + if (body != null) { + return body.getEventHandler("onload"); } else { return null; Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/XMLDocument.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/XMLDocument.java 2008-02-28 01:17:03 UTC (rev 2487) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/XMLDocument.java 2008-02-28 01:33:41 UTC (rev 2488) @@ -338,4 +338,12 @@ return null; } + /** + * {@inheritDoc} + */ + @Override + protected boolean limitAppendChildToIE() { + return false; + } + } Modified: trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/DocumentTest.java =================================================================== --- trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/DocumentTest.java 2008-02-28 01:17:03 UTC (rev 2487) +++ trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/DocumentTest.java 2008-02-28 01:33:41 UTC (rev 2488) @@ -624,12 +624,9 @@ */ @Test public void appendChildAtDocumentLevel() throws Exception { - if (notYetImplemented()) { - return; - } - appendChildAtDocumentLevel(BrowserVersion.FIREFOX_2); - appendChildAtDocumentLevel(BrowserVersion.INTERNET_EXPLORER_6_0, "0", "2", "HTML", "DIV", "1"); - appendChildAtDocumentLevel(BrowserVersion.INTERNET_EXPLORER_7_0, "0", "2", "HTML", "DIV", "1"); + appendChildAtDocumentLevel(BrowserVersion.FIREFOX_2, "1", "exception"); + appendChildAtDocumentLevel(BrowserVersion.INTERNET_EXPLORER_6_0, "1", "2", "HTML", "DIV", "1"); + appendChildAtDocumentLevel(BrowserVersion.INTERNET_EXPLORER_7_0, "1", "2", "HTML", "DIV", "1"); } private void appendChildAtDocumentLevel(final BrowserVersion version, final String... expected) @@ -642,12 +639,16 @@ + " function test() {\n" + " var div = document.createElement('div');\n" + " div.innerHTML = 'test';\n" - + " document.appendChild(div); // Error in FF\n" - + " alert(document.body.childNodes.length); // 0\n" - + " alert(document.childNodes.length); // 2\n" - + " alert(document.childNodes[0].tagName); // HTML\n" - + " alert(document.childNodes[1].tagName); // DIV\n" - + " alert(document.getElementsByTagName('div').length); // 1\n" + + " try {\n" + + " alert(document.childNodes.length); // 1\n" + + " document.appendChild(div); // Error in FF\n" + + " alert(document.childNodes.length); // 2\n" + + " alert(document.childNodes[0].tagName); // HTML\n" + + " alert(document.childNodes[1].tagName); // DIV\n" + + " alert(document.getElementsByTagName('div').length); // 1\n" + + " } catch(ex) {\n" + + " alert('exception');\n" + + " }\n" + " }\n" + " </script>\n" + " </head>\n" @@ -1462,6 +1463,112 @@ } /** + * Verifies that document.write() sends content to the correct destination (always somewhere in the body). + * @throws Exception if an error occurs + */ + @Test + public void testDocumentWrite_Destination() throws Exception { + testDocumentWrite_Destination(BrowserVersion.FIREFOX_2, "null", "[object HTMLBodyElement]", "s1 s2 s3 s4 s5"); + testDocumentWrite_Destination(BrowserVersion.INTERNET_EXPLORER_6_0, "null", "[object]", "s1 s2 s3 s4 s5"); + testDocumentWrite_Destination(BrowserVersion.INTERNET_EXPLORER_7_0, "null", "[object]", "s1 s2 s3 s4 s5"); + } + + private void testDocumentWrite_Destination(final BrowserVersion version, final String... expected) + throws Exception { + final String html = + " <html>\n" + + " <head>\n" + + " <script>alert(document.body);</script>\n" + + " <script>document.write('<span id=\"s1\">1</span>');</script>\n" + + " <script>alert(document.body);</script>\n" + + " <title>test</title>\n" + + " <script>document.write('<span id=\"s2\">2</span>');</script>\n" + + " </head>\n" + + " <body id='foo'>\n" + + " <script>document.write('<span id=\"s3\">3</span>');</script>\n" + + " <span id='s4'>4</span>\n" + + " <script>document.write('<span id=\"s5\">5</span>');</script>\n" + + " <script>\n" + + " var s = '';\n" + + " for(var n = document.body.firstChild; n; n = n.nextSibling) {\n" + + " if(n.id) {\n" + + " if(s.length > 0) s+= ' ';\n" + + " s += n.id;\n" + + " }\n" + + " }\n" + + " alert(s);\n" + + " </script>\n" + + " </body>\n" + + " </html>\n"; + final List<String> actual = new ArrayList<String>(); + loadPage(version, html, actual); + assertEquals(expected, actual); + } + + /** + * Verifies that document.write() sends content to the correct destination (always somewhere in the body), + * and that if a synthetic temporary body needs to be created, the attributes of the real body are eventually + * used once the body is parsed. + * @throws Exception if an error occurs + */ + @Test + public void testDocumentWrite_BodyAttributesKept() throws Exception { + testDocumentWrite_BodyAttributesKept(BrowserVersion.FIREFOX_2, "null", "[object HTMLBodyElement]", "", "foo"); + testDocumentWrite_BodyAttributesKept(BrowserVersion.INTERNET_EXPLORER_6_0, "null", "[object]", "", "foo"); + testDocumentWrite_BodyAttributesKept(BrowserVersion.INTERNET_EXPLORER_7_0, "null", "[object]", "", "foo"); + } + + private void testDocumentWrite_BodyAttributesKept(final BrowserVersion version, final String... expected) + throws Exception { + final String html = + " <html>\n" + + " <head>\n" + + " <script>alert(document.body);</script>\n" + + " <script>document.write('<span id=\"s1\">1</span>');</script>\n" + + " <script>alert(document.body);</script>\n" + + " <script>alert(document.body.id);</script>\n" + + " <title>test</title>\n" + + " </head>\n" + + " <body id='foo'>\n" + + " <script>alert(document.body.id);</script>\n" + + " </body>\n" + + " </html>\n"; + final List<String> actual = new ArrayList<String>(); + loadPage(version, html, actual); + assertEquals(expected, actual); + } + + /** + * Verifies that document.write() sends content to the correct destination (always somewhere in the body), + * and that script elements written to the document are executed in the correct order. + * @throws Exception if an error occurs + */ + @Test + public void testDocumentWrite_ScriptExecutionOrder() throws Exception { + testDocumentWrite_ScriptExecutionOrder(BrowserVersion.FIREFOX_2, "1", "2", "3"); + testDocumentWrite_ScriptExecutionOrder(BrowserVersion.INTERNET_EXPLORER_6_0, "1", "2", "3"); + testDocumentWrite_ScriptExecutionOrder(BrowserVersion.INTERNET_EXPLORER_7_0, "1", "2", "3"); + } + + private void testDocumentWrite_ScriptExecutionOrder(final BrowserVersion version, final String... expected) + throws Exception { + final String html = + " <html>\n" + + " <head>\n" + + " <title>test</title>\n" + + " <script>alert('1');</script>\n" + + " <script>document.write('<scrip'+'t>alert(\"2\")</s'+'cript>');</script>\n" + + " </head>\n" + + " <body>\n" + + " <script>document.write('<scrip'+'t>alert(\"3\")</s'+'cript>');</script>\n" + + " </body>\n" + + " </html>\n"; + final List<String> actual = new ArrayList<String>(); + loadPage(version, html, actual); + assertEquals(expected, actual); + } + + /** * @throws Exception if the test fails */ @Test @@ -1752,7 +1859,7 @@ } /** - * Firefox supports document.all ... but it is "hidden" + * Firefox supports document.all, but it is "hidden". * @throws Exception If the test fails. */ @Test @@ -3110,9 +3217,6 @@ */ @Test public void noBodyTag() throws Exception { - if (notYetImplemented()) { - return; - } noBodyTag(BrowserVersion.FIREFOX_2, new String[] {"1: null", "2: null", "3: [object HTMLBodyElement]"}); noBodyTag(BrowserVersion.INTERNET_EXPLORER_6_0, new String[] {"1: null", "2: [object]", "3: [object]"}); noBodyTag(BrowserVersion.INTERNET_EXPLORER_7_0, new String[] {"1: null", "2: [object]", "3: [object]"}); @@ -3141,9 +3245,6 @@ */ @Test public void noBodyTag_IFrame() throws Exception { - if (notYetImplemented()) { - return; - } noBodyTag_IFrame(BrowserVersion.FIREFOX_2, "1: [object HTMLBodyElement]", "2: [object HTMLBodyElement]"); noBodyTag_IFrame(BrowserVersion.INTERNET_EXPLORER_6_0, "1: null", "2: [object]"); noBodyTag_IFrame(BrowserVersion.INTERNET_EXPLORER_7_0, "1: null", "2: [object]"); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |