flex-users / flex-iframe

IFrame component for Flex applications.
github.com/flex-users/flex-iframe
120 stars 63 forks source link

iFrame is positioned relative to document, not the swf container #77

Closed nicoulaj closed 13 years ago

nicoulaj commented 13 years ago

Originally filed by CoffeeAn...@gmail.com on 2009-02-17T20:11:11

What steps will reproduce the problem?

  1. make a fixed width swf and center it with CSS
  2. make an iFrame popup in a movable container
  3. drag the container around

What is the expected output? What do you see instead? The iFrame should move along with the container all over the screen. Instead, the position is partially incorrect when the container is anywhere but [0,0]. It gets worse the farther away from the top-left of the window you get.

What version of the product are you using? On what operating system? fb3 v1.3.2 on OSX Leopard in Firefox

Possible Fix: In the FUNCTION_MOVEIFRAME function, add a call to document.getElementBy('ID of Flash SWF'). Then add the offsetLeft to the x of frameRef.style.left and offsetTop to the y of frameRef.style.top

I'll try to post my code:

private static var FUNCTION_MOVEIFRAME:String = "document.insertScript = function ()" + "{ " + "if (document.moveIFrame==null)" + "{" + "moveIFrame = function(frameID, iframeID, x,y,w,h) " + "{" + "var frameRef=document.getElementById(frameID);" + "var flashMovie=document.getElementById('idOfFlashSWF');" + "frameRef.style.left=x + flashMovie.offsetLeft;" + "frameRef.style.top=y + flashMovie.offsetTop;" + "var iFrameRef=document.getElementById(iframeID);" + "iFrameRef.width=w;" + "iFrameRef.height=h;" + "}" + "}" + "}";

nicoulaj commented 13 years ago

Updated by adrianwe...@ntlworld.com on 2009-02-24T13:10:28

Hi, After much hassle with IFrames appearing offset from a Flash Player not possitioned at 0,0 of the browser, your suggestion works.

It needed a little tweak though.

Here's the working MOVEIFRAME string

   private static var FUNCTION_MOVEIFRAME:String = 
        "document.insertScript = function ()" +
        "{ " +
            "if (document.moveIFrame==null)" +
            "{" +
                "moveIFrame = function(frameID, iframeID, x,y,w,h) " + 
                "{" +
                    "var frameRef=document.getElementById(frameID);" +
                    "var flashMovie=document.getElementById('" 

+Application.application.id + "');" + "frameRef.style.left=x + flashMovie.offsetLeft;" + "frameRef.style.top=y + flashMovie.offsetTop;" + "var iFrameRef=document.getElementById(iframeID);" + "iFrameRef.width=w;" + "iFrameRef.height=h;" + "}" + "}" + "}";

If this doesn't appear formatted well, then the key change to the original one above is replacing ('idOfFlashSWF') with ('" + Application.application.id

I tested this in IE7, Opera 9.63, FF3.0.6 and all work.

..,there's a slight quirkyness in FF3 where the IFrame, if scrollbars are shown, they are thicker than in IE or Opera. I have an IFrame added as a child (using percentWidth and percentHeight of 100) to a
that has a 10px padded border (sort of framing the IFrame in the ) and the padded border is being encroached on by the scrollbars (both vertical and horizontal do it).

The is then in another because I need to overlay some footer text. The is actually a component in the Application.mxml and therefore I need to ensure the footer text is constrained to the bottom so it overlays the by making the canvas hug the panel component.

Also, to make this work in all broswers, you need to use the Quirks modes of in my html wrapper. Note the lack of the URL as this puts most browsers in to Quirks mode.

And of course wmode="opaque" !!!

My html wrapper has a stripped down version of the standard FB3 generated one, but for a test the section has a style The section then launched the Flash Player using the standard AC_FL_RunContent(....) javascript call passing specific width and height (i.e. not values such as 100%) - completely as standard in FB3 - (using SDK 3.3 but the same in SDK 3.2). This produced the problem that needed solving. The IFrame would apear on the browser as though the was not offset. Have fun and I hope this works for you guys.

