@@ -44,11 +44,16 @@ api.cache = new ActiveContextCache();
44
44
* @param options the context processing options.
45
45
* @param isPropertyTermScopedContext `true` if `localCtx` is a scoped context
46
46
* from a property term.
47
+ * @param isTypeScopedContext `true` if `localCtx` is a scoped context
48
+ * from a type.
47
49
*
48
50
* @return the new active context.
49
51
*/
50
- api . process = (
51
- { activeCtx, localCtx, options, isPropertyTermScopedContext = false } ) => {
52
+ api . process = ( {
53
+ activeCtx, localCtx, options,
54
+ isPropertyTermScopedContext = false ,
55
+ isTypeScopedContext = false
56
+ } ) => {
52
57
// normalize local context to an array of @context objects
53
58
if ( _isObject ( localCtx ) && '@context' in localCtx &&
54
59
_isArray ( localCtx [ '@context' ] ) ) {
@@ -233,7 +238,8 @@ api.process = (
233
238
// process all other keys
234
239
for ( const key in ctx ) {
235
240
api . createTermDefinition (
236
- rval , ctx , key , defined , options , isPropertyTermScopedContext ) ;
241
+ rval , ctx , key , defined , options ,
242
+ isPropertyTermScopedContext , isTypeScopedContext ) ;
237
243
}
238
244
239
245
// cache result
@@ -259,10 +265,13 @@ api.process = (
259
265
* signal a warning.
260
266
* @param isPropertyTermScopedContext `true` if `localCtx` is a scoped context
261
267
* from a property term.
268
+ * @param isTypeScopedContext `true` if `localCtx` is a scoped context
269
+ * from a type.
262
270
*/
263
271
api . createTermDefinition = (
264
272
activeCtx , localCtx , term , defined , options ,
265
- isPropertyTermScopedContext = false ) => {
273
+ isPropertyTermScopedContext = false ,
274
+ isTypeScopedContext = false ) => {
266
275
if ( defined . has ( term ) ) {
267
276
// term already defined
268
277
if ( defined . get ( term ) ) {
@@ -314,7 +323,11 @@ api.createTermDefinition = (
314
323
}
315
324
316
325
// remove old mapping
326
+ let previousMapping = null ;
317
327
if ( activeCtx . mappings . has ( term ) ) {
328
+ if ( isTypeScopedContext ) {
329
+ previousMapping = activeCtx . mappings . get ( term ) ;
330
+ }
318
331
activeCtx . mappings . delete ( term ) ;
319
332
}
320
333
@@ -349,6 +362,11 @@ api.createTermDefinition = (
349
362
// create new mapping
350
363
const mapping = { } ;
351
364
activeCtx . mappings . set ( term , mapping ) ;
365
+ if ( isTypeScopedContext ) {
366
+ activeCtx . hasTypeScopedTerms = true ;
367
+ mapping . isTypeScopedTerm = true ;
368
+ mapping . previousMapping = previousMapping ;
369
+ }
352
370
mapping . reverse = false ;
353
371
354
372
// make sure term definition only has expected keywords
@@ -762,6 +780,7 @@ api.getInitialContext = options => {
762
780
inverse : null ,
763
781
getInverse : _createInverseContext ,
764
782
clone : _cloneActiveContext ,
783
+ revertTypeScopedTerms : _revertTypeScopedTerms ,
765
784
protected : { }
766
785
} ;
767
786
// TODO: consider using LRU cache instead
@@ -937,6 +956,7 @@ api.getInitialContext = options => {
937
956
child . inverse = null ;
938
957
child . getInverse = this . getInverse ;
939
958
child . protected = util . clone ( this . protected ) ;
959
+ child . revertTypeScopedTerms = this . revertTypeScopedTerms ;
940
960
if ( '@language' in this ) {
941
961
child [ '@language' ] = this [ '@language' ] ;
942
962
}
@@ -945,6 +965,30 @@ api.getInitialContext = options => {
945
965
}
946
966
return child ;
947
967
}
968
+
969
+ /**
970
+ * Reverts any type-scoped terms in this active context to their previous
971
+ * mappings.
972
+ */
973
+ function _revertTypeScopedTerms ( ) {
974
+ // optimization: no type-scoped terms to remove, reuse active context
975
+ if ( ! this . hasTypeScopedTerms ) {
976
+ return this ;
977
+ }
978
+ // create clone without type scoped terms
979
+ const child = this . clone ( ) ;
980
+ const entries = child . mappings . entries ( ) ;
981
+ for ( const [ term , mapping ] of entries ) {
982
+ if ( mapping . isTypeScopedTerm ) {
983
+ if ( mapping . previousMapping ) {
984
+ child . mappings . set ( term , mapping . previousMapping ) ;
985
+ } else {
986
+ child . mappings . delete ( term ) ;
987
+ }
988
+ }
989
+ }
990
+ return child ;
991
+ }
948
992
} ;
949
993
950
994
/**
0 commit comments