PDFObject 2.0 released

After almost eight years in the making (and nearly 7 years of procrastinating), PDFObject 2.0 has arrived.

PDFObject is an open-source standards-friendly JavaScript utility for embedding PDF files into HTML documents. It’s like SWFObject, but for PDFs.

Version 1.0 was released in 2008 and has enjoyed modest success. Based on stats from PDFObject.com (including devious hot-linkers) and integration with 3rd-party products, I’m guesstimating it has been used on well over a million web pages. (If I had a nickel for every time it was used…)

I updated it a few times over the years, but generally only if someone reported a compatibility issue. Like an old beat-up car, it was a bit crusty, but still ran like a champ. That is, it ran like a champ until the rules of the game were changed — when Microsoft changed their ActiveX strategy in Internet Explorer 10-11 and Microsoft Edge, PDFObject’s checks for ActiveX began to fail, rendering PDFObject useless in those browsers. This marked the beginning of the end for PDFObject 1.x.

An update was overdue, yet I let it sit for a couple of years – I fully admit that kids, my job, and life tend to take precedence over an unfunded open-source project. But I never stopped thinking about PDFObject. I intentionally kept it at arm’s length for a while; I was fascinated by changes in the front-end development world, and waited to see how things would shake out.

It’s incredible how much has changed since 2008. For starters, the browser landscape has completely changed. Chrome, which didn’t exist when PDFObject was first released, now rules the land. It also happens to include built-in PDF support. PDF.js was invented, and eventually became Firefox’s default PDF rendering engine. Safari renders PDFs natively using Preview. iOS and Android exploded onto the scene, as did Node.js and NPM. Conversely, Adobe Reader’s market share took a nosedive thanks to browser vendors making Adobe Reader less relevant, not to mention disdain for Adobe Reader’s bloat and security holes. And, of course, HTML5 is now official, which means the <embed> element is officially sanctioned.

PDFObject 2.0 is a complete rewrite that tries to take all of this into consideration. It supports PDF.js. It’s packaged for NPM. It uses the <embed> element instead of the <object> element (not going to rename it to PDFEmbed though). It doesn’t pollute the global space and uses modern JavaScript conventions. It supports all CSS selectors, not just IDs. If you’re feeling frisky, you can even pass a jQuery element instead of a CSS selector (note: PDFObject does not require jQuery). Lots of little changes, which I hope add up to a better experience, wider compatibility, and lots of flexibility.

If you’d like to learn more about PDFObject 2.0, please visit the official site (completely redesigned as well), with examples, documentation and a code generator: http://pdfobject.com

The code is up on GitHub, and has been posted to npm.

Advertisements

Introducing SWFRightClick

Adobe Captivate currently ships with a 3rd-party JavaScript utility named RightClick.js, which enables the Captivate SWF to detect when a user right-clicks the SWF. While upgrading the Captivate publishing templates, I realized RightClick.js wasn’t built to work with SWFObject 2.x and suffered from a few shortcomings. I modified the Captivate template’s SWFObject code to get around the issue, but marked it down as something to revisit when I have the time.

Now, I’m happy to report I’ve created a replacement for the RightClick.js utility, creatively named SWFRightClick. It uses the same approach to handling right-clicks, but does it with a completely new codebase and a few extra goodies. SWFRightClick is compatible with every edition of SWFObject, and is free to use (MIT license).

Check it out on GitHub. I plan to fold it in to my Captivate publishing templates very soon.

Using the object element to dynamically embed Flash SWFs in Internet Explorer

This is a journey into the madness of Internet Explorer.

Yes, there is a happy ending. Jump to the end of the post if you just want the solution and don’t care about how we got there.

The Scenario

You want to embed a Flash SWF into your HTML document using the object element, and you need to be able to do it using JavaScript. (Let’s pretend SWFObject doesn’t exist, ok?)

If you were using HTML markup without JavaScript, embedding a Flash SWF using an object element would be pretty straightforward:


<object id="mySWF" width="550" height="400" 
        data="mymovie.swf" 
        type="application/x-shockwave-flash">
   <param name="flashvars" value="dog=woof&cat=meow" />
</object>

Microsoft designed Internet Explorer’s object to work a bit differently, so the markup for Internet Explorer becomes:


<object id="mySWF" width="550" height="400"
        classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000">
   <param name="movie" value="mymovie.swf" />
   <param name="flashvars" value="dog=woof&cat=meow" />
</object>

The key differences are:

  • Internet Explorer requires the classid attribute instead of type
  • Internet Explorer requires the param name="movie" child node instead of the data attribute in the object

Annoying, perhaps, but workable. If you’re working with hard-coded markup — what SWFObject refers to as static publishing — you can drop in some conditional comments and be done:


