[ htmlunit-Bugs-1192854 ] frames[i] return null for frames generated by document.write

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[ htmlunit-Bugs-1192854 ] frames[i] return null for frames generated by document.write

SourceForge.net
Bugs item #1192854, was opened at 2005-04-30 04:14
Message generated for change (Comment added) made by sheldong
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=448266&aid=1192854&group_id=47038

Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: None
Group: 1.5
Status: Open
Resolution: None
Priority: 5
Submitted By: xingj (xingj)
Assigned to: Nobody/Anonymous (nobody)
Summary: frames[i] return null for frames generated by document.write

Initial Comment:
This problem happens when using javascript to create
frames and then trying to access these frames
by ".frames[i]", which is always a "null".  

Example to reproduce this problem:

<html>
<script language="javascript">
var root=this;
function listframes(frame) {
    if (frame == null) {
        alert("frame=null.\n");
    } else {
        alert("frame=OK\n href="+frame.location.href+"\n");
        var i;
        var len;
        len = frame.frames.length;
        alert(" frames.length="+len+"\n");
        for (i=0;i<len;i++) {
            listframes(frame.frames[i]);
        }
    }
}

document.write('<frameset id="frameset1"
rows="50,50"><frame id="frame1-1"
src="about:blank"><frame id="frame1-2"
src="about:blank"></frameset>');

listframes(root);

</script>
</html>

When visiting this page in htmlunit 1.5, the alerts log is
something like:

Java Script is enabled.
Redirect is enabled.
Hello, World!
frame=OK
 href=http://myserver/1.html
 frames.length=2
frame=null.
frame=null.

When visiting this page in IE6, the alerts are something
like:

frame=OK
 href=http://myserver/1.html
 frames.length=2
frame=OK
 href=about:blank
 frames.length=0
frame=OK
 href=about:blank
 frames.length=0

The length seems OK, but not the frames[i].  If the
frames were defined by pure html tags, not by javascript
document.write, everything is fine.

Any clues? Or any idea where to debugging this?  
Glimpse over the source files in the htmluni 1.5, it
seems have to investigate places inside
ElementArray.java.  Any suggestions?

----------------------------------------------------------------------

Comment By: sheldong (sheldong)
Date: 2005-10-12 22:31

Message:
Logged In: YES
user_id=1075416

Here is the Unit Test:

            public void testFrameTag1192854() throws Exception {
            final WebClient webClient = new WebClient();
            webClient.setJavaScriptEnabled(true);
           
                final String htmlContent
                    = "<html>\n"
                    + "<script language=\javascript\>\n"
                    + "var root=this;"
                    + "function listframes(frame) {\n"
                    + "if (frame == null) {\n"
                    + "alert(\frame=null\);\n"
                    + "} else {\n"
                    + "alert(\frame=OK\);\n"
                    + "var i;\n"
                    + "var len;\n"
                    + "len = frame.frames.length;\n"
                    + "alert(\frames.length=\+len);\n"
                    + "for (i=0;i<len;i++) {\n"
                    + "listframes(frame.frames[i]);\n"
                    + "}\n"
                    + "}\n"
                    + "}\n"
                    + "document.write('<frameset id=\frameset1\ "
                    + "rows=\50,50\><frame id=\frame1-1\ "
                    + "src=\about:blank\><frame id=\frame1-2\ "
                    + "src=\about:blank\></frameset>');\n"
                    + "listframes(root);\n"
                    + "</script>\n"
                    + "</html>";
                final WebResponse webResponse = new
StringWebResponse(htmlContent);
                final HtmlPage page = HTMLParser.parse(webResponse,
webClient.getCurrentWindow());
                final List collectedAlerts = new ArrayList();
                final List expectedAlerts = Arrays.asList( new
String[]{"frame=OK",
                "frames.length=2",
                "frame=OK",
                "frames.length=0",
                "frame=OK",
                "frames.length=0"});
               
                loadPage(htmlContent,collectedAlerts);

                assertEquals(collectedAlerts,expectedAlerts);
            }

----------------------------------------------------------------------

Comment By: Marc Guillemot (mguillem)
Date: 2005-05-30 07:56

Message:
Logged In: YES
user_id=402164

xingj, can you provide your suggested fix as diffs. This is
really easier to apply.

----------------------------------------------------------------------

Comment By: xingj (xingj)
Date: 2005-05-29 12:21

Message:
Logged In: YES
user_id=1269645

Here is my suggested fix:

in HTMLElement.java
================

    private Collection parseHtmlSnippet(final String
htmlSnippet) {
        if (htmlSnippet.indexOf('<') >= 0) {
            // build a pseudo WebResponse
            final WebClient webClient = getDomNodeOrDie
().getPage().getWebClient();
            final boolean jsEnabled =
webClient.isJavaScriptEnabled();
            // disable js while interpreting the html snippet: it
only needs to be interpreted
            // when integrated in the real page
            webClient.setJavaScriptEnabled(false);

            final WebResponse webResp = new
StringWebResponse("<html><body>" + htmlSnippet
+ "</body></html>",
                    getDomNodeOrDie().getPage
().getWebResponse().getUrl());
            try {
                final WebWindow pseudoWindow = new
WebWindow() {
                    public Page getEnclosedPage() {
                        return null;
                    }
                    public String getName() {
                        return null;
                    }
                    public void setName(final String name) {
                        // nothing
                    }
                    public WebWindow getParentWindow() {
                        return null;
                    }
                    public Object getScriptObject() {
                        return null;
                    }
                    public WebWindow getTopWindow() {
                        return null;
                    }
                    public WebClient getWebClient() {
                        return webClient;
                    }
                    public void setEnclosedPage(final Page page) {
                    }
                    public void setScriptObject(final Object
scriptObject) {
                    }
                };
                final HtmlPage pseudoPage = HTMLParser.parse
(webResp, pseudoWindow);
                final HtmlBody body = (HtmlBody)
pseudoPage.getDocumentElement().getFirstChild();
               
                final Collection nodes = new ArrayList();

                // ************************
                //    Patch part 1
                // ************************
       
                boolean statusJavaScriptEnabled =
webClient.isJavaScriptEnabled();
                webClient.setJavaScriptEnabled(true);
               
                // end of patch part 1

                for (final Iterator iter = body.getChildIterator();
iter.hasNext();) {
                    final DomNode child = (DomNode) iter.next();
                    nodes.add(copy(child, getHtmlElementOrDie
().getPage()));
                }
                // ************************
                //    Patch part 2
                // ************************

                webClient.setJavaScriptEnabled
(statusJavaScriptEnabled);

                // end of patch part 2

                return nodes;
            }
            catch (final Exception e) {
                getLog().error("Unexpected exception occured
while parsing html snippet", e);
                throw Context.reportRuntimeError("Unexpected
exception occured while parsing html snippet: "
                        + e.getMessage());
            }
            finally {
                // set javascript enabled back to original state
                webClient.setJavaScriptEnabled(jsEnabled);
            }
        }
        else {
            // just text, keep it simple
            final DomNode node = new DomText
(getDomNodeOrDie().getPage(), htmlSnippet);
            return Collections.singleton(node);
        }
    }

    /**
     * Copies the node to make it available to the page.
     * All this stuff just to change the htmlPage_ property on
all nodes!
     *
     * @param node The node to copy.
     * @param page The page containing the node.
     * @return a node with the same properties but bound to
the page.
     */
    private DomNode copy(final DomNode node, final
HtmlPage page) {
        final DomNode copy;
        if (node instanceof DomText) {
            copy = new DomText(page, node.getNodeValue());
        }
        else {
            final HtmlElement htmlElt = (HtmlElement) node;
            final IElementFactory factory =
HTMLParser.getFactory(htmlElt.getNodeName());
            copy = factory.createElement(page,
node.getNodeName(), readAttributes(htmlElt));
            for (final Iterator iter = node.getChildIterator();
iter.hasNext();) {
                final DomNode child = (DomNode) iter.next();
                copy.appendChild(copy(child, page));
            }
        }

        // ************************
        //    Patch part 3
        // ************************
        //
        // Workaround to enable JavaScript running inside
htmlSnippet.
        //
        // HtmlUnit doesn't set the scriptObject correctly for
frame object (it always put a null there).
        // So I need to set it manually.

        if (node instanceof BaseFrame) {
        ((BaseFrame)copy).getEnclosedWindow
().setScriptObject(copy.getScriptObject());
        }

        // end of patch part 3

        return copy;
    }


----------------------------------------------------------------------

You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=448266&aid=1192854&group_id=47038


-------------------------------------------------------
This SF.Net email is sponsored by:
Power Architecture Resource Center: Free content, downloads, discussions,
and more. http://solutions.newsforge.com/ibmarch.tmpl
_______________________________________________
HtmlUnit-develop mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/htmlunit-develop