UNPKG

14.6 kBJavaScriptView Raw
1(function() {
2 var isEqual, macModifierKeyMap, nonMacModifierKeyMap, plus, shiftKeyMap, splitKeyPath, _,
3 __slice = [].slice;
4
5 _ = require('underscore');
6
7 macModifierKeyMap = {
8 cmd: '\u2318',
9 ctrl: '\u2303',
10 alt: '\u2325',
11 option: '\u2325',
12 shift: '\u21e7',
13 enter: '\u23ce',
14 left: '\u2190',
15 right: '\u2192',
16 up: '\u2191',
17 down: '\u2193'
18 };
19
20 nonMacModifierKeyMap = {
21 cmd: 'Cmd',
22 ctrl: 'Ctrl',
23 alt: 'Alt',
24 option: 'Alt',
25 shift: 'Shift',
26 enter: 'Enter',
27 left: 'Left',
28 right: 'Right',
29 up: 'Up',
30 down: 'Down'
31 };
32
33 shiftKeyMap = {
34 '~': '`',
35 '_': '-',
36 '+': '=',
37 '|': '\\',
38 '{': '[',
39 '}': ']',
40 ':': ';',
41 '"': '\'',
42 '<': ',',
43 '>': '.',
44 '?': '/'
45 };
46
47 splitKeyPath = function(keyPath) {
48 var char, i, keyPathArray, startIndex, _i, _len;
49 startIndex = 0;
50 keyPathArray = [];
51 for (i = _i = 0, _len = keyPath.length; _i < _len; i = ++_i) {
52 char = keyPath[i];
53 if (char === '.' && (i === 0 || keyPath[i - 1] !== '\\')) {
54 keyPathArray.push(keyPath.substring(startIndex, i));
55 startIndex = i + 1;
56 }
57 }
58 keyPathArray.push(keyPath.substr(startIndex, keyPath.length));
59 return keyPathArray;
60 };
61
62 plus = {
63 adviseBefore: function(object, methodName, advice) {
64 var original;
65 original = object[methodName];
66 return object[methodName] = function() {
67 var args;
68 args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
69 if (advice.apply(this, args) !== false) {
70 return original.apply(this, args);
71 }
72 };
73 },
74 camelize: function(string) {
75 if (string) {
76 return string.replace(/[_-]+(\w)/g, function(m) {
77 return m[1].toUpperCase();
78 });
79 } else {
80 return '';
81 }
82 },
83 capitalize: function(word) {
84 if (!word) {
85 return '';
86 }
87 if (word.toLowerCase() === 'github') {
88 return 'GitHub';
89 } else {
90 return word[0].toUpperCase() + word.slice(1);
91 }
92 },
93 compactObject: function(object) {
94 var key, newObject, value;
95 newObject = {};
96 for (key in object) {
97 value = object[key];
98 if (value != null) {
99 newObject[key] = value;
100 }
101 }
102 return newObject;
103 },
104 dasherize: function(string) {
105 if (!string) {
106 return '';
107 }
108 string = string[0].toLowerCase() + string.slice(1);
109 return string.replace(/([A-Z])|(_)/g, function(m, letter) {
110 if (letter) {
111 return "-" + letter.toLowerCase();
112 } else {
113 return "-";
114 }
115 });
116 },
117 deepClone: function(object) {
118 if (_.isArray(object)) {
119 return object.map(function(value) {
120 return plus.deepClone(value);
121 });
122 } else if (_.isObject(object)) {
123 return plus.mapObject(object, (function(_this) {
124 return function(key, value) {
125 return [key, plus.deepClone(value)];
126 };
127 })(this));
128 } else {
129 return object;
130 }
131 },
132 deepExtend: function() {
133 var key, object, objects, result, value, _i, _len;
134 objects = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
135 result = {};
136 for (_i = 0, _len = objects.length; _i < _len; _i++) {
137 object = objects[_i];
138 for (key in object) {
139 value = object[key];
140 if (_.isObject(value) && !_.isArray(value)) {
141 result[key] = plus.deepExtend(result[key], value);
142 } else {
143 if (result[key] == null) {
144 result[key] = value;
145 }
146 }
147 }
148 }
149 return result;
150 },
151 deepContains: function(array, target) {
152 var object, _i, _len;
153 if (array == null) {
154 return false;
155 }
156 for (_i = 0, _len = array.length; _i < _len; _i++) {
157 object = array[_i];
158 if (_.isEqual(object, target)) {
159 return true;
160 }
161 }
162 return false;
163 },
164 endsWith: function(string, suffix) {
165 if (suffix == null) {
166 suffix = '';
167 }
168 if (string) {
169 return string.indexOf(suffix, string.length - suffix.length) !== -1;
170 } else {
171 return false;
172 }
173 },
174 escapeAttribute: function(string) {
175 if (string) {
176 return string.replace(/"/g, '&quot;').replace(/\n/g, '').replace(/\\/g, '-');
177 } else {
178 return '';
179 }
180 },
181 escapeRegExp: function(string) {
182 if (string) {
183 return string.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
184 } else {
185 return '';
186 }
187 },
188 humanizeEventName: function(eventName, eventDoc) {
189 var event, namespace, namespaceDoc, _ref;
190 _ref = eventName.split(':'), namespace = _ref[0], event = _ref[1];
191 if (event == null) {
192 return plus.undasherize(namespace);
193 }
194 namespaceDoc = plus.undasherize(namespace);
195 if (eventDoc == null) {
196 eventDoc = plus.undasherize(event);
197 }
198 return "" + namespaceDoc + ": " + eventDoc;
199 },
200 humanizeKey: function(key, platform) {
201 var modifierKeyMap;
202 if (platform == null) {
203 platform = process.platform;
204 }
205 if (!key) {
206 return key;
207 }
208 modifierKeyMap = platform === 'darwin' ? macModifierKeyMap : nonMacModifierKeyMap;
209 if (modifierKeyMap[key]) {
210 return modifierKeyMap[key];
211 } else if (key.length === 1 && (shiftKeyMap[key] != null)) {
212 return [modifierKeyMap.shift, shiftKeyMap[key]];
213 } else if (key.length === 1 && key === key.toUpperCase() && key.toUpperCase() !== key.toLowerCase()) {
214 return [modifierKeyMap.shift, key.toUpperCase()];
215 } else if (key.length === 1 || /f[0-9]{1,2}/.test(key)) {
216 return key.toUpperCase();
217 } else {
218 if (platform === 'darwin') {
219 return key;
220 } else {
221 return plus.capitalize(key);
222 }
223 }
224 },
225 humanizeKeystroke: function(keystroke, platform) {
226 var humanizedKeystrokes, index, key, keys, keystrokes, splitKeystroke, _i, _j, _len, _len1;
227 if (platform == null) {
228 platform = process.platform;
229 }
230 if (!keystroke) {
231 return keystroke;
232 }
233 keystrokes = keystroke.split(' ');
234 humanizedKeystrokes = [];
235 for (_i = 0, _len = keystrokes.length; _i < _len; _i++) {
236 keystroke = keystrokes[_i];
237 keys = [];
238 splitKeystroke = keystroke.split('-');
239 for (index = _j = 0, _len1 = splitKeystroke.length; _j < _len1; index = ++_j) {
240 key = splitKeystroke[index];
241 if (key === '' && splitKeystroke[index - 1] === '') {
242 key = '-';
243 }
244 if (key) {
245 keys.push(plus.humanizeKey(key, platform));
246 }
247 }
248 keys = _.uniq(_.flatten(keys));
249 if (platform === 'darwin') {
250 keys = keys.join('');
251 } else {
252 keys = keys.join('+');
253 }
254 humanizedKeystrokes.push(keys);
255 }
256 return humanizedKeystrokes.join(' ');
257 },
258 isSubset: function(potentialSubset, potentialSuperset) {
259 return _.every(potentialSubset, function(element) {
260 return _.include(potentialSuperset, element);
261 });
262 },
263 losslessInvert: function(hash) {
264 var inverted, key, value;
265 inverted = {};
266 for (key in hash) {
267 value = hash[key];
268 if (inverted[value] == null) {
269 inverted[value] = [];
270 }
271 inverted[value].push(key);
272 }
273 return inverted;
274 },
275 mapObject: function(object, iterator) {
276 var key, newObject, value, _ref;
277 newObject = {};
278 for (key in object) {
279 value = object[key];
280 _ref = iterator(key, value), key = _ref[0], value = _ref[1];
281 newObject[key] = value;
282 }
283 return newObject;
284 },
285 multiplyString: function(string, n) {
286 var finalString, i;
287 finalString = "";
288 i = 0;
289 while (i < n) {
290 finalString += string;
291 i++;
292 }
293 return finalString;
294 },
295 pluralize: function(count, singular, plural) {
296 if (count == null) {
297 count = 0;
298 }
299 if (plural == null) {
300 plural = singular + 's';
301 }
302 if (count === 1) {
303 return "" + count + " " + singular;
304 } else {
305 return "" + count + " " + plural;
306 }
307 },
308 remove: function(array, element) {
309 var index;
310 index = array.indexOf(element);
311 if (index >= 0) {
312 array.splice(index, 1);
313 }
314 return array;
315 },
316 setValueForKeyPath: function(object, keyPath, value) {
317 var key, keys;
318 keys = splitKeyPath(keyPath);
319 while (keys.length > 1) {
320 key = keys.shift();
321 if (object[key] == null) {
322 object[key] = {};
323 }
324 object = object[key];
325 }
326 if (value != null) {
327 return object[keys.shift()] = value;
328 } else {
329 return delete object[keys.shift()];
330 }
331 },
332 hasKeyPath: function(object, keyPath) {
333 var key, keys, _i, _len;
334 keys = splitKeyPath(keyPath);
335 for (_i = 0, _len = keys.length; _i < _len; _i++) {
336 key = keys[_i];
337 if (!object.hasOwnProperty(key)) {
338 return false;
339 }
340 object = object[key];
341 }
342 return true;
343 },
344 spliceWithArray: function(originalArray, start, length, insertedArray, chunkSize) {
345 var chunkStart, _i, _ref, _results;
346 if (chunkSize == null) {
347 chunkSize = 100000;
348 }
349 if (insertedArray.length < chunkSize) {
350 return originalArray.splice.apply(originalArray, [start, length].concat(__slice.call(insertedArray)));
351 } else {
352 originalArray.splice(start, length);
353 _results = [];
354 for (chunkStart = _i = 0, _ref = insertedArray.length; chunkSize > 0 ? _i <= _ref : _i >= _ref; chunkStart = _i += chunkSize) {
355 _results.push(originalArray.splice.apply(originalArray, [start + chunkStart, 0].concat(__slice.call(insertedArray.slice(chunkStart, chunkStart + chunkSize)))));
356 }
357 return _results;
358 }
359 },
360 sum: function(array) {
361 var elt, sum, _i, _len;
362 sum = 0;
363 for (_i = 0, _len = array.length; _i < _len; _i++) {
364 elt = array[_i];
365 sum += elt;
366 }
367 return sum;
368 },
369 uncamelcase: function(string) {
370 var result;
371 if (!string) {
372 return '';
373 }
374 result = string.replace(/([A-Z])|_+/g, function(match, letter) {
375 if (letter == null) {
376 letter = '';
377 }
378 return " " + letter;
379 });
380 return plus.capitalize(result.trim());
381 },
382 undasherize: function(string) {
383 if (string) {
384 return string.split('-').map(plus.capitalize).join(' ');
385 } else {
386 return '';
387 }
388 },
389 underscore: function(string) {
390 if (!string) {
391 return '';
392 }
393 string = string[0].toLowerCase() + string.slice(1);
394 return string.replace(/([A-Z])|-+/g, function(match, letter) {
395 if (letter == null) {
396 letter = '';
397 }
398 return "_" + (letter.toLowerCase());
399 });
400 },
401 valueForKeyPath: function(object, keyPath) {
402 var key, keys, _i, _len;
403 keys = splitKeyPath(keyPath);
404 for (_i = 0, _len = keys.length; _i < _len; _i++) {
405 key = keys[_i];
406 object = object[key];
407 if (object == null) {
408 return;
409 }
410 }
411 return object;
412 },
413 isEqual: function(a, b, aStack, bStack) {
414 if (_.isArray(aStack) && _.isArray(bStack)) {
415 return isEqual(a, b, aStack, bStack);
416 } else {
417 return isEqual(a, b);
418 }
419 },
420 isEqualForProperties: function() {
421 var a, b, properties, property, _i, _len;
422 a = arguments[0], b = arguments[1], properties = 3 <= arguments.length ? __slice.call(arguments, 2) : [];
423 for (_i = 0, _len = properties.length; _i < _len; _i++) {
424 property = properties[_i];
425 if (!_.isEqual(a[property], b[property])) {
426 return false;
427 }
428 }
429 return true;
430 }
431 };
432
433 isEqual = function(a, b, aStack, bStack) {
434 var aCtor, aCtorValid, aElement, aKeyCount, aValue, bCtor, bCtorValid, bKeyCount, bValue, equal, i, key, stackIndex, _i, _len;
435 if (aStack == null) {
436 aStack = [];
437 }
438 if (bStack == null) {
439 bStack = [];
440 }
441 if (a === b) {
442 return _.isEqual(a, b);
443 }
444 if (_.isFunction(a) || _.isFunction(b)) {
445 return _.isEqual(a, b);
446 }
447 stackIndex = aStack.length;
448 while (stackIndex--) {
449 if (aStack[stackIndex] === a) {
450 return bStack[stackIndex] === b;
451 }
452 }
453 aStack.push(a);
454 bStack.push(b);
455 equal = false;
456 if (_.isFunction(a != null ? a.isEqual : void 0)) {
457 equal = a.isEqual(b, aStack, bStack);
458 } else if (_.isFunction(b != null ? b.isEqual : void 0)) {
459 equal = b.isEqual(a, bStack, aStack);
460 } else if (_.isArray(a) && _.isArray(b) && a.length === b.length) {
461 equal = true;
462 for (i = _i = 0, _len = a.length; _i < _len; i = ++_i) {
463 aElement = a[i];
464 if (!isEqual(aElement, b[i], aStack, bStack)) {
465 equal = false;
466 break;
467 }
468 }
469 } else if (_.isRegExp(a) && _.isRegExp(b)) {
470 equal = _.isEqual(a, b);
471 } else if (_.isElement(a) && _.isElement(b)) {
472 equal = a === b;
473 } else if (_.isObject(a) && _.isObject(b)) {
474 aCtor = a.constructor;
475 bCtor = b.constructor;
476 aCtorValid = _.isFunction(aCtor) && aCtor instanceof aCtor;
477 bCtorValid = _.isFunction(bCtor) && bCtor instanceof bCtor;
478 if (aCtor !== bCtor && !(aCtorValid && bCtorValid)) {
479 equal = false;
480 } else {
481 aKeyCount = 0;
482 equal = true;
483 for (key in a) {
484 aValue = a[key];
485 if (!_.has(a, key)) {
486 continue;
487 }
488 aKeyCount++;
489 if (!(_.has(b, key) && isEqual(aValue, b[key], aStack, bStack))) {
490 equal = false;
491 break;
492 }
493 }
494 if (equal) {
495 bKeyCount = 0;
496 for (key in b) {
497 bValue = b[key];
498 if (_.has(b, key)) {
499 bKeyCount++;
500 }
501 }
502 equal = aKeyCount === bKeyCount;
503 }
504 }
505 } else {
506 equal = _.isEqual(a, b);
507 }
508 aStack.pop();
509 bStack.pop();
510 return equal;
511 };
512
513 module.exports = _.extend({}, _, plus);
514
515}).call(this);