10a7d70bc112307becdb4cfbb954ecda5a68e0b0
[yaffs-website] / node_modules / uncss / node_modules / lodash / fp / _baseConvert.js
1 var mapping = require('./_mapping'),
2     mutateMap = mapping.mutate,
3     placeholder = {};
4
5 /**
6  * The base implementation of `convert` which accepts a `util` object of methods
7  * required to perform conversions.
8  *
9  * @param {Object} util The util object.
10  * @param {string} name The name of the function to wrap.
11  * @param {Function} func The function to wrap.
12  * @returns {Function|Object} Returns the converted function or object.
13  */
14 function baseConvert(util, name, func) {
15   if (typeof func != 'function') {
16     func = name;
17     name = undefined;
18   }
19   if (func == null) {
20     throw new TypeError;
21   }
22   var isLib = name === undefined && typeof func.VERSION == 'string';
23
24   var _ = isLib ? func : {
25     'ary': util.ary,
26     'cloneDeep': util.cloneDeep,
27     'curry': util.curry,
28     'forEach': util.forEach,
29     'isFunction': util.isFunction,
30     'iteratee': util.iteratee,
31     'keys': util.keys,
32     'rearg': util.rearg
33   };
34
35   var ary = _.ary,
36       cloneDeep = _.cloneDeep,
37       curry = _.curry,
38       each = _.forEach,
39       isFunction = _.isFunction,
40       keys = _.keys,
41       rearg = _.rearg;
42
43   var baseArity = function(func, n) {
44     return n == 2
45       ? function(a, b) { return func.apply(undefined, arguments); }
46       : function(a) { return func.apply(undefined, arguments); };
47   };
48
49   var baseAry = function(func, n) {
50     return n == 2
51       ? function(a, b) { return func(a, b); }
52       : function(a) { return func(a); };
53   };
54
55   var cloneArray = function(array) {
56     var length = array ? array.length : 0,
57         result = Array(length);
58
59     while (length--) {
60       result[length] = array[length];
61     }
62     return result;
63   };
64
65   var createCloner = function(func) {
66     return function(object) {
67       return func({}, object);
68     };
69   };
70
71   var immutWrap = function(func, cloner) {
72     return overArg(func, cloner, true);
73   };
74
75   var iterateeAry = function(func, n) {
76     return overArg(func, function(func) {
77       return baseAry(func, n);
78     });
79   };
80
81   var iterateeRearg = function(func, indexes) {
82     return overArg(func, function(func) {
83       var n = indexes.length;
84       return baseArity(rearg(baseAry(func, n), indexes), n);
85     });
86   };
87
88   var overArg = function(func, iteratee, retArg) {
89     return function() {
90       var length = arguments.length,
91           args = Array(length);
92
93       while (length--) {
94         args[length] = arguments[length];
95       }
96       args[0] = iteratee(args[0]);
97       var result = func.apply(undefined, args);
98       return retArg ? args[0] : result;
99     };
100   };
101
102   var wrappers = {
103     'iteratee': function(iteratee) {
104       return function() {
105         var func = arguments[0],
106             arity = arguments[1];
107
108         arity = arity > 2 ? (arity - 2) : 1;
109         func = iteratee(func);
110         var length = func.length;
111         return (length && length <= arity) ? func : baseAry(func, arity);
112       };
113     },
114     'mixin': function(mixin) {
115       return function(source) {
116         var func = this;
117         if (!isFunction(func)) {
118           return mixin(func, Object(source));
119         }
120         var methods = [],
121             methodNames = [];
122
123         each(keys(source), function(key) {
124           var value = source[key];
125           if (isFunction(value)) {
126             methodNames.push(key);
127             methods.push(func.prototype[key]);
128           }
129         });
130
131         mixin(func, Object(source));
132
133         each(methodNames, function(methodName, index) {
134           var method = methods[index];
135           if (isFunction(method)) {
136             func.prototype[methodName] = method;
137           } else {
138             delete func.prototype[methodName];
139           }
140         });
141         return func;
142       };
143     },
144     'runInContext': function(runInContext) {
145       return function(context) {
146         return baseConvert(util, runInContext(context));
147       };
148     }
149   };
150
151   var wrap = function(name, func) {
152     var wrapper = wrappers[name];
153     if (wrapper) {
154       return wrapper(func);
155     }
156     if (mutateMap.array[name]) {
157       func = immutWrap(func, cloneArray);
158     }
159     else if (mutateMap.object[name]) {
160       func = immutWrap(func, createCloner(func));
161     }
162     else if (mutateMap.set[name]) {
163       func = immutWrap(func, cloneDeep);
164     }
165     var result;
166     each(mapping.caps, function(cap) {
167       each(mapping.aryMethod[cap], function(otherName) {
168         if (name == otherName) {
169           var indexes = mapping.iterateeRearg[name],
170               n = !isLib && mapping.aryIteratee[name];
171
172           result = ary(func, cap);
173           if (cap > 1 && !mapping.skipRearg[name]) {
174             result = rearg(result, mapping.methodRearg[name] || mapping.aryRearg[cap]);
175           }
176           if (indexes) {
177             result = iterateeRearg(result, indexes);
178           } else if (n) {
179             result = iterateeAry(result, n);
180           }
181           if (cap > 1) {
182             result = curry(result, cap);
183           }
184           return false;
185         }
186       });
187       return !result;
188     });
189
190     result || (result = func);
191     if (mapping.placeholder[name]) {
192       result.placeholder = placeholder;
193     }
194     return result;
195   };
196
197   if (!isLib) {
198     return wrap(name, func);
199   }
200   // Iterate over methods for the current ary cap.
201   var pairs = [];
202   each(mapping.caps, function(cap) {
203     each(mapping.aryMethod[cap], function(key) {
204       var func = _[mapping.key[key] || key];
205       if (func) {
206         pairs.push([key, wrap(key, func)]);
207       }
208     });
209   });
210
211   // Assign to `_` leaving `_.prototype` unchanged to allow chaining.
212   each(pairs, function(pair) {
213     _[pair[0]] = pair[1];
214   });
215
216   // Wrap the lodash method and its aliases.
217   each(keys(_), function(key) {
218     each(mapping.alias[key] || [], function(alias) {
219       _[alias] = _[key];
220     });
221   });
222
223   return _;
224 }
225
226 module.exports = baseConvert;