Hi Alex,
thanks for your reply.
I guess you're right about the styles, since we use modal window to
open the loaded swf, we simply unloaded the main app styles before
loading the 2nd app.
Then, when the user is done with the loaded swf, we called it's
deactivate() method which unloads its styles and the main app reloads
its styles.
About the flashvars, I made it work, in a very hacky way, but I can't
think of anything else.
Basically, the solution is to catch the right moment to inject data to
the application.parameters, which is between when the application gets
a copy of the SystemManager.parameters and the tyime when the
application dispatces a "preinitialize" event, which is the time for
the app to start kicking.
The only way I found to catch this moment was to use the event
UIComponent.dispatchEventHook and check for the first "preinitialize"
event.
I had 2 problems with that:
1. I use actionscript only application for the wrapper, otherwise it
will make no sense to use a wrapper - that can be solved by copying
the mx_internal to access the UIComponent.dispatchEventHook and using
ApplicationDomain.getDefinition()
2. The UIComponent class definition is only avialable through
ApplicationDomain.getDefinition() at the SystemManager 2nd frame
So at first, I thought I could simply add an event listener to the
enterFrame, but then I found out, that the enterFrame is always
dispatched after the frameScript function, which in some cases can be
too late, because the application can get initialized and disapcth the
preinitialize before the first enterFrame event for frame 2 is dispacthed.
So, to overcome these timing issues I had to override the call to the
SystemManager.docFrameHandler, by passing my own frameScript function
where I first acquire the UICompoennt class definition to use its
dispatch hook, and only then call the SystemManager.docFrameHandler
"manually"
Enough bubbling, here is the code, it's hacky, I'm aware of the risk
of using the mx_internal, but currently it works, so here it is:
package {
import flash.display.Loader;
import flash.display.MovieClip;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.net.URLRequest;
import mx.managers.SystemManager; SystemManager;
import mx.core.mx_internal;
import mx.core.EventPriority;
//import mx.core.mx_internal;
public class SWFWrapper extends MovieClip
{
//import mx.core.mx_internal;
private var _loader:Loader = new Loader;
private var _systemManager:MovieClip;
private var _classUiComponent:Class;
use namespace mx_internal;
public function SWFWrapper()
{
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
_loader.contentLoaderInfo.addEventListener(Event.INIT,
loaderCompleteHandler, false, EventPriority.DEFAULT_HANDLER);
_loader.load(new URLRequest("Loadee.swf"));
this.addChild(_loader);
}
private function loaderCompleteHandler(completeEvent:Event):void
{
_systemManager = _loader.content as MovieClip;
_systemManager.addFrameScript(1, docFrameHandler);
}
private function docFrameHandler(e:Event = null):void
{
_classUiComponent =
_systemManager.loaderInfo.applicationDomain.getDefinition("mx.core.UIComponent")
as Class;
_classUiComponent.mx_internal::["dispatchEventHook"] =
myEventHook;
_systemManager.mx_internal::["docFrameHandler"]();
}
private function myEventHook(event:Event, uic:Object):void
{
if (event.type == "preinitialize" && _firstTime)
{
_firstTime = false;
_systemManager["application"]["parameters"]["message"] = "Great
success!";
}
}
}
}
--- In [email protected], "Alex Harui" <[EMAIL PROTECTED]> wrote:
>
> There is no good way to have a loaded SWF keep its own styles. There
> might be in 3.x later this year.
>
>
>
> Since you own both SWFs, I'd simply have a handshake between the loader
> and the loaded app. Sublcass App, override its parameters property and
> have it query the loading Apps loaderInfo.parameters.
>
>
>
> ________________________________
>
> From: [email protected] [mailto:[EMAIL PROTECTED] On
> Behalf Of mydarkspoon
> Sent: Saturday, May 31, 2008 4:22 AM
> To: [email protected]
> Subject: [flexcoders] Two questions: Nested applications styles
> colllisions, flashvars injection
>
>
>
> Hi all,
> I'm targeting here 2 problems I've been struggling with for quite long
> time regarding nested SWFs.
>
> The first, which is more nasty and 5 times more evil is using different
> styles for 2 flex applications where one application is loaded into the
> shell app.
> The behavior I'd like to have is like this:
>
> 1. If the loaded app uses a class selector "greenButton" and the
> loader also uses this app, each of the applications would be able to use
> the "greenButton" definition it came with.
> 2. Same as no. 1 but for type selectors (e.g Alert{...},
> Button{...}).
> 3. If the loaded app uses some component, whose styles weren't
> defined (no class, nor type selctors) it would inherit these styles from
> the loader app.
>
> I can settle down without no. 3, but I can/t find anyway to achieve 1 &
> 2.
> To make this question clearer, I made a small app
> <http://www.2shared.com/file/3367026/5!%0d%0a%205565dba/StylesTests.html
> ?A> that demonstrate the problem I'm refering:
>
> The second issue that gives me hard time is like this:
> I use a wrapper swf to load my main flex application. it works just
> fine, it's a 1KB swf that does nothing but load a flex application.
> However, the flex application is unaware of it being loaded into a
> wrapper swf, and since it uses flashvars to know the basic coniguration
> to work with (service url and so...), it reads the
> Application.application.parameters.
> The application.parameters, as you know is simply the
> LoaderInfo.parameters copied into the application by thye SystemManager.
> What I'd like to do is to inject the application the wrapper swf
> flashvars (which is embedded in the html page) just before the
> application dispatches the preinitialize event, which is where
> client-server communication starts.
>
> I could just load the flex app with query string (app.swf?mode=5), but
> that! would prevent browser caching, which I'd like to leverage on.!
> Then , the other options are:
>
> 1. Get a hold of the loaded swf root (SystemManager) and set
> it's LoaderInfo.parameters to {mode: 5}. that would not work as this is
> a read only property...
> 2. ok,so whay won't you get a reference of that parameters
> object and dynamically add some properties to it like that:
> var p:Object = loader.content.parameters;
> p.mode = 5;
> sounds ok, but guess what? every time you access the
> loaderInfo.parameters it returns a different copy it, so you end up with
> different object every time and can't add new proprties to the soource
> object...grrr
> 3. Ok, so hacking my way there, I thought of changing the
> loader.content["application"].parameters, shich is a property copoed
> from the SystemManager's loaderinfo.parameters.However, that can be done
> only after the SystemManager dispatches an "applicationComplete" event
> (because the sys manager just doesn't informs us of any other
> events...), which is! n't the best time to change the parameters,
> because the loaded application can take a hold of them right after the
> "preinitialize" event, which is when I always start to fetch
> configuration data from the server.
>
>
> I'd be grateful for any ideas.
> :)<http://us.i1.yimg.com/us.yimg.com/i/mesg/tsmileys2/01.gif>
>
> Thanks in advance,
>
> Almog Kurtser.
>