We recently stumbled upon an interesting part of web application : making a Flash object communicating with its containing HTML page’s JavaScript functions. This is not unheard of, of course, but in the world of UWA, this can prove difficult to implement in a working way.
A reminder: JavaScript in UWA
As UWA developers know, portability and predictability in the framework’s usage has lead us to not recommend the use of JavaScript objets such as ‘window’ and ‘document’, instead recommending the equivalent to some of their methods that have been implemented in the UWA-specific ‘widget’ objet. For instance, ‘window.open()’ is to be dropped in favor of ‘widget.openURL()’, or document.getElementById(’uniqueID’)’ is to be replaced by unique classes and the use of ‘widget.boy.getElementsById(’uniqueClass’)[0]‘, among other things.
Failing to find the needed function equivalent in the UWA JS Framework, developers are suggested to implement the required code within the widget’s HTML page.
That is all fine and dandy: all UWA developers are now used to play with these idiosynchrasies, and their widgets just get sturdier thanks to that. But when it comes to Flash-JavaScript communication, things get more “idiosynchratic”, if you will…
The curious case of Flash-JavaScript communication
Flash-JS communication is a subject at least as old as Flash itself (well, at least as old as Flash 2 and FSCommand, then). The solutions at the time seemed almost magical, nowadays they are well understood and implemented within ActionScript – the Flash scripting language.
Calling a JavaScript function from the Flash application’s containing HTML page only requires a couple of ActionScript lines with Flash CS4. Let’s say we have on our Flash scene two main instances: a textfield named myInputText and a button named myButton. With a click on myButton, we want Flash to send the text content of myInputText to a JavaScript function called, for lack of a better name, theJavaScriptFunction().
Here’s how our ActionScript code could look like:
import flash.external.ExternalInterface;
myButton.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
function mouseDownHandler(event:MouseEvent):void {
if (ExternalInterface.available) {
try {
var tempStr:String = ExternalInterface.call("theJavaScriptFunction", myInputText.text);
}
catch (error:SecurityError) {
// ignore
}
}
}
Basically, with Flash CS4, the ExternalInterface object is the central place to improve your communication skillz. Past versions of Flash had other methods, that we’ll let you peruse at will, since it’s a safe bet CS4’s methods are here to stay…
Flash-JavaScript communication in UWA
Since UWA isn’t much more than a XHTML page, having Flash communicate with JS in that context should be a cake, right?
Wrong. Remember the first part of the article, where I reminded you of the “no ‘document’ object” recommendation? Well, as it turns out, JS method calls from Flash are targetted at the document – which means, basically, that if you try to call your MyWidget.AwesomeFunction(), Flash will in fact target document.MyWidget.AwesomeFunction(). Hilarity ensues.
One solution here is to break out of the “no ‘document’ object” rule, and build a proxy function for each JS method that you want called. For instance, in order to call this function:
MyWidget.AwesomeFunction = function(var) {
// some code
}
…you’d simply have to define a proxy AwesomeFunction directly on the page’s default object (the ‘document’ one), and have it call your UWA-tied function, like so:
function AwesomeFunction(var) {
MyWidget.AwesomeFunction(var);
}
So, this would tend to prove a little diversion can go a long way. But wait! There’s more!
Making your way through domains

