Flex IFrame – Web browser in flash (update)

Clipboard02

You can not have a web browser inside your web flash applications right? Well, you can! This solution uses html iframe to generate fake build in browser. So the behaviour of the browser in flash is the same as the one you are previewing this flash in (it is the same one). The best part of it is, you can manipulate with the position and size of this browser directly from flash. sk.yoz.html.IFrame solution was inspired by Alistair Rutherford, www.netthreads.co.uk.

Flex Iframe application

Core of this thing is sk.yoz.html.IFrame class. It extends Canvas that is used to inherit properties and methods for positioning and sizing. There is one in order to make it work – every IFrame element must have id!

package sk.yoz.html
{
    import flash.events.Event;
    import flash.external.ExternalInterface;
    import flash.geom.Point;
    
    import mx.containers.Canvas;

    public class IFrame extends Canvas
    {
        public var methodResize:String = "FlexIFrame.resize";
        public var methodMove:String = "FlexIFrame.move";
        public var methodNavigate:String = "FlexIFrame.navigate";
        public var methodVisibility:String = "FlexIFrame.visibility";
        
        public var positionChanged:Boolean = false;
        public var sizeChanged:Boolean = false;
        
        private var _autoResize:Boolean = false;
        private var _url:String = '';
        
        public function IFrame()
        {
            super();
            addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler)
        }
        
        override public function set id(value:String):void
        {
            super.id = value;
        }
        
        protected function addedToStageHandler(event:Event):void
        {
            positionChanged = true;
            sizeChanged = true;
            invalidateProperties();
        }
        
        public function set autoResize(value:Boolean):void
        {
            _autoResize = value;
            if(value)
                addEventListener(Event.RESIZE, autoResizeHandler);
            else
                removeEventListener(Event.RESIZE, autoResizeHandler);
        }
        
        public function get autoResize():Boolean
        {
            return _autoResize;
        }
        
        protected function autoResizeHandler(event:Event):void
        {
            positionChanged = true;
            sizeChanged = true;
            invalidateProperties();
        }
        
        override protected function commitProperties():void
        {
            super.commitProperties();
            
            if(positionChanged)
            {
                var point:Point = localToGlobal(new Point(0, 0));
                callJS(methodMove, point.x, point.y);
                positionChanged = false;
            }
            
            if(sizeChanged)
            {
                callJS(methodResize, width, height);
                sizeChanged = false;
            }
        }
        
        public function set url(value:String):void
        {
            _url = value;
            callJS(methodNavigate, value)
        }
        
        public function get url():String
        {
            return _url;
        }
        
        protected function callJS(method:String, ... values):void
        {
            if(!id)
                throw new Error("IFrame id is not defined");
            var args:Array = [method, id];
            try
            {
                ExternalInterface.call.apply(ExternalInterface, args.concat(values));
            }
            catch(error:Error)
            {
                trace(error.message);
            }
        }
        
        override public function set visible(value:Boolean):void
        {
            super.visible = value;
            callJS(methodVisibility, value);
        }
        
        override public function set width(value:Number):void
        {
            super.width = value;
            callJS(methodResize, value, height);
        }
        
        override public function set height(value:Number):void
        {
            super.height = value;
            callJS(methodResize, width, value);
        }
        
        override public function set x(value:Number):void
        {
            super.x = value;
            var point:Point = localToGlobal(new Point(0, 0));
            callJS(methodMove, point.x, point.y);
        }
        
        override public function set y(value:Number):void
        {
            super.y = value;
            var point:Point = localToGlobal(new Point(0, 0));
            callJS(methodMove, point.x, point.y);
        }
    }
}

FlexIFrame.js is JavaScript file. It uses your flex IFrame id from to create (html iframe) or use html element (any element) with the same id (id in flash = id in html). So you can use your prefabricated html elements (banners etc).

var FlexIFrame = {
    get: function(id)
    {
        var iframe = document.getElementById(id);
        if(!iframe)
            return FlexIFrame.create(id);
        return iframe;
    },

    create: function(id)
    {
        var iframe = document.createElement('iframe');
        iframe.id = id;
        iframe.frameborder = 0;
        iframe.style.position = "absolute";
        iframe.style.zIndex = 1;
        iframe.style.border = "none";
        document.body.insertBefore(iframe, document.body.firstChild);
        return iframe;
    },

    resize: function(id, width, height)
    {
        var iframe = FlexIFrame.get(id);
        iframe.style.width = width + "px";
        iframe.style.height = height + "px";
    },

    move: function(id, x, y)
    {
        var iframe = FlexIFrame.get(id);
        iframe.style.left = x + "px";
        iframe.style.top = y + "px";
    },

    navigate: function(id, url)
    {
        var iframe = FlexIFrame.get(id);
        iframe.src = url;
    },

    visibility: function(id, visible)
    {
        var iframe = FlexIFrame.get(id);
        iframe.style.display = visible ? "block" : "none";
    }
}

This is simple applicationion presenting draggable TitleWindow with “web browser” inside:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" applicationComplete="init()" xmlns:html="sk.yoz.html.*">
<mx:Script>
<![CDATA[
    private function init():void
    {
        go();
    }
    
    private function go():void
    {
        iframe.url = iframeURL.text;
    }
    
    private function mouseDownHandler():void
    {
        container.startDrag();
        container.addEventListener(Event.ENTER_FRAME, enterFrameDrag);
    }
    
    private function mouseUpHandler():void
    {
        container.stopDrag();
    }
    
    private function enterFrameDrag(event:Event):void
    {
        iframe.positionChanged = true;
        iframe.invalidateProperties();
    }
]]>
</mx:Script>
<mx:TitleWindow id="container" layout="vertical" width="300" height="300"
    mouseDown="mouseDownHandler()" mouseUp="mouseUpHandler()" >
    <mx:HBox width="100%">
        <mx:TextInput id="iframeURL" text="http://blog.yoz.sk" width="100%"
            enter="go()"/>
        <mx:Button label="Go" click="go()"/>
    </mx:HBox>
    <html:IFrame width="100%" height="100%" id="iframe" autoResize="true"/>
</mx:TitleWindow>
</mx:Application>

Finally do not forget to add flexiframe.js into your .html file:

<html>
    <head>
        <script type="text/javascript" src="js/flexiframe.js"></script>
        ...

Update (Feb 8, 2010): flexiframe.js resize() method uses style property for width and height (instead of original html element width, height)

35 comments so far

  1. Polprav November 3, 2009 02:30

    Hello from Russia!
    Can I quote a post “No teme” in your blog with the link to you?

  2. Jozef Chúťka November 3, 2009 10:27

    sure

  3. […] post connects my 3 previous posts: Flex IFrame – Web browser in flash, FacebookLogger and Facebook Extended Permissions With Authorization by Overriding Class in swc in […]

  4. […] import flexiframe.js used for positioning html input on correct […]

  5. Pedro Varela March 16, 2010 21:59

    Hey Jozef.. yeap you are right! we can have HTML on our flash apps.. but the IFrame is the wors’t thing we can have in a Flex app, why? Because all PopUps will remain behind the IFrame, you have to implement workarounds like hiding the IFrame if a PopUp has to show, other little terrible thing, is that you have to relocate the IFrame if your browser is resize.

    That’s why I’m against the IFrame.. so for everybody who reads this, if you don´t really have to render HTML in your app, don´t do it.

  6. Jozef Chúťka March 17, 2010 00:12

    Hi Pedro, thanks for your comment. I think you misunderstood the whole example and aim of this Class. It does not mean that all your PopUps are gonna be raplaced by HTML iframe. HTML iframe only overlaps the sk.yoz.html.IFrame class! Its aim IS to show iframe positioned and sized over this element. There is no workaround needed for hidding etc. You can hide it using IFrame.visible = false. Yes, you are right that in specific case (when your flash app extends with browser resize), you need to call:
    iframe.positionChanged = true;
    iframe.sizeChanged = true;
    iframe.invalidateProperties();
    it is meant to be used that way

    whats more, sk.yoz.html.IFrame, can be used for positioning any other html element, see some examples here:
    http://blog.yoz.sk/2010/02/textinput-wmode-opaque-transparent-workaround/
    http://blog.yoz.sk/2010/01/elegant-facebook-login-for-desktop-application/

  7. bar June 9, 2010 04:02

    hi..
    im trying to do this a lot of time in my websites,
    you can download rar file that include all works?

    thanks

  8. Jozef Chúťka June 9, 2010 09:37

    @bar just copy paste content of these 3 files + add .js line into your main html wrapper thats all

  9. Rafael SP August 11, 2010 23:57

    It works!

    Thank you for this post. It helped me a lot.

  10. sreeja November 11, 2010 13:51

    Its really great !Excellent work.I had implemented this to my project.

  11. sreeja November 12, 2010 09:42

    hi friend,First of all i would to thank you for sharing this app. i m using ur app inside a tab.Its working.But whats d problem is when i move to other tabs its still visible.i cant make it invisible.how can i use it as normal ?

    expecting your reply
    Thanks and Regards,
    Sreeja.T

  12. Jozef Chúťka November 12, 2010 15:47

    Hi sreeja,
    use iframe.visible = false in order to hide the iframe, what it does is:
    1. it hides mxml element in flash
    2. it calls javascript and set iframe.style.display = “none”

  13. peperone November 23, 2010 16:02

    Hi there,
    Im viewing this site with FF 3.6 on WXP and the iFrame positioning is off, x + 100px and y + 100px more or less.
    Just so you know!

  14. Jozef Chúťka November 23, 2010 16:42

    peperone, everything ok here on 3.6.11, anyway you can make your own .css files or .js files to handle position

  15. milton ortiz January 14, 2011 03:36

    this is interesting, i just ask if this can run from a flash project not from a html??
    or should it always run from a page?

  16. milton ortiz January 14, 2011 05:39

    weird…i wrote something here but can’t find the post….could this be applied in a flash project? in the fla not html? thanks a lot

  17. Jozef Chúťka January 14, 2011 15:43

    @milton, this thing requires iframe/html. You can not make it work from standalone .swf, however you can use HTMLLoader http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/flash/html/HTMLLoader.html in AIR projects. … all post from new users waits for my approval

  18. Daniel February 16, 2011 06:19

    Hello

    This looks amazing! Thank you for this, but I am unsure how to use it properly.

    I understand that there is a separate Actionscript file which I believe my .SWF would call and a separate Javascript file, but am unsure where the application code for the draggable window goes.

    Also, how would I build a basic flash file that calls on the actionscript to load html in the IFrame?

    I have spent a couple days trying to figure this out and any help would be greatly appreciated.

    Thanks,

    Daniel

  19. Jozef Chúťka February 17, 2011 00:42

    Hi Daniel,

    With flash builder create an flex project. Set SDK compiler to be compatible with flex 3 SDK (this post is 15 months old). Put into main application file all the code starting with “http://classes.yoz.sk/sk/yoz/html/IFrame.as and put it into src/sk/yoz/html/IFrame.as. Download .js file and place it into html-template dir, open your html wrapper and put reference to this .js file as described. Now build the project.

    Daniel, this blog is not for beginners, if it takes you days to make this simple thing work, maybe you should start with some flex tutorials

  20. Daniel February 17, 2011 03:58

    Thank you. I appreciate it.

    I have been working in simple flash for years, but there is a whole other level I have no idea about.
    I’ll look into some tutorials.

    Thanks again!

  21. Yirgu July 21, 2011 17:48

    I appreciate the idea. But it doesn’t work. I don’t no what I miss. please make it clear what i do to use ion my project.
    thanks in advance

  22. Jozef Chúťka July 22, 2011 11:27

    Yirgu, does the example on this page work for you? The example is now almost 2 years old. mx components are not cool anymore, thus you need to rewrite canvas to group or something simplier. all sources are available in the article, just take a look again and go step by step

  23. Flash Expert 83 March 14, 2012 09:21

    I read the blog and tried the code, but I’m very confused on how to go about it. Is there a video tutorial on how to insert a web browser into a Flash file to create the whole effect. Please let me know.

  24. Jozef Chúťka March 15, 2012 13:07
  25. Matt April 3, 2012 22:32

    Will it work with Action Script 2.0?

    How do I use it? I dont see the part where it talks about the fla file. thx

    Please email me if you can.

  26. Jozef Chúťka April 4, 2012 11:12

    Matt, flex is only for actionscript 3.0

  27. Daniel September 18, 2012 02:10

    hi, what softwares will i use to make this? and can i place it inside a flash projector? 🙂

  28. Jozef Chúťka September 18, 2012 08:29

    Daniel, its basicaly an iframe positioned on top over flash. You can not do this in projector but you can use http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/controls/HTML.html in air

  29. FreddyKrueger September 28, 2012 14:18

    Daniel good afternoon. Firstly thank you for your work.
    Took a few days researching the topic of Flash Builder 4.6 iFrames from
    Toas the solutions I’ve seen are not good or do not work.

    In Fles 4.5 if they do but I do not use that version.

    I really liked your approach to the solution, and we have implemented.

    It works fine in Firefox but does not work in Internet Explorer (if there are people who still use it lol) and also in chrome, which opens web browsing but not the url.

    I need this, is a matter of life or death, as quermeos call tinymce in that iFrame.

    I would appreciate your help, or if you know a better solution I’d appreciate it infinitely.

    Work as a freelancer?

    infinite thanks
    Atentemante
    FreddyKrueger

  30. Jason January 23, 2014 23:32

    Hi Jozef – this is a great component you have here.

    Do you have a built-in way to communicate from Flex to the HTML page displayed in the iFrame? I have some Javascript functions on the HTML page I want to display in the iFrame that I want to be able to call from my Flex application. Would the callJS function serve this purpose?

  31. Jozef Chúťka January 24, 2014 00:02

    hi Jason,
    yes, you should be able to communicate with javacsript between parent window and child iframe (thus from flex to iframe). It will be propably restricted to a domain so both pages must be loaded from the same one etc. have a look here http://stackoverflow.com/questions/251420/invoking-javascript-code-in-an-iframe-from-the-parent-page
    You can use ExternalInterface to execute javascript from flash.

  32. Tam July 31, 2015 07:56

    Can someone help me with this. I am newbie to Flash builder 4.6 i want to embed a box with an html page (a google map page)

    I am wanting to build a web app…I have built a simple program that has buttons and goes between states and now I just need to embed an html page…I have read up on iFrame but I don’t understand what to code….any help ?

    Thanks

  33. Jozef Chúťka July 31, 2015 10:42

    hi Tam. what the code does it creates html iframe and use absolute position to overlay it on top of flash

  34. Yogesh March 18, 2016 18:52

    hi,

    Nice post. But what if I want to load html content to this iframe instead of loading url. I dont know if it is possible with this . if yes then how ?

    Thanks 🙂

  35. Chen Nahmani December 17, 2016 22:08

    works perfectly!
    How can i use multiple iframes id ?
    i bet its simple tho i am kinda newbie to flash builder, i have experience in as3 and a bit java, maybe you can direct me to what i should be concentrate my learning on to understand all of this better?
    Thanks!!

Leave a comment

Please be polite and on topic. Your e-mail will never be published.