1
1
import * as vscode from 'vscode'
2
+ import { getCodeAndMap } from './getCodeAndMap'
3
+ import { getHtmlForWebview } from './getHtmlForWebview'
2
4
3
5
export function activate ( context : vscode . ExtensionContext ) {
4
6
// Track currently webview panel
@@ -56,7 +58,10 @@ function getViewColumn() {
56
58
async function updatePanel ( panel : vscode . WebviewPanel ) {
57
59
if ( ! panel )
58
60
return
59
- const data = await getCodeAndMap ( )
61
+ const data = await getCodeAndMap ( ) . catch ( ( err ) => {
62
+ console . warn ( 'Get code and map error:' , err )
63
+ return undefined
64
+ } )
60
65
if ( ! data )
61
66
return
62
67
panel . webview . postMessage ( {
@@ -65,95 +70,3 @@ async function updatePanel(panel: vscode.WebviewPanel) {
65
70
} )
66
71
}
67
72
68
- async function getCodeAndMap ( ) {
69
- const editor = vscode . window . activeTextEditor
70
- if ( ! editor )
71
- return
72
-
73
- const document = editor . document
74
-
75
- const file = document . isUntitled ? 'Untitled Document' : document . fileName
76
- const dir = file . replace ( / \/ [ ^ \/ ] + $ / , '' )
77
- const fileName = file . split ( '/' ) . pop ( )
78
- if ( ! fileName )
79
- return
80
-
81
- const fileMetas = await Promise . resolve ( vscode . workspace . fs . readDirectory ( vscode . Uri . file ( dir ) ) ) . catch ( ( ) => [ ] )
82
- let mapFileName = fileMetas . find ( ( [ name ] ) => name === `${ fileName } .map` ) ?. [ 0 ]
83
- mapFileName ??= fileMetas . find ( ( [ name ] ) => name . startsWith ( fileName ?. split ( '.' ) [ 0 ] ) && name . endsWith ( '.map' ) ) ?. [ 0 ]
84
-
85
- const selectedCode = document . getText ( editor . selection )
86
- const getFullCode = async ( ) => Promise . resolve ( vscode . workspace . fs . readFile ( vscode . Uri . file ( file ) ) . then ( buffer => new TextDecoder ( 'utf-8' ) . decode ( buffer ) ) ) . catch ( ( ) => document . getText ( ) )
87
- const code = selectedCode || await getFullCode ( )
88
- if ( ! mapFileName ) {
89
- const lastLine = ( selectedCode ? await getFullCode ( ) : code ) . split ( '\n' ) . pop ( ) ?? ''
90
- if ( ! lastLine . startsWith ( '//# sourceMappingURL=' ) ) {
91
- vscode . window . setStatusBarMessage ( 'Source map not found!' , 5000 )
92
- return
93
- }
94
- const map = new TextDecoder ( 'utf-8' ) . decode ( Buffer . from ( lastLine . split ( ',' ) . pop ( ) ?? '' , 'base64' ) )
95
- if ( ! map ) {
96
- vscode . window . setStatusBarMessage ( 'Source map not found!' , 5000 )
97
- return
98
- }
99
- return { code, map }
100
- }
101
-
102
- const mapFile = `${ dir } /${ mapFileName } `
103
-
104
- const map = await vscode . workspace . fs . readFile ( vscode . Uri . file ( mapFile ) ) . then ( buffer => new TextDecoder ( 'utf-8' ) . decode ( buffer ) )
105
-
106
- return { code, map }
107
- }
108
-
109
- function getHtmlForWebview ( webview : vscode . Webview , extensionUri : vscode . Uri ) {
110
- // Get the local path to main script run in the webview, then convert it to a uri we can use in the webview.
111
- const mainScriptUri = webview . asWebviewUri ( vscode . Uri . joinPath ( extensionUri , 'res' , 'main.js' ) )
112
- const codeScriptUri = webview . asWebviewUri ( vscode . Uri . joinPath ( extensionUri , 'res' , 'code.js' ) )
113
-
114
- // Do the same for the stylesheet.
115
- const styleUri = webview . asWebviewUri ( vscode . Uri . joinPath ( extensionUri , 'res' , 'style.css' ) )
116
-
117
- // Use a nonce to only allow a specific script to be run.
118
- const nonce = getNonce ( )
119
-
120
- return `<!DOCTYPE html>
121
- <html lang="en">
122
- <head>
123
- <meta charset="utf-8" />
124
- <!-- <meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src ${ webview . cspSource } ; script-src 'nonce-${ nonce } ';"> -->
125
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
126
- <link href="${ styleUri } " rel="stylesheet">
127
- </head>
128
- <body>
129
- <div id="toolbar">
130
- <section>
131
- <h2>Original code</h2>
132
- <div id="fileListParent"><select id="fileList"></select></div>
133
- </section>
134
- <section>
135
- <h2>Generated code</h2>
136
- </section>
137
- </div>
138
- <div id="statusBar">
139
- <section>
140
- <div id="originalStatus"></div>
141
- </section>
142
- <section>
143
- <div id="generatedStatus"></div>
144
- </section>
145
- </div>
146
- <script nonce="${ nonce } " src="${ mainScriptUri } "></script>
147
- <script nonce="${ nonce } " src="${ codeScriptUri } "></script>
148
- </body>
149
- </html>`
150
- }
151
-
152
- function getNonce ( ) {
153
- let text = ''
154
- const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
155
- for ( let i = 0 ; i < 32 ; i ++ )
156
- text += possible . charAt ( Math . floor ( Math . random ( ) * possible . length ) )
157
-
158
- return text
159
- }
0 commit comments