Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit6c73657

Browse files
committed
fix react webview script issue
1 parentc39666a commit6c73657

File tree

1 file changed

+176
-162
lines changed

1 file changed

+176
-162
lines changed

‎src/editor/ReactWebView.ts

Lines changed: 176 additions & 162 deletions
Original file line numberDiff line numberDiff line change
@@ -2,173 +2,187 @@ import * as path from 'path'
22
import*asCRfrom'typings'
33
import*asvscodefrom'vscode'
44

5+
constgetNonce=():string=>{
6+
lettext=''
7+
constpossible='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
8+
for(leti=0;i<32;i++){
9+
text+=possible.charAt(Math.floor(Math.random()*possible.length))
10+
}
11+
returntext
12+
}
13+
14+
515
/**
616
* Manages React webview panels
717
*/
818
classReactWebView{
9-
//@ts-ignore
10-
publicloaded:boolean
11-
privatepanel:vscode.WebviewPanel
12-
privateextensionPath:string
13-
privatedisposables:vscode.Disposable[]=[]
14-
privateonReceive:any// TODO: properly type
15-
16-
publicconstructor(extensionPath:string){
17-
this.extensionPath=extensionPath
18-
19-
// Create and show a new webview panel
20-
this.panel=this.createWebviewPanel(vscode.ViewColumn.Two)
21-
22-
// Set the webview's initial html content
23-
this.panel.webview.html=this.getHtmlForWebview()
24-
25-
// Listen for when the panel is disposed
26-
// This happens when the user closes the panel or when the panel is closed programatically
27-
this.panel.onDidDispose(this.dispose,this,this.disposables)
28-
29-
// Handle messages from the webview
30-
constonReceive=(action:string|CR.Action)=>{
31-
// await loading of webview in React before proceeding with loaded state
32-
if(action==='WEBVIEW_LOADED'){
33-
this.loaded=true
34-
}else{
35-
vscode.commands.executeCommand('coderoad.receive_action',action)
36-
}
37-
}
38-
this.panel.webview.onDidReceiveMessage(onReceive,null,this.disposables)
39-
40-
// update panel on changes
41-
constupdateWindows=()=>{
42-
vscode.commands.executeCommand('vscode.setEditorLayout',{
43-
orientation:0,
44-
groups:[{groups:[{}],size:0.6},{groups:[{}],size:0.4}],
45-
})
46-
}
47-
48-
// prevents new panels from going ontop of coderoad panel
49-
vscode.window.onDidChangeActiveTextEditor((textEditor)=>{
50-
console.log('onDidChangeActiveTextEditor')
51-
console.log(textEditor)
52-
if(!textEditor||textEditor.viewColumn!==vscode.ViewColumn.Two){
53-
updateWindows()
54-
}
55-
})
56-
// // prevents moving coderoad panel on top of left panel
57-
vscode.window.onDidChangeVisibleTextEditors((textEditor)=>{
58-
console.log('onDidChangeVisibleTextEditors')
59-
updateWindows()
60-
})
61-
62-
// TODO: prevent window from moving to the left when no windows remain on rights
63-
}
64-
65-
publiccreateOrShow(column:number,callback?:()=>void):void{
66-
// If we already have a panel, show it.
67-
// Otherwise, create a new panel.
68-
if(this.panel&&this.panel.webview){
69-
this.panel.reveal(column)
70-
}else{
71-
this.panel=this.createWebviewPanel(column)
72-
}
73-
if(callback){
74-
// listen for when webview is loaded
75-
// unfortunately there is no easy way of doing this
76-
constwebPanelListener=setInterval(()=>{
77-
if(this.loaded){
78-
// callback tells editor the webview has loaded
79-
setTimeout(callback)
80-
clearInterval(webPanelListener)
81-
}
82-
},200)
83-
}
84-
}
85-
86-
publicasyncpostMessage(action:CR.Action):Promise<void>{
87-
// Send a message to the webview webview.
88-
// You can send any JSON serializable data.
89-
constsuccess=awaitthis.panel.webview.postMessage(action)
90-
if(!success){
91-
thrownewError(`Message post failure:${JSON.stringify(action)}`)
92-
}
93-
}
94-
95-
privateasyncdispose():Promise<void>{
96-
// Clean up our resources
97-
this.loaded=false
98-
this.panel.dispose()
99-
Promise.all(this.disposables.map((x)=>x.dispose()))
100-
}
101-
102-
privatecreateWebviewPanel(column:number):vscode.WebviewPanel{
103-
constviewType='CodeRoad'
104-
consttitle='CodeRoad'
105-
constconfig={
106-
// Enable javascript in the webview
107-
enableScripts:true,
108-
// And restric the webview to only loading content from our extension's `media` directory.
109-
localResourceRoots:[vscode.Uri.file(path.join(this.extensionPath,'build'))],
110-
// prevents destroying the window when it is in the background
111-
retainContextWhenHidden:true,
112-
}
113-
returnvscode.window.createWebviewPanel(viewType,title,column,config)
114-
}
115-
116-
privategetNonce():string{
117-
lettext=''
118-
constpossible='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
119-
for(leti=0;i<32;i++){
120-
text+=possible.charAt(Math.floor(Math.random()*possible.length))
121-
}
122-
returntext
123-
}
124-
125-
privategetHtmlForWebview():string{
126-
// eslint-disable-next-line
127-
constmanifest=require(path.join(this.extensionPath,'build','asset-manifest.json'))
128-
constmainScript=manifest.files['main.js']
129-
// grab first chunk
130-
constchunk=Object.keys(manifest.files).filter(f=>f.match(/^static\/js\/.+\.js$/))[0]
131-
constchunkScript=manifest.files[chunk]
132-
constmainStyle=manifest.files['main.css']
133-
134-
constscriptPathOnDisk=vscode.Uri.file(path.join(this.extensionPath,'build',mainScript))
135-
constscriptUri=scriptPathOnDisk.with({scheme:'vscode-resource'})
136-
constchunkPathOnDisk=vscode.Uri.file(path.join(this.extensionPath,'build',chunkScript))
137-
constchunkUri=chunkPathOnDisk.with({scheme:'vscode-resource'})
138-
conststylePathOnDisk=vscode.Uri.file(path.join(this.extensionPath,'build',mainStyle))
139-
conststyleUri=stylePathOnDisk.with({scheme:'vscode-resource'})
140-
141-
// Use a nonce to whitelist which scripts can be run
142-
const[n1,n2,n3]=[1,2,3].map(this.getNonce)
143-
144-
return`<!DOCTYPE html>
19+
//@ts-ignore
20+
publicloaded:boolean
21+
privatepanel:vscode.WebviewPanel
22+
privateextensionPath:string
23+
privatedisposables:vscode.Disposable[]=[]
24+
privateonReceive:any// TODO: properly type
25+
26+
publicconstructor(extensionPath:string){
27+
this.extensionPath=extensionPath
28+
29+
// Create and show a new webview panel
30+
this.panel=this.createWebviewPanel(vscode.ViewColumn.Two)
31+
32+
// Set the webview's initial html content
33+
this.panel.webview.html=this.getHtmlForWebview()
34+
35+
// Listen for when the panel is disposed
36+
// This happens when the user closes the panel or when the panel is closed programatically
37+
this.panel.onDidDispose(this.dispose,this,this.disposables)
38+
39+
// Handle messages from the webview
40+
constonReceive=(action:string|CR.Action)=>{
41+
// await loading of webview in React before proceeding with loaded state
42+
if(action==='WEBVIEW_LOADED'){
43+
this.loaded=true
44+
}else{
45+
vscode.commands.executeCommand('coderoad.receive_action',action)
46+
}
47+
}
48+
this.panel.webview.onDidReceiveMessage(onReceive,null,this.disposables)
49+
50+
// update panel on changes
51+
constupdateWindows=()=>{
52+
vscode.commands.executeCommand('vscode.setEditorLayout',{
53+
orientation:0,
54+
groups:[{groups:[{}],size:0.6},{groups:[{}],size:0.4}],
55+
})
56+
}
57+
58+
// prevents new panels from going ontop of coderoad panel
59+
vscode.window.onDidChangeActiveTextEditor((textEditor)=>{
60+
console.log('onDidChangeActiveTextEditor')
61+
console.log(textEditor)
62+
if(!textEditor||textEditor.viewColumn!==vscode.ViewColumn.Two){
63+
updateWindows()
64+
}
65+
})
66+
// // prevents moving coderoad panel on top of left panel
67+
vscode.window.onDidChangeVisibleTextEditors((textEditor)=>{
68+
console.log('onDidChangeVisibleTextEditors')
69+
updateWindows()
70+
})
71+
72+
// TODO: prevent window from moving to the left when no windows remain on rights
73+
}
74+
75+
publiccreateOrShow(column:number,callback?:()=>void):void{
76+
// If we already have a panel, show it.
77+
// Otherwise, create a new panel.
78+
if(this.panel&&this.panel.webview){
79+
this.panel.reveal(column)
80+
}else{
81+
this.panel=this.createWebviewPanel(column)
82+
}
83+
if(callback){
84+
// listen for when webview is loaded
85+
// unfortunately there is no easy way of doing this
86+
constwebPanelListener=setInterval(()=>{
87+
if(this.loaded){
88+
// callback tells editor the webview has loaded
89+
setTimeout(callback)
90+
clearInterval(webPanelListener)
91+
}
92+
},200)
93+
}
94+
}
95+
96+
publicasyncpostMessage(action:CR.Action):Promise<void>{
97+
// Send a message to the webview webview.
98+
// You can send any JSON serializable data.
99+
constsuccess=awaitthis.panel.webview.postMessage(action)
100+
if(!success){
101+
thrownewError(`Message post failure:${JSON.stringify(action)}`)
102+
}
103+
}
104+
105+
privateasyncdispose():Promise<void>{
106+
// Clean up our resources
107+
this.loaded=false
108+
this.panel.dispose()
109+
Promise.all(this.disposables.map((x)=>x.dispose()))
110+
}
111+
112+
privatecreateWebviewPanel(column:number):vscode.WebviewPanel{
113+
constviewType='CodeRoad'
114+
consttitle='CodeRoad'
115+
constconfig={
116+
// Enable javascript in the webview
117+
enableScripts:true,
118+
// And restric the webview to only loading content from our extension's `media` directory.
119+
localResourceRoots:[vscode.Uri.file(path.join(this.extensionPath,'build'))],
120+
// prevents destroying the window when it is in the background
121+
retainContextWhenHidden:true,
122+
}
123+
returnvscode.window.createWebviewPanel(viewType,title,column,config)
124+
}
125+
126+
privategetHtmlForWebview():string{
127+
constbuildUri=vscode.Uri.file(path.join(this.extensionPath,'build')).with({scheme:'vscode-resource'})
128+
129+
constmanifest=require(path.join(this.extensionPath,'build','asset-manifest.json'))
130+
131+
constmainStyle=manifest.files['main.css']
132+
conststylePathOnDisk=vscode.Uri.file(path.join(this.extensionPath,'build',mainStyle))
133+
conststyleUri=stylePathOnDisk.with({scheme:'vscode-resource'})
134+
135+
constgetSrc=(manifestName:string):any=>{
136+
constfile=manifest.files[manifestName]
137+
consturiPath=vscode.Uri.file(path.join(this.extensionPath,'build',file))
138+
returnuriPath.with({scheme:'vscode-resource'})
139+
}
140+
141+
// map over scripts
142+
constscripts=[{
143+
file:'./webpackBuild.js',
144+
},{
145+
manifest:'runtime~main.js',
146+
},{
147+
manifest:'main.js',
148+
},{
149+
// grab first file that matches chunk
150+
manifest:Object.keys(manifest.files).filter(f=>f.match(/^static\/js\/.+\.js$/))[0],
151+
}].map(script=>({
152+
nonce:getNonce(),
153+
src:script.manifest ?getSrc(script.manifest) :script.file
154+
}))
155+
156+
157+
constindexHtml=`<!DOCTYPE html>
145158
<html lang='en'>
146-
<head>
147-
<meta charset='utf-8'>
148-
<meta name='viewport' content='width=device-width,initial-scale=1,shrink-to-fit=no'>
149-
<meta name='theme-color' content='#000000'>
150-
<title>React App</title>
151-
<link rel='manifest' href='./manifest.json' />
152-
153-
<!-- TODO: load styles through package -->
154-
<link rel='stylesheet' href='https://unpkg.com/@alifd/next/dist/next.css' />
155-
<link rel='stylesheet' type='text/css' href='${styleUri}'>
156-
157-
<meta http-equiv='Content-Security-Policy' content="font-src *; img-src vscode-resource: https:; script-src 'nonce-${n1}' 'nonce-${n2}' 'nonce-${n3}'; style-src vscode-resource: 'unsafe-inline' http: https: data:;">
158-
<base href='${vscode.Uri.file(path.join(this.extensionPath,'build')).with({
159-
scheme:'vscode-resource',
160-
})}/'>
161-
</head>
162-
163-
<body>
164-
<noscript>You need to enable JavaScript to run this app.</noscript>
165-
<div id='root'>Loading...</div>
166-
<script nonce=${n1} src='./webpackBuild.js'></script>
167-
<script nonce=${n2} src='${chunkUri}'></script>
168-
<script nonce='${n3}' src='${scriptUri}'></script>
169-
</body>
170-
</html>`
171-
}
159+
<head>
160+
<meta charset='utf-8'>
161+
<meta name='viewport' content='width=device-width,initial-scale=1,shrink-to-fit=no'>
162+
<meta name='theme-color' content='#000000'>
163+
<title>React App</title>
164+
<link rel='manifest' href='./manifest.json' />
165+
166+
<!-- TODO: load styles through package -->
167+
<!-- <link rel='stylesheet' href='https://unpkg.com/@alifd/next/dist/next.css' /> -->
168+
<!-- <link rel='stylesheet' type='text/css' href='${styleUri}'> -->
169+
170+
<meta http-equiv='Content-Security-Policy' content="font-src *; img-src vscode-resource: https:; script-src${scripts.map(script=>`'nonce-${script.nonce}'`).join(' ')}; style-src vscode-resource: 'unsafe-inline' http: https: data:;">
171+
<base href='${buildUri}/'>
172+
</head>
173+
174+
<body>
175+
<noscript>You need to enable JavaScript to run this app.</noscript>
176+
<div id='root'>Loading...</div>
177+
${scripts.map(s=>`<script nonce='${s.nonce}' src='${s.src}'></script>`).join('\n')}
178+
</body>
179+
</html>`
180+
181+
console.log(indexHtml)
182+
183+
returnindexHtml
184+
}
185+
172186
}
173187

174188
exportdefaultReactWebView

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp