<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>pipwerks.com</title>
	
	<link>http://pipwerks.com/journal</link>
	<description>Philip Hutchison's technology journal, dedicated to exploring web technologies for website and e-learning development.</description>
	<lastBuildDate>Tue, 23 Jun 2009 06:13:23 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<creativeCommons:license>http://creativecommons.org/licenses/by-sa/3.0/</creativeCommons:license><image><link>http://creativecommons.org/licenses/by-sa/3.0/</link><url>http://creativecommons.org/images/public/somerights20.gif</url><title>Some Rights Reserved</title></image><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/pipwerks" type="application/rss+xml" /><feedburner:emailServiceId>pipwerks</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
		<title>Changes to pipwerks.com</title>
		<link>http://feedproxy.google.com/~r/pipwerks/~3/gUKw_risedQ/</link>
		<comments>http://pipwerks.com/journal/2009/06/22/changes-to-pipwerks-com/#comments</comments>
		<pubDate>Tue, 23 Jun 2009 06:13:23 +0000</pubDate>
		<dc:creator>Philip Hutchison</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://pipwerks.com/journal/?p=661</guid>
		<description><![CDATA[Just a quick note: I'm renovating this site to make better use of WordPress' capabilities. Because of the move to WordPress, many of my static HTML files will be converted to WordPress 'pages'; this means you may see some odd posts in my RSS feed from time to time. Feel free to ignore them.<p><p><a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-sa/3.0/us/80x15.png" /></a><br />This work by <a xmlns:cc="http://creativecommons.org/ns#" href="http://pipwerks.com" property="cc:attributionName" rel="cc:attributionURL">Philip Hutchison</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/">Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License</a>.</p></p>
<p><a href="http://pipwerks.com/journal/2009/06/22/changes-to-pipwerks-com/">Changes to pipwerks.com</a></p>
]]></description>
			<content:encoded><![CDATA[<p>Just a quick note: I&#039;m renovating this site to make better use of WordPress&#039; capabilities.</p>
<p>The current version of pipwerks.com is mostly traditional HTML with WordPress being used for the <em>Journal</em> entries; the new version of the site will be almost exclusively Wordpress-powered.</p>
<p>Because of the move to WordPress, many of my static HTML files will be converted to WordPress &#039;pages&#039;; this means you may see some odd posts in my RSS feed from time to time. Feel free to ignore them.</p>
<p>Why WordPress? A number of reasons, including:</p>
<ul>
<li>easy &#039;themability&#039;</li>
<li>enabling users to post comments on normal pages, not just blog entries (this will be especially useful for gathering feedback about my lab work with SCORM and Captivate)</li>
<li>statistics tracking</li>
<li>ease-of-updates for pages (browser-based editing means no more Dreamweaver and FTP)</li>
<li>WordPress&#039; extensibility via plugins and widgets</li>
<li>Search engine friendliness</li>
<li>Automated linking of content via <em>tags</em> and <em>categories</em> can help visitors find related content more easily</li>
</ul>
<p>I&#039;ll still be using plain HTML for code examples and demonstrations, but that&#039;s about it.</p>
<p>I have a few tricks up my sleeve and hope to try them out soon. In the meantime, I&#039;ll just mention that my new theme (which hasn&#039;t been activated yet) is HTML 5-based and uses a bunch of CSS trickery. Geeky fun for all. <img src='http://pipwerks.com/journal/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<h3>Why so quiet lately?</h3>
<p>If you&#039;re a regular reader of this blog, you may have noticed that it has been very quiet lately. Rest assured there are a number of blog entries waiting in the wings &#8212; I&#039;ve simply been too busy to write them. I promise I will get to them soon(ish).  In the meantime, I invite you to join me on <a href="http://twitter.com/pipwerks">twitter</a>.<br />
<h3>Possibly related journal entries:</h3>
<ul class="related_post">
<li>March 21, 2009 &#8212; <a href="http://pipwerks.com/journal/2009/03/21/gotchas-in-internet-explorer-8/" title="Gotchas in Internet Explorer 8">Gotchas in Internet Explorer 8</a></li>
<li>February 1, 2009 &#8212; <a href="http://pipwerks.com/journal/2009/02/01/obfuscating-email-addresses-revisited/" title="Obfuscating email addresses, revisited">Obfuscating email addresses, revisited</a></li>
<li>February 28, 2008 &#8212; <a href="http://pipwerks.com/journal/2008/02/28/accessibility-development-tools/" title="Accessibility development tools">Accessibility development tools</a></li>
<li>February 7, 2008 &#8212; <a href="http://pipwerks.com/journal/2008/02/07/development-standards-for-e-learning-a-starting-point/" title="Development standards for e-learning&#8230; a starting point">Development standards for e-learning&#8230; a starting point</a></li>
<li>February 4, 2008 &#8212; <a href="http://pipwerks.com/journal/2008/02/04/rapid-intake-where-are-the-standards/" title="Rapid Intake: Where are the standards?">Rapid Intake: Where are the standards?</a></li>
<li>June 13, 2007 &#8212; <a href="http://pipwerks.com/journal/2007/06/13/email-address-obsfucation/" title="Email address obfuscation">Email address obfuscation</a></li>
</ul>
<p><p><a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-sa/3.0/us/80x15.png" /></a><br />This work by <a xmlns:cc="http://creativecommons.org/ns#" href="http://pipwerks.com" property="cc:attributionName" rel="cc:attributionURL">Philip Hutchison</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/">Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License</a>.</p></p>
<p><a href="http://pipwerks.com/journal/2009/06/22/changes-to-pipwerks-com/">Changes to pipwerks.com</a></p>
<img src="http://feeds.feedburner.com/~r/pipwerks/~4/gUKw_risedQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://pipwerks.com/journal/2009/06/22/changes-to-pipwerks-com/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://pipwerks.com/journal/2009/06/22/changes-to-pipwerks-com/</feedburner:origLink></item>
		<item>
		<title>Introducing the CaptivateController</title>
		<link>http://feedproxy.google.com/~r/pipwerks/~3/Uez6OolRwLU/</link>
		<comments>http://pipwerks.com/journal/2009/06/07/introducing-the-captivatecontroller/#comments</comments>
		<pubDate>Mon, 08 Jun 2009 06:27:29 +0000</pubDate>
		<dc:creator>Philip Hutchison</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[e-learning]]></category>
		<category><![CDATA[Adobe Captivate]]></category>
		<category><![CDATA[Adobe E-Learning Suite]]></category>
		<category><![CDATA[Captivate 4]]></category>
		<category><![CDATA[CaptivateController]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://pipwerks.com/journal/?p=637</guid>
		<description><![CDATA[It took me much much longer than I anticipated, but I am happy to announce the new CaptivateController utility.

This controller is not a simple rehash of the original <a href="http://pipwerks.com/lab/captivate/examples/Captivate-JavaScript/control-utility/index.html">pipwerks.captivate.control</a> utility; it is a complete re-write that adds a number of extra features.<p><p><a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-sa/3.0/us/80x15.png" /></a><br />This work by <a xmlns:cc="http://creativecommons.org/ns#" href="http://pipwerks.com" property="cc:attributionName" rel="cc:attributionURL">Philip Hutchison</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/">Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License</a>.</p></p>
<p><a href="http://pipwerks.com/journal/2009/06/07/introducing-the-captivatecontroller/">Introducing the CaptivateController</a></p>
]]></description>
			<content:encoded><![CDATA[<p>It took me much much longer than I anticipated, but I am happy to announce the new CaptivateController utility. The CaptivateController is a JavaScript utility that helps you control Captivate SWFs using simple JavaScript commands. For example:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #39C;">//Assuming your SWF is embedded using the ID &quot;myID&quot;</span>
<span style="color: #00F;  font-weight: bold;">var</span> myMovie <span style="color: #393;">=</span> CaptivateController<span style="color: #666;">&#40;</span><span style="color: #36C;">&quot;myID&quot;</span><span style="color: #666;">&#41;</span><span style="color: #393;">;</span>
myMovie.<span style="color: #90C;  font-weight: bold;">pause</span><span style="color: #666;">&#40;</span><span style="color: #666;">&#41;</span><span style="color: #393;">;</span> <span style="color: #39C;">//Pauses the Captivate SWF</span>
myMovie.<span style="color: #90C;  font-weight: bold;">mute</span><span style="color: #666;">&#40;</span><span style="color: #666;">&#41;</span><span style="color: #393;">;</span> <span style="color: #39C;">//Mutes the Captivate SWF</span></pre></div></div>

<p>For those of you familiar with the <a href="http://pipwerks.com/lab/captivate/examples/Captivate-JavaScript/control-utility/index.html">pipwerks.captivate.control</a> utility, this CaptivateController is not a simple rehash of the original; it is a complete re-write that adds a number of extra features, including:</p>
<ul>
<li>Support for Captivate 2, Captivate 3, and Captivate 4 files</li>
<li>Auto-detection for skins; you can write the exact same JavaScript whether your SWF uses a skin or not</li>
<li>New query methods, including the ability to query a user-defined variable in a Captivate 4 file</li>
</ul>
<p>The CaptivateController took a long time to develop because it deals with a number of inconsistencies between Captivate 2/3 SWFs and Captivate 4 SWFs, including the shift from using GetVariable to using Captivate 4&#039;s proprietary cpGetValue (via ExternalInterface). It also handles inconsistencies with Flash Player in different browsers. Safari and Internet Explorer both provided their own small challenges.</p>
<p>There are still some inconsistencies that cannot be solved using JavaScript; for instance, Captivate 4 SWFs published using ActionScript 3 provide a richer set of system variables than Captivate 4 files published using ActionScript 2. I expected to have the same access to all system variables regardless of ActionScript version, but alas it was not meant to be.</p>
<p>Someday I hope to post a chart of which variables work when, but until then you can check out the <a href="http://pipwerks.com/lab/captivate/CaptivateController/testsuite/queries-automated.html">Automated Test Suite</a>, which illustrates which variables are available for each flavor of Captivate SWF.</p>
<h2>Download</h2>
<p>The CaptivateController weighs in at about 8kb and has been successfully tested in the following systems:</p>
<ul>
<li>Mac OS X (10.5): Firefox 3.0.10, Safari 3.2, Opera 9.6</li>
<li>Windows XP: Internet Explorer 6, Internet Explorer 8, Firefox 3.0.10</li>
<li>Windows Vista: Internet Explorer 7</li>
</ul>
<p>You can <a href="http://pipwerks.com/journal/downloads/15">download the compressed version (8kb) here</a>.</p>
<p>You can <a href="http://pipwerks.com/lab/captivate/CaptivateController/CaptivateController_source.js">view the source version here</a> (please do not hotlink).</p>
<h2>Quickie documentation</h2>
<p>I haven&#039;t had the time to do a full write-up of the CaptivateController API, but the following information should be enough to get you started.</p>
<p>Don&#039;t forget to check out the <a href="http://pipwerks.com/lab/captivate/CaptivateController/testsuite/">test suite</a>. A list of Captivate Variables can be found on the <a href="http://pipwerks.com/lab/captivate/CaptivateController/testsuite/queries-automated.html">Automated Test Suite</a> and also in <a href="http://pipwerks.com/journal/2009/05/16/captivate-4-variables-gone-wild/">this blog post</a>.</p>
<h3>&#034;Control&#034; methods available in the API</h3>
<ul>
<li>pause()</li>
<li>resume()</li>
<li>next()</li>
<li>previous()</li>
<li>rewindAndStop()</li>
<li>rewindAndPlay()</li>
<li>gotoSlideAndPlay(slidenumber)</li>
<li>gotoSlideAndStop(slidenumber)</li>
<li>gotoFrameAndPlay(framenumber)</li>
<li>gotoFrameAndStop(framenumber)</li>
<li>volume(volumelevel)
<ul>
<li>Takes number, 0-100</li>
<li>Returns current volume level, 0-100</li>
<li>Volume only works in CP4+</li>
</ul>
</li>
<li>mute()</li>
<li>unmute()</li>
<li>muteAndShowCaptions()</li>
<li>unmuteAndHideCaptions()</li>
<li>showCaptions()</li>
<li>hideCaptions()</li>
<li>showInfoBox()</li>
<li>hidePlaybar()
<ul>
<li>Doesn&#039;t seem to work consistently via JavaScript</li>
</ul>
</li>
<li>showPlaybar()
<ul>
<li>Doesn&#039;t seem to work consistently via JavaScript</li>
</ul>
</li>
<li>lockTOC()
<ul>
<li>Enables/disables user interaction on TOC</li>
<li>Only works in CP4+</li>
</ul>
</li>
<li>unlockTOC()
<ul>
<li>Enables/disables user interaction on TOC</li>
<li>Only works in CP4+</li>
</ul>
</li>
<li>exit</li>
</ul>
<p>Example:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #39C;">//Assuming your SWF is embedded using the ID &quot;myID&quot;</span>
<span style="color: #00F;  font-weight: bold;">var</span> myMovie <span style="color: #393;">=</span> CaptivateController<span style="color: #666;">&#40;</span><span style="color: #36C;">&quot;myID&quot;</span><span style="color: #666;">&#41;</span><span style="color: #393;">;</span>
myMovie.<span style="color: #90C;  font-weight: bold;">pause</span><span style="color: #666;">&#40;</span><span style="color: #666;">&#41;</span><span style="color: #393;">;</span> <span style="color: #39C;">//Pauses the Captivate SWF</span>
myMovie.<span style="color: #90C;  font-weight: bold;">mute</span><span style="color: #666;">&#40;</span><span style="color: #666;">&#41;</span><span style="color: #393;">;</span> <span style="color: #39C;">//Mutes the Captivate SWF</span></pre></div></div>

<p>Commands can also be chained together, like so:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #00F;  font-weight: bold;">var</span> myMovie <span style="color: #393;">=</span> CaptivateController<span style="color: #666;">&#40;</span><span style="color: #36C;">&quot;myID&quot;</span><span style="color: #666;">&#41;</span><span style="color: #393;">;</span>
myMovie.<span style="color: #90C;  font-weight: bold;">pause</span><span style="color: #666;">&#40;</span><span style="color: #666;">&#41;</span>.<span style="color: #90C;  font-weight: bold;">mute</span><span style="color: #666;">&#40;</span><span style="color: #666;">&#41;</span><span style="color: #393;">;</span> <span style="color: #39C;">//Pauses then mutes Captivate SWF</span></pre></div></div>

<h3>Query methods</h3>
<p>The primary query technique is to use .query(&#034;captivate_variable_name&#034;). For example,</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #00F;  font-weight: bold;">var</span> myMovie <span style="color: #393;">=</span> CaptivateController<span style="color: #666;">&#40;</span><span style="color: #36C;">&quot;myID&quot;</span><span style="color: #666;">&#41;</span><span style="color: #393;">;</span>
<span style="color: #39C;">//Retrieves the author's name, if available</span>
<span style="color: #00F;  font-weight: bold;">var</span> author <span style="color: #393;">=</span> myMovie.<span style="color: #90C;  font-weight: bold;">query</span><span style="color: #666;">&#40;</span><span style="color: #36C;">&quot;cpInfoAuthor&quot;</span><span style="color: #666;">&#41;</span><span style="color: #393;">;</span></pre></div></div>

<p>You can also use this method to query user-defined variables:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #00F;  font-weight: bold;">var</span> myMovie <span style="color: #393;">=</span> CaptivateController<span style="color: #666;">&#40;</span><span style="color: #36C;">&quot;myID&quot;</span><span style="color: #666;">&#41;</span><span style="color: #393;">;</span>
&nbsp;
<span style="color: #39C;">//Retrieves the variable My_custom_variable_name, if available</span>
<span style="color: #00F;  font-weight: bold;">var</span> myUserDefinedvariable <span style="color: #393;">=</span> myMovie.<span style="color: #90C;  font-weight: bold;">query</span><span style="color: #666;">&#40;</span><span style="color: #36C;">&quot;My_custom_variable_name&quot;</span><span style="color: #666;">&#41;</span><span style="color: #393;">;</span></pre></div></div>

<p>I have created some additional query methods below. Some are designed to help avoid worrying which version of Captivate is being used (ie they work with both CP3 and CP4), and others provide data directly from the Flash SWF (not using CP variables).</p>
<ul>
<li>captivateVersion()
<ul>
<li>Returns major number, currently either 2 or 4 (Captivate 3 SWFs self-identify as CP2 SWFs!)</li>
</ul>
</li>
<li>asVersion()
<ul>
<li>Returns either 2 or 3</li>
</ul>
</li>
<li>FPS()
<ul>
<li>Returns the frames per second of the SWF</li>
</ul>
</li>
<li>hasSkinSWF()
<ul>
<li>Returns a boolean indicating whether the SWF is using a skin</li>
</ul>
</li>
<li>hasTOC()
<ul>
<li>Returns a boolean indicating whether the movie has a Table of Contents</li>
</ul>
</li>
<li>hasPlaybar()
<ul>
<li>Returns a boolean indicating whether the SWF has a playbar</li>
</ul>
</li>
<li>width()</li>
<li>height()</li>
<li>volume()
<ul>
<li>Returns a number (0-100) indicating volume level. Note: volume only works in CP4+.</li>
</ul>
</li>
<li>Flash SWF (not Captivate) properties
<ul>
<li>percentLoaded()</li>
<li>getname()</li>
<li>geturl()</li>
</ul>
</li>
</ul>
<p>You can also grab a reference to the SWF itself by using <code>.swf</code>. This is the equivalent of <code>document.getElementById()</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #00F;  font-weight: bold;">var</span> myMovie <span style="color: #393;">=</span> CaptivateController<span style="color: #666;">&#40;</span><span style="color: #36C;">&quot;myID&quot;</span><span style="color: #666;">&#41;</span><span style="color: #393;">;</span>
myMovie.<span style="color: #90C;  font-weight: bold;">swf</span> <span style="color: #393;">===</span> document.<span style="color: #90C;  font-weight: bold;">getElementById</span><span style="color: #666;">&#40;</span><span style="color: #36C;">&quot;myID&quot;</span><span style="color: #666;">&#41;</span><span style="color: #393;">;</span></pre></div></div>

<h2>Does it work for you?</h3>
<p>I&#039;m planning on refining this controller utility over time. If you encounter any problems or have any suggestions for improvements/new features, please let me know by leaving a comment below.</p>
<p class="note">DISCLAIMER: This controller is provided as-is. Use this controller at your own risk. I cannot be held responsible for any problems you may encounter while using the controller. kthxbai.</p>
<h3>Possibly related journal entries:</h3>
<ul class="related_post">
<li>May 16, 2009 &#8212; <a href="http://pipwerks.com/journal/2009/05/16/captivate-4-variables-gone-wild/" title="Captivate 4 variables gone wild">Captivate 4 variables gone wild</a></li>
<li>January 20, 2009 &#8212; <a href="http://pipwerks.com/journal/2009/01/20/adobe-elearning-suite-and-captivate-4-released/" title="Adobe eLearning Suite and Captivate 4 released">Adobe eLearning Suite and Captivate 4 released</a></li>
<li>November 10, 2008 &#8212; <a href="http://pipwerks.com/journal/2008/11/10/adobe-e-learning-products-sneak-peeks/" title="Adobe E-Learning Products &#034;Sneak Peeks&#034;">Adobe E-Learning Products &#034;Sneak Peeks&#034;</a></li>
<li>September 8, 2008 &#8212; <a href="http://pipwerks.com/journal/2008/09/08/control-a-captivate-swf-using-javascript-the-basics/" title="Control a Captivate SWF using JavaScript: The basics">Control a Captivate SWF using JavaScript: The basics</a></li>
<li>September 7, 2008 &#8212; <a href="http://pipwerks.com/journal/2008/09/07/send-captivate-quiz-data-to-javascript/" title="Send Captivate Quiz Data to JavaScript">Send Captivate Quiz Data to JavaScript</a></li>
<li>March 23, 2009 &#8212; <a href="http://pipwerks.com/journal/2009/03/23/legacycaptivateloader-example-updated/" title="LegacyCaptivateLoader example updated">LegacyCaptivateLoader example updated</a></li>
</ul>
<p><p><a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-sa/3.0/us/80x15.png" /></a><br />This work by <a xmlns:cc="http://creativecommons.org/ns#" href="http://pipwerks.com" property="cc:attributionName" rel="cc:attributionURL">Philip Hutchison</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/">Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License</a>.</p></p>
<p><a href="http://pipwerks.com/journal/2009/06/07/introducing-the-captivatecontroller/">Introducing the CaptivateController</a></p>
<img src="http://feeds.feedburner.com/~r/pipwerks/~4/Uez6OolRwLU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://pipwerks.com/journal/2009/06/07/introducing-the-captivatecontroller/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<feedburner:origLink>http://pipwerks.com/journal/2009/06/07/introducing-the-captivatecontroller/</feedburner:origLink></item>
		<item>
		<title>Captivate 4 variables gone wild</title>
		<link>http://feedproxy.google.com/~r/pipwerks/~3/sFluHskEAhk/</link>
		<comments>http://pipwerks.com/journal/2009/05/16/captivate-4-variables-gone-wild/#comments</comments>
		<pubDate>Sun, 17 May 2009 00:42:43 +0000</pubDate>
		<dc:creator>Philip Hutchison</dc:creator>
				<category><![CDATA[e-learning]]></category>
		<category><![CDATA[actionscript]]></category>
		<category><![CDATA[Adobe Captivate]]></category>
		<category><![CDATA[Captivate 4]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://pipwerks.com/journal/?p=626</guid>
		<description><![CDATA[The folks at Adobe recently <a href="http://blogs.adobe.com/captivate/2009/05/list_of_system_variables_in_cp.html">published a list of Captivate 4 variables</a>. While it's a solid list, it's not really a complete list.<p><p><a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-sa/3.0/us/80x15.png" /></a><br />This work by <a xmlns:cc="http://creativecommons.org/ns#" href="http://pipwerks.com" property="cc:attributionName" rel="cc:attributionURL">Philip Hutchison</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/">Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License</a>.</p></p>
<p><a href="http://pipwerks.com/journal/2009/05/16/captivate-4-variables-gone-wild/">Captivate 4 variables gone wild</a></p>
]]></description>
			<content:encoded><![CDATA[<p>The folks at Adobe recently <a href="http://blogs.adobe.com/captivate/2009/05/list_of_system_variables_in_cp.html">published a list of Captivate 4 variables</a>. While it&#039;s a solid list, it&#039;s not really a complete list.</p>
<p>Here is a list of variables I dug up while combing through Captivate 4&#039;s source AS files.  I tried to add descriptions where I could, and will continue to revise this list as I get more information.  Kudos to Michael at <a href="http://www.captivate4.com">www.captivate4.com</a> for posting his <a href="http://www.captivate4.com/2009/04/28/system-variables-in-captivate-4-%E2%80%93-a-complete-list/">helpful list</a>, too.</p>
<p>Notes: </p>
<ul>
<li>I&#039;ve tested each of these variables in JavaScript to ensure they exist and are accessible, and have weeded out variables that return errors.</li>
<li>I&#039;ve also included Captivate 3 variables at the bottom of this page.</li>
</ul>
<h2>Captivate 4 Variables</h2>
<h3>Functional variables (perform an action)</h3>
<table cellspacing="0">
<tr>
<th>Variable</th>
<th>Returns</th>
<th>Default values</th>
<th>Description (if available)</th>
</tr>
<tr>
<td>cpAutoPlay</td>
<td>boolean</td>
<td>true</td>
<td>Toggles auto-play on (true) or off (false). Movie auto-plays by default.</td>
</tr>
<tr>
<td>cpCmndCC</td>
<td>number</td>
<td>0</td>
<td>Toggles closed captioning on (1) or off (0). Replaces rdcmndCC.</td>
</tr>
<tr>
<td>cpCmndFastForward</td>
<td>number</td>
<td>0</td>
<td>Setting to 1 increases speed of playback.</td>
</tr>
<tr>
<td>cpCmndGotoFrameAndResume</td>
<td>number</td>
<td>-1</td>
<td>Jumps to the specified frame number (NOT slide number) and resumes playback. </p>
<p>    Replaces rdcmndGotoFrameAndResume.</td>
</tr>
<tr>
<td>cpCmndMute</td>
<td>boolean</td>
<td>false</td>
<td>Toggles audio. Setting to true mutes the audio, setting to false unmutes the audio. </p>
<p>    Replaces rdcmndMute.</td>
</tr>
<tr>
<td>cpCmndNext</td>
<td>number</td>
<td>0</td>
<td>Setting value to 1 will  jump to the next slide in project. </p>
<p>    Replaces rdcmndNext</td>
</tr>
<tr>
<td>cpCmndShowPlaybar</td>
<td>number</td>
<td>1</td>
<td>Toggles playbar visibility. Setting to 0 will hide the playbar, setting to 1 will restore it.</p>
<p>    Replaces rdcmndHidePlaybar.</td>
</tr>
<tr>
<td>cpCmndVolume</td>
<td>number</td>
<td>100</td>
<td>Sets audio volume (if applicable). Range is 0-100, where 0 is off and 100 is full volume. Querying cpCmndVolume will return the current volume level.</td>
</tr>
<tr>
<td>rdcmndGotoSlide</td>
<td>number</td>
<td>-1</td>
<td>
<p>Jumps to the specified slide number. Takes slide number (0-based index) as argument.</p>
</td>
</tr>
<p><!-- tr>
<td>rdcmndCC</td>
<td>number</td>
<td>0</td>
<td>Deprecated. Replaced by cpCmndCC (see above)</td>
</tr>
<tr>
<td>rdcmndMute</td>
<td>boolean</td>
<td>false</td>
<td>Deprecated. Replaced by cpCmndMute (see above)</td>
</tr>
<tr>
<td>rdcmndNext</td>
<td>boolean</td>
<td>false</td>
<td>Deprecated. Replaced by cpCmndNext (see above)</td>
</tr-->
<tr>
<td>rdcmndPlaybarMoved</td>
<td>boolean</td>
<td>false</td>
<td>&nbsp;</td>
</tr>
</table>
<p>&nbsp;</p>
<h3>Informational variables (retrieve or set data)</h3>
<table cellspacing="0">
<tr>
<th>Variable</th>
<th>Returns</th>
<th>Sample values</th>
<th>Description (if available)</th>
</tr>
<tr>
<td>CaptivateVersion</td>
<td>string</td>
<td>4.0.0</td>
<td>Returns version of Captivate that published the SWF.</td>
</tr>
<tr>
<td>cpCmndPlaybarMoved</td>
<td>boolean</td>
<td>false</td>
<td>Replaces rdcmndPlaybarMoved.</td>
</tr>
<tr>
<td>cpHasSkinSWF</td>
<td>boolean</td>
<td>false</td>
<td>Returns boolean indicating whether the movie is using a SWF-based skin.</td>
</tr>
<tr>
<td>cpInfoAuthor</td>
<td>string</td>
<td>Philip Hutchison</td>
<td>Returns the project author&#039;s name, if available.</td>
</tr>
<tr>
<td>cpInfoCompany</td>
<td>string</td>
<td>pipwerks</td>
<td>Returns the project company&#039;s name, if available.</td>
</tr>
<tr>
<td>cpInfoCopyright</td>
<td>number</td>
<td>2009</td>
<td>Returns the project&#039;s copyright notice, if available.</td>
</tr>
<tr>
<td>cpInfoCurrentDate</td>
<td>string</td>
<td>11</td>
<td>Returns the day of the month using the client&#039;s system clock. </p>
<p>    String(now.getDate())</td>
</tr>
<tr>
<td>cpInfoCurrentDateString</td>
<td>string</td>
<td>5/11/2009</td>
<td>Returns the calendar date in mm/dd/yyyy format using the client&#039;s system clock.</p>
<p>    Returns (now.getMonth() + 1 + &quot;/&quot; + now.getDate() + &quot;/&quot; + now.getFullYear());</td>
</tr>
<tr>
<td>cpInfoCurrentDay</td>
<td>string</td>
<td>2</td>
<td>Returns the numerical day of the week using the client&#039;s system clock (Sunday is day 1).</p>
<p>    Returns String(now.getDay()+ 1);</td>
</tr>
<tr>
<td>cpInfoCurrentHour</td>
<td>string</td>
<td>19</td>
<td>Returns the current hour using the client&#039;s system clock.</p>
<p>    Returns String(now.getHours());</td>
</tr>
<tr>
<td>cpInfoCurrentMinutes</td>
<td>string</td>
<td>59</td>
<td>Returns the current minute using the client&#039;s system clock.</p>
<p>    Returns String(now.getMinutes());</td>
</tr>
<tr>
<td>cpInfoCurrentMonth</td>
<td>string</td>
<td>5</td>
<td>Returns the numerical month using the client&#039;s system clock (January is 1).</p>
<p>    Returns String(now.getMonth() + 1);</td>
</tr>
<tr>
<td>cpInfoCurrentSlide</td>
<td>number</td>
<td>1</td>
<td>Returns the current slide number. Unlike rdinfoCurrentSlide, <em>cpInfoCurrentSlide</em> uses 1-based indexing, so slide 1 of the project will return <em>1</em>.</p>
<p>    Returns (rdinfoCurrentSlide + 1);</td>
</tr>
<tr>
<td>cpInfoCurrentSlideLabel</td>
<td>string</td>
<td>SlideLabel:0</td>
<td>Returns the label of the slide, if available.</td>
</tr>
<tr>
<td>cpInfoCurrentSlideType</td>
<td>string</td>
<td>NormalSlide</td>
<td>Returns a string indicating the current slide&#039;s type. There are currently three possible results: &quot;NormalSlide&quot;, &quot;QuestionSlide&quot;, and &quot;RandomQuestionSlide&quot;</td>
</tr>
<tr>
<td>cpInfoCurrentTime</td>
<td>string</td>
<td>19:59:27</td>
<td>Returns the current time in HH:MM:SS format using the client&#039;s system clock. Note: uses 24-hour clock.</p>
<p>    Returns (now.getHours() + &quot;:&quot; + now.getMinutes() + &quot;:&quot; + now.getSeconds());</td>
</tr>
<tr>
<td>cpInfoCurrentYear</td>
<td>string</td>
<td>2009</td>
<td>Returns the current year in YYYY format using the client&#039;s system clock.</p>
<p>    Returns String(now.getFullYear());</td>
</tr>
<tr>
<td>cpInfoDescription</td>
<td>string</td>
<td>This demonstration will teach you the&#8230;</td>
<td>Returns the project description, if available.</td>
</tr>
<tr>
<td>cpInfoElapsedTimeMS</td>
<td>number</td>
<td>1537</td>
<td>Returns the amount of time (in milliseconds) that has elapsed since the movie began playing.</p>
<p>    Returns (cpInfoEpochMS &#8211; movie.m_StartTime)</td>
</tr>
<tr>
<td>cpInfoEmail</td>
<td>string</td>
<td>hello@world.org</td>
<td>Returns the project author&#039;s email address, if available.</td>
</tr>
<tr>
<td>cpInfoEpochMS</td>
<td>number</td>
<td>1242097167686</td>
<td>Per <a href="http://www.adobe.com/support/flash/action_scripts/actionscript_dictionary/actionscript_dictionary162.html">Adobe</a>:<em> </em>&quot;returns the number of milliseconds since midnight January 1, 1970, universal time, for the specified Date object. Use this method to represent a specific instant in time when comparing two or more Date objects.&quot;</p>
<p>    Returns now.getTime();</td>
</tr>
<tr>
<td>cpInfoHasPlaybar</td>
<td>number</td>
<td>1</td>
<td>Returns a boolean (in number format) indicating whether the Captivate file was published with playback controls (a playbar). </td>
</tr>
<tr>
<td>cpInfoIsStandalone</td>
<td>number</td>
<td>0</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>cpInfoLastVisitedSlide</td>
<td>number</td>
<td>0</td>
<td>Returns the index number of the last visited slide. Uses zero-based numbering (0 = slide 1, 1 = slide 2).</td>
</tr>
<tr>
<td>cpInfoPercentage</td>
<td>number</td>
<td>0</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>cpInfoPrevSlide</td>
<td>number</td>
<td>-1</td>
<td>Returns the index number of the slide that comes before the current slide. Uses zero-based numbering (0 = slide 1, 1 = slide 2).</td>
</tr>
<tr>
<td>cpInfoProjectName</td>
<td>string</td>
<td>CaptivateController</td>
<td>Returns the project name, if available.</td>
</tr>
<tr>
<td>cpInfoWebsite</td>
<td>string</td>
<td>www.pipwerks.com</td>
<td>Returns the website listed in the project properties, if available.</td>
</tr>
<tr>
<td>cpMovieHeight</td>
<td>number</td>
<td>432</td>
<td>Returns the movie&#039;s original height, regardless of how it has been sized via HTML or CSS.</td>
</tr>
<tr>
<td>CPMovieType</td>
<td>number</td>
<td>1</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>cpMovieWidth</td>
<td>number</td>
<td>551</td>
<td>Returns the movie&#039;s original width, regardless of how it has been sized via HTML or CSS.</td>
</tr>
<tr>
<td>cpQuizInfoAnswerChoice</td>
<td>string</td>
<td>&#034;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>cpQuizInfoAttempts</td>
<td>number</td>
<td>1</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>cpQuizInfoLastSlidePointScored</td>
<td>number</td>
<td>0</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>cpQuizInfoMaxAttemptsOnCurrentQuestion</td>
<td>number</td>
<td>0</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>cpQuizInfoNoQuestionsPerQuiz</td>
<td>number</td>
<td>0</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>cpQuizInfoPointsPerQuestionSlide</td>
<td>number</td>
<td>0</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>cpQuizInfoPointsscored</td>
<td>number</td>
<td>0</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>cpQuizInfoQuestionSlideTiming</td>
<td>number</td>
<td>0</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>cpQuizInfoQuestionSlideType</td>
<td>string</td>
<td>choice</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>cpQuizInfoQuizPassPercent</td>
<td>number</td>
<td>0</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>cpQuizInfoQuizPassPoints</td>
<td>number</td>
<td>0</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>cpQuizInfoTotalCorrectAnswers</td>
<td>number</td>
<td>0</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>cpQuizInfoTotalProjectPoints</td>
<td>number</td>
<td>0</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>cpQuizInfoTotalQuestionsPerProject</td>
<td>number</td>
<td>0</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>cpQuizInfoTotalQuizPoints</td>
<td>number</td>
<td>0</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>cpQuizInfoTotalUnansweredQuestions</td>
<td>number</td>
<td>0</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>inAutoPlayState</td>
<td>boolean</td>
<td>false</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>isCPMovie</td>
<td>boolean</td>
<td>true</td>
<td>Returns a boolean indicating whether this movie was published using Adobe Captivate.</td>
</tr>
<tr>
<td>isPreview</td>
<td>number</td>
<td>0</td>
<td>Returns a boolean (in number format) indicating whether this is a preview. Primarily used internally by Captivate when previewing a project. Replaces rdIsPreview.</td>
</tr>
<tr>
<td>isPreviewSkin</td>
<td>number</td>
<td>0</td>
<td>Returns a boolean (in number format) indicating whether this is a skin for a preview. Primarily used internally by Captivate when previewing a project.</td>
</tr>
<tr>
<td>loadedFromAggregator</td>
<td>boolean</td>
<td>false</td>
<td>Returns a boolean indicating whether the SWF has been loaded by Captivate&#039;s aggregator.</td>
</tr>
<tr>
<td>LocalConnectionInUse</td>
<td>boolean</td>
<td>false</td>
<td>Returns a boolean indicating whether the movie is using LocalConnection. This is primarily used internally by Captivate.</td>
</tr>
<tr>
<td>NoOfTOCEntries</td>
<td>number</td>
<td>-1</td>
<td>Returns a count of entries in the Table of Contents, if available.</td>
</tr>
<tr>
<td>pbcBtnTips</td>
<td>object [array]</td>
<td>Rewind, Back, Play, <br />
  Pause, Forward, <br />
  Closed Captioning, <br />
  Audio On, Audio Off, <br />
  Exit, Information, <br />
  Dummy for slider, <br />
  Table Of Contents, <br />
  2x Fast Forward Speed, <br />
  4x Fast Forward Speed, <br />
  Normal Speed, Print</td>
<td>Returns the label values used in the playback controller&#039;s tool tips.</td>
</tr>
<tr>
<td>playbarHeight</td>
<td>number</td>
<td>31</td>
<td>Returns the height of the playbar in pixels, if applicable.</td>
</tr>
<tr>
<td>playbarPosition</td>
<td>number</td>
<td>3</td>
<td>Returns the position of the playbar in pixels, if applicable.</td>
</tr>
<tr>
<td>rdIsPreview</td>
<td>boolean</td>
<td>false</td>
<td>Deprecated. Replaced by isPreview.</td>
</tr>
<tr>
<td>rdinfoCurrentFrame</td>
<td>number</td>
<td>41</td>
<td>Returns the number of the current frame (NOT slide), counting from the beginning of the movie&#039;s timeline.</td>
</tr>
<tr>
<td>rdinfoCurrentSlide</td>
<td>number</td>
<td>0</td>
<td>Deprecated. Replaced by cpInfoCurrentSlide.</td>
</tr>
<tr>
<td>rdinfoCurrentSlideInProject</td>
<td>number</td>
<td>0</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>rdinfoFPS</td>
<td>number</td>
<td>30</td>
<td>Returns the SWF&#039;s <em>frames per second</em> rate.</td>
</tr>
<tr>
<td>rdinfoFrameCount</td>
<td>number</td>
<td>90</td>
<td>Returns the number of frames in the entire SWF.</td>
</tr>
<tr>
<td>rdinfoSlideCount</td>
<td>number</td>
<td>1</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>rdinfoSlidesInProject</td>
<td>number</td>
<td>1</td>
<td>Returns the number of slides in the project.</td>
</tr>
<tr>
<td>rdinfocurrFrame</td>
<td>number</td>
<td>2</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>swfCmtAutoPlay</td>
<td>boolean</td>
<td>false</td>
<td>Returns boolean indicating whether SWF commenting auto-play is enabled. This is only used by the SWF Commenting AIR application.</td>
</tr>
<tr>
<td>swfCommenting</td>
<td>boolean</td>
<td>false</td>
<td>Returns boolean indicating whether SWF commenting auto-play is enabled. This is only used by the SWF Commenting AIR application.</td>
</tr>
<tr>
<td>tocInitDone</td>
<td>boolean</td>
<td>true</td>
<td>Returns boolean indicating whether the Table of Contents has finished initializing.</td>
</tr>
</table>
<h2>Captivate 3 Variables</h2>
<h3>Functional variables (perform an action)</h3>
<table cellspacing="0">
<tr>
<th>Variable</th>
<th>Returns</th>
<th>Default values</th>
<th>Description (if available)</th>
</tr>
<tr>
<td>rdcmndCC</td>
<td>string</td>
<td>0</td>
<td>Toggles closed captioning on (1) or off (0).</td>
</tr>
<tr>
<td>rdcmndGotoSlide</td>
<td>string</td>
<td>-1</td>
<td>Jumps to the specified slide number. Takes slide number (0-based index) as argument.</td>
</tr>
<tr>
<td>rdcmndMute</td>
<td>string</td>
<td>0</td>
<td>Toggles audio. Setting to 1 mutes the audio, setting to 0 unmutes the audio.</td>
</tr>
<tr>
<td>rdcmndNext</td>
<td>string</td>
<td>0</td>
<td>Setting value to 1 will  jump to the next slide in project.</td>
</tr>
<tr>
<td>rdcmndHidePlaybar</td>
<td>string</td>
<td>0</td>
<td>Toggles playbar&#039;s visibility</td>
</tr>
</table>
<h3>Informational variables (retrieve or set data)</h3>
<table cellspacing="0">
<tr>
<th>Variable</th>
<th>Returns</th>
<th>Sample values</th>
<th>Description (if available)</th>
</tr>
<tr>
<td>CaptivateVersion</td>
<td>string</td>
<td>2.0.0</td>
<td>Returns version of Captivate that published the SWF.</td>
</tr>
<tr>
<td>rdIsPreview</td>
<td>string</td>
<td>0</td>
<td>Returns a boolean (in number format) indicating whether this is a preview. Primarily used internally by Captivate when previewing a project.</td>
</tr>
<tr>
<td>rdinfoCurrentFrame</td>
<td>string</td>
<td>1</td>
<td>Returns the number of the current frame (NOT slide), counting from the beginning of the movie&#039;s timeline.</td>
</tr>
<tr>
<td>rdinfoCurrentSlide</td>
<td>string</td>
<td>1</td>
<td>Returns the current slide number using zero-based indexing (slide 1 of the project will return <em>0)</em>.</td>
</tr>
<tr>
<td>rdinfoCurrentSlideInProject</td>
<td>string</td>
<td>1</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>rdinfoFPS</td>
<td>string</td>
<td>24</td>
<td>Returns the SWF&#039;s <em>frames per second</em> rate.</td>
</tr>
<tr>
<td>rdinfoFrameCount</td>
<td>string</td>
<td>2889</td>
<td>Returns the number of frames in the entire SWF.</td>
</tr>
<tr>
<td>rdinfoHasPlaybar</td>
<td>string</td>
<td>1</td>
<td>Returns a boolean (in number format) indicating whether the Captivate file was published with playback controls (a playbar).</td>
</tr>
<tr>
<td>rdinfoSlideCount</td>
<td>string</td>
<td>13</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>rdinfoSlidesInProject</td>
<td>string</td>
<td>13</td>
<td>Returns the number of slides in the project.</td>
</tr>
<tr>
<td>rdinfocurrFrame</td>
<td>string</td>
<td>0</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>rdcmndPlaybarMoved</td>
<td>string</td>
<td>0</td>
<td>&nbsp;</td>
</tr>
</table>
<h3>Possibly related journal entries:</h3>
<ul class="related_post">
<li>June 7, 2009 &#8212; <a href="http://pipwerks.com/journal/2009/06/07/introducing-the-captivatecontroller/" title="Introducing the CaptivateController">Introducing the CaptivateController</a></li>
<li>March 23, 2009 &#8212; <a href="http://pipwerks.com/journal/2009/03/23/legacycaptivateloader-example-updated/" title="LegacyCaptivateLoader example updated">LegacyCaptivateLoader example updated</a></li>
<li>April 8, 2008 &#8212; <a href="http://pipwerks.com/journal/2008/04/08/legacycaptivateloader-dealing-with-pre-existing-scripts-in-your-captivate-swf/" title="LegacyCaptivateLoader: dealing with pre-existing scripts in your Captivate SWF">LegacyCaptivateLoader: dealing with pre-existing scripts in your Captivate SWF</a></li>
<li>April 3, 2008 &#8212; <a href="http://pipwerks.com/journal/2008/04/03/new-legacycaptivateloader-class/" title="New: LegacyCaptivateLoader class">New: LegacyCaptivateLoader class</a></li>
<li>March 11, 2008 &#8212; <a href="http://pipwerks.com/journal/2008/03/11/introducing-the-pipwerks-e-learning-development-forum/" title="Introducing the pipwerks e-learning development forum">Introducing the pipwerks e-learning development forum</a></li>
<li>August 14, 2007 &#8212; <a href="http://pipwerks.com/journal/2007/08/14/captivate-3-javascript-and-actionscript/" title="Captivate 3, JavaScript and Actionscript">Captivate 3, JavaScript and Actionscript</a></li>
</ul>
<p><p><a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-sa/3.0/us/80x15.png" /></a><br />This work by <a xmlns:cc="http://creativecommons.org/ns#" href="http://pipwerks.com" property="cc:attributionName" rel="cc:attributionURL">Philip Hutchison</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/">Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License</a>.</p></p>
<p><a href="http://pipwerks.com/journal/2009/05/16/captivate-4-variables-gone-wild/">Captivate 4 variables gone wild</a></p>
<img src="http://feeds.feedburner.com/~r/pipwerks/~4/sFluHskEAhk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://pipwerks.com/journal/2009/05/16/captivate-4-variables-gone-wild/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		<feedburner:origLink>http://pipwerks.com/journal/2009/05/16/captivate-4-variables-gone-wild/</feedburner:origLink></item>
		<item>
		<title>SCORM security (two kinds of SCORM people)</title>
		<link>http://feedproxy.google.com/~r/pipwerks/~3/LicuDHrYA_E/</link>
		<comments>http://pipwerks.com/journal/2009/04/02/scorm-security-two-kinds-of-scorm-people/#comments</comments>
		<pubDate>Thu, 02 Apr 2009 08:09:28 +0000</pubDate>
		<dc:creator>Philip Hutchison</dc:creator>
				<category><![CDATA[SCORM]]></category>
		<category><![CDATA[e-learning]]></category>
		<category><![CDATA[ADL]]></category>
		<category><![CDATA[best practices]]></category>
		<category><![CDATA[cheating]]></category>
		<category><![CDATA[elearning]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[learning management systems]]></category>
		<category><![CDATA[letsi]]></category>
		<category><![CDATA[SCORM 2.0]]></category>
		<category><![CDATA[standards]]></category>

		<guid isPermaLink="false">http://pipwerks.com/journal/?p=607</guid>
		<description><![CDATA[I've had a flurry of emails and messages regarding my SCORM cheat the past few days, and have received feedback from a number of well-regarded SCORM aficionados, some of whom contributed to the standard and helped make SCORM what it is today.  This is wonderful, I'm very happy to hear from everyone, especially regarding such an engaging topic.

But as I hear more from these seasoned SCORM pros, I've made (what I believe to be) an interesting observation: there is a sharp division between die-hard SCORM developers and casual users.  I suppose I've felt this way for a long time, but it's really coming into focus this week. Let me try to define the camps.<p><p><a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-sa/3.0/us/80x15.png" /></a><br />This work by <a xmlns:cc="http://creativecommons.org/ns#" href="http://pipwerks.com" property="cc:attributionName" rel="cc:attributionURL">Philip Hutchison</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/">Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License</a>.</p></p>
<p><a href="http://pipwerks.com/journal/2009/04/02/scorm-security-two-kinds-of-scorm-people/">SCORM security (two kinds of SCORM people)</a></p>
]]></description>
			<content:encoded><![CDATA[<p>I&#039;ve had a flurry of emails and messages regarding my <a href="http://pipwerks.com/journal/2009/03/22/cheating-in-scorm/">SCORM cheat</a> the past few days, and have received feedback from a number of well-regarded SCORM aficionados, some of whom contributed to the standard and helped make SCORM what it is today.  This is wonderful, I&#039;m very happy to hear from everyone, especially regarding such an engaging topic.</p>
<p>But as I hear more from these seasoned SCORM pros, I&#039;ve made (what I believe to be) an interesting observation: there is a sharp division between die-hard SCORM developers and casual users.  I suppose I&#039;ve felt this way for a long time, but it&#039;s really coming into focus this week. Let me try to define the camps.</p>
<ul>
<li><strong>Die-hard SCORM developers (aka <em>scormmies</em>)</strong>. The scormmie is a person who understands what SCO roll-up means, and can hand-code an entire manifest.  A scormmie thinks the word <em>metadata</em> is sexy. This person believes a course should be designed to use SCORM from the start, complete with sequencing and interaction tracking; if the course isn&#039;t running in an LMS, it won&#039;t function without being loaded into some kind of SCORM player or test suite. Scormmies get angry if their LMS hasn&#039;t implemented the entire SCORM spec.</li>
<li><strong>Casual users (aka <em>shruggies</em>)</strong>. The shruggie is a person who doesn&#039;t care about multi-SCO courses. Shruggies don&#039;t want to be bothered by the technical details, and use rapid e-learning development tools to build courses, freeing them from needing to know any of the technical mumbo-jumbo. Meta<em>what</em>? &#034;SCORM&#8230; yeah, that&#039;s one of the publishing options in [insert product name here], right?  So it will work with my LMS?&#034;</li>
</ul>
<h3>The e-learning market has changed significantly</h3>
<p>Over the last week I&#039;ve mostly heard from scormmies who make comments such as &#039;<em>well, if a developer knows what they&#039;re doing, they&#039;d never make their course that vulnerable to begin with!</em>&#039; and &#039;<em>a developer should never design a course to only require a completion and score&#8230; that&#039;s asking for trouble.</em>&#039;</p>
<p>The problem with this line of reasoning is that the e-learning landscape has changed dramatically since SCORM was first conceived; the scormmie used to be the majority.  Now, with the proliferation of e-learning development tools and LMSs, the scormmie is a minority. Most &#034;e-learning developers&#034; are not programmers by trade, and are not familiar with the very complicated and intimidating SCORM spec. They use tools that do the heavy lifting for them.</p>
<p>If you survey most e-learning development tools (which is a <em>booming</em> market), the courses they publish are almost exclusively single-SCO courses that only use the simplest core SCORM functionality: completion status, lesson location (bookmarking), score, and suspend_data.  These products are designed to create courses that work <em>without SCORM</em>, which means they only add the minimal SCORM code needed to get the course running on an LMS; all other logic is generally handled internally.  They certainly don&#039;t use sequencing and navigation or cmi.interactions.</p>
<p>LMS vendors generally advise customers to buy these off-the-shelf tools to build their courses.  E-learning conferences are packed with tool vendors and advertisements selling the virtues of a &#039;no technical expertise required&#039; tool.  At work I sometimes get calls from vendors trying to sell me the latest and greatest tool.</p>
<h3>The majority of courses are no longer developed by scormmies</h3>
<p>All of this leads to one point: I think some of the SCORM guys have lost touch with the current market and don&#039;t realize just how much of a problem a simple SCORM cheat like mine could be.  Sure, it probably wouldn&#039;t work on courses developed by seasoned scormmies because multi-SCO courses that utilize interactions are much too complicated for my itty-bitty script to tackle&#8230; but courses developed by mainstream development tools are easy targets. Ducks in a barrel. So long as the API is JavaScript and unprotected, a script like mine can bypass the SCO completely and set the course to complete before the learner even gets past the table of contents.  The only way to figure out if someone cheated is to run a completion report and look for unusual patterns, which is highly unlikely in most corporate environments. As a friend noted the other day, there are many more <em>script kiddies</em> who can write cheats like mine now than there were when SCORM was first proposed.</p>
<h3>Who gets the blame for the vulnerability?</h3>
<p>Can the tool makers be blamed? Maybe, but hey, their #1 priority is satisfying the needs of the community, and the community wants quick, easy, and &#039;can run on a CD-Rom&#039;. Could the vendors have implemented more sophisticated SCORM mechanisms? Yes. However, everyone chooses the path of least resistance (and least development dollars), and we all know SCORM development is not a walk in the park. I&#039;ve been using SCORM for five years and still avoid most of the complicated stuff because it&#039;s &#8230; well &#8230; <em>complicated</em>.</p>
<p>The community at large (aka the shruggies) has bought into the notion that SCORM is <em>the</em> standard for e-learning.  This is what the scormmies wanted, and it made the most sense for everyone involved, even the tool vendors.  But how many people knew about the security vulnerabilities in the JavaScript-based API? A lot: the SCORM authors, the ADL, LMS vendors, tool vendors, and a number of prominent SCORM developers. Did any of these people warn the end clients of the risks? Maybe, but I personally have never been warned of any SCORM security issues in my five odd years of SCORM work. I&#039;ve never been told &#034;don&#039;t use SCORM for that because it isn&#039;t secure.&#034;</p>
<h3>Why didn&#039;t anyone act?</h3>
<p>I wasn&#039;t privy to the early conversations, but I&#039;ve been told that SCORM developers have said &#034;don&#039;t use SCORM for high-stakes assessments&#034; from the very beginning, circa 2000.  If this is the case, why has nothing been done to improve SCORM&#039;s security?  It&#039;s only been about <em>nine years</em>. Did convenience beat out security in the race to implement the standard?</p>
<p>I get the impression that the scormmies (and remember, my term <em>scormmie</em> just means a person that works with SCORM, not necessarily an official representative) felt no one would bother trying to hack the system, and that a well-built course would be so difficult to cheat that it would be easier to simply take the course.  With today&#039;s simplistic single-SCO courseware tools, I don&#039;t think this is a valid argument anymore.</p>
<p>I&#039;ve also heard from scormmies that we&#039;re still fine, because everyone knows SCORM shouldn&#039;t be used for high-stakes training. I think a significant number of corporate, military and government trainers would disagree with that assessment, because the LMS salesperson never mentioned it.  Neither did the e-learning development tool vendor. Oh, and that instructional designer we hired out of college?  She&#039;s heard of SCORM but has no clue how it works. Isn&#039;t it safe since you have to log into the LMS with a password?  There&#039;s a padlock icon and an <em>https</em> protocol&#8230; that means it&#039;s secure, right?</p>
<p>Nope.</p>
<p>Simple-SCO courses are used for all kinds of sensitive training nowadays. Compliance training alone is <em>huge</em> these days and can be found in examples from almost every simple-SCO tool vendor. As a colleague recently remarked, &#034;it&#039;s all low stakes until someone&#039;s attorney gets involved&#034;.</p>
<h3>No hard feelings!</h3>
<p>I would like to point out that I am not targeting anyone in particular, have no animosity towards anyone, and have the utmost respect for the scormmies and what they do (I&#039;m half-scormmie myself). I&#039;m an optimist with a very critical eye, and this post is intended as <em>constructive</em> criticism&#8230; criticism intended to cause positive change.</p>
<p>It simply became apparent to me that at some point the scormmie community dropped the ball and got complacent; it seems as though the whole community assumed no one would bother to hack a course. Well, I did. And I used public documentation to do it. It took two hours while I was flying on an airplane, and I&#039;m not the sharpest tack in the box. I&#039;m sorry if my cheat script caused a stir (and if this blog post makes some people uncomfortable) but we need to talk about this issue.  Now.</p>
<h3>What&#039;s the solution?</h3>
<p>OK, we&#039;ve covered enough of the criticisms and the importance of working towards a solution&#8230; I&#039;m ready to let it rest. Let&#039;s finish on a positive note: SCORM uses existing technology and standards, and if multinational banks can protect billions of dollars from cyber-criminals using standard web technology, we should be able to secure our courseware, too. I personally think we should be able to figure something out in the next couple of months and that it ideally shouldn&#039;t require much work to implement &#8212; no need to wait until SCORM 2.0 comes out!</p>
<p>Here are some suggestions I&#039;ve heard:</p>
<ul>
<li>using a secure web service to handle important duties such as processing completions and scores</li>
<li>rolling up SCOs in a way that forces the LMS to analyze multiple SCOs before setting pass/fail (a second &#039;dummy&#039; SCO could be used if the course is a single-SCO course)</li>
<li>using form posts to submit the completions (the form post would contain a unique encrypted key that must match a key on the LMS)</li>
</ul>
<p>Personally, I&#039;m especially interested in ideas that don&#039;t require modifications to LMS implementations and might only involve a strategic re-organizing of a SCO&#039;s manifest or SCORM code. Perhaps using a SCO roll-up can become a security best practice, even if the course only uses one SCO? That type of simple solution would be ideal since it wouldn&#039;t require modifications to an LMS or SCORM spec &#8212; it would only require a broad marketing effort to get the word out to all SCORM developers and toolmakers.</p>
<p>I would love to hear other ideas, as I feel we can probably come up with any number of workable solutions.    Please add to the discussion! Remember, these need to be solutions that can be implemented easily and by the single-SCO type of courseware tools flooding the e-learning market.</p>
<p>By the way, while we&#039;re at it, can we improve accessibility in our e-learning, too?  <img src='http://pipwerks.com/journal/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /><br />
<h3>Possibly related journal entries:</h3>
<ul class="related_post">
<li>December 13, 2008 &#8212; <a href="http://pipwerks.com/journal/2008/12/13/scorm-20-high-level-solutions-or-low-level-tools/" title="SCORM 2.0: high-level solutions or low-level tools?">SCORM 2.0: high-level solutions or low-level tools?</a></li>
<li>June 22, 2008 &#8212; <a href="http://pipwerks.com/journal/2008/06/22/what-do-you-want-your-scorm-to-do/" title="What do you want *your* SCORM to do?">What do you want *your* SCORM to do?</a></li>
<li>March 11, 2008 &#8212; <a href="http://pipwerks.com/journal/2008/03/11/introducing-the-pipwerks-e-learning-development-forum/" title="Introducing the pipwerks e-learning development forum">Introducing the pipwerks e-learning development forum</a></li>
<li>February 14, 2008 &#8212; <a href="http://pipwerks.com/journal/2008/02/14/scorm-javascript-wrapper-updated-to-114/" title="SCORM JavaScript wrapper updated to 1.1.4">SCORM JavaScript wrapper updated to 1.1.4</a></li>
<li>January 28, 2008 &#8212; <a href="http://pipwerks.com/journal/2008/01/28/scorm-api-wrapper-updated-to-112/" title="SCORM API Wrapper updated to 1.1.2">SCORM API Wrapper updated to 1.1.2</a></li>
<li>January 24, 2008 &#8212; <a href="http://pipwerks.com/journal/2008/01/24/scorm-api-wrapper-updated-to-111/" title="SCORM API Wrapper updated to 1.1.1">SCORM API Wrapper updated to 1.1.1</a></li>
</ul>
<p><p><a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-sa/3.0/us/80x15.png" /></a><br />This work by <a xmlns:cc="http://creativecommons.org/ns#" href="http://pipwerks.com" property="cc:attributionName" rel="cc:attributionURL">Philip Hutchison</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/">Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License</a>.</p></p>
<p><a href="http://pipwerks.com/journal/2009/04/02/scorm-security-two-kinds-of-scorm-people/">SCORM security (two kinds of SCORM people)</a></p>
<img src="http://feeds.feedburner.com/~r/pipwerks/~4/LicuDHrYA_E" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://pipwerks.com/journal/2009/04/02/scorm-security-two-kinds-of-scorm-people/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		<feedburner:origLink>http://pipwerks.com/journal/2009/04/02/scorm-security-two-kinds-of-scorm-people/</feedburner:origLink></item>
		<item>
		<title>LegacyCaptivateLoader example updated</title>
		<link>http://feedproxy.google.com/~r/pipwerks/~3/9HXSamd43Ew/</link>
		<comments>http://pipwerks.com/journal/2009/03/23/legacycaptivateloader-example-updated/#comments</comments>
		<pubDate>Tue, 24 Mar 2009 01:45:23 +0000</pubDate>
		<dc:creator>Philip Hutchison</dc:creator>
				<category><![CDATA[e-learning]]></category>
		<category><![CDATA[actionscript]]></category>
		<category><![CDATA[Adobe Captivate]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[LegacyCaptivateLoader class]]></category>

		<guid isPermaLink="false">http://pipwerks.com/journal/?p=595</guid>
		<description><![CDATA[Just a note to point out that I updated the <a href="http://pipwerks.com/lab/captivate/LegacyCaptivateLoader/EI/index.html">LegacyCaptivateLoader example</a> to use SWFObject 2.1 (dynamic publishing).<p><p><a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-sa/3.0/us/80x15.png" /></a><br />This work by <a xmlns:cc="http://creativecommons.org/ns#" href="http://pipwerks.com" property="cc:attributionName" rel="cc:attributionURL">Philip Hutchison</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/">Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License</a>.</p></p>
<p><a href="http://pipwerks.com/journal/2009/03/23/legacycaptivateloader-example-updated/">LegacyCaptivateLoader example updated</a></p>
]]></description>
			<content:encoded><![CDATA[<p>Just a note to point out that I updated the <a href="http://pipwerks.com/lab/captivate/LegacyCaptivateLoader/EI/index.html">LegacyCaptivateLoader example</a> to use SWFObject 2.1 (dynamic publishing). It has been successfully tested in the following systems:</p>
<ul>
<li>Mac OS X:
<ul>
<li> Firefox 3.0.7</li>
<li> Opera 9.6.3</li>
<li> Safari 3.2.1</li>
</ul>
</li>
<li>Windows XP:
<ul>
<li>Internet Explorer 6</li>
<li>Firefox 3.0.6</li>
</ul>
</li>
<li>Windows Vista Business:
<ul>
<li>Internet Explorer 7</li>
<li>Firefox 3.0.2</li>
<li>Opera 9.5.2</li>
<li>Safari 3.2.1</li>
</ul>
</li>
<li>Windows 7 Experimental
<ul>
<li>Internet Explorer 8 (Beta)</li>
</ul>
</li>
</ul>
<p>Note: the LegacyCaptivateLoader will probably fail if you embed the SWF using SWFObject 2&#039;s <em>static publishing</em> option, as the nested <code>&lt;object&gt;</code> elements will cause problems for the JavaScript.<br />
<h3>Possibly related journal entries:</h3>
<ul class="related_post">
<li>April 8, 2008 &#8212; <a href="http://pipwerks.com/journal/2008/04/08/legacycaptivateloader-dealing-with-pre-existing-scripts-in-your-captivate-swf/" title="LegacyCaptivateLoader: dealing with pre-existing scripts in your Captivate SWF">LegacyCaptivateLoader: dealing with pre-existing scripts in your Captivate SWF</a></li>
<li>April 3, 2008 &#8212; <a href="http://pipwerks.com/journal/2008/04/03/new-legacycaptivateloader-class/" title="New: LegacyCaptivateLoader class">New: LegacyCaptivateLoader class</a></li>
<li>May 16, 2009 &#8212; <a href="http://pipwerks.com/journal/2009/05/16/captivate-4-variables-gone-wild/" title="Captivate 4 variables gone wild">Captivate 4 variables gone wild</a></li>
<li>March 11, 2008 &#8212; <a href="http://pipwerks.com/journal/2008/03/11/introducing-the-pipwerks-e-learning-development-forum/" title="Introducing the pipwerks e-learning development forum">Introducing the pipwerks e-learning development forum</a></li>
<li>January 14, 2008 &#8212; <a href="http://pipwerks.com/journal/2008/01/14/loading-captivate-files-into-an-as3-flash-swf/" title="Loading Captivate files into an AS3 Flash SWF">Loading Captivate files into an AS3 Flash SWF</a></li>
<li>August 14, 2007 &#8212; <a href="http://pipwerks.com/journal/2007/08/14/captivate-3-javascript-and-actionscript/" title="Captivate 3, JavaScript and Actionscript">Captivate 3, JavaScript and Actionscript</a></li>
</ul>
<p><p><a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-sa/3.0/us/80x15.png" /></a><br />This work by <a xmlns:cc="http://creativecommons.org/ns#" href="http://pipwerks.com" property="cc:attributionName" rel="cc:attributionURL">Philip Hutchison</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/">Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License</a>.</p></p>
<p><a href="http://pipwerks.com/journal/2009/03/23/legacycaptivateloader-example-updated/">LegacyCaptivateLoader example updated</a></p>
<img src="http://feeds.feedburner.com/~r/pipwerks/~4/9HXSamd43Ew" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://pipwerks.com/journal/2009/03/23/legacycaptivateloader-example-updated/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://pipwerks.com/journal/2009/03/23/legacycaptivateloader-example-updated/</feedburner:origLink></item>
	</channel>
</rss>
