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.
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.
// Look for the 'standard' functions that flash adds to window.parent
if (window.parent.__flash__toXML != null)
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.
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.
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.
TA – now that’s lateral thinking.
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