@tomjs/vite-plugin-vscode 2.4.1 → 2.5.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 +9 -0
- package/README.zh_CN.md +9 -0
- package/dist/client.global.js +44 -38
- package/dist/webview.js +164 -123
- package/dist/webview.mjs +163 -122
- package/package.json +1 -2
package/README.md
CHANGED
|
@@ -200,6 +200,14 @@ function __getWebviewHtml__(
|
|
|
200
200
|
): string;
|
|
201
201
|
```
|
|
202
202
|
|
|
203
|
+
### Warning
|
|
204
|
+
|
|
205
|
+
When using the `acquireVsCodeApi().getState()` method of [@types/vscode-webview](https://www.npmjs.com/package/@types/vscode-webview), you must use `await` to call it. Since `acquireVsCodeApi` is a simulated implementation of this method by the plugin, it is inconsistent with the original method. I am very sorry. If you have other solutions, please share them. Thank you very much.
|
|
206
|
+
|
|
207
|
+
```ts
|
|
208
|
+
const value = await acquireVsCodeApi().getState();
|
|
209
|
+
```
|
|
210
|
+
|
|
203
211
|
## Documentation
|
|
204
212
|
|
|
205
213
|
- [index.d.ts](https://www.unpkg.com/browse/@tomjs/vite-plugin-vscode/dist/index.d.ts) provided by [unpkg.com](https://www.unpkg.com).
|
|
@@ -375,3 +383,4 @@ Open the [examples](./examples) directory, there are `vue` and `react` examples.
|
|
|
375
383
|
|
|
376
384
|
- [@tomjs/vscode](https://npmjs.com/package/@tomjs/vscode): Some utilities to simplify the development of [VSCode Extensions](https://marketplace.visualstudio.com/VSCode).
|
|
377
385
|
- [@tomjs/vscode-dev](https://npmjs.com/package/@tomjs/vscode-dev): Some development tools to simplify the development of [vscode extensions](https://marketplace.visualstudio.com/VSCode).
|
|
386
|
+
- [@tomjs/vscode-webview](https://npmjs.com/package/@tomjs/webview): Optimize the `postMessage` issue between `webview` page and [vscode extensions](https://marketplace.visualstudio.com/VSCode)
|
package/README.zh_CN.md
CHANGED
|
@@ -204,6 +204,14 @@ function __getWebviewHtml__(
|
|
|
204
204
|
): string;
|
|
205
205
|
```
|
|
206
206
|
|
|
207
|
+
### 警告
|
|
208
|
+
|
|
209
|
+
使用 [@types/vscode-webview](https://www.npmjs.com/package/@types/vscode-webview) 的 `acquireVsCodeApi().getState()` 方法时,要使用 `await` 调用。由于 `acquireVsCodeApi` 是插件对该方法的模拟实现,故与原方法出现不一致性,非常抱歉。如果有其他方案,请分享,非常感谢。
|
|
210
|
+
|
|
211
|
+
```ts
|
|
212
|
+
const value = await acquireVsCodeApi().getState();
|
|
213
|
+
```
|
|
214
|
+
|
|
207
215
|
## 文档
|
|
208
216
|
|
|
209
217
|
- [unpkg.com](https://www.unpkg.com/) 提供的 [index.d.ts](https://www.unpkg.com/browse/@tomjs/vite-plugin-vscode/dist/index.d.ts).
|
|
@@ -378,3 +386,4 @@ pnpm build
|
|
|
378
386
|
|
|
379
387
|
- [@tomjs/vscode](https://npmjs.com/package/@tomjs/vscode): 一些实用工具,用于简化 [vscode 扩展](https://marketplace.visualstudio.com/VSCode) 的开发。
|
|
380
388
|
- [@tomjs/vscode-dev](https://npmjs.com/package/@tomjs/vscode-dev): 一些开发工具,用于简化 [vscode 扩展](https://marketplace.visualstudio.com/VSCode) 的开发。
|
|
389
|
+
- [@tomjs/vscode-webview](https://npmjs.com/package/@tomjs/vscode-webview): 优化 `webview` 页面与 [vscode 扩展](https://marketplace.visualstudio.com/VSCode) 的 `postMessage` 问题
|
package/dist/client.global.js
CHANGED
|
@@ -20,47 +20,60 @@
|
|
|
20
20
|
document.addEventListener("DOMContentLoaded", callback);
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
|
-
function setStateData(data) {
|
|
24
|
-
localStorage.setItem("vscode.state", JSON.stringify(data));
|
|
25
|
-
}
|
|
26
|
-
function getStateData() {
|
|
27
|
-
try {
|
|
28
|
-
const v = localStorage.getItem("vscode.state");
|
|
29
|
-
return v ? JSON.parse(v) : v;
|
|
30
|
-
} catch (e) {
|
|
31
|
-
}
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
23
|
function patchInitData(data) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
24
|
+
onDomReady(() => {
|
|
25
|
+
console.log(TAG, "patch client style");
|
|
26
|
+
const { style, body, root } = data;
|
|
27
|
+
document.documentElement.style.cssText = root.cssText;
|
|
28
|
+
document.body.className = body.className;
|
|
29
|
+
Object.keys(body.dataset).forEach((key) => {
|
|
30
|
+
document.body.dataset[key] = body.dataset[key];
|
|
31
|
+
});
|
|
32
|
+
const defaultStyles = document.createElement("style");
|
|
33
|
+
defaultStyles.id = "_defaultStyles";
|
|
34
|
+
defaultStyles.textContent = style;
|
|
35
|
+
document.head.appendChild(defaultStyles);
|
|
41
36
|
});
|
|
42
|
-
const defaultStyles = document.createElement("style");
|
|
43
|
-
defaultStyles.id = "_defaultStyles";
|
|
44
|
-
defaultStyles.textContent = style;
|
|
45
|
-
document.head.appendChild(defaultStyles);
|
|
46
37
|
}
|
|
38
|
+
var GET_STATE_TYPE = "[vscode:client]:getState";
|
|
39
|
+
var SET_STATE_TYPE = "[vscode:client]:setState";
|
|
40
|
+
var POST_MESSAGE_TYPE = "[vscode:client]:postMessage";
|
|
47
41
|
function patchAcquireVsCodeApi() {
|
|
48
42
|
class AcquireVsCodeApi {
|
|
49
43
|
postMessage(message) {
|
|
50
|
-
console.log(TAG
|
|
51
|
-
window.parent.postMessage({ type:
|
|
44
|
+
console.log(TAG, "mock acquireVsCodeApi.postMessage:", message);
|
|
45
|
+
window.parent.postMessage({ type: POST_MESSAGE_TYPE, data: message }, "*");
|
|
52
46
|
}
|
|
53
47
|
getState() {
|
|
54
|
-
console.log(TAG
|
|
55
|
-
return
|
|
48
|
+
console.log(TAG, "mock acquireVsCodeApi.getState");
|
|
49
|
+
return new Promise((resolve, reject) => {
|
|
50
|
+
function post() {
|
|
51
|
+
window.parent.postMessage({ type: GET_STATE_TYPE }, "*");
|
|
52
|
+
}
|
|
53
|
+
const timeoutId = setTimeout(() => {
|
|
54
|
+
window.removeEventListener("message", receive);
|
|
55
|
+
reject(new Error("Timeout"));
|
|
56
|
+
}, 2e3);
|
|
57
|
+
function receive(e) {
|
|
58
|
+
var _a, _b;
|
|
59
|
+
console.log(e);
|
|
60
|
+
if (!e.origin.startsWith("vscode-webview://") || ((_a = e.data) == null ? void 0 : _a.type) !== GET_STATE_TYPE) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
window.removeEventListener("message", receive);
|
|
64
|
+
clearTimeout(timeoutId);
|
|
65
|
+
resolve((_b = e.data) == null ? void 0 : _b.data);
|
|
66
|
+
}
|
|
67
|
+
window.addEventListener("message", receive);
|
|
68
|
+
post();
|
|
69
|
+
});
|
|
56
70
|
}
|
|
57
71
|
setState(newState) {
|
|
58
|
-
console.log(TAG
|
|
59
|
-
|
|
60
|
-
window.parent.postMessage({ type: "[vscode:client]:setSate", data: newState }, "*");
|
|
72
|
+
console.log(TAG, "mock acquireVsCodeApi.setState:", newState);
|
|
73
|
+
window.parent.postMessage({ type: SET_STATE_TYPE, data: newState }, "*");
|
|
61
74
|
}
|
|
62
75
|
}
|
|
63
|
-
console.log(TAG
|
|
76
|
+
console.log(TAG, "patch acquireVsCodeApi");
|
|
64
77
|
let api;
|
|
65
78
|
window.acquireVsCodeApi = () => {
|
|
66
79
|
if (!api) {
|
|
@@ -72,19 +85,12 @@
|
|
|
72
85
|
};
|
|
73
86
|
}
|
|
74
87
|
var INIT_TYPE = "[vscode:extension]:init";
|
|
75
|
-
var GET_STATE_TYPE = "[vscode:extension]:state";
|
|
76
88
|
window.addEventListener("message", (e) => {
|
|
77
89
|
const { type, data } = e.data || {};
|
|
78
|
-
if (!e.origin.startsWith("vscode-webview://") ||
|
|
90
|
+
if (!e.origin.startsWith("vscode-webview://") || type !== INIT_TYPE) {
|
|
79
91
|
return;
|
|
80
92
|
}
|
|
81
|
-
|
|
82
|
-
if (type === INIT_TYPE) {
|
|
83
|
-
patchInitData(data);
|
|
84
|
-
} else if (type === GET_STATE_TYPE) {
|
|
85
|
-
localStorage.setItem("vscode.state", JSON.stringify(data));
|
|
86
|
-
}
|
|
87
|
-
});
|
|
93
|
+
patchInitData(data);
|
|
88
94
|
});
|
|
89
95
|
}
|
|
90
96
|
});
|
package/dist/webview.js
CHANGED
|
@@ -1,148 +1,189 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/webview/template.html
|
|
2
2
|
var template_default = `<!doctype html>
|
|
3
3
|
<html lang="en">
|
|
4
|
-
<head>
|
|
5
|
-
<meta charset="UTF-8" />
|
|
6
|
-
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
7
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
8
|
-
<style>
|
|
9
|
-
html,
|
|
10
|
-
body {
|
|
11
|
-
width: 100%;
|
|
12
|
-
height: 100%;
|
|
13
|
-
margin: 0;
|
|
14
|
-
padding: 0;
|
|
15
|
-
overflow: hidden;
|
|
16
|
-
}
|
|
17
4
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
5
|
+
<head>
|
|
6
|
+
<meta charset="UTF-8" />
|
|
7
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
8
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
9
|
+
<style>
|
|
10
|
+
html,
|
|
11
|
+
body {
|
|
12
|
+
width: 100%;
|
|
13
|
+
height: 100%;
|
|
14
|
+
margin: 0;
|
|
15
|
+
padding: 0;
|
|
16
|
+
overflow: hidden;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
#webview-patch-iframe {
|
|
20
|
+
width: 100%;
|
|
21
|
+
height: 100%;
|
|
22
|
+
border: none;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.outer {
|
|
26
|
+
width: 100%;
|
|
27
|
+
height: 100%;
|
|
28
|
+
overflow: hidden;
|
|
29
|
+
}
|
|
30
|
+
</style>
|
|
31
|
+
|
|
32
|
+
<script type="module" id="webview-patch">
|
|
33
|
+
const TAG = '[@tomjs:vscode:extension] ';
|
|
34
|
+
|
|
35
|
+
function onDomReady(callback, doc) {
|
|
36
|
+
const _doc = doc || document
|
|
37
|
+
if (_doc.readyState === 'interactive' || _doc.readyState === 'complete') {
|
|
38
|
+
callback();
|
|
39
|
+
} else {
|
|
40
|
+
_doc.addEventListener('DOMContentLoaded', callback);
|
|
22
41
|
}
|
|
42
|
+
}
|
|
23
43
|
|
|
24
|
-
|
|
25
|
-
width: 100%;
|
|
26
|
-
height: 100%;
|
|
27
|
-
overflow: hidden;
|
|
28
|
-
}
|
|
29
|
-
</style>
|
|
44
|
+
let vsCodeApi;
|
|
30
45
|
|
|
31
|
-
|
|
32
|
-
|
|
46
|
+
function getApi() {
|
|
47
|
+
if (vsCodeApi) return vsCodeApi;
|
|
48
|
+
return (vsCodeApi = acquireVsCodeApi());
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function sendInitData(iframe) {
|
|
52
|
+
console.log(TAG + 'init data');
|
|
53
|
+
const dataset = {};
|
|
54
|
+
Object.keys(document.body.dataset).forEach(key => {
|
|
55
|
+
dataset[key] = document.body.dataset[key];
|
|
56
|
+
});
|
|
33
57
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
58
|
+
iframe.contentWindow.postMessage(
|
|
59
|
+
{
|
|
60
|
+
type: '[vscode:extension]:init',
|
|
61
|
+
data: {
|
|
62
|
+
state: getApi().getState(),
|
|
63
|
+
style: document.getElementById('_defaultStyles').innerHTML,
|
|
64
|
+
root: {
|
|
65
|
+
cssText: document.documentElement.style.cssText,
|
|
66
|
+
},
|
|
67
|
+
body: {
|
|
68
|
+
dataset: dataset,
|
|
69
|
+
className: document.body.className,
|
|
70
|
+
role: document.body.getAttribute('role'),
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
'*',
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function observeAttributeChanges(element, attributeName, callback) {
|
|
79
|
+
const observer = new MutationObserver(function (mutationsList) {
|
|
80
|
+
for (let mutation of mutationsList) {
|
|
81
|
+
if (mutation.type === 'attributes' && mutation.attributeName === attributeName) {
|
|
82
|
+
callback(mutation.target.getAttribute(attributeName));
|
|
83
|
+
}
|
|
39
84
|
}
|
|
85
|
+
});
|
|
86
|
+
observer.observe(element, { attributes: true });
|
|
87
|
+
return observer;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// message handler
|
|
91
|
+
let iframeLoaded = false;
|
|
92
|
+
const cacheMessages = [];
|
|
93
|
+
|
|
94
|
+
function handleMessage(e) {
|
|
95
|
+
const iframe = document.getElementById('webview-patch-iframe');
|
|
96
|
+
if (!iframeLoaded || !iframe) {
|
|
97
|
+
return;
|
|
40
98
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
99
|
+
if (e.origin.startsWith('vscode-webview://')) {
|
|
100
|
+
iframe.contentWindow.postMessage(e.data, '*');
|
|
101
|
+
} else if ('{{serverUrl}}'.startsWith(e.origin)) {
|
|
102
|
+
const { type, data } = e.data;
|
|
103
|
+
console.log(TAG + ' received:', e.data);
|
|
104
|
+
if (type === '[vscode:client]:postMessage') {
|
|
105
|
+
getApi().postMessage(data);
|
|
106
|
+
} else if (type === '[vscode:client]:getState') {
|
|
107
|
+
iframe.contentWindow.postMessage(
|
|
108
|
+
{
|
|
109
|
+
type: '[vscode:client]:getState',
|
|
110
|
+
data: getApi().getState(),
|
|
111
|
+
},
|
|
112
|
+
'*',
|
|
113
|
+
);
|
|
114
|
+
} else if (type === '[vscode:client]:setState') {
|
|
115
|
+
getApi().setState(data);
|
|
116
|
+
}
|
|
47
117
|
}
|
|
118
|
+
}
|
|
48
119
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
dataset[key] = document.body.dataset[key];
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
iframe.contentWindow.postMessage(
|
|
57
|
-
{
|
|
58
|
-
type: '[vscode:extension]:init',
|
|
59
|
-
data: {
|
|
60
|
-
state: getApi().getState(),
|
|
61
|
-
style: document.getElementById('_defaultStyles').innerHTML,
|
|
62
|
-
root: {
|
|
63
|
-
cssText: document.documentElement.style.cssText,
|
|
64
|
-
},
|
|
65
|
-
body: {
|
|
66
|
-
dataset: dataset,
|
|
67
|
-
className: document.body.className,
|
|
68
|
-
role: document.body.getAttribute('role'),
|
|
69
|
-
},
|
|
70
|
-
},
|
|
71
|
-
},
|
|
72
|
-
'*',
|
|
73
|
-
);
|
|
120
|
+
window.addEventListener('message', function (event) {
|
|
121
|
+
if (event.origin.startsWith('vscode-webview://')) {
|
|
122
|
+
cacheMessages.push(event);
|
|
123
|
+
return;
|
|
74
124
|
}
|
|
125
|
+
handleMessage(event);
|
|
126
|
+
});
|
|
75
127
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
} else if ('{{serverUrl}}'.startsWith(e.origin)) {
|
|
81
|
-
const { type, data } = e.data;
|
|
82
|
-
if (type === '[vscode:client]:postMessage') {
|
|
83
|
-
getApi().postMessage(data);
|
|
84
|
-
} else if (type === '[vscode:client]:getState') {
|
|
85
|
-
iframe.contentWindow.postMessage(
|
|
86
|
-
{
|
|
87
|
-
type: '[vscode:extension]:getState',
|
|
88
|
-
data: getApi().getState(),
|
|
89
|
-
},
|
|
90
|
-
'*',
|
|
91
|
-
);
|
|
92
|
-
} else if (type === '[vscode:client]:setState') {
|
|
93
|
-
getApi().setState(data);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
});
|
|
128
|
+
let isCacheWorking = false;
|
|
129
|
+
setInterval(() => {
|
|
130
|
+
if (isCacheWorking) {
|
|
131
|
+
return;
|
|
97
132
|
}
|
|
98
133
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
});
|
|
107
|
-
observer.observe(element, { attributes: true });
|
|
108
|
-
return observer;
|
|
134
|
+
isCacheWorking = true;
|
|
135
|
+
if (iframeLoaded) {
|
|
136
|
+
let event = cacheMessages.shift()
|
|
137
|
+
while (event) {
|
|
138
|
+
handleMessage(event);
|
|
139
|
+
event = cacheMessages.shift()
|
|
140
|
+
}
|
|
109
141
|
}
|
|
142
|
+
isCacheWorking = false;
|
|
143
|
+
}, 50);
|
|
144
|
+
|
|
145
|
+
onDomReady(function () {
|
|
146
|
+
/** @type {HTMLIFrameElement} */
|
|
147
|
+
const iframe = document.getElementById('webview-patch-iframe');
|
|
148
|
+
observeAttributeChanges(document.body, 'class', function (className) {
|
|
149
|
+
sendInitData(iframe);
|
|
150
|
+
});
|
|
110
151
|
|
|
111
152
|
onDomReady(function () {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
} catch (e) {
|
|
153
|
+
iframeLoaded = true;
|
|
154
|
+
sendInitData(iframe);
|
|
155
|
+
}, iframe.contentDocument);
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
iframe.addEventListener('load', function (e) {
|
|
159
|
+
iframeLoaded = true;
|
|
160
|
+
|
|
161
|
+
let interval = setInterval(() => {
|
|
162
|
+
try {
|
|
163
|
+
if (document.getElementById('_defaultStyles')) {
|
|
164
|
+
sendInitData(iframe);
|
|
165
|
+
// addListeners(iframe);
|
|
126
166
|
clearInterval(interval);
|
|
127
|
-
|
|
167
|
+
return;
|
|
128
168
|
}
|
|
129
|
-
}
|
|
130
|
-
|
|
169
|
+
} catch (e) {
|
|
170
|
+
clearInterval(interval);
|
|
171
|
+
console.error(e);
|
|
172
|
+
}
|
|
173
|
+
}, 10);
|
|
131
174
|
});
|
|
132
|
-
|
|
133
|
-
</
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
</div>
|
|
145
|
-
</body>
|
|
175
|
+
});
|
|
176
|
+
</script>
|
|
177
|
+
</head>
|
|
178
|
+
|
|
179
|
+
<body>
|
|
180
|
+
<div class="outer">
|
|
181
|
+
<iframe id="webview-patch-iframe" frameborder="0"
|
|
182
|
+
sandbox="allow-scripts allow-same-origin allow-forms allow-pointer-lock allow-downloads"
|
|
183
|
+
allow="cross-origin-isolated; autoplay; clipboard-read; clipboard-write" src="{{serverUrl}}"></iframe>
|
|
184
|
+
</div>
|
|
185
|
+
</body>
|
|
186
|
+
|
|
146
187
|
</html>
|
|
147
188
|
`;
|
|
148
189
|
|
package/dist/webview.mjs
CHANGED
|
@@ -1,148 +1,189 @@
|
|
|
1
1
|
// src/webview/template.html
|
|
2
2
|
var template_default = `<!doctype html>
|
|
3
3
|
<html lang="en">
|
|
4
|
-
<head>
|
|
5
|
-
<meta charset="UTF-8" />
|
|
6
|
-
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
7
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
8
|
-
<style>
|
|
9
|
-
html,
|
|
10
|
-
body {
|
|
11
|
-
width: 100%;
|
|
12
|
-
height: 100%;
|
|
13
|
-
margin: 0;
|
|
14
|
-
padding: 0;
|
|
15
|
-
overflow: hidden;
|
|
16
|
-
}
|
|
17
4
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
5
|
+
<head>
|
|
6
|
+
<meta charset="UTF-8" />
|
|
7
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
8
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
9
|
+
<style>
|
|
10
|
+
html,
|
|
11
|
+
body {
|
|
12
|
+
width: 100%;
|
|
13
|
+
height: 100%;
|
|
14
|
+
margin: 0;
|
|
15
|
+
padding: 0;
|
|
16
|
+
overflow: hidden;
|
|
17
|
+
}
|
|
23
18
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
</style>
|
|
19
|
+
#webview-patch-iframe {
|
|
20
|
+
width: 100%;
|
|
21
|
+
height: 100%;
|
|
22
|
+
border: none;
|
|
23
|
+
}
|
|
30
24
|
|
|
31
|
-
|
|
32
|
-
|
|
25
|
+
.outer {
|
|
26
|
+
width: 100%;
|
|
27
|
+
height: 100%;
|
|
28
|
+
overflow: hidden;
|
|
29
|
+
}
|
|
30
|
+
</style>
|
|
33
31
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
32
|
+
<script type="module" id="webview-patch">
|
|
33
|
+
const TAG = '[@tomjs:vscode:extension] ';
|
|
34
|
+
|
|
35
|
+
function onDomReady(callback, doc) {
|
|
36
|
+
const _doc = doc || document
|
|
37
|
+
if (_doc.readyState === 'interactive' || _doc.readyState === 'complete') {
|
|
38
|
+
callback();
|
|
39
|
+
} else {
|
|
40
|
+
_doc.addEventListener('DOMContentLoaded', callback);
|
|
40
41
|
}
|
|
42
|
+
}
|
|
41
43
|
|
|
42
|
-
|
|
44
|
+
let vsCodeApi;
|
|
43
45
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
function getApi() {
|
|
47
|
+
if (vsCodeApi) return vsCodeApi;
|
|
48
|
+
return (vsCodeApi = acquireVsCodeApi());
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function sendInitData(iframe) {
|
|
52
|
+
console.log(TAG + 'init data');
|
|
53
|
+
const dataset = {};
|
|
54
|
+
Object.keys(document.body.dataset).forEach(key => {
|
|
55
|
+
dataset[key] = document.body.dataset[key];
|
|
56
|
+
});
|
|
48
57
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
root: {
|
|
63
|
-
cssText: document.documentElement.style.cssText,
|
|
64
|
-
},
|
|
65
|
-
body: {
|
|
66
|
-
dataset: dataset,
|
|
67
|
-
className: document.body.className,
|
|
68
|
-
role: document.body.getAttribute('role'),
|
|
69
|
-
},
|
|
58
|
+
iframe.contentWindow.postMessage(
|
|
59
|
+
{
|
|
60
|
+
type: '[vscode:extension]:init',
|
|
61
|
+
data: {
|
|
62
|
+
state: getApi().getState(),
|
|
63
|
+
style: document.getElementById('_defaultStyles').innerHTML,
|
|
64
|
+
root: {
|
|
65
|
+
cssText: document.documentElement.style.cssText,
|
|
66
|
+
},
|
|
67
|
+
body: {
|
|
68
|
+
dataset: dataset,
|
|
69
|
+
className: document.body.className,
|
|
70
|
+
role: document.body.getAttribute('role'),
|
|
70
71
|
},
|
|
71
72
|
},
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
},
|
|
74
|
+
'*',
|
|
75
|
+
);
|
|
76
|
+
}
|
|
75
77
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
const { type, data } = e.data;
|
|
82
|
-
if (type === '[vscode:client]:postMessage') {
|
|
83
|
-
getApi().postMessage(data);
|
|
84
|
-
} else if (type === '[vscode:client]:getState') {
|
|
85
|
-
iframe.contentWindow.postMessage(
|
|
86
|
-
{
|
|
87
|
-
type: '[vscode:extension]:getState',
|
|
88
|
-
data: getApi().getState(),
|
|
89
|
-
},
|
|
90
|
-
'*',
|
|
91
|
-
);
|
|
92
|
-
} else if (type === '[vscode:client]:setState') {
|
|
93
|
-
getApi().setState(data);
|
|
94
|
-
}
|
|
78
|
+
function observeAttributeChanges(element, attributeName, callback) {
|
|
79
|
+
const observer = new MutationObserver(function (mutationsList) {
|
|
80
|
+
for (let mutation of mutationsList) {
|
|
81
|
+
if (mutation.type === 'attributes' && mutation.attributeName === attributeName) {
|
|
82
|
+
callback(mutation.target.getAttribute(attributeName));
|
|
95
83
|
}
|
|
96
|
-
}
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
observer.observe(element, { attributes: true });
|
|
87
|
+
return observer;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// message handler
|
|
91
|
+
let iframeLoaded = false;
|
|
92
|
+
const cacheMessages = [];
|
|
93
|
+
|
|
94
|
+
function handleMessage(e) {
|
|
95
|
+
const iframe = document.getElementById('webview-patch-iframe');
|
|
96
|
+
if (!iframeLoaded || !iframe) {
|
|
97
|
+
return;
|
|
97
98
|
}
|
|
99
|
+
if (e.origin.startsWith('vscode-webview://')) {
|
|
100
|
+
iframe.contentWindow.postMessage(e.data, '*');
|
|
101
|
+
} else if ('{{serverUrl}}'.startsWith(e.origin)) {
|
|
102
|
+
const { type, data } = e.data;
|
|
103
|
+
console.log(TAG + ' received:', e.data);
|
|
104
|
+
if (type === '[vscode:client]:postMessage') {
|
|
105
|
+
getApi().postMessage(data);
|
|
106
|
+
} else if (type === '[vscode:client]:getState') {
|
|
107
|
+
iframe.contentWindow.postMessage(
|
|
108
|
+
{
|
|
109
|
+
type: '[vscode:client]:getState',
|
|
110
|
+
data: getApi().getState(),
|
|
111
|
+
},
|
|
112
|
+
'*',
|
|
113
|
+
);
|
|
114
|
+
} else if (type === '[vscode:client]:setState') {
|
|
115
|
+
getApi().setState(data);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
98
119
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
120
|
+
window.addEventListener('message', function (event) {
|
|
121
|
+
if (event.origin.startsWith('vscode-webview://')) {
|
|
122
|
+
cacheMessages.push(event);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
handleMessage(event);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
let isCacheWorking = false;
|
|
129
|
+
setInterval(() => {
|
|
130
|
+
if (isCacheWorking) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
isCacheWorking = true;
|
|
135
|
+
if (iframeLoaded) {
|
|
136
|
+
let event = cacheMessages.shift()
|
|
137
|
+
while (event) {
|
|
138
|
+
handleMessage(event);
|
|
139
|
+
event = cacheMessages.shift()
|
|
140
|
+
}
|
|
109
141
|
}
|
|
142
|
+
isCacheWorking = false;
|
|
143
|
+
}, 50);
|
|
144
|
+
|
|
145
|
+
onDomReady(function () {
|
|
146
|
+
/** @type {HTMLIFrameElement} */
|
|
147
|
+
const iframe = document.getElementById('webview-patch-iframe');
|
|
148
|
+
observeAttributeChanges(document.body, 'class', function (className) {
|
|
149
|
+
sendInitData(iframe);
|
|
150
|
+
});
|
|
110
151
|
|
|
111
152
|
onDomReady(function () {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
} catch (e) {
|
|
153
|
+
iframeLoaded = true;
|
|
154
|
+
sendInitData(iframe);
|
|
155
|
+
}, iframe.contentDocument);
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
iframe.addEventListener('load', function (e) {
|
|
159
|
+
iframeLoaded = true;
|
|
160
|
+
|
|
161
|
+
let interval = setInterval(() => {
|
|
162
|
+
try {
|
|
163
|
+
if (document.getElementById('_defaultStyles')) {
|
|
164
|
+
sendInitData(iframe);
|
|
165
|
+
// addListeners(iframe);
|
|
126
166
|
clearInterval(interval);
|
|
127
|
-
|
|
167
|
+
return;
|
|
128
168
|
}
|
|
129
|
-
}
|
|
130
|
-
|
|
169
|
+
} catch (e) {
|
|
170
|
+
clearInterval(interval);
|
|
171
|
+
console.error(e);
|
|
172
|
+
}
|
|
173
|
+
}, 10);
|
|
131
174
|
});
|
|
132
|
-
|
|
133
|
-
</
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
</div>
|
|
145
|
-
</body>
|
|
175
|
+
});
|
|
176
|
+
</script>
|
|
177
|
+
</head>
|
|
178
|
+
|
|
179
|
+
<body>
|
|
180
|
+
<div class="outer">
|
|
181
|
+
<iframe id="webview-patch-iframe" frameborder="0"
|
|
182
|
+
sandbox="allow-scripts allow-same-origin allow-forms allow-pointer-lock allow-downloads"
|
|
183
|
+
allow="cross-origin-isolated; autoplay; clipboard-read; clipboard-write" src="{{serverUrl}}"></iframe>
|
|
184
|
+
</div>
|
|
185
|
+
</body>
|
|
186
|
+
|
|
146
187
|
</html>
|
|
147
188
|
`;
|
|
148
189
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tomjs/vite-plugin-vscode",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.1",
|
|
4
4
|
"description": "Use vue/react to develop 'vscode extension webview', supporting esm/cjs",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"vite",
|
|
@@ -62,7 +62,6 @@
|
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|
|
64
64
|
"@tomjs/node": "^2.2.0",
|
|
65
|
-
"@tomjs/vscode-extension-webview": "^1.2.0",
|
|
66
65
|
"dayjs": "^1.11.10",
|
|
67
66
|
"execa": "^5.1.1",
|
|
68
67
|
"kolorist": "^1.8.0",
|