Scriptability refers to the ability of plugins to interact with JavaScript. In particular, the Macromedia® Flash™ plugin exposes certain plugin functionality for access via JavaScript. It can also access JavaScript methods from within the plugin. This article explains how JavaScript can be used to access methods from within the Flash plugin, as well as how a feature called FSCommands can be used to access JavaScript functions from within the Flash animation. The focus of this article is to present tips on scripting Flash within Gecko™-based web browsers.
Detecting the Right Flash Plugin (and browser)
Adobe Flash has exposed the scriptability feature in Netscape Gecko browsers since Flash 6r49 and later. Versions of Flash prior to Flash 6r49 (such as Flash 5) are not scriptable in Netscape Gecko browsers. Thus client-side detection for the right version of Flash is an important aspect of creating a scripted Flash experience. On Mac OS X, there is an additional caveat: Netscape Gecko browsers such as Camino (formerly Chimera), the latest Mozilla browsers, and future versions of Netscape which are built using the Mach-O binary format won't be able to use Flash's scriptability features. Until Macromedia changes this from within the Flash plugin, scriptability can not be used on Mac OS X browsers based on Gecko. The example below shows a detection heuristic in action.
Example 1: Verifying the Flash Plugin Version
Below, JavaScript identifies the version of Flash, and whether it is scriptable in Netscape Gecko:
can we have javascript in a wiki page? <script type="text/javascript">identifyFlash();</script>
Typically, JavaScript code that determines what version of the plugin is installed looks at the mimeTypes array that is part of the navigator object. Every plugin exposes a description string that typically includes the plugin's name and version number. The Flash plugin's description string uses a standard versioning nomenclature that can then be parsed for meaningful information. For example, the current Flash plugin version is Flash 6 r79. The description string exposes this version. Furthermore, it is also necessary weed out versions of Flash that are not scriptable in Mach-O browsers on OS X. Fortunately, Mach-O browsers based on Netscape Gecko expose this information in their user-agent string. An algorithmic approach to detecting Flash plugin version might be:
var plugin = navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin; var description = plugin.description; // 1. Tokenize description string to its constituent parts var versionArray = description.match(/[\d.]+/g); // 2. Determine if the Flash version is greater than 6r.49 // 3. If so, the plugin is scriptable on Windows and Linux // 4. Determine whether the browser is a Mach-O browser // 5. If the browser is a Mach-O browser, determine whether the version of the plugin // is greater than 12, a hypothetical version when Flash will fix the plugin to be // scriptable on Mach-O browsers also var flashVersionOSXScriptable = 12; if(navigator.userAgent.indexOf("Mach-O")!=-1) { if(flashversion < flashVersionOSXScriptable) // Flash version is less than version 12, thus not scriptable on OS X } // 6. Handle errors (no Flash installed, etc.)
Example 1 uses the RegExp (regular expression) object exposed to JavaScript strings. The description string is broken into an array of constituent strings based on an invocation of the match method with a regular expression that assumes that the string format will be in the format Flash Major rMinor where Major can be a major revision such as "5" or "6" and Minor is the subsidiary version number. Example 1 also creates a constant flashVersionOSXScriptable that declares (arbitrarily) that Macromedia will fix Flash to be scriptable in Mach-O browsers (on OS X) by version 12. This is currently NOT the case, but 12 is a sufficiently high version number (current versions are version 6r.79) to allow for some leeway for fixing this down the road. When information about when this problem on Mac OS X will be addressed becomes available, the constant can be updated to reflect something less arbitrary. A complete code listing which expands on the above approach can be found in the flashversion.js file used in the samples.
Performance and Flash
As is the case with any plug-in content, Flash content has the potential to slow down or even completely stall not just the tab it's running in, but the entire browser and even the entire computer it's being used on. Avoiding poorly-written or unnecessary Flash content is crucial to ensuring the user has a positive experience on not just your site, but the entire Web. As part of Mozilla's effort to improve the user experience, a feature was added in Firefox 49 that automatically blocks certain Flash modules that have little or no user-noticeable impact from being used. These block-listed modules include various fingerprinting and HTTP_cookie#Supercookie modules. In the future, other modules may be blocked as well. And, of course, eventually Flash support will be removed from Firefox entirely. Most of its functions can be reproduced using modern Web APIs.
Using the right HTML
The object element OR the embed element can be used to invoke plugins in Netscape Gecko browsers. The former is part of the W3C HTML 4 standard, whereas the latter is a deprecated element, as discussed in Using the Right Markup to Invoke Plugins. However, if you wish to use FSCommands with the Flash plugin to call JavaScript functions in an HTML page, then you must use the embed element, as discussed further in the section on FSCommands.
Accessing Flash from JavaScript
The simple example below shows how input into an HTML text box in a form field can be transferred to a Flash animation (the grey text box below).
Example 2: JavaScript to Flash Communication
Note: Javascript to Flash Communication may not work with flash player versions older than version 8 if the user has installed multiple Mozilla based browsers onto the same machine (see bug 284057 and bug 233533).
Enter some text in the HTML form field below and then click outside the field, or hit the Enter key, to send the text to the Flash movie below:
The example is missing.
Example 2 shows the use of Macromedia Flash's SetVariable method being invoked from JavaScript. In general, to invoke a Macromedia-defined method on a Flash animation in Netscape Gecko browsers:
- Use DOM methods to get a handle to the HTML element that spawns the plugin. This may be the embed element or the object element's name or ID attribute respectively.
- Treat the handle to the HTML element as a handle to the actual Flash plugin and invoke the published methods on it. The illustrative code snippet below shows this idea:
<object id="myFlash" ..... > <param name="movie" value="somefile.swf" /> .... var myFlash = document.getElementById("myFlash").SetVariable("myVar", sendText);
A more expanded code example that shows how Example 2 was created is shown in this source listing.
FSCommands: Accessing JavaScript from Flash
Note: FSCommand may not work with Flash Player versions older than version 8 if the user has installed multiple Mozilla based browsers onto the same machine (see bug 32048 and bug 233533).
In Example 2, a JavaScript function first obtained a handle to the HTML that spawned the plugin (the object element or the embed element) and then called a published method of the Flash plugin on the reference to the HTML element. With FSCommands, developers may choose to use Macromedia's ActionScript language to make a call back into the environment that contains the Flash animation -- in this case, the HTML page. The example below shows both types of communication in action:
Example 3: JavaScript to Flash Communication And FSCommands -- Flash to JavaScript Communication
The example is missing.
In Example 3, clicking the HTML button causes a ball to move in the Flash animation. This exemplifies JavaScript to Flash communication. By clicking the HTML button, you trigger a JavaScript event that further triggers actions within the Flash animation. Below that, you can change the color of the entire HTML page by clicking a colored tab. This shows communication flowing in the other direction -- namely, an action taken within the Flash animation affects something in the HTML page that contains the Flash animation.
Example 3 shows FSCommands in action. If you are embedding a Flash animation and wish to use FSCommands in Netscape Gecko browsers, currently you must use the embed element and not the object element. You can always nest the embed element within the object element that you serve to IE. Future Flash versions may support the object element for use with FSCommands in Netscape Gecko browsers. This issue is being tracked in Mozilla's Bugzilla database.
The background color of the entire page is toggled by clicking on a color within the Flash animation. Clicking on the animation makes a callback to the external environment that hosts the plugin (the HTML page) and looks for a JavaScript method to handle the call from within Flash. The call is made within the Flash animation's ActionScript methods. JavaScript functions that handle such callbacks are specially named so that the Flash plugin can find them. These special callback functions are named with a concatenation of the name of the embed element, the underscore ("_"), and the string "DoFSCommand". The following code snippet illustrates the ideas behind the use of FSCommands demonstrated in Example 3:
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" id="myFlash" width="250" height="150" VIEWASTEXT> <param name="movie" value="js2flash.swf" /> <param name="quality" value="high"></param> <embed src="js2flash.swf" width="250" height="150" swLiveConnect="true" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" name="myFlash"> </embed> </object> ..... function myFlash_DoFSCommand(command, args) { // handle any callback logic that you may have designed into your Flash plugin // the Flash animation will supply you with the values for command and args // This is a function that handles any information that the Flash animation may pass it // ActionScript can communicate with JavaScript via FSCommands! }
In the above code listing, the JavaScript function handles what Flash sends it, and is named the same as the embed element's name attribute, concatenated with "_DoFSCommand". The source listing flash-to-js.html shows a source for this example. See Macromedia's ActionScript dictionary for pointers on invoking FSCommands from within the Flash animation code.
See also
Macromedia Flash Developer Documentation
- Scripting The Flash Player Plugin
- Communication Between JavaScript and Macromedia Flash
- FSCommands (Definition from the ActionScript Dictonary)
- ActionScript Dictionary