<!--[if IE]>
<object id="mySWF" width="550" height="400"
        classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000">
   <param name="movie" value="mymovie.swf">
<![endif]-->

<!--[if !IE]>-->
<object id="mySWF" width="550" height="400"
        data="mymovie.swf"
        type="application/x-shockwave-flash">
<!--<![endif]-->

   <param name="flashvars" value="dog=woof&cat=meow" />

<p>Fallback content for people without Flash Player</p>

</object>

That’s nice, but I need to use JavaScript

On the surface, using JavaScript to recreate the HTML markup appears to be a trivial task; we just need to add conditional logic to handle the two small differences between Internet Explorer’s object element and the object element used by the other browsers:


var target_element = document.getElementById("replaceMe"),
   obj = document.createElement("object"),
   isMSIE = /*@cc_on!@*/false;

//Add attributes to <object>
obj.setAttribute("id", "myObjID");
obj.setAttribute("width", "550");
obj.setAttribute("height", "400");

//Add <param> node(s) to <object>
var param_flashvars = document.createElement("param");
param_flashvars.setAttribute("name", "flashvars");
param_flashvars.setAttribute("value", "cat=meow&dog=woof");
obj.appendChild(param_flashvars);

if (isMSIE) {            

   //IE requires the 'classid' attribute
   obj.setAttribute("classid", "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000");
   
   //IE requires the 'movie' <param>
   var param_movie = document.createElement("param");
   param_movie.setAttribute("name", "movie");
   param_movie.setAttribute("value", "test.swf");
   obj.appendChild(param_movie);

} else {

   //Non-IE browsers require the 'type' attribute
   obj.setAttribute("type", "application/x-shockwave-flash");
   
   //Non-IE browsers require the 'data' attribute
   obj.setAttribute("data", "test.swf");

}

//Replace targeted DOM element with our new <object>
target_element.parentNode.replaceChild(obj, target_element);

Seems simple enough, right? Not so fast. If you try running this in Internet Explorer (6-9), you’ll notice the SWF fails to load, and IE will behave as though it’s stuck trying to load a file — the “loading” icon never goes away.

Issues with Microsoft’s proprietary classid attribute

It turns out Internet Explorer’s object does not like having the classid appended after the object has been created. This is very similar to the well-known IE bug for adding the name attribute to certain form elements. For the form element bug, Microsoft’s solution is to include the name attribute in the createElement string:

Attributes can be included with the sTag as long as the entire string is valid HTML. To include the NAME attribute at run time on objects created with the createElement method, use the sTag.

Microsoft provides the following example:


var newRadioButton = document.createElement("<INPUT TYPE='RADIO' NAME='RADIOTEST' VALUE='First Choice'>")

What happens if we use this solution for the classid issue?


var node_name = (isMSIE) ? "<object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000' />" : "object";
var obj = document.createElement(node_name);

This works like a charm… in IE 8 and lower. Unfortunately, IE 9 chucks a wobbly. Microsoft, in their wisdom, decided that angled brackets should no longer be valid inside the createElement method. This is actually excellent news: Internet Explorer 9 is behaving like other browsers, so let’s just use a try/catch to target IE versions prior to IE9, and use standard W3C code for IE9:


var target_element = document.getElementById("replaceMe"),
   isMSIE = /*@cc_on!@*/false,
   obj;

if (isMSIE) {

   try {
      
      //For IE 8 and lower
      obj = document.createElement("<object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000' />");

      //IE requires the 'movie' <param>
      var param_movie = document.createElement("param");
      param_movie.setAttribute("name", "movie");
      param_movie.setAttribute("value", "test.swf");
      obj.appendChild(param_movie);
      
   } catch (e) {
      
      //Let IE9 and higher fall through and use the standard browser markup
            
   }
   
}

if (!obj) {

   obj = document.createElement("object");
   obj.setAttribute("type", "application/x-shockwave-flash");
   obj.setAttribute("data", "test.swf");
   
}

//Add attributes to <object>
obj.setAttribute("id", "myObjID");
obj.setAttribute("width", "550");
obj.setAttribute("height", "400");

//Add <param> node(s) to <object>
var param_flashvars = document.createElement("param");
param_flashvars.setAttribute("name", "flashvars");
param_flashvars.setAttribute("value", "cat=meow&dog=woof");
obj.appendChild(param_flashvars);

//Replace targeted DOM element with our new <object>
target_element.parentNode.replaceChild(obj, target_element);

Still works in Internet Explorer 8 and lower, but fails in IE 9. Okay, perhaps IE9 still requires the classid attribute and ‘movie’ param. Let’s fork the code some more and try it out.


