« AS3 Documentation and Libraries | Main | A Sabbatical, Adobe, and Allaire »

Update to Embedding HTML in a Flex Application

An update to this example for the final version of Flex 2 can be found here.

I updated the files for Embedding HTML in a Flex application in AS3 in this directory. I didn't test the files with beta 2, but they should work with the upcoming beta 3.

One important change is in the HTML wrapper, which was causing the HTML to sometimes disappear when using IE. There needs to be a parm setting wmode to opaque. I also updated the HTML wrapper to a newer version, and made a few other minor changes (which I would list, but it's been so long I've forgotten them...)

The migration text I promised a long time ago doesn't look like it'll ever get completed, so I'm just going to copy the 80% done version below for those interested.

When migrating Christophe's solution, Embedding HTML in a Flex application using an IFrame to Flex 2, I kept detailed notes of what I was doing. Below is the prettified version of these notes.

The Easy Changes

After writing this part of the migration explanation, I realized it wasn't really necessary, that it's easy for anybody to compile, see the errors, and look up in the help system any of the errors that come up. This worked very well, and I was easily able to figure out most of the issues I came across. But I kept writing things out, so here's the full migration info for those interested.

I took the compile-fix-repeat method of fixing the issues. A studying of a migration guides along with a more structured search and replace would make more sense for a large project, but I knew some of the issues already, and I'm only converting three files.

The first thing I did, without thinking, was change the mxml namespace from "http://www.macromedia.com/2003/mxml" to "http://www.macromedia.com/2005/mxml". The next change I made with my eyes closed was to add access modifiers to functions and type declarations variables. So "function moveIFrame()" became "private function moveIFrame()".

Adding a type declaration of Object to pt gave me the Error "Implicit coercion of a value with static type 'Object' to a possibly unrelated type 'flash.geom:Point'". This made it obvious that I needed to change:

var pt:Object={x:0, y:0};

to:

var pt:Point=new Point(0, 0);

After that, I compile the add and got the error "Overriding function that is not marked for override" in IFrame.mxml, which extends Canvas, on this method:

