@jiangzhongxi0322/messagechannel 1.0.0 → 1.0.1
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 +1 -1
- package/src/messageChannel.ts +264 -0
- package/dist/messageChennel.d.ts +0 -15
package/README.md
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
# MessageChannel 库
|
|
2
|
+
|
|
3
|
+
一个轻量级的消息通道库,用于在 VSCode 扩展和 Webview 之间进行通信。
|
|
4
|
+
|
|
5
|
+
## 特性
|
|
6
|
+
|
|
7
|
+
- **双向通信**:在 VSCode 扩展和 Webview 之间实现无缝通信。
|
|
8
|
+
- **事件订阅**:允许订阅特定事件类型以进行有针对性的消息处理。
|
|
9
|
+
- **基于 Promise 的 API**:支持使用 async/await 模式处理消息和响应。
|
|
10
|
+
- **跨扩展通信**:促进不同 VSCode 扩展之间的通信。
|
|
11
|
+
|
|
12
|
+
## 安装
|
|
13
|
+
|
|
14
|
+
通过 npm 安装库:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install messagechannel
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## 使用方法
|
|
21
|
+
|
|
22
|
+
### 基本设置
|
|
23
|
+
|
|
24
|
+
#### 在 VSCode 扩展(Node.js 端)
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import MessageChannel from 'messagechannel';
|
|
28
|
+
|
|
29
|
+
const channel = MessageChannel();
|
|
30
|
+
|
|
31
|
+
// 设置载体(VSCode Webview)
|
|
32
|
+
channel.setCarrier(yourWebview);
|
|
33
|
+
|
|
34
|
+
// 订阅一个事件
|
|
35
|
+
channel.subscribe('eventType1', (data) => {
|
|
36
|
+
console.log('接收到的数据:', data);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// 发布一个事件
|
|
40
|
+
channel.publish('eventType2', { key: 'value2' });
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
#### 在 Webview(浏览器端)
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
import MessageChannel from 'messagechannel';
|
|
47
|
+
|
|
48
|
+
const channel = MessageChannel();
|
|
49
|
+
|
|
50
|
+
// 初始化通道(Webview 中不需要载体)
|
|
51
|
+
channel.setCarrier(undefined);
|
|
52
|
+
|
|
53
|
+
// 订阅一个事件
|
|
54
|
+
channel.subscribe('eventType2', (data) => {
|
|
55
|
+
console.log('接收到的数据:', data);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
// 发布一个事件
|
|
59
|
+
channel.publish('eventType1', { key: 'value1' });
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### 高级用法
|
|
63
|
+
|
|
64
|
+
#### 使用 `pubWithSub` 进行请求-响应模式
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
import MessageChannel from 'messagechannel';
|
|
68
|
+
|
|
69
|
+
const channel = MessageChannel();
|
|
70
|
+
|
|
71
|
+
// 发布并订阅一次调用
|
|
72
|
+
const response = await channel.pubWithSub('eventType', { key: 'value' }); // 也可以channel.pubWithSub('eventType', { key: 'value' }, (response) => {})
|
|
73
|
+
console.log('响应:', response);
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
#### 跨扩展通信
|
|
77
|
+
插件A的web端
|
|
78
|
+
```typescript
|
|
79
|
+
import MessageChannel from 'messagechannel';
|
|
80
|
+
|
|
81
|
+
const channel = MessageChannel();
|
|
82
|
+
|
|
83
|
+
// 向另一个扩展发布事件
|
|
84
|
+
channel..pubWithSub(extensionId, options, callback);
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
1. extensionId,要通信的插件的唯一标识,由package.json中的name和publisher组成。
|
|
88
|
+
|
|
89
|
+
2. options,是一个对象,包含如下选项:
|
|
90
|
+
|
|
91
|
+
1. viewType,要打开的webview的type,一般声明为静态类型。
|
|
92
|
+
|
|
93
|
+
2. source
|
|
94
|
+
|
|
95
|
+
| 文件预览型webview | 命令打开的webview面板 |
|
|
96
|
+
| ----- | ----- |
|
|
97
|
+
| D:\\\\project\\\\vscode\\\\vscode-extension-samples\\\\url-webview-sample\\\\exampleFiles\\\\example.cscratch' | 相应的命令 |
|
|
98
|
+
|
|
99
|
+
3. selector,打开web后要自动点击的元素的选择器列表,多个元素依次点击。比如打开env的页面后自动添加添加按钮。
|
|
100
|
+
|
|
101
|
+
4. payload,要传递的额外参数,这个参数会自动添加为selector对应元素的payload属性
|
|
102
|
+
|
|
103
|
+
3. callback,接受另一个插件的web部分回传的数据
|
|
104
|
+
###### 示例
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
// 扩展 A webviewProvider
|
|
108
|
+
const channel = MessageChannel();
|
|
109
|
+
channel.initiator(ColorsViewProvider.viewType);
|
|
110
|
+
// 这俩顺序没关系
|
|
111
|
+
channel.setCarrier(webview);
|
|
112
|
+
// 扩展 A web 在某个时机比如点击按钮调用下面就会自动打开扩展B的webview
|
|
113
|
+
channel.pubWithSub('extensionB',
|
|
114
|
+
{
|
|
115
|
+
viewType: 'catCustoms.catScratch',
|
|
116
|
+
source: 'D:\\\\project\\\\vscode\\\\vscode-extension-samples\\\\url-webview-sample\\\\exampleFiles\\\\example.cscratch',
|
|
117
|
+
selector: ['input'],
|
|
118
|
+
payload: value
|
|
119
|
+
},
|
|
120
|
+
(data) => {
|
|
121
|
+
console.log(data);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
// 扩展 B webviewProvider
|
|
125
|
+
const channel = MessageChannel();
|
|
126
|
+
channel.initiator(CatCodingPanel.viewType);
|
|
127
|
+
// 这俩顺序没关系
|
|
128
|
+
channel.setCarrier(webview);
|
|
129
|
+
// 扩展 B web 在某个实际比如点击事件,可以通过feedbackResult回馈数据
|
|
130
|
+
const channel = MessageChannel();
|
|
131
|
+
document.querySelector('button').addEventListener('click', (args) => {
|
|
132
|
+
const result = document.querySelector('input').value;
|
|
133
|
+
feedbackResult && feedbackResult(result);
|
|
134
|
+
});
|
|
135
|
+
channel.setCarrier();
|
|
136
|
+
channel.initiator();
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## API 参考
|
|
140
|
+
|
|
141
|
+
### `MessageChannel()`
|
|
142
|
+
|
|
143
|
+
创建一个新的消息通道实例。
|
|
144
|
+
|
|
145
|
+
#### 返回值
|
|
146
|
+
|
|
147
|
+
一个包含以下方法的对象:
|
|
148
|
+
|
|
149
|
+
- `publish(typename: string, msg?: any)`:向通道发布消息。
|
|
150
|
+
- `subscribe(typename: string, subscriber: (data: FeedbackData) => any, once?: boolean)`:订阅一个消息类型。
|
|
151
|
+
- `setCarrier(carrier: any)`:设置消息通道的载体。
|
|
152
|
+
- `pubWithSub(typename: string, msg: any, subscriber?: (data: FeedbackData) => any)`:发布消息并订阅响应。
|
|
153
|
+
- `initiator(viewType: string)`:初始化特定 Webview 类型的通信。
|
|
154
|
+
- `getCarrier()`:获取当前载体。
|
|
155
|
+
|
|
156
|
+
### 接口
|
|
157
|
+
|
|
158
|
+
#### `Event`
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
interface Event {
|
|
162
|
+
typename?: string;
|
|
163
|
+
key?: string;
|
|
164
|
+
channelId: string;
|
|
165
|
+
data: FeedbackData;
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
#### `FeedbackData`
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
interface FeedbackData {
|
|
173
|
+
code: 0 | 1 | 2;
|
|
174
|
+
msg: string;
|
|
175
|
+
data: any;
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## 许可证
|
|
180
|
+
|
|
181
|
+
本项目采用 MIT 许可证。详情请见 [LICENSE](LICENSE) 文件。
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as vscode from 'vscode';
|
|
2
|
+
declare const MessageChannel: () => {
|
|
3
|
+
publish: (typename: string, data?: any) => void;
|
|
4
|
+
subscribe: (typename: string, subscriber: (data: any) => any, once?: boolean) => (() => void) | undefined;
|
|
5
|
+
setCarrier: (carrier?: null | vscode.Webview) => void;
|
|
6
|
+
pubWithSub: (typename: string, msg: any, subscriber?: (data: any) => any) => Promise<unknown>;
|
|
7
|
+
initiator: (viewType?: string) => void;
|
|
8
|
+
getCarrier: () => vscode.Webview | null;
|
|
9
|
+
};
|
|
10
|
+
export default MessageChannel;
|
|
@@ -46,6 +46,12 @@ const vscode = __importStar(require("vscode"));
|
|
|
46
46
|
const MessageChannel = () => {
|
|
47
47
|
let cachedCarrier;
|
|
48
48
|
let dispose;
|
|
49
|
+
/**
|
|
50
|
+
* @carrier 在vscode的webviewProvider以及webview的web内都调用这个接口,设置发送和接受事件的载体
|
|
51
|
+
* webviewProvider示例:CI.setCarrier(webviewView.webview); // 在最早获取到webview的地方
|
|
52
|
+
* webview的react项目示例:CI.setCarrier(); // 在根组件
|
|
53
|
+
* carrier如果为空,则清空之前的载体
|
|
54
|
+
*/
|
|
49
55
|
const setCarrier = (carrier) => {
|
|
50
56
|
if (carrier === undefined) {
|
|
51
57
|
cachedCarrier = window.acquireVsCodeApi();
|
|
@@ -58,19 +64,18 @@ const MessageChannel = () => {
|
|
|
58
64
|
dispose.dispose();
|
|
59
65
|
}
|
|
60
66
|
cachedCarrier = carrier;
|
|
61
|
-
if (
|
|
67
|
+
if (cachedCarrier === null) {
|
|
62
68
|
return;
|
|
63
69
|
}
|
|
64
70
|
dispose = cachedCarrier.onDidReceiveMessage((event) => messageHandler(event));
|
|
65
71
|
};
|
|
66
72
|
const subscribers = {};
|
|
67
73
|
const messageHandler = (event) => __awaiter(void 0, void 0, void 0, function* () {
|
|
68
|
-
const { data
|
|
69
|
-
const data = feedbackData.data;
|
|
74
|
+
const { data, typename } = event;
|
|
70
75
|
const isTalkInExtension = typename && subscribers[typename];
|
|
71
76
|
if (isTalkInExtension) {
|
|
72
77
|
subscribers[typename].forEach((resolver) => {
|
|
73
|
-
resolver(
|
|
78
|
+
resolver(data);
|
|
74
79
|
});
|
|
75
80
|
return;
|
|
76
81
|
}
|
|
@@ -106,6 +111,11 @@ const MessageChannel = () => {
|
|
|
106
111
|
}
|
|
107
112
|
}
|
|
108
113
|
});
|
|
114
|
+
/**
|
|
115
|
+
* typename: 消息类型,消息的发布和订阅都依赖这个typename
|
|
116
|
+
* subscriber:收到消息后把消息传递给subscriber
|
|
117
|
+
* once:一次性订阅,收到消息后就把订阅者移除
|
|
118
|
+
*/
|
|
109
119
|
const subscribe = (typename, subscriber, once = false) => {
|
|
110
120
|
if (!subscriber || !(subscriber instanceof Function)) {
|
|
111
121
|
return;
|
|
@@ -145,18 +155,25 @@ const MessageChannel = () => {
|
|
|
145
155
|
}
|
|
146
156
|
};
|
|
147
157
|
};
|
|
148
|
-
|
|
158
|
+
/**
|
|
159
|
+
* typename: 消息类型,消息的发布和订阅都依赖这个typename
|
|
160
|
+
* msg:消息发布时带的参数
|
|
161
|
+
*/
|
|
162
|
+
const publish = (typename, data) => {
|
|
149
163
|
try {
|
|
150
164
|
cachedCarrier === null || cachedCarrier === void 0 ? void 0 : cachedCarrier.postMessage({
|
|
151
165
|
typename: typename,
|
|
152
|
-
data:
|
|
166
|
+
data: data,
|
|
153
167
|
});
|
|
154
168
|
}
|
|
155
169
|
catch (error) {
|
|
156
170
|
0;
|
|
157
171
|
}
|
|
158
172
|
};
|
|
159
|
-
|
|
173
|
+
/**
|
|
174
|
+
* 如果要唤醒其余插件的webview,则双方插件的provider、web都要调用这个函数初始化
|
|
175
|
+
* viewType:provider传递WebviewProvieder的viewType,web则不用传递参数
|
|
176
|
+
*/
|
|
160
177
|
const initiator = (viewType) => {
|
|
161
178
|
// for node
|
|
162
179
|
if (viewType) {
|
|
@@ -191,7 +208,7 @@ const MessageChannel = () => {
|
|
|
191
208
|
}));
|
|
192
209
|
return;
|
|
193
210
|
}
|
|
194
|
-
publish('webviewRenderDone'
|
|
211
|
+
publish('webviewRenderDone');
|
|
195
212
|
subscribe('clickAnyElement', (data) => {
|
|
196
213
|
const clickAnyElement = (data) => __awaiter(void 0, void 0, void 0, function* () {
|
|
197
214
|
const selectorList = data === null || data === void 0 ? void 0 : data.selector;
|
|
@@ -0,0 +1,23 @@
|
|
|
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
|
+
ignorePatterns: [
|
|
14
|
+
'media'
|
|
15
|
+
],
|
|
16
|
+
rules: {
|
|
17
|
+
'semi': [2, "always"],
|
|
18
|
+
'@typescript-eslint/no-unused-vars': 0,
|
|
19
|
+
'@typescript-eslint/no-explicit-any': 0,
|
|
20
|
+
'@typescript-eslint/explicit-module-boundary-types': 0,
|
|
21
|
+
'@typescript-eslint/no-non-null-assertion': 0,
|
|
22
|
+
}
|
|
23
|
+
};
|
|
@@ -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,47 @@
|
|
|
1
|
+
# Cat Coding — A Webview API Sample
|
|
2
|
+
|
|
3
|
+
Demonstrates VS Code's [webview API](https://code.visualstudio.com/api/extension-guides/webview). This includes:
|
|
4
|
+
|
|
5
|
+
- Creating and showing a basic webview.
|
|
6
|
+
- Dynamically updating a webview's content.
|
|
7
|
+
- Loading local content in a webview.
|
|
8
|
+
- Running scripts in a webview.
|
|
9
|
+
- Sending message from an extension to a webview.
|
|
10
|
+
- Sending messages from a webview to an extension.
|
|
11
|
+
- Using a basic content security policy.
|
|
12
|
+
- Webview lifecycle and handling dispose.
|
|
13
|
+
- Saving and restoring state when the panel goes into the background.
|
|
14
|
+
- Serialization and persistence across VS Code reboots.
|
|
15
|
+
|
|
16
|
+
## Demo
|
|
17
|
+
|
|
18
|
+

|
|
19
|
+
|
|
20
|
+
## VS Code API
|
|
21
|
+
|
|
22
|
+
### `vscode` module
|
|
23
|
+
|
|
24
|
+
- [`window.createWebviewPanel`](https://code.visualstudio.com/api/references/vscode-api#window.createWebviewPanel)
|
|
25
|
+
- [`window.registerWebviewPanelSerializer`](https://code.visualstudio.com/api/references/vscode-api#window.registerWebviewPanelSerializer)
|
|
26
|
+
|
|
27
|
+
## Running the example
|
|
28
|
+
|
|
29
|
+
- Open this example in VS Code 1.47+
|
|
30
|
+
- `npm install`
|
|
31
|
+
- `npm run watch` or `npm run compile`
|
|
32
|
+
- `F5` to start debugging
|
|
33
|
+
|
|
34
|
+
Run the `Cat Coding: Start cat coding session` to create the webview.
|
|
35
|
+
|
|
36
|
+
## Commands
|
|
37
|
+
|
|
38
|
+
This extension provides the following commands:
|
|
39
|
+
|
|
40
|
+
- `Cat Coding: Start cat coding session`: Creates and displays the Cat Coding webview.
|
|
41
|
+
- `Cat Coding: Do refactor`: Halves the count of lines of code displayed in the Cat Coding webview.
|
|
42
|
+
|
|
43
|
+
## Messages
|
|
44
|
+
|
|
45
|
+
The Cat Coding webview can send the following messages to the extension:
|
|
46
|
+
|
|
47
|
+
- `alert`: Sent when the cat introduces a bug. The message includes the text '🐛 on line ' followed by the current line count.
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"module": "commonjs",
|
|
4
|
+
"target": "es2020",
|
|
5
|
+
"jsx": "preserve",
|
|
6
|
+
"checkJs": true,
|
|
7
|
+
"strict": true,
|
|
8
|
+
"strictFunctionTypes": true,
|
|
9
|
+
"lib": [
|
|
10
|
+
"dom"
|
|
11
|
+
]
|
|
12
|
+
},
|
|
13
|
+
"exclude": [
|
|
14
|
+
"node_modules",
|
|
15
|
+
"**/node_modules/*"
|
|
16
|
+
],
|
|
17
|
+
"typeAcquisition": {
|
|
18
|
+
"include": [
|
|
19
|
+
"@types/vscode-webview"
|
|
20
|
+
]
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// This script will be run within the webview itself
|
|
2
|
+
// It cannot access the main VS Code APIs directly.
|
|
3
|
+
|
|
4
|
+
(function () {
|
|
5
|
+
const vscode = acquireVsCodeApi();
|
|
6
|
+
|
|
7
|
+
const oldState = /** @type {{ count: number} | undefined} */ (vscode.getState());
|
|
8
|
+
|
|
9
|
+
const counter = /** @type {HTMLElement} */ (document.getElementById('lines-of-code-counter'));
|
|
10
|
+
console.log('Initial state', oldState);
|
|
11
|
+
|
|
12
|
+
let currentCount = (oldState && oldState.count) || 0;
|
|
13
|
+
counter.textContent = `${currentCount}`;
|
|
14
|
+
|
|
15
|
+
setInterval(() => {
|
|
16
|
+
counter.textContent = `${currentCount++} `;
|
|
17
|
+
|
|
18
|
+
// Update state
|
|
19
|
+
vscode.setState({ count: currentCount });
|
|
20
|
+
|
|
21
|
+
// Alert the extension when the cat introduces a bug
|
|
22
|
+
if (Math.random() < Math.min(0.001 * currentCount, 0.05)) {
|
|
23
|
+
// Send a message back to the extension
|
|
24
|
+
vscode.postMessage({
|
|
25
|
+
command: 'alert',
|
|
26
|
+
text: '🐛 on line ' + currentCount
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}, 100);
|
|
30
|
+
|
|
31
|
+
// Handle messages sent from the extension to the webview
|
|
32
|
+
window.addEventListener('message', event => {
|
|
33
|
+
const message = event.data; // The json data that the extension sent
|
|
34
|
+
switch (message.command) {
|
|
35
|
+
case 'refactor':
|
|
36
|
+
currentCount = Math.ceil(currentCount * 0.5);
|
|
37
|
+
counter.textContent = `${currentCount}`;
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}());
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
html {
|
|
2
|
+
box-sizing: border-box;
|
|
3
|
+
font-size: 13px;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
*,
|
|
7
|
+
*:before,
|
|
8
|
+
*:after {
|
|
9
|
+
box-sizing: inherit;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
body,
|
|
13
|
+
h1,
|
|
14
|
+
h2,
|
|
15
|
+
h3,
|
|
16
|
+
h4,
|
|
17
|
+
h5,
|
|
18
|
+
h6,
|
|
19
|
+
p,
|
|
20
|
+
ol,
|
|
21
|
+
ul {
|
|
22
|
+
margin: 0;
|
|
23
|
+
padding: 0;
|
|
24
|
+
font-weight: normal;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
img {
|
|
28
|
+
max-width: 100%;
|
|
29
|
+
height: auto;
|
|
30
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--container-padding: 20px;
|
|
3
|
+
--input-padding-vertical: 6px;
|
|
4
|
+
--input-padding-horizontal: 4px;
|
|
5
|
+
--input-margin-vertical: 4px;
|
|
6
|
+
--input-margin-horizontal: 0;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
body {
|
|
10
|
+
padding: 0 var(--container-padding);
|
|
11
|
+
color: var(--vscode-foreground);
|
|
12
|
+
font-size: var(--vscode-font-size);
|
|
13
|
+
font-weight: var(--vscode-font-weight);
|
|
14
|
+
font-family: var(--vscode-font-family);
|
|
15
|
+
background-color: var(--vscode-editor-background);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
ol,
|
|
19
|
+
ul {
|
|
20
|
+
padding-left: var(--container-padding);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
body > *,
|
|
24
|
+
form > * {
|
|
25
|
+
margin-block-start: var(--input-margin-vertical);
|
|
26
|
+
margin-block-end: var(--input-margin-vertical);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
*:focus {
|
|
30
|
+
outline-color: var(--vscode-focusBorder) !important;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
a {
|
|
34
|
+
color: var(--vscode-textLink-foreground);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
a:hover,
|
|
38
|
+
a:active {
|
|
39
|
+
color: var(--vscode-textLink-activeForeground);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
code {
|
|
43
|
+
font-size: var(--vscode-editor-font-size);
|
|
44
|
+
font-family: var(--vscode-editor-font-family);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
button {
|
|
48
|
+
border: none;
|
|
49
|
+
padding: var(--input-padding-vertical) var(--input-padding-horizontal);
|
|
50
|
+
width: 100%;
|
|
51
|
+
text-align: center;
|
|
52
|
+
outline: 1px solid transparent;
|
|
53
|
+
outline-offset: 2px !important;
|
|
54
|
+
color: var(--vscode-button-foreground);
|
|
55
|
+
background: var(--vscode-button-background);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
button:hover {
|
|
59
|
+
cursor: pointer;
|
|
60
|
+
background: var(--vscode-button-hoverBackground);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
button:focus {
|
|
64
|
+
outline-color: var(--vscode-focusBorder);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
button.secondary {
|
|
68
|
+
color: var(--vscode-button-secondaryForeground);
|
|
69
|
+
background: var(--vscode-button-secondaryBackground);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
button.secondary:hover {
|
|
73
|
+
background: var(--vscode-button-secondaryHoverBackground);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
input:not([type='checkbox']),
|
|
77
|
+
textarea {
|
|
78
|
+
display: block;
|
|
79
|
+
width: 100%;
|
|
80
|
+
border: none;
|
|
81
|
+
font-family: var(--vscode-font-family);
|
|
82
|
+
padding: var(--input-padding-vertical) var(--input-padding-horizontal);
|
|
83
|
+
color: var(--vscode-input-foreground);
|
|
84
|
+
outline-color: var(--vscode-input-border);
|
|
85
|
+
background-color: var(--vscode-input-background);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
input::placeholder,
|
|
89
|
+
textarea::placeholder {
|
|
90
|
+
color: var(--vscode-input-placeholderForeground);
|
|
91
|
+
}
|