import * as vscode from 'vscode' ; import * as fs from 'fs' ; import * as path from 'path' ; /**
 * Manages connect input webview panels
 */ export default class QueryGridView { /**
     * Track the currently panel. Only allow a single panel to exist at a time.
     */ public static currentPanel : QueryGridView | undefined ; private static readonly viewType = 'GridView' ; private readonly _panel : vscode . WebviewPanel ; private readonly _extensionPath : string ; private _htmlContent : string ; private _currentData : string ; private _disposables : vscode . Disposable [ ] = [ ] ; public static createOrShow ( extensionPath , data ) { if ( QueryGridView . currentPanel ) { QueryGridView . currentPanel . _currentData = data ; QueryGridView . currentPanel . _panel . reveal ( QueryGridView . currentPanel . _panel . viewColumn ) ; } else { QueryGridView . currentPanel = new QueryGridView ( extensionPath , data ) ; } } public sendData ( data ) { this . _panel . webview . postMessage ( { command : 'showGridView' , data : data } ) ; } public dispose ( ) { QueryGridView . currentPanel = undefined ; this . _panel . dispose ( ) ; while ( this . _disposables . length ) { const x = this . _disposables . pop ( ) ; if ( x ) { x . dispose ( ) ; } } } private constructor ( extensionPath , data ) { this . _extensionPath = extensionPath ; this . _currentData = data ; this . _panel = vscode . window . createWebviewPanel ( QueryGridView . viewType , 'Oracle result' , vscode . ViewColumn . Beside , { enableScripts : true , localResourceRoots : [ vscode . Uri . file ( path . join ( this . _extensionPath , 'resources' , 'webview' ) ) , vscode . Uri . file ( path . join ( this . _extensionPath , 'node_modules' ) ) ] } ) ; this . _update ( ) ; this . _panel . onDidDispose ( ( ) => this . dispose ( ) , null , this . _disposables ) ; this . _panel . onDidChangeViewState ( e => { if ( this . _panel . visible ) { this . _update ( ) ; } } , this , this . _disposables ) ; this . _panel . webview . onDidReceiveMessage ( message => { switch ( message . command ) { case 'cancelGridView' : this . dispose ( ) ; return ; } } , this , this . _disposables ) ; } private _update ( ) { if ( this . _htmlContent ) { this . _panel . webview . html = this . _htmlContent ; this . sendData ( this . _currentData ) ; } else this . _getHtmlForWebview ( ) . then ( html => { this . _htmlContent = html ; this . _panel . webview . html = html ; this . sendData ( this . _currentData ) ; } ) ; } private _getHtmlForWebview ( ) { const htmlPathOnDisk = path . join ( this . _extensionPath , 'resources' , 'webview' , 'gridView.html' ) ; const scriptPathOnDisk = vscode . Uri . file ( path . join ( this . _extensionPath , 'resources' , 'webview' , 'gridView.js' ) ) ; const cssPathOnDisk = vscode . Uri . file ( path . join ( this . _extensionPath , 'resources' , 'webview' , 'gridView.css' ) ) ; const scriptAgGrid = vscode . Uri . file ( path . join ( this . _extensionPath , 'node_modules' , 'ag-grid-community' , 'dist' , 'ag-grid-community.min.noStyle.js' ) ) ; const cssAgGrid = vscode . Uri . file ( path . join ( this . _extensionPath , 'node_modules' , 'ag-grid-community' , 'dist' , 'styles' , 'ag-grid.css' ) ) ; const cssAgTheme = vscode . Uri . file ( path . join ( this . _extensionPath , 'node_modules' , 'ag-grid-community' , 'dist' , 'styles' , 'ag-theme-balham.css' ) ) ; const scriptUri = scriptPathOnDisk . with ( { scheme : 'vscode-resource' } ) ; const cssUri = cssPathOnDisk . with ( { scheme : 'vscode-resource' } ) ; const scriptAgGridUri = scriptAgGrid . with ( { scheme : 'vscode-resource' } ) ; const cssAgGridUri = cssAgGrid . with ( { scheme : 'vscode-resource' } ) ; const cssAgThemeUri = cssAgTheme . with ( { scheme : 'vscode-resource' } ) ; return this . readHTMLFile ( htmlPathOnDisk , { scriptUri , cssUri , scriptAgGridUri , cssAgGridUri , cssAgThemeUri , } , this . getNonce ( ) ) ; } private readHTMLFile ( file , uris , nonce ) { return new Promise ( ( resolve , reject ) => { fs . readFile ( file , 'utf8' , ( err , data ) => { if ( err ) return reject ( err ) ; let html = data . toString ( ) ; Object . keys ( uris ) . forEach ( uri => { html = html . replace ( '${' + uri + '}' , uris [ uri ] ) ; } ) ; html = html . replace ( /\${nonce}/g , nonce ) ; return resolve ( html ) ; } ) ; } ) ; } private getNonce ( ) { let text = '' ; const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' ; for ( let i = 0 ; i < 32 ; i ++ ) { text += possible . charAt ( Math . floor ( Math . random ( ) * possible . length ) ) ; } return text ; } }