var target_element = document.getElementById("replaceMe"),
   isMSIE = /*@cc_on!@*/false,
   obj;

if (isMSIE) {

   try {
      
      //For IE 8 and lower
      obj = document.createElement("<object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000' />");
      
   } catch (e) {
      
      //IE9 doesn't support classid in createElement, so let's add it afterward
      obj = document.createElement("object");
      obj.setAttribute("classid", "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000");
      
   }

   //IE requires the 'movie' <param>
   var param_movie = document.createElement("param");
   param_movie.setAttribute("name", "movie");
   param_movie.setAttribute("value", "test.swf");
   obj.appendChild(param_movie);
   
} else {

   //Standard browsers
   obj = document.createElement("object");
   obj.setAttribute("type", "application/x-shockwave-flash");
   obj.setAttribute("data", "test.swf");
   
}

//Add attributes to <object>
obj.setAttribute("id", "myObjID");
obj.setAttribute("width", "550");
obj.setAttribute("height", "400");

//Add <param> node(s) to <object>
var param_flashvars = document.createElement("param");
param_flashvars.setAttribute("name", "flashvars");
param_flashvars.setAttribute("value", "cat=meow&dog=woof");
obj.appendChild(param_flashvars);

//Replace targeted DOM element with our new <object>
target_element.parentNode.replaceChild(obj, target_element);

Are you ready for the surprise? This doesn’t work in IE9, either. Adding classid to the object after it has been created simply will not work in any version of Internet Explorer. Microsoft removed their own recommended workaround — adding the attribute in the createElement string — to standardize their browser, yet they failed to provide full support for the related W3C standards being used by their competitors.

In their announcement of the createElement change for IE9, Microsoft recommended using the W3C standard setAttribute method, yet it fails for classid. *grumble*

To their credit, Microsoft also provided a second workaround consisting of strings and innerHTML:


var parent=document.createElement("div");
parent.innerHTML="<div id='myDiv'></div>";
var elm=parent.firstChild;

For our purposes, it would look like this:


function createIeObject(){
   var div = document.createElement("div");
   div.innerHTML = "<object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000'></object>";
   return div.firstChild;
}

var target_element = document.getElementById("replaceMe"),
   isMSIE = /*@cc_on!@*/false,
   obj = (isMSIE) ? createIeObject() : document.createElement("object");

if (isMSIE) {
   //IE requires the 'movie' <param>
   var param_movie = document.createElement("param");
   param_movie.setAttribute("name", "movie");
   param_movie.setAttribute("value", "test.swf");
   obj.appendChild(param_movie);
} else {
   obj.setAttribute("type", "application/x-shockwave-flash");
   obj.setAttribute("data", "test.swf");
}

//Add attributes to <object>
obj.setAttribute("id", "myObjID");
obj.setAttribute("width", "550");
obj.setAttribute("height", "400");

//Add <param> node(s) to <object>
var param_flashvars = document.createElement("param");
param_flashvars.setAttribute("name", "flashvars");
param_flashvars.setAttribute("value", "cat=meow&dog=woof");
obj.appendChild(param_flashvars);

//Replace targeted DOM element with our new <object>
target_element.parentNode.replaceChild(obj, target_element);

This feels like it’s getting us somewhere. Unfortunately, the SWF still doesn’t load. What else can we try? What if the ‘movie’ param were added at the same time the object is created and classid attribute is specified in Internet Explorer?


function createIeObject(url){
   var div = document.createElement("div");
   div.innerHTML = "<object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000'><param name='movie' value='" +url + "'></object>";
   return div.firstChild;
}

var target_element = document.getElementById("replaceMe"),
   isMSIE = /*@cc_on!@*/false,
   obj = (isMSIE) ? createIeObject("test.swf") : document.createElement("object");

if (!isMSIE) {
   obj.setAttribute("type", "application/x-shockwave-flash");
   obj.setAttribute("data", "test.swf");
}

//Add attributes to <object>
obj.setAttribute("id", "myObjID");
obj.setAttribute("width", "550");
obj.setAttribute("height", "400");

//Add <param> node(s) to <object>
var param_flashvars = document.createElement("param");
param_flashvars.setAttribute("name", "flashvars");
param_flashvars.setAttribute("value", "cat=meow&dog=woof");
obj.appendChild(param_flashvars);

//Replace targeted DOM element with our new <object>
target_element.parentNode.replaceChild(obj, target_element);

EUREKA! The SWF now displays as it should in all versions of Internet Explorer, and IE no longer behaves as if it’s stuck trying to load something. The takeaway is that Internet Explorer’s proprietary classid attribute and ‘movie’ param need to be created together or all is lost.

