Deep Linking in Shockwave


On the World Wide Web, deep link­ing is mak­ing a hyper­link that points to a speci­fic page or image on a web­site, instead of that website’s main or home page. Such links are called deep links. Court cas­es again­st deep link­ing have gone both ways in var­i­ous coun­tries.
Web­sites which are built on web tech­nolo­gies such as Adobe Flash and AJAX often do not sup­port deep link­ing. This can result in usabil­i­ty prob­lems for peo­ple vis­it­ing such web­sites. For exam­ple, vis­i­tors to the­se web­sites may be unable to save book­marks to indi­vid­u­al pages or states of the site, web browser for­ward and back but­tons may not work as expect­ed, and use of the browser’s refresh but­ton may return the user to the ini­tial page. How­ev­er, this is not a fun­da­men­tal lim­i­ta­tion of the­se tech­nolo­gies. Well-known tech­niques, and libraries such as SWFAd­dress and His­to­ry Keep­er, now exist that web­site cre­ators using Flash or AJAX can use to provide deep link­ing to pages with­in their sites.

From Wikipedia, the free ency­clo­pe­dia

 

This arti­cle treats an exem­plary imple­men­ta­tion of deep-link­ing in Shock­wave. In the fol­low­ing exam­ple we will use the unFo­cus His­to­ry Keep­er library, and espe­cial­ly the script called unFocus-History-p.js. This script will man­age the browser his­to­ry entries. The com­mu­ni­ca­tion between the sock­wave movie and the java script will be sup­plied by Valentin’s Direc­tor / JavaScript Inte­gra­tion Kit.

 

Here comes the demon­stra­tion of the tech­nique (it opens in a new win­dow). You can also try some dif­fer­ent URLs. For exam­ple, you can go direct­ly to the port­fo­lio sec­tion, to a par­tic­u­lar page of the port­fo­lio or try to go to a non-exist­ing page.

 

HTML AND JAVASCRIPT

1. Cre­ate a fold­er called c:\director_deeplinking\

2. Copy dir­jskit\ from Valentin’s Direc­tor / JavaScript Inte­gra­tion Kit into the fold­er

3. From the unFo­cus His­to­ry Keep­er library copy unFocus-History-p.js into the same fold­er

4. Cre­ate index.html in the fold­er. This will be the con­tain­er page for the shock­wave movie. Write in it the fol­low­ing HTML code:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<title>Director Deep linking Test</title>
	</head>
	<body>	
	</body>
</html>

It is nec­es­sary to import the Valentin’s Direc­tor / JavaScript Inte­gra­tion Kit scripts, as well as unFocus-History-p.js from the His­to­ry Keep­er library. That is why we add the fol­low­ing lines in the <head> ele­ment:

<script type="text/javascript" src="dirjskit/Exception.js"></script>
<script type="text/javascript" src="dirjskit/FlashTag.js"></script>
<script type="text/javascript" src="dirjskit/FlashSerializer.js"></script>
<script type="text/javascript" src="dirjskit/DirProxy.js"></script>
<script type="text/javascript" src="dirjskit/DirTag.js"></script>
<script type="text/javascript" src="unFocus-History-p.js"></script>

Now comes a piece of javascript. Add the fol­low­ing lines of code:

<script type="text/javascript">
	var uid = new Date().getTime();
	var dirProxy = new DirProxy( uid, "dirjskit/JavaScriptDirectorGateway.swf" );
	var toDirector = function( parameters ){dirProxy.call( "receiveFromJS", parameters  );}
	var fromDirector = function( parameters ){unFocus.History.addHistory( parameters );}
	var initializeShockwaveMovie = function(){ toDirector( unFocus.History.getCurrent() ); }
	unFocus.History.addEventListener( "historyChange", toDirector );
</script>

The first line cre­ates a unique id. We will use this id lat­er to embed the shock­wave. The next line cre­ates a proxy to direc­tor shock­wave movie. The next two lines define two func­tions — the first one sends data to the shock­wave and the sec­ond one — receives data from it. The ini­tial­izeShock­wave­Movie() func­tion is called once, when the movie is load­ed. This func­tion will set the ini­tial state of the movie, based on the pro­vid­ed URL. The final line of code sets the toDi­rec­tor() func­tion as event lis­ten­er for his­to­ryChange event — every time when the event is fired, the func­tion is called.

We will embed the shock­wave movie with the help of the fol­low­ing lines in the <body> ele­ment:

	<script type="text/javascript">
		var tag = new DirTag( "minimal.dcr", 320, 240, true );
		tag.setDirvars( uid );
		tag.write( document );
	</script>

Note that we provide the pre­vi­ous­ly gen­er­at­ed unique ID as a para­me­ter to the embed­ded shock­wave object. The final appear­ance of the HTML code must be:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<title>Director Deep linking Test</title>
		<script type="text/javascript" src="dirjskit/Exception.js"></script>
		<script type="text/javascript" src="dirjskit/FlashTag.js"></script>
		<script type="text/javascript" src="dirjskit/FlashSerializer.js"></script>
		<script type="text/javascript" src="dirjskit/DirProxy.js"></script>
		<script type="text/javascript" src="dirjskit/DirTag.js"></script>
		<script type="text/javascript" src="unFocus-History-p.js"></script>
		<script type="text/javascript">
			var uid = new Date().getTime();
			var dirProxy = new DirProxy( uid, "dirjskit/JavaScriptDirectorGateway.swf" );
			var toDirector = function( parameters ){dirProxy.call( "receiveFromJS", parameters  );}
			var fromDirector = function( parameters ){unFocus.History.addHistory( parameters );}
			var initializeShockwaveMovie = function(){ toDirector( unFocus.History.getCurrent() ); }
			unFocus.History.addEventListener( "historyChange", toDirector );
		</script>	
	</head>
	<body>
		<script type="text/javascript">
			var tag = new DirTag( "minimal.dcr", 320, 240, true );
			tag.setDirvars( uid );
			tag.write( document );
		</script>	
	</body>
