Phlip
2006-Dec-16  17:55 UTC
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... ;-) ]
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?
-- 
  Phlip
  http://www.greencheese.us/ZeekLand <-- NOT a blog!!! 
--~--~---------~--~----~------------~-------~--~----~
 You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---
Phlip
2006-Dec-16  18:21 UTC
Re: foist javascript into another frame, and evaluate it in the target context
> Firefox updates the inner <span id=''update_me''>, and IE updates the outer > one.I figured it out, but I''m keeping it a secret because I want to be the only one who knows how to do it. Oooh, okay, read this: http://johnvey.com/features/deliciousdirector/web-service-broker.html Then do this: function update_grinder(sauce) { var grinder = $(''grinder''); grinder.src=''javascript:void(function(){''+sauce+''}())''; }> -- > Phlip > http://www.greencheese.us/ZeekLand <-- NOT a blog!!!--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---