views:

33

answers:

2

I'm trying to write a web application using the new offline capabilities of HTML5. In this application, I'd like to be able to edit some HTML—a full document, not a fragment—in a <textarea>, press a button and then populate a new browser window (or <iframe>, haven't decided yet) with the HTML found in the <textarea>. The new content is not persisted anywhere except the local client, so setting the source on the window.open call or the src attribute on an <iframe> is not going to work.

I found the following question on StackOverflow: "Putting HTML from the current page into a new window", which got me part of the way there. It seems this technique works well with fragments, but I was unsuccessful in getting an entirely new HTML document loaded. The strange thing is when I view the DOM in Firebug, I see the new HTML—it just doesn't render.

Is it possible to render a generated HTML document in a new window or <iframe>?

EDIT: Here's a "working" example of how I'm attempting to accomplish this:

<!doctype html>
<html>
<head>
<title>Test new DOM</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"&gt;&lt;/script&gt;
<script>
    function runonload() {
        return $("#newcode")[0].value;
    }
    $(function() {
        $("#runit").click(function() {
            w=window.open("");
            $(w.document).ready(function() {
                $(w.document).html(w.opener.runonload());
            });
        });
    });
</script>
</head>
<body>
<textarea id="newcode">
&lt;!doctype html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;title&gt;New Page Test&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;h1&gt;Testing 1 2 3&lt;/h1&gt;
&lt;/body&gt;
&lt;/html&gt;
</textarea>
<br/>
<button id="runit">Run it!</button>
</body>
</html>
+4  A: 

I think you are overcomplicating this...

try this:

<SCRIPT LANGUAGE="JavaScript">
function displayHTML(form) {
var inf = form.htmlArea.value;
win = window.open(", ", 'popup', 'toolbar = no, status = no'); win.document.write("" + inf + ""); } // </script>
<form>
<textarea name="htmlArea" cols=60 rows=12> </textarea> <br> <input type="button" value=" Preview HTML (New Window)" onclick="displayHTML(this.form)"> </form>
Darren Westall
+1, but a little later than @bobince. Also, I didn't have my <textarea> in a <form> because clicking the button would submit the form and cause the page to refresh, which caused the script on the source page to halt. In hindsight, it seems the best approach would be to leave the <form> in there and return false from the click handler to prevent the event from bubbling.
technomalogical
Later? Looks like first from the timestamps here! +1. @technomalogical: it's generally best to cancel form submissions in `form.onsubmit`, to stop Enter presses submitting the form in all cases.
bobince
@bobince: thanks for the form.onsubmit tip. As for the timestamp, I redact my original comment and now state that you gave a more thorough answer :) I wish I could award both of you with the answer!
technomalogical
Simple answer for a simple question ;) hehe
Darren Westall
@Darren: I started learning the DOM and vanilla JavaScript *after* learning jQuery, as I didn't know about document.write. Looks like I need to go back and learn some of the "old-school" techniques! You're right though, sometimes the simplest is the best.
technomalogical
+3  A: 
$(w.document).html(w.opener.runonload());

You can't set innerHTML—or, consequently, jQuery's html()—on a Document object itself.

Even if you could, you wouldn't be able to do it using html(), because that parses the given markup in the context of an element (usually <div>) from the current document. The doctype declaration won't fit/work, putting <html>/<body>/etc inside a <div> is invalid, and trying to insert the elements it creates from the current ownerDocument into a different document should give a WRONG_DOCUMENT_ERR DOMException. (Some browsers let you get away with that bit though.)

This is a case where the old-school way is still the best:

w= window.open('', '_blank');
w.document.write($('#newcode').val());
w.document.close();

Whilst you can inject innerHTML into a pop-up's document.documentElement, if you do it that way you don't get the chance to set a <!DOCTYPE>, which means the page is stuck in nasty old Quirks Mode.

bobince
I came up with a similar solution, but didn't realize that I could write the document out immediately (I was waiting for the blank document in the new window to load first... silly, I know). Thanks for the great answer.
technomalogical