import StackFrame from './react-error-overlay/utils/stack-frame' ; const isFF = navigator . userAgent . indexOf ( 'Firefox' ) !== - 1 ; function openResource ( fileName , lineNumber , stackFrame ) { const adjustedLineNumber = Math . max ( lineNumber - 1 , 0 ) ; chrome . devtools . panels . openResource ( fileName , adjustedLineNumber , ( ( result ) => { if ( result . isError ) { const { fileName : finalFileName , lineNumber : finalLineNumber } = stackFrame ; const adjustedLineNumber = Math . max ( finalLineNumber ! - 1 , 0 ) ; chrome . devtools . panels . openResource ( finalFileName ! , adjustedLineNumber , ( ) => { } ) ; } } ) as ( ) => void ) ; } function openAndCloseTab ( url ) { chrome . tabs . create ( { url } , ( tab ) => { const removeTab = ( ) => { chrome . windows . onFocusChanged . removeListener ( removeTab ) ; if ( tab && tab . id ) { chrome . tabs . remove ( tab . id , async ( ) => { if ( chrome . runtime . lastError ) console . log ( chrome . runtime . lastError ) ; else if ( chrome . devtools && chrome . devtools . inspectedWindow ) { await chrome . tabs . update ( chrome . devtools . inspectedWindow . tabId , { active : true , } ) ; } } ) ; } } ; if ( chrome . windows ) chrome . windows . onFocusChanged . addListener ( removeTab ) ; } ) ; } function openInIframe ( url ) { const iframe = document . createElement ( 'iframe' ) ; iframe . src = url ; iframe . style . display = 'none' ; document . body . appendChild ( iframe ) ; setTimeout ( ( ) => iframe . parentNode ! . removeChild ( iframe ) , 3000 ) ; } function openInEditor ( editor , path , stackFrame ) { const projectPath = path . replace ( /\/$/ , '' ) ; const file = stackFrame . _originalFileName || ( stackFrame as unknown as { finalFileName : string ; } ) . finalFileName || stackFrame . fileName || '' ; let filePath = /^https?:\/\// . test ( file ) ? file . replace ( /^https?:\/\/[^/]*/ , '' ) : file . replace ( /^\w+:\/\// , '' ) ; filePath = filePath . replace ( /^\/~\// , '/node_modules/' ) ; const line = stackFrame . _originalLineNumber || stackFrame . lineNumber || '0' ; const column = stackFrame . _originalColumnNumber || stackFrame . columnNumber || '0' ; let url ; switch ( editor ) { case 'vscode' : case 'code' : url = `vscode://file/${ projectPath }${ filePath }:${ line }:${ column }` ; break ; case 'atom' : url = `atom://core/open/file?filename=${ projectPath }${ filePath }&line=${ line }&column=${ column }` ; break ; case 'webstorm' : case 'phpstorm' : case 'idea' : url = `${ editor }://open?file=${ projectPath }${ filePath }&line=${ line }&column=${ column }` ; break ; default : url = `${ editor }://open/?url=file://${ projectPath }${ filePath }&line=${ line }&column=${ column }` ; } if ( chrome . devtools && ! isFF ) { if ( chrome . tabs ) openAndCloseTab ( url ) ; else window . open ( url ) ; } else { openInIframe ( url ) ; } } export default function openFile ( fileName , lineNumber , stackFrame ) { if ( ! chrome || ! chrome . storage ) return ; const storage = isFF ? chrome . storage . local : chrome . storage . sync || chrome . storage . local ; storage . get ( [ 'useEditor' , 'editor' , 'projectPath' ] , function ( { useEditor , editor , projectPath } ) { if ( useEditor && projectPath && typeof editor === 'string' && /^\w{1,30}$/ . test ( editor ) ) { openInEditor ( editor . toLowerCase ( ) , projectPath as string , stackFrame ) ; } else { if ( chrome . devtools && chrome . devtools . panels && ! ! chrome . devtools . panels . openResource ) { openResource ( fileName , lineNumber , stackFrame ) ; } else if ( chrome . runtime && ( chrome . runtime . openOptionsPage || isFF ) ) { if ( chrome . devtools && isFF ) { chrome . devtools . inspectedWindow . eval ( 'confirm("Set the editor to open the file in?")' , ( result ) => { if ( ! result ) return ; chrome . runtime . sendMessage ( { type : 'OPEN_OPTIONS' } ) ; } ) ; } else if ( confirm ( 'Set the editor to open the file in?' ) ) { chrome . runtime . openOptionsPage ( ) ; } } } } ) ; }