public function set visible(visible: Boolean): Void {

That's another thing I should done off the bat, which is add override to methods that override:

override public function set visible(visible: Boolean): Void {

Next I'm told that getURL doesn't exist:

getURL("javascript:hideIFrame()");

I search the help and see that this line now needs to be:

public var u:URLRequest = new URLRequest("javascript:hideIFrame()");
navigateToURL(u);

And I add "import flash.net.navigateToURL;" to the top of the Script block.

Next I saw "Type annotation is not a compile-time constant: Void", which means I needed to change Void to void everywhere I see it.

doLater() showed up as removed, so after searching the docs I changed this it to callLater, from:

doLater(this, 'moveIFrame')

to:

callLater(moveIFrame)

Dealing with HTML and ExternalInterface

At this point everything compiled fine. I put index.htm into the directory where the SWF was (since I couldn't tell Flex Builder to use a custom html wrapper) and then clicked on the file to display... nothing. Ah yes, the SWF name was different now, from IFrameDemo.mxml.swf to IFrameDemo.swf. So I load it again and... nothing. I load just the SWF and it displays. I take the script out of the HTML page and see this error from Flash:

SecurityError: Error #2051: Security sandbox violation: 'file:///C:/dev/flex/projects/iframe/IFrameDemo.swf' may not evaluate scripting URLs within 'file:///C:/dev/flex/projects/iframe/index2.htm'.

I remembered that there was a new restriction in Player 8 (and 8.5) where local files and network files could not be accessed in the same movie. I wondered if relative URLs were thought to be network files. Sure enough, when I loaded the SWF through JRun, I didn't get the error anymore. But the page within the page still didn't show up. I figured out that unlike getURL(), navigateToURL() would not work allow any frame to be given as the second argument. So I decided to go ahead and convert the navigateToURL() calls to ExternalInterface.

This took awhile. Converting the navigateToURL() calls was easy, as the ExternalInterface calls were very simple, like this:

ExternalInterface.call("loadIFrame", source);

But still the html page was not showing up. What was going on?

At this point I conceived my my "debugging strategy" in Javascript, which consisted of looking at Firefox's Javascript console and throwing alerts up as debug statements. Ug. Is there a better way to do this? After sifting through the methods, I figured out that only the first argument to moveIFrame had all of argument information in it. So I changed:

ExternalInterface.call("moveIFrame", pt.x+","+pt.y+","+this.width+","+this.height);

to:

ExternalInterface.call("moveIFrame", pt.x, pt.y, this.width, this.height);

Once changed, the html finally showed up. But the frame showed up in the upper left hand corner. localToGlobal did not look to be working correctly.

var newPt = this.localToGlobal(pt);

After this, everything finally worked!


Making Things Better

The one problem I had at first with the generated html in Flex Builder was that I didn't know there was a to interject Javascript into the page. (html-template)
Add the Javascript functions (moveFrame, etc). Added onMouseDown="document.body.focus();" to the embed, alhtough not sure if htat was needed. Also added + 'wmode="opaque"'
+ 'swLiveConnect="true"' to the embed. Added the iframe named 'myFrame'.

The Tree on the left still looked really odd. Apparently the......

Tried adding "rootVisible="false""

Change the change attribute value in Tree from :

iFrame.source=tree.selectedNode.attributes.path

to

iFrame.source=tree.selectedNode.path

I made a few cleanup changes. The VBScript and related Javascript method in index.htm were removed, since it was only needed for some commented-out fscommands. In IFrame.mxml, I added a check for ExternalInterface via ExternalInterface.available, throwing an Error if it wasn't available. In IFrameDemo.mxml, I added a third section of links for Flex sites.

Comments (13)

Darren:

We found that (in Beta 1) by setting wmode=opaque inexplicably stops shift-tab from working (I suspect it is interfering with shift and ctrl keys from being detected by flash).

Have you found the same thing? (we have logged a bug in the Flex forums about this0.

Daniel:

Has anyone managed to get this to work in Flex 2 Final. It is creating a pop-up window on my system instead of a iFrame in IE6.

Anthony:


Ditto - I can't get this to work in Flex 2 Final and I would be beyond grateful if you could pass along some hints as to what we might change.

Cheers!

Brian:

I haven't had the chance to look into it, although it's still on the short-list of things to do for Flex outside of work. If anybody else has a working solution, please comment, or email me and I'd be happy to link to it.

MySchizoBuddy:

So this way I can embed Quicktime movies directly inside flex, or is there a better way to do that.

Brian:

This is probably the second-best way to embed Quicktime movies. The best way, when possible, is to convert the Quicktime movie to FLV and use the FLV.

Steve:

Any progress on getting this to work with the final version of Flex 2? This is a HUGE enabler for lots of us using FLEX and immediately opens up all sorts of possibilities. Any help / advice would be greatly appreciated. Thanks.

Brian:

Hi Steve, I still haven't started this. If anybody else is updating these files, please let me know, as I would be happy to link to a finished version for Flex 2! If not, know that I'm still planning to do this, but I haven't found the full day I need for an update. Next weekend doesn't look full yet, so we shall see...

Rob:

FYI, these files work just fine for me. The only change I had to make was in the HTML file. Change the major revision from 8 to 9 and the minor revision from 5 to 0, and it will work.

The sizing didn't quite work out as planned. When I opened the browser window, the Iframe was too small. But I also modified the loadIFrame method to accept height and width parameters from my application, and things went smoothly from that point. Resize did not work for me, but for my purposes, I do not need it.

At any rate, thought it might be helpful to let you all know that this code is functional. You just have to change the revision to get the IFrame going. Pz.

Mike:

The revision number changes don't work for me...anybody else get this going?

Brian Deitte:

Mike, try the updated version of these files: http://www.deitte.com/archives/2006/08/finally_updated.htm

Dear sir
i am a Final year MCA student doing project on flex.
i downloaded your project and tried to run this but got problem...page was not displaying..i have a very similar requirement where i want to displayed multiple Flex builder compiled html in to single flex application..it will be great if you help me...
i am using flex builder3 for developing the application....

doesn't work on flex 2??