How can a preloader dynamically determine target URL when served from CDN - actionscript-3

I have a preloader that is being served from a CDN, and I want it to load the target SWF also from the CDN but when it uses loaderInfo, it returns the hostname of the html file... Here's the setup:
index.html (hosted on primary domain) uses SWFObject to embed preloader
preloader.as hosted on remote CDN, contains code below
target.swf is to be loaded
I have inherited this code from another developer that I can't contact and I'm not an AS coder...
var url:String = "target.swf";
....
var request:URLRequest = new URLRequest(url);
loader = new Loader();
loader.load(request);
This is what I've tried, but I think it's returning the url of the index.html, not the CDN-hosted preloader:
var currentUrl:String = stage.loaderInfo.url;
var url:String = currentUrl.substring(0,currentUrl.length-13) + "target.swf";
....
Is there some way that I can get the URL that the preloader was served from which is the CDN?
Thanks,
Jonathan

stage.loaderInfo.url returns indeed the URL of the page displaying the swf. You may give your swf the address of the CDN as a parameter:
HTML
<script type="text/javascript">
var flashvars = {CDNroot:'http://mycdn/'
};
var params = {
menu: "false",
scale: "showAll",
allowFullscreen: "true",
allowScriptAccess: "always",
quality:"best",
bgcolor: "#FFFFFF"
};
var attributes = {
id:"main", name:"main"
};
swfobject.embedSWF("loader.swf", "altContent", "100%", "100%", "10.0.0", "expressInstall.swf", flashvars, params, attributes);
</script>
Then to retrieve this parameter, use:
AS3
var url:String = stage.loaderInfo.parameters["CDNroot"] + "target.swf";

Related

Adding static image to Lightswitch HTML 2013 Browse Screen

In my case, I have color coded some tiles in the HTML client and I want to add a simple color code key. I have the PNG file I want to use.
I do not require the ability to upload or change the image.
This link seems to achieve what I am looking for, but I am not sure where to implement. Does all of this code go into the PostRender of the Image Control I created?
Add image to lightswitch using local property and file location
Here is what the PostRender of the simple Image data item I created as an Image Local Property, and then dragged into the Solution Designer. It was basically copied from the link above, but I did change the name of the image file to match mine, and I have already added the item to the Content\Images folder structure and it shows in the file view:
myapp.BrowseOrderLines.ColorKey_postRender = function (element, contentItem) {
// Write code here.
function GetImageProperty(operation) {
var image = new Image();
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
// XMLHttpRequest used to allow external cross-domain resources to be processed using the canvas.
// unlike crossOrigin = "Anonymous", XMLHttpRequest works in IE10 (important for LightSwitch)
// still requires the appropriate server-side ACAO header (see https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image)
var xhr = new XMLHttpRequest();
xhr.onload = function () {
var url = URL.createObjectURL(this.response);
image.onload = function () {
URL.revokeObjectURL(url);
canvas.width = image.width;
canvas.height = image.height;
ctx.drawImage(image, 0, 0);
var dataURL = canvas.toDataURL("image/png");
operation.complete(dataURL.substring(dataURL.indexOf(",") + 1));
};
image.src = url;
};
xhr.open('GET', this.imageSource, true);
xhr.responseType = 'blob';
xhr.send();
};
myapp.BrowseOrderLines.ColorKey_postRender = function (element, contentItem) {
// Write code here.
msls.promiseOperation
(
$.proxy(
GetImageProperty,
{ imageSource: "content/images/Key.png" }
)
).then(
function (result) {
contentItem.screen.ImageProperty = result;
}
);
};
}
Currently, the Image control does show on the screen in the browser, and is the custom size I choose, but it is just a light blue area that does not display my image file.
I am not sure if I have embedded the image? I am not sure if that is a missing step?
Thank you!!
The easiest method of testing this approach would be to change your postRender to the following (which embeds the helper function within the postRender function):
myapp.BrowseOrderLines.ColorKey_postRender = function (element, contentItem) {
function GetImageProperty(imageSource) {
return msls.promiseOperation(
function (operation) {
var image = new Image();
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
// XMLHttpRequest used to allow external cross-domain resources to be processed using the canvas.
// unlike crossOrigin = "Anonymous", XMLHttpRequest works in IE10 (important for LightSwitch)
// still requires the appropriate server-side ACAO header (see https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image)
var xhr = new XMLHttpRequest();
xhr.onload = function () {
var url = URL.createObjectURL(this.response);
image.onload = function () {
URL.revokeObjectURL(url);
canvas.width = image.width;
canvas.height = image.height;
ctx.drawImage(image, 0, 0);
var dataURL = canvas.toDataURL("image/png");
operation.complete(dataURL.substring(dataURL.indexOf(",") + 1));
};
image.onerror = function () {
operation.error("Image load error");
};
image.src = url;
};
xhr.open('GET', imageSource, true);
xhr.responseType = 'blob';
xhr.send();
}
);
};
GetImageProperty("content/images/Key.png").then(function onComplete(result) {
contentItem.screen.ImageProperty = result;
}, function onError(error) {
msls.showMessageBox(error);
});
};
This assumes that you named the local property ImageProperty as per my original post and the Image control on your screen is named ColorKey.
In the above example, I've also taken the opportunity to slightly simplify and improve the code from my original post. It also includes a simple error handler which may flag up if there is a problem with loading the image.
If this still doesn't work, you could test the process by changing the image source file-name to content/images/user-splash-screen.png (this png file should have been added as a matter of course when you created your LightSwitch HTML project).
As the GetImageProperty function is a helper routine, rather than embedding it within the postRender you'd normally place it within a JavaScript helper module. This will allow it to be easily reused without repeating the function's code. If you don't already have such a library and you're interested in implementing one, the following post covers some of details involved in doing this:
Lightswitch HTML global JS file to pass variable

