Here’s a larger part of the bigger project of which I shared a smaller part a few days ago. I seemed to be doing a lot with the source paths (neé class paths), and decided to write a SourcePath class.

I don’t usually bother with classes in JSFL, as Object-Oriented JavaScript is, in my opinion, pretty painful. However, I needed this functionality in a few different scripts and went with a class as being the easiest way to share and encapsulate functionality.

Here’s a link to the documentation (created by making a stub ActionScript class and running it through asdoc). The basic functions are convenience functions. You can get the source paths as an Array of individual paths (as opposed to the normal semi-colon-separated String), you can get all source paths available to the document (both the document’s source paths combined with the application preference source paths), and you can add or remove paths more easily.

The money function is that you can get all of the paths as file URIs if desired. Assuming your working document is saved, relative source paths will get resolved to relative to the Flash document.

Here’s the class (available here, as well):

/**
 * Provides utility methods and easy access to the source paths available to a given document.
 * A SourcePath, when created, is associated with a specific Flash document.  A given SourcePath
 * object will always hold that document reference.
**/

/**
 * Creates a new SourcePath object.
 * @param	document	The document to associate with this SourcePath object.  If null, will use the currently
 * 						focused document.
**/

function SourcePath(doc) {

	if (!doc) doc = fl.getDocumentDOM();
	this.doc = doc;

	// PRIVATE
	function getFlaDir() {
		var flaPath    = that.doc.pathURI;
		if (!flaPath) return null;

		var flaPieces  = flaPath.split("/");
		flaPieces.pop()
		// This removes the hard drive name from the URI on the Mac
		flaPieces.splice(3, 1);
		var flaDir     = flaPieces.join("/");
		return flaDir;
	}

	var that = this;

	this.flaDir = getFlaDir();

	/**
	 * Gets an Array of Strings defining source paths set in the target document.
	**/
	this.__defineGetter__("docPaths", function(){
		return this.doc.sourcePath.split(";");
	});

	/**
	 * Gets an Array of Strings defining source paths set in the Flash preferences.
	**/
	this.__defineGetter__("appPaths", function(){
		return fl.sourcePath.split(";");
	});

	/**
	 * Gets an Array of Strings defining all source paths available to the current document, both those
	 * defined in the document and in the Flash preferences, in that order.
	**/
	this.__defineGetter__("paths", function(){
		var allPaths = this.doc.sourcePath + ";" + fl.sourcePath;
	 	return allPaths.split(";");
	});

	/**
	 * Returns an Array of Strings defining the source paths, as URIs, set in the target document.
	**/
	this.__defineGetter__("docPathsURI", function() {
		return this.__makeURIList(this.docPaths);
	});

	/**
	 * Gets an Array of Strings defining source paths, as URIs, set in the Flash preferences.
	**/
	this.__defineGetter__("appPathsURI", function() {
		return this.__makeURIList(this.appPaths);
	});

	/**
	 * Gets an Array of Strings defining all source paths available to the current document, both those
	 * defined in the document and in the Flash preferences, in that order.  Source paths are evaluated
	 * as URIs.
	**/
	this.__defineGetter__("pathsURI", function() {
		return this.__makeURIList(this.paths);
	});

	// PRIVATE
	this.__makeURIList = function(pathList) {
		var pathsURI = [];
		var iLen = pathList.length;
		var URI;
		for (var i = 0; i  pathLength) at = pathLength;
		if (at < 0) at = 0;

		paths.splice(at, 0, path);
		this.doc.sourcePath = paths.join(";");
	}
	/**
	 * Removes a source path from the target document by the index.
	 * @param	at	The index of the path to remove.
	**/
	this.removeDocPathAt = function(at) {
		var paths = this.docPaths;
		paths.splice(at, 1);
		this.doc.sourcePath = paths.join(";");
	}
	/**
	 * Removes a source path from the target document by name.
	 * @param	path	The source path to remove.  If not found, no changes are made.
	**/
	this.removeDocPath = function(path) {
		var paths = this.docPaths;
		var iLen = paths.length;
		var p;
		for (var i = 0; i  pathLength) at = pathLength;
		if (at < 0) at = 0;

		paths.splice(at, 0, path);
		fl.sourcePath = paths.join(";");
	}
	/**
	 * Removes a source path from the Flash preferences by the index.
	 * @param	at	The index of the path to remove.
	**/
	this.removeAppPathAt = function(at) {
		var paths = this.appPaths;
		paths.splice(at, 1);
		fl.sourcePath = paths.join(";");
	}
	/**
	 * Removes a source path from the Flash preferences by name.
	 * @param	path	The source path to remove.  If not found, no changes are made.
	**/
	this.removeAppPath = function(path) {
		var paths = this.appPaths;
		var iLen = paths.length;
		var p;
		for (var i = 0; i < iLen; i++) {
			p = paths[i];
			if (p == path) {
				paths.splice(i, 1);
				break;
			}
		}
		fl.sourcePath = paths.join(";");
	}

	/**
	 * Takes a source path and returns an absolute URI equivalent.  Relative source paths are evaluated against the target
	 * document's location.
	 * @param	path	The soruce path to evaluate.
	 * @return	A file URI string.  If the input path is relative, the file URI will resolve according to the target document.
	 * 			If the target document is not saved, then a relative input path will return null.
	**/
	this.pathToURI = function(path) {
		//fl.trace("flaDir: " + flaDir);
		// If flaDir is null, then we can return URI if it's an absolute path; but otherwise we can't resolve the path
		// and it's of no use anyway, so we'll return null
		//fl.trace("test: " + evaluatePath(path, flaDir));
		return evaluatePath(path, this.flaDir);
	}

	// PRIVATE
	function evaluatePath(classPath, flaDir) {
		// Always remove the trailing slash, if present.  We'll add it back in later.
		classPath = classPath.replace(/\/$/, "");
		if (classPath == ".") {
			if (!flaDir) return null;
			// We're on the "." class path, just concatenate the Flash file directory with the class file path.
			tryPath = flaDir + "/";
		} else if (classPath.indexOf("..") == 0) {
			if (!flaDir) return null;
			// We have a relative path that goes "up" first, so we need to remove
			var cPathPieces = classPath.split("/");
			var jLen = cPathPieces.length;
			for (var j = 0; j < jLen; j++) {
				var piece = cPathPieces[j];
				if (piece != "..") break;
			}
			cPathPieces = cPathPieces.splice(j);
			var tmpFlaPieces = flaDir.split("/");
			tmpFlaPieces = tmpFlaPieces.splice(0, tmpFlaPieces.length-j);
			tryPath = tmpFlaPieces.join("/") + "/" + cPathPieces.join("/");
			if (tryPath.search(/\/$/) == -1) {
				tryPath += "/"
			}

		} else if (classPath.indexOf("/") == 0) {
			// We have an absolute class path, so just concatenate it to the class file path.
			if (classPath.search(/\/$/) == -1) {
				classPath += "/"
			}
			tryPath = "file://" + classPath;
		} else {
			// We can assume we have a relative path that does not go "up," e.g., a "classes" folder in the same folder as the FLA.
			classPath = classPath.replace(/^\.\//, "");
			tryPath = flaDir + "/" + classPath + "/";
		}
		return tryPath;

	}

}
Advertisement