diff options
Diffstat (limited to 'node_modules/clone/clone.js')
-rw-r--r-- | node_modules/clone/clone.js | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/node_modules/clone/clone.js b/node_modules/clone/clone.js new file mode 100644 index 000000000..f8fa3159a --- /dev/null +++ b/node_modules/clone/clone.js @@ -0,0 +1,144 @@ +'use strict'; + +function objectToString(o) { + return Object.prototype.toString.call(o); +} + +// shim for Node's 'util' package +// DO NOT REMOVE THIS! It is required for compatibility with EnderJS (http://enderjs.com/). +var util = { + isArray: function (ar) { + return Array.isArray(ar) || (typeof ar === 'object' && objectToString(ar) === '[object Array]'); + }, + isDate: function (d) { + return typeof d === 'object' && objectToString(d) === '[object Date]'; + }, + isRegExp: function (re) { + return typeof re === 'object' && objectToString(re) === '[object RegExp]'; + }, + getRegExpFlags: function (re) { + var flags = ''; + re.global && (flags += 'g'); + re.ignoreCase && (flags += 'i'); + re.multiline && (flags += 'm'); + return flags; + } +}; + + +if (typeof module === 'object') + module.exports = clone; + +/** + * Clones (copies) an Object using deep copying. + * + * This function supports circular references by default, but if you are certain + * there are no circular references in your object, you can save some CPU time + * by calling clone(obj, false). + * + * Caution: if `circular` is false and `parent` contains circular references, + * your program may enter an infinite loop and crash. + * + * @param `parent` - the object to be cloned + * @param `circular` - set to true if the object to be cloned may contain + * circular references. (optional - true by default) + * @param `depth` - set to a number if the object is only to be cloned to + * a particular depth. (optional - defaults to Infinity) + * @param `prototype` - sets the prototype to be used when cloning an object. + * (optional - defaults to parent prototype). +*/ + +function clone(parent, circular, depth, prototype) { + // maintain two arrays for circular references, where corresponding parents + // and children have the same index + var allParents = []; + var allChildren = []; + + var useBuffer = typeof Buffer != 'undefined'; + + if (typeof circular == 'undefined') + circular = true; + + if (typeof depth == 'undefined') + depth = Infinity; + + // recurse this function so we don't reset allParents and allChildren + function _clone(parent, depth) { + // cloning null always returns null + if (parent === null) + return null; + + if (depth == 0) + return parent; + + var child; + var proto; + if (typeof parent != 'object') { + return parent; + } + + if (util.isArray(parent)) { + child = []; + } else if (util.isRegExp(parent)) { + child = new RegExp(parent.source, util.getRegExpFlags(parent)); + if (parent.lastIndex) child.lastIndex = parent.lastIndex; + } else if (util.isDate(parent)) { + child = new Date(parent.getTime()); + } else if (useBuffer && Buffer.isBuffer(parent)) { + child = new Buffer(parent.length); + parent.copy(child); + return child; + } else { + if (typeof prototype == 'undefined') { + proto = Object.getPrototypeOf(parent); + child = Object.create(proto); + } + else { + child = Object.create(prototype); + proto = prototype; + } + } + + if (circular) { + var index = allParents.indexOf(parent); + + if (index != -1) { + return allChildren[index]; + } + allParents.push(parent); + allChildren.push(child); + } + + for (var i in parent) { + var attrs; + if (proto) { + attrs = Object.getOwnPropertyDescriptor(proto, i); + } + + if (attrs && attrs.set == null) { + continue; + } + child[i] = _clone(parent[i], depth - 1); + } + + return child; + } + + return _clone(parent, depth); +} + +/** + * Simple flat clone using prototype, accepts only objects, usefull for property + * override on FLAT configuration object (no nested props). + * + * USE WITH CAUTION! This may not behave as you wish if you do not know how this + * works. + */ +clone.clonePrototype = function(parent) { + if (parent === null) + return null; + + var c = function () {}; + c.prototype = parent; + return new c(); +}; |