Refactor mixin and always redefine proxy/delegate methods

This commit is contained in:
Ritchie Martori 2014-02-20 17:25:07 -08:00
parent 38c7a16da2
commit dd597d2197
1 changed files with 27 additions and 27 deletions

View File

@ -55,39 +55,39 @@ exports.mixin = function (newClass, mixinClass, options) {
}
if (options.staticProperties) {
var staticProxies = [];
Object.keys(mixinClass).forEach(function (classProp) {
if (classProp !== 'super_' && classProp !== '_mixins'
&& (!newClass.hasOwnProperty(classProp) || options.override)) {
var pd = Object.getOwnPropertyDescriptor(mixinClass, classProp);
if (options.proxyFunctions && pd.writable
&& typeof pd.value === 'function') {
pd.value = exports.proxy(pd.value, staticProxies);
}
Object.defineProperty(newClass, classProp, pd);
}
});
mixInto(mixinClass, newClass, options);
}
if (options.instanceProperties) {
if (mixinClass.prototype) {
var instanceProxies = [];
Object.keys(mixinClass.prototype).forEach(function (instanceProp) {
if (!newClass.prototype.hasOwnProperty(instanceProp) || options.override) {
var pd = Object.getOwnPropertyDescriptor(mixinClass.prototype, instanceProp);
if (options.proxyFunctions && pd.writable && typeof pd.value === 'function') {
pd.value = exports.proxy(pd.value, instanceProxies);
}
Object.defineProperty(newClass.prototype, instanceProp, pd);
}
});
}
if (options.instanceProperties && mixinClass.prototype) {
mixInto(mixinClass.prototype, newClass.prototype, options);
}
return newClass;
};
exports.proxy = function (fn, proxies) {
function mixInto(sourceScope, targetScope, options) {
var proxies = [];
Object.keys(sourceScope).forEach(function (propertyName, options) {
var targetPropertyExists = targetScope.hasOwnProperty(propertyName);
var sourceProperty = Object.getOwnPropertyDescriptor(sourceScope, propertyName);
var targetProperty = targetPropertyExists && Object.getOwnPropertyDescriptor(targetScope, propertyName);
var sourceIsFunc = typeof sourceProperty.value === 'function';
var isFunc = targetPropertyExists && typeof targetProperty.value === 'function';
var isDelegate = isFunc && targetProperty.value._delegate;
var shouldOverride = options.override || !targetPropertyExists || isDelegate;
if (shouldOverride) {
if (sourceIsFunc) {
sourceProperty.value = exports.proxy(sourceProperty.value, proxies);
}
Object.defineProperty(targetScope, propertyName, sourceProperty);
}
});
}
exports.proxy = function createProxy(fn, proxies) {
// Make sure same methods referenced by different properties have the same proxy
// For example, deleteById is an alias of removeById
proxies = proxies || [];