nicoulaj commented 13 years ago

Updated by adrianwe...@ntlworld.com on 2009-02-25T01:36:54

A slight improvement to the FUNCTION_MOVEIFRAME string definition. This is cleaner looking but requires a change to the ExternalInterface call that uses it to call the javascript function once it's in the DOM.

   private static var FUNCTION_MOVEIFRAME:String = 
        "document.insertScript = function ()" +
        "{ " +
            "if (document.moveIFrame==null)" +
            "{" +
                "moveIFrame = function(appID, frameID, iframeID, 

x,y,w,h) " + "{" + "var frameRef=document.getElementById(frameID);" + "var flashMovie=document.getElementById(appID);" + "frameRef.style.left=x + flashMovie.offsetLeft;" + "frameRef.style.top=y + flashMovie.offsetTop;" + "var iFrameRef=document.getElementById(iframeID);" + "iFrameRef.width=w;" + "iFrameRef.height=h;" + "}" + "}" + "}";

And in udateDisplayList(...) of fb3_1_3_3 (r14 in this issue list) the ExternalInterface cal changes to

ExternalInterface.call("moveIFrame", Application.application.id, 
    frameId, iframeId, globalPt.x, globalPt.y, this.width, 
    this.height);

So all I'm doing here is cleaing up the javascript and passing in the Applicaiton ID through a function parameter.

No attachment this time as code seems to layout just as you cut'n'paste from FB3.

nicoulaj commented 13 years ago

Updated by TimothyR...@gmail.com on 2009-05-28T22:22:37

I think that the above code does not take in to account nested embed tags. This is not super tested, but it is a start.

private static var FUNCTION_MOVEIFRAME:String = "document.insertScript = function ()" + "{ " + "if (document.moveIFrame==null)" + "{" + "moveIFrame = function(appID, frameID, iframeID, x,y,w,h) " + "{" + "var frameRef=document.getElementById(frameID);" + "var flashMovie=document.getElementById(appID);" + "var ol=x;" + "var ot=y;" + "var obj=flashMovie;" + "var includeObjOff= (/Firefox/.test(navigator.userAgent)==false);" + "do" + "{" + "if( (includeObjOff) || (obj.tagName && (obj.tagName.toUpperCase() !='OBJECT')) )" + "{" + "ol+=obj.offsetLeft;" + "ot+=obj.offsetTop;" + "}" + "} while (obj=obj.offsetParent);" +

                    "frameRef.style.left=ol;" + 
                    "frameRef.style.top=ot;" +
                    "var iFrameRef=document.getElementById(iframeID);" +
                    "iFrameRef.width=w;" +
                    "iFrameRef.height=h;" +
                "}" +
            "}" +
        "}";

The above code just recursively iterates up the DOM to get the absolute offsetTop/Left. In Firefox I noticed that the values for the actual flash movie do not appear to be accurate if the HTML method is used. I put in a quick hack for this, but the code still needs some massaging. Hope this helps.

nicoulaj commented 13 years ago

Updated by wesley.d...@gmail.com on 2009-09-15T03:00:22

Can someone who has the above situation actually working post a sample app (mxml file and the working IFrame.as file) so I can see it in action. I have the above isssue, but even with the solutions posted above, can't seem to get it working correctly.

Thank you in advance, Wes

nicoulaj commented 13 years ago

Updated by Julien.N...@gmail.com on 2009-10-30T14:51:24

Did someone merge one of the solutions exposed below with Flex-IFrame 1.4 ?

Original ticket set status to Accepted (we converted to open)

nicoulaj commented 13 years ago

Updated by Julien.N...@gmail.com on 2009-11-09T18:24:11

A fix has been committed at revision r83. I'm closing this issue, if there are still bugs, they should be browser-specific so please open new issues with the details.

Original ticket set status to Fixed (we converted to closed)