Why not use innerHTML all the way?

Many developers will say: Why not use innerHTML for the whole thing? After all, SWFObject 2.0 through 2.2 uses string building and innerHTML for the entire object creation in Internet Explorer:


el.outerHTML = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"' + att + '>' + par + '</object>';

In SWFObject, the attributes (att) and parameters (par) are added to the string via string concatenation. This is functional, but means that a completely different workflow — one devoid of standard W3C techniques — is required for Internet Explorer versus all other browsers.

For example, if there are many param nodes to add to the object, they will have to be generated as a long string of params in IE, while the fork for the non-IE browsers will all use a createElement/appendChild combination. In my opinion, it would be best to keep the code simple and use the same code for handling attributes and parameters in all browsers. This is ideal for maintenance, security, and file size.

Using the proposed IE solution allows us to modify the object via W3C techniques — we can add parameters and attributes and they all function as expected. The only difference between IE and other browsers is the creation of the initial object, but once it’s set up, IE’s object behaves the same in all browsers.

The obligatory poke at Microsoft

This is a perfect example of why there is not much love for Internet Explorer (and by extension, Microsoft) in many web developer circles. A task that should be trivial is utterly complicated, and requires hours of troubleshooting and experimentation just to achieve some basic functionality.

It’s my sincere hope that Internet Explorer 10+ will use the standard object code, but it probably won’t, since IE will probably still rely on ActiveX for the Flash Plugin. Falling short of using the standard object element, I hope that IE 10+ will at least allow us to add the classid attribute using setAttribute, and also allow us to add the movie param using createElement and appendChild.

Sniffing Internet Explorer via JavaScript

I’ve been reviewing bug submissions for the SWFObject project and was reminded of a big problem with SWFObject 2.2: the JavaScript technique it uses for detecting Internet Explorer does not work in Internet Explorer 9.

SWFObject 2.2 currently uses an IE detection technique proposed by Andrea Giammarchi in 2009:


var isIE = !+"v1";

It’s a hack that relied on Internet Explorer’s unique handling of vertical spaces (v). Now that it has stopped working, I decided to take a quick look at what others are doing.

One of my favorite approaches is Dean Edwards’ “sniff” technique, which takes advantage of Microsoft’s conditional compilation.


var isIE = /*@cc_on!@*/!1;

It’s 4 years old, but still works like a charm. The only problem is that some JavaScript compressors and optimizers (including YUI Compressor and Google Closure) have a hard time with the inline comment and strip it out. It makes the code difficult to maintain, because it requires editing post-compression.

One way to get around the compressor issue (as pointed out by a commenter on Dean Edwards’ post) is to wrap the conditional compilation statement in an eval() function:


var isIE = eval("/*@cc_on!@*/!1");

Since eval() is evil, I won’t use this approach.

One of the most long-standing methods of detecting Internet Explorer is to examine the userAgent string:


var isIE = /msie/gi.test(navigator.userAgent);

However, this isn’t foolproof, as most browsers allow you to change the userAgent string at will. For example, I changed Safari’s userAgent string to report itself as Internet Explorer 8, and /msie/gi.test(navigator.userAgent); returned true!

So far, the only test I’ve found that seems to fit the bill is the old navigator.appName test:


var isIE = navigator.appName === 'Microsoft Internet Explorer';

Is it perfect? Not a chance, but it has a lot of upside: it works in IE9, doesn’t get damaged when compressed, doesn’t rely on any hacky tricks (as fun as they might be), and isn’t affected by spoofed userAgent strings.

What are the Frameworks using?

jQuery uses userAgent sniffing, and includes a warning that it’s unreliable. MooTools uses a combination of properties from the navigator object, including navigator.userAgent and navigator.platform. It’s interesting to note that MooTools previously used feature detection to infer the browser brand, but changes introduced by Firefox 3.6 prompted the MooTools team to switch to a userAgent-based detection method instead. (Nicholas Zakas wrote an interesting blog post about MooTools’ prior detection technique.)
Dustin Diaz’s Bowser detection script uses userAgent exclusively.

Why sniff in the first place?

Before you get down on me for even talking about sniffing, relax, I agree with you. I much prefer feature detection to browser sniffing; this is especially important with our quickly changing browser landscape: HTML5, web storage, geolocation, etc. (Modernizr is a great tool for modern feature detection.)

But Internet Explorer always makes us do things we’re not quite comfortable doing. Sometimes it’s not very easy to detect IE’s support for a given issue. For example, IE is notorious for not allowing JavaScript developers to set the name attribute of form elements via setAttribute; it requires including the name in the createElement invocation. Craziness!

