@@ -664,7 +664,7 @@ api.createTermDefinition = (
664664 // be equal
665665 activeCtx . protected [ term ] = true ;
666666 mapping . protected = true ;
667- if ( ! _areTermDefinitionsEqual ( previousMapping , mapping ) ) {
667+ if ( ! _deepCompare ( previousMapping , mapping ) ) {
668668 const protectedMode = ( options && options . protectedMode ) || 'error' ;
669669 if ( protectedMode === 'error' ) {
670670 throw new JsonLdError (
@@ -1317,42 +1317,45 @@ function _findContextUrls(input, urls, replace, base) {
13171317 }
13181318}
13191319
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 ) ) {
13241329 return false ;
13251330 }
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 ) {
13391333 return false ;
13401334 }
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 ] ) ) {
13441337 return false ;
13451338 }
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 ( ) ;
13521356 }
13531357 }
1354- // strings
1355- if ( v1 !== v2 ) {
1358+ if ( ! _deepCompare ( v1 , v2 ) ) {
13561359 return false ;
13571360 }
13581361 }
0 commit comments