1
+ /*
2
+ Clone NPM module.
3
+
4
+ https://www.npmjs.com/package/clone (2.1.1)
5
+
6
+ Copyright © 2011-2015 Paul Vorbach <[email protected] >
7
+
8
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
9
+ this software and associated documentation files (the “Software”), to deal in
10
+ the Software without restriction, including without limitation the rights to
11
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
12
+ the Software, and to permit persons to whom the Software is furnished to do so,
13
+ subject to the following conditions:
14
+
15
+ The above copyright notice and this permission notice shall be included in all
16
+ copies or substantial portions of the Software.
17
+
18
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
20
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
21
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
22
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, OUT OF OR IN CONNECTION WITH THE
23
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
+ */
25
+
26
+ var clone = ( function ( ) {
27
+ 'use strict' ;
28
+
29
+ function _instanceof ( obj , type ) {
30
+ return type != null && obj instanceof type ;
31
+ }
32
+
33
+ var nativeMap ;
34
+ try {
35
+ nativeMap = Map ;
36
+ } catch ( _ ) {
37
+ // maybe a reference error because no `Map`. Give it a dummy value that no
38
+ // value will ever be an instanceof.
39
+ nativeMap = function ( ) { } ;
40
+ }
41
+
42
+ var nativeSet ;
43
+ try {
44
+ nativeSet = Set ;
45
+ } catch ( _ ) {
46
+ nativeSet = function ( ) { } ;
47
+ }
48
+
49
+ var nativePromise ;
50
+ try {
51
+ nativePromise = Promise ;
52
+ } catch ( _ ) {
53
+ nativePromise = function ( ) { } ;
54
+ }
55
+
56
+ /**
57
+ * Clones (copies) an Object using deep copying.
58
+ *
59
+ * This function supports circular references by default, but if you are certain
60
+ * there are no circular references in your object, you can save some CPU time
61
+ * by calling clone(obj, false).
62
+ *
63
+ * Caution: if `circular` is false and `parent` contains circular references,
64
+ * your program may enter an infinite loop and crash.
65
+ *
66
+ * @param `parent` - the object to be cloned
67
+ * @param `circular` - set to true if the object to be cloned may contain
68
+ * circular references. (optional - true by default)
69
+ * @param `depth` - set to a number if the object is only to be cloned to
70
+ * a particular depth. (optional - defaults to Infinity)
71
+ * @param `prototype` - sets the prototype to be used when cloning an object.
72
+ * (optional - defaults to parent prototype).
73
+ * @param `includeNonEnumerable` - set to true if the non-enumerable properties
74
+ * should be cloned as well. Non-enumerable properties on the prototype
75
+ * chain will be ignored. (optional - false by default)
76
+ */
77
+ function clone ( parent , circular , depth , prototype , includeNonEnumerable ) {
78
+ if ( typeof circular === 'object' ) {
79
+ depth = circular . depth ;
80
+ prototype = circular . prototype ;
81
+ includeNonEnumerable = circular . includeNonEnumerable ;
82
+ circular = circular . circular ;
83
+ }
84
+ // maintain two arrays for circular references, where corresponding parents
85
+ // and children have the same index
86
+ var allParents = [ ] ;
87
+ var allChildren = [ ] ;
88
+
89
+ var useBuffer = typeof Buffer != 'undefined' ;
90
+
91
+ if ( typeof circular == 'undefined' )
92
+ circular = true ;
93
+
94
+ if ( typeof depth == 'undefined' )
95
+ depth = Infinity ;
96
+
97
+ // recurse this function so we don't reset allParents and allChildren
98
+ function _clone ( parent , depth ) {
99
+ // cloning null always returns null
100
+ if ( parent === null )
101
+ return null ;
102
+
103
+ if ( depth === 0 )
104
+ return parent ;
105
+
106
+ var child ;
107
+ var proto ;
108
+ if ( typeof parent != 'object' ) {
109
+ return parent ;
110
+ }
111
+
112
+ if ( _instanceof ( parent , nativeMap ) ) {
113
+ child = new nativeMap ( ) ;
114
+ } else if ( _instanceof ( parent , nativeSet ) ) {
115
+ child = new nativeSet ( ) ;
116
+ } else if ( _instanceof ( parent , nativePromise ) ) {
117
+ child = new nativePromise ( function ( resolve , reject ) {
118
+ parent . then ( function ( value ) {
119
+ resolve ( _clone ( value , depth - 1 ) ) ;
120
+ } , function ( err ) {
121
+ reject ( _clone ( err , depth - 1 ) ) ;
122
+ } ) ;
123
+ } ) ;
124
+ } else if ( clone . __isArray ( parent ) ) {
125
+ child = [ ] ;
126
+ } else if ( clone . __isRegExp ( parent ) ) {
127
+ child = new RegExp ( parent . source , __getRegExpFlags ( parent ) ) ;
128
+ if ( parent . lastIndex ) child . lastIndex = parent . lastIndex ;
129
+ } else if ( clone . __isDate ( parent ) ) {
130
+ child = new Date ( parent . getTime ( ) ) ;
131
+ } else if ( useBuffer && Buffer . isBuffer ( parent ) ) {
132
+ child = new Buffer ( parent . length ) ;
133
+ parent . copy ( child ) ;
134
+ return child ;
135
+ } else if ( _instanceof ( parent , Error ) ) {
136
+ child = Object . create ( parent ) ;
137
+ } else {
138
+ if ( typeof prototype == 'undefined' ) {
139
+ proto = Object . getPrototypeOf ( parent ) ;
140
+ child = Object . create ( proto ) ;
141
+ }
142
+ else {
143
+ child = Object . create ( prototype ) ;
144
+ proto = prototype ;
145
+ }
146
+ }
147
+
148
+ if ( circular ) {
149
+ var index = allParents . indexOf ( parent ) ;
150
+
151
+ if ( index != - 1 ) {
152
+ return allChildren [ index ] ;
153
+ }
154
+ allParents . push ( parent ) ;
155
+ allChildren . push ( child ) ;
156
+ }
157
+
158
+ if ( _instanceof ( parent , nativeMap ) ) {
159
+ parent . forEach ( function ( value , key ) {
160
+ var keyChild = _clone ( key , depth - 1 ) ;
161
+ var valueChild = _clone ( value , depth - 1 ) ;
162
+ child . set ( keyChild , valueChild ) ;
163
+ } ) ;
164
+ }
165
+ if ( _instanceof ( parent , nativeSet ) ) {
166
+ parent . forEach ( function ( value ) {
167
+ var entryChild = _clone ( value , depth - 1 ) ;
168
+ child . add ( entryChild ) ;
169
+ } ) ;
170
+ }
171
+
172
+ for ( var i in parent ) {
173
+ var attrs ;
174
+ if ( proto ) {
175
+ attrs = Object . getOwnPropertyDescriptor ( proto , i ) ;
176
+ }
177
+
178
+ if ( attrs && attrs . set == null ) {
179
+ continue ;
180
+ }
181
+ child [ i ] = _clone ( parent [ i ] , depth - 1 ) ;
182
+ }
183
+
184
+ if ( Object . getOwnPropertySymbols ) {
185
+ var symbols = Object . getOwnPropertySymbols ( parent ) ;
186
+ for ( var i = 0 ; i < symbols . length ; i ++ ) {
187
+ // Don't need to worry about cloning a symbol because it is a primitive,
188
+ // like a number or string.
189
+ var symbol = symbols [ i ] ;
190
+ var descriptor = Object . getOwnPropertyDescriptor ( parent , symbol ) ;
191
+ if ( descriptor && ! descriptor . enumerable && ! includeNonEnumerable ) {
192
+ continue ;
193
+ }
194
+ child [ symbol ] = _clone ( parent [ symbol ] , depth - 1 ) ;
195
+ if ( ! descriptor . enumerable ) {
196
+ Object . defineProperty ( child , symbol , {
197
+ enumerable : false
198
+ } ) ;
199
+ }
200
+ }
201
+ }
202
+
203
+ if ( includeNonEnumerable ) {
204
+ var allPropertyNames = Object . getOwnPropertyNames ( parent ) ;
205
+ for ( var i = 0 ; i < allPropertyNames . length ; i ++ ) {
206
+ var propertyName = allPropertyNames [ i ] ;
207
+ var descriptor = Object . getOwnPropertyDescriptor ( parent , propertyName ) ;
208
+ if ( descriptor && descriptor . enumerable ) {
209
+ continue ;
210
+ }
211
+ child [ propertyName ] = _clone ( parent [ propertyName ] , depth - 1 ) ;
212
+ Object . defineProperty ( child , propertyName , {
213
+ enumerable : false
214
+ } ) ;
215
+ }
216
+ }
217
+
218
+ return child ;
219
+ }
220
+
221
+ return _clone ( parent , depth ) ;
222
+ }
223
+
224
+ /**
225
+ * Simple flat clone using prototype, accepts only objects, usefull for property
226
+ * override on FLAT configuration object (no nested props).
227
+ *
228
+ * USE WITH CAUTION! This may not behave as you wish if you do not know how this
229
+ * works.
230
+ */
231
+ clone . clonePrototype = function clonePrototype ( parent ) {
232
+ if ( parent === null )
233
+ return null ;
234
+
235
+ var c = function ( ) { } ;
236
+ c . prototype = parent ;
237
+ return new c ( ) ;
238
+ } ;
239
+
240
+ // private utility functions
241
+
242
+ function __objToStr ( o ) {
243
+ return Object . prototype . toString . call ( o ) ;
244
+ }
245
+ clone . __objToStr = __objToStr ;
246
+
247
+ function __isDate ( o ) {
248
+ return typeof o === 'object' && __objToStr ( o ) === '[object Date]' ;
249
+ }
250
+ clone . __isDate = __isDate ;
251
+
252
+ function __isArray ( o ) {
253
+ return typeof o === 'object' && __objToStr ( o ) === '[object Array]' ;
254
+ }
255
+ clone . __isArray = __isArray ;
256
+
257
+ function __isRegExp ( o ) {
258
+ return typeof o === 'object' && __objToStr ( o ) === '[object RegExp]' ;
259
+ }
260
+ clone . __isRegExp = __isRegExp ;
261
+
262
+ function __getRegExpFlags ( re ) {
263
+ var flags = '' ;
264
+ if ( re . global ) flags += 'g' ;
265
+ if ( re . ignoreCase ) flags += 'i' ;
266
+ if ( re . multiline ) flags += 'm' ;
267
+ return flags ;
268
+ }
269
+ clone . __getRegExpFlags = __getRegExpFlags ;
270
+
271
+ return clone ;
272
+ } ) ( ) ;
273
+
274
+ if ( typeof module === 'object' && module . exports ) {
275
+ module . exports = clone ;
276
+ }
0 commit comments