import { ISession , IBrowserProcess , IAPIClient , IDebuggingProtocolClient , ITabResponse , } from "chrome-debugging-client" ; import { createSession , ISessionExt } from "./createChromeSession" ; import { HeapProfiler , Page , DOMStorage , } from "chrome-debugging-client/dist/protocol/tot" ; import * as vscode from "vscode" ; import * as url from "url" ; import * as os from "os" ; import * as fs from "fs" ; import * as path from "path" ; import { close } from "inspector" ; import { format } from "url" ; class DrawioTab { private _page : undefined | Page ; private _domstorage : undefined | DOMStorage ; constructor ( debugClient ) { } } /**
 * 管理draw.io的chrome实例
 */ export class DrawioChrome { private _mdFilePath : string ; private _assetsPath : string ; private _session : undefined | ISessionExt ; private _process : undefined | IBrowserProcess ; private _apiClient : undefined | IAPIClient ; private _debugClient : undefined | IDebuggingProtocolClient ; private _page : undefined | Page ; private _domstorage : undefined | DOMStorage ; private _chromeWorkDir : undefined | string ; private _tab : undefined | ITabResponse ; constructor ( mdFilePath ) { console . log ( "open drawio chrome for" , this . _mdFilePath ) ; this . _initChromeWorkDir ( ) ; this . _initAssetsDir ( mdFilePath ) ; } _initChromeWorkDir ( ) { console . log ( "-----!" , vscode . workspace . workspaceFolders ) ; if ( vscode . workspace . workspaceFolders && vscode . workspace . workspaceFolders . length > 0 ) { this . _chromeWorkDir = path . resolve ( vscode . workspace . workspaceFolders [ 0 ] . uri . fsPath , ".drawio-chrome" ) ; } else { this . _chromeWorkDir = path . resolve ( os . tmpdir ( ) , "drawio-chrome" ) ; } if ( ! fs . existsSync ( this . _chromeWorkDir ) ) { console . log ( "make assets dir:" , this . _chromeWorkDir ) ; fs . mkdirSync ( this . _chromeWorkDir ) ; } } _initAssetsDir ( mdFile ) { this . _mdFilePath = mdFile ; const assetsDirName = vscode . workspace . getConfiguration ( "drawio" ) . get ( "assetsDirName" ) ; this . _assetsPath = path . resolve ( mdFile , assetsDirName ) ; if ( ! fs . existsSync ( this . _assetsPath ) ) { console . log ( "make assets dir:" , this . _assetsPath ) ; fs . mkdirSync ( this . _assetsPath ) ; } } /**
     * 初始化并加载assets
     */ async init ( ) { this . _session = await createSession ( ) ; this . _process = await this . _session . spawnBrowser ( { additionalArguments : [ "--mute-audio" , "--disable-infobars" , "--enable-automation" , ] , windowSize : { width : 1024 , height : 720 } , userDataRoot : this . _chromeWorkDir , autoDeleteUseDataDir : false , stdio : "inherit" , } ) ; console . log ( "spawnBrowser:port=" , this . _process . remoteDebuggingPort ) ; this . _apiClient = await this . _session . createAPIClient ( "localhost" , this . _process . remoteDebuggingPort ) ; console . log ( "apiClient connected" ) ; this . _tab = ( await this . _apiClient . listTabs ( ) ) [ 0 ] ; this . _debugClient = await this . _session . openDebuggingProtocol ( this . _tab . webSocketDebuggerUrl ) ; this . _debugClient . on ( "close" , async ( ev ) => { await this . close ( ) ; } ) ; console . log ( "debugClient connected:" , this . _tab . webSocketDebuggerUrl ) ; this . _page = new Page ( this . _debugClient ) ; await this . _page . enable ( ) ; await this . _page . navigate ( { url : this . _drawioUrl ( ) } ) ; this . _domstorage = new DOMStorage ( this . _debugClient ) ; await this . _domstorage . enable ( ) ; this . _domstorage . domStorageItemUpdated = async ( params ) => { if ( params . key . match ( ".+.svg" ) ) { fs . writeFileSync ( path . join ( this . _assetsPath , params . key ) , params . newValue ) ; vscode . window . showInformationMessage ( `save drawio svg:${ params . key }` ) ; } } ; await this . _loadAllAssetsToChrome ( ) ; } isClosed ( ) { return ! this . _session ; } private _drawioUrl ( fileName ? ) { const offline = vscode . workspace . getConfiguration ( "drawio" ) . get ( "offline" ) ; const f = fileName ? `L${ fileName }` : "" ; return offline ? `https://www.draw.io?offline=1#${ f }` : `https://www.draw.io#${ f }` ; } async _loadAllAssetsToChrome ( ) { if ( ! this . _domstorage ) { console . log ( "domstorage not opened!" ) ; return ; } const files = fs . readdirSync ( this . _assetsPath ) ; console . log ( "----readdirSync:" , files , this . _assetsPath ) ; let count = 0 ; for ( const f of files ) { console . log ( "----dir:" , f ) ; if ( f . startsWith ( "." ) ) continue ; if ( ! fs . statSync ( path . join ( this . _assetsPath , f ) ) . isFile ( ) ) { continue ; } if ( path . parse ( f ) . ext !== ".svg" ) { continue ; } await this . _domstorage . setDOMStorageItem ( { storageId : { isLocalStorage : true , securityOrigin : "https://www.draw.io" , } , key : f , value : fs . readFileSync ( path . join ( this . _assetsPath , f ) , { encoding : "utf8" , } ) , } ) ; count ++ ; console . log ( `${ count } load asset to chrome: ${ f }` ) ; } console . log ( `${ count } file loaded` ) ; } param svgFile async active ( svgFile ? ) { console . log ( "active:" , svgFile ) ; await this . _page . navigate ( { url : this . _drawioUrl ( svgFile ) } ) ; await this . _apiClient . activateTab ( this . _tab . id ) ; } async close ( ) { this . _domstorage = null ; if ( this . _debugClient ) { await this . _debugClient . dispose ( ) ; this . _debugClient = null ; } if ( this . _page ) { this . _page = null ; } this . _apiClient = null ; if ( this . _process ) { await this . _process . dispose ( ) ; this . _process = null ; } if ( this . _session ) { await this . _session . dispose ( ) ; this . _session = null ; } console . log ( "close chrome for:" , this . _mdFilePath ) ; } }