How to embed HTML url pages in adobe flex? - actionscript-3

I have a desktop adobe flex application and would like to show the content of an URL. How could a HTML page be best embedded into a desktop flex app?
I know there is some old mx:HTML location="{url}" but this seems to have many rendering and javascript issues.
I don't want to open an external browser window.

You can try StageWebView with argument useNative=true. Here is a wrapper component for Flex.

You can use stagewebview for rendering html page in flex application. Use below code to open google page.
Note: 'http' or protocol of the url should be added in the url.
private var _stageWebView:StageWebView;
private var _stage : Stage;
protected function addedToStageHandler(event:Event):void
{
_stage = this.stage;
}
private function onInitStageWebView():void
{
_stageWebView = new StageWebView(true); //true - for system engine, false - embedded webkit
_stageWebView.stage = _stage1;
_stageWebView.viewPort = new Rectangle(42, 50, this.width, this.height);
_stageWebView.addEventListener(Event.COMPLETE, completeHandler);
_stageWebView.addEventListener(ErrorEvent.ERROR, errorHandler);
_stageWebView.addEventListener( LocationChangeEvent.LOCATION_CHANGING, onLocationChange_Handler );
_stageWebView.loadURL("http://www.google.com");
}
protected function onLocationChange_Handler( event : LocationChangeEvent ):void
{
trace( "Location Changed to : " : event.location );
}

Related

Opening an SWF file in a new window

I have a button in my desktop flash application, when clicked, it must load an external SWF file and open it in a new window without using the browser.
i've tried
import flash.system.fscommand;
loadButton.addEventListener(MouseEvent.CLICK, clickHandler);
function clickHandler(event:MouseEvent):void {
fscommand ("exec", "external.swf");
}
But it didn't work. Someone mentioned in a forum that the app must be compiled as a .EXE file for this code to work. is that true?.
i've also tried
loadButton.addEventListener(MouseEvent.CLICK, clickHandler);
function clickHandler(event:MouseEvent):void {
navigateToURL(new URLRequest("external.swf"), "_blank");
}
But this opens the file in a new browser window.
Any idea how can i do it without using the browser window?
It is simple with the NativeWindow. Despite the fact the NativeWindow is a separate window, your application is still a whole and have a full access to everything, the new window included. You just need to add a Loader with another SWF to the new window's stage.
// This is an example from official docs:
// https://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/NativeWindow.html#NativeWindow()
var windowOptions:NativeWindowInitOptions = new NativeWindowInitOptions();
windowOptions.systemChrome = NativeWindowSystemChrome.STANDARD;
windowOptions.type = NativeWindowType.NORMAL;
var newWindow:NativeWindow = new NativeWindow(windowOptions);
newWindow.stage.scaleMode = StageScaleMode.NO_SCALE;
newWindow.stage.align = StageAlign.TOP_LEFT;
newWindow.bounds = new Rectangle(100, 100, 800, 800);
newWindow.activate();
// Now the only thing left is to load the external SWF into it:
var aLoader:Loader = new Loader;
// Load SWF as usual:
aLoader.load(new URLRequest("external.swf"));
// Add it as a child to the new window's stage:
newWindow.stage.addChild(aLoader);

Flash Loader works only inside of Flash

I need to load flex swf file into a flash (a button on witch I need to apply flex skin). I'm using flash Loader() and inside of Flash it works fine (swf is loaded and displayed). But when I try run a compiled flash swf, the Loader does not load the flex swf. There are no errors handled with IOErrorEvent.IO_ERROR and the ProgressEvent.PROGRESS just sais that 0 bytes was loaded. Than nothing else happen.
Here is a part of my code (just display flex button and set a label):
var flexBtn:String = "button.swf"; //swf file is in the same folder as flash source code
var myLoader:Loader = new Loader();
myLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,loadComplete);
myLoader.load(new URLRequest(flexBtn));
stage.addChild(myLoader);
var timer:Timer;
function loadComplete(event:Event):void
{
timer = new Timer(200);
timer.addEventListener(TimerEvent.TIMER, timeHandler);
timer.start();
}
function timeHandler(event:Event):void
{
timer.stop();
var myClip:MovieClip = myLoader.content as MovieClip;
myClip.x = 10;
myClip.y = 10;
if (myClip.currentFrame == 2){
myClip.application.flexButton.label = "FlexButton";
}
}
I have tried different versions of SDK and different Loaders but it didn't work.
All suggestion will be appreciated :-)
Add SecurityErrorEvent - I guess it's because of a privacy policy error.
And of course you must be sure they are in the exact same folder (correct url).

