views:

303

answers:

3

The FDMSLib for the Flex-AJAX bridge has a load function that renders a flash object to the page where ever it is called. This causes problems when using Ext.JS as the inserted object can either be discarded by another render function or cause conflicts during the rendering of the page, so I'm trying to rewrite the load function so that its Ext.JS (and probably other JS framework) friendly.

This is the original function.

FDMSLibrary.load = function(path, callback)
{
    var result = "<object id='_fesLib' classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000' \
                 codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,5,0,0' \
                  height='1' width='1'> \
                 <param name='flashvars' value='bridgeName=flash'/> \
                 <param name='AllowScriptAccess' value='always'/> \
                 <param name='src' value='"+ (path != undefined ? path : "") + "'/> \
                 <param name='wmode' value='transparent' /> \
                 <embed name='_fesLib' pluginspage='http://www.macromedia.com/go/getflashplayer' allowScriptAccess='always'\
                 src='" + (path != undefined ? path : "") + "' height='1' width='1' flashvars='bridgeName=flash'/> \
              </object>";
    document.write(result);

   // todo:need a callback and variable here so you can keep track that both the fabridge and the fdmsbridge are available
    FDMSLibrary.addInitializationCallback("flash", callback);

  // register for call back when the FABridge has completed initialization
    FABridge.addInitializationCallback("flash", FABridge_ready);
 }

I've replaced this with the following :

loadFDMSBridge: function(path,callback) {
    var FABridgeSWF = new Ext.FlashComponent({
        id : '_fesLib',
        height: '1',
        width: '1',
        flashVars : {
            bridgeName:'flash'
        },
        wmode : 'transparent',
        flashVersion : '8.5.0.0',
        renderTo : Ext.getBody(),
        url : path,
        listeners : {
            'render' : {
                fn : this.initBridge,
                scope : this
            }

        }
    });


},
initBridge : function () {
        FDMSLibrary.addInitializationCallback("flash", this.initPolling);
        FABridge.addInitializationCallback("flash", FABridge_ready);
}

The flash object is rendered to the page, it uses the data attribute in object rather than a src param, but I assume this is correct for rendering flash objects.

The problem I'm having with this is that when I call the FDMSLibrary.addInitializationCallback function it would appear that the bridge is not ready.

The javascript is told by the swf file that it is ready to be used. I'm pretty certain that its no a problem with the swf as I have an simple test page up and running using the same swf and javascript libraries, but without any interference from any other javascript, content and so on. It kind of feels like the swf isn't being loaded and "executed" and Firebug would seem to back this up, but I don't really know why or what I've missed.

If you would like to see the full javascript libraries and the actionscript source for the FABridge you can find them here in Adobe's subversion repo : fds ajax bridge repo path

Thanks in advance for your help

+1  A: 

Not sure, but you might try the afterrender event instead of render. As it happens later in the rendering cycle (well, after it :) it might help -- I know that there have been issues in the past with render firing before certain pieces of a component were actually done rendering (which is why the afterrender event was later added).

Another thing if that doesn't work might be to try deferring your initBridge functionality slightly. This is a bit of a stretch, but I've seen the case before where there is either a timing issue with the JS execution, or possibly some blocking that causes this type of symptom. Deferring your code will both delay its execution and execute it on a new thread, which may solve the problem. Not the best solution, but I've worked around several browser quirks this way. E.g.:

initBridge : function () {
    (function(){
        FDMSLibrary.addInitializationCallback("flash", this.initPolling);
        FABridge.addInitializationCallback("flash", FABridge_ready);
    }).defer(500, this);
}

At least this might confirm whether or not it's a timing/blocking issue. You can adjust the 500 (ms) up or down to see if you hit any difference in behavior.

bmoeskau
A: 

@bmoeskau : thanks for the helpful suggestions.

Looking at my code again with your suggestions I realised a couple of things.

First was that I was making changes in the wrong files. I'd made a standalone version and had accidentally been editing those files and not the ext.js application.

Secondly, with all the changes,testing and general messing about I had managed to overload some of my functions, which meant that the wrong functions were being called. No matter how much I changed the function I was looking at it never got called.

The above code actually works as stated.

Stephen Moretti
NOTE : this was also exacerbated by this bug in Firefox : http://code.google.com/p/swfobject/wiki/faq#16._Why_does_Firefox_load_my_SWF_twice?
Stephen Moretti
A: 

Just to tidy this up :

I had continuing issues courtesy of a Firefox bug and swfobjects (the underlying library for Ext.Flashcomponent). I ended up having to push the original html from the FDMSLib load() function into the DOM rather than use the Ext object.

    // spec up the flash object for FABridge
    var foSpec = {
            tag : 'object',
            id : '_fesLib',
            classid : 'clsid:D27CDB6E-AE6D-11cf-96B8-444553540000',
            codebase: 'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,5,0,0',
            height :'1',
            width : '1',
            cn : [
                    {tag:'param', name:'flashvars', value:'bridgeName=flash'},
                    {tag:'param', name:'AllowScriptAccess', value:'always'},
                    {tag:'param', name:'src', value:path},
                    {tag:'param', name:'wmode', value:'transparent'},
                    {tag:'embed', name:"_fesLib", pluginspage:'http://www.macromedia.com/go/getflashplayer', allowScriptAccess:'always', src:path, height:'1', width:'1', flashvars:'bridgeName=flash'}                   
            ]

    };
    // Add it to the end of the body
    Ext.getBody().createChild(foSpec);

I vaguely recall a post somewhere that says that FABridge uses the "embed" tag and as swfobject doesn't insert an "embed" tag this may also have been causing issues.

To add to this, the flashParams property of Ext.Flashcomponent makes reference to this adobe technote on required params. This states that an object only inclusion of a flash object must include the param "movie". swfobject forcibly removes any param with the name "movie".

Not much fun to be had anywhere with this!

Stephen Moretti