So we carry on. I use feature detection for just about everything, but once in a while I need a global “are you Internet Explorer?”, and browser sniffing fits the bill.

PDFObject Updated, Moved to GitHub

PDFObject is a JavaScript utility I created in 2008 to embed PDFs in HTML documents. It was modeled on SWFObject.

Three years have passed since PDFObject 1.0 was released, and the browser landscape has changed dramatically. I figured it’s time to dust off PDFObject and see if it can be improved and/or updated for today’s browsers.

I’ve placed a modified edition of PDFObject (version 1.1) on GitHub as an open-source project, allowing anyone to create a fork and make modifications. There are also a handful of example/test HTML files there, too. I could use some help testing the examples in different OS/browser combinations, and with different PDF plugins.

If you have suggestions for improvements, or have a few minutes to test PDFObject examples in your browser/OS of choice, I’d be grateful to hear from you. Just leave a comment below, or send me a message on twitter. So far I’ve only performed some cursory tests in Firefox 3.6 in OSX 10.6.6, but everything seems to work as expected.

https://github.com/pipwerks/PDFObject

I plan to update PDFObject.com soon, too.

IFrames and cross-domain security, part 3

In 2008 I posted a quick writeup on how I dealt with cross-domain security issues for some of my e-learning courseware. Since then, I’ve had a lot of people contact me with various questions and requests for a working example.

Tonight I decided to revisit the topic and whip up some quick example files. To my chagrin, I discovered a load of typos in my original post. Yikes! No wonder people wanted to see some working examples.

Well, ask no more, here they are:

The explanation provided in the previous post is still valid, just refer to these new sample files instead of the code in that post’s examples. (I will update that post with new code examples soon.)

Remember, the proxy.html file must reside on the same domain as the parent frame. This solution will not work if you don’t have FTP access to both domains, since you need to place support scripts on both domains.

Complete List of Variables for Adobe Captivate 5

While updating my CaptivateController script I noticed there have been some changes to the Captivate variables available to Captivate developers. I figured I should document them for future reference.

Note that some variables available in CP3 and CP4 are no longer available. The following list should be exhaustive for CP5; variables for previous versions of Captivate have been purposely left off this list. I also purposely left off some publicly accessible (but useless) movieclips and objects.

While most people seem to focus on using Captivate variables natively within a Captivate project via the Variables menu or widgets, my focus has been figuring out how accessible/usable they are via JavaScript. Thus you may find small differences between my list and other people’s lists, and differing opinions regarding the usefulness of some variables and publicly accessible movieclips. Regardless, the items below should be accessible via every method: widgets, JavaScript, and the native Variables support in Adobe Captivate.

If you know of any variables that I missed, please leave a comment. Thanks!

Update: Kurt Melander has kindly converted this list to PDF format if you’d like to download or print it. Thanks, Kurt.

Variable Type Description

CPMovieType

[number] Informational variable. Indicates whether the queried SWF is a skin SWF (0) or the main content SWF (1).
CaptivateVersion [string] Informational variable. Indicates the version of Adobe Captivate that published the SWF
DoNotRegisterRightClickBecauseOfAggregator [boolean] Internal variable, no information available
LocalConnectionInUse [boolean] Internal variable, no information available
NoOfTOCEntries [number] Informational variable. Returns the number of items contained in the project’s Table of Contents

PlaybarProperties

[string]
in Chrome

[XML] in Firefox

Internal variable, no information available.

NOTE: This item is
:XML data type in AS3. Because browsers have different support for native XML data types, values returned from this variable should not be considered cross-browser. Use at your own risk.

__loadbase [string]

Informational variable. Returns project’s root file path.

NOTE: This value can only be obtained when the project uses an external skin.

contentHeight [number] Informational variable. Returns the height of the Captivate main SWF (in pixels)
contentLeft [number] Informational variable. Returns the distance of the Captivate main SWF from the leftmost edge of the project (in pixels).
contentSWF [string]

Informational variable. Returns the file name for the project’s main SWF.

NOTE: This value can only be obtained when the project uses an external skin.

contentTop [number] Informational variable. Returns the distance of the Captivate main SWF from the topmost edge of the project (in pixels).
contentWidth [number] Informational variable. Returns the width of the Captivate main SWF (in pixels)
cpAutoPlay [boolean] Informational variable. Indicates whether the project is set to auto-play.
cpCaptivateSkinSWF [boolean]

Informational variable. Indicates whether the SWF is a skin SWF or primary project SWF.

NOTE: This value can only be obtained when the project uses an external skin.

cpCmndCC [number] Command variable. Setting to 1 will enable captioning. Setting to 0 will disable captioning.
cpCmndFastForward [number] Command variable. Setting to 1 will fast-forward the movie (play the movie at a higher framerate). Setting to 0 will return the movie to the normal playback speed.
cpCmndGotoFrameAndResume [number]

