@@ -44,11 +44,16 @@ api.cache = new ActiveContextCache();
4444 * @param options the context processing options.
4545 * @param isPropertyTermScopedContext `true` if `localCtx` is a scoped context
4646 * from a property term.
47+ * @param isTypeScopedContext `true` if `localCtx` is a scoped context
48+ * from a type.
4749 *
4850 * @return the new active context.
4951 */
50- api . process = (
51- { activeCtx, localCtx, options, isPropertyTermScopedContext = false } ) => {
52+ api . process = ( {
53+ activeCtx, localCtx, options,
54+ isPropertyTermScopedContext = false ,
55+ isTypeScopedContext = false
56+ } ) => {
5257 // normalize local context to an array of @context objects
5358 if ( _isObject ( localCtx ) && '@context' in localCtx &&
5459 _isArray ( localCtx [ '@context' ] ) ) {
@@ -233,7 +238,8 @@ api.process = (
233238 // process all other keys
234239 for ( const key in ctx ) {
235240 api . createTermDefinition (
236- rval , ctx , key , defined , options , isPropertyTermScopedContext ) ;
241+ rval , ctx , key , defined , options ,
242+ isPropertyTermScopedContext , isTypeScopedContext ) ;
237243 }
238244
239245 // cache result
@@ -259,10 +265,13 @@ api.process = (
259265 * signal a warning.
260266 * @param isPropertyTermScopedContext `true` if `localCtx` is a scoped context
261267 * from a property term.
268+ * @param isTypeScopedContext `true` if `localCtx` is a scoped context
269+ * from a type.
262270 */
263271api . createTermDefinition = (
264272 activeCtx , localCtx , term , defined , options ,
265- isPropertyTermScopedContext = false ) => {
273+ isPropertyTermScopedContext = false ,
274+ isTypeScopedContext = false ) => {
266275 if ( defined . has ( term ) ) {
267276 // term already defined
268277 if ( defined . get ( term ) ) {
@@ -314,7 +323,11 @@ api.createTermDefinition = (
314323 }
315324
316325 // remove old mapping
326+ let previousMapping = null ;
317327 if ( activeCtx . mappings . has ( term ) ) {
328+ if ( isTypeScopedContext ) {
329+ previousMapping = activeCtx . mappings . get ( term ) ;
330+ }
318331 activeCtx . mappings . delete ( term ) ;
319332 }
320333
@@ -349,6 +362,11 @@ api.createTermDefinition = (
349362 // create new mapping
350363 const mapping = { } ;
351364 activeCtx . mappings . set ( term , mapping ) ;
365+ if ( isTypeScopedContext ) {
366+ activeCtx . hasTypeScopedTerms = true ;
367+ mapping . isTypeScopedTerm = true ;
368+ mapping . previousMapping = previousMapping ;
369+ }
352370 mapping . reverse = false ;
353371
354372 // make sure term definition only has expected keywords
@@ -762,6 +780,7 @@ api.getInitialContext = options => {
762780 inverse : null ,
763781 getInverse : _createInverseContext ,
764782 clone : _cloneActiveContext ,
783+ revertTypeScopedTerms : _revertTypeScopedTerms ,
765784 protected : { }
766785 } ;
767786 // TODO: consider using LRU cache instead
@@ -937,6 +956,7 @@ api.getInitialContext = options => {
937956 child . inverse = null ;
938957 child . getInverse = this . getInverse ;
939958 child . protected = util . clone ( this . protected ) ;
959+ child . revertTypeScopedTerms = this . revertTypeScopedTerms ;
940960 if ( '@language' in this ) {
941961 child [ '@language' ] = this [ '@language' ] ;
942962 }
@@ -945,6 +965,30 @@ api.getInitialContext = options => {
945965 }
946966 return child ;
947967 }
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+ }
948992} ;
949993
950994/**
0 commit comments