UNPKG

riveter

Version:

Mix-in, inheritance and constructor extend behavior for your JavaScript enjoyment.

124 lines (118 loc) 3.72 kB
/*global riveter,slice,deepExtend*/ riveter.rivet = function(fn) { if (!fn.hasOwnProperty("extend")) { fn.extend = function(props, ctorProps, options) { return riveter.extend(fn, props, ctorProps, options); }; } if (!fn.hasOwnProperty("compose")) { fn.compose = function() { return riveter.compose.apply(this, [fn].concat(slice.call(arguments, 0))); }; } if (!fn.hasOwnProperty("inherits")) { fn.inherits = function(parent, ctorProps, options) { return riveter.inherits(fn, parent, ctorProps, options); }; } if (!fn.hasOwnProperty("mixin")) { fn.mixin = function() { return riveter.mixin.apply(this, ([fn].concat(slice.call(arguments, 0)))); }; } if (!fn.hasOwnProperty("punch")) { fn.punch = function() { return riveter.punch.apply(this, ([fn].concat(slice.call(arguments, 0)))); }; } }; riveter.inherits = function(child, parent, ctorProps, options) { options = options || {}; var childProto; var TmpCtor = function() {}; var Child = function() { parent.apply(this, arguments); }; if (typeof child === "object") { if (child.hasOwnProperty("constructor")) { Child = child.constructor; } childProto = child; } else { Child = child; childProto = child.prototype; } riveter.rivet(Child); if (options.deep) { deepExtend(Child, parent, ctorProps); } else { _.defaults(Child, parent, ctorProps); } TmpCtor.prototype = parent.prototype; Child.prototype = new TmpCtor(); if (options.deep) { deepExtend(Child.prototype, childProto, { constructor: Child }); } else { _.extend(Child.prototype, childProto, { constructor: Child }); } Child.__super = parent; // Next line is all about Backbone compatibility Child.__super__ = parent.prototype; return Child; }; riveter.extend = function(ctor, props, ctorProps, options) { return riveter.inherits(props, ctor, ctorProps, options); }; riveter.compose = function() { var args = slice.call(arguments, 0); var ctor = args.shift(); riveter.rivet(ctor); var mixin = _.reduce(args, function(memo, val) { if (val.hasOwnProperty("_preInit")) { memo.preInit.push(val._preInit); } if (val.hasOwnProperty("_postInit")) { memo.postInit.push(val._postInit); } val = val.mixin || val; memo.items.push(val); return memo; }, { items: [], preInit: [], postInit: [] }); var res = ctor.extend({ constructor: function() { var args = slice.call(arguments, 0); _.each(mixin.preInit, function(initializer) { initializer.apply(this, args); }, this); ctor.prototype.constructor.apply(this, args); _.each(mixin.postInit, function(initializer) { initializer.apply(this, args); }, this); } }); riveter.rivet(res); _.defaults(res.prototype, _.extend.apply(null, [{}].concat(mixin.items))); return res; }; riveter.mixin = function() { var args = slice.call(arguments, 0); var ctor = args.shift(); riveter.rivet(ctor); _.defaults(ctor.prototype, _.extend.apply(null, [{}].concat(args))); return ctor; }; riveter.punch = function() { var args = slice.call(arguments, 0); var ctor = args.shift(); riveter.rivet(ctor); _.extend(ctor.prototype, _.extend.apply(null, [{}].concat(args))); return ctor; };