How can I read the POST data in AS3?

I am creating the below url request which launches a flex application through the mentioned url. I have also added data and set url req method to POST. How can I read this POST data in my Flex Application which is being launched
var urlReq:URLRequest = new URLRequest();
var requestVars:URLVariables = new URLVariables();
requestVars.id = 'abc';
urlReq.data = requestVars;
urlReq.method = URLRequestMethod.POST;
urlReq.url = '../../bin-debug/FlexApp.html';
navigateToURL(urlReq);
Could you pass your variables within the url and then use flashvars via swfobject to pass them to the target app?
I've had more or less similar issue, and used this method.
In my first swf:
var urlReq:URLRequest = new URLRequest(String("game.html?user_id="+userId+"&user_code="+userCode));
And then in game.html I parsed those variables and sent then as flashvars:
<script type="text/javascript" src="swfobject.js"></script>
<script type="text/javascript">
function getUrlVars() {
var vars = {};
var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi,
function(m,key,value) {
vars[key] = value;
});
return vars;
};
var flashvars = {
user_id: getUrlVars()["user_id"],
user_code: getUrlVars()["user_code"]
};
var params = {
quality: "high",
bgcolor: "#000000",
play: "true",
loop: "true",
wmode: "window",
scale: "showall",
menu: "true",
devicefont: "false",
allowScriptAccess: "true"
};
swfobject.embedSWF("preloader.swf", "flashContent", "980", "663", "11.2.0",false, flashvars, params);
</script>
And finally in my target swf I received them like this:
var userId:String = loaderInfo.parameters.user_id as String;
var userCode:String = loaderInfo.parameters.user_code as String;
I hope this helps, and if not, then I probably didn't understand the main issue.
The POST data is sent to the server, so if you want to read it on FlexApp.html from the client then the server needs to echo it back on that page somehow. Otherwise you could use a GET request and access the request parameters using JavaScript window.location.search.
Here's an example using PHP to output the POST variables as JSON to the page:
<script>
var post_params = <? echo json_encode($_POST); ?>
function getPostParam(name){
return post_params[name];
}
</script>
Call from JavaScript:
alert(getPostParam("id"));
Call from ActionScript:
trace(ExternalInterface.call("getPostParam", "id"));

AS3 Flash URLRequest not working upon export

This simple login form works within the test environment of CS6 (Flash 11.4) but upon exporting does not work. I've narrowed down the issue to the actual URLRequest not working properly. Hopefully somebody can shed some light!
Many thanks, Nick :)
AS3
login.loginSubmit.addEventListener(MouseEvent.CLICK, function(){
if(login.loginPassword.text!="Password" && login.loginPassword.text!=""){
login.loginSubmit.enabled = false;
// Begin URL setup for login
var loginVariables:URLVariables = new URLVariables("email="+login.loginEmail.text+"&password="+login.loginPassword.text);
var loginRequest:URLRequest = new URLRequest();
loginRequest.url = "login.php";
loginRequest.method = URLRequestMethod.POST;
loginRequest.data = loginVariables;
var loginLoader:URLLoader = new URLLoader();
loginLoader.dataFormat = URLLoaderDataFormat.VARIABLES;
loginLoader.addEventListener(Event.COMPLETE, loginHandler);
function loginHandler(event:Event):void {
if(loginLoader.data.passed=="true"){
var hideInitial:Tween = new Tween(uiInitial, "x", Strong.easeOut, 6, -315, 0.5, true);
hideInitial.addEventListener(TweenEvent.MOTION_FINISH, function(){
member.data.email = loginLoader.data.email;
member.data.fname = loginLoader.data.fname;
member.data.lname = loginLoader.data.lname;
member.flush();
});
}else{
trace("error");
}
}
// Send PHP/SQL request
loginLoader.load(loginRequest);
}
});
You need to enable the network access for your published SWF. Go to Publish Settings for Flash (.swf) and Set the "Local playback security" settings to "Access Network Only".
Turns out that there is both a local and external URLRequest, causing trouble with the settings. I've made both the same (external) and of course hosted them on the same domain as the Flash, now works.

