The Problem
I don’t know about everyone else, but this has happened to me more times than I can count. For one reason or another, the link between document class and FLA gets lost. Maybe you moved the FLA file and now it can’t find the class path, or maybe you refactored your code and put the class in a new package, and forgot to update the FLA file.
Of course, when you ask Flash to verify your document class, it will tell you if it can’t find one. But that’s only if you ask. If you open up a file that had worked in the past, but now doesn’t, Flash won’t tell you. It will simply create the supposed class for you, as an empty MovieClip subclass, when you publish the file.
The solution
For some reason, this has happened to me enough that I gave it some thought, and have come up with a rudimentary way of asking Flash to check the validity of the document class for you. This involves a JSFL script that checks for the existence of a file, derived from the document class name and the various class paths available to that document. Most importantly, it registers an event listener for documentChanged, so this check will run any time you open up or switch to a different a Flash file.
The issue I’m facing right now is making it happen automatically; right now you have to execute the script, at which point the listener gets set up and you’re good to go, but you have to still execute the script. It would be nice to have it execute right away once Flash starts up. Seems like a WindowSWF or a Tool could accomplish that, but both of those would require that you have extension installed and open as part of your workspace.
The Important Things to Note
Please note these two important things:
- The script is Mac-only as written. This is easily fixed, all you have to do is update the
tmpFilePathvariable as appropriate. - The script depends on the SourcePath class. You can find out more about that in this post, and you may wish/need to update the first line of the script so that it loads the SourcePath class from the place where you’ve installed it. Oh, to have a more robust class management system with JSFL.
The Script
I banged this out pretty quick, because I’m supposed to be doing other things, so, there’s room for improvement. Here’s the source code (viewable and downloadable at this link, as well):
fl.runScript(fl.configURI + "Commands/lib/SourcePath.jsfl");
var tmpFilePath = "file:///tmp/docClassCheckerIds.txt";
if (FLfile.exists(tmpFilePath)) {
var contents = FLfile.read(tmpFilePath);
var lines = contents.split("\n");
var iLen = lines.length;
for (var i = 0; i < iLen; i++) {
var line = lines[i];
var pieces = line.split("=");
var eventType = pieces[0];
var eventId = pieces[1];
fl.removeEventListener(eventType, parseInt(eventId));
}
}
var changeId = fl.addEventListener("documentChanged", onDocumentOpened);
FLfile.write(tmpFilePath, "documentChanged=" + changeId);
function onDocumentOpened() {
fl.trace("Event happened.")
testForDocumentClass();
}
function testForDocumentClass() {
var doc = fl.getDocumentDOM();
if (!doc) return;
if (doc.asVersion < 3) return;
var documentClass = doc.docClass;
if (documentClass == "") return;
var source = new SourcePath();
var classPaths = source.pathsURI;
var iLen = classPaths.length;
var classPath;
var docClassPath = documentClass.replace(/\./g, "/") + ".as";
for (var i = 0; i < iLen; i++) {
classPath = classPaths[i];
if (FLfile.exists(classPath + docClassPath)) {
// We found a matching file, so no further action is required.
return;
}
}
// If we got here, we didn't break the loop on success, so we didn't find a Document Class.
alert("Couldn't find a document class called \""+documentClass+"\" for this document.");
}
testForDocumentClass();
The Geeky Discussion
If you’re interested in some of the details, the logic is pretty straightforward, thanks to the SourcePath class. The bulk of it involves just looping over all of the available source paths, concatenating that to a file-system version of the stated document class for the file, and checking to see if a file exists at that path. If we get just one match, then we’re good. If we have no matches, we throw up an alert box.
I spent a little extra time on the event management. Because I was afraid of accidentally running the script more than once in a session, I wanted to make sure we removed any previously existing event listeners. This was troublesome, however, thanks to the undocumented changes in how the event listener functions operate. See this post for more details.
My solution involved capturing the event IDs, and writing them to a temporary file. Then, if we can get the ids out of this file, we remove the event listener based on this id before we add it. That is, if the script is run a second time, we’ll clean up the events set in the first run. Kinda laborious, but at least it works. Otherwise, you run the risk of seeing that alert several times in a row.

Leave a comment
Comments feed for this article