In short – externalInterface is the work of the devil.
There are others that have a low opinion of it.
- “In general, whoever coded ExternalInterface should be fired.”
- “ExternalInterface bug (Firefox)”
- “ExternalInterface Bug in Flash Player 9“
- “The official Adobe Buglist“
So far the issue I have found seems to affect the interaction between Windows Media Center, FlashPlayer 9.16.0 (FlashPlayer 8 does not have the issue) and Flash SWFs that use externalInterface.
But there is a solution.
externalInterface is much nicer than fsCommand but suffers from some of the same problems when it comes to adding Flash to a page dynamically. In a previous post I have outlined a workaround.
The issue with externalInterface is very different which seems to center on that fact that it injects its own JavaScript code into window.parent
If you have seen the movie Terminator, there is a scene where Arnie walks up to biker and punches him in a chest and pulls out his still beating heart. Imagine that played back in reverse and you have a fair idea of what FlashPlayer 9 does to the browser.
eg
// Look for the 'standard' functions that flash adds to window.parent
if (window.parent.__flash__toXML != null)
{
alert("window.parent.__flash__toXML exists");
}
else
{
alert("window.parent.__flash__toXML not there");
}
Windows Media Center runs HTML applications in a shell of IE. It’s IE plus a series of objects that you can script against to do MCE specific operations. It also behaves differently to IE in one critical aspect.
In WMC, when running an application, if you play a movie full screen or use one of the hot keys to browse forward, including the magic green button and then at a later time browse back to the application by hitting the “BACK” button, the BODY.onload event fires again.
In an application that has no embedded Flash SWFs this can be handled in JavaScript by setting a simple flag – but if your application embeds SWFs that use externalInterface and you have FlashPlayer 9 installed – your SWF dies. You get a white screen of “not really there”. The SWF is still running. It’s still able to call into JavaScript, but you can’t call it and there is no way to make it start displaying again.
This does not happen with the FlashPlayer 8. Something has changed. Either the window.parent fisting is broken, or FlashPlayer 9 listens to BODY.onload and is doing something extra that is just not kosher for WMC.
I suspect that in WMC, window.parent may be something other than what FlashPlayer9 is expecting. I’m still exploring the specifics of this.
The solution is to give Arnie a cardboard cutout to insert its giblets into and that can be achieved by embedding your SWF or even your whole application in an IFRAME. This guarantees that window.parent, if called from within the IFRAME is the document that embedded the IFRAME.
Arnie shoves his fist from the IFRAME into your parent document, and not somewhere unexpected.
I’m working on an addition to the MetaWrap JavaScript libraries that will include a lot of WMC support, in particular for remoting applications and dealing with flash. Will post and update when its released.
Not sure if this helps you, but there is a way to differentiate between a "real" window.onload event and a ‘fake’ one seen by hitting the back button. The trick involves creating a hidden form and form field while the page is loading with a document.write. Then, after the page is loaded, write the text ‘pageloaded’ into this page form. Now, when the user leaves the page then comes back to it with the back button, the browser’s form autosave feature will save this text; if you grab the form field through the DOM and see the text ‘pageloaded’ in there, then this is a fake onload; if it isn’t there, then it’s a real one. You might be able to use this to create a higher-level workaround for Flash 9.
Best,
Brad Neuberg
Weblog: http://codinginparadise.org
TA – now that’s lateral thinking.
Luckily the JavaScript state is preserved so I can just set a flag to true on the first BODY.onload and check for it in future onloads.
Just a quick idea, couldn’t you write something like:
window.parent = window.parent || window;
That would gave Arnie the window…
Another good idea.
That could confuse other things as well, assuming that the browser lets you reassign window.parent 🙂
Here is a great bug!
FLASH + IE + HTTPS + XML + NoCache = Bad
http://www.blog.lessrain.com/?p=276