Official explanation graphic from Adobe
Let’s say your ActionScript and JavaScript code is in place, as explain above. You load the widget directly in your browser (standalone mode), and it just works: awesomeness! But then you decide to install the widget on a Netvibes page, and lo!, it fails to even trigger AwesomeFunction(). Fatalitas!
No, Netvibes is not blocking such usage of UWA code. Simply put, Flash has some security restriction which you will need to check one by one before you can make it all shine.
The basis of these security measures is the domain name. In short, by default, a Flash app (.swf) can only communicate with external files (.html, .php, .xml, .js …) if it is hosted on the very same domain name.
This behavior is therefore broken once in Netvibes (or any Exposition-based widget server, for that matter), since widget’s are not only displayed within an iFrame (which might be a problem in itself), but also on a unique domain name. Hence, the HTML file can never be on the same domain as the SWF file, and therefore the data loading (or JavaScript communication, in our case) cannot happen.
Luckilly, Macromedia at the time undertstood that need, and gave us support for a crossdomain.xml file, which would let the developer allow (or disallow) a given set of domain to be accessed by the SWF. This XML file, hosted at the root of the domain bearing the Flash file, can take this form:
<?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="*" />
</cross-domain-policy>
For added fun, you can add the following lines to your ActionScript code:
import flash.system.Security;
Security.allowDomain("*");
These lines are another way for Flash to validate crossdomain access.
One down, only one more to go….
But that’s only for data, here. What we need in our case is access to the local JavaScript. This, in turn, is made possible by adding the AllowScriptAccess attribute in the SWF’s embed code, and setting it to “always”. Your embed code would therefore look like this:
<embed type="application/x-shockwave-flash"
src="http://domain-name.net/uwa-flash.swf"
width="250" height="100" bgcolor="#FFFFFF"
AllowScriptAccess="always"></embed>
Still willing to use Flash for your widget? Then hop onto the next section!
Handling UWA preferences from a Flash application
As if that wasn’t enough, there are cases where you’d like your Flash application to make use of UWA’s preferences methods, if only in order to record the user’s settings for the Flash app within the confines of the UWA environment.
This case should be view from two points:
- Have the Flash settings be saved as UWA preferences;
- Have the Flash app load the UWA preferences on startup.
The first part is pretty ease if you you follow the instructions above: instead of calling widget.setValue() directly from ActionScript (which would result in document.widget.setValue() being called instead, and therefore nothing happenning), you’d call UWA_setValue(), which in the HTML file would be defined as…
function UWA_saveInPref(varid) {
widget.setValue('myValue', varid);
}
Obviously, if you have more than one preference to set from Flash, you’d nees to expand on this code a bit…
Now, we want the SWF file to load up a preference, but only if it is set (obviously, else it would load the preference as ‘null’ or other unset values). That can be done pretty easily by passing variables to Flash via the embed code’s URL (or more precisely, its query string).

Why, yes it is!
Here is one way to get a nice, working query string for your Flash app…
First, retrieve the preference value, and build it into your query string via a ternary operator, for instance. Here is an example:
var myValue = widget.getValue('myValue');
div_flash.innerHTML += '<embed type="application/x-shockwave-flash"
src="http://domain-name.net/uwa-flash.swf'+ (myValue?'?theValue='+myValue+'':'')
+'" width="250" height="100" bgcolor="#FFFFFF" AllowScriptAccess="always"></embed>';
widget.setBody(div_flash);
If the ternary XXX finds that myValue is not empty (ergo, the preference is set), then it assigns its content to the Flash app’s theValue internal variable. If it is empty, ‘theValue’ is not even defined in the query string, and the Flash app launches in its default state – which is pretty much the whole point of this ternary operator.
Second, add the following two lines of ActionScript in your SWF’s first frame (given that you want to update a ‘myInputText’ textfield based on that query string):
var myQueryStrings = this.loaderInfo.parameters;
myInputText.text = myQueryStrings.theValue;
This will load our query string (using the loaderInfo object and its ‘parameters’ property), and assign the ‘theValue’ value as the text content of our beloved myInputText. Done: the textfield is updated with the correct UWA preference on each loading (or preference update)!
You can see it for yourself with this basic widget, the code of which is available here (you might need Flash CS4).
Two final tips, for the road
1) Don’t forget to add wmode=”opaque” to your embed code, so that i doesn’t overlap with Netvibes’s content!
2) Choose the “hidden” preference type if you want that preference to only be changeable through your Flash app!
Now go and build more awesome Flash-based UWA widgets!