Projekt

Obecné

Profil

Stáhnout (3.41 KB) Statistiky
| Větev: | Revize:
1
/*!
2
 * use <https://github.com/jonschlinkert/use>
3
 *
4
 * Copyright (c) 2015-2017, Jon Schlinkert.
5
 * Released under the MIT License.
6
 */
7

    
8
'use strict';
9

    
10
module.exports = function base(app, options) {
11
  if (!isObject(app) && typeof app !== 'function') {
12
    throw new TypeError('expected an object or function');
13
  }
14

    
15
  var opts = isObject(options) ? options : {};
16
  var prop = typeof opts.prop === 'string' ? opts.prop : 'fns';
17
  if (!Array.isArray(app[prop])) {
18
    define(app, prop, []);
19
  }
20

    
21
  /**
22
   * Define a plugin function to be passed to use. The only
23
   * parameter exposed to the plugin is `app`, the object or function.
24
   * passed to `use(app)`. `app` is also exposed as `this` in plugins.
25
   *
26
   * Additionally, **if a plugin returns a function, the function will
27
   * be pushed onto the `fns` array**, allowing the plugin to be
28
   * called at a later point by the `run` method.
29
   *
30
   * ```js
31
   * var use = require('use');
32
   *
33
   * // define a plugin
34
   * function foo(app) {
35
   *   // do stuff
36
   * }
37
   *
38
   * var app = function(){};
39
   * use(app);
40
   *
41
   * // register plugins
42
   * app.use(foo);
43
   * app.use(bar);
44
   * app.use(baz);
45
   * ```
46
   * @name .use
47
   * @param {Function} `fn` plugin function to call
48
   * @api public
49
   */
50

    
51
  define(app, 'use', use);
52

    
53
  /**
54
   * Run all plugins on `fns`. Any plugin that returns a function
55
   * when called by `use` is pushed onto the `fns` array.
56
   *
57
   * ```js
58
   * var config = {};
59
   * app.run(config);
60
   * ```
61
   * @name .run
62
   * @param {Object} `value` Object to be modified by plugins.
63
   * @return {Object} Returns the object passed to `run`
64
   * @api public
65
   */
66

    
67
  define(app, 'run', function(val) {
68
    if (!isObject(val)) return;
69

    
70
    if (!val.use || !val.run) {
71
      define(val, prop, val[prop] || []);
72
      define(val, 'use', use);
73
    }
74

    
75
    if (!val[prop] || val[prop].indexOf(base) === -1) {
76
      val.use(base);
77
    }
78

    
79
    var self = this || app;
80
    var fns = self[prop];
81
    var len = fns.length;
82
    var idx = -1;
83

    
84
    while (++idx < len) {
85
      val.use(fns[idx]);
86
    }
87
    return val;
88
  });
89

    
90
  /**
91
   * Call plugin `fn`. If a function is returned push it into the
92
   * `fns` array to be called by the `run` method.
93
   */
94

    
95
  function use(type, fn, options) {
96
    var offset = 1;
97

    
98
    if (typeof type === 'string' || Array.isArray(type)) {
99
      fn = wrap(type, fn);
100
      offset++;
101
    } else {
102
      options = fn;
103
      fn = type;
104
    }
105

    
106
    if (typeof fn !== 'function') {
107
      throw new TypeError('expected a function');
108
    }
109

    
110
    var self = this || app;
111
    var fns = self[prop];
112

    
113
    var args = [].slice.call(arguments, offset);
114
    args.unshift(self);
115

    
116
    if (typeof opts.hook === 'function') {
117
      opts.hook.apply(self, args);
118
    }
119

    
120
    var val = fn.apply(self, args);
121
    if (typeof val === 'function' && fns.indexOf(val) === -1) {
122
      fns.push(val);
123
    }
124
    return self;
125
  }
126

    
127
  /**
128
   * Wrap a named plugin function so that it's only called on objects of the
129
   * given `type`
130
   *
131
   * @param {String} `type`
132
   * @param {Function} `fn` Plugin function
133
   * @return {Function}
134
   */
135

    
136
  function wrap(type, fn) {
137
    return function plugin() {
138
      return this.type === type ? fn.apply(this, arguments) : plugin;
139
    };
140
  }
141

    
142
  return app;
143
};
144

    
145
function isObject(val) {
146
  return val && typeof val === 'object' && !Array.isArray(val);
147
}
148

    
149
function define(obj, key, val) {
150
  Object.defineProperty(obj, key, {
151
    configurable: true,
152
    writable: true,
153
    value: val
154
  });
155
}
(3-3/4)