-
-
Notifications
You must be signed in to change notification settings - Fork 46
/
extension.ts
178 lines (162 loc) Β· 5.84 KB
/
extension.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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
'use strict';
import {
workspace,
window,
commands,
ExtensionContext,
Disposable,
QuickPickItem,
Uri,
ViewColumn,
TextDocument,
TextDocumentChangeEvent
} from 'vscode';
import * as path from 'path';
import * as config from './config';
import {Logger} from './logger';
import {MapView, MapViewSerializer} from './map.view';
import {viewManager} from './view.manager';
import {Template, ITemplateManager, TemplateManager} from './template.manager';
// extension logger
const logger: Logger = new Logger('geo.data.viewer:', config.logLevel);
/**
* Activates this extension per rules set in package.json.
* @param context vscode extension context.
* @see https://code.visualstudio.com/api/references/activation-events for more info.
*/
export function activate(context: ExtensionContext) {
const extensionPath: string = context.extensionPath;
// logger.info('activate(): activating from extPath:', context.extensionPath);
// initialize geo data viewer webview panel templates
const templateManager: ITemplateManager = new TemplateManager(context.asAbsolutePath('web'));
const mapViewTemplate: Template | undefined = templateManager.getTemplate('map.view.html');
// register map view serializer for restore on vscode restart
window.registerWebviewPanelSerializer('map.view',
new MapViewSerializer('map.view', extensionPath, mapViewTemplate));
// add Geo: View Map command
const mapWebview: Disposable =
createMapViewCommand('map.view', extensionPath, mapViewTemplate);
context.subscriptions.push(mapWebview);
// add Geo: View Map from URL command
const viewRemoteMap: Disposable = commands.registerCommand('map.view.url', () => {
window.showInputBox({
ignoreFocusOut: true,
placeHolder: 'https://gist.github.com/.../*.json or https://kepler.gl/#/demo?mapUrl=...',
prompt: 'Input map config URL'
}).then((mapUrl) => {
if (mapUrl && mapUrl !== undefined && mapUrl.length > 0) {
const mapUri: Uri = Uri.parse(mapUrl);
// launch new remote map view
commands.executeCommand('map.view', mapUri);
}
});
});
context.subscriptions.push(viewRemoteMap);
// add Geo: Map Gallery command
const mapGalleryCommand: Disposable =
commands.registerCommand('map.gallery', () => createMapGalleryCommand());
context.subscriptions.push(mapGalleryCommand);
// refresh associated map view on geo data file save
workspace.onDidSaveTextDocument((document: TextDocument) => {
if (isGeoDataFile(document)) {
const uri: Uri = document.uri.with({scheme: 'map.view'});
const mapView: MapView | undefined = viewManager.find(uri);
if (mapView) {
mapView.refresh();
}
}
});
// reset associated map view on geo data file change
workspace.onDidChangeTextDocument((changeEvent: TextDocumentChangeEvent) => {
if (isGeoDataFile(changeEvent.document)) {
const uri: Uri = changeEvent.document.uri.with({scheme: 'map.view'});
const mapView: MapView | undefined = viewManager.find(uri);
if (mapView && changeEvent.contentChanges.length > 0) {
// TODO: add refresh interval before enabling this
// mapView.refresh();
}
}
});
// reset all views on config change
workspace.onDidChangeConfiguration(() => {
viewManager.configure();
});
logger.info('activate(): activated! extPath:', context.extensionPath);
} // end of activate()
/**
* Deactivates this vscode extension to free up resources.
*/
export function deactivate() {
// TODO: add extension cleanup code, if needed
}
/**
* Creates map.view command.
* @param viewType View command type.
* @param extensionPath Extension path for loading scripts, examples and data.
* @param viewTemplate View html template.
*/
function createMapViewCommand(viewType: string,
extensionPath: string, viewTemplate: Template | undefined): Disposable {
const mapWebview: Disposable = commands.registerCommand(viewType, (uri) => {
let resource: any = uri;
let viewColumn: ViewColumn = getViewColumn();
if (!(resource instanceof Uri)) {
if (window.activeTextEditor) {
resource = window.activeTextEditor.document.uri;
} else {
window.showInformationMessage('Open a geo data file to view map.');
return;
}
}
const mapView: MapView = new MapView(viewType,
extensionPath, resource, viewColumn, viewTemplate);
viewManager.add(mapView);
return mapView.webview;
});
return mapWebview;
}
/**
* Displays map gallery quick pick list.
*/
async function createMapGalleryCommand(): Promise<void> {
const mapQuickPickItems: Array<QuickPickItem> = [];
config.mapList.forEach(map => mapQuickPickItems.push({
label: `$(preview) ${map.name}`,
description: map.description,
detail: map.url.replace('https://raw.githubusercontent.com/', 'github@')
.replace('https://gist.githubusercontent.com/', 'gist@')
}));
const selectedMap: QuickPickItem | undefined =
await window.showQuickPick(mapQuickPickItems, {canPickMany: false});
if (selectedMap) {
const mapUrl: string | undefined = selectedMap.detail;
if (mapUrl) {
const mapUri: Uri = Uri.parse(
mapUrl.replace('github@', 'https://raw.githubusercontent.com/')
.replace('gist@', 'https://gist.githubusercontent.com/')
);
// launch new remote map view
commands.executeCommand('map.view', mapUri);
}
}
}
/**
* Gets map view display view column
* based on active editor view column.
*/
function getViewColumn(): ViewColumn {
let viewColumn: ViewColumn = ViewColumn.One;
const activeEditor = window.activeTextEditor;
if (activeEditor && activeEditor.viewColumn) {
viewColumn = activeEditor.viewColumn; // + 1; // for view on side ...
}
return viewColumn;
}
/**
* Checks if the vscode text document is a geo data file.
* @param document The vscode text document to check.
*/
function isGeoDataFile(document: TextDocument): boolean {
const fileName: string = path.basename(document.uri.fsPath);
return config.supportedDataFiles.test(fileName);
}