Resolving some issues with swfobject

There are some known issues with swfobject and ASP.NET, infact it’s not just with swfobject but also with the Flash object in general, one issue of using ExternaInterafce from an ASP.NET Form can be solved with these technics

I had a strange issue with swfobject lately and obviously I’ve blamed ASP.NET for inserting unwanted code into my pages and causing problems. Generally it’s reasonable to blame it as it does make a mess sometimes, but, this time it was my fault for not noticing other Javascript code is conflicting with swfobject.

The issue I had, was with the swfobject’s addVariable and addParam functions. The Flash SWF HTML seemed to be written to the page’s flashContent div but all of the variables and parameters I’ve added were ignored. After examining the swfobject getSWFHTML function, this function gives you the HTML code that is gonna embed the Flash inside the page, when I saw how strange the HTML is, I realized what happened:
Without naming names ;) some Javascript developers, extensions and frameworks like to write to the prototype of generic Javascript objects (This is also how Object Oriented Actionscript 1 was done in the past). And with doing so, extending these built-in objects (object, array, string, etc’) with various functionalities. A good example is the javascript JSON implementation which extends the Javascript object with object.toJSONString(). Swfobject stores the variables and parameters inside a regular Javascript object and when it prepares the Flash HTML it uses a for..in loop to go through all the elements and add them to the markup
<param value=”flashMovie.swf” name=”movie” />
<param value=”transparent” name=”wmode” /> etc’

