Files
cappuccino/Objective-J/StaticResourceNode.js
T
2010-01-27 00:43:54 -08:00

378 lines
11 KiB
JavaScript

var FILE =
{
absolute: function(/*String*/ aPath)
{
aPath = FILE.normal(aPath);
if (FILE.isAbsolute(aPath))
return aPath;
return FILE.join(FILE.cwd(), aPath);
},
basename: function(/*String*/ aPath)
{
var components = FILE.split(FILE.normal(aPath));
return components[components.length - 1];
},
cwd: function()
{
return FILE.dirname(window.location.pathname);
},
normal: function(/*String*/ aPath)
{
if (!aPath)
return "";
var components = aPath.split("/"),
results = [],
index = 0,
count = components.length,
isRoot = aPath.charAt(0) === "/";
for (; index < count; ++index)
{
var component = components[index];
// These simply remain in the current directory.
if (component === "" || component === ".")
continue;
if (component !== "..")
{
results.push(component);
continue;
}
var resultsCount = results.length;
// If we have a valid previous component, "climb" it.
if (resultsCount > 0 && results[resultsCount - 1] !== "..")
results.pop();
// If we are at the beginning and this isn't a root listing,
// add it since it makes sense for relative paths.
else if (!isRoot && resultsCount < 0)
results.push(component);
}
return (isRoot ? "/" : "") + results.join("/");
},
dirname: function(/*String*/ aPath)
{
var components = FILE.split(FILE.normal(aPath));
return FILE.join.apply(FILE, components.slice(0, components.length - 1));
},
isAbsolute: function(/*String*/ aPath)
{
return aPath.charAt(0) === "/";
},
join: function()
{
return Array.prototype.join.apply(arguments, ["/"]);
},
split: function(/*String*/ aPath)
{
return FILE.normal(aPath).split("/");
}
}
StaticResourceNode.FileType = 0;
StaticResourceNode.DirectoryType = 1;
StaticResourceNode.NotFoundType = 2;
function StaticResourceNode(/*String*/ aName, /*StaticResourceNode*/ aParentNode, /*Type*/ aType, /*BOOL*/ isResolved)
{
this._parentNode = aParentNode;
this._rootNode = aParentNode ? aParentNode._rootNode : this;
this._eventDispatcher = new EventDispatcher(this);
this._name = aName;
this._isResolved = isResolved;
if (!aParentNode)
this._path = "/";
else if (aParentNode === this._rootNode)
this._path = "/" + aName;
else
this._path = aParentNode.path() + "/" + aName;
this._type = aType;
if (aParentNode)
aParentNode._childNodes[aName] = this;
if (aType === StaticResourceNode.DirectoryType)
this._childNodes = { };
else if (aType === StaticResourceNode.FileType)
{
this._contents = "";
if (!isResolved)
this.resolveAsFile();
}
}
StaticResourceNode.prototype.name = function()
{
return this._name;
}
StaticResourceNode.prototype.path = function()
{
return this._path;
}
StaticResourceNode.prototype.contents = function()
{
return this._contents;
}
StaticResourceNode.prototype.type = function()
{
return this._type;
}
StaticResourceNode.prototype.parentNode = function()
{
return this._parentNode;
}
StaticResourceNode.prototype.rootNode = function()
{
return this._rootNode;
}
StaticResourceNode.prototype.isResolved = function()
{
return this._isResolved;
}
function resolveStaticResourceNode(/*StaticResourceNode*/ aStaticResourceNode, /*BOOL*/ shouldDispatchEvent)
{
aStaticResourceNode._isResolved = YES;
if (shouldDispatchEvent)
aStaticResourceNode._eventDispatcher.dispatchEvent(
{
type:"resolve",
staticResourceNode:aStaticResourceNode
});
}
StaticResourceNode.prototype.write = function(/*String*/ aString)
{
this._contents += aString;
}
StaticResourceNode.prototype.resolveAsFile = function()
{console.log("NOW LOOKING FOR FILE!");
var self = this,
request = new HTTPRequest();
request.onsuccess = function()
{
self._type = StaticResourceNode.FileType;
self._contents = request.responseText();
resolveStaticResourceNode(self, YES);
}
request.onfailure = function()
{console.log("FIALE");
self._type = StaticResourceNode.NotFoundType;
resolveStaticResourceNode(self, YES);
}
request.open("GET", this.path(), true);
request.send("");
}
StaticResourceNode.prototype.resolveSubPath = function(/*String*/ aPath, /*Type*/ aType, /*Function*/ aCallback)
{
var components = FILE.split(FILE.normal(FILE.join(this.path(), aPath))),
index = this === this.rootNode() ? 1 : FILE.split(this.path()).length;
//console.log("request for " + FILE.normal(this.path() + "/" + aPath));
resolvePathComponents(this, aType, components, index, aCallback);
}
function resolvePathComponents(/*StaticResourceNode*/ startNode, /*Type*/aType, /*Array*/ components, /*Integer*/ index, /*Function*/ aCallback)
{
var count = components.length,
parentNode = startNode;
for (; index < count; ++index)
{
var name = components[index],
childNode = parentNode._childNodes[name];
//console.log(name + " of " + parentNode.name() + " " + (childNode && childNode.name()));
//console.log(parentNode._childNodes);
// + "(" + components + ")" + " " + index + "/" + count + ":" + (childNode && childNode.name()) +">" + (childNode ? 1:0) + " " + (childNode && childNode.isResolved()));
if (!childNode)
{
function continueResolution()
{
resolvePathComponents(parentNode, aType, components, index, aCallback);
}
if (index + 1 < count || aType === StaticResourceNode.DirectoryType)
{
var bundle = new Bundle(components.slice(0, index + 1).join("/"));
// Eat any errors.
bundle.onerror = function() { };
bundle.addEventListener("load", continueResolution);
bundle.addEventListener("error", continueResolution);
bundle.load(NO);
}
else
{
childNode = new StaticResourceNode(name, parentNode, StaticResourceNode.FileType, NO);
childNode.addEventListener("resolve", continueResolution);
}
return;
}
else if (childNode.isResolved())
{
// If we've already determined that this file doesn't exist...
if (childNode.isNotFound())
return aCallback(null, new Error("File not found: " + components.join("/")));
// If we have no more path components...
if (index + 1 >= count)
return aCallback(childNode);
// Make sure this is a directory
if (childNode.type() !== StaticResourceNode.DirectoryType)
return aCallback(null, new Error("File is not a directory: " + components.join("/")));
// Do nothing: simply allow the loop to progress to the next child.
}
// If this node is still being resolved, just wait and rerun this same method when it's ready.
else
{
childNode.addEventListener("resolve", continueResolution);
return;
}
parentNode = childNode;
}
}
StaticResourceNode.prototype.addEventListener = function(/*String*/ anEventName, /*Function*/ anEventListener)
{
this._eventDispatcher.addEventListener(anEventName, anEventListener);
}
StaticResourceNode.prototype.removeEventListener = function(/*String*/ anEventName, /*Function*/ anEventListener)
{
this._eventDispatcher.removeEventListener(anEventName, anEventListener);
}
StaticResourceNode.prototype.isNotFound = function()
{
return this.type() === StaticResourceNode.NotFoundType;
}
StaticResourceNode.prototype.toString = function(/*BOOL*/ includeNotFounds)
{
if (this.isNotFound())
return "<file not found: " + this.name() + ">";
var string = this.parentNode() ? this.name() : "/",
type = this.type();
if (type === StaticResourceNode.DirectoryType)
{
var childNodes = this._childNodes;
for (var name in childNodes)
if (childNodes.hasOwnProperty(name))
{
var childNode = childNodes[name];
if (includeNotFounds || !childNode.isNotFound())
string += "\n\t" + childNodes[name].toString(includeNotFounds).split('\n').join("\n\t");
}
}
return string;
}
StaticResourceNode.prototype.nodeAtSubPath = function(/*String*/ aPath, /*BOOL*/ shouldResolveAsDirectories)
{
aPath = FILE.normal(aPath);
var components = FILE.split(FILE.isAbsolute(aPath) ? aPath : FILE.join(this.path(), aPath)),
index = 1,
count = components.length,
parentNode = this.rootNode();
for (; index < count; ++index)
{
var name = components[index];
if (hasOwnProperty.apply(parentNode._childNodes, [name]))
parentNode = parentNode._childNodes[name];
else if (shouldResolveAsDirectories)
parentNode = new StaticResourceNode(name, parentNode, StaticResourceNode.DirectoryType, YES);
else
throw NULL;
}
return parentNode;
}
StaticResourceNode.resolveStandardNodeAtPath = function(/*String*/ aPath, /*Function*/ aCallback)
{
var includePaths = exports.includePaths(),
resolveStandardNodeAtPath = function(/*String*/ aPath, /*int*/ anIndex)
{
var searchPath = FILE.absolute(FILE.join(includePaths[anIndex], FILE.normal(aPath)));
if (searchPath.indexOf("CPObject.j") !== -1) console.log("WILL SEARCH IN: " + searchPath);
rootNode.resolveSubPath(searchPath, StaticResourceNode.FileType, function(/*StaticResourceNode*/ aStaticResourceNode)
{if (searchPath.indexOf("CPObject.j") !== -1) console.log("FOUND...: " + aStaticResourceNode);
if (!aStaticResourceNode)
{
if (anIndex + 1< includePaths.length)
resolveStandardNodeAtPath(aPath, anIndex + 1);
else
aCallback(NULL);
return;
}
aCallback(aStaticResourceNode);
});
};
resolveStandardNodeAtPath(aPath, 0);
}
exports.includePaths = function()
{
return global.OBJJ_INCLUDE_PATHS || ["Frameworks", "Frameworks/Debug"];
}