@tomjs/vite-plugin-vscode 4.3.0 → 5.1.0
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 +14 -8
- package/README.zh_CN.md +14 -8
- package/dist/client.iife.js +84 -0
- package/dist/index.d.ts +74 -78
- package/dist/index.js +289 -346
- package/dist/webview.d.ts +7 -6
- package/dist/webview.js +14 -199
- package/package.json +31 -35
- package/dist/client.global.js +0 -93
- package/dist/index.d.mts +0 -93
- package/dist/index.mjs +0 -396
- package/dist/webview.d.mts +0 -13
- package/dist/webview.mjs +0 -203
package/dist/index.mjs
DELETED
|
@@ -1,396 +0,0 @@
|
|
|
1
|
-
// node_modules/.pnpm/tsup@8.5.0_@swc+core@1.11.24_jiti@2.4.2_postcss@8.5.6_tsx@4.20.3_typescript@5.7.3_yaml@2.8.0/node_modules/tsup/assets/esm_shims.js
|
|
2
|
-
import path from "path";
|
|
3
|
-
import { fileURLToPath } from "url";
|
|
4
|
-
var getFilename = () => fileURLToPath(import.meta.url);
|
|
5
|
-
var getDirname = () => path.dirname(getFilename());
|
|
6
|
-
var __dirname = /* @__PURE__ */ getDirname();
|
|
7
|
-
|
|
8
|
-
// src/index.ts
|
|
9
|
-
import fs from "fs";
|
|
10
|
-
import os from "os";
|
|
11
|
-
import path2 from "path";
|
|
12
|
-
import { cwd } from "process";
|
|
13
|
-
import { emptyDirSync, readFileSync, readJsonSync } from "@tomjs/node";
|
|
14
|
-
import merge from "lodash.merge";
|
|
15
|
-
import { parse as htmlParser } from "node-html-parser";
|
|
16
|
-
import { build as tsupBuild } from "tsup";
|
|
17
|
-
|
|
18
|
-
// src/constants.ts
|
|
19
|
-
var PLUGIN_NAME = "tomjs:vscode";
|
|
20
|
-
var PACKAGE_NAME = "@tomjs/vite-plugin-vscode";
|
|
21
|
-
var WEBVIEW_METHOD_NAME = "__getWebviewHtml__";
|
|
22
|
-
|
|
23
|
-
// src/logger.ts
|
|
24
|
-
import Logger from "@tomjs/logger";
|
|
25
|
-
function createLogger() {
|
|
26
|
-
return new Logger({
|
|
27
|
-
prefix: `[${PLUGIN_NAME}]`,
|
|
28
|
-
time: true
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// src/utils.ts
|
|
33
|
-
function resolveHostname(hostname) {
|
|
34
|
-
const loopbackHosts = /* @__PURE__ */ new Set([
|
|
35
|
-
"localhost",
|
|
36
|
-
"127.0.0.1",
|
|
37
|
-
"::1",
|
|
38
|
-
"0000:0000:0000:0000:0000:0000:0000:0001"
|
|
39
|
-
]);
|
|
40
|
-
const wildcardHosts = /* @__PURE__ */ new Set(["0.0.0.0", "::", "0000:0000:0000:0000:0000:0000:0000:0000"]);
|
|
41
|
-
return loopbackHosts.has(hostname) || wildcardHosts.has(hostname) ? "localhost" : hostname;
|
|
42
|
-
}
|
|
43
|
-
function resolveServerUrl(server) {
|
|
44
|
-
const addressInfo = server.httpServer.address();
|
|
45
|
-
const isAddressInfo = (x) => x == null ? void 0 : x.address;
|
|
46
|
-
if (isAddressInfo(addressInfo)) {
|
|
47
|
-
const { address, port } = addressInfo;
|
|
48
|
-
const hostname = resolveHostname(address);
|
|
49
|
-
const options = server.config.server;
|
|
50
|
-
const protocol = options.https ? "https" : "http";
|
|
51
|
-
const devBase = server.config.base;
|
|
52
|
-
const path3 = typeof options.open === "string" ? options.open : devBase;
|
|
53
|
-
const url = path3.startsWith("http") ? path3 : `${protocol}://${hostname}:${port}${path3}`;
|
|
54
|
-
return url;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// src/index.ts
|
|
59
|
-
var isDev = process.env.NODE_ENV === "development";
|
|
60
|
-
var logger = createLogger();
|
|
61
|
-
function getPkg() {
|
|
62
|
-
const pkgFile = path2.resolve(process.cwd(), "package.json");
|
|
63
|
-
if (!fs.existsSync(pkgFile)) {
|
|
64
|
-
throw new Error("Main file is not specified, and no package.json found");
|
|
65
|
-
}
|
|
66
|
-
const pkg = readJsonSync(pkgFile);
|
|
67
|
-
if (!pkg.main) {
|
|
68
|
-
throw new Error("Main file is not specified, please check package.json");
|
|
69
|
-
}
|
|
70
|
-
return pkg;
|
|
71
|
-
}
|
|
72
|
-
function preMergeOptions(options) {
|
|
73
|
-
const pkg = getPkg();
|
|
74
|
-
const format = pkg.type === "module" ? "esm" : "cjs";
|
|
75
|
-
const opts = merge(
|
|
76
|
-
{
|
|
77
|
-
webview: true,
|
|
78
|
-
recommended: true,
|
|
79
|
-
debug: false,
|
|
80
|
-
extension: {
|
|
81
|
-
entry: "extension/index.ts",
|
|
82
|
-
outDir: "dist-extension",
|
|
83
|
-
target: format === "esm" ? ["node20"] : ["es2019", "node14"],
|
|
84
|
-
format,
|
|
85
|
-
shims: true,
|
|
86
|
-
clean: true,
|
|
87
|
-
dts: false,
|
|
88
|
-
treeshake: isDev ? false : "smallest",
|
|
89
|
-
outExtension() {
|
|
90
|
-
return { js: ".js" };
|
|
91
|
-
},
|
|
92
|
-
external: ["vscode"],
|
|
93
|
-
skipNodeModulesBundle: isDev
|
|
94
|
-
}
|
|
95
|
-
},
|
|
96
|
-
options
|
|
97
|
-
);
|
|
98
|
-
const opt = opts.extension || {};
|
|
99
|
-
["entry", "format"].forEach((prop) => {
|
|
100
|
-
const value = opt[prop];
|
|
101
|
-
if (!Array.isArray(value) && value) {
|
|
102
|
-
opt[prop] = [value];
|
|
103
|
-
}
|
|
104
|
-
});
|
|
105
|
-
if (isDev) {
|
|
106
|
-
opt.sourcemap = opt.sourcemap ?? true;
|
|
107
|
-
} else {
|
|
108
|
-
opt.minify ??= true;
|
|
109
|
-
}
|
|
110
|
-
opt.external = ["vscode"].concat(opt.external ?? []);
|
|
111
|
-
if (!opt.skipNodeModulesBundle) {
|
|
112
|
-
opt.noExternal = Object.keys(pkg.dependencies || {}).concat(
|
|
113
|
-
Object.keys(pkg.peerDependencies || {})
|
|
114
|
-
);
|
|
115
|
-
}
|
|
116
|
-
opts.extension = opt;
|
|
117
|
-
if (opts.webview !== false) {
|
|
118
|
-
let name = WEBVIEW_METHOD_NAME;
|
|
119
|
-
if (typeof opts.webview === "string") {
|
|
120
|
-
name = opts.webview ?? WEBVIEW_METHOD_NAME;
|
|
121
|
-
}
|
|
122
|
-
opts.webview = Object.assign({ name }, opts.webview);
|
|
123
|
-
}
|
|
124
|
-
return opts;
|
|
125
|
-
}
|
|
126
|
-
var prodCachePkgName = `${PACKAGE_NAME}-inject`;
|
|
127
|
-
function genProdWebviewCode(cache, webview) {
|
|
128
|
-
webview = Object.assign({}, webview);
|
|
129
|
-
const prodCacheFolder = path2.join(cwd(), "node_modules", prodCachePkgName);
|
|
130
|
-
emptyDirSync(prodCacheFolder);
|
|
131
|
-
const destFile = path2.join(prodCacheFolder, "index.js");
|
|
132
|
-
function handleHtmlCode(html) {
|
|
133
|
-
const root = htmlParser(html);
|
|
134
|
-
const head = root.querySelector("head");
|
|
135
|
-
if (!head) {
|
|
136
|
-
root == null ? void 0 : root.insertAdjacentHTML("beforeend", "<head></head>");
|
|
137
|
-
}
|
|
138
|
-
const csp = (webview == null ? void 0 : webview.csp) || `<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src {{cspSource}} 'unsafe-inline'; script-src 'nonce-{{nonce}}' 'unsafe-eval';">`;
|
|
139
|
-
head.insertAdjacentHTML("afterbegin", csp);
|
|
140
|
-
if (csp && csp.includes("{{nonce}}")) {
|
|
141
|
-
const tags = {
|
|
142
|
-
script: "src",
|
|
143
|
-
link: "href"
|
|
144
|
-
};
|
|
145
|
-
Object.keys(tags).forEach((tag) => {
|
|
146
|
-
const elements = root.querySelectorAll(tag);
|
|
147
|
-
elements.forEach((element) => {
|
|
148
|
-
const attr = element.getAttribute(tags[tag]);
|
|
149
|
-
if (attr) {
|
|
150
|
-
element.setAttribute(tags[tag], `{{baseUri}}${attr}`);
|
|
151
|
-
}
|
|
152
|
-
element.setAttribute("nonce", "{{nonce}}");
|
|
153
|
-
});
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
return root.removeWhitespace().toString();
|
|
157
|
-
}
|
|
158
|
-
const cacheCode = (
|
|
159
|
-
/* js */
|
|
160
|
-
`const htmlCode = {
|
|
161
|
-
${Object.keys(cache).map((s) => `'${s}': \`${handleHtmlCode(cache[s])}\`,`).join("\n")}
|
|
162
|
-
};`
|
|
163
|
-
);
|
|
164
|
-
const code = (
|
|
165
|
-
/* js */
|
|
166
|
-
`import { Uri } from 'vscode';
|
|
167
|
-
|
|
168
|
-
${cacheCode}
|
|
169
|
-
|
|
170
|
-
function uuid() {
|
|
171
|
-
let text = '';
|
|
172
|
-
const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
173
|
-
for (let i = 0; i < 32; i++) {
|
|
174
|
-
text += possible.charAt(Math.floor(Math.random() * possible.length));
|
|
175
|
-
}
|
|
176
|
-
return text;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
export default function getWebviewHtml(options){
|
|
180
|
-
const { webview, context, inputName, injectCode } = options || {};
|
|
181
|
-
const nonce = uuid();
|
|
182
|
-
const baseUri = webview.asWebviewUri(Uri.joinPath(context.extensionUri, (process.env.VITE_WEBVIEW_DIST || 'dist')));
|
|
183
|
-
let html = htmlCode[inputName || 'index'] || '';
|
|
184
|
-
if (injectCode) {
|
|
185
|
-
html = html.replace('<head>', '<head>'+ injectCode);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
return html.replaceAll('{{cspSource}}', webview.cspSource).replaceAll('{{nonce}}', nonce).replaceAll('{{baseUri}}', baseUri);
|
|
189
|
-
}
|
|
190
|
-
`
|
|
191
|
-
);
|
|
192
|
-
fs.writeFileSync(destFile, code, { encoding: "utf8" });
|
|
193
|
-
return fixWindowsPath(destFile);
|
|
194
|
-
}
|
|
195
|
-
function fixWindowsPath(webviewPath) {
|
|
196
|
-
if (os.platform() === "win32") {
|
|
197
|
-
webviewPath = webviewPath.replaceAll("\\", "/");
|
|
198
|
-
}
|
|
199
|
-
return webviewPath;
|
|
200
|
-
}
|
|
201
|
-
function useVSCodePlugin(options) {
|
|
202
|
-
const opts = preMergeOptions(options);
|
|
203
|
-
const handleConfig = (config) => {
|
|
204
|
-
var _a, _b, _c, _d, _e;
|
|
205
|
-
let outDir = ((_a = config == null ? void 0 : config.build) == null ? void 0 : _a.outDir) || "dist";
|
|
206
|
-
opts.extension ??= {};
|
|
207
|
-
if (opts.recommended) {
|
|
208
|
-
opts.extension.outDir = path2.resolve(outDir, "extension");
|
|
209
|
-
outDir = path2.resolve(outDir, "webview");
|
|
210
|
-
}
|
|
211
|
-
const assetsDir = ((_b = config == null ? void 0 : config.build) == null ? void 0 : _b.assetsDir) || "assets";
|
|
212
|
-
const output = {
|
|
213
|
-
chunkFileNames: `${assetsDir}/[name].js`,
|
|
214
|
-
entryFileNames: `${assetsDir}/[name].js`,
|
|
215
|
-
assetFileNames: `${assetsDir}/[name].[ext]`
|
|
216
|
-
};
|
|
217
|
-
let rollupOutput = ((_d = (_c = config == null ? void 0 : config.build) == null ? void 0 : _c.rollupOptions) == null ? void 0 : _d.output) ?? {};
|
|
218
|
-
if (Array.isArray(rollupOutput)) {
|
|
219
|
-
rollupOutput.map((s) => Object.assign(s, output));
|
|
220
|
-
} else {
|
|
221
|
-
rollupOutput = Object.assign({}, rollupOutput, output);
|
|
222
|
-
}
|
|
223
|
-
return {
|
|
224
|
-
build: {
|
|
225
|
-
outDir,
|
|
226
|
-
sourcemap: isDev ? true : (_e = config == null ? void 0 : config.build) == null ? void 0 : _e.sourcemap,
|
|
227
|
-
rollupOptions: {
|
|
228
|
-
output: rollupOutput
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
};
|
|
232
|
-
};
|
|
233
|
-
let devWebviewClient;
|
|
234
|
-
if (opts.webview) {
|
|
235
|
-
devWebviewClient = readFileSync(path2.join(__dirname, "client.global.js"));
|
|
236
|
-
}
|
|
237
|
-
let resolvedConfig;
|
|
238
|
-
const prodHtmlCache = {};
|
|
239
|
-
let devtoolsFlag = false;
|
|
240
|
-
return [
|
|
241
|
-
{
|
|
242
|
-
name: "@tomjs:vscode",
|
|
243
|
-
apply: "serve",
|
|
244
|
-
config(config) {
|
|
245
|
-
return handleConfig(config);
|
|
246
|
-
},
|
|
247
|
-
configResolved(config) {
|
|
248
|
-
resolvedConfig = config;
|
|
249
|
-
},
|
|
250
|
-
configureServer(server) {
|
|
251
|
-
var _a;
|
|
252
|
-
if (!server || !server.httpServer) {
|
|
253
|
-
return;
|
|
254
|
-
}
|
|
255
|
-
(_a = server.httpServer) == null ? void 0 : _a.once("listening", async () => {
|
|
256
|
-
const env = {
|
|
257
|
-
NODE_ENV: server.config.mode || "development",
|
|
258
|
-
VITE_DEV_SERVER_URL: resolveServerUrl(server)
|
|
259
|
-
};
|
|
260
|
-
logger.info("extension build start");
|
|
261
|
-
let buildCount = 0;
|
|
262
|
-
const webview = opts == null ? void 0 : opts.webview;
|
|
263
|
-
const { onSuccess: _onSuccess, ...tsupOptions } = opts.extension || {};
|
|
264
|
-
await tsupBuild(
|
|
265
|
-
merge(tsupOptions, {
|
|
266
|
-
watch: true,
|
|
267
|
-
env,
|
|
268
|
-
silent: true,
|
|
269
|
-
esbuildPlugins: !webview ? [] : [
|
|
270
|
-
{
|
|
271
|
-
name: "@tomjs:vscode:inject",
|
|
272
|
-
setup(build) {
|
|
273
|
-
build.onLoad({ filter: /\.ts$/ }, async (args) => {
|
|
274
|
-
const file = fs.readFileSync(args.path, "utf-8");
|
|
275
|
-
if (file.includes(`${webview.name}(`)) {
|
|
276
|
-
return {
|
|
277
|
-
contents: `import ${webview.name} from '${PACKAGE_NAME}/webview';
|
|
278
|
-
${file}`,
|
|
279
|
-
loader: "ts"
|
|
280
|
-
};
|
|
281
|
-
}
|
|
282
|
-
return {};
|
|
283
|
-
});
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
],
|
|
287
|
-
async onSuccess() {
|
|
288
|
-
if (typeof _onSuccess === "function") {
|
|
289
|
-
await _onSuccess();
|
|
290
|
-
}
|
|
291
|
-
if (buildCount++ > 1) {
|
|
292
|
-
logger.info("extension rebuild success");
|
|
293
|
-
} else {
|
|
294
|
-
logger.info("extension build success");
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
})
|
|
298
|
-
);
|
|
299
|
-
});
|
|
300
|
-
},
|
|
301
|
-
transformIndexHtml(html) {
|
|
302
|
-
if (!opts.webview) {
|
|
303
|
-
return html;
|
|
304
|
-
}
|
|
305
|
-
if (opts.devtools ?? true) {
|
|
306
|
-
let port;
|
|
307
|
-
if (resolvedConfig.plugins.find(
|
|
308
|
-
(s) => ["vite:react-refresh", "vite:react-swc"].includes(s.name)
|
|
309
|
-
)) {
|
|
310
|
-
port = 8097;
|
|
311
|
-
} else if (resolvedConfig.plugins.find((s) => ["vite:vue", "vite:vue2"].includes(s.name))) {
|
|
312
|
-
port = 8098;
|
|
313
|
-
}
|
|
314
|
-
if (port) {
|
|
315
|
-
html = html.replace(/<head>/i, `<head><script src="http://localhost:${port}"></script>`);
|
|
316
|
-
} else if (!devtoolsFlag) {
|
|
317
|
-
devtoolsFlag = true;
|
|
318
|
-
logger.warn("Only support react-devtools and vue-devtools!");
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
return html.replace(/<head>/i, `<head><script>${devWebviewClient}</script>`);
|
|
322
|
-
}
|
|
323
|
-
},
|
|
324
|
-
{
|
|
325
|
-
name: "@tomjs:vscode",
|
|
326
|
-
apply: "build",
|
|
327
|
-
enforce: "post",
|
|
328
|
-
config(config) {
|
|
329
|
-
return handleConfig(config);
|
|
330
|
-
},
|
|
331
|
-
configResolved(config) {
|
|
332
|
-
resolvedConfig = config;
|
|
333
|
-
},
|
|
334
|
-
transformIndexHtml(html, ctx) {
|
|
335
|
-
var _a;
|
|
336
|
-
if (!opts.webview) {
|
|
337
|
-
return html;
|
|
338
|
-
}
|
|
339
|
-
prodHtmlCache[(_a = ctx.chunk) == null ? void 0 : _a.name] = html;
|
|
340
|
-
return html;
|
|
341
|
-
},
|
|
342
|
-
closeBundle() {
|
|
343
|
-
let webviewPath;
|
|
344
|
-
const webview = opts == null ? void 0 : opts.webview;
|
|
345
|
-
if (webview) {
|
|
346
|
-
webviewPath = genProdWebviewCode(prodHtmlCache, webview);
|
|
347
|
-
}
|
|
348
|
-
let outDir = resolvedConfig.build.outDir.replace(cwd(), "").replaceAll("\\", "/");
|
|
349
|
-
if (outDir.startsWith("/")) {
|
|
350
|
-
outDir = outDir.substring(1);
|
|
351
|
-
}
|
|
352
|
-
const env = {
|
|
353
|
-
NODE_ENV: resolvedConfig.mode || "production",
|
|
354
|
-
VITE_WEBVIEW_DIST: outDir
|
|
355
|
-
};
|
|
356
|
-
logger.info("extension build start");
|
|
357
|
-
const { onSuccess: _onSuccess, ...tsupOptions } = opts.extension || {};
|
|
358
|
-
tsupBuild(
|
|
359
|
-
merge(tsupOptions, {
|
|
360
|
-
env,
|
|
361
|
-
silent: true,
|
|
362
|
-
esbuildPlugins: !webview ? [] : [
|
|
363
|
-
{
|
|
364
|
-
name: "@tomjs:vscode:inject",
|
|
365
|
-
setup(build) {
|
|
366
|
-
build.onLoad({ filter: /\.ts$/ }, async (args) => {
|
|
367
|
-
const file = fs.readFileSync(args.path, "utf-8");
|
|
368
|
-
if (file.includes(`${webview.name}(`)) {
|
|
369
|
-
return {
|
|
370
|
-
contents: `import ${webview.name} from \`${webviewPath}\`;
|
|
371
|
-
${file}`,
|
|
372
|
-
loader: "ts"
|
|
373
|
-
};
|
|
374
|
-
}
|
|
375
|
-
return {};
|
|
376
|
-
});
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
],
|
|
380
|
-
async onSuccess() {
|
|
381
|
-
if (typeof _onSuccess === "function") {
|
|
382
|
-
await _onSuccess();
|
|
383
|
-
}
|
|
384
|
-
logger.info("extension build success");
|
|
385
|
-
}
|
|
386
|
-
})
|
|
387
|
-
);
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
];
|
|
391
|
-
}
|
|
392
|
-
var index_default = useVSCodePlugin;
|
|
393
|
-
export {
|
|
394
|
-
index_default as default,
|
|
395
|
-
useVSCodePlugin
|
|
396
|
-
};
|
package/dist/webview.d.mts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
interface WebviewHtmlOptions {
|
|
2
|
-
/**
|
|
3
|
-
* local server url
|
|
4
|
-
*/
|
|
5
|
-
serverUrl: string;
|
|
6
|
-
}
|
|
7
|
-
/**
|
|
8
|
-
*
|
|
9
|
-
* @param options serverUrl string or object options
|
|
10
|
-
*/
|
|
11
|
-
declare function getWebviewHtml(options: WebviewHtmlOptions): string;
|
|
12
|
-
|
|
13
|
-
export { type WebviewHtmlOptions, getWebviewHtml as default, getWebviewHtml };
|
package/dist/webview.mjs
DELETED
|
@@ -1,203 +0,0 @@
|
|
|
1
|
-
// src/webview/template.html
|
|
2
|
-
var template_default = `<!doctype html>
|
|
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
|
-
|
|
18
|
-
#webview-patch-iframe {
|
|
19
|
-
width: 100%;
|
|
20
|
-
height: 100%;
|
|
21
|
-
border: none;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
.outer {
|
|
25
|
-
width: 100%;
|
|
26
|
-
height: 100%;
|
|
27
|
-
overflow: hidden;
|
|
28
|
-
}
|
|
29
|
-
</style>
|
|
30
|
-
|
|
31
|
-
<script type="module" id="webview-patch">
|
|
32
|
-
const TAG = '[@tomjs:vscode:extension] ';
|
|
33
|
-
|
|
34
|
-
function onDomReady(callback, doc) {
|
|
35
|
-
const _doc = doc || document;
|
|
36
|
-
if (_doc.readyState === 'interactive' || _doc.readyState === 'complete') {
|
|
37
|
-
callback();
|
|
38
|
-
} else {
|
|
39
|
-
_doc.addEventListener('DOMContentLoaded', callback);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
let vsCodeApi;
|
|
44
|
-
|
|
45
|
-
function getApi() {
|
|
46
|
-
if (vsCodeApi) return vsCodeApi;
|
|
47
|
-
return (vsCodeApi = acquireVsCodeApi());
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function sendInitData(iframe) {
|
|
51
|
-
console.log(TAG + 'init data');
|
|
52
|
-
const dataset = {};
|
|
53
|
-
Object.keys(document.body.dataset).forEach((key) => {
|
|
54
|
-
dataset[key] = document.body.dataset[key];
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
iframe.contentWindow.postMessage(
|
|
58
|
-
{
|
|
59
|
-
type: '[vscode:extension]:init',
|
|
60
|
-
data: {
|
|
61
|
-
state: getApi().getState(),
|
|
62
|
-
style: document.getElementById('_defaultStyles').innerHTML,
|
|
63
|
-
root: {
|
|
64
|
-
cssText: document.documentElement.style.cssText,
|
|
65
|
-
},
|
|
66
|
-
body: {
|
|
67
|
-
dataset: dataset,
|
|
68
|
-
className: document.body.className,
|
|
69
|
-
role: document.body.getAttribute('role'),
|
|
70
|
-
},
|
|
71
|
-
},
|
|
72
|
-
},
|
|
73
|
-
'*',
|
|
74
|
-
);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function observeAttributeChanges(element, attributeName, callback) {
|
|
78
|
-
const observer = new MutationObserver(function (mutationsList) {
|
|
79
|
-
for (let mutation of mutationsList) {
|
|
80
|
-
if (mutation.type === 'attributes' && mutation.attributeName === attributeName) {
|
|
81
|
-
callback(mutation.target.getAttribute(attributeName));
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
});
|
|
85
|
-
observer.observe(element, { attributes: true });
|
|
86
|
-
return observer;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// message handler
|
|
90
|
-
let iframeLoaded = false;
|
|
91
|
-
const cacheMessages = [];
|
|
92
|
-
|
|
93
|
-
function handleMessage(e) {
|
|
94
|
-
const iframe = document.getElementById('webview-patch-iframe');
|
|
95
|
-
if (!iframeLoaded || !iframe) {
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
if (e.origin.startsWith('vscode-webview://')) {
|
|
99
|
-
iframe.contentWindow.postMessage(e.data, '*');
|
|
100
|
-
} else if ('{{serverUrl}}'.startsWith(e.origin)) {
|
|
101
|
-
const { type, data } = e.data;
|
|
102
|
-
console.log(TAG + ' received:', e.data);
|
|
103
|
-
if (type === '[vscode:client]:postMessage') {
|
|
104
|
-
getApi().postMessage(data);
|
|
105
|
-
} else if (type === '[vscode:client]:commands') {
|
|
106
|
-
if (data === 'F1') {
|
|
107
|
-
window.dispatchEvent(
|
|
108
|
-
new KeyboardEvent('keydown', {
|
|
109
|
-
key: 'F1',
|
|
110
|
-
keyCode: 112,
|
|
111
|
-
code: 'F1',
|
|
112
|
-
}),
|
|
113
|
-
);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
window.addEventListener('message', function (event) {
|
|
120
|
-
if (event.origin.startsWith('vscode-webview://')) {
|
|
121
|
-
cacheMessages.push(event);
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
handleMessage(event);
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
let isCacheWorking = false;
|
|
128
|
-
setInterval(() => {
|
|
129
|
-
if (isCacheWorking) {
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
isCacheWorking = true;
|
|
134
|
-
if (iframeLoaded) {
|
|
135
|
-
let event = cacheMessages.shift();
|
|
136
|
-
while (event) {
|
|
137
|
-
handleMessage(event);
|
|
138
|
-
event = cacheMessages.shift();
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
isCacheWorking = false;
|
|
142
|
-
}, 50);
|
|
143
|
-
|
|
144
|
-
onDomReady(function () {
|
|
145
|
-
/** @type {HTMLIFrameElement} */
|
|
146
|
-
const iframe = document.getElementById('webview-patch-iframe');
|
|
147
|
-
observeAttributeChanges(document.body, 'class', function (className) {
|
|
148
|
-
sendInitData(iframe);
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
onDomReady(function () {
|
|
152
|
-
iframeLoaded = true;
|
|
153
|
-
sendInitData(iframe);
|
|
154
|
-
}, iframe.contentDocument);
|
|
155
|
-
|
|
156
|
-
iframe.addEventListener('load', function (e) {
|
|
157
|
-
iframeLoaded = true;
|
|
158
|
-
|
|
159
|
-
let interval = setInterval(() => {
|
|
160
|
-
try {
|
|
161
|
-
if (document.getElementById('_defaultStyles')) {
|
|
162
|
-
sendInitData(iframe);
|
|
163
|
-
// addListeners(iframe);
|
|
164
|
-
clearInterval(interval);
|
|
165
|
-
return;
|
|
166
|
-
}
|
|
167
|
-
} catch (e) {
|
|
168
|
-
clearInterval(interval);
|
|
169
|
-
console.error(e);
|
|
170
|
-
}
|
|
171
|
-
}, 10);
|
|
172
|
-
});
|
|
173
|
-
});
|
|
174
|
-
</script>
|
|
175
|
-
</head>
|
|
176
|
-
|
|
177
|
-
<body>
|
|
178
|
-
<div class="outer">
|
|
179
|
-
<iframe
|
|
180
|
-
id="webview-patch-iframe"
|
|
181
|
-
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"
|
|
184
|
-
src="{{serverUrl}}"
|
|
185
|
-
></iframe>
|
|
186
|
-
</div>
|
|
187
|
-
</body>
|
|
188
|
-
</html>
|
|
189
|
-
`;
|
|
190
|
-
|
|
191
|
-
// src/webview/webview.ts
|
|
192
|
-
function getWebviewHtml(options) {
|
|
193
|
-
const opts = {
|
|
194
|
-
serverUrl: ""
|
|
195
|
-
};
|
|
196
|
-
Object.assign(opts, options);
|
|
197
|
-
return template_default.replace(/\{\{serverUrl\}\}/g, opts.serverUrl);
|
|
198
|
-
}
|
|
199
|
-
var webview_default = getWebviewHtml;
|
|
200
|
-
export {
|
|
201
|
-
webview_default as default,
|
|
202
|
-
getWebviewHtml
|
|
203
|
-
};
|