-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathns.js
157 lines (133 loc) · 4.71 KB
/
ns.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
(function(){
/* IE8 polyfill */
if(!Array.prototype.indexOf) {
Array.prototype.indexOf = function(searchElement) {
var len = this.length;
for(var i = 0; i< len; i++) {
var item = this[i];
if(item === searchElement)
return i;
}
return -1;
};
}
//"use strict"; <- causes error in browsers != Chrome
var DEFAULT_PROPS = ["length", "name", "arguments", "caller", "prototype"];
var Ns = initiator;
var nsList = [];
var inheritanceList = {};
function Namespace(namespace, reference) {
var scope = Ns;
var names = namespace.split("."),
i = 0,
len = names.length,
last = len - 1;
for(i; i<len; i++) {
var name = names[i];
if(!/^[A-Za-z]+$/.test(name)) {
throw new Error('Invalid character in namespace '+namespace);
}
if(i === last) {
if(reference) {
if(scope[name]) {
throw new Error('Selected namespace "'+namespace+'" already exist');
}
scope[name] = reference;
if(nsList.indexOf(namespace) === -1) {
nsList.push(namespace);
}
}
}
else {
if(i === 0) {
if (DEFAULT_PROPS.indexOf(name) !== -1) {
throw new Error('Cannot use reserved word: "' + name + '"');
}
}
if(typeof scope[name] === "function") {
throw new Error('Function cannot be used as a part of namespace: "'+name+'"');
}
scope[name] = scope[name] || {};
}
scope = scope[name];
}
return scope;
}
/*
* Based on John Resig's Simple JavaScript Inheritance http://ejohn.org/blog/simple-javascript-inheritance
*/
var initializing = false;
var fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
function extend(base, prop) {
var _super = base.prototype;
initializing = true;
var prototype = new base();
initializing = false;
for (var name in prop) {
prototype[name] = typeof prop[name] == 'function' &&
typeof _super[name] == "function" && fnTest.test(prop[name]) ?
(function(name, fn){
return function() {
var tmp = this._super;
this._super = _super[name];
var ret = fn.apply(this, arguments);
this._super = tmp;
return ret;
};
})(name, prop[name]) :
prop[name];
}
function Class() {
if ( !initializing && this.init )
this.init.apply(this, arguments);
}
Class.prototype = prototype;
Class.prototype.constructor = Class;
return Class;
}
function initiator(ns) {
if(!ns){
return {
"list" : nsList.sort(),
"getClasspath" : function(_ns) {
var list = [];
while(_ns = inheritanceList[_ns]) {
list.push(_ns);
}
return list.length ? list : null;
}
}
}
return {
"Class" : function(prop) {
var _new = extend(function(){}, prop);
return Namespace(ns, _new);
},
"extends": function(_ns){
var base = Namespace(_ns);
if(!base) {
throw new Error ('No such a class: "'+_ns+'" found');
}
if(Object.prototype.toString.call(base) === '[object Object]') { //if base is static
throw new Error ('Cannot extend static class');
}
return {
"Class": function(prop) {
var _new = extend(base, prop);
inheritanceList[ns] = _ns;
return Namespace(ns, _new);
}
}
},
"static" : {
"Class" : function(prop) {
if(Object.prototype.toString.call(prop) !== '[object Object]') {
throw new Error('Static class must bye type of object');
}
return Namespace(ns, prop);
}
}
};
}
window._ns = Ns;
})();