@jiangzhongxi0322/messagechannel 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +181 -0
- package/dist/messageChannel.d.ts +10 -0
- package/dist/{messageChennel.js → messageChannel.js} +25 -8
- package/examples/command-webview-sample/.eslintrc.js +23 -0
- package/examples/command-webview-sample/.vscode/extensions.json +9 -0
- package/examples/command-webview-sample/.vscode/launch.json +18 -0
- package/examples/command-webview-sample/.vscode/settings.json +3 -0
- package/examples/command-webview-sample/.vscode/tasks.json +20 -0
- package/examples/command-webview-sample/README.md +47 -0
- package/examples/command-webview-sample/demo.gif +0 -0
- package/examples/command-webview-sample/media/cat.gif +0 -0
- package/examples/command-webview-sample/media/jsconfig.json +22 -0
- package/examples/command-webview-sample/media/main.js +41 -0
- package/examples/command-webview-sample/media/reset.css +30 -0
- package/examples/command-webview-sample/media/vscode.css +91 -0
- package/examples/command-webview-sample/package-lock.json +2764 -0
- package/examples/command-webview-sample/package.json +51 -0
- package/examples/command-webview-sample/src/extension.ts +227 -0
- package/{src/messageChennel.ts → examples/command-webview-sample/src/messageChannel.ts} +34 -21
- package/examples/command-webview-sample/tsconfig.json +12 -0
- package/examples/publish-webview-sample/.eslintrc.js +20 -0
- package/examples/publish-webview-sample/.vscode/extensions.json +9 -0
- package/examples/publish-webview-sample/.vscode/launch.json +18 -0
- package/examples/publish-webview-sample/.vscode/settings.json +3 -0
- package/examples/publish-webview-sample/.vscode/tasks.json +20 -0
- package/examples/publish-webview-sample/README.md +24 -0
- package/examples/publish-webview-sample/media/main.css +54 -0
- package/examples/publish-webview-sample/media/main.js +100 -0
- package/examples/publish-webview-sample/media/reset.css +30 -0
- package/examples/publish-webview-sample/media/vscode.css +91 -0
- package/examples/publish-webview-sample/package-lock.json +2720 -0
- package/examples/publish-webview-sample/package.json +71 -0
- package/examples/publish-webview-sample/src/extension.ts +170 -0
- package/examples/publish-webview-sample/src/messageChannel.ts +264 -0
- package/examples/publish-webview-sample/tsconfig.json +12 -0
- package/examples/url-webview-sample/.eslintignore +1 -0
- package/examples/url-webview-sample/.eslintrc.js +20 -0
- package/examples/url-webview-sample/.vscode/extensions.json +9 -0
- package/examples/url-webview-sample/.vscode/launch.json +18 -0
- package/examples/url-webview-sample/.vscode/settings.json +3 -0
- package/examples/url-webview-sample/.vscode/tasks.json +20 -0
- package/examples/url-webview-sample/README.md +25 -0
- package/examples/url-webview-sample/documentation/example.png +0 -0
- package/examples/url-webview-sample/exampleFiles/example.cscratch +14 -0
- package/examples/url-webview-sample/exampleFiles/example.pawDraw +0 -0
- package/examples/url-webview-sample/exampleFiles/log/python-kaleido-case-api.exe.log +1 -0
- package/examples/url-webview-sample/exampleFiles/log/python-request.exe.log +1 -0
- package/examples/url-webview-sample/exampleFiles/pump/config/default.json +1 -0
- package/examples/url-webview-sample/exampleFiles/test_cases/log/output_202511181702.log +6 -0
- package/examples/url-webview-sample/media/catScratch.css +65 -0
- package/examples/url-webview-sample/media/catScratch.js +100 -0
- package/examples/url-webview-sample/media/paw-color.svg +21 -0
- package/examples/url-webview-sample/media/paw-outline.svg +21 -0
- package/examples/url-webview-sample/media/pawDraw.css +83 -0
- package/examples/url-webview-sample/media/pawDraw.js +266 -0
- package/examples/url-webview-sample/media/reset.css +30 -0
- package/examples/url-webview-sample/media/sand-dark.jpg +0 -0
- package/examples/url-webview-sample/media/sand.jpg +0 -0
- package/examples/url-webview-sample/media/vscode.css +91 -0
- package/examples/url-webview-sample/package-lock.json +2751 -0
- package/examples/url-webview-sample/package.json +64 -0
- package/examples/url-webview-sample/src/catScratchEditor.ts +215 -0
- package/examples/url-webview-sample/src/dispose.ts +37 -0
- package/examples/url-webview-sample/src/extension.ts +7 -0
- package/examples/url-webview-sample/src/messageChannel.ts +264 -0
- package/examples/url-webview-sample/src/util.ts +8 -0
- package/examples/url-webview-sample/tsconfig.json +13 -0
- package/package.json +3 -3
- package/src/messageChannel.ts +264 -0
- package/dist/messageChennel.d.ts +0 -15
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "command-webview-sample",
|
|
3
|
+
"description": "Cat Coding - A Webview API Sample",
|
|
4
|
+
"version": "0.0.5",
|
|
5
|
+
"publisher": "walker",
|
|
6
|
+
"private": true,
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/Microsoft/vscode-extension-samples"
|
|
11
|
+
},
|
|
12
|
+
"engines": {
|
|
13
|
+
"vscode": "^1.74.0"
|
|
14
|
+
},
|
|
15
|
+
"categories": [
|
|
16
|
+
"Other"
|
|
17
|
+
],
|
|
18
|
+
"activationEvents": [
|
|
19
|
+
"onWebviewPanel:catCoding"
|
|
20
|
+
],
|
|
21
|
+
"main": "./out/extension.js",
|
|
22
|
+
"contributes": {
|
|
23
|
+
"commands": [
|
|
24
|
+
{
|
|
25
|
+
"command": "catCoding.start",
|
|
26
|
+
"title": "Start cat coding session",
|
|
27
|
+
"category": "Cat Coding"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"command": "catCoding.doRefactor",
|
|
31
|
+
"title": "Do some refactoring",
|
|
32
|
+
"category": "Cat Coding"
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
"scripts": {
|
|
37
|
+
"vscode:prepublish": "npm run compile",
|
|
38
|
+
"compile": "tsc -p ./",
|
|
39
|
+
"lint": "eslint \"src/**/*.ts\"",
|
|
40
|
+
"watch": "tsc -w -p ./"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@types/node": "^18",
|
|
44
|
+
"@types/vscode": "^1.73.0",
|
|
45
|
+
"@types/vscode-webview": "^1.57.0",
|
|
46
|
+
"@typescript-eslint/eslint-plugin": "^6.7.0",
|
|
47
|
+
"@typescript-eslint/parser": "^6.7.0",
|
|
48
|
+
"eslint": "^8.26.0",
|
|
49
|
+
"typescript": "^5.4.2"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import * as vscode from 'vscode';
|
|
2
|
+
import MessageChannel from './messageChannel';
|
|
3
|
+
|
|
4
|
+
const mc = MessageChannel();
|
|
5
|
+
const cats = {
|
|
6
|
+
'Coding Cat': 'https://media.giphy.com/media/JIX9t2j0ZTN9S/giphy.gif',
|
|
7
|
+
'Compiling Cat': 'https://media.giphy.com/media/mlvseq9yvZhba/giphy.gif',
|
|
8
|
+
'Testing Cat': 'https://media.giphy.com/media/3oriO0OEd9QIDdllqo/giphy.gif'
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export function activate(context: vscode.ExtensionContext) {
|
|
12
|
+
mc.initiator(CatCodingPanel.viewType);
|
|
13
|
+
context.subscriptions.push(
|
|
14
|
+
vscode.commands.registerCommand('catCoding.start', () => {
|
|
15
|
+
CatCodingPanel.createOrShow(context.extensionUri);
|
|
16
|
+
mc.setCarrier((CatCodingPanel.currentPanel as any)._panel.webview);
|
|
17
|
+
})
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
if (vscode.window.registerWebviewPanelSerializer) {
|
|
21
|
+
// Make sure we register a serializer in activation event
|
|
22
|
+
vscode.window.registerWebviewPanelSerializer(CatCodingPanel.viewType, {
|
|
23
|
+
async deserializeWebviewPanel(webviewPanel: vscode.WebviewPanel, state: any) {
|
|
24
|
+
console.log(`Got state: ${state}`);
|
|
25
|
+
// Reset the webview options so we use latest uri for `localResourceRoots`.
|
|
26
|
+
webviewPanel.webview.options = getWebviewOptions(context.extensionUri);
|
|
27
|
+
CatCodingPanel.revive(webviewPanel, context.extensionUri);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function getWebviewOptions(extensionUri: vscode.Uri): vscode.WebviewOptions {
|
|
34
|
+
return {
|
|
35
|
+
// Enable javascript in the webview
|
|
36
|
+
enableScripts: true,
|
|
37
|
+
|
|
38
|
+
// And restrict the webview to only loading content from our extension's `media` directory.
|
|
39
|
+
localResourceRoots: [vscode.Uri.joinPath(extensionUri, 'media')]
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Manages cat coding webview panels
|
|
45
|
+
*/
|
|
46
|
+
class CatCodingPanel {
|
|
47
|
+
/**
|
|
48
|
+
* Track the currently panel. Only allow a single panel to exist at a time.
|
|
49
|
+
*/
|
|
50
|
+
public static currentPanel: CatCodingPanel | undefined;
|
|
51
|
+
|
|
52
|
+
public static readonly viewType = 'catCoding';
|
|
53
|
+
|
|
54
|
+
private readonly _panel: vscode.WebviewPanel;
|
|
55
|
+
private readonly _extensionUri: vscode.Uri;
|
|
56
|
+
private _disposables: vscode.Disposable[] = [];
|
|
57
|
+
|
|
58
|
+
public static createOrShow(extensionUri: vscode.Uri) {
|
|
59
|
+
const column = vscode.window.activeTextEditor
|
|
60
|
+
? vscode.window.activeTextEditor.viewColumn
|
|
61
|
+
: undefined;
|
|
62
|
+
|
|
63
|
+
// If we already have a panel, show it.
|
|
64
|
+
if (CatCodingPanel.currentPanel) {
|
|
65
|
+
CatCodingPanel.currentPanel._panel.reveal(column);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Otherwise, create a new panel.
|
|
70
|
+
const panel = vscode.window.createWebviewPanel(
|
|
71
|
+
CatCodingPanel.viewType,
|
|
72
|
+
'Cat Coding',
|
|
73
|
+
column || vscode.ViewColumn.One,
|
|
74
|
+
getWebviewOptions(extensionUri),
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
CatCodingPanel.currentPanel = new CatCodingPanel(panel, extensionUri);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
public static revive(panel: vscode.WebviewPanel, extensionUri: vscode.Uri) {
|
|
81
|
+
CatCodingPanel.currentPanel = new CatCodingPanel(panel, extensionUri);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
private constructor(panel: vscode.WebviewPanel, extensionUri: vscode.Uri) {
|
|
85
|
+
this._panel = panel;
|
|
86
|
+
this._extensionUri = extensionUri;
|
|
87
|
+
|
|
88
|
+
// Set the webview's initial html content
|
|
89
|
+
this._update();
|
|
90
|
+
|
|
91
|
+
// Listen for when the panel is disposed
|
|
92
|
+
// This happens when the user closes the panel or when the panel is closed programmatically
|
|
93
|
+
this._panel.onDidDispose(() => this.dispose(), null, this._disposables);
|
|
94
|
+
|
|
95
|
+
// Update the content based on view changes
|
|
96
|
+
this._panel.onDidChangeViewState(
|
|
97
|
+
e => {
|
|
98
|
+
if (this._panel.visible) {
|
|
99
|
+
this._update();
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
null,
|
|
103
|
+
this._disposables
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
// Handle messages from the webview
|
|
107
|
+
this._panel.webview.onDidReceiveMessage(
|
|
108
|
+
message => {
|
|
109
|
+
switch (message.command) {
|
|
110
|
+
case 'alert':
|
|
111
|
+
vscode.window.showErrorMessage(message.text);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
null,
|
|
116
|
+
this._disposables
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
public doRefactor() {
|
|
121
|
+
// Send a message to the webview webview.
|
|
122
|
+
// You can send any JSON serializable data.
|
|
123
|
+
this._panel.webview.postMessage({ command: 'refactor' });
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
public dispose() {
|
|
127
|
+
CatCodingPanel.currentPanel = undefined;
|
|
128
|
+
|
|
129
|
+
// Clean up our resources
|
|
130
|
+
this._panel.dispose();
|
|
131
|
+
|
|
132
|
+
while (this._disposables.length) {
|
|
133
|
+
const x = this._disposables.pop();
|
|
134
|
+
if (x) {
|
|
135
|
+
x.dispose();
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
private _update() {
|
|
141
|
+
const webview = this._panel.webview;
|
|
142
|
+
|
|
143
|
+
// Vary the webview's content based on where it is located in the editor.
|
|
144
|
+
switch (this._panel.viewColumn) {
|
|
145
|
+
case vscode.ViewColumn.Two:
|
|
146
|
+
this._updateForCat(webview, 'Compiling Cat');
|
|
147
|
+
return;
|
|
148
|
+
|
|
149
|
+
case vscode.ViewColumn.Three:
|
|
150
|
+
this._updateForCat(webview, 'Testing Cat');
|
|
151
|
+
return;
|
|
152
|
+
|
|
153
|
+
case vscode.ViewColumn.One:
|
|
154
|
+
default:
|
|
155
|
+
this._updateForCat(webview, 'Coding Cat');
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
private _updateForCat(webview: vscode.Webview, catName: keyof typeof cats) {
|
|
161
|
+
this._panel.title = catName;
|
|
162
|
+
this._panel.webview.html = this._getHtmlForWebview(webview, cats[catName]);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
private _getHtmlForWebview(webview: vscode.Webview, catGifPath: string) {
|
|
166
|
+
// Local path to main script run in the webview
|
|
167
|
+
const scriptPathOnDisk = vscode.Uri.joinPath(this._extensionUri, 'media', 'main.js');
|
|
168
|
+
|
|
169
|
+
// And the uri we use to load this script in the webview
|
|
170
|
+
const scriptUri = webview.asWebviewUri(scriptPathOnDisk);
|
|
171
|
+
|
|
172
|
+
// Local path to css styles
|
|
173
|
+
const styleResetPath = vscode.Uri.joinPath(this._extensionUri, 'media', 'reset.css');
|
|
174
|
+
const stylesPathMainPath = vscode.Uri.joinPath(this._extensionUri, 'media', 'vscode.css');
|
|
175
|
+
|
|
176
|
+
// Uri to load styles into webview
|
|
177
|
+
const stylesResetUri = webview.asWebviewUri(styleResetPath);
|
|
178
|
+
const stylesMainUri = webview.asWebviewUri(stylesPathMainPath);
|
|
179
|
+
|
|
180
|
+
// Use a nonce to only allow specific scripts to be run
|
|
181
|
+
const nonce = getNonce();
|
|
182
|
+
|
|
183
|
+
return `<!DOCTYPE html>
|
|
184
|
+
<html lang="en">
|
|
185
|
+
<head>
|
|
186
|
+
<meta charset="UTF-8">
|
|
187
|
+
|
|
188
|
+
<!--
|
|
189
|
+
Use a content security policy to only allow loading images from https or from our extension directory,
|
|
190
|
+
and only allow scripts that have a specific nonce.
|
|
191
|
+
-->
|
|
192
|
+
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src ${webview.cspSource}; img-src ${webview.cspSource} https:; script-src 'nonce-${nonce}';">
|
|
193
|
+
|
|
194
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
195
|
+
|
|
196
|
+
<link href="${stylesResetUri}" rel="stylesheet">
|
|
197
|
+
<link href="${stylesMainUri}" rel="stylesheet">
|
|
198
|
+
|
|
199
|
+
<title>Cat Coding</title>
|
|
200
|
+
</head>
|
|
201
|
+
<body>
|
|
202
|
+
此处输入需要反馈的数据:<input style="border: 1px solid #ccc; padding: 4px; border-radius: 4px;" placeholder="请输入反馈内容"/>
|
|
203
|
+
<button>反馈</button>
|
|
204
|
+
|
|
205
|
+
<script nonce="${nonce}">
|
|
206
|
+
const result = document.querySelector('input').value;
|
|
207
|
+
document.querySelector('button').addEventListener('click', (args) => {
|
|
208
|
+
const result = document.querySelector('input').value;
|
|
209
|
+
feedbackResult && feedbackResult(result);
|
|
210
|
+
});
|
|
211
|
+
window.mc = (${MessageChannel.toString()})();
|
|
212
|
+
window.mc.setCarrier();
|
|
213
|
+
window.mc.initiator();
|
|
214
|
+
</script>
|
|
215
|
+
</body>
|
|
216
|
+
</html>`;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function getNonce() {
|
|
221
|
+
let text = '';
|
|
222
|
+
const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
223
|
+
for (let i = 0; i < 32; i++) {
|
|
224
|
+
text += possible.charAt(Math.floor(Math.random() * possible.length));
|
|
225
|
+
}
|
|
226
|
+
return text;
|
|
227
|
+
}
|
|
@@ -4,22 +4,24 @@ interface Event {
|
|
|
4
4
|
typename?: string;
|
|
5
5
|
key?: string;
|
|
6
6
|
channelId: string;
|
|
7
|
-
data: FeedbackData;
|
|
8
|
-
}
|
|
9
|
-
interface FeedbackData {
|
|
10
|
-
code: 0 | 1 | 2;
|
|
11
|
-
msg: string;
|
|
12
7
|
data: any;
|
|
13
8
|
}
|
|
9
|
+
|
|
14
10
|
// 每个vscode的node端和webview都分别拥有一个MessageChannel返回的对象,因为他们是不同载体
|
|
15
11
|
// 同一webview如果打开了多个文档,各个文档也应该有不同的载体
|
|
16
12
|
declare const window: any;
|
|
17
13
|
|
|
18
14
|
const MessageChannel = () => {
|
|
19
|
-
let cachedCarrier: vscode.Webview;
|
|
15
|
+
let cachedCarrier: vscode.Webview | null;
|
|
20
16
|
let dispose: vscode.Disposable;
|
|
21
17
|
|
|
22
|
-
|
|
18
|
+
/**
|
|
19
|
+
* @carrier 在vscode的webviewProvider以及webview的web内都调用这个接口,设置发送和接受事件的载体
|
|
20
|
+
* webviewProvider示例:CI.setCarrier(webviewView.webview); // 在最早获取到webview的地方
|
|
21
|
+
* webview的react项目示例:CI.setCarrier(); // 在根组件
|
|
22
|
+
* carrier如果为空,则清空之前的载体
|
|
23
|
+
*/
|
|
24
|
+
const setCarrier = (carrier?: null | vscode.Webview) => {
|
|
23
25
|
if (carrier === undefined) {
|
|
24
26
|
cachedCarrier = (window as any).acquireVsCodeApi();
|
|
25
27
|
(window as any).addEventListener('message', (event: any) => {
|
|
@@ -31,7 +33,7 @@ const MessageChannel = () => {
|
|
|
31
33
|
dispose.dispose();
|
|
32
34
|
}
|
|
33
35
|
cachedCarrier = carrier;
|
|
34
|
-
if (
|
|
36
|
+
if (cachedCarrier === null) {
|
|
35
37
|
return;
|
|
36
38
|
}
|
|
37
39
|
dispose = cachedCarrier.onDidReceiveMessage((event) =>
|
|
@@ -44,16 +46,15 @@ const MessageChannel = () => {
|
|
|
44
46
|
} = {};
|
|
45
47
|
|
|
46
48
|
const messageHandler = async (event: Event) => {
|
|
47
|
-
const { data
|
|
48
|
-
const data = feedbackData.data;
|
|
49
|
+
const { data, typename } = event;
|
|
49
50
|
const isTalkInExtension = typename && subscribers[typename];
|
|
50
51
|
if (isTalkInExtension) {
|
|
51
52
|
subscribers[typename as string].forEach((resolver) => {
|
|
52
|
-
resolver(
|
|
53
|
+
resolver(data);
|
|
53
54
|
});
|
|
54
55
|
return;
|
|
55
56
|
}
|
|
56
|
-
const isTalkToExtension = typename && data?.viewType;
|
|
57
|
+
const isTalkToExtension = typename && (data as any)?.viewType;
|
|
57
58
|
if(isTalkToExtension) {
|
|
58
59
|
const activeTargetExtension = async (extensionId: string) => {
|
|
59
60
|
const targetExtension = vscode.extensions.getExtension(extensionId);
|
|
@@ -86,15 +87,20 @@ const MessageChannel = () => {
|
|
|
86
87
|
}
|
|
87
88
|
|
|
88
89
|
};
|
|
90
|
+
/**
|
|
91
|
+
* typename: 消息类型,消息的发布和订阅都依赖这个typename
|
|
92
|
+
* subscriber:收到消息后把消息传递给subscriber
|
|
93
|
+
* once:一次性订阅,收到消息后就把订阅者移除
|
|
94
|
+
*/
|
|
89
95
|
const subscribe = (
|
|
90
96
|
typename: string,
|
|
91
|
-
subscriber: (data:
|
|
97
|
+
subscriber: (data: any) => any,
|
|
92
98
|
once = false
|
|
93
99
|
) => {
|
|
94
100
|
if (!subscriber || !(subscriber instanceof Function)) {
|
|
95
101
|
return;
|
|
96
102
|
}
|
|
97
|
-
const resolver = (data:
|
|
103
|
+
const resolver = (data: any) => {
|
|
98
104
|
const result = subscriber(data);
|
|
99
105
|
if (result !== undefined) {
|
|
100
106
|
if (result instanceof Promise) {
|
|
@@ -128,18 +134,25 @@ const MessageChannel = () => {
|
|
|
128
134
|
};
|
|
129
135
|
};
|
|
130
136
|
|
|
131
|
-
|
|
137
|
+
/**
|
|
138
|
+
* typename: 消息类型,消息的发布和订阅都依赖这个typename
|
|
139
|
+
* msg:消息发布时带的参数
|
|
140
|
+
*/
|
|
141
|
+
const publish = (typename: string, data?: any) => {
|
|
132
142
|
try {
|
|
133
143
|
cachedCarrier?.postMessage({
|
|
134
144
|
typename: typename,
|
|
135
|
-
data:
|
|
145
|
+
data: data,
|
|
136
146
|
});
|
|
137
147
|
} catch (error) {0;}
|
|
138
148
|
};
|
|
139
149
|
|
|
140
150
|
|
|
141
|
-
|
|
142
|
-
|
|
151
|
+
/**
|
|
152
|
+
* 如果要唤醒其余插件的webview,则双方插件的provider、web都要调用这个函数初始化
|
|
153
|
+
* viewType:provider传递WebviewProvieder的viewType,web则不用传递参数
|
|
154
|
+
*/
|
|
155
|
+
const initiator = (viewType?: string) => {
|
|
143
156
|
// for node
|
|
144
157
|
if(viewType) {
|
|
145
158
|
vscode.commands.registerCommand(`to_${viewType}`, async (args) => {
|
|
@@ -178,7 +191,7 @@ const MessageChannel = () => {
|
|
|
178
191
|
});
|
|
179
192
|
return;
|
|
180
193
|
}
|
|
181
|
-
publish('webviewRenderDone'
|
|
194
|
+
publish('webviewRenderDone');
|
|
182
195
|
subscribe('clickAnyElement', (data) => {
|
|
183
196
|
const clickAnyElement = async (data: any) => {
|
|
184
197
|
const selectorList = data?.selector;
|
|
@@ -222,12 +235,12 @@ const MessageChannel = () => {
|
|
|
222
235
|
const pubWithSub = async (
|
|
223
236
|
typename: string,
|
|
224
237
|
msg: any,
|
|
225
|
-
subscriber?: (data:
|
|
238
|
+
subscriber?: (data: any) => any
|
|
226
239
|
) => {
|
|
227
240
|
publish(typename, msg);
|
|
228
241
|
|
|
229
242
|
return new Promise((resolve) => {
|
|
230
|
-
const removeSubscribe = subscribe(typename, (data:
|
|
243
|
+
const removeSubscribe = subscribe(typename, (data: any) => {
|
|
231
244
|
if (subscriber) {
|
|
232
245
|
subscriber(data);
|
|
233
246
|
} else {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**@type {import('eslint').Linter.Config} */
|
|
2
|
+
// eslint-disable-next-line no-undef
|
|
3
|
+
module.exports = {
|
|
4
|
+
root: true,
|
|
5
|
+
parser: '@typescript-eslint/parser',
|
|
6
|
+
plugins: [
|
|
7
|
+
'@typescript-eslint',
|
|
8
|
+
],
|
|
9
|
+
extends: [
|
|
10
|
+
'eslint:recommended',
|
|
11
|
+
'plugin:@typescript-eslint/recommended',
|
|
12
|
+
],
|
|
13
|
+
rules: {
|
|
14
|
+
'semi': [2, "always"],
|
|
15
|
+
'@typescript-eslint/no-unused-vars': 0,
|
|
16
|
+
'@typescript-eslint/no-explicit-any': 0,
|
|
17
|
+
'@typescript-eslint/explicit-module-boundary-types': 0,
|
|
18
|
+
'@typescript-eslint/no-non-null-assertion': 0,
|
|
19
|
+
}
|
|
20
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
{
|
|
2
|
+
// See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
|
|
3
|
+
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
|
|
4
|
+
|
|
5
|
+
// List of extensions which should be recommended for users of this workspace.
|
|
6
|
+
"recommendations": [
|
|
7
|
+
"dbaeumer.vscode-eslint"
|
|
8
|
+
]
|
|
9
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// A launch configuration that compiles the extension and then opens it inside a new window
|
|
2
|
+
// Use IntelliSense to learn about possible attributes.
|
|
3
|
+
// Hover to view descriptions of existing attributes.
|
|
4
|
+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
|
5
|
+
{
|
|
6
|
+
"version": "0.2.0",
|
|
7
|
+
"configurations": [
|
|
8
|
+
{
|
|
9
|
+
"name": "Run Extension",
|
|
10
|
+
"type": "extensionHost",
|
|
11
|
+
"request": "launch",
|
|
12
|
+
"runtimeExecutable": "${execPath}",
|
|
13
|
+
"args": ["--extensionDevelopmentPath=${workspaceRoot}"],
|
|
14
|
+
"outFiles": ["${workspaceFolder}/out/**/*.js"],
|
|
15
|
+
"preLaunchTask": "npm: watch"
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
|
2
|
+
// for the documentation about the tasks.json format
|
|
3
|
+
{
|
|
4
|
+
"version": "2.0.0",
|
|
5
|
+
"tasks": [
|
|
6
|
+
{
|
|
7
|
+
"type": "npm",
|
|
8
|
+
"script": "watch",
|
|
9
|
+
"problemMatcher": "$tsc-watch",
|
|
10
|
+
"isBackground": true,
|
|
11
|
+
"presentation": {
|
|
12
|
+
"reveal": "never"
|
|
13
|
+
},
|
|
14
|
+
"group": {
|
|
15
|
+
"kind": "build",
|
|
16
|
+
"isDefault": true
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Calico Colors — Webview View API Sample
|
|
2
|
+
|
|
3
|
+
Demonstrates VS Code's [webview view API](https://github.com/microsoft/vscode/issues/46585). This includes:
|
|
4
|
+
|
|
5
|
+
- Contributing a webview based view to the explorer.
|
|
6
|
+
- Posting messages from an extension to a webview view
|
|
7
|
+
- Posting message from a webview to an extension
|
|
8
|
+
- Persisting state in the view.
|
|
9
|
+
- Contributing commands to the view title.
|
|
10
|
+
|
|
11
|
+
## VS Code API
|
|
12
|
+
|
|
13
|
+
### `vscode` module
|
|
14
|
+
|
|
15
|
+
- [`window.registerWebviewViewProvider`](https://code.visualstudio.com/api/references/vscode-api#window.registerWebviewViewProvider)
|
|
16
|
+
|
|
17
|
+
## Running the example
|
|
18
|
+
|
|
19
|
+
- Open this example in VS Code 1.49+
|
|
20
|
+
- `npm install`
|
|
21
|
+
- `npm run watch` or `npm run compile`
|
|
22
|
+
- `F5` to start debugging
|
|
23
|
+
|
|
24
|
+
In the explorer, expand the `Calico Colors` view.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
body {
|
|
2
|
+
background-color: transparent;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.color-list {
|
|
6
|
+
list-style: none;
|
|
7
|
+
padding: 0;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.color-entry {
|
|
11
|
+
width: 100%;
|
|
12
|
+
display: flex;
|
|
13
|
+
margin-bottom: 0.4em;
|
|
14
|
+
border: 1px solid var(--vscode-input-border);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.color-preview {
|
|
18
|
+
width: 2em;
|
|
19
|
+
height: 2em;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.color-preview:hover {
|
|
23
|
+
outline: inset white;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.color-input {
|
|
27
|
+
display: block;
|
|
28
|
+
flex: 1;
|
|
29
|
+
width: 100%;
|
|
30
|
+
color: var(--vscode-input-foreground);
|
|
31
|
+
background-color: var(--vscode-input-background);
|
|
32
|
+
border: none;
|
|
33
|
+
padding: 0 0.6em;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.add-color-button {
|
|
37
|
+
display: block;
|
|
38
|
+
border: none;
|
|
39
|
+
margin: 0 auto;
|
|
40
|
+
}
|
|
41
|
+
.command-webview {
|
|
42
|
+
border-top: 1px solid #3c3c3c;
|
|
43
|
+
margin-top: 15px;
|
|
44
|
+
}
|
|
45
|
+
h2 {
|
|
46
|
+
font-weight: bold;
|
|
47
|
+
}
|
|
48
|
+
.send-message {
|
|
49
|
+
margin-top: 16px;
|
|
50
|
+
display: flex;
|
|
51
|
+
}
|
|
52
|
+
.response-message {
|
|
53
|
+
display: flex;
|
|
54
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
//@ts-check
|
|
2
|
+
|
|
3
|
+
// This script will be run within the webview itself
|
|
4
|
+
// It cannot access the main VS Code APIs directly.
|
|
5
|
+
(function () {
|
|
6
|
+
const vscode = acquireVsCodeApi();
|
|
7
|
+
|
|
8
|
+
const oldState = vscode.getState() || { colors: [] };
|
|
9
|
+
|
|
10
|
+
/** @type {Array<{ value: string }>} */
|
|
11
|
+
let colors = oldState.colors;
|
|
12
|
+
|
|
13
|
+
updateColorList(colors);
|
|
14
|
+
|
|
15
|
+
document.querySelector('.add-color-button').addEventListener('click', () => {
|
|
16
|
+
addColor();
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
// Handle messages sent from the extension to the webview
|
|
20
|
+
window.addEventListener('message', event => {
|
|
21
|
+
const message = event.data; // The json data that the extension sent
|
|
22
|
+
switch (message.type) {
|
|
23
|
+
case 'addColor':
|
|
24
|
+
{
|
|
25
|
+
addColor();
|
|
26
|
+
break;
|
|
27
|
+
}
|
|
28
|
+
case 'clearColors':
|
|
29
|
+
{
|
|
30
|
+
colors = [];
|
|
31
|
+
updateColorList(colors);
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @param {Array<{ value: string }>} colors
|
|
40
|
+
*/
|
|
41
|
+
function updateColorList(colors) {
|
|
42
|
+
const ul = document.querySelector('.color-list');
|
|
43
|
+
ul.textContent = '';
|
|
44
|
+
for (const color of colors) {
|
|
45
|
+
const li = document.createElement('li');
|
|
46
|
+
li.className = 'color-entry';
|
|
47
|
+
|
|
48
|
+
const colorPreview = document.createElement('div');
|
|
49
|
+
colorPreview.className = 'color-preview';
|
|
50
|
+
colorPreview.style.backgroundColor = `#${color.value}`;
|
|
51
|
+
colorPreview.addEventListener('click', () => {
|
|
52
|
+
onColorClicked(color.value);
|
|
53
|
+
});
|
|
54
|
+
li.appendChild(colorPreview);
|
|
55
|
+
|
|
56
|
+
const input = document.createElement('input');
|
|
57
|
+
input.className = 'color-input';
|
|
58
|
+
input.type = 'text';
|
|
59
|
+
input.value = color.value;
|
|
60
|
+
input.addEventListener('change', (e) => {
|
|
61
|
+
const value = e.target.value;
|
|
62
|
+
if (!value) {
|
|
63
|
+
// Treat empty value as delete
|
|
64
|
+
colors.splice(colors.indexOf(color), 1);
|
|
65
|
+
} else {
|
|
66
|
+
color.value = value;
|
|
67
|
+
}
|
|
68
|
+
updateColorList(colors);
|
|
69
|
+
});
|
|
70
|
+
li.appendChild(input);
|
|
71
|
+
|
|
72
|
+
ul.appendChild(li);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Update the saved state
|
|
76
|
+
vscode.setState({ colors: colors });
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* @param {string} color
|
|
81
|
+
*/
|
|
82
|
+
function onColorClicked(color) {
|
|
83
|
+
vscode.postMessage({ type: 'colorSelected', value: color });
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* @returns string
|
|
88
|
+
*/
|
|
89
|
+
function getNewCalicoColor() {
|
|
90
|
+
const colors = ['020202', 'f1eeee', 'a85b20', 'daab70', 'efcb99'];
|
|
91
|
+
return colors[Math.floor(Math.random() * colors.length)];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function addColor() {
|
|
95
|
+
colors.push({ value: getNewCalicoColor() });
|
|
96
|
+
updateColorList(colors);
|
|
97
|
+
}
|
|
98
|
+
}());
|
|
99
|
+
|
|
100
|
+
|