smart-mixin
Advanced tools
Comparing version 1.2.1 to 2.0.0
142
index.js
@@ -1,9 +0,54 @@ | ||
var objToStr = function(x){ return Object.prototype.toString.call(x); }; | ||
function objToStr(x){ return Object.prototype.toString.call(x); }; | ||
var thrower = function(error){ | ||
throw error; | ||
function returner(x) { return x; } | ||
function wrapIfFunction(thing){ | ||
return typeof thing !== "function" ? thing | ||
: function(){ | ||
return thing.apply(this, arguments); | ||
}; | ||
} | ||
function setNonEnumerable(target, key, value){ | ||
if (key in target){ | ||
target[key] = value; | ||
} | ||
else { | ||
Object.defineProperty(target, key, { | ||
value: value, | ||
writable: true, | ||
configurable: true | ||
}); | ||
} | ||
} | ||
function defaultNonFunctionProperty(left, right, key){ | ||
if (left !== undefined && right !== undefined) { | ||
var getTypeName = function(obj){ | ||
if (obj && obj.constructor && obj.constructor.name) { | ||
return obj.constructor.name; | ||
} | ||
else { | ||
return objToStr(obj).slice(8, -1); | ||
} | ||
}; | ||
throw new TypeError('Cannot mixin key ' + key + ' because it is provided by multiple sources, ' | ||
+ 'and the types are ' + getTypeName(left) + ' and ' + getTypeName(right)); | ||
} | ||
return left === undefined ? right : left; | ||
}; | ||
function assertObject(obj, obj2){ | ||
var type = objToStr(obj); | ||
if (type !== '[object Object]') { | ||
var displayType = obj.constructor ? obj.constructor.name : 'Unknown'; | ||
var displayType2 = obj2.constructor ? obj2.constructor.name : 'Unknown'; | ||
throw new Error('cannot merge returned value of type ' + displayType + ' with an ' + displayType2); | ||
} | ||
}; | ||
var mixins = module.exports = function makeMixinFunction(rules, _opts){ | ||
var opts = _opts || {}; | ||
if (!opts.unknownFunction) { | ||
@@ -14,32 +59,5 @@ opts.unknownFunction = mixins.ONCE; | ||
if (!opts.nonFunctionProperty) { | ||
opts.nonFunctionProperty = function(left, right, key){ | ||
if (left !== undefined && right !== undefined) { | ||
var getTypeName = function(obj){ | ||
if (obj && obj.constructor && obj.constructor.name) { | ||
return obj.constructor.name; | ||
} | ||
else { | ||
return objToStr(obj).slice(8, -1); | ||
} | ||
}; | ||
throw new TypeError('Cannot mixin key ' + key + ' because it is provided by multiple sources, ' | ||
+ 'and the types are ' + getTypeName(left) + ' and ' + getTypeName(right)); | ||
} | ||
return left === undefined ? right : left; | ||
}; | ||
opts.nonFunctionProperty = defaultNonFunctionProperty; | ||
} | ||
function setNonEnumerable(target, key, value){ | ||
if (key in target){ | ||
target[key] = value; | ||
} | ||
else { | ||
Object.defineProperty(target, key, { | ||
value: value, | ||
writable: true, | ||
configurable: true | ||
}); | ||
} | ||
} | ||
return function applyMixin(source, mixin){ | ||
@@ -53,9 +71,2 @@ Object.keys(mixin).forEach(function(key){ | ||
var wrapIfFunction = function(thing){ | ||
return typeof thing !== "function" ? thing | ||
: function(){ | ||
return thing.call(this, arguments); | ||
}; | ||
}; | ||
// do we have a rule for this key? | ||
@@ -92,11 +103,2 @@ if (rule) { | ||
mixins._mergeObjects = function(obj1, obj2) { | ||
var assertObject = function(obj, obj2){ | ||
var type = objToStr(obj); | ||
if (type !== '[object Object]') { | ||
var displayType = obj.constructor ? obj.constructor.name : 'Unknown'; | ||
var displayType2 = obj2.constructor ? obj2.constructor.name : 'Unknown'; | ||
thrower('cannot merge returned value of type ' + displayType + ' with an ' + displayType2); | ||
} | ||
}; | ||
if (Array.isArray(obj1) && Array.isArray(obj2)) { | ||
@@ -112,3 +114,3 @@ return obj1.concat(obj2); | ||
if (Object.prototype.hasOwnProperty.call(obj2, k)) { | ||
thrower('cannot merge returns because both have the ' + JSON.stringify(k) + ' key'); | ||
throw new Error('cannot merge returns because both have the ' + JSON.stringify(k) + ' key'); | ||
} | ||
@@ -123,5 +125,4 @@ result[k] = obj1[k]; | ||
return result; | ||
}; | ||
} | ||
// define our built-in mixin types | ||
@@ -132,14 +133,9 @@ mixins.ONCE = function(left, right, key){ | ||
} | ||
var fn = left || right; | ||
return function(args){ | ||
return fn.apply(this, args); | ||
}; | ||
return left || right; | ||
}; | ||
mixins.MANY = function(left, right, key){ | ||
return function(args){ | ||
if (right) right.apply(this, args); | ||
return left ? left.apply(this, args) : undefined; | ||
return function(){ | ||
if (right) right.apply(this, arguments); | ||
return left ? left.apply(this, arguments) : undefined; | ||
}; | ||
@@ -149,13 +145,12 @@ }; | ||
mixins.MANY_MERGED_LOOSE = function(left, right, key) { | ||
if(left && right) { | ||
if (left && right) { | ||
return mixins._mergeObjects(left, right); | ||
} | ||
return left || right; | ||
} | ||
}; | ||
mixins.MANY_MERGED = function(left, right, key){ | ||
return function(args){ | ||
var res1 = right && right.apply(this, args); | ||
var res2 = left && left.apply(this, args); | ||
return function(){ | ||
var res1 = right && right.apply(this, arguments); | ||
var res2 = left && left.apply(this, arguments); | ||
if (res1 && res2) { | ||
@@ -168,8 +163,7 @@ return mixins._mergeObjects(res1, res2) | ||
mixins.REDUCE_LEFT = function(_left, _right, key){ | ||
var left = _left || function(x){ return x }; | ||
var right = _right || function(x){ return x }; | ||
return function(args){ | ||
return right.call(this, left.apply(this, args)); | ||
var left = _left || returner; | ||
var right = _right || returner; | ||
return function(){ | ||
return right.call(this, left.apply(this, arguments)); | ||
}; | ||
@@ -179,8 +173,8 @@ }; | ||
mixins.REDUCE_RIGHT = function(_left, _right, key){ | ||
var left = _left || function(x){ return x }; | ||
var right = _right || function(x){ return x }; | ||
return function(args){ | ||
return left.call(this, right.apply(this, args)); | ||
var left = _left || returner; | ||
var right = _right || returner; | ||
return function(){ | ||
return left.call(this, right.apply(this, arguments)); | ||
}; | ||
}; | ||
{ | ||
"name": "smart-mixin", | ||
"version": "1.2.1", | ||
"version": "2.0.0", | ||
"description": "", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -12,3 +12,3 @@ ![travis](https://travis-ci.org/brigand/smart-mixin.svg) | ||
# will expose window.smartMixin or the smartMixin AMD module | ||
curl 'wzrd.in/standalone/smart-mixin@1' > vendor/smart-mixin.js | ||
curl 'wzrd.in/standalone/smart-mixin@2' > vendor/smart-mixin.js | ||
``` | ||
@@ -54,4 +54,4 @@ | ||
// define your own handler for it | ||
@@ -64,16 +64,13 @@ // the two operands are the value of onKeyPress on each object | ||
// key is 'onKeyPress' here, this allows reuse of these functions | ||
// args is the arguments we were called with; treat it like an arraylike object | ||
// thrower is a special function which attempts to improve the error stack by including | ||
// the location where it was actually mixed in | ||
onKeyPress: function(left, right, key) { | ||
left = left || function(){}; | ||
right = right || function(){}; | ||
return function(args, thrower){ | ||
return function(event){ | ||
var event = args[0]; | ||
if (!event) thrower(TypeError(key + ' called without an event object')); | ||
if (!event) throw new TypeError(key + ' called without an event object'); | ||
var ret = left.apply(this, args); | ||
var ret = left.apply(this, arguments); | ||
if (event && !event.immediatePropagationIsStopped) { | ||
var ret2 = right.apply(this, args); | ||
var ret2 = right.apply(this, arguments); | ||
} | ||
@@ -103,3 +100,3 @@ return ret || ret2; | ||
getState(foo){ | ||
return {bar: foo+1} | ||
return {bar: foo+1} | ||
} | ||
@@ -106,0 +103,0 @@ }; |
23461
461
126