Loader Complete event does not work with browser (AS3)

Im trying to load an image in a movie clip and change its size as follow:
var loader:Loader = new Loader();
public function setProfilePicture(url:String){
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplte);
loader.load(new URLRequest(url));
addChild(loader);
}
protected function onComplte(event:Event):void
{
EventDispatcher(event.target).removeEventListener(event.type, arguments.callee);
var image:DisplayObject = (event.target as LoaderInfo).content;
image.width = 132;
image.height = 132;
}
The code above works fine when I execute it with adobe flash CS5, but when I try to open it with a browser (e.g. Chrome), the size of images does not change to 132x132. I tried to put addChild(loader) in the onComplete function, but in this time when I open it with a browser, the image won't be even loaded, while executing with adobe flash CS5 remains as before.
My suggestion is that when we open it by browser, the function onComplete does not work, but WHY???
Any idea will be appreciated.
Try this hack:
protected function onComplte( event:Event ):void {
EventDispatcher( event.target ).removeEventListener( event.type, arguments.callee );
var loaderInfo:LoaderInfo = LoaderInfo( event.target );
loaderInfo.loader.scaleX = 132 / loaderInfo.width;
loaderInfo.loader.scaleY = 132 / loaderInfo.height;
}
check this link: actionscript3 (flash) don't load images form user file in chrome
Verify that it works in a different browser other than chrome. This is most likely the pepper flash problem in chrome
I played with your onComplte function and somehow the content property of LoaderInfo is not accessible from in there. If all else fail, the size of the image can still be controlled from within setProfilePicture by scaling the Loader:
public function setProfilePicture(url:String){
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplte);
loader.load(new URLRequest(url));
loader.scaleX = 10; ////
loader.scaleY = 10; ////
addChild(loader);
}

actionscript3 (flash) don't load images form user file in chrome

I'm trying to write flash applet where user can upload image from their hard disk.
So actionscript will edit image and send it to server.
Loading images work in flash player, firefox, and in opera, but in chrome after selecting image it stops.
I'm using flashdevelop.
Here is my code:
public class Main extends Sprite
{
[Embed(source = "../lib/lena.png")]
private var layer0Class : Class;
private var layer0:Bitmap = new layer0Class();
private var fileReferenceSelect:FileReference = new FileReference();
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
/// add image to flash scene
addChild(layer0);
/// add button
var my_button:SimpleButton;
my_button = new SimpleButton();
my_button.x = 150;
my_button.y = 50;
var cerchio:Shape=new Shape();
cerchio.graphics.beginFill(0x000000,1);
cerchio.graphics.drawCircle(my_button.x,my_button.y,20);
cerchio.graphics.endFill();
my_button.upState = cerchio;
my_button.overState = cerchio;;
my_button.downState=cerchio;
my_button.hitTestState = my_button.upState;
addChild(my_button);
/// button clicked
my_button.addEventListener(MouseEvent.CLICK,function(m:MouseEvent):void
{
fileReferenceSelect.browse([new FileFilter("PNG Files (*.png)","*.png; *.jpg; *.jpeg")]);
});
/// file selected
fileReferenceSelect.addEventListener(Event.SELECT, function(event:Event):void
{
fileReferenceSelect.load();
});
/// file ready to load
fileReferenceSelect.addEventListener(Event.COMPLETE, function(event:Event):void
{
var ldr:Loader = new Loader();
/// file loaded
ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, function(e:Event):void {
var bm:Bitmap = Bitmap(e.target.content as Bitmap); /// here chrome is messing up
layer0.bitmapData = bm.bitmapData;
});
ldr.loadBytes(fileReferenceSelect.data);
});
}
}
Is it because of some limit in chrome (I read that flash in chrome is in sandbox) ?
Is there better way to do this ?
I've had issues loading flash content locally in chrome. Its the flash global player settings. The problem is, chrome has its own version of flash built in..I forget what its called..I think pepper flash? Anyway, it doesn't obey the settings all the time from this site: http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html
As long as you are testing on a web server it should be fine..heck even a local web server will work

