Skip to content

Commit b8b5a3c

Browse files
committed
refactor: format explorer
1 parent ea70040 commit b8b5a3c

File tree

7 files changed

+266
-279
lines changed

7 files changed

+266
-279
lines changed

.eslintrc.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ module.exports = {
44
root: true,
55
globals: {
66
__DEV__: true,
7+
__COMMIT__: true,
78
page: true,
89
browser: true,
910
context: true,

packages/format-explorer/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
Intlify message format explorer
44

5+
https://format-explorer.netlify.app
6+
57
## 🔨 develop the format explorer
68

79
```sh

packages/format-explorer/src/App.vue

Lines changed: 155 additions & 179 deletions
Original file line numberDiff line numberDiff line change
@@ -1,209 +1,185 @@
1-
<script lang="ts">
2-
import { defineComponent, ref } from 'vue'
3-
import Navigation from './components/Navigation.vue'
4-
import Editor from './components/Editor.vue'
1+
<script setup lang="ts">
2+
import { ref } from 'vue'
3+
import { SourceMapConsumer } from 'source-map'
54
import { baseCompile } from '@intlify/message-compiler'
65
import * as monaco from 'monaco-editor'
6+
import Navigation from './components/Navigation.vue'
7+
import Editor from './components/Editor.vue'
78
import { debounce } from './utils'
8-
import { SourceMapConsumer } from 'source-map'
99
import type { CompileError, CompileOptions } from '@intlify/message-compiler'
1010
1111
interface PersistedState {
1212
src?: string
1313
options: CompileOptions
1414
}
1515
16-
export default defineComponent({
17-
name: 'App',
16+
/**
17+
* states
18+
*/
19+
const genCodes = ref<string>('')
20+
const compileErrors = ref<CompileError[]>([])
21+
const persistedState: PersistedState = JSON.parse(
22+
decodeURIComponent(window.location.hash.slice(1)) ||
23+
localStorage.getItem('state') ||
24+
`{}`
25+
)
26+
const initialCodes = persistedState.src || 'hello {name}!'
1827
19-
components: {
20-
Navigation,
21-
Editor
22-
},
28+
/**
29+
* utilties
30+
*/
31+
let lastSuccessCode: string
32+
let lastSuccessfulMap: SourceMapConsumer | undefined
33+
async function compile(message: string): Promise<string> {
34+
console.clear()
2335
24-
setup() {
25-
/**
26-
* states
27-
*/
28-
const genCodes = ref<string>('')
29-
const compileErrors = ref<CompileError[]>([])
30-
const persistedState: PersistedState = JSON.parse(
31-
decodeURIComponent(window.location.hash.slice(1)) ||
32-
localStorage.getItem('state') ||
33-
`{}`
34-
)
35-
const initialCodes = persistedState.src || 'hello {name}!'
36+
try {
37+
const start = performance.now()
3638
37-
/**
38-
* utilties
39-
*/
40-
let lastSuccessCode: string
41-
let lastSuccessfulMap: SourceMapConsumer | undefined
42-
async function compile(message: string): Promise<string> {
43-
console.clear()
44-
45-
try {
46-
const start = performance.now()
39+
const errors: CompileError[] = []
40+
const options = {
41+
sourceMap: true,
42+
onError: (err: CompileError) => errors.push(err)
43+
}
44+
const { code, ast, map } = baseCompile(message, options)
45+
if (errors.length > 0) {
46+
console.error(errors)
47+
}
4748
48-
const errors: CompileError[] = []
49-
const options = {
50-
sourceMap: true,
51-
onError: (err: CompileError) => errors.push(err)
52-
}
53-
const { code, ast, map } = baseCompile(message, options)
54-
if (errors.length > 0) {
55-
console.error(errors)
56-
}
49+
console.log(`Compiled in ${(performance.now() - start).toFixed(2)}ms.`)
50+
compileErrors.value = errors
51+
console.log(`AST: `, ast)
52+
console.log('sourcemap', map)
5753
58-
console.log(`Compiled in ${(performance.now() - start).toFixed(2)}ms.`)
59-
compileErrors.value = errors
60-
console.log(`AST: `, ast)
61-
console.log('sourcemap', map)
54+
const evalCode = new Function(`return ${code}`)()
55+
lastSuccessCode =
56+
evalCode.toString() + `\n\n// Check the console for the AST`
57+
lastSuccessfulMap = await new SourceMapConsumer(map!)
58+
lastSuccessfulMap!.computeColumnSpans()
59+
} catch (e) {
60+
lastSuccessCode = `/* ERROR: ${e.message} (see console for more info) */`
61+
console.error(e)
62+
}
6263
63-
const evalCode = new Function(`return ${code}`)()
64-
lastSuccessCode =
65-
evalCode.toString() + `\n\n// Check the console for the AST`
66-
lastSuccessfulMap = await new SourceMapConsumer(map!)
67-
lastSuccessfulMap!.computeColumnSpans()
68-
} catch (e) {
69-
lastSuccessCode = `/* ERROR: ${e.message} (see console for more info) */`
70-
console.error(e)
71-
}
64+
return lastSuccessCode
65+
}
7266
73-
return lastSuccessCode
74-
}
67+
/**
68+
* envet handlers
69+
*/
7570
76-
/**
77-
* envet handlers
78-
*/
71+
let inputEditor: monaco.editor.IStandaloneCodeEditor | null = null
72+
let outputEditor: monaco.editor.IStandaloneCodeEditor | null = null
7973
80-
let inputEditor: monaco.editor.IStandaloneCodeEditor | null = null
81-
let outputEditor: monaco.editor.IStandaloneCodeEditor | null = null
74+
// input editor model change event
75+
const onChangeModel = async (message: string): Promise<void> => {
76+
const state = JSON.stringify({ src: message } as PersistedState)
77+
localStorage.setItem('state', state)
78+
window.location.hash = encodeURIComponent(state)
79+
genCodes.value = await compile(message)
80+
}
8281
83-
// input editor model change event
84-
const onChangeModel = async (message: string): Promise<void> => {
85-
const state = JSON.stringify({ src: message } as PersistedState)
86-
localStorage.setItem('state', state)
87-
window.location.hash = encodeURIComponent(state)
88-
genCodes.value = await compile(message)
89-
}
82+
// highlight output codes
83+
let prevOutputDecos: string[] = []
84+
function clearOutputDecos() {
85+
if (!outputEditor) {
86+
return
87+
}
88+
prevOutputDecos = outputEditor.deltaDecorations(prevOutputDecos, [])
89+
}
9090
91-
// highlight output codes
92-
let prevOutputDecos: string[] = []
93-
function clearOutputDecos() {
94-
if (!outputEditor) {
95-
return
96-
}
97-
prevOutputDecos = outputEditor.deltaDecorations(prevOutputDecos, [])
98-
}
91+
let prevInputDecos: string[] = []
92+
function clearInputDecos() {
93+
if (!inputEditor) {
94+
return
95+
}
96+
prevInputDecos = inputEditor.deltaDecorations(prevInputDecos, [])
97+
}
9998
100-
let prevInputDecos: string[] = []
101-
function clearInputDecos() {
102-
if (!inputEditor) {
103-
return
99+
// input editor ready event
100+
const onReadyInput = (editor: monaco.editor.IStandaloneCodeEditor) => {
101+
inputEditor = editor
102+
inputEditor.onDidChangeCursorPosition(
103+
debounce(e => {
104+
clearInputDecos()
105+
if (lastSuccessfulMap) {
106+
const pos = lastSuccessfulMap.generatedPositionFor({
107+
source: 'message.intl',
108+
line: e.position.lineNumber,
109+
column: e.position.column
110+
})
111+
if (pos.line != null && pos.column != null) {
112+
prevOutputDecos = outputEditor!.deltaDecorations(prevOutputDecos, [
113+
{
114+
range: new monaco.Range(
115+
pos.line,
116+
pos.column + 1,
117+
pos.line,
118+
pos.lastColumn ? pos.lastColumn + 2 : pos.column + 2
119+
),
120+
options: {
121+
inlineClassName: `highlight`
122+
}
123+
}
124+
])
125+
outputEditor!.revealPositionInCenter({
126+
lineNumber: pos.line,
127+
column: pos.column + 1
128+
})
129+
} else {
130+
clearOutputDecos()
131+
}
104132
}
105-
prevInputDecos = inputEditor.deltaDecorations(prevInputDecos, [])
106-
}
133+
}, 100)
134+
)
135+
}
107136
108-
// input editor ready event
109-
const onReadyInput = (editor: monaco.editor.IStandaloneCodeEditor) => {
110-
inputEditor = editor
111-
inputEditor.onDidChangeCursorPosition(
112-
debounce(e => {
113-
clearInputDecos()
114-
if (lastSuccessfulMap) {
115-
const pos = lastSuccessfulMap.generatedPositionFor({
116-
source: 'message.intl',
117-
line: e.position.lineNumber,
118-
column: e.position.column
119-
})
120-
if (pos.line != null && pos.column != null) {
121-
prevOutputDecos = outputEditor!.deltaDecorations(
122-
prevOutputDecos,
123-
[
124-
{
125-
range: new monaco.Range(
126-
pos.line,
127-
pos.column + 1,
128-
pos.line,
129-
pos.lastColumn ? pos.lastColumn + 2 : pos.column + 2
130-
),
131-
options: {
132-
inlineClassName: `highlight`
133-
}
134-
}
135-
]
136-
)
137-
outputEditor!.revealPositionInCenter({
138-
lineNumber: pos.line,
139-
column: pos.column + 1
140-
})
141-
} else {
142-
clearOutputDecos()
143-
}
137+
// output editor ready event
138+
const onReadyOutput = (editor: monaco.editor.IStandaloneCodeEditor) => {
139+
outputEditor = editor
140+
editor.onDidChangeCursorPosition(
141+
debounce(e => {
142+
clearOutputDecos()
143+
if (lastSuccessfulMap) {
144+
const pos = lastSuccessfulMap.originalPositionFor({
145+
line: e.position.lineNumber,
146+
column: e.position.column
147+
})
148+
console.log('onReadyOutput', e.position, pos)
149+
if (
150+
pos.line != null &&
151+
pos.column != null &&
152+
!(
153+
// ignore mock location
154+
(pos.line === 1 && pos.column === 0)
155+
)
156+
) {
157+
const translatedPos = {
158+
column: pos.column + 1,
159+
lineNumber: pos.line
144160
}
145-
}, 100)
146-
)
147-
}
148-
149-
// output editor ready event
150-
const onReadyOutput = (editor: monaco.editor.IStandaloneCodeEditor) => {
151-
outputEditor = editor
152-
editor.onDidChangeCursorPosition(
153-
debounce(e => {
154-
clearOutputDecos()
155-
if (lastSuccessfulMap) {
156-
const pos = lastSuccessfulMap.originalPositionFor({
157-
line: e.position.lineNumber,
158-
column: e.position.column
159-
})
160-
console.log('onReadyOutput', e.position, pos)
161-
if (
162-
pos.line != null &&
163-
pos.column != null &&
164-
!(
165-
// ignore mock location
166-
(pos.line === 1 && pos.column === 0)
167-
)
168-
) {
169-
const translatedPos = {
170-
column: pos.column + 1,
171-
lineNumber: pos.line
161+
prevInputDecos = inputEditor!.deltaDecorations(prevInputDecos, [
162+
{
163+
range: new monaco.Range(
164+
pos.line,
165+
pos.column + 1,
166+
pos.line,
167+
pos.column + 1
168+
),
169+
options: {
170+
isWholeLine: true,
171+
className: `highlight`
172172
}
173-
prevInputDecos = inputEditor!.deltaDecorations(prevInputDecos, [
174-
{
175-
range: new monaco.Range(
176-
pos.line,
177-
pos.column + 1,
178-
pos.line,
179-
pos.column + 1
180-
),
181-
options: {
182-
isWholeLine: true,
183-
className: `highlight`
184-
}
185-
}
186-
])
187-
inputEditor!.revealPositionInCenter(translatedPos)
188-
} else {
189-
clearInputDecos()
190173
}
191-
}
192-
}, 100)
193-
)
194-
}
195-
196-
// setup context
197-
return {
198-
initialCodes,
199-
genCodes,
200-
compileErrors,
201-
onChangeModel,
202-
onReadyInput,
203-
onReadyOutput
204-
}
205-
}
206-
})
174+
])
175+
inputEditor!.revealPositionInCenter(translatedPos)
176+
} else {
177+
clearInputDecos()
178+
}
179+
}
180+
}, 100)
181+
)
182+
}
207183
</script>
208184

209185
<template>

0 commit comments

Comments
 (0)