Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

advancing ...

  • Loading branch information...
commit bc5e9c45689ab220c5bee380c00e1a70107fc20f 1 parent c204d63
Doru Moisa authored
Showing with 328 additions and 0 deletions.
  1. +90 −0 src/Class.js
  2. +238 −0 tests/spec/ClassSpec.js
View
90 src/Class.js
@@ -0,0 +1,90 @@
+var O2 = O2 || {};
+O2.Super = function(obj, args){
+ var argsArray = Array.prototype.slice.call(args),
+ crt = args.callee,
+ crtName,
+ undef;
+
+ // do nothing on static methods
+ if(crt.superclass) return undef;
+
+ // if super previously cached, call it
+ if(typeof crt.__super__ == 'function') {
+ return crt.__super__.apply(obj, argsArray);
+ }
+
+ // super constructor check
+ if(obj.constructor == crt && typeof obj.constructor.superclass == 'function') {
+ crt.__super__ = obj.constructor.superclass;
+ return crt.superclass.apply(obj, argsArray);
+ }
+
+ // find super method, if exists
+ for(var p in obj.constructor.prototype){
+ if(obj.constructor.prototype[p] == crt) {
+ crtName = p;
+ break;
+ }
+ }
+
+ // if not found, quit
+ if(!crtName) return undef;
+
+ // finally, if super method exists, call it
+ if(typeof obj.constructor.superclass.prototype[crtName] == 'function'){
+ crt.__super__ = obj.constructor.superclass.prototype[crtName];
+ return crt.__super__.apply(obj, argsArray);
+ }
+
+ return undef;
+};
+
+O2.Class = function(c, p){
+
+ // type checks: only accept functions || undefined
+ var tc = typeof c,
+ tp = typeof p;
+
+ if(tc != 'function' && tc != 'undefined'){
+ throw new TypeError('Illegal argument #0: [' + tc + ']');
+ }
+ if(tp != 'function' && tp != 'undefined'){
+ throw new TypeError('Illegal argument #1: [' + tp + ']');
+ }
+
+ if(!c) c = function(){};
+ if(p){
+ var s = function(){};
+ s.prototype = p.prototype;
+ var proto = new s;
+
+ //copy existing prototype members to the new prototype;
+ for(var oldp in c.prototype){
+ if(oldp == 'constructor') continue;
+ if(typeof proto[oldp] == 'undefined') {
+ proto[oldp] = c.prototype[oldp];
+ }
+ }
+
+ c.prototype = proto;
+ c.prototype.constructor = c;
+ }
+
+ // clear Super() caches, we have an inheritance override
+ if(c.superclass){
+ var crt, n;
+ for(n in c.prototype){
+ crt = c.prototype[n];
+ if(typeof crt == 'function' && crt.__super__) {
+ delete crt.__super__;
+ }
+ }
+ }
+
+ // we need this for Super() calls
+ c.superclass = p;
+
+ return c;
+}
+
+
View
238 tests/spec/ClassSpec.js
@@ -1,3 +1,241 @@
+/*******
+
+var O2 = O2 || {};
+O2.Super = function(obj, args){
+ var argsArray = Array.prototype.slice.call(args),
+ crt = args.callee,
+ crtName,
+ undef;
+
+ // do nothing on static methods
+ if(crt.superclass) return undef;
+
+ // if super previously cached, call it
+ if(typeof crt.__super__ == 'function') {
+ return crt.__super__.apply(obj, argsArray);
+ }
+
+ // super constructor check
+ if(obj.constructor == crt && typeof obj.constructor.superclass == 'function') {
+ crt.__super__ = obj.constructor.superclass;
+ return crt.superclass.apply(obj, argsArray);
+ }
+
+ // find super method, if exists
+ for(var p in obj.constructor.prototype){
+ if(obj.constructor.prototype[p] == crt) {
+ crtName = p;
+ break;
+ }
+ }
+
+ // if not found, quit
+ if(!crtName) return undef;
+
+ // finally, if super method exists, call it
+ if(typeof obj.constructor.superclass.prototype[crtName] == 'function'){
+ crt.__super__ = obj.constructor.superclass.prototype[crtName];
+ return crt.__super__.apply(obj, argsArray);
+ }
+
+ return undef;
+};
+
+O2.Class = function(c, p){
+
+ // type checks: only accept functions || undefined
+ var tc = typeof c,
+ tp = typeof p,
+ undef;
+
+ if(tc != 'function' && tc != 'undefined'){
+ throw new TypeError('Illegal argument #0: [' + tc + ']');
+ }
+ if(tp != 'function' && tp != 'undefined'){
+ throw new TypeError('Illegal argument #1: [' + tp + ']');
+ }
+
+ if(!c) c = function(){};
+ if(p){
+ var s = function(){};
+ s.prototype = p.prototype;
+ var proto = new s;
+
+ //copy existing prototype members to the new prototype;
+ for(var oldp in c.prototype){
+ if(oldp == 'constructor' || oldp == 'superclass') continue;
+ if(typeof proto[oldp] == 'undefined') {
+ proto[oldp] = c.prototype[oldp];
+ }
+ }
+
+ c.prototype = proto;
+ c.prototype.constructor = c;
+ }
+
+ // clear Super() caches, we have an inheritance override
+ if(c.superclass != undef){
+ var crt, n;
+
+ for(n in c.prototype){
+ crt = c.prototype[n];
+ if(typeof crt == 'function' && crt.__super__) {
+ delete crt.__super__;
+ }
+ }
+ }
+
+ // we need this for Super() calls
+ console.error('!!!!');
+ console.debug(p);
+ c.superclass = p;
+
+ return c;
+}
+
+//////////////////////////////////////////////////////////////////
+var Base = O2.Class(function(){});
+Base.toString = function(){return 'Base()';};
+Base.prototype.x = 0;
+Base.prototype.foo = function(){
+ console.info('Base.foo()');
+ this.x++;
+};
+Base.bar = function(){ console.info('Base::bar()'); }
+
+//////////////////////////////////////////////////////////////////
+var Child = O2.Class(function(){
+ O2.Super(this, arguments);
+ console.info('Child()');
+}, Base);
+Child.bar = function(){ console.info('Child::bar()'); O2.Super(this, arguments); }
+
+Child.prototype.foo = function(){
+ console.info('Child.foo()');
+ O2.Super(this, arguments);
+ this.x++;
+}
+
+var x = new Child;
+x.foo();
+//Child.bar();
+
+//////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////
+var Base2 = O2.Class(function(){});
+Base.toString = function(){return 'Base2()';};
+Base2.prototype.y = 0;
+Base2.prototype.foo = function(){
+ console.info('Base2.foo()');
+ this.x+=10;
+};
+Base2.bar2 = function(){ console.info('Base2::bar()'); }
+Base2.prototype.foo2 = function(){
+ console.info('Base2.foo2()');
+ this.y++;
+};
+
+//////////////////////////////////////////////////////////////////
+// nasty stuff ahead:
+Child = O2.Class(Child, Base2);
+Child.prototype.foo2 = function(){
+ console.info('Child.foo2() 2');
+ O2.Super(this, arguments);
+ this.y++;
+}
+
+var y = new Child;
+y.foo();
+y.foo2();
+console.dir(y);
+
+
+x.foo();
+console.dir(x);
+
+Child = O2.Class(Child, Base);
+var z = new Child;
+z.foo();
+console.dir(z);
+
+Child.bar();
+console.log(Child.superclass);
+//console.dir(Base);
+//Base.toString();
+
+console.log('===');
+var a = new Child();
+a.foo();
+console.dir(a);
+console.log(a.foo.toSource());
+
+
+ **********/
+/*
+
+//////////////////////////////////////////////////////////////////
+var Base = O2.Class(function(){});
+Base.prototype.x = 0;
+Base.prototype.foo = function(){
+ console.info('Base.foo()');
+ this.x++;
+};
+
+
+//////////////////////////////////////////////////////////////////
+var Child = O2.Class(function(){
+ O2.Super(this, arguments);
+ console.info('Child()');
+}, Base);
+
+Child.prototype.foo = function(){
+ console.info('Child.foo()');
+ O2.Super(this, arguments);
+ this.x++;
+}
+
+var x = new Child;
+x.foo();
+//////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////
+var Base2 = O2.Class(function(){});
+Base2.prototype.y = 0;
+Base2.prototype.foo = function(){
+ console.info('Base2.foo()');
+ this.x+=10;
+};
+Base2.prototype.foo2 = function(){
+ console.info('Base2.foo2()');
+ this.y++;
+};
+
+//////////////////////////////////////////////////////////////////
+// nasty stuff ahead:
+Child = O2.Class(Child, Base2);
+Child.prototype.foo2 = function(){
+ console.info('Child.foo2() 2');
+ O2.Super(this, arguments);
+ this.y++;
+}
+
+var y = new Child;
+y.foo();
+y.foo2();
+console.dir(y);
+
+
+x.foo();
+console.dir(x);
+
+Child = O2.Class(Child, Base);
+var z = new Child;
+z.foo();
+console.dir(z);
+
+*/
+
describe("Class specs", function(){
it("return true", function(){
Please sign in to comment.
Something went wrong with that request. Please try again.