Skip to content

Commit 184c680

Browse files
committed
feat: add SkSL Runner entry
1 parent 212ebca commit 184c680

File tree

5 files changed

+137
-4
lines changed

5 files changed

+137
-4
lines changed

package.json

+16-1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,21 @@
5454
"path": "./build/grammar.json"
5555
}
5656
],
57+
"commands": [
58+
{
59+
"command": "sksl.showRunner",
60+
"title": "Show SkSL Runner"
61+
}
62+
],
63+
"menus": {
64+
"editor/context": [
65+
{
66+
"when": "resourceLangId == sksl",
67+
"command": "sksl.showRunner",
68+
"group": "navigation"
69+
}
70+
]
71+
},
5772
"walkthroughs": [
5873
{
5974
"id": "skslWelcome",
@@ -90,8 +105,8 @@
90105
"@types/vscode": "^1.77.0",
91106
"@typescript-eslint/eslint-plugin": "^6.7.4",
92107
"@typescript-eslint/parser": "^6.7.4",
93-
"@vscode/test-electron": "^2.3.6",
94108
"@vscode/test-cli": "^0.0.4",
109+
"@vscode/test-electron": "^2.3.6",
95110
"@vscode/vsce": "^2.21.1",
96111
"eslint": "^8.38.0",
97112
"jest": "^29.5.0",

src/html-builder.test.ts

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { HtmlBuilder } from './html-builder'
2+
3+
describe('HtmlBuilder', () => {
4+
it('build', () => {
5+
const html = HtmlBuilder.build((b) => {
6+
b.html({
7+
lang: 'en',
8+
})
9+
})
10+
expect(html).toBe('<!DOCTYPE html><html lang="en"></html>')
11+
})
12+
})

src/html-builder.ts

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
type Attributes = { [key: string]: string }
2+
type Block = (builder: HtmlBuilder) => void
3+
const emptyBlock: Block = () => {}
4+
5+
export class HtmlBuilder {
6+
public static build(block: (builder: HtmlBuilder) => void): string {
7+
const builder = new HtmlBuilder()
8+
builder.result += '<!DOCTYPE html>'
9+
block(builder)
10+
return builder.result
11+
}
12+
13+
public element(tag: string, attributes: Attributes, block: Block = emptyBlock) {
14+
this.result += '<'
15+
this.result += tag
16+
17+
for (const [key, value] of Object.entries(attributes)) {
18+
this.result += ' '
19+
this.result += key
20+
if (value.length > 0) {
21+
this.result += '='
22+
this.result += '"'
23+
this.result += value
24+
this.result += '"'
25+
}
26+
}
27+
28+
this.result += '>'
29+
30+
if (block) {
31+
block(this)
32+
}
33+
34+
this.result += '</'
35+
this.result += tag
36+
this.result += '>'
37+
}
38+
39+
public body(attributes: Attributes, block: Block = emptyBlock) {
40+
this.element('body', attributes, block)
41+
}
42+
43+
public html(attributes: Attributes, block: Block = emptyBlock) {
44+
this.element('html', attributes, block)
45+
}
46+
47+
public head(attributes: Attributes, block: Block = emptyBlock) {
48+
this.element('head', attributes, block)
49+
}
50+
51+
public meta(attributes: Attributes, block: Block = emptyBlock) {
52+
this.element('meta', attributes, block)
53+
}
54+
55+
public title(attributes: Attributes, block: Block = emptyBlock) {
56+
this.element('title', attributes, block)
57+
}
58+
59+
public img(attributes: Attributes, block: Block = emptyBlock) {
60+
this.element('img', attributes, block)
61+
}
62+
63+
public input(attributes: Attributes, block: Block = emptyBlock) {
64+
this.element('input', attributes, block)
65+
}
66+
67+
public h1(attributes: Attributes, block: Block = emptyBlock) {
68+
this.element('h1', attributes, block)
69+
}
70+
71+
public text(value: string) {
72+
this.result += value
73+
}
74+
75+
private result: string = ''
76+
77+
private constructor() {}
78+
}

src/index.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import * as path from 'path'
2-
import { ExtensionContext } from 'vscode'
2+
import * as vscode from 'vscode'
33
import { LanguageClient, TransportKind } from 'vscode-languageclient/node'
4+
import { showRunner } from './runner'
45

56
let client: LanguageClient | undefined
67

7-
export async function activate(context: ExtensionContext) {
8+
export async function activate(context: vscode.ExtensionContext) {
9+
context.subscriptions.push(vscode.commands.registerCommand('sksl.showRunner', showRunner))
10+
811
const module = context.asAbsolutePath(path.join('build', 'server.js'))
912
const skslWasmPath = context.asAbsolutePath(path.join('build', 'sksl-wasm.wasm'))
1013
const transport = TransportKind.ipc
@@ -23,7 +26,6 @@ export async function activate(context: ExtensionContext) {
2326
initializationOptions: { skslWasmPath },
2427
},
2528
)
26-
2729
await client.start()
2830
}
2931

src/runner.ts

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import * as vscode from 'vscode'
2+
import { HtmlBuilder } from './html-builder'
3+
4+
export function showRunner() {
5+
const panel = vscode.window.createWebviewPanel('sksl.runner', 'SkSL Runner', vscode.ViewColumn.Beside, {})
6+
panel.webview.html = getWebviewContent()
7+
}
8+
9+
function getWebviewContent() {
10+
return HtmlBuilder.build((_) => {
11+
_.html({ lang: 'en' }, () => {
12+
_.head({}, () => {
13+
_.meta({ charset: 'UTF-8' })
14+
_.meta({ name: 'viewport', content: 'width=device-width, initial-scale=1.0' })
15+
_.title({}, () => {
16+
_.text('SkSL Runner')
17+
})
18+
})
19+
_.body({}, () => {
20+
_.h1({}, () => {
21+
_.text('SkSL Runner')
22+
})
23+
})
24+
})
25+
})
26+
}

0 commit comments

Comments
 (0)