| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 | /*! * static-extend <https://github.com/jonschlinkert/static-extend> * * Copyright (c) 2016, Jon Schlinkert. * Licensed under the MIT License. */'use strict';var copy = require('object-copy');var define = require('define-property');var util = require('util');/** * Returns a function for extending the static properties, * prototype properties, and descriptors from the `Parent` * constructor onto `Child` constructors. * * ```js * var extend = require('static-extend'); * Parent.extend = extend(Parent); * * // optionally pass a custom merge function as the second arg * Parent.extend = extend(Parent, function(Child) { *   Child.prototype.mixin = function(key, val) { *     Child.prototype[key] = val; *   }; * }); * * // extend "child" constructors * Parent.extend(Child); * * // optionally define prototype methods as the second arg * Parent.extend(Child, { *   foo: function() {}, *   bar: function() {} * }); * ``` * @param {Function} `Parent` Parent ctor * @param {Function} `extendFn` Optional extend function for handling any necessary custom merging. Useful when updating methods that require a specific prototype. *   @param {Function} `Child` Child ctor *   @param {Object} `proto` Optionally pass additional prototype properties to inherit. *   @return {Object} * @api public */function extend(Parent, extendFn) {  if (typeof Parent !== 'function') {    throw new TypeError('expected Parent to be a function.');  }  return function(Ctor, proto) {    if (typeof Ctor !== 'function') {      throw new TypeError('expected Ctor to be a function.');    }    util.inherits(Ctor, Parent);    copy(Ctor, Parent);    // proto can be null or a plain object    if (typeof proto === 'object') {      var obj = Object.create(proto);      for (var k in obj) {        Ctor.prototype[k] = obj[k];      }    }    // keep a reference to the parent prototype    define(Ctor.prototype, '_parent_', {      configurable: true,      set: function() {},      get: function() {        return Parent.prototype;      }    });    if (typeof extendFn === 'function') {      extendFn(Ctor, Parent);    }    Ctor.extend = extend(Ctor, extendFn);  };};/** * Expose `extend` */module.exports = extend;
 |