Command variable. Will cause the movie to jump to the specified frame and resume playing (frame numbering begins at 0).

Note: frames are not the same as slides.

cpCmndGotoSlide [number]

Command variable. Will cause the movie to jump to the specified slide (slide numbering starts at 0).

Note: frames are not the same as slides.

cpCmndMute [boolean] Command variable. Setting to 1 will disable (mute) the audio. Setting to 0 will restore it to normal.
cpCmndNext [number] Command variable. Setting to 1 will cause the movie to jump to the next slide. Setting to 0 will do nothing.
cpCmndPlaybarMoved [boolean] Command variable. Internal variable. According to Captivate documentation, "Set to 1 if the playbar has moved."
cpCmndShowPlaybar [number] Command variable. Setting to 1 will cause the movie’s playbar to appear. Setting to 0 will make the palybar disappear.
cpCmndVolume [number] Command variable. Setting to a number will cause the volume to change. The volume ranges from 0 (muted) to 100 (maximum volume).
cpContentLoadStart [boolean]

Informational variable. Indicates whether the main project SWF has started.

NOTE: This value can only be obtained when the project uses an external skin.

cpContentLoaded [boolean]

Informational variable. Indicates whether the main project SWF has loaded.

NOTE: This value can only be obtained when the project uses an external skin.

cpContentPositioned Internal variable. No information available.
cpContentScaled Internal variable. No information available.
cpHasSkinSWF [boolean] Informational variable. Indicates whether the Captivate project uses an external skin.
cpInfoAuthor [string] Informational variable. Returns the project author’s name, as entered in the movie’s properties before publishing.
cpInfoCompany [string] Informational variable. Returns the project company’s name, as entered in the movie’s properties before publishing.
cpInfoCopyright [number] Informational variable. Returns the project’s copyright notice, as entered in the movie’s properties before publishing.
cpInfoCourseID [number] Informational variable. Returns the project’s course ID, as entered in the movie’s properties before publishing.
cpInfoCourseName [string] Informational variable. Returns the project’s course name, as entered in the movie’s properties before publishing.
cpInfoCurrentDate [string] Informational variable. Returns the day portion of the current date.
cpInfoCurrentDateString [string] Informational variable. Returns today’s date (US English format).
cpInfoCurrentDay [string] Informational variable. Returns number indicating day of week (1 = Sunday, 2 = Monday, etc.)
cpInfoCurrentHour [string] Informational variable. Returns the current hour (24 hour clock format).
cpInfoCurrentMinutes [string] Informational variable. Returns the minutes portion of the current time.
cpInfoCurrentMonth [string] Informational variable. Returns the month portion of the current date.
cpInfoCurrentSlide [number] Informational variable. Returns the current slide number. (Uses 1-based index)
cpInfoCurrentSlideLabel [string] Informational variable. Returns the slide label for the current slide, if available.
cpInfoCurrentSlideType [string] Informational variable. Returns the slide type for the current slide.
cpInfoCurrentTime [string] Informational variable. Returns the current time, including seconds (24 hour clock format).
cpInfoCurrentYear [string] Informational variable. Returns the year portion of the current date.
cpInfoDescription [string] Informational variable. Returns the project’s description, as entered in the movie’s properties before publishing.
cpInfoElapsedTimeMS [number] Informational variable. Returns the amount of time (in milliseconds) that has elapsed since the project began playing.
cpInfoEmail [string] Informational variable. Returns the project author’s e-mail address, as entered in the movie’s properties before publishing.
cpInfoEpochMS [number] Informational variable. Returns the current time elapsed (in milliseconds) since January 01, 1970.
cpInfoHasPlaybar [number] Informational variable. Indcates whether the Captivate movie has a playbar. 1=true, 0=false
cpInfoIsStandalone [number] Informational variable. Indicates whether Captivate project is en .exe or .app file (1) or standard SWF (0).
cpInfoLastVisitedSlide [number] Informational variable. Returns the last visited slide number. (Unlike cpInfoCurrentSlide, this variable uses 0-based index)
cpInfoPercentage [number] Informational variable. Returns the current score as a percentage (if available).
cpInfoPrevSlide [number] Informational variable. Returns the number of the slide before the current slide. (Uses 1-based index)
cpInfoProjectName [string] Informational variable. Returns the project’s name, as entered in the movie’s properties before publishing.
cpInfoWebsite [string] Informational variable. Returns the project’s web addess, as entered in the movie’s properties before publishing.
cpLockTOC [number] Command variable. Setting to 1 disables user interaction on the Table of Contents. Setting to 0 re-enables (unlocks) user interaction.
cpMovieHeight [number] Informational variable. Returns the height of the Captivate project, in pixels.
cpMovieWidth [number] Informational variable. Returns the width of the Captivate project, in pixels.
cpMovieXForEmbededPlaybar [number] Informational variable. Returns the x coordinate (left position) of the Captivate project’s toolbar, if available.
cpMovieXForTOC [number] Informational variable. Returns the x coordinate (left position) of the Captivate project’s Table of Contents movieclip, if available.
cpMovieYForEmbededPlaybar [number] Informational variable. Returns the y coordinate (top position) of the Captivate project’s toolbar, if available.
cpMovieYForTOC [number] Informational variable. Returns the y coordinate (top position) of the Captivate project’s Table of Contents movieclip, if available.
cpOrgSWFPath [string]

