2525
2626/******************************************************************************/ 
2727
28+ { 
29+ // >>>>> start of local scope 
30+ 
31+ /******************************************************************************/ 
32+ 
33+ const  redirectNames  =  new  Map ( ) ; 
34+ const  scriptletNames  =  new  Map ( ) ; 
35+ const  preparseDirectiveNames  =  new  Set ( ) ; 
36+ 
37+ /******************************************************************************/ 
38+ 
2839CodeMirror . defineMode ( 'ubo-static-filtering' ,  function ( )  { 
2940    const  StaticFilteringParser  =  typeof  vAPI  ===  'object' 
3041        ? vAPI . StaticFilteringParser 
3142        : self . StaticFilteringParser ; 
3243    if  (  StaticFilteringParser  instanceof  Object  ===  false  )  {  return ;  } 
3344    const  parser  =  new  StaticFilteringParser ( {  interactive : true  } ) ; 
3445
35-     const  reDirective  =  / ^ ! # (?: i f | e n d i f | i n c l u d e ) \b / ; 
46+     const  rePreparseDirectives  =  / ^ ! # (?: i f | e n d i f | i n c l u d e ) \b / ; 
47+     const  rePreparseIfDirective  =  / ^ ( ! # i f   ! ? ) ( .+ ) $ / ; 
3648    let  parserSlot  =  0 ; 
3749    let  netOptionValueMode  =  false ; 
3850
51+     const  colorCommentSpan  =  function ( stream )  { 
52+         if  (  rePreparseDirectives . test ( stream . string )  ===  false  )  { 
53+             stream . skipToEnd ( ) ; 
54+             return  'comment' ; 
55+         } 
56+         const  match  =  rePreparseIfDirective . exec ( stream . string ) ; 
57+         if  (  match  ===  null  )  { 
58+             stream . skipToEnd ( ) ; 
59+             return  'variable strong' ; 
60+         } 
61+         if  (  stream . pos  <  match [ 1 ] . length  )  { 
62+             stream . pos  =  match [ 1 ] . length ; 
63+             return  'variable strong' ; 
64+         } 
65+         stream . skipToEnd ( ) ; 
66+         if  ( 
67+             preparseDirectiveNames . size  ===  0  || 
68+             preparseDirectiveNames . has ( match [ 2 ] . trim ( ) ) 
69+         )  { 
70+             return  'variable strong' ; 
71+         } 
72+         return  'error strong' ; 
73+     } ; 
74+ 
3975    const  colorExtHTMLPatternSpan  =  function ( stream )  { 
4076        const  {  i }  =  parser . patternSpan ; 
4177        if  (  stream . pos  ===  parser . slices [ i + 1 ]  )  { 
@@ -202,10 +238,7 @@ CodeMirror.defineMode('ubo-static-filtering', function() {
202238            return  'comment' ; 
203239        } 
204240        if  (  parser . category  ===  parser . CATComment  )  { 
205-             stream . skipToEnd ( ) ; 
206-             return  reDirective . test ( stream . string ) 
207-                 ? 'variable strong' 
208-                 : 'comment' ; 
241+             return  colorCommentSpan ( stream ) ; 
209242        } 
210243        if  (  ( parser . slices [ parserSlot ]  &  parser . BITIgnore )  !==  0  )  { 
211244            stream . pos  +=  parser . slices [ parserSlot + 2 ] ; 
@@ -243,6 +276,23 @@ CodeMirror.defineMode('ubo-static-filtering', function() {
243276            style  =  style . trim ( ) ; 
244277            return  style  !==  ''  ? style  : null ; 
245278        } , 
279+         setHints : function ( details )  { 
280+             for  (  const  [  name ,  desc  ]  of  details . redirectResources  )  { 
281+                 const  displayText  =  desc . aliasOf  !==  '' 
282+                     ? `${ name }   (${ desc . aliasOf }  )` 
283+                     : '' ; 
284+                 if  (  desc . canRedirect  )  { 
285+                     redirectNames . set ( name ,  displayText ) ; 
286+                 } 
287+                 if  (  desc . canInject  &&  name . endsWith ( '.js' )  )  { 
288+                     scriptletNames . set ( name . slice ( 0 ,  - 3 ) ,  displayText ) ; 
289+                 } 
290+             } 
291+             details . preparseDirectives . forEach ( a  =>  { 
292+                 preparseDirectiveNames . add ( a ) ; 
293+             } ) ; 
294+             initHints ( ) ; 
295+         } , 
246296    } ; 
247297} ) ; 
248298
@@ -251,17 +301,13 @@ CodeMirror.defineMode('ubo-static-filtering', function() {
251301// Following code is for auto-completion. Reference: 
252302//   https://codemirror.net/demo/complete.html 
253303
254- ( (  )  =>  { 
255-     if  (  typeof  vAPI  !==  'object'  )  {  return ;  } 
256- 
304+ const  initHints  =  function ( )  { 
257305    const  StaticFilteringParser  =  typeof  vAPI  ===  'object' 
258306        ? vAPI . StaticFilteringParser 
259307        : self . StaticFilteringParser ; 
260308    if  (  StaticFilteringParser  instanceof  Object  ===  false  )  {  return ;  } 
261309
262310    const  parser  =  new  StaticFilteringParser ( ) ; 
263-     const  redirectNames  =  new  Map ( ) ; 
264-     const  scriptletNames  =  new  Map ( ) ; 
265311    const  proceduralOperatorNames  =  new  Map ( 
266312        Array . from ( parser . proceduralOperatorTokens ) . filter ( item  =>  { 
267313            return  ( item [ 1 ]  &  0b01 )  !==  0 ; 
@@ -380,7 +426,28 @@ CodeMirror.defineMode('ubo-static-filtering', function() {
380426        return  pickBestHints ( cursor ,  matchLeft [ 1 ] ,  matchRight [ 1 ] ,  hints ) ; 
381427    } ; 
382428
383-     const  getHints  =  function ( cm )  { 
429+     const  getCommentHints  =  function ( cursor ,  line )  { 
430+         const  beg  =  cursor . ch ; 
431+         if  (  line . startsWith ( '!#if ' )  )  { 
432+             const  matchLeft  =  / ^ ! # i f   ! ? ( \w * ) $ / . exec ( line . slice ( 0 ,  beg ) ) ; 
433+             const  matchRight  =  / ^ \w * / . exec ( line . slice ( beg ) ) ; 
434+             if  (  matchLeft  ===  null  ||  matchRight  ===  null  )  {  return ;  } 
435+             const  hints  =  [ ] ; 
436+             for  (  const  hint  of  preparseDirectiveNames  )  { 
437+                 hints . push ( hint ) ; 
438+             } 
439+             return  pickBestHints ( cursor ,  matchLeft [ 1 ] ,  matchRight [ 0 ] ,  hints ) ; 
440+         } 
441+         if  (  line . startsWith ( '!#' )  &&  line  !==  '!#endif'  )  { 
442+             const  matchLeft  =  / ^ ! # ( \w * ) $ / . exec ( line . slice ( 0 ,  beg ) ) ; 
443+             const  matchRight  =  / ^ \w * / . exec ( line . slice ( beg ) ) ; 
444+             if  (  matchLeft  ===  null  ||  matchRight  ===  null  )  {  return ;  } 
445+             const  hints  =  [  'if ' ,  'endif\n' ,  'include '  ] ; 
446+             return  pickBestHints ( cursor ,  matchLeft [ 1 ] ,  matchRight [ 0 ] ,  hints ) ; 
447+         } 
448+     } ; 
449+ 
450+     CodeMirror . registerHelper ( 'hint' ,  'ubo-static-filtering' ,  function ( cm )  { 
384451        const  cursor  =  cm . getCursor ( ) ; 
385452        const  line  =  cm . getLine ( cursor . line ) ; 
386453        parser . analyze ( line ) ; 
@@ -393,25 +460,15 @@ CodeMirror.defineMode('ubo-static-filtering', function() {
393460        if  (  parser . category  ===  parser . CATStaticNetFilter  )  { 
394461            return  getNetHints ( cursor ,  line ) ; 
395462        } 
396-     } ; 
397- 
398-     vAPI . messaging . send ( 'dashboard' ,  { 
399-         what : 'getResourceDetails' 
400-     } ) . then ( response  =>  { 
401-         if  (  Array . isArray ( response )  ===  false  )  {  return ;  } 
402-         for  (  const  [  name ,  details  ]  of  response  )  { 
403-             const  displayText  =  details . aliasOf  !==  '' 
404-                 ? `${ name }   (${ details . aliasOf }  )` 
405-                 : '' ; 
406-             if  (  details . canRedirect  )  { 
407-                 redirectNames . set ( name ,  displayText ) ; 
408-             } 
409-             if  (  details . canInject  &&  name . endsWith ( '.js' )  )  { 
410-                 scriptletNames . set ( name . slice ( 0 ,  - 3 ) ,  displayText ) ; 
411-             } 
463+         if  (  parser . category  ===  parser . CATComment  )  { 
464+             return  getCommentHints ( cursor ,  line ) ; 
412465        } 
413-         CodeMirror . registerHelper ( 'hint' ,  'ubo-static-filtering' ,  getHints ) ; 
414466    } ) ; 
415- } ) ( ) ; 
467+ } ; 
468+ 
469+ /******************************************************************************/ 
470+ 
471+ // <<<<< end of local scope 
472+ } 
416473
417474/******************************************************************************/ 
0 commit comments