-
Notifications
You must be signed in to change notification settings - Fork 95
/
officeViewerProvider.ts
113 lines (103 loc) · 4.39 KB
/
officeViewerProvider.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
import { ReactApp } from '@/common/reactApp';
import { readFileSync } from 'fs';
import { extname } from 'path';
import * as vscode from 'vscode';
import { Handler } from '../common/handler';
import { Util } from '../common/util';
import { handleClass } from './handlers/classHandler';
import { handleImage, isImage } from './handlers/imageHanlder';
import { handleZip } from './handlers/zipHandler';
/**
* support view office files
*/
export class OfficeViewerProvider implements vscode.CustomReadonlyEditorProvider {
private extensionPath: string;
constructor(private context: vscode.ExtensionContext) {
this.extensionPath = context.extensionPath;
}
bindCustomEditors(viewOption: { webviewOptions: vscode.WebviewPanelOptions }) {
const viewers = ['cweijan.officeViewer', 'cweijan.imageViewer', 'cweijan.htmlViewer', 'cweijan.classViewer']
return viewers.map(viewer => vscode.window.registerCustomEditorProvider(viewer, this, viewOption))
}
public openCustomDocument(uri: vscode.Uri, openContext: vscode.CustomDocumentOpenContext, token: vscode.CancellationToken): vscode.CustomDocument | Thenable<vscode.CustomDocument> {
return { uri, dispose: (): void => { } };
}
public resolveCustomEditor(document: vscode.CustomDocument, webviewPanel: vscode.WebviewPanel, token: vscode.CancellationToken): void | Thenable<void> {
const uri = document.uri;
const webview = webviewPanel.webview;
const folderPath = vscode.Uri.joinPath(uri, '..')
webview.options = {
enableScripts: true,
localResourceRoots: [vscode.Uri.file(this.extensionPath), folderPath]
}
const send = () => {
handler.emit("open", {
ext: extname(uri.fsPath),
path: handler.panel.webview.asWebviewUri(uri).with({ query: `nonce=${Date.now().toString()}` }).toString(),
})
}
const handler = Handler.bind(webviewPanel, uri)
.on("editInVSCode", (full: boolean) => {
const side = full ? vscode.ViewColumn.Active : vscode.ViewColumn.Beside;
vscode.commands.executeCommand('vscode.openWith', uri, "default", side);
})
.on('developerTool', () => vscode.commands.executeCommand('workbench.action.toggleDevTools'))
.on("init", send)
.on("fileChange", send)
let route: string;
const ext = extname(uri.fsPath).toLowerCase()
if (isImage(ext)) {
handleImage(handler, uri, webview)
route = 'image'
}
switch (ext) {
case ".xlsx":
case ".xlsm":
case ".xls":
case ".csv":
case ".ods":
route = 'excel';
break;
case ".docx":
case ".dotx":
route = 'word'
break;
case ".jar":
case ".zip":
case ".apk":
case ".vsix":
route = 'zip';
handleZip(uri, handler);
break;
case ".ttf":
case ".woff":
case ".woff2":
case ".otf":
route = 'font';
break;
case ".pdf":
webview.html = readFileSync(this.extensionPath + "/resource/pdf/viewer.html", 'utf8')
.replace("{{baseUrl}}", this.getBaseUrl(webview, 'pdf'))
break;
case ".class":
handleClass(uri, webviewPanel);
break;
case ".htm":
case ".html":
webview.html = Util.buildPath(readFileSync(uri.fsPath, 'utf8'), webview, folderPath.fsPath);
Util.listen(webviewPanel, uri, () => {
webviewPanel.webview.html = Util.buildPath(readFileSync(uri.fsPath, 'utf8'), webviewPanel.webview, folderPath.fsPath);
})
break;
default:
if (route) break;
vscode.commands.executeCommand('vscode.openWith', uri, "default");
}
if (route) return ReactApp.view(webview, { route })
}
private getBaseUrl(webview: vscode.Webview, path: string) {
const baseUrl = webview.asWebviewUri(vscode.Uri.file(`${this.extensionPath}/resource/${path}`))
.toString().replace(/\?.+$/, '').replace('https://git', 'https://file')
return baseUrl;
}
}