Informational variable. Provides the file name for the project’s main SWF. Appears to duplicate functionality of cpOrgSWFPath.

NOTE: This value can only be obtained when the project uses an external skin.

cpQuizInfoAnswerChoice [string] Informational variable. Returns the chosen answer for the quiz question.
cpQuizInfoAttempts [number] Informational variable. Returns the number of times the quiz has been attempted.
cpQuizInfoLastSlidePointScored [number] Informational variable. Returns the score for the last visited quiz slide.
cpQuizInfoMaxAttemptsOnCurrentQuestion [number] Informational variable. Returns the number of attempts allowed for this quiz question.
cpQuizInfoNoQuestionsPerQuiz Informational variable. No information available. Best guess: returns the number of questions in the quiz.
cpQuizInfoPassFail [number] Informational variable. Returns the result of the quiz: pass or fail.
cpQuizInfoPointsPerQuestionSlide [number] Informational variable. Returns the number of points for this quiz question.
cpQuizInfoPointsscored [number] Informational variable. Returns the total number of points scored in the project.
cpQuizInfoQuestionSlideTiming [number] Informational variable. Returns the time limit for the current question (in seconds).
cpQuizInfoQuestionSlideType [string] Informational variable. Returns the current question’s type (multiple-choice, true-false, likert, etc.).
cpQuizInfoQuizPassPercent [number] Informational variable. Returns the passing percentage for the quiz.
cpQuizInfoQuizPassPoints [number] Informational variable. Returns the passing points for the quiz.
cpQuizInfoTotalCorrectAnswers [number] Informational variable. Returns the number of correctly answered quiz questions.
cpQuizInfoTotalProjectPoints [number] Informational variable. Returns the total number of points for the project.
cpQuizInfoTotalQuestionsPerProject [number] Informational variable. Returns the total number of questions for the project.
cpQuizInfoTotalQuizPoints [number] Informational variable. Returns the total number of quiz points for the project.
cpQuizInfoTotalUnansweredQuestions [number] Informational variable. Returns the total number of unanswered questions for the project.
endSwfAction [number] Internal variable. No information available.
expired [boolean] Internal variable. No information available. Best guess: Boolean indicating whether time limit has elapsed.
hasProjectFadeOut [boolean] Internal variable. No information available. Best guess: Boolean indicating whether last slide in project is set to fade out.
inAutoPlayState [boolean] Internal variable. No information available. Best guess: Boolean indicating whether project is set to auto-play.
isCPMovie [boolean] Informational variable. Indicates whether the SWF is a Captivate SWF.
isContiniousModeRecording [number] Internal variable. No information available. (Yes, that’s how it was spelled in the code.)
isCustomizable [boolean]

Internal variable. No information available. Best guess: Indicates whether the skin is customizable.

NOTE: This value can only be obtained when the project uses an external skin.

isForceMuteAudio [boolean] Internal variable. No information available. Best guess: Indicates whether the audio was muted by the user.
isPlayBarBtnClicked [boolean] Internal variable. No information available. Best guess: Indicates whether a specific action was performed via clicking the playbar (such as muting audio).
isPreview [number] Internal variable. No information available. Best guess: Indicates whether the SWF is a preview SWF (used when previewing projects within the Captivate authoring environment).
isPreviewForAudioDialog [boolean] Internal variable. No information available. Best guess: Indicates whether the SWF is a preview SWF (used when previewing projects within the Captivate authoring environment).
isPreviewSkin [boolean] Internal variable. No information available. Best guess: Indicates whether the project SWF’s skin is a preview SWF (used when previewing projects within the Captivate authoring environment).
lmsString [string] Internal variable. No information available. Best guess: The text displayed when Captivate initializes an LMS connection (SCORM, AICC, etc.).
loadedFromAggregator [boolean] Internal variable. No information available. Best guess: Indicates whether the Captivate SWF was loaded as part of an aggregator project.
m_quizPoolColl [object] Internal variable. No information available. Best guess: Object containing question pool questions.
movieQuality [string] Internal variable. No information available. Best guess: Indicates quality setting of SWF playback.