Action Script 3 loading images from remote domain

I have an application that is running on portal VK com. I need to load images (.png) from their domain (which are players avatars basicly). What I get is SecurityError: Error #2123. It looks like in crossdomain.xml file on their domain there is no proper tag.
I've done following things:
Set allowSecurityDomain to * in my swf
I'm passing LoaderContext to Loader::load method defined like this:
var context:LoaderContext = new LoaderContext();
var context.checkPolicyFile = true;
loader.load(new URLRequest(img), context);
This is working on other portals (facebook, mojmir, odnoklassiniki, etc..) but not this one.
If you want to load images you can use the Image tag:
<mx:Image source="http://...." autoload="true" />
You won't have to deal with cross domain policy.
In AScript you can use:
var img:Image = new Image();
img.autoLoad = true;
img.source = "http://someurl/img.png"
img.addEventListener(Event.COMPLETE, function(e:Event):void {
//loaded
});
img.addEventListener(IOErrorEvent.IO_ERROR, function(e:IOErrorEvent):void {
//not loaded
});

How to get the swf name using javascript?

I have embedded a single swf three times named as video.swf.
The swfs names are video1 , video2 and video3.
If I play a swf, I wants to get the currently playing swf's name?
Is it possible ?
I'm using javascript for communication.
I had to do something very similar for work on a project for Swatch/MTV (having multiple embedded players on a page and playing only one clip at a time (playing a different clip, would pause others, etc.)
e.g.
var vids = ['video/file/72066f40bfcaea46e10460585b4e4bcb.mp4','video/file/3d5db6b87f9cdacb016c9c55afed1e08.mp4','video/file/c18b04a1a548cbf20609de70a106d7cc.mp4','video/file/4568a11f3f6a7ff467a85fefe2ac08e6.mp4','video/file/b91081d37a81692194c0e34580958c51.mp4']; for(var i = 0 ; i < vids.length; i++){
var flashvars = {};
flashvars.video_url = 'http://www.swatchmtvplayground.com/'+vids[i];
flashvars.video_id = i;
flashvars.locale = "gb";
flashvars.skin = 'upperBackground:0xf8c3c4,lowerBackground:0xe2e2e2,generalControls:0x000000,slider:0xb58f8f,progress:0xe2e2e2';
var params = {};
var attributes = {};
attributes.id = "mediaplayer"+i;
so = swfobject.embedSWF("http://www.swatchmtvplayground.com/flash/mediaplayer/mediaplayer.swf", "mediaplayer"+i, "578", "345", "10.0.0", false, flashvars, params, attributes);
}
function pauseAllPlayers(exceptThisOne){
for(var i = 0 ; i < vids.length ; i++) if(exceptThisOne != "mediaplayer"+i) document.getElementById("mediaplayer"+i).pause();
}
to get the id I've used a neat little trick I didn't previously know about (executing JS created with actionscript) using Zeh Fernando's excellent guide: Getting the SWF’s HTML object/embed id from within the Flash movie itself
HTH
If you're using the same swf file three times you'd have to pass in a flash var to let the swf know which instance it is (video1, video2, or video3). Then when a video.swf instance starts playing use AS3's ExternalInterface to call JavaScript and mark that swf instance as the one currently playing.
Using SWFObject to embed the swfs in the page you can set the flashvars in JavaScript like this:
var flashvars1 = {
name: "video1",
};
swfobject.embedSWF("video1.swf", "flashContent1", "640", "480", "10.0.0", false, flashvars1, {}, {});
var flashvars2 = {
name: "video2",
};
swfobject.embedSWF("video2.swf", "flashContent2", "640", "480", "10.0.0", false, flashvars2, {}, {});
var flashvars3 = {
name: "video3",
};
swfobject.embedSWF("video3.swf", "flashContent3", "640", "480", "10.0.0", false, flashvars3, {}, {});
Within each swf you'll now have a 'name' var that can be accessed through LoaderInfo:
var name:String = LoaderInfo(this.root.loaderInfo).parameters.name;
And you call ExternalInterface from Flash like so:
ExternalInterface.call( "videoPlaying", name );
This would call a JavaScript function called 'videoPlaying' with the name as the argument:
function videoPlaying(name) {
// do something with the name arg
}