@@ -197,14 +197,17 @@ var JsDiff = (function() {
197
197
198
198
var objectPrototypeToString = Object . prototype . toString ;
199
199
200
- function canonicalize ( obj , stack ) {
200
+ // This function handles the presence of circular references by bailing out when encountering an
201
+ // object that is already on the "stack" of items being processed.
202
+ function canonicalize ( obj , stack , replacementStack ) {
201
203
stack = stack || [ ] ;
204
+ replacementStack = replacementStack || [ ] ;
202
205
203
206
var i ;
204
207
205
208
for ( var i = 0 ; i < stack . length ; i += 1 ) {
206
209
if ( stack [ i ] === obj ) {
207
- return obj ;
210
+ return replacementStack [ i ] ;
208
211
}
209
212
}
210
213
@@ -213,28 +216,32 @@ var JsDiff = (function() {
213
216
if ( '[object Array]' === objectPrototypeToString . call ( obj ) ) {
214
217
stack . push ( obj ) ;
215
218
canonicalizedObj = new Array ( obj . length ) ;
219
+ replacementStack . push ( canonicalizedObj ) ;
216
220
for ( i = 0 ; i < obj . length ; i += 1 ) {
217
- canonicalizedObj [ i ] = canonicalize ( obj [ i ] , stack ) ;
221
+ canonicalizedObj [ i ] = canonicalize ( obj [ i ] , stack , replacementStack ) ;
218
222
}
219
223
stack . pop ( ) ;
224
+ replacementStack . pop ( ) ;
220
225
} else if ( typeof obj === 'object' && obj !== null ) {
221
226
stack . push ( obj ) ;
222
227
canonicalizedObj = { } ;
228
+ replacementStack . push ( canonicalizedObj ) ;
223
229
var sortedKeys = [ ] ;
224
230
for ( var key in obj ) {
225
231
sortedKeys . push ( key ) ;
226
232
}
227
233
sortedKeys . sort ( ) ;
228
234
for ( i = 0 ; i < sortedKeys . length ; i += 1 ) {
229
235
var key = sortedKeys [ i ] ;
230
- canonicalizedObj [ key ] = canonicalize ( obj [ key ] , stack ) ;
236
+ canonicalizedObj [ key ] = canonicalize ( obj [ key ] , stack , replacementStack ) ;
231
237
}
232
238
stack . pop ( ) ;
239
+ replacementStack . pop ( ) ;
233
240
} else {
234
241
canonicalizedObj = obj ;
235
242
}
236
243
return canonicalizedObj ;
237
- }
244
+ } ;
238
245
239
246
return {
240
247
Diff : Diff ,
@@ -420,7 +427,9 @@ var JsDiff = (function() {
420
427
ret . push ( [ ( change . added ? 1 : change . removed ? - 1 : 0 ) , change . value ] ) ;
421
428
}
422
429
return ret ;
423
- }
430
+ } ,
431
+
432
+ canonicalize : canonicalize
424
433
} ;
425
434
} ) ( ) ;
426
435
0 commit comments