2013-05-29 17:03:01 +00:00
|
|
|
var util = require('util');
|
2013-05-28 05:20:30 +00:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @param newClass
|
|
|
|
* @param baseClass
|
|
|
|
*/
|
2013-05-29 17:03:01 +00:00
|
|
|
exports.inherits = function (newClass, baseClass, options) {
|
|
|
|
util.inherits(newClass, baseClass);
|
|
|
|
|
|
|
|
options = options || {
|
|
|
|
staticProperties: true,
|
|
|
|
override: false
|
|
|
|
};
|
|
|
|
|
|
|
|
if (options.staticProperties) {
|
|
|
|
Object.keys(baseClass).forEach(function (classProp) {
|
|
|
|
if (classProp !== 'super_' && (!newClass.hasOwnProperty(classProp) || options.override)) {
|
|
|
|
var pd = Object.getOwnPropertyDescriptor(baseClass, classProp);
|
|
|
|
Object.defineProperty(newClass, classProp, pd);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2011-10-10 13:22:51 +00:00
|
|
|
};
|
|
|
|
|
2013-05-28 05:20:30 +00:00
|
|
|
|
|
|
|
/**
|
2013-10-02 05:14:21 +00:00
|
|
|
* Mix in the a class into the new class
|
|
|
|
* @param newClass The target class to receive the mixin
|
|
|
|
* @param mixinClass The class to be mixed in
|
2013-05-28 05:20:30 +00:00
|
|
|
* @param options
|
|
|
|
*/
|
2013-10-02 05:14:21 +00:00
|
|
|
exports.mixin = function (newClass, mixinClass, options) {
|
|
|
|
if (Array.isArray(newClass._mixins)) {
|
|
|
|
if(newClass._mixins.indexOf(mixinClass) !== -1) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
newClass._mixins.push(mixinClass);
|
|
|
|
} else {
|
|
|
|
newClass._mixins = [mixinClass];
|
|
|
|
}
|
|
|
|
|
2013-05-28 05:20:30 +00:00
|
|
|
options = options || {
|
|
|
|
staticProperties: true,
|
|
|
|
instanceProperties: true,
|
2013-12-04 21:44:25 +00:00
|
|
|
override: false,
|
|
|
|
proxyFunctions: false
|
2013-05-28 05:20:30 +00:00
|
|
|
};
|
|
|
|
|
2013-12-04 21:44:25 +00:00
|
|
|
if(options.staticProperties === undefined) {
|
|
|
|
options.staticProperties = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(options.instanceProperties === undefined) {
|
|
|
|
options.instanceProperties = true;
|
|
|
|
}
|
|
|
|
|
2013-05-28 05:20:30 +00:00
|
|
|
if (options.staticProperties) {
|
2013-10-02 05:14:21 +00:00
|
|
|
Object.keys(mixinClass).forEach(function (classProp) {
|
|
|
|
if (classProp !== 'super_' && classProp !== '_mixins' && (!newClass.hasOwnProperty(classProp) || options.override)) {
|
|
|
|
var pd = Object.getOwnPropertyDescriptor(mixinClass, classProp);
|
2013-12-04 21:44:25 +00:00
|
|
|
if(options.proxyFunctions && pd.writable && typeof pd.value === 'function') {
|
2013-12-04 05:14:12 +00:00
|
|
|
pd.value = exports.proxy(pd.value);
|
|
|
|
}
|
2013-05-28 20:50:59 +00:00
|
|
|
Object.defineProperty(newClass, classProp, pd);
|
2013-05-28 05:20:30 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
if (options.instanceProperties) {
|
2013-10-02 05:14:21 +00:00
|
|
|
if (mixinClass.prototype) {
|
|
|
|
Object.keys(mixinClass.prototype).forEach(function (instanceProp) {
|
2013-10-12 01:37:45 +00:00
|
|
|
if (!newClass.prototype.hasOwnProperty(instanceProp) || options.override) {
|
2013-10-02 05:14:21 +00:00
|
|
|
var pd = Object.getOwnPropertyDescriptor(mixinClass.prototype, instanceProp);
|
2013-12-04 21:44:25 +00:00
|
|
|
if(options.proxyFunctions && pd.writable && typeof pd.value === 'function') {
|
2013-12-04 05:14:12 +00:00
|
|
|
pd.value = exports.proxy(pd.value);
|
|
|
|
}
|
2013-05-28 20:50:59 +00:00
|
|
|
Object.defineProperty(newClass.prototype, instanceProp, pd);
|
|
|
|
}
|
2013-05-28 05:20:30 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-28 20:50:59 +00:00
|
|
|
return newClass;
|
2013-05-28 05:20:30 +00:00
|
|
|
};
|
|
|
|
|
2013-12-04 05:14:12 +00:00
|
|
|
exports.proxy = function(fn) {
|
|
|
|
var f = function() {
|
|
|
|
return fn.apply(this, arguments);
|
|
|
|
};
|
|
|
|
Object.keys(fn).forEach(function(x) {
|
|
|
|
f[x] = fn[x];
|
|
|
|
});
|
|
|
|
return f;
|
|
|
|
};
|
|
|
|
|