/**
* I'm not sure how this differs from classmanager or which came first.
*
* I'm guessing this came first
*/
function JSClass(declaration, closure) {
if (JSClass.processor.verify(declaration,closure)!==true)return;
JSClass.processor.addToWindow(declaration,closure);
}
JSClass.processor = {
staticDomId: 0,
allObjects: [],
getClassName: function(declaration){
//assumes that declaration has been verified
if (declaration.indexOf("extends") != -1) {
var parts = declaration.split("extends");
className = parts[0].trim();
} else {
className = declaration.trim();
}
return className;
},
getParentClassName: function(declaration){
//assumes that declaration has been verified
if (declaration.indexOf("extends") != -1) {
var parts = declaration.split("extends");
parentClassName = parts[1].trim();
return parentClassName;
} else {
return null;
}
},
verify: function(declaration, closure) {
var errorNotice = "\nProblem declaration is '" + declaration + "'. \n";
var errorTips =
"Proper declaration is JSClass('MyClass',function(){BODY}). \n" +
"To extend, try JSClass('MyClass extends ParentClass',function(){BODY}).";
var className;
var parentClassName;
var functype = typeof function() {};
//set and derive the class name and parent class name, checking for syntax errors
//make sure the closure is a function
if (typeof closure != functype) {
console.log(
"closure must be a function. See JSClass(name,closure). " +
errorNotice +
errorTips
);
}
if (declaration.indexOf("extends") != -1) {
var parts = declaration.split("extends");
if (parts.length != 2) {
console.log(
"You can only declare one extends. " + errorNotice + errorTips
);
return false;
}
className = parts[0].trim();
parentClassName = parts[1].trim();
if (parentClassName.length < 1) {
console.log(
"If using 'extends', Parent Class Name must not be empty. " +
errorNotice +
errorTips
);
return false;
}
if (parentClassName.indexOf(" ") != -1) {
console.log(
"Parent class name must not contain any spaces. " +
errorNotice +
errorTips
);
return false;
}
} else {
className = declaration.trim();
}
if (className.length < 1) {
console.log("Class name cannot be empty. " + errorNotice + errorTips);
return false;
}
if (className.indexOf(" ") != -1) {
console.log(
"Class name must not contain any spaces. " + errorNotice + errorTips
);
return false;
}
//className and parentClassName are valid.
//parentClassName may be null, if not extending
return true;
},
addToWindow: function(declaration,closure){
var closureWrapper = function(){
JSClass.processor.allObjects.push(this);
JSClass.processor.instantiate.call(this,declaration,closure);
if ('construct' in this){
this.construct.apply(this,arguments);
}
};
this.applyStaticParamaters(declaration,closure,closureWrapper);
window[this.getClassName(declaration)] = closureWrapper;
},
applyStaticParamaters: function(declaration,closure,closureWrapper){
closure.prototype.static = {};
var obj = new closure();
for (var staticVar in obj.static){
closureWrapper[staticVar] = obj.static[staticVar];
}
return obj;
},
instantiate: function(declaration, closure){
//this refers to the object that is being created
closure.prototype.static = window[JSClass.processor.getClassName(declaration)];
closure.prototype.dom = {};
var parentName = JSClass.processor.getParentClassName(declaration);
if (parentName!=null){
JSClass.processor.extendClass.call(this,parentName);
}
closure.apply(this);//
// var obj = new closure();
// for (var propName in obj){
// this[propName] = obj[propName];
// }
},
extendClass: function(parentName){
if (!(parentName in window)){
console.log("Class '"+parentName+"' does not exist, so it cannot be extended.");
return;
}
window[parentName].apply(this);
var newObj = function(){};
this.parent = this;
window[parentName].apply(this.parent);
var funcType = typeof function(){};
for (var propName in this.parent){
if ((typeof this.parent[propName])!==funcType
&&propName in this
&&propName in this.parent){
console.log("overwrite "+propName);
this.parent[propName] = this[propName];
}
}
},
getElements: function(){
var nodeList = document.getElementsByClassName("jsclass");
var node;
var elements = [];
for (var i=0;i<nodeList.length;i++){
node = nodeList[i];
elements.push(node);
}
return elements;
},
getJSClassFromElement: function(element){
var classList = element.classList;
for (var z=0;z<classList.length;z++){
var classListName=classList[z];
if (classListName.indexOf("jsclass-")===0){
var className = classListName.substring(8);
if (!(className in window)){
console.log("Class '"+className+"' has not been declared in javascript");
return null;
}
return className;
}
}
},
attachClassToElement: function(element){
var className = JSClass.processor.getJSClassFromElement(element);
if (className===null){
console.log("Classname was null for element:");
console.log(element);
return;
}
if (!(className in window)){
console.log("class '"+className+"' does not exist.");
}
var obj = new window[className]();
obj.dom = element;
element.jsclass = obj;
obj.attach.call(obj,element);
},
attachClassesToDom: function(){
var elements = JSClass.processor.getElements();
for (var i=0; i<elements.length;i++){
var element = elements[i];
JSClass.processor.attachClassToElement(element);
}
},
setEventListener: function(){
if (window.readyState == "complete") {
JSClass.processor.attachClassesToDom();
} else if (window.addEventListener != null) {
document.addEventListener("DOMContentLoaded", function() {
if (document.readyState=="interactive"){
JSClass.processor.attachClassesToDom();
}
});
} else {
window.onload = function() {
JSClass.processor.attachClassesToDom();
};
}
}
};
JSClass.processor.setEventListener();