@@ -664,7 +664,7 @@ api.createTermDefinition = (
664
664
// be equal
665
665
activeCtx . protected [ term ] = true ;
666
666
mapping . protected = true ;
667
- if ( ! _areTermDefinitionsEqual ( previousMapping , mapping ) ) {
667
+ if ( ! _deepCompare ( previousMapping , mapping ) ) {
668
668
const protectedMode = ( options && options . protectedMode ) || 'error' ;
669
669
if ( protectedMode === 'error' ) {
670
670
throw new JsonLdError (
@@ -1317,42 +1317,45 @@ function _findContextUrls(input, urls, replace, base) {
1317
1317
}
1318
1318
}
1319
1319
1320
- function _areTermDefinitionsEqual ( d1 , d2 ) {
1321
- const k1 = Object . keys ( d1 ) ;
1322
- const k2 = Object . keys ( d2 ) ;
1323
- if ( k1 . length !== k2 . length ) {
1320
+ function _deepCompare ( x1 , x2 ) {
1321
+ // compare `null` or primitive types directly
1322
+ if ( ( ! ( x1 && typeof x1 === 'object' ) ) ||
1323
+ ( ! ( x2 && typeof x2 === 'object' ) ) ) {
1324
+ return x1 === x2 ;
1325
+ }
1326
+ // x1 and x2 are objects (also potentially arrays)
1327
+ const x1Array = Array . isArray ( x1 ) ;
1328
+ if ( x1Array !== Array . isArray ( x2 ) ) {
1324
1329
return false ;
1325
1330
}
1326
-
1327
- for ( const k of k1 ) {
1328
- const v1 = d1 [ k ] ;
1329
- const v2 = d2 [ k ] ;
1330
- if ( k === '@context' ) {
1331
- // FIXME: temporary hack, use deep comparison instead
1332
- if ( JSON . stringify ( v1 ) !== JSON . stringify ( v2 ) ) {
1333
- return false ;
1334
- }
1335
- continue ;
1336
- }
1337
- const isArray = Array . isArray ( v1 ) ;
1338
- if ( isArray !== Array . isArray ( v2 ) ) {
1331
+ if ( x1Array ) {
1332
+ if ( x1 . length !== x2 . length ) {
1339
1333
return false ;
1340
1334
}
1341
- // `@container`
1342
- if ( isArray ) {
1343
- if ( v1 . length !== v2 . length ) {
1335
+ for ( let i = 0 ; i < x1 . length ; ++ i ) {
1336
+ if ( ! _deepCompare ( x1 [ i ] , x2 [ i ] ) ) {
1344
1337
return false ;
1345
1338
}
1346
- v1 . sort ( ) ;
1347
- v2 . sort ( ) ;
1348
- for ( let i = 0 ; i < v1 . length ; ++ i ) {
1349
- if ( v1 [ i ] !== v2 [ i ] ) {
1350
- return false ;
1351
- }
1339
+ }
1340
+ return true ;
1341
+ }
1342
+ // x1 and x2 are non-array objects
1343
+ const k1s = Object . keys ( x1 ) ;
1344
+ const k2s = Object . keys ( x2 ) ;
1345
+ if ( k1s . length !== k2s . length ) {
1346
+ return false ;
1347
+ }
1348
+ for ( const k1 in x1 ) {
1349
+ let v1 = x1 [ k1 ] ;
1350
+ let v2 = x2 [ k1 ] ;
1351
+ // special case: `@container` can be in any order
1352
+ if ( k1 === '@container' ) {
1353
+ if ( Array . isArray ( v1 ) && Array . isArray ( v2 ) ) {
1354
+ v1 = v1 . slice ( ) . sort ( ) ;
1355
+ v2 = v2 . slice ( ) . sort ( ) ;
1352
1356
}
1353
1357
}
1354
- // strings
1355
- if ( v1 !== v2 ) {
1358
+ if ( ! _deepCompare ( v1 , v2 ) ) {
1356
1359
return false ;
1357
1360
}
1358
1361
}
0 commit comments