Cross domain problems in Flash

I have two swf files hosted on different domains aaa.com/a.swf and bbb.com/b.swf. a.swf is loading b.swf and trying to cast it to some interface. When both of these swf files are under the same domain everything works fine. But when they are under different domains I'm getting null after casting b.swf to the implemented interface IComponent. Both of these swfs are compiled with use-network=true and with the same IComponent.as.
public class Wrapper extends Sprite
{
public function Wrapper()
{
super();
var request:URLRequest = new URLRequest("http://aaa.com/Component.swf");
var loaderContext:LoaderContext = new LoaderContext();
loaderContext.applicationDomain = ApplicationDomain.currentDomain;
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onLoadingComplete);
loader.load(request,loaderContext);
addChild(loader);
}
private function onLoadingComplete(event:Event):void
{
var target:LoaderInfo = event.target as LoaderInfo;
var component:IComponent = target.content as IComponent;
component.init({"s":1});
component.run();
}
}
public class Component extends Sprite implements IComponent
{
public function Component()
{
super();
Security.allowInsecureDomain("*");
}
public function init(params:Object):void
{
//some actions
}
public function run():void
{
//some actions
}
}
Try this:
//Assuming you've set a crossdomain policy file
var loaderContext:LoaderContext =
new LoaderContext( true , ApplicationDomain.currentDomain )
It seems that the reason why it's not working has to do with the fact that either IComponent is not recognized or that there's a definition conflict. I would have thought that with ApplicationDomain set to currentDomain, a definition conflict should have been avoided... but it may be worth trying to leave each SWF within their own domain.
//Assuming you've set a crossdomain policy file
var loaderContext:LoaderContext =
new LoaderContext( true );
You could also check if IComponent "exists" before loading the other SWF. This could help in diagnosing what's going on...
var ClassName:Object = getDefinitionByName('IComponent');
trace( ClassName );
Maybe you have to set cross-domain security policy by crossdomain.xml file
http://www.adobe.com/devnet/flashplayer/articles/fplayer9_security.html
For example:
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy
SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-access-from domain="*.example.com" />
</cross-domain-policy>
Thanks all for answers, I've found a working solution today.
Instead of casting loaded content to IComponent I'm casting it to object
var component:Object = (event.target as LoaderInfo).content as Object;
component["init"](null);
component["run"]();
I's confimed from testing that even when we are using shared class with static fields and methods it doesn't work. Both of wrapper and component are instantiating their own instances of shared class. It's really strange.
If you have the same problems please ensure that your wrapper/component classes have Security.allowDomain calls
This is a bug in the player:
http://bugs.adobe.com/jira/browse/ASC-3529
It happens when you try to "share" an interface between swfs that were loaded from different domains. This should work provided that you put both swfs under the same app domain (as you have).
Using an Object works, but kind of defeats the purpose of using an interface in the first place.
Here's a workaround that basically loads the swf as a binary and then uses Loader::loadBytes to actually load the swf into memory:
http://blog.aleksandarandreev.com/?p=42
my idea about syntax errors was pointless, here's an edit:
this code:
private function ololo():void{
var request:URLRequest = new URLRequest("http://domain/file.swf");
var loaderContext:LoaderContext = new LoaderContext();
loaderContext.applicationDomain = ApplicationDomain.currentDomain;
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onLoadingComplete);
loader.load(request,loaderContext);
}
private function onLoadingComplete(e:Event):void {
var target:LoaderInfo = e.target as LoaderInfo;
addChild(target.content as Sprite);
}
works well even if files are on completely different domains.
does it work if you treat your IComponent as Sprite?