Skip to content

Commit

Permalink
Merge pull request #5 from Kanahiro/debounce
Browse files Browse the repository at this point in the history
use setStyle instead of rewrite entire html
  • Loading branch information
Kanahiro authored Aug 6, 2024
2 parents ea08cbc + 341af03 commit 7fb3bd9
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 130 deletions.
9 changes: 0 additions & 9 deletions CHANGELOG.md

This file was deleted.

4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"displayName": "MapLibre",
"description": "",
"publisher": "kiguchi",
"version": "0.0.5",
"version": "0.0.6",
"engines": {
"vscode": "^1.92.0"
},
Expand Down
85 changes: 10 additions & 75 deletions src/extension.ts
Original file line number Diff line number Diff line change
@@ -1,97 +1,32 @@
// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
import * as vscode from 'vscode';
import { createWebview, updateStyle } from './viewer';

const styleUtils = require('@maplibre/maplibre-gl-style-spec');

const validateStyleJson = (stylejson: string): Array<{ message: string }> => {
let _json: any;
try {
_json = JSON.parse(stylejson);
} catch {
return [{ message: 'Invalid JSON' }];
}

return styleUtils.validateStyleMin(_json);
};

const updateWebview = (webview: vscode.Webview, stylejson: string) => {
const errors = validateStyleJson(stylejson);

if (errors.length > 0) {
webview.html = errors.map((e: any) => e.message).join('<br>');
return;
}

webview.html = `<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello World</title>
<script src="https://unpkg.com/[email protected]/dist/maplibre-gl.js"></script>
<link
href="https://unpkg.com/[email protected]/dist/maplibre-gl.css"
rel="stylesheet"
/>
</head>
<body>
<div id="map" style="height: 100vh"></div>
<script>
const map = new maplibregl.Map({
container: 'map',
style: ${stylejson}
});
</script>
</body>
</html>`;
};

// This method is called when your extension is activated
// Your extension is activated the very first time the command is executed
export function activate(context: vscode.ExtensionContext) {
// Use the console to output diagnostic information (console.log) and errors (console.error)
// This line of code will only be executed once when your extension is activated
console.log('Congratulations, your extension "maplibre" is now active!');

// The command has been defined in the package.json file
// Now provide the implementation of the command with registerCommand
// The commandId parameter must match the command field in package.json

const disposable = vscode.commands.registerCommand(
'maplibre.viewer',
() => {
// The code you place here will be executed every time your command is executed
// Display a message box to the user
const panel = vscode.window.createWebviewPanel(
'maplibre-viewer',
vscode.window.activeTextEditor?.document.fileName ?? 'MapLibre',
vscode.ViewColumn.One,
{
enableScripts: true,
},
);
const target = vscode.window.activeTextEditor?.document;
const panel = createWebview();

const uri = vscode.window.activeTextEditor?.document.uri.toString();
updateStyle(panel.webview, target?.getText() ?? '');
panel.onDidChangeViewState(() => {
updateStyle(panel.webview, target?.getText() ?? '');
});

const changeDocumentSubscription =
vscode.workspace.onDidChangeTextDocument((e) => {
if (e.document.uri.toString() === uri) {
updateWebview(panel.webview, e.document.getText());
if (e.document.uri.toString() === target?.uri.toString()) {
updateStyle(panel.webview, target?.getText() ?? '');
}
});

panel.onDidDispose(() => {
changeDocumentSubscription.dispose();
});

const _json = vscode.window.activeTextEditor?.document.getText()!;
updateWebview(panel.webview, _json);
},
);

context.subscriptions.push(disposable);
}

// This method is called when your extension is deactivated
export function deactivate() {}
98 changes: 98 additions & 0 deletions src/viewer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import * as vscode from 'vscode';

const createWebview = () => {
const panel = vscode.window.createWebviewPanel(
'maplibre-viewer',
vscode.window.activeTextEditor?.document.fileName ?? 'MapLibre',
vscode.ViewColumn.One,
{ enableScripts: true },
);

panel.webview.html = `<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello World</title>
<script src="https://unpkg.com/[email protected]/dist/maplibre-gl.js"></script>
<link
href="https://unpkg.com/[email protected]/dist/maplibre-gl.css"
rel="stylesheet"
/>
</head>
<body>
<div id="map" style="height: 100vh">
<div id="error"></div>
</div>
<script>
const map = new maplibregl.Map({
container: 'map',
style: {
"version": 8,
"sources": {},
"layers": []
}
});
map.addControl(new maplibregl.NavigationControl());
window.addEventListener('message', event => {
const message = event.data;
const errDiv = document.getElementById('error');
switch (message.command) {
case 'style':
errDiv.innerHTML = '';
map.setStyle(message.style);
break;
case 'error':
errDiv.innerHTML = message.error;
map.setStyle({
"version": 8,
"sources": {},
"layers": []
});
break;
}
});
</script>
</body>
</html>`;
return panel;
};

const styleUtils = require('@maplibre/maplibre-gl-style-spec');

const validateStyleJson = (stylejson: string): Array<{ message: string }> => {
let _json: any;
try {
_json = JSON.parse(stylejson);
} catch {
return [{ message: 'Invalid JSON' }];
}

return styleUtils.validateStyleMin(_json);
};

let debounceTimer: NodeJS.Timeout | null = null;
const updateStyle = (webview: vscode.Webview, stylejson: string) => {
if (debounceTimer !== null) {
clearTimeout(debounceTimer);
debounceTimer = null;
}

const errors = validateStyleJson(stylejson);
if (errors.length === 0) {
webview.postMessage({ command: 'style', style: JSON.parse(stylejson) });
return;
}

// when has errors, debounce that change
debounceTimer = setTimeout(() => {
webview.postMessage({
command: 'error',
error: errors.map((e) => e.message).join('\n'),
});
return;
}, 1000);
};

export { createWebview, updateStyle };
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"lib": [
"ES2022"
],
"skipLibCheck": true,
"sourceMap": true,
"rootDir": "src",
"strict": true /* enable all strict type-checking options */
Expand Down
43 changes: 0 additions & 43 deletions vsc-extension-quickstart.md

This file was deleted.

0 comments on commit 7fb3bd9

Please sign in to comment.