@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.
Files changed (70) hide show
  1. package/README.md +181 -0
  2. package/dist/messageChannel.d.ts +10 -0
  3. package/dist/{messageChennel.js → messageChannel.js} +25 -8
  4. package/examples/command-webview-sample/.eslintrc.js +23 -0
  5. package/examples/command-webview-sample/.vscode/extensions.json +9 -0
  6. package/examples/command-webview-sample/.vscode/launch.json +18 -0
  7. package/examples/command-webview-sample/.vscode/settings.json +3 -0
  8. package/examples/command-webview-sample/.vscode/tasks.json +20 -0
  9. package/examples/command-webview-sample/README.md +47 -0
  10. package/examples/command-webview-sample/demo.gif +0 -0
  11. package/examples/command-webview-sample/media/cat.gif +0 -0
  12. package/examples/command-webview-sample/media/jsconfig.json +22 -0
  13. package/examples/command-webview-sample/media/main.js +41 -0
  14. package/examples/command-webview-sample/media/reset.css +30 -0
  15. package/examples/command-webview-sample/media/vscode.css +91 -0
  16. package/examples/command-webview-sample/package-lock.json +2764 -0
  17. package/examples/command-webview-sample/package.json +51 -0
  18. package/examples/command-webview-sample/src/extension.ts +227 -0
  19. package/{src/messageChennel.ts → examples/command-webview-sample/src/messageChannel.ts} +34 -21
  20. package/examples/command-webview-sample/tsconfig.json +12 -0
  21. package/examples/publish-webview-sample/.eslintrc.js +20 -0
  22. package/examples/publish-webview-sample/.vscode/extensions.json +9 -0
  23. package/examples/publish-webview-sample/.vscode/launch.json +18 -0
  24. package/examples/publish-webview-sample/.vscode/settings.json +3 -0
  25. package/examples/publish-webview-sample/.vscode/tasks.json +20 -0
  26. package/examples/publish-webview-sample/README.md +24 -0
  27. package/examples/publish-webview-sample/media/main.css +54 -0
  28. package/examples/publish-webview-sample/media/main.js +100 -0
  29. package/examples/publish-webview-sample/media/reset.css +30 -0
  30. package/examples/publish-webview-sample/media/vscode.css +91 -0
  31. package/examples/publish-webview-sample/package-lock.json +2720 -0
  32. package/examples/publish-webview-sample/package.json +71 -0
  33. package/examples/publish-webview-sample/src/extension.ts +170 -0
  34. package/examples/publish-webview-sample/src/messageChannel.ts +264 -0
  35. package/examples/publish-webview-sample/tsconfig.json +12 -0
  36. package/examples/url-webview-sample/.eslintignore +1 -0
  37. package/examples/url-webview-sample/.eslintrc.js +20 -0
  38. package/examples/url-webview-sample/.vscode/extensions.json +9 -0
  39. package/examples/url-webview-sample/.vscode/launch.json +18 -0
  40. package/examples/url-webview-sample/.vscode/settings.json +3 -0
  41. package/examples/url-webview-sample/.vscode/tasks.json +20 -0
  42. package/examples/url-webview-sample/README.md +25 -0
  43. package/examples/url-webview-sample/documentation/example.png +0 -0
  44. package/examples/url-webview-sample/exampleFiles/example.cscratch +14 -0
  45. package/examples/url-webview-sample/exampleFiles/example.pawDraw +0 -0
  46. package/examples/url-webview-sample/exampleFiles/log/python-kaleido-case-api.exe.log +1 -0
  47. package/examples/url-webview-sample/exampleFiles/log/python-request.exe.log +1 -0
  48. package/examples/url-webview-sample/exampleFiles/pump/config/default.json +1 -0
  49. package/examples/url-webview-sample/exampleFiles/test_cases/log/output_202511181702.log +6 -0
  50. package/examples/url-webview-sample/media/catScratch.css +65 -0
  51. package/examples/url-webview-sample/media/catScratch.js +100 -0
  52. package/examples/url-webview-sample/media/paw-color.svg +21 -0
  53. package/examples/url-webview-sample/media/paw-outline.svg +21 -0
  54. package/examples/url-webview-sample/media/pawDraw.css +83 -0
  55. package/examples/url-webview-sample/media/pawDraw.js +266 -0
  56. package/examples/url-webview-sample/media/reset.css +30 -0
  57. package/examples/url-webview-sample/media/sand-dark.jpg +0 -0
  58. package/examples/url-webview-sample/media/sand.jpg +0 -0
  59. package/examples/url-webview-sample/media/vscode.css +91 -0
  60. package/examples/url-webview-sample/package-lock.json +2751 -0
  61. package/examples/url-webview-sample/package.json +64 -0
  62. package/examples/url-webview-sample/src/catScratchEditor.ts +215 -0
  63. package/examples/url-webview-sample/src/dispose.ts +37 -0
  64. package/examples/url-webview-sample/src/extension.ts +7 -0
  65. package/examples/url-webview-sample/src/messageChannel.ts +264 -0
  66. package/examples/url-webview-sample/src/util.ts +8 -0
  67. package/examples/url-webview-sample/tsconfig.json +13 -0
  68. package/package.json +1 -1
  69. package/src/messageChannel.ts +264 -0
  70. 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 (carrier === null) {
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: feedbackData, typename } = event;
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(feedbackData);
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
- const publish = (typename, msg) => {
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: msg,
166
+ data: data,
153
167
  });
154
168
  }
155
169
  catch (error) {
156
170
  0;
157
171
  }
158
172
  };
159
- // vscode.WebviewViewProvider的静态方法中调用
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', null);
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,3 @@
1
+ {
2
+ "editor.insertSpaces": false
3
+ }
@@ -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
+ ![demo](demo.gif)
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.
@@ -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
+ }