movieXML

[string] in Chrome

[XML] in Firefox

Internal variable, no information available.

NOTE: This item is
:XML data type in AS3. Because browsers have different support for native XML data types, values returned from this variable should not be considered cross-browser. Use at your own risk.

needToMuteAudioForAggregator [boolean]

Internal variable. No information available.

NOTE: This value can only be obtained when the project uses an external skin.

passwordPresent [boolean] Internal variable. Indicates whether a password has been supplied.
pbcBtnTips [object] Internal variable. Alias for pbcBtnTips_ENU.
pbcBtnTips_ENU [object] Internal variable (array). Returns list of tooltips used by the playbar buttons.
playbarBarAlign [number]

Internal variable. No information available.

NOTE: This value can only be obtained when the project uses an external skin.

playbarHeight [number] Informational variable. Returns height of playbar, in pixels.
playbarPosition [number]

Internal variable. No information available.

NOTE: This value can only be obtained when the project uses an external skin.

rdIsInLivePreviewMode [boolean] Internal variable. No information available. Best guess: Indicates whether the SWF is a preview SWF (used when previewing projects within the Captivate authoring environment).
rdIsPreview [boolean] Internal variable. No information available. Best guess: Deprecated variable replaced by isPreview
rdIsPreviewInBrowser [boolean] Internal variable. No information available.
rdIsStandalone [boolean] Internal variable. No information available. Best guess: Deprecated variable replaced by cpInfoIsStandalone
rdcmndCC [number] Command variable (deprecated). Alias for cpCmndCC.
rdcmndExit [number] Command variable. According to Captivate documentation, "Exit the movie. Set to 1 to exit." Has never worked for me.
rdcmndGotoFrame [number] Command variable (deprecated). Alias for cpCmndGotoFrame.
rdcmndGotoFrameAndResume [number] Command variable (deprecated). Alias for cpCmndGotoFrameAndResume.
rdcmndGotoSlide [number] Command variable (deprecated). Alias for cpCmndGotoSlide.
rdcmndMute [boolean] Command variable (deprecated). Alias for cpCmndMute.
rdcmndNext [boolean] Command variable (deprecated). Alias for cpCmndNext.
rdcmndNextSlide [number] Command variable (deprecated). Alias for cpCmndNext.
rdcmndPause [number] Command variable. Setting to 1 will cause the movie to stop playing (pause). Setting to 0 will do nothing.
rdcmndPlaybarMoved [boolean] Command variable (deprecated). Alias for cpCmndPlaybarMoved.
rdcmndPrevious [number] Command variable. Setting to 1 will cause the movie to stop playing (pause). Setting to 0 will do nothing.
rdcmndResume [number] Command variable. Setting to 1 will cause the movie to go backwards to the previous slide. Setting to 0 will do nothing.
rdinfoCurrentFrame [number] Informational variable. Returns current frame number using 0-based index.
rdinfoCurrentSlide [number] Informational variable (deprecated). Alias for cpInfoCurrentSlide.
rdinfoCurrentSlideInProject [number] Informational variable. No information available. Best guess: Alias for cpInfoCurrentSlide.
rdinfoFPS [number] Informational variable. Returns the SWF’s frame rate (in seconds).
rdinfoFrameCount [number] Informational variable. Returns the number of frames in the SWF.
rdinfoHasPlaybar [boolean] Informational variable (deprecated). Alias for cpInfoHasPlaybar.
rdinfoSlideCount [number] Informational variable. Returns the number of slides in the Captivate movie.
rdinfoSlidesInProject [number] Informational variable. No information available. Best guess: An unused/deprecated variable.
rdinfocurrFrame [number] Informational variable. No information available. Best guess: Alias for rdinfoCurrentFrame.
skinHeight [number]

Internal variable. No information available.

NOTE: This value can only be obtained when the project uses an external skin.

skinWidth [number]

Internal variable. No information available.

NOTE: This value can only be obtained when the project uses an external skin.

swfCmtAutoPlay [boolean] Internal variable. No information available. Best guess: Indicates whether the SWF will auto-play when in commenting mode.
swfCommenting [boolean] Internal variable. No information available. Best guess: Indicates whether the SWF is in commenting mode.
tocInitDone [boolean] Internal variable. Indicates when the Table of Contents has finished initializing.
waitCount [number] Internal variable. Indicates how long the SWF has been waiting (used for internal timer-related functions).