foist javascript into another frame, and evaluate it in the target context

[This post is here, under marginal topicality, because I'm awaiting approval to get on the Rails-spinoffs mailing list.

[Hope the post doesn't influence the approval... :wink: ]

I have an outer page and an inner iframe. The outer page calculates some javascript, and wants the inner frame to run it. The inner frame should hit a page on the same (private) web server, so this is not a cross-site scripting attack. But I would prefer not to taint the target page with any extra logic to do this. (I will if I must.)

The calling page has these elements:

<script src="/javascripts/prototype.js" type="text/javascript" />... <span id='update_me'>yo2</span> <iframe id='grinder' src='sample.html' > </iframe>

So here's most of the page which the iframe hits:

<script src="/javascripts/prototype.js" type="text/javascript" />... <body bgcolor='silver'>     <span id='update_me'>yo</span> </body></html>

Note that both the outer and inner page have a span with the same ID.

This question will resemble a JavaScript FAQ - how to evaluate Javascript on the fly, or how to reload a JS file. The answers on the web generally do not transport the JS across a frame boundary, so they don't address the bug I encountered, and I can't tell if prototype.js or IE is at fault.

The outer page calls Ajax goodies that generate some JS looking like this:

   Element.update("update_me", "here I B");

The page sends that, as a string, into this JS (in application.js):

  function update_grinder(sauce)   {     var grinder = $('grinder');

    if (grinder)     {     var doc = grinder.contentDocument;     if (!doc) doc = grinder.document;     if (doc)       {       evaluate(doc, sauce);       return;       }     }     document.write("your browser sucks");   }

So that contains enough logic to find the iframe's document, and it works for Firefox, IE, Konqueror, and Opera. The code calls evaluate() with the document where we need the evaluation context, and the string with our source.

Here's evaluate():

  function evaluate(doc, sauce)   {     var s = doc.createElement('script');     //s.defer = true; // <-- no effect     s.text = sauce;     var body = doc.getElementsByTagName('body').item(0);

    if (body)       {       body.appendChild(s);       return;       }     body = doc.body;     if (body)       {       body.appendChild(s);       return;       }   }

That creates a <script> block, sticks our string in as its contents, and pushes the block to the end of our <body> tag. Now here's the bug:

Firefox updates the inner <span id='update_me'>, and IE updates the outer one.

If I remove the outer <span id='update_me'>, then IE simply can't find it and throws an error. Even though it evaluates a script block clearly in the context of the inner iframe.

I have tried calling the script from setTimeout, and from a button's onclick handler.

Is there some script.aculo.us way to fix (yet another) bug in IE? Or is this a bug in prototype.js?