(Perhaps) Unexpected Point of View:  SWF Defers to HTML

ActionScript 2.0 Flash

Ever aiming for a small SWF footprint, I often load external assets at runtime.  This includes FLVs, MP3s, XML, sometimes CSS, and frequently images (which even includes PNG — woo hoo! — since the release of Flash Player 8).  As often as not, I use a relative path to specify the location of an asset.  This means the resolution of that path depends on its position in relation to the SWF itself.  For example, with something like  mc.loadMovie("external.jpg");, it only makes sense that the SWF with this ActionScript must reside in the same folder as the JPG it loads.  Why?  Because no absolute path to the JPG is provided — how would the SWF possibly know where else to look, other than its own folder?

If the SWF was in one folder and the JPG in another, you’d have to provide a path to that location.  For example, if the SWF was inside a folder named swf and the JPG was inside a subfolder of the first — say, swf/images — you would have to specify mc.loadMovie("images/external.jpg");.  The SWF would interpret that as, “Okay, start from where I am; now, look for a folder named ‘images,’ then look for external.jpg.”  If the images folder was side-by-side with the swf folder, the relative path would instead be mc.loadMovie("../images/external.jpg");; that is, “Ah, back up one folder [that’s what the .. means], then look for a folder named ‘images,” then look for external.jpg.”  All of this should be pretty straightforward, and it always works when the HTML document is also in the same folder as the SWF.  But there’s the rub:  what happens if it isn’t? 

This may be counter intuitive, but a SWF’s point of view is not its own when embedded in an HTML document.  When embedded, the SWF’s point of view is that of the HTML document itself.

Let’s look at an illustration.  Suppose you have an HTML document in the root of your site.  This document embeds a SWF contained in a subfolder of the root.  (I like to do this, for example, to separate my HTML files from my SWFs; I do the same with images.)  If the SWF references a JPG from the point of view of itself (such as the same folder as itself, without a path reference, as above), the JPG will not load when the SWF is tested from the HTML document.

To restate:  HTML is in the root; SWF and JPG are in the same subfolder, which is a subfolder of the root.  SWF references JPG without a path, or with a relative path that relies on the SWF as its point of reference.  JPG will load when you run the SWF on its own, but will not load when you run the SWF from the HTML.

Why?  Because the ActionScript says mc.loadMovie("external.jpg");, and remember, the point of view is now that of the HTML document, so the SWF will look “through the eyes” of the HTML document in order to locate that JPG.

You could bypass this trouble altogether by using an absolute path, such as …

mc.loadMovie("http://www.domain.com/images/external.jpg");

… but that means you’d have to upload your JPG to the server in order to test your ActionScript.  You could alternatively get fancy and let the SWF determine whether or not it’s playing in a browser.  The System.capabilities object comes in handy here …

if (System.capabilities.isDebugger) {
  this.loadMovie("external.jpg");
} else {
  this.loadMovie("images/external.jpg");
}

… but that may be overkill in this context.

You could, of course, just be aware of the issue and make your own best judgment.  ;)   For you, that may mean keeping all three files in the same place, putting the JPG in both locations, or … heck, it’s up to you.

Update!

Note:  As recounted in Unexpected ”Gotcha“ with Relative Paths in ActionScript, I discovered the above holds true except for Flash video files (FLV).

Leave a Reply