UNPKG

foibles

Version:

Composition and mixins and TypeScript classes

76 lines 2.33 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); // Symbol used to mark if a certain mixin has been applied var application = Symbol('decorator:application'); /** * Check if the given prototype has the given mixin applied to itself. * * @param object * @param mixin */ function has(object, mixin) { while (object != null) { if (object.hasOwnProperty(application) && object[application] === mixin) { return true; } object = Object.getPrototypeOf(object); } } /** * Turn a function into a fully featured mixin. The mixin function should be * a function which takes a single argument which is the class to extend and * the function must return an extended class. * * ```javascript * const ExampleMixin = toMixin(base => class extends base { * ... * }); * ``` * * @param func */ function toMixin(func) { /* * Define a function that checks if the mixin has already been applied * to the prototype chain. This allows mixins to use other mixins as needed * without them being applied twice. */ var mixinOnce = function (base) { if (has(base.prototype, func)) return base; var result = func(base); result.prototype[application] = func; return result; }; /* * Define a custom hasInstance symbol so that instanceof can be used if * the environment supports it. */ if (Symbol.hasInstance) { if (func.hasOwnProperty(Symbol.hasInstance)) { /* * Mixin has its own hasInstance, let the outer function delegate * to it. */ Object.defineProperty(mixinOnce, Symbol.hasInstance, { value: function mixinHasInstance(other) { return func[Symbol.hasInstance](other); } }); } else { /* * The mixin function does not have a custom hasInstance, use our * own. */ Object.defineProperty(mixinOnce, Symbol.hasInstance, { value: function mixinHasInstance(other) { return has(other, func); } }); } } return mixinOnce; } exports.toMixin = toMixin; //# sourceMappingURL=mixin.js.map