Initial commit
[yaffs-website] / node_modules / grunt-contrib-watch / node_modules / lodash / internal / baseMergeDeep.js
1 var arrayCopy = require('./arrayCopy'),
2     isArguments = require('../lang/isArguments'),
3     isArray = require('../lang/isArray'),
4     isArrayLike = require('./isArrayLike'),
5     isPlainObject = require('../lang/isPlainObject'),
6     isTypedArray = require('../lang/isTypedArray'),
7     toPlainObject = require('../lang/toPlainObject');
8
9 /**
10  * A specialized version of `baseMerge` for arrays and objects which performs
11  * deep merges and tracks traversed objects enabling objects with circular
12  * references to be merged.
13  *
14  * @private
15  * @param {Object} object The destination object.
16  * @param {Object} source The source object.
17  * @param {string} key The key of the value to merge.
18  * @param {Function} mergeFunc The function to merge values.
19  * @param {Function} [customizer] The function to customize merged values.
20  * @param {Array} [stackA=[]] Tracks traversed source objects.
21  * @param {Array} [stackB=[]] Associates values with source counterparts.
22  * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
23  */
24 function baseMergeDeep(object, source, key, mergeFunc, customizer, stackA, stackB) {
25   var length = stackA.length,
26       srcValue = source[key];
27
28   while (length--) {
29     if (stackA[length] == srcValue) {
30       object[key] = stackB[length];
31       return;
32     }
33   }
34   var value = object[key],
35       result = customizer ? customizer(value, srcValue, key, object, source) : undefined,
36       isCommon = result === undefined;
37
38   if (isCommon) {
39     result = srcValue;
40     if (isArrayLike(srcValue) && (isArray(srcValue) || isTypedArray(srcValue))) {
41       result = isArray(value)
42         ? value
43         : (isArrayLike(value) ? arrayCopy(value) : []);
44     }
45     else if (isPlainObject(srcValue) || isArguments(srcValue)) {
46       result = isArguments(value)
47         ? toPlainObject(value)
48         : (isPlainObject(value) ? value : {});
49     }
50     else {
51       isCommon = false;
52     }
53   }
54   // Add the source value to the stack of traversed objects and associate
55   // it with its merged value.
56   stackA.push(srcValue);
57   stackB.push(result);
58
59   if (isCommon) {
60     // Recursively merge objects and arrays (susceptible to call stack limits).
61     object[key] = mergeFunc(result, srcValue, customizer, stackA, stackB);
62   } else if (result === result ? (result !== value) : (value === value)) {
63     object[key] = result;
64   }
65 }
66
67 module.exports = baseMergeDeep;