Using Browser States
Track states within your Flash application
To communicate the application state to the browser, you can use the BrowserStateManager class included in the source code download. This class supports synchronizing the browser's current URL with the state of a Flash app, and can optionally update the browser window title to describe the current state. These features enable direct access to states of the Flash application and bookmarking of those states.
To use this class, import BrowserStateManager in your Flash application and create a new instance, for example:
import BrowserStateManager;
var browserState = new BrowserStateManager();
After creating the browserState this way, you can find out the initial state that your app should be in (be sure to handle the cases where no state or an invalid state is specified), and set it to that state, for example:
var id = browserState.getValue("id");
When the state changes in your application, you should notify the browser:
browserState.setValue("id", String(photoIndex));
browserState.setWindowTitle("Kevin's Photo #"+String(photoIndex));
More than one value can be stored as part of the browser state, just call setValue for each one and they will all be recorded in the browser state. Setting the window title is not required, but helps the user distinguish names of bookmarks with different states in the same application.
Set up the containing HTML page
To receive messages from the Flash application in the browser, you'll need to include the following code in the HTML head section of the page containing your Flash application (as shown in index.html in the example source):
<script language="VBScript">
<!--
Sub flashapp_FSCommand(ByVal command, ByVal args)
select case command
case "putHREF" location.href = args
case "putTitle" document.title = args
end select
end sub
-->
</script>
<script language="JavaScript">
<!--
function flashPutHref(href) { location.href = href; }
function flashPutTitle(title) { document.title = title; }
function showFlash(swf, w, h)
{
var isMSIE = navigator.appName.indexOf("Microsoft") != -1;
var l1 = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0" width="'+w+'" height="'+h+'" id="flashapp" align="">'
var l2 = '<param name="movie" value="'+swf+'" />'
var l3 = '<param name="menu" value="false" />'
var l4 = '<param name="quality" value="best" />'
var l5 = '<param name="FlashVars" value="initialURL='+document.location+'&isMSIE='+isMSIE+'" />'
var l6 = '<embed src="'+swf+'" FlashVars="initialURL='+document.location+'&isMSIE='+isMSIE+'" menu="false" quality="best" width="'+w+'" height="'+h+'" name="flashapp" align="" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed></object>'
document.write(l1+l2+l3+l4+l5+l6);
}
-->
</script>
Finally, call the showFlash function in the body of the HTML page to insert the application and establish communication with the browser -- the parameters are the URL of the Flash application, width, and height:
<script language="JavaScript">
showFlash("example.swf", 500, 400);
</script>
How It Works
The above information should be enough to enable you to support browser states in your Flash applications. If you're curious about how this works underneath the covers, read on.
Encoding state information
The state management of Flash applications is based on a combination of how named anchors refer to locations in an HTML page and how serverside states are managed. The following is a quick review of those approaches and how to encode local application states.
Named anchors: URIs can point to a particular location within a page is using
a named anchor tag and referring to it after a # sign (for example, http://klynch.com/someplace/index.html#comments goes
to the comment section on that page).
Serverside states: URIs can refer to a particular state of a serverside application
by placing state information after a ? character (for example, http://technorati.com/cosmos/search.html?rank=links&url=klynch.com instructs
Technorati to display recent links to my blog). This is often referred to as
a REST (representational state transfer) model.
Local application states: The Flash application state management technique combines these techniques, placing the state in an anchor reference and encoding the state in the REST syntax. This results in URIs of the following form, which can be updated during interaction without reloading the page and can be bookmarked:
http://klynch.com/apps/flashlinking/index.html#id=3&foo=kevin
This form also supports combining local state with dynamic serverside parameters, for example if Technorati returned a Flash application on its result page the REST information for the server and the local application can both be preserved:
http://technorati.com/cosmos/search.html?rank=links&url=klynch.com#id=3&foo=kevin
Passing information to Flash on load
When the page is loaded, any state information will need to be passed to the Flash application so it can display the correct initial state. There are several ways to accomplish this, and the best way appears to be through the FlashVars parameter. Variables passed in this way are automatically defined in the Flash application. This can be seen in the code above as the following two fragments:
var l5 = '<param name="FlashVars" value="initialURL='+document.location+'&isMSIE='+isMSIE+'" />'
var l6 = '<embed src="'+swf+'" FlashVars="initialURL='+document.location+'&isMSIE='+isMSIE+'" ...
Two variables are passed into the Flash application this way: initialURL,
which is set to the whole URL of the page containing the Flash application
(which may have state information in it), and isMSIE, which is
set to true if the browser is Microsoft Internet Explorer (this is used by
the Flash application to tell how to best communicate back to the browser).
Calling browser functions from Flash
When the state changes in the Flash application, the browser is notified by calling some functions on the HTML page from Flash. This is best accomplished two different ways depending on whether the browser is Internet Explorer or not. These communication issues are of course all handled within the BrowserStateManager class.
On non-IE browsers, Flash can send messages to a JavaScript function in HTML by simply calling getURL in ActionScript and using the javascript prefix to indicate there is some script to be run, in this case calling flashPutHref:
getURL('javascript:flashPutHref("#'+this.stateStr+'");');
The receiving JavaScript functions are defined in the containing HTML page such as:
<script language="JavaScript">
<!--
function flashPutHref(href) { location.href = href; }
function flashPutTitle(title) { document.title = title; }
-->
</script>
On Internet Explorer, the communication is more reliable using FSCommand from Flash ActionScript as follows:
fscommand("putHREF", "#"+this.stateStr);
The receiving functions in Internet Explorer are defined in VBScript on the containing HTML page such as:
<script language="VBScript">
<!--
Sub flashapp_FSCommand(ByVal command, ByVal args)
select case command
case "putHREF" location.href = args
case "putTitle" document.title = args
end select
end sub
-->
Something to note here is the name of the VBScript function (flashapp_FSCommand) needs to begin with the same name as the Flash application's ID used in the Object tag (flashapp), as this is how the Flash Player knows which function to call on the page in Internet Explorer.
Setting the URL and window title
Once the message is sent from Flash to the browser, setting the URL and window
title is just a simple bit of JavaScript or VBScript. The URL is updated by
setting location.href to the new string, and the window title
is updated by assigning a new value to document.title.
What Doesn't Work
This technique covers bookmarking well, but doesn't support using the browser's back button to step backward to previous states. Some browsers will actually update the URL to show the previous states, but Flash isn't notified of the change.