-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.ts
124 lines (112 loc) · 4.26 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import * as fs from 'fs';
import * as path from 'path';
import * as vscode from 'vscode';
export interface VSCExpressCommandResponsePayload {
code: number;
// tslint:disable-next-line:no-any
result?: any;
message?: string;
}
export class VSCExpress {
static webviewPanelList: {[uri: string]: vscode.WebviewPanel} = {};
private _webRootAbsolutePath: string;
constructor(context: vscode.ExtensionContext, webRootPath: string) {
this._webRootAbsolutePath = path.join(context.extensionPath, webRootPath);
}
/**
* Open a specific page in VS Code
*
* @param path The relative path of the page in web root.
* @param title The title of the page. The default is an empty string.
* @param viewColumn The view column to open the page in. The default is
* vscode.ViewColumn.Two.
*/
open(
filePath: string, title = '',
viewColumn: vscode.ViewColumn = vscode.ViewColumn.Two,
options?: vscode.WebviewPanelOptions&vscode.WebviewOptions) {
options = options || {enableScripts: true, enableCommandUris: true};
filePath = path.join(this._webRootAbsolutePath, filePath);
const context =
new VSCExpressPanelContext(filePath, title, viewColumn, options);
return context.panel;
}
close(filePath: string) {
filePath = path.join(this._webRootAbsolutePath, filePath);
if (VSCExpress.webviewPanelList[filePath]) {
VSCExpress.webviewPanelList[filePath].dispose();
delete VSCExpress.webviewPanelList[filePath];
}
}
}
export class VSCExpressPanelContext {
private filePath: string;
private title: string|undefined;
private viewColumn: vscode.ViewColumn;
private options: vscode.WebviewOptions;
panel: vscode.WebviewPanel;
constructor(
filePath: string, title?: string, viewColumn?: vscode.ViewColumn,
options?: vscode.WebviewPanelOptions&vscode.WebviewOptions) {
const _location:
{href: string, search?: string, hash?: string} = {href: filePath};
const _hash = filePath.split('#')[1];
filePath = filePath.split('#')[0];
const _search = filePath.split('?')[1];
filePath = filePath.split('?')[0];
if (_hash) {
_location.hash = '#' + _hash;
}
if (_search) {
_location.search = '?' + _search;
}
this.filePath = filePath;
this.title = title || filePath;
this.viewColumn = viewColumn || vscode.ViewColumn.Two;
this.options = options || {};
const fileUrl = vscode.Uri.file(filePath).with({scheme: 'vscode-resource'});
let locationInject = '';
if (_location) {
locationInject =
`<script>var _location=${JSON.stringify(_location)}</script>`;
}
let html = fs.readFileSync(filePath, 'utf8');
if (/(<head(\s.*)?>)/.test(html)) {
html = html.replace(
/(<head(\s.*)?>)/,
`$1<base href="${fileUrl.toString()}">${locationInject}`);
} else if (/(<html(\s.*)?>)/.test(html)) {
html = html.replace(
/(<html(\s.*)?>)/,
`$1<head><base href="${fileUrl.toString()}">${
locationInject}</head>`);
} else {
html = `<head><base href="${fileUrl.toString()}">${
locationInject}</head>${html}`;
}
if (!VSCExpress.webviewPanelList[this.filePath]) {
this.panel = vscode.window.createWebviewPanel(
'VSCExpress', this.title, this.viewColumn, this.options);
this.panel.webview.html = html;
this.panel.webview.onDidReceiveMessage(async message => {
const payload: VSCExpressCommandResponsePayload = {code: 0};
try {
const result = await vscode.commands.executeCommand.apply(
null, [message.command as string, ...message.parameter]);
payload.result = result;
} catch (error) {
payload.message = error.message;
}
this.panel.webview.postMessage({messageId: message.messageId, payload});
});
this.panel.onDidDispose(() => {
delete VSCExpress.webviewPanelList[this.filePath];
}, this);
VSCExpress.webviewPanelList[this.filePath] = this.panel;
} else {
this.panel = VSCExpress.webviewPanelList[this.filePath];
this.panel.title = this.title;
this.panel.webview.html = html;
}
}
}