</html>
 
 
 

THE LINGO PART
Here are the nec­es­sary min­i­mum steps to add deep-link­ing func­tion­al­i­ty to your shock­wave movie:

1. The JavaScript­Proxy and JavaScript­Se­ri­al­iz­er scripts from Valentin’s Direc­tor / JavaScript Inte­gra­tion Kit, as well as the dlMeth­ods and dlNav­i­ga­tion scripts must be avail­able in your movie.

Show code
-- Movie script "dlMethods"

global gProxy -- global proxy object that will handle shockwave <-> js communication

on startMovie()
  uid = _player.externalParamValue( "sw1" )        -- get unique ID
  gProxy = newJavaScriptProxy( uid, _movie, true ) -- create a new (global) proxy object
end startMovie

on stopMovie()
  clearAsObjects() -- Clear any remaining global Flash objects
  gProxy = VOID
end stopMovie


on sendToJS( params )
  if( _system.environmentPropList.runMode = "Plugin" ) then
    gProxy.call( "fromDirector", params  )
  else
    navigateTo( params )
  end if  
end sendToJS

on receiveFromJS( params )
  navigateTo( params )
end receiveFromJS

on navigateTo( aframe )
  if( ilk( aframe ) = #string ) then
    if( aframe = EMPTY ) then
      _movie.go( "/home/" )
      exit
    else
      ml = _movie.markerlist
      pos = ml.getPos( aframe )
      if( pos > 0 ) then
        f = ml.getpropAt( pos )
      end if
    end if
  else if( ilk( aframe ) = #integer ) then
    f = aframe
  end if
  if( ilk( f ) = #integer ) then
    _movie.go( f )
  else
    _movie.go( "/error/" )
  end if
end navigateTo

-- Behaviour script "dlNavigation"

property _marker

on getPropertyDescriptionList( me )
  pdl = [:]
  pdl.addProp( #_marker,  [ #format:#String, #default:EMPTY, #comment:"Go to:" ] )
  return pdl
end getPropertyDescriptionList

on mouseUp( me )
  sendToJS( me._marker )
end mouseUp

2. Mark­ers called /home/ and /error/ must be pre­sent­ed in your movie.

3. On every of your nav­i­ga­tion but­tons:

  • Drop the dlNav­i­ga­tion behav­ior.
  • Fill the name of the mark­er, which you would like the head to go to after the but­ton has been pressed.

For clar­i­ty, I offer a mini tuto­ri­al. Down­load it and unzip DeepLinking.zip.

Deep Link­ing (6727 down­loads)
 

Open the minimal_start.dir file. Cre­ate mark­ers, as shown on the pic­ture.

Drop the dlNav­i­ga­tion behav­ior on each of the but­tons. In the Para­me­ters for dlNav­i­ga­tion dialog fill /A/ for the first but­ton, /B/ for the sec­ond and /C/ for the third one. Drop the LOOP behav­ior in the frame script chan­nel on frame 2 and enlarge it to frame 10 (as shown on the pic­ture). To assure your­self that the things work, start the movie and exe­cute the fol­low­ing code in the mes­sage win­dow:

sendToJS("/C/")

If every­thing works prop­er­ly, the head will move to the /C/ mark­er.
Com­pile a shock­wave movie called minimal.dcr and put it in c:\director_deeplinking\ on the same lev­el as index.html. The file struc­ture should look as this:

dirjskit\
	DirProxy.js
	DirTag.js
	Exception.js
	FlashSerializer.js
	FlashTag.js
	JavaScriptDirectorGateway.swf
index.html
minimal.dcr
unFocus-History-p.js

When index.html is start­ed in the browser and you click the but­tons, you will see that with every change of the cur­rent mark­er in the movie, a new URL is gen­er­at­ed and the pre­vi­ous URL is writ­ten in the browser his­to­ry. To assure your­self of that, you can use the BACK but­ton of the browser. Now you can go direct­ly to any “page” of your shock­wave movie, for exam­ple:

file:///C:/director_deeplinking/index.html#/B/
 
Comments

In the recent ver­sions of chrome (sad­ly I missed in which one it appears first­ly) there is a prob­lem with this tech­nique. It is caused by the built-in chrome flash play­er. To solve this prob­lem, you need to install flash play­er from Adobe web­site and dis­able the built-in chrome.
1.Open chrome and go to chrome://plugins
2.Disable the built-in play­er — its loca­tion is some­thing like:
“C:\Users\XXXXXXXXXX\AppData\Local\Google\Chrome\Application\23.0.1271.64\PepperFlash\pepflashplayer.dll”.
3.Go to http://get.adobe.com/flashplayer/?no_redirect and install the flash play­er.
4.Open chrome and go to chrome://plugins again to make sure that only the new­ly installed flash play­er is acti­vat­ed.
For me (Win­dows 7, Chrome 23.0.1271.64 m) this solves the prob­lem com­plete­ly and things work as described.