-
Notifications
You must be signed in to change notification settings - Fork 0
/
angular-base-class.js
100 lines (77 loc) · 3.5 KB
/
angular-base-class.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
// CommonJS package manager support
if (typeof module === 'object' && module.exports) {
module.exports = 'BaseClass';
}
angular.module('BaseClass', [])
.factory('BaseClass', function () {
'use strict';
var findObjectOfProperty = function (start, propName) {
while (true) {
if (!start) {
throw Error('Could not find property "' + propName + '"');
}
if (start.hasOwnProperty(propName)) {
return start;
}
start = Object.getPrototypeOf(start);
}
};
// BaseClass constructor
var BaseClass = function (attributes) {
if (!angular.isUndefined(attributes) && !angular.isObject(attributes)) {
throw Error('arguments provided to constructor must be a key/value pair object!');
}
angular.extend(this, attributes);
};
BaseClass.extend = function (properties) {
var Class = this,
SubClass;
if (angular.isObject(properties) && properties.hasOwnProperty('constructor')) {
SubClass = properties.constructor;
} else {
SubClass = function () {
return Class.apply(this, arguments);
};
}
SubClass.extend = Class.extend;
// Creates new Object based on Class prototype.
SubClass.prototype = Object.create(Class.prototype, {
constructor: { // Sets correct constructor on a SubClass prototype.
writable: true,
value: SubClass
},
_super: { // In case we need to access Class prototype from within a SubClass prototype.
value: function (method, args) {
var __super, previousSuper, start, superObject, returnValue;
__super = '__super__' + method;
previousSuper = this[__super];
start = Object.getPrototypeOf(
previousSuper ? previousSuper : findObjectOfProperty(this, method) // where is the current method?
);
superObject = findObjectOfProperty(start, method);
this[__super] = superObject;
args = (args && args.hasOwnProperty('length')) ? Array.prototype.slice.call(args) : [args];
returnValue = superObject[method].apply(this, args);
if (previousSuper) {
this[__super] = previousSuper;
} else {
delete this[__super];
}
return returnValue;
}
}
});
angular.extend(SubClass.prototype, properties); // Extends SubClass prototype with supplied properties.
if (Array.isArray(properties.mixins)) { // Add any mixin methods to SubClass prototype.
properties.mixins.forEach(function (mixin) {
for (var prop in mixin) {
if (angular.isFunction(mixin[prop]) && angular.isUndefined(SubClass.prototype[prop])) {
SubClass.prototype[prop] = mixin[prop];
}
}
});
}
return SubClass;
};
return BaseClass;
});