in case you’re using the json.js, your HTML will have also
<param name=”toJSONString” value=”function (w) {….and whole lotta mess” />.

This might cause the embedding of the Flash movie to fail or function improperly.

The solution for this is to add a check to all of the for..in loops inside swfobject with the hasOwnProperty, for example:

[JS]for(key in variables){
if( variables.hasOwnProperty( key ) )
{
variablePairs[variablePairs.length] = key +”=”+ variables[key];
}
}[/JS]

The hasOwnProperty function returns true only if the property is not built-in and not in the prototype chain. Therefor the toJSONString in our example will return false and wont be considered as a flash variable or parameter.

When encountering issues with the swfobject a good place to check is the swfobject.getSWFHTML() function.
[JS]var o=new SWFObject(“flashFile.swf”,”falshMovie”,200,300,”9″,”#FFFFFF”);
o.addVariable(“firstName”,”Jon”);
o.addVariable(“lastName”,”Smith”);
o.addParam(“wmode”,”transparent”);

//exmine the html before it’s being writen to the div
alert(o.getSWFHTML());

o.write(“flashContent”); [/JS]

More related info about hasOwnProperty.

Script# – C# compiled into Javascript

This might sound familiar to you, the idea of writing an Object Oriented code, that allow compile-time checking, and good code design, that is then compiled into a script code was introduced by Macromedia at 2003 with Flash 7 and it’s shiny new Actionscript 2.0, but, AS2, with all the respect is not as complete as C#.

Script# does the same for Javascript, it lets you leverage the power of C# with it’s Object Oriented abilities and compile it into a clean and readable Javascript.
The new Script# version 0.2.0.0 now have added support for WPF/E.

Learn more about it…

There is a similar OS tool named Google Web Toolkit that appearntly does similar things for Java and Javascript.

Uglying your photos with style

You might call it Pimp if you want it to sound cooler, but all in all pikipimp.com will help you make fun of people by uglying their images. Check out how I’ve uglified this beautiful model. You won’t see too many masterpieces coming from there, maybe also because it isn’t meant for creating works of art. The “Pimping” is easily done and is accessible for everyone. You simply upload your photo and immediately you can start to drag elements like beards and glasses on it.

I think, that not so long ago, maybe a year ago, it was unlikely that such a website will emerge. Before the Javascript-goldenage no one would have dare to use such a complex Javascript which now looks very natural to use. Also the hype around such a site wouldn’t be as massive, these days it is mentioned in many of the leading Web 2.0 / technical blogs like Techcrunch and Go2Web2.

While it was neatly done with javascript, and I’ve read the author mentioned Ruby, some apps are just ment to be flashed. For example, rotating the elements is done by the server and suffer from a long unintuitive delay, Flash could easily handle these rotations on the client. Also, the stacking of the elements is done by setting the HTML div’s position to absolute, that’s the only way z-index can be applied in HTML, on the other hand, your image is embeded along with the relative site structure, so, if you resize your page your creation get scrambled. There are many more improvements that Flash could have handled, I won’t have to tell you everything, when every stupid innovation is worth millions of dollars and can be called a Start-Up these days ;) lol.

Get piki-pimping…

PikiPimp Interface

pikipimp_glasses

Every element has it’s own controls

pikipimp_controls

Original photo

pikipimp_model_small

Pimped (uglified) photo

pikipimp_pimped

Best way to get address variables into Flash

I’ve seen too many wrong or old soulotions for sending query string variables into Flash (page.html?var1=Jon&var2=Smith… etc.). In fact, if you’ll google it you’ll find this old Macromedia article from the year 2000 and about Flash 4, while most of it still applies it’s definitely old. These days, we’re using swfobject, if you don’t use it then you should, swfobject comes with a “global” javascript function called getQueryParamValue and you can use it for setting query/address string variables into FlashVars as follows:

[js]var so = new SWFObject(“movie.swf”, “flashMovie”, “250″, “150″, “8″, “#FFFFFF”);
so.addVariable(“var1″, getQueryParamValue(“var1″));
so.addVariable(“var2″, getQueryParamValue(“var2″));[/js]

These variables will be availble as _root.var1, _root.var2, etc. For complete explanation go here. The best thing about FlashVars is that they are available for use as soon as the Flash movie starts, and before everything else, so you can refer, for example, to the variable _root.var1 in the first line of code, as opposed to another old method setVariable, where we had to wait for the variable availability using somthing like watch.

Though the advantage of FlashVars, personly, I don’t like _root variables, it seems unclean, especially when it’s a long query string that’ll make tons of them floating in my _root. Since Flash 8 we can use ExternalInterface to call to getQueryParamValue and get an immediate and synchronous response from within Flash, that way we can have a neater control over owr address variables, for example:

[as]var sVar1:Object = ExternalInterface.call(“getQueryParamValue”, “var1″);[/as]

Play with the example, try different variables.

If you don’t use swfobject, I guess you can easily write your own javascript method for getting address variables, but why bother, I don’t think you can easily improve on that one. I also don’t think that Geoff Stearns, the author of swfobject, will care if you’ll copy this function:

[js]function getQueryParamValue(param){
var q = document.location.search || document.location.hash; if(q){
var startIndex = q.indexOf(param +”=”);
var endIndex = (q.indexOf(“&”, startIndex) > -1) ? q.indexOf(“&”, startIndex) : q.length;
if (q.length > 1 && startIndex > -1) {
return q.substring(q.indexOf(“=”, startIndex)+1, endIndex);
}
}
return “”;
}[/js]

It’s great for non flash websites as well.

Get example files

Get swfobject

Understanding Flash’s ExternalInterface.

It occurs to me that too many people are not aware of the Flash 8 new and shiny ExternalInterface and are still using fscommand and setVariable or getURL for flash-javascript communication.
In this post I’ll describe the advantages of ExternalInterface over the previous solutions, how to use it, a short tutorial about it, and also about the future of Flash-to-Javascript symbiosis with FABridge. Bear in mind that the ExternalInterface Class can be used to communicate from a flash-swf file to any kind of a supported container, in this text I will focus on a webpage container and we’ll connect to its Javascript functionality. We could, for example, use it in a similar way to communicate between Flash hosted inside an executable and its C# functionality.


Why should I care ?!

There are many reason to use Flash-Javascript communication, the more general ones are: using functionality that doesn’t yet implement naturally into Flash like XPath, REgEx, etc’. Controlling other webpage elements, active-x or plugin, from Flash. For example: Window Media Active-x. Using Flash with AJAX, and much more.
Check Step by step tutorials at the bottom of this text.


ExternalInterface minimum requirements

The ExternalInterface Class is only available from Flash 8 and above and will work only in Flash Player 8 and above. Also, there is a minimum browser requirement, the supported are:

Windows Internet Explorer 5.0 and above
Firefox 1.0 and above
Mozilla 1.7.5 and above
Netscape 8.0 and above
Safari 1.3 and above.
Opera 9 and above.
And any browser that supports the NPRuntime API.

The static Boolean property ExternalInterface.available will indicate whether the requirements are meet. Check it from within your targeted container / browser.
Click on the button, if it’s ‘false’ then your browser is probably not supported, if it’s ‘undefined’ then your player is probably less then version 8, if it’s ‘true’ you’re ready to go!

[kml_flashembed movie="http://blog.guya.net/wp-content/uploads/2006/06/ExternalInterface_available.swf" height="90" width="290" /]
If you’re targeting a not supported browsers or an older Flash players, then you may consider: Flash / JavaScript Integration Kit


Main improvements:

Easier to setup:
Well, that’s an understatement, in order to make your flash ready for javascript communication you need to do…, nothing. But, because of the new Flash 8 Player security you can’t test your files locally. Meaning that, the files will only run properly on a web server. If you want to test your files locally, all you have to do is make sure that the “allowScriptAccess” is set to “always” inside your html Flash <object> tag, like this:
<param name=”allowScriptAccess” value=”always” /> to support firefox and alike change also the <embed> tag: allowScriptAccess=”sameDomain” to “always”.
If you’re using swfobject your script will look something like this:
so.addParam(“allowScriptAccess”, “always”);. This also won’t guaranty that your files will work locally in all cases, though. You might also need to go to the Flash Player Setting Menager and add the swf files or folder as trusted. Here is a video demo on how to do that.
In Flash 6, 7 some Javascript and Vbscript functions had to be written in order to catch the fscommand calls from Flash. Flash 7 and above can insert these function automatically for you if you choose: Publish Settings… -> HTML -> Template->’Flash with FSCommand’. But it’s still ugly.

Synchronous:
Which mean you can return a value from a Javascript function into flash and vice versa. If you ever used flash-to-javascript communication before flash 8, you’ll understand how useful this is. On previous versions of Flash this couldn’t be done. In order to receive data from javascript, we had to call a javascript setVariable, and that only worked on Object’s/MovieClip’s dynamic properties, and then we had to watch / wait for the data that was written into the MovieClip’s property to arrive to Flash. As opposed to now, communication was asynchronous, the data just wasn’t available instantly, and since the Object.watch sux so much in Flash 7. onEnterFrame or intervals had to be used. (I’ll admit that the Object.watch can be suitable in simple cases, though)

Calling Actionscript functions from Javascript:
Again, an amazing improvement. Now, any declared Flash function can be called directly from javascript with a simple script like flashMovie.someFunction(); and if this function returns a value it can be synchronously received by the browser’s Javascript. Before Flash 8, if we wanted something done inside flash and do it from javascript, calling a flash function for example, we had to set up a flag and go through a similar process as described above, of waiting/watching for that flag/data to arrive into Flash. Then according to that flag call the desired function.

Multiple Variables:
ExternalInterface enable us to send or receive as many arguments as we want or send none. With the old fscommand only 1 and at least 1 string could have been sent to a javascript function.

Multiple Data types:
ExternalInterface supports, sending and receiving, arguments of type: Boolean, String, Number, Array, Object (user defined classes are not supported). Sorry to be dramatic again but this has almost brought tears of joy to my eyes. All this time we had to use nothing more then one lousy String.


How to use the ExternalInterface Class

Calling is easy, Use the static ExternalInterface.call() function.

import flash.external.ExternalInterface;

ExternalInterface.call(“alert”, “called from flash”);

This will call the javascript’s ‘alert’ function with the value of “called from flash”

alert_called_from_flash.jpg

For me, this is the most important improvement: Synchronous. If the Javascript function return a value you can simply retrieve it as follows (in this example it’s a Number but it can be any of the supported types):

var nValue:Object = ExternalInterface.call(“someJSFunction”);

To declare a Flash function as callable from Javascript you simply use the static ExternalInterface.addCallback() function.

The addCallback static method accepts 3 arguments. The first is a string representing the name, the Actionscript function should be called at, from Javascript. The second is an object reference for the Actionscript function, it’s where the scope of “this” inside the Flash function will be. The third is a reference to the Flash function. It is recommended to name the Javascript function the same as the real Flash function for sake of clarity.

ExternalInterface.addCallback(“someFlashFunction”, this, someFlashFunction);

Use this Javascript code to get a reference to your Flash movie.

“flashMovieID” is the ID of the Flash movie object inside the HTML.

[js][/js]

If the Flash function returns a value you can retrieve it as follows, as you might guessed:
var oValue = flashMovie.someFlashFunction();


Step by Step Tutorials for ExternalInterface

I will publish some step by step tutorials with in-depth explanation, source code and images in the next posts. I want to keep this post more concise. (or maybe I’m just too lazy right now… ;) )

Among the tutorials will be:

Best way to get browser’s address variables into Flash.
Controlling another Active-X control – creating flash buttons for Windows Media Player or Apple Quicktime.
Putting Javascript power in Flash’s use – RegEx and XPath.
Catching Javascript Exceptions in Flash.
Creating, a, dynamic Flash website with AJAX.


Examples

Download ExternalInterface availability check

The Flash 8 IDE Installation will install two examples of using the ExternalInterface including the fla sources. But, it doesn’t work locally because they forgot to update the html <object> “allowScriptAccess” to “always”. If you want to check these examples locally simply change the word “sameDomain” wherever it appear (change it twice: one for the object param and one for the embed param) to “always” from within the html files. If it’s still doesn’t work go to the Flash Player Setting Menager and add the swf files or folder as trusted. As described above under Easier to setup:

Find the examples here:
In Windows, browse to boot driveProgram FilesMacromediaFlash 8Samples and TutorialsSamplesActionScriptExternalAPI.
• On the Macintosh, browse to Macintosh HD/Applications/Macromedia Flash 8/Samples and Tutorials/Samples/ActionScript/ExternalAPI.


The future of Flash-Javascript symiosis with FABridge

Adobe wants to make Flash an IDE independent platform. Which means we’ll be able to create Flash RIA websites and application without the need of Adobe Flex Builder, Using the free Flex SDK, free Flex Data Services and any other third party software. Adobe relized that in order to make Flash the dominant force behind the rich web they have to free it from the restraints of any Flash/Flex IDE. And to leave it solely in the hand of the Flash/Flex developer. Adobe wants to make the Flash Platform as standard as HTML is.

With FABridge and alike, after the Flex Builder IDE was removed from the equation, the aim is to reduce the need for the Flex developer. With the insertion of the FABridge library into your Flex project you are completely exposing all the Actionscript 3.0 capabilities to Javascript. Basically you can code complete Flex apps using nothing but Javascript. This will appeal to Javascript developers who are comfortable with it and don’t want to develop simultaneously in both Flex and Javascript environments. FABridge will enable us to take full AJAX websites and Frameworks and easily update it to a full Flex websites or Frameworks to harness all the Flash platform capabilities.

FABridge is availble in pre-alpha since march 2006, so there is already some info about it circling around:
Last Friday I saw the online Adobe event “Flex and Ajax – Better Together” with James Ward. While it was mostly about how much superior Flex is from AJAX, he did showed a few integration / FABridge examples.
A similar presentation by Christophe Coenraets is availble here, with some more FABridge examples.

Go here to download FABridge and get some more info about it. Also check this impressive example that only scratch the surface. (require Flash Player 9).