From dd597d21973c0119147be806199d2d415ffc0b5c Mon Sep 17 00:00:00 2001 From: Ritchie Martori Date: Thu, 20 Feb 2014 17:25:07 -0800 Subject: [PATCH] Refactor mixin and always redefine proxy/delegate methods --- lib/jutil.js | 54 ++++++++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/lib/jutil.js b/lib/jutil.js index 03e21500..c33ec24c 100644 --- a/lib/jutil.js +++ b/lib/jutil.js @@ -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 || [];