11import  *  as  vscode  from  "vscode" ; 
22import  {  AtelierAPI  }  from  "../api" ; 
33import  {  iscIcon  }  from  "../extension" ; 
4- import  {  outputChannel ,  outputConsole ,  notIsfs ,  handleError ,  openLowCodeEditors  }  from  "../utils" ; 
4+ import  {  outputChannel ,  outputConsole ,  notIsfs ,  handleError ,  openLowCodeEditors ,   stringifyError  }  from  "../utils" ; 
55import  {  DocumentContentProvider  }  from  "../providers/DocumentContentProvider" ; 
66import  {  UserAction  }  from  "../api/atelier" ; 
77import  {  isfsDocumentName  }  from  "../providers/FileSystemProvider/FileSystemProvider" ; 
@@ -113,7 +113,7 @@ export class StudioActions {
113113    ) ; 
114114  } 
115115
116-   public  processUserAction ( userAction : UserAction ) : Thenable < any >  { 
116+   public  async   processUserAction ( userAction : UserAction ) : Promise < any >  { 
117117    const  serverAction  =  userAction . action ; 
118118    const  {  target,  errorText }  =  userAction ; 
119119    if  ( errorText  !==  "" )  { 
@@ -128,7 +128,22 @@ export class StudioActions {
128128        return  vscode . window 
129129          . showWarningMessage ( target ,  {  modal : true  } ,  "Yes" ,  "No" ) 
130130          . then ( ( answer )  =>  ( answer  ===  "Yes"  ? "1"  : answer  ===  "No"  ? "0"  : "2" ) ) ; 
131-       case  2 : // Run a CSP page/Template. The Target is the full path of CSP page/template on the connected server 
131+       case  2 : { 
132+         // Run a CSP page/Template. The Target is the full path of CSP page/template on the connected server 
133+ 
134+         // Do this ourself instead of using our new getCSPToken wrapper function, because that function reuses tokens which causes issues with 
135+         // webview when server is 2020.1.1 or greater, as session cookie scope is typically Strict, meaning that the webview 
136+         // cannot store the cookie. Consequence is web sessions may build up (they get a 900 second timeout) 
137+         const  cspchd  =  await  this . api 
138+           . actionQuery ( "select %Atelier_v1_Utils.General_GetCSPToken(?) token" ,  [ target ] ) 
139+           . then ( ( data )  =>  data . result . content [ 0 ] . token ) 
140+           . catch ( ( error )  =>  { 
141+             outputChannel . appendLine ( 
142+               `Failed to construct a CSP session for server-side source control User Action 2 (show a CSP page) on page '${ target } ${ stringifyError ( error ) }  
143+             ) ; 
144+             outputChannel . show ( true ) ; 
145+           } ) ; 
146+         if  ( ! cspchd )  return  "2" ; 
132147        return  new  Promise ( ( resolve )  =>  { 
133148          let  answer  =  "2" ; 
134149          const  column  =  vscode . window . activeTextEditor  ? vscode . window . activeTextEditor . viewColumn  : undefined ; 
@@ -157,16 +172,10 @@ export class StudioActions {
157172          const  url  =  new  URL ( 
158173            `${ config . https  ? "https"  : "http" } ${ config . host } ${ config . port } ${ config . pathPrefix } ${ target }  
159174          ) ; 
160- 
161-           // Do this ourself instead of using our new getCSPToken wrapper function, because that function reuses tokens which causes issues with 
162-           // webview when server is 2020.1.1 or greater, as session cookie scope is typically Strict, meaning that the webview 
163-           // cannot store the cookie. Consequence is web sessions may build up (they get a 900 second timeout) 
164-           this . api . actionQuery ( "select %Atelier_v1_Utils.General_GetCSPToken(?) token" ,  [ target ] ) . then ( ( tokenObj )  =>  { 
165-             const  csptoken  =  tokenObj . result . content [ 0 ] . token ; 
166-             url . searchParams . set ( "CSPCHD" ,  csptoken ) ; 
167-             url . searchParams . set ( "CSPSHARE" ,  "1" ) ; 
168-             url . searchParams . set ( "Namespace" ,  this . api . config . ns ) ; 
169-             panel . webview . html  =  ` 
175+           url . searchParams . set ( "CSPCHD" ,  cspchd ) ; 
176+           url . searchParams . set ( "CSPSHARE" ,  "1" ) ; 
177+           url . searchParams . set ( "Namespace" ,  this . api . ns ) ; 
178+           panel . webview . html  =  ` 
170179              <!DOCTYPE html> 
171180              <html lang="en"> 
172181              <head> 
@@ -194,18 +203,21 @@ export class StudioActions {
194203              </body> 
195204              </html> 
196205              ` ; 
197-           } ) ; 
198206        } ) ; 
207+       } 
199208      case  3 : { 
200209        // Run an EXE on the client. 
201-         const  urlRegex  =  / ^ ( h t | f ) t p ( s ? ) : \/ \/ / gim; 
202-         if  ( target . search ( urlRegex )  ===  0 )  { 
210+         if  ( / ^ ( h t | f ) t p s ? : \/ \/ / i. test ( target ) )  { 
203211          // Allow target that is a URL to be opened in an external browser 
204212          vscode . env . openExternal ( vscode . Uri . parse ( target ) ) ; 
205-           break ; 
206213        }  else  { 
207-           throw  new  Error ( "processUserAction: Run EXE (Action=3) not supported" ) ; 
214+           // Anything else is not supported 
215+           outputChannel . appendLine ( 
216+             `Server-side source control User Action 3 (run an EXE on the client) is not supported for target '${ target }  
217+           ) ; 
218+           outputChannel . show ( true ) ; 
208219        } 
220+         break ; 
209221      } 
210222      case  4 : { 
211223        // Insert the text in Target in the current document at the current selection point 
@@ -219,39 +231,45 @@ export class StudioActions {
219231      } 
220232      case  5 : // Studio will open the documents listed in Target 
221233        target . split ( "," ) . forEach ( ( element )  =>  { 
222-           let  classname : string  =  element ; 
234+           let  fileName : string  =  element ; 
223235          let  method : string ; 
224236          let  offset  =  0 ; 
225237          if  ( element . includes ( ":" ) )  { 
226-             [ classname ,  method ]  =  element . split ( ":" ) ; 
238+             [ fileName ,  method ]  =  element . split ( ":" ) ; 
227239            if  ( method . includes ( "+" ) )  { 
228240              offset  =  + method . split ( "+" ) [ 1 ] ; 
229241              method  =  method . split ( "+" ) [ 0 ] ; 
230242            } 
231243          } 
232244
233-           const  splitClassname  =  classname . split ( "." ) ; 
234-           const  filetype  =  splitClassname [ splitClassname . length  -  1 ] ; 
245+           const  fileExt  =  fileName . split ( "." ) . pop ( ) . toLowerCase ( ) ; 
235246          const  isCorrectMethod  =  ( text : string )  => 
236-             filetype  ===  "cls"  ? text . match ( "Method "  +  method )  : text . startsWith ( method ) ; 
237- 
238-           const  uri  =  DocumentContentProvider . getUri ( classname ) ; 
239-           vscode . window . showTextDocument ( uri ,  {  preview : false  } ) . then ( ( newEditor )  =>  { 
240-             if  ( method )  { 
241-               const  document  =  newEditor . document ; 
242-               for  ( let  i  =  0 ;  i  <  document . lineCount ;  i ++ )  { 
243-                 const  line  =  document . lineAt ( i ) ; 
244-                 if  ( isCorrectMethod ( line . text ) )  { 
245-                   if  ( ! line . text . endsWith ( "{" ) )  offset ++ ; 
246-                   const  targetLine  =  document . lineAt ( i  +  offset ) ; 
247-                   const  range  =  new  vscode . Range ( targetLine . range . start ,  targetLine . range . start ) ; 
248-                   newEditor . selection  =  new  vscode . Selection ( range . start ,  range . start ) ; 
249-                   newEditor . revealRange ( range ,  vscode . TextEditorRevealType . InCenter ) ; 
250-                   break ; 
247+             fileExt  ===  "cls"  ? text . match ( "Method "  +  method )  : text . startsWith ( method ) ; 
248+ 
249+           vscode . window . showTextDocument ( DocumentContentProvider . getUri ( fileName ) ,  {  preview : false  } ) . then ( 
250+             ( newEditor )  =>  { 
251+               if  ( method )  { 
252+                 const  document  =  newEditor . document ; 
253+                 for  ( let  i  =  0 ;  i  <  document . lineCount ;  i ++ )  { 
254+                   const  line  =  document . lineAt ( i ) ; 
255+                   if  ( isCorrectMethod ( line . text ) )  { 
256+                     if  ( ! line . text . endsWith ( "{" ) )  offset ++ ; 
257+                     const  targetLine  =  document . lineAt ( i  +  offset ) ; 
258+                     const  range  =  new  vscode . Range ( targetLine . range . start ,  targetLine . range . start ) ; 
259+                     newEditor . selection  =  new  vscode . Selection ( range . start ,  range . start ) ; 
260+                     newEditor . revealRange ( range ,  vscode . TextEditorRevealType . InCenter ) ; 
261+                     break ; 
262+                   } 
251263                } 
252264              } 
265+             } , 
266+             ( error )  =>  { 
267+               outputChannel . appendLine ( 
268+                 `Server-side source control User Action 5 failed to show '${ element } ${ stringifyError ( error ) }  
269+               ) ; 
270+               outputChannel . show ( true ) ; 
253271            } 
254-           } ) ; 
272+           ) ; 
255273        } ) ; 
256274        break ; 
257275      case  6 : // Display an alert dialog in Studio with the text from the Target variable. 
@@ -268,7 +286,8 @@ export class StudioActions {
268286            } ; 
269287          } ) ; 
270288      default :
271-         throw  new  Error ( `processUserAction: ${ userAction }  ) ; 
289+         outputChannel . appendLine ( `Unknown server-side source control User Action ${ serverAction }  ) ; 
290+         outputChannel . show ( true ) ; 
272291    } 
273292    return  Promise . resolve ( ) ; 
274293  } 
0 commit comments