UNPKG

es6-mixin

Version:

Minimalist mixin helper designed to be used with ES6 (ES2015) classes.

140 lines (107 loc) 6.32 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); exports.mixin = mixin; exports.mix = mix; function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** * Converts an object to an array of pairs, in the form of an array of tuples * where index 0 is the key and index 1 is the value. This include both * enumerable and non-enumerable properties. * @param {object} object Object for which to get pairs * @returns {[string, *][]} Array containing object pairs */ function entries(object) { return Object.getOwnPropertyNames(object).map(function (key) { return [key, object[key]]; }); } /** * Generic mixin superclass. This class is intended to be extended by actual * mixins. */ var Mixin = exports.Mixin = function () { function Mixin() { _classCallCheck(this, Mixin); } _createClass(Mixin, null, [{ key: 'mixin', /** * Mixes in this class's methods into an existing object. * @param {object} [target={}] Any object to mix this class's methods into * @param {function} [MixedIn=this] Constructor to be mixed in * @param {...*} [args] Arguments to pass to the mixed in constructor, if any * @return {object} The original target object, mutated */ value: function mixin() { var target = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; var MixedIn = arguments.length <= 1 || arguments[1] === undefined ? this : arguments[1]; for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { args[_key - 2] = arguments[_key]; } var instance = new (Function.prototype.bind.apply(MixedIn, [null].concat(args)))(); // Get all the methods from this class, bind them to the instance, and copy // them to the target object. entries(MixedIn.prototype).filter(function (_ref) { var _ref2 = _slicedToArray(_ref, 2); var methodName = _ref2[0]; var method = _ref2[1]; return typeof method === 'function' && methodName !== 'constructor'; }).forEach(function (_ref3) { var _ref4 = _slicedToArray(_ref3, 2); var methodName = _ref4[0]; var method = _ref4[1]; return target[methodName] = method.bind(instance); }); return target; } }]); return Mixin; }(); /** * Mixes in this class's methods into an existing object. * @param {object} [target={}] Any object to mix this class's methods into * @param {function} [MixedIn=Mixin] Constructor to be mixed in * @param {...*} [args] Arguments to pass to the mixed in constructor, if any * @return {object} The original target object, mutated */ function mixin() { var target = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; var MixedIn = arguments.length <= 1 || arguments[1] === undefined ? Mixin : arguments[1]; for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) { args[_key2 - 2] = arguments[_key2]; } return Mixin.mixin.apply(Mixin, [target, MixedIn].concat(args)); } /** * Create a subclass of a constructor and mix 1 or many mixin into it. * @param {function} SuperClass Class that will be used as super-class * @param {...function} mixins Mixins to add * @return {function} A new anonymous class that extends `SuperClass` and has all `mixins` mixed in */ function mix(SuperClass) { for (var _len3 = arguments.length, mixins = Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) { mixins[_key3 - 1] = arguments[_key3]; } return function (_SuperClass) { _inherits(_class, _SuperClass); function _class() { var _Object$getPrototypeO; _classCallCheck(this, _class); for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { args[_key4] = arguments[_key4]; } var _this = _possibleConstructorReturn(this, (_Object$getPrototypeO = Object.getPrototypeOf(_class)).call.apply(_Object$getPrototypeO, [this].concat(args))); mixins.forEach(function (Mixedin) { return mixin(_this, Mixedin); }); return _this; } return _class; }(SuperClass); }