@slidev/client 0.48.0-beta.15 → 0.48.0-beta.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/builtin/Monaco.vue +104 -88
- package/logic/nav.ts +3 -6
- package/package.json +8 -4
- package/setup/monaco.ts +103 -44
- package/shim.d.ts +1 -1
- package/styles/monaco.css +27 -0
- package/iframes/monaco/index.css +0 -28
- package/iframes/monaco/index.html +0 -7
- package/iframes/monaco/index.ts +0 -260
package/builtin/Monaco.vue
CHANGED
|
@@ -12,11 +12,11 @@ Learn more: https://sli.dev/guide/syntax.html#monaco-editor
|
|
|
12
12
|
-->
|
|
13
13
|
|
|
14
14
|
<script setup lang="ts">
|
|
15
|
-
import
|
|
16
|
-
import {
|
|
17
|
-
import
|
|
15
|
+
import * as monaco from 'monaco-editor'
|
|
16
|
+
import { computed, nextTick, onMounted, ref } from 'vue'
|
|
17
|
+
import { debounce } from '@antfu/utils'
|
|
18
18
|
import { decompressFromBase64 } from 'lz-string'
|
|
19
|
-
import
|
|
19
|
+
import setup from '../setup/monaco'
|
|
20
20
|
import { makeId } from '../logic/utils'
|
|
21
21
|
|
|
22
22
|
const props = withDefaults(defineProps<{
|
|
@@ -25,109 +25,125 @@ const props = withDefaults(defineProps<{
|
|
|
25
25
|
lang?: string
|
|
26
26
|
readonly?: boolean
|
|
27
27
|
lineNumbers?: 'on' | 'off' | 'relative' | 'interval'
|
|
28
|
-
height?: number | string
|
|
28
|
+
height?: number | string // Posible values: 'initial', 'auto', '100%', '200px', etc.
|
|
29
29
|
editorOptions?: monaco.editor.IEditorOptions
|
|
30
|
+
ata?: boolean
|
|
30
31
|
}>(), {
|
|
31
32
|
codeLz: '',
|
|
32
33
|
lang: 'typescript',
|
|
33
34
|
readonly: false,
|
|
34
35
|
lineNumbers: 'off',
|
|
35
|
-
height: '
|
|
36
|
+
height: 'initial',
|
|
37
|
+
ata: true,
|
|
36
38
|
})
|
|
37
39
|
|
|
38
|
-
const
|
|
39
|
-
const
|
|
40
|
-
const diff = ref(props.diffLz ? decompressFromBase64(props.diffLz) : null)
|
|
41
|
-
const lineHeight = +(getComputedStyle(document.body).getPropertyValue('--slidev-code-line-height') || '18').replace('px', '') || 18
|
|
42
|
-
const editorHeight = ref(0)
|
|
43
|
-
const calculatedHeight = computed(() => code.value.split(/\r?\n/g).length * lineHeight)
|
|
44
|
-
const height = computed(() => {
|
|
45
|
-
return props.height === 'auto' ? `${Math.max(calculatedHeight.value, editorHeight.value) + 20}px` : props.height
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
const iframe = ref<HTMLIFrameElement>()
|
|
40
|
+
const code = decompressFromBase64(props.codeLz).trimEnd()
|
|
41
|
+
const diff = props.diffLz && decompressFromBase64(props.diffLz).trimEnd()
|
|
49
42
|
|
|
50
|
-
const
|
|
51
|
-
'
|
|
52
|
-
'
|
|
53
|
-
'--slidev-code-background',
|
|
54
|
-
'--slidev-code-line-height',
|
|
55
|
-
'--slidev-code-padding',
|
|
56
|
-
'--slidev-code-margin',
|
|
57
|
-
'--slidev-code-radius',
|
|
58
|
-
]
|
|
59
|
-
|
|
60
|
-
function getStyleObject(el: Element) {
|
|
61
|
-
const object: Record<string, string> = {}
|
|
62
|
-
const style = getComputedStyle(el)
|
|
63
|
-
for (const v of cssVars)
|
|
64
|
-
object[v] = style.getPropertyValue(v)
|
|
65
|
-
return object
|
|
43
|
+
const langMap: Record<string, string> = {
|
|
44
|
+
ts: 'typescript',
|
|
45
|
+
js: 'javascript',
|
|
66
46
|
}
|
|
47
|
+
const lang = langMap[props.lang] ?? props.lang
|
|
48
|
+
const extMap: Record<string, string> = {
|
|
49
|
+
typescript: 'mts',
|
|
50
|
+
javascript: 'mjs',
|
|
51
|
+
ts: 'mts',
|
|
52
|
+
js: 'mjs',
|
|
53
|
+
}
|
|
54
|
+
const ext = extMap[props.lang] ?? props.lang
|
|
67
55
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
frame.setAttribute('sandbox', [
|
|
71
|
-
'allow-forms',
|
|
72
|
-
'allow-modals',
|
|
73
|
-
'allow-pointer-lock',
|
|
74
|
-
'allow-popups',
|
|
75
|
-
'allow-same-origin',
|
|
76
|
-
'allow-scripts',
|
|
77
|
-
'allow-top-navigation-by-user-activation',
|
|
78
|
-
].join(' '))
|
|
79
|
-
|
|
80
|
-
let src = __DEV__
|
|
81
|
-
? `${location.origin}${__SLIDEV_CLIENT_ROOT__}/`
|
|
82
|
-
: import.meta.env.BASE_URL
|
|
83
|
-
src += `iframes/monaco/index.html?id=${id}&lineNumbers=${props.lineNumbers}&lang=${props.lang}`
|
|
84
|
-
if (diff.value)
|
|
85
|
-
src += '&diff=1'
|
|
86
|
-
frame.src = src
|
|
56
|
+
const outer = ref<HTMLDivElement>()
|
|
57
|
+
const container = ref<HTMLDivElement>()
|
|
87
58
|
|
|
88
|
-
|
|
59
|
+
const contentHeight = ref(0)
|
|
60
|
+
const initialHeight = ref<number>()
|
|
61
|
+
const height = computed(() => {
|
|
62
|
+
if (props.height === 'auto')
|
|
63
|
+
return `${contentHeight.value}px`
|
|
64
|
+
if (props.height === 'initial')
|
|
65
|
+
return `${initialHeight.value}px`
|
|
66
|
+
return props.height
|
|
89
67
|
})
|
|
90
68
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
69
|
+
onMounted(async () => {
|
|
70
|
+
const { ata } = await setup()
|
|
71
|
+
const model = monaco.editor.createModel(code, lang, monaco.Uri.parse(`file:///${makeId()}.${ext}`))
|
|
72
|
+
const commonOptions = {
|
|
73
|
+
automaticLayout: true,
|
|
74
|
+
readOnly: props.readonly,
|
|
75
|
+
lineNumbers: props.lineNumbers,
|
|
76
|
+
minimap: { enabled: false },
|
|
77
|
+
overviewRulerBorder: false,
|
|
78
|
+
overviewRulerLanes: 0,
|
|
79
|
+
padding: { top: 10, bottom: 10 },
|
|
80
|
+
lineNumbersMinChars: 3,
|
|
81
|
+
bracketPairColorization: { enabled: false },
|
|
82
|
+
tabSize: 2,
|
|
83
|
+
fontSize: 11.5,
|
|
84
|
+
fontFamily: 'var(--slidev-code-font-family)',
|
|
85
|
+
scrollBeyondLastLine: false,
|
|
86
|
+
...props.editorOptions,
|
|
87
|
+
} satisfies monaco.editor.IStandaloneEditorConstructionOptions & monaco.editor.IDiffEditorConstructionOptions
|
|
101
88
|
|
|
102
|
-
|
|
103
|
-
if (
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
89
|
+
let editableEditor: monaco.editor.IStandaloneCodeEditor
|
|
90
|
+
if (diff) {
|
|
91
|
+
const diffModel = monaco.editor.createModel(diff, lang, monaco.Uri.parse(`file:///${nanoid()}.${ext}`))
|
|
92
|
+
const editor = monaco.editor.createDiffEditor(container.value!, {
|
|
93
|
+
renderOverviewRuler: false,
|
|
94
|
+
...commonOptions,
|
|
95
|
+
})
|
|
96
|
+
editor.setModel({
|
|
97
|
+
original: model,
|
|
98
|
+
modified: diffModel,
|
|
99
|
+
})
|
|
100
|
+
const originalEditor = editor.getOriginalEditor()
|
|
101
|
+
const modifiedEditor = editor.getModifiedEditor()
|
|
102
|
+
const onContentSizeChange = () => {
|
|
103
|
+
const newHeight = Math.max(originalEditor.getContentHeight(), modifiedEditor.getContentHeight()) + 4
|
|
104
|
+
initialHeight.value ??= newHeight
|
|
105
|
+
contentHeight.value = newHeight
|
|
106
|
+
nextTick(() => editor.layout())
|
|
107
|
+
}
|
|
108
|
+
originalEditor.onDidContentSizeChange(onContentSizeChange)
|
|
109
|
+
modifiedEditor.onDidContentSizeChange(onContentSizeChange)
|
|
110
|
+
editableEditor = modifiedEditor
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
const editor = monaco.editor.create(container.value!, {
|
|
114
|
+
model,
|
|
115
|
+
lineDecorationsWidth: 0,
|
|
116
|
+
...commonOptions,
|
|
117
|
+
})
|
|
118
|
+
editor.onDidContentSizeChange((e) => {
|
|
119
|
+
const newHeight = e.contentHeight + 4
|
|
120
|
+
initialHeight.value ??= newHeight
|
|
121
|
+
contentHeight.value = newHeight
|
|
122
|
+
nextTick(() => editableEditor.layout())
|
|
123
|
+
})
|
|
124
|
+
editableEditor = editor
|
|
125
|
+
}
|
|
126
|
+
if (props.ata) {
|
|
127
|
+
ata(editableEditor.getValue())
|
|
128
|
+
editableEditor.onDidChangeModelContent(debounce(1000, () => {
|
|
129
|
+
ata(editableEditor.getValue())
|
|
130
|
+
}))
|
|
131
|
+
}
|
|
132
|
+
const originalLayoutContentWidget = editableEditor.layoutContentWidget.bind(editableEditor)
|
|
133
|
+
editableEditor.layoutContentWidget = (widget: any) => {
|
|
134
|
+
originalLayoutContentWidget(widget)
|
|
135
|
+
const id = widget.getId()
|
|
136
|
+
if (id === 'editor.contrib.resizableContentHoverWidget') {
|
|
137
|
+
widget._resizableNode.domNode.style.transform = widget._positionPreference === 1
|
|
138
|
+
? /* ABOVE */ `translateY(calc(100% * (var(--slidev-slide-scale) - 1)))`
|
|
139
|
+
: /* BELOW */ `` // reset
|
|
117
140
|
}
|
|
118
|
-
return
|
|
119
141
|
}
|
|
120
|
-
if (payload.type !== 'slidev-monaco')
|
|
121
|
-
return
|
|
122
|
-
if (payload.data?.height)
|
|
123
|
-
editorHeight.value = payload.data?.height
|
|
124
|
-
if (payload?.data?.code && code.value !== payload.data.code)
|
|
125
|
-
code.value = payload.data.code
|
|
126
|
-
if (payload?.data?.diff && diff.value !== payload.data.diff)
|
|
127
|
-
diff.value = payload.data.diff
|
|
128
142
|
})
|
|
129
143
|
</script>
|
|
130
144
|
|
|
131
145
|
<template>
|
|
132
|
-
<
|
|
146
|
+
<div ref="outer" class="slidev-monaco-container" :style="{ height }">
|
|
147
|
+
<div ref="container" class="absolute inset-0.5" />
|
|
148
|
+
</div>
|
|
133
149
|
</template>
|
package/logic/nav.ts
CHANGED
|
@@ -135,16 +135,13 @@ export function go(page: number | string, clicks?: number) {
|
|
|
135
135
|
export function useSwipeControls(root: Ref<HTMLElement | undefined>) {
|
|
136
136
|
const swipeBegin = ref(0)
|
|
137
137
|
const { direction, distanceX, distanceY } = usePointerSwipe(root, {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
return
|
|
138
|
+
pointerTypes: ['touch'],
|
|
139
|
+
onSwipeStart() {
|
|
141
140
|
if (isDrawing.value)
|
|
142
141
|
return
|
|
143
142
|
swipeBegin.value = timestamp()
|
|
144
143
|
},
|
|
145
|
-
onSwipeEnd(
|
|
146
|
-
if (e.pointerType !== 'touch')
|
|
147
|
-
return
|
|
144
|
+
onSwipeEnd() {
|
|
148
145
|
if (!swipeBegin.value)
|
|
149
146
|
return
|
|
150
147
|
if (isDrawing.value)
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@slidev/client",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.48.0-beta.
|
|
4
|
+
"version": "0.48.0-beta.16",
|
|
5
5
|
"description": "Presentation slides for developers",
|
|
6
6
|
"author": "antfu <anthonyfu117@hotmail.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -29,8 +29,10 @@
|
|
|
29
29
|
"@antfu/utils": "^0.7.7",
|
|
30
30
|
"@iconify-json/carbon": "^1.1.30",
|
|
31
31
|
"@iconify-json/ph": "^1.1.11",
|
|
32
|
+
"@shikijs/monaco": "^1.1.7",
|
|
32
33
|
"@shikijs/vitepress-twoslash": "^1.1.7",
|
|
33
34
|
"@slidev/rough-notation": "^0.1.0",
|
|
35
|
+
"@typescript/ata": "^0.9.4",
|
|
34
36
|
"@unhead/vue": "^1.8.10",
|
|
35
37
|
"@unocss/reset": "^0.58.5",
|
|
36
38
|
"@vueuse/core": "^10.8.0",
|
|
@@ -46,16 +48,18 @@
|
|
|
46
48
|
"katex": "^0.16.9",
|
|
47
49
|
"lz-string": "^1.5.0",
|
|
48
50
|
"mermaid": "^10.8.0",
|
|
49
|
-
"monaco-editor": "^0.
|
|
51
|
+
"monaco-editor": "^0.46.0",
|
|
52
|
+
"nanoid": "^5.0.6",
|
|
50
53
|
"prettier": "^3.2.5",
|
|
51
54
|
"recordrtc": "^5.6.2",
|
|
52
55
|
"resolve": "^1.22.8",
|
|
56
|
+
"shiki": "^1.1.7",
|
|
53
57
|
"shiki-magic-move": "^0.1.0",
|
|
54
58
|
"unocss": "^0.58.5",
|
|
55
59
|
"vue": "^3.4.20",
|
|
56
60
|
"vue-router": "^4.3.0",
|
|
57
|
-
"@slidev/
|
|
58
|
-
"@slidev/
|
|
61
|
+
"@slidev/parser": "0.48.0-beta.16",
|
|
62
|
+
"@slidev/types": "0.48.0-beta.16"
|
|
59
63
|
},
|
|
60
64
|
"devDependencies": {
|
|
61
65
|
"vite": "^5.1.4"
|
package/setup/monaco.ts
CHANGED
|
@@ -1,52 +1,115 @@
|
|
|
1
|
-
import { getCurrentInstance, onMounted } from 'vue'
|
|
2
|
-
import * as monaco from 'monaco-editor'
|
|
3
1
|
import { createSingletonPromise } from '@antfu/utils'
|
|
4
2
|
import type { MonacoSetupReturn } from '@slidev/types'
|
|
3
|
+
import * as monaco from 'monaco-editor'
|
|
4
|
+
import { watchEffect } from 'vue'
|
|
5
|
+
import { setupTypeAcquisition } from '@typescript/ata'
|
|
6
|
+
import ts from 'typescript'
|
|
7
|
+
|
|
8
|
+
import EditorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'
|
|
9
|
+
import CssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker'
|
|
10
|
+
import HtmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker'
|
|
11
|
+
import JsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker'
|
|
12
|
+
import TsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker'
|
|
13
|
+
|
|
14
|
+
// @ts-expect-error missing types
|
|
15
|
+
import { ContextViewService } from 'monaco-editor/esm/vs/platform/contextview/browser/contextViewService'
|
|
16
|
+
|
|
17
|
+
// @ts-expect-error missing types
|
|
18
|
+
import { SyncDescriptor } from 'monaco-editor/esm/vs/platform/instantiation/common/descriptors'
|
|
19
|
+
|
|
20
|
+
// @ts-expect-error missing types
|
|
21
|
+
import { StandaloneServices } from 'monaco-editor/esm/vs/editor/standalone/browser/standaloneServices'
|
|
22
|
+
|
|
23
|
+
import { isDark } from '../logic/dark'
|
|
24
|
+
import configs from '#slidev/configs'
|
|
5
25
|
|
|
6
26
|
/* __imports__ */
|
|
7
27
|
|
|
28
|
+
window.MonacoEnvironment = {
|
|
29
|
+
getWorker(_, label) {
|
|
30
|
+
if (label === 'json')
|
|
31
|
+
return new JsonWorker()
|
|
32
|
+
if (label === 'css' || label === 'scss' || label === 'less')
|
|
33
|
+
return new CssWorker()
|
|
34
|
+
if (label === 'html' || label === 'handlebars' || label === 'razor')
|
|
35
|
+
return new HtmlWorker()
|
|
36
|
+
if (label === 'typescript' || label === 'javascript')
|
|
37
|
+
return new TsWorker()
|
|
38
|
+
return new EditorWorker()
|
|
39
|
+
},
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
class ContextViewService2 extends ContextViewService {
|
|
43
|
+
showContextView(...args: any) {
|
|
44
|
+
super.showContextView(...args)
|
|
45
|
+
// @ts-expect-error missing types
|
|
46
|
+
const contextView = this.contextView.view as HTMLElement
|
|
47
|
+
contextView.style.left = `calc(${contextView.style.left} / var(--slidev-slide-scale))`
|
|
48
|
+
contextView.style.top = `calc(${contextView.style.top} / var(--slidev-slide-scale))`
|
|
49
|
+
// Reset the scale to 1. Otherwise, the sub-menu will be in the wrong position.
|
|
50
|
+
contextView.style.transform = `scale(calc(1 / var(--slidev-slide-scale)))`
|
|
51
|
+
contextView.style.transformOrigin = '0 0'
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
8
55
|
const setup = createSingletonPromise(async () => {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
56
|
+
// Initialize services first, otherwise we can't override them.
|
|
57
|
+
StandaloneServices.initialize({
|
|
58
|
+
contextViewService: new SyncDescriptor(ContextViewService2, [], true),
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
const defaults = monaco.languages.typescript.typescriptDefaults
|
|
62
|
+
|
|
63
|
+
defaults.setCompilerOptions({
|
|
64
|
+
...defaults.getCompilerOptions(),
|
|
15
65
|
strict: true,
|
|
66
|
+
moduleResolution: monaco.languages.typescript.ModuleResolutionKind.NodeJs,
|
|
67
|
+
module: monaco.languages.typescript.ModuleKind.ESNext,
|
|
16
68
|
})
|
|
17
69
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
getWorker(_: any, label: string) {
|
|
37
|
-
if (label === 'json')
|
|
38
|
-
return new JsonWorker()
|
|
39
|
-
if (label === 'css' || label === 'scss' || label === 'less')
|
|
40
|
-
return new CssWorker()
|
|
41
|
-
if (label === 'html' || label === 'handlebars' || label === 'razor')
|
|
42
|
-
return new HtmlWorker()
|
|
43
|
-
if (label === 'typescript' || label === 'javascript')
|
|
44
|
-
return new TsWorker()
|
|
45
|
-
return new EditorWorker()
|
|
70
|
+
// Load types from server
|
|
71
|
+
import('#slidev/monaco-types')
|
|
72
|
+
|
|
73
|
+
const ata = configs.monacoTypesSource === 'cdn'
|
|
74
|
+
? setupTypeAcquisition({
|
|
75
|
+
projectName: 'TypeScript Playground',
|
|
76
|
+
typescript: ts as any, // Version mismatch. No problem found so far.
|
|
77
|
+
logger: console,
|
|
78
|
+
delegate: {
|
|
79
|
+
receivedFile: (code: string, path: string) => {
|
|
80
|
+
defaults.addExtraLib(code, `file://${path}`)
|
|
81
|
+
const uri = monaco.Uri.file(path)
|
|
82
|
+
if (monaco.editor.getModel(uri) === null)
|
|
83
|
+
monaco.editor.createModel(code, 'javascript', uri)
|
|
84
|
+
},
|
|
85
|
+
progress: (downloaded: number, total: number) => {
|
|
86
|
+
// eslint-disable-next-line no-console
|
|
87
|
+
console.debug(`[Typescript ATA] ${downloaded} / ${total}`)
|
|
46
88
|
},
|
|
47
|
-
}
|
|
48
|
-
})
|
|
49
|
-
|
|
89
|
+
},
|
|
90
|
+
})
|
|
91
|
+
: () => { }
|
|
92
|
+
|
|
93
|
+
// monaco.languages.register({ id: 'vue' })
|
|
94
|
+
monaco.languages.register({ id: 'typescript' })
|
|
95
|
+
monaco.languages.register({ id: 'javascript' })
|
|
96
|
+
|
|
97
|
+
const { shiki, themes, shikiToMonaco } = await import('#slidev/shiki')
|
|
98
|
+
const highlighter = await shiki
|
|
99
|
+
|
|
100
|
+
// Use Shiki to highlight Monaco
|
|
101
|
+
shikiToMonaco(highlighter, monaco)
|
|
102
|
+
|
|
103
|
+
if (typeof themes === 'string') {
|
|
104
|
+
monaco.editor.setTheme(themes)
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
watchEffect(() => {
|
|
108
|
+
monaco.editor.setTheme(isDark.value
|
|
109
|
+
? themes.dark || 'vitesse-dark'
|
|
110
|
+
: themes.light || 'vitesse-light')
|
|
111
|
+
})
|
|
112
|
+
}
|
|
50
113
|
|
|
51
114
|
// @ts-expect-error injected in runtime
|
|
52
115
|
// eslint-disable-next-line unused-imports/no-unused-vars
|
|
@@ -56,15 +119,11 @@ const setup = createSingletonPromise(async () => {
|
|
|
56
119
|
|
|
57
120
|
/* __async_injections__ */
|
|
58
121
|
|
|
59
|
-
if (getCurrentInstance())
|
|
60
|
-
await new Promise<void>(resolve => onMounted(resolve))
|
|
61
|
-
|
|
62
122
|
return {
|
|
63
123
|
monaco,
|
|
124
|
+
ata,
|
|
64
125
|
...injection_return,
|
|
65
126
|
}
|
|
66
127
|
})
|
|
67
128
|
|
|
68
129
|
export default setup
|
|
69
|
-
|
|
70
|
-
setup()
|
package/shim.d.ts
CHANGED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
div[widgetid='messageoverlay'] {
|
|
2
|
+
transform: translateY(calc(100% * (var(--slidev-slide-scale) - 1)));
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.slidev-monaco-container {
|
|
6
|
+
position: relative;
|
|
7
|
+
margin: var(--slidev-code-margin);
|
|
8
|
+
padding: var(--slidev-code-padding);
|
|
9
|
+
line-height: var(--slidev-code-line-height);
|
|
10
|
+
border-radius: var(--slidev-code-radius);
|
|
11
|
+
background: var(--slidev-code-background);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.slidev-monaco-container .monaco-editor {
|
|
15
|
+
--monaco-monospace-font: var(--slidev-code-font-family);
|
|
16
|
+
--vscode-editor-background: var(--slidev-code-background);
|
|
17
|
+
--vscode-editorGutter-background: var(--slidev-code-background);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Revert styles */
|
|
21
|
+
.slidev-monaco-container .monaco-editor a {
|
|
22
|
+
border-bottom: none;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.slidev-monaco-container .monaco-editor a:hover {
|
|
26
|
+
border-bottom: none;
|
|
27
|
+
}
|
package/iframes/monaco/index.css
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
html,
|
|
2
|
-
body,
|
|
3
|
-
#container {
|
|
4
|
-
padding: 0;
|
|
5
|
-
margin: 0;
|
|
6
|
-
background: var(--slidev-code-background);
|
|
7
|
-
width: 100%;
|
|
8
|
-
height: 200%;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
#container {
|
|
12
|
-
padding: var(--slidev-code-padding);
|
|
13
|
-
margin: var(--slidev-code-margin);
|
|
14
|
-
border-radius: var(--slidev-code-radius);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
.monaco-editor .monaco-hover {
|
|
18
|
-
border-radius: var(--slidev-code-radius);
|
|
19
|
-
overflow: hidden;
|
|
20
|
-
border: none;
|
|
21
|
-
outline: none;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
.monaco-editor .lines-content,
|
|
25
|
-
.monaco-editor .view-line,
|
|
26
|
-
.monaco-editor .view-lines {
|
|
27
|
-
user-select: none;
|
|
28
|
-
}
|
package/iframes/monaco/index.ts
DELETED
|
@@ -1,260 +0,0 @@
|
|
|
1
|
-
import '/@slidev/styles'
|
|
2
|
-
import './index.css'
|
|
3
|
-
|
|
4
|
-
import type * as monaco from 'monaco-editor'
|
|
5
|
-
import { formatCode } from '../../setup/prettier'
|
|
6
|
-
import setupMonaco from '../../setup/monaco'
|
|
7
|
-
import '/@slidev/monaco-types'
|
|
8
|
-
|
|
9
|
-
const url = new URL(location.href)
|
|
10
|
-
const props = {
|
|
11
|
-
id: url.searchParams.get('id'),
|
|
12
|
-
code: '',
|
|
13
|
-
diff: '',
|
|
14
|
-
lang: url.searchParams.get('lang') ?? 'typescript',
|
|
15
|
-
readonly: false,
|
|
16
|
-
lineNumbers: url.searchParams.get('lineNumbers') ?? 'off',
|
|
17
|
-
dark: false,
|
|
18
|
-
style: '',
|
|
19
|
-
editorOptions: {},
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const styleObject = document.createElement('style')
|
|
23
|
-
let originalEditor: monaco.editor.IStandaloneCodeEditor
|
|
24
|
-
let modifiedEditor: monaco.editor.IStandaloneCodeEditor
|
|
25
|
-
let format: () => void = () => { }
|
|
26
|
-
let update: () => void = () => { }
|
|
27
|
-
|
|
28
|
-
document.body.appendChild(styleObject)
|
|
29
|
-
|
|
30
|
-
function lang() {
|
|
31
|
-
switch (props.lang) {
|
|
32
|
-
case 'ts':
|
|
33
|
-
case 'tsx':
|
|
34
|
-
return 'typescript'
|
|
35
|
-
case 'jsx':
|
|
36
|
-
case 'js':
|
|
37
|
-
return 'javascript'
|
|
38
|
-
default:
|
|
39
|
-
return props.lang
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function ext() {
|
|
44
|
-
switch (lang()) {
|
|
45
|
-
case 'typescript':
|
|
46
|
-
return 'ts'
|
|
47
|
-
case 'javascript':
|
|
48
|
-
return 'js'
|
|
49
|
-
default:
|
|
50
|
-
return lang()
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function post(data: any, type = 'slidev-monaco') {
|
|
55
|
-
if (window.parent === window)
|
|
56
|
-
return
|
|
57
|
-
|
|
58
|
-
window.parent.postMessage(
|
|
59
|
-
{
|
|
60
|
-
type,
|
|
61
|
-
id: props.id,
|
|
62
|
-
data,
|
|
63
|
-
},
|
|
64
|
-
location.origin,
|
|
65
|
-
)
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
async function start() {
|
|
69
|
-
const { monaco, theme = {}, editorOptions = {} } = await setupMonaco()
|
|
70
|
-
|
|
71
|
-
const style = getComputedStyle(document.documentElement)
|
|
72
|
-
const container = document.getElementById('container')!
|
|
73
|
-
|
|
74
|
-
const model = monaco.editor.createModel(
|
|
75
|
-
props.code,
|
|
76
|
-
lang(),
|
|
77
|
-
monaco.Uri.parse(`file:///root/${Date.now()}.${ext()}`),
|
|
78
|
-
)
|
|
79
|
-
|
|
80
|
-
if (url.searchParams.get('diff')) {
|
|
81
|
-
// Diff editor
|
|
82
|
-
const diffModel = monaco.editor.createModel(
|
|
83
|
-
props.diff,
|
|
84
|
-
lang(),
|
|
85
|
-
monaco.Uri.parse(`file:///root/${Date.now()}.${ext()}`),
|
|
86
|
-
)
|
|
87
|
-
const monacoEditor = monaco.editor.createDiffEditor(container, {
|
|
88
|
-
fontSize: +style.getPropertyValue('--slidev-code-font-size').replace(/px/g, ''),
|
|
89
|
-
fontFamily: style.getPropertyValue('--slidev-code-font-family'),
|
|
90
|
-
lineHeight: +style.getPropertyValue('--slidev-code-line-height').replace(/px/g, ''),
|
|
91
|
-
lineDecorationsWidth: 0,
|
|
92
|
-
lineNumbersMinChars: 0,
|
|
93
|
-
scrollBeyondLastLine: false,
|
|
94
|
-
scrollBeyondLastColumn: 0,
|
|
95
|
-
automaticLayout: true,
|
|
96
|
-
readOnly: props.readonly,
|
|
97
|
-
theme: 'vitesse-dark',
|
|
98
|
-
lineNumbers: props.lineNumbers as any,
|
|
99
|
-
glyphMargin: false,
|
|
100
|
-
scrollbar: {
|
|
101
|
-
useShadows: false,
|
|
102
|
-
vertical: 'hidden',
|
|
103
|
-
horizontal: 'hidden',
|
|
104
|
-
},
|
|
105
|
-
overviewRulerLanes: 0,
|
|
106
|
-
minimap: { enabled: false },
|
|
107
|
-
enableSplitViewResizing: false,
|
|
108
|
-
renderOverviewRuler: false,
|
|
109
|
-
// renderSideBySide: false,
|
|
110
|
-
...editorOptions,
|
|
111
|
-
})
|
|
112
|
-
monacoEditor.setModel({
|
|
113
|
-
original: model,
|
|
114
|
-
modified: diffModel,
|
|
115
|
-
})
|
|
116
|
-
originalEditor = monacoEditor.getOriginalEditor()
|
|
117
|
-
modifiedEditor = monacoEditor.getModifiedEditor()
|
|
118
|
-
|
|
119
|
-
format = async () => {
|
|
120
|
-
model.setValue((await formatCode(props.code, lang())).trim())
|
|
121
|
-
diffModel.setValue((await formatCode(props.diff, lang())).trim())
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// ctrl+s to format
|
|
125
|
-
originalEditor.onKeyDown((e) => {
|
|
126
|
-
if ((e.ctrlKey || e.metaKey) && e.code === 'KeyS') {
|
|
127
|
-
e.preventDefault()
|
|
128
|
-
format()
|
|
129
|
-
}
|
|
130
|
-
})
|
|
131
|
-
modifiedEditor.onKeyDown((e) => {
|
|
132
|
-
if ((e.ctrlKey || e.metaKey) && e.code === 'KeyS') {
|
|
133
|
-
e.preventDefault()
|
|
134
|
-
format()
|
|
135
|
-
}
|
|
136
|
-
})
|
|
137
|
-
|
|
138
|
-
update = () => {
|
|
139
|
-
monaco.editor.setTheme(props.dark
|
|
140
|
-
? (theme.dark || 'vitesse-dark')
|
|
141
|
-
: (theme.light || 'vitesse-light'))
|
|
142
|
-
styleObject.innerHTML = `:root { ${props.style} }`
|
|
143
|
-
|
|
144
|
-
if (originalEditor.getValue().toString() !== props.code) {
|
|
145
|
-
const selection = originalEditor.getSelection()
|
|
146
|
-
originalEditor.setValue(props.code)
|
|
147
|
-
if (selection)
|
|
148
|
-
originalEditor.setSelection(selection)
|
|
149
|
-
}
|
|
150
|
-
originalEditor.updateOptions(props.editorOptions)
|
|
151
|
-
|
|
152
|
-
if (modifiedEditor.getValue().toString() !== props.diff) {
|
|
153
|
-
const selection = modifiedEditor.getSelection()
|
|
154
|
-
modifiedEditor.setValue(props.diff)
|
|
155
|
-
if (selection)
|
|
156
|
-
modifiedEditor.setSelection(selection)
|
|
157
|
-
}
|
|
158
|
-
modifiedEditor.updateOptions(props.editorOptions)
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
diffModel.onDidChangeContent(() => {
|
|
162
|
-
onCodeChange(diffModel.getValue().toString())
|
|
163
|
-
})
|
|
164
|
-
|
|
165
|
-
function onCodeChange(diff: string) {
|
|
166
|
-
props.diff = diff
|
|
167
|
-
post({ diff })
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
else {
|
|
171
|
-
// Normal editor
|
|
172
|
-
originalEditor = monaco.editor.create(container, {
|
|
173
|
-
model,
|
|
174
|
-
tabSize: 2,
|
|
175
|
-
insertSpaces: true,
|
|
176
|
-
detectIndentation: false,
|
|
177
|
-
folding: false,
|
|
178
|
-
fontSize: +style.getPropertyValue('--slidev-code-font-size').replace(/px/g, ''),
|
|
179
|
-
fontFamily: style.getPropertyValue('--slidev-code-font-family'),
|
|
180
|
-
lineHeight: +style.getPropertyValue('--slidev-code-line-height').replace(/px/g, ''),
|
|
181
|
-
lineDecorationsWidth: 0,
|
|
182
|
-
lineNumbersMinChars: 0,
|
|
183
|
-
scrollBeyondLastLine: false,
|
|
184
|
-
scrollBeyondLastColumn: 0,
|
|
185
|
-
automaticLayout: true,
|
|
186
|
-
readOnly: props.readonly,
|
|
187
|
-
theme: 'vitesse-dark',
|
|
188
|
-
lineNumbers: props.lineNumbers as any,
|
|
189
|
-
glyphMargin: false,
|
|
190
|
-
scrollbar: {
|
|
191
|
-
useShadows: false,
|
|
192
|
-
vertical: 'hidden',
|
|
193
|
-
horizontal: 'hidden',
|
|
194
|
-
},
|
|
195
|
-
overviewRulerLanes: 0,
|
|
196
|
-
minimap: { enabled: false },
|
|
197
|
-
...editorOptions,
|
|
198
|
-
})
|
|
199
|
-
|
|
200
|
-
format = async () => {
|
|
201
|
-
model.setValue((await formatCode(props.code, lang())).trim())
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
// ctrl+s to format
|
|
205
|
-
originalEditor.onKeyDown((e) => {
|
|
206
|
-
if ((e.ctrlKey || e.metaKey) && e.code === 'KeyS') {
|
|
207
|
-
e.preventDefault()
|
|
208
|
-
format()
|
|
209
|
-
}
|
|
210
|
-
})
|
|
211
|
-
|
|
212
|
-
update = () => {
|
|
213
|
-
monaco.editor.setTheme(props.dark
|
|
214
|
-
? (theme.dark || 'vitesse-dark')
|
|
215
|
-
: (theme.light || 'vitesse-light'))
|
|
216
|
-
styleObject.innerHTML = `:root { ${props.style} }`
|
|
217
|
-
|
|
218
|
-
if (originalEditor.getValue().toString() !== props.code) {
|
|
219
|
-
const selection = originalEditor.getSelection()
|
|
220
|
-
originalEditor.setValue(props.code)
|
|
221
|
-
if (selection)
|
|
222
|
-
originalEditor.setSelection(selection)
|
|
223
|
-
}
|
|
224
|
-
originalEditor.updateOptions(props.editorOptions)
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
originalEditor.onDidContentSizeChange(() => {
|
|
229
|
-
post({ height: Math.max(originalEditor.getContentHeight(), modifiedEditor?.getContentHeight() ?? 0) })
|
|
230
|
-
})
|
|
231
|
-
|
|
232
|
-
model.onDidChangeContent(() => {
|
|
233
|
-
onCodeChange(model.getValue().toString())
|
|
234
|
-
})
|
|
235
|
-
|
|
236
|
-
function onCodeChange(code: string) {
|
|
237
|
-
props.code = code
|
|
238
|
-
post({ code })
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
update()
|
|
242
|
-
|
|
243
|
-
post({}, 'slidev-monaco-loaded')
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
window.addEventListener('message', (payload) => {
|
|
247
|
-
if (payload.source === window)
|
|
248
|
-
return
|
|
249
|
-
if (payload.origin !== location.origin)
|
|
250
|
-
return
|
|
251
|
-
if (typeof payload.data !== 'string')
|
|
252
|
-
return
|
|
253
|
-
const { type, data, id } = JSON.parse(payload.data)
|
|
254
|
-
if (type === 'slidev-monaco' && id === props.id) {
|
|
255
|
-
Object.assign(props, data)
|
|
256
|
-
update()
|
|
257
|
-
}
|
|
258
|
-
})
|
|
259
|
-
|
|
260
|
-
start()
|