@slidev/client 0.48.0-beta.8 → 0.48.0
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/App.vue +7 -0
- package/builtin/Arrow.vue +2 -4
- package/builtin/CodeBlockWrapper.vue +33 -28
- package/builtin/KaTexBlockWrapper.vue +1 -1
- package/builtin/Link.vue +3 -1
- package/builtin/Mermaid.vue +4 -3
- package/builtin/Monaco.vue +166 -93
- package/builtin/ShikiMagicMove.vue +103 -0
- package/builtin/SlidevVideo.vue +1 -1
- package/builtin/Toc.vue +1 -1
- package/builtin/TocList.vue +4 -3
- package/builtin/Tweet.vue +12 -9
- package/builtin/VClick.ts +2 -1
- package/composables/useClicks.ts +19 -32
- package/composables/useDarkMode.ts +9 -0
- package/composables/useDrawings.ts +181 -0
- package/composables/useNav.ts +346 -44
- package/{logic/note.ts → composables/useSlideInfo.ts} +13 -16
- package/composables/useSwipeControls.ts +43 -0
- package/composables/useTocTree.ts +81 -0
- package/composables/useViewTransition.ts +7 -4
- package/constants.ts +4 -3
- package/context.ts +13 -6
- package/env.ts +7 -16
- package/index.html +1 -0
- package/index.ts +12 -0
- package/internals/ClicksSlider.vue +93 -0
- package/internals/CodeRunner.vue +142 -0
- package/internals/Controls.vue +2 -2
- package/internals/DomElement.vue +18 -0
- package/internals/DrawingControls.vue +15 -17
- package/internals/DrawingLayer.vue +6 -5
- package/internals/DrawingPreview.vue +4 -2
- package/internals/Goto.vue +9 -6
- package/internals/IconButton.vue +7 -3
- package/internals/NavControls.vue +31 -12
- package/internals/NoteDisplay.vue +131 -8
- package/internals/NoteEditable.vue +129 -0
- package/internals/NoteStatic.vue +8 -6
- package/internals/PrintContainer.vue +11 -8
- package/internals/PrintSlide.vue +11 -12
- package/internals/PrintSlideClick.vue +14 -19
- package/internals/{SlidesOverview.vue → QuickOverview.vue} +35 -22
- package/internals/RecordingControls.vue +1 -1
- package/internals/RecordingDialog.vue +5 -6
- package/internals/{Editor.vue → SideEditor.vue} +26 -17
- package/internals/SlideContainer.vue +13 -9
- package/internals/SlideLoading.vue +19 -0
- package/internals/SlideWrapper.vue +79 -0
- package/internals/SlidesShow.vue +36 -22
- package/layouts/error.vue +5 -0
- package/layouts/two-cols-header.vue +9 -3
- package/logic/overview.ts +2 -2
- package/logic/route.ts +16 -5
- package/logic/slides.ts +20 -0
- package/logic/transition.ts +50 -0
- package/logic/utils.ts +24 -1
- package/main.ts +3 -15
- package/{setup → modules}/codemirror.ts +1 -3
- package/modules/context.ts +1 -46
- package/modules/mermaid.ts +9 -8
- package/package.json +21 -15
- package/{internals/EntrySelect.vue → pages/entry.vue} +7 -0
- package/{internals/NotesView.vue → pages/notes.vue} +9 -6
- package/pages/overview.vue +231 -0
- package/{internals/Play.vue → pages/play.vue} +22 -15
- package/{internals/PresenterPrint.vue → pages/presenter/print.vue} +15 -8
- package/{internals/Presenter.vue → pages/presenter.vue} +129 -107
- package/{internals/Print.vue → pages/print.vue} +6 -5
- package/routes.ts +26 -57
- package/setup/code-runners.ts +164 -0
- package/setup/main.ts +39 -9
- package/setup/mermaid.ts +5 -6
- package/setup/monaco.ts +114 -51
- package/setup/root.ts +62 -18
- package/setup/shortcuts.ts +15 -12
- package/shim-vue.d.ts +34 -0
- package/shim.d.ts +1 -13
- package/state/index.ts +2 -2
- package/styles/code.css +9 -5
- package/styles/index.css +63 -7
- package/styles/katex.css +1 -1
- package/styles/layouts-base.css +17 -12
- package/styles/shiki-twoslash.css +1 -1
- package/styles/vars.css +1 -0
- package/uno.config.ts +14 -2
- package/utils.ts +15 -2
- package/composables/useContext.ts +0 -17
- package/composables/useTweetScript.ts +0 -17
- package/iframes/monaco/index.css +0 -28
- package/iframes/monaco/index.html +0 -7
- package/iframes/monaco/index.ts +0 -260
- package/internals/NoteEditor.vue +0 -88
- package/internals/SlideWrapper.ts +0 -58
- package/logic/drawings.ts +0 -161
- package/logic/nav.ts +0 -278
- package/setup/prettier.ts +0 -43
- /package/{composables → logic}/hmr.ts +0 -0
package/state/index.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { slideAspect } from '../env'
|
|
|
5
5
|
export const showRecordingDialog = ref(false)
|
|
6
6
|
export const showInfoDialog = ref(false)
|
|
7
7
|
export const showGotoDialog = ref(false)
|
|
8
|
+
export const showOverview = ref(false)
|
|
8
9
|
|
|
9
10
|
export const shortcutsEnabled = ref(true)
|
|
10
11
|
export const breakpoints = useBreakpoints({
|
|
@@ -13,7 +14,7 @@ export const breakpoints = useBreakpoints({
|
|
|
13
14
|
})
|
|
14
15
|
export const windowSize = useWindowSize()
|
|
15
16
|
export const magicKeys = useMagicKeys()
|
|
16
|
-
export const isScreenVertical = computed(() => windowSize.height.value - windowSize.width.value / slideAspect > 120)
|
|
17
|
+
export const isScreenVertical = computed(() => windowSize.height.value - windowSize.width.value / slideAspect.value > 120)
|
|
17
18
|
export const fullscreen = useFullscreen(isClient ? document.body : null)
|
|
18
19
|
|
|
19
20
|
export const activeElement = useActiveElement()
|
|
@@ -24,7 +25,6 @@ export const currentCamera = useLocalStorage<string>('slidev-camera', 'default',
|
|
|
24
25
|
export const currentMic = useLocalStorage<string>('slidev-mic', 'default', { listenToStorageChanges: false })
|
|
25
26
|
export const slideScale = useLocalStorage<number>('slidev-scale', 0)
|
|
26
27
|
|
|
27
|
-
export const showOverview = useLocalStorage('slidev-show-overview', false, { listenToStorageChanges: false })
|
|
28
28
|
export const showPresenterCursor = useLocalStorage('slidev-presenter-cursor', true, { listenToStorageChanges: false })
|
|
29
29
|
export const showEditor = useLocalStorage('slidev-show-editor', false, { listenToStorageChanges: false })
|
|
30
30
|
export const isEditorVertical = useLocalStorage('slidev-editor-vertical', false, { listenToStorageChanges: false })
|
package/styles/code.css
CHANGED
|
@@ -44,9 +44,9 @@ html:not(.dark) .shiki span {
|
|
|
44
44
|
overflow: auto;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
.slidev-code .
|
|
47
|
+
.slidev-code .slidev-code-highlighted {
|
|
48
48
|
}
|
|
49
|
-
.slidev-code .
|
|
49
|
+
.slidev-code .slidev-code-dishonored {
|
|
50
50
|
opacity: 0.3;
|
|
51
51
|
pointer-events: none;
|
|
52
52
|
}
|
|
@@ -59,7 +59,9 @@ html:not(.dark) .shiki span {
|
|
|
59
59
|
.slidev-code-line-numbers .slidev-code code .line::before {
|
|
60
60
|
content: counter(step);
|
|
61
61
|
counter-increment: step;
|
|
62
|
-
|
|
62
|
+
display: inline-block;
|
|
63
|
+
text-align: right;
|
|
64
|
+
--uno: w-4 mr-6 text-gray-400 dark-text-gray-600;
|
|
63
65
|
}
|
|
64
66
|
|
|
65
67
|
/* Inline Code */
|
|
@@ -67,7 +69,7 @@ html:not(.dark) .shiki span {
|
|
|
67
69
|
font-size: 0.9em;
|
|
68
70
|
background: var(--slidev-code-background);
|
|
69
71
|
border-radius: var(--slidev-code-radius);
|
|
70
|
-
|
|
72
|
+
--uno: font-light py-0.5 px-1.5;
|
|
71
73
|
}
|
|
72
74
|
|
|
73
75
|
.slidev-layout :not(pre) > code:before {
|
|
@@ -82,4 +84,6 @@ html:not(.dark) .shiki span {
|
|
|
82
84
|
}
|
|
83
85
|
|
|
84
86
|
/* CodeMirror */
|
|
85
|
-
.CodeMirror pre.CodeMirror-placeholder {
|
|
87
|
+
.CodeMirror pre.CodeMirror-placeholder {
|
|
88
|
+
opacity: 0.4;
|
|
89
|
+
}
|
package/styles/index.css
CHANGED
|
@@ -16,22 +16,27 @@ html {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
.slidev-icon-btn {
|
|
19
|
-
|
|
19
|
+
aspect-ratio: 1;
|
|
20
|
+
display: inline-block;
|
|
21
|
+
user-select: none;
|
|
22
|
+
outline: none;
|
|
23
|
+
cursor: pointer;
|
|
20
24
|
@apply opacity-75 transition duration-200 ease-in-out align-middle rounded p-1;
|
|
21
25
|
@apply hover:(opacity-100 bg-gray-400 bg-opacity-10);
|
|
22
26
|
@apply md:p-2;
|
|
23
27
|
}
|
|
24
28
|
|
|
25
29
|
.slidev-icon-btn.shallow {
|
|
26
|
-
|
|
30
|
+
opacity: 0.3;
|
|
27
31
|
}
|
|
28
32
|
|
|
29
33
|
.slidev-icon-btn.active {
|
|
30
|
-
|
|
34
|
+
opacity: 1;
|
|
31
35
|
}
|
|
32
36
|
|
|
33
37
|
.slidev-icon-btn.disabled {
|
|
34
|
-
|
|
38
|
+
opacity: 0.25;
|
|
39
|
+
pointer-events: none;
|
|
35
40
|
}
|
|
36
41
|
|
|
37
42
|
.slidev-vclick-target {
|
|
@@ -39,11 +44,13 @@ html {
|
|
|
39
44
|
}
|
|
40
45
|
|
|
41
46
|
.slidev-vclick-hidden {
|
|
42
|
-
|
|
47
|
+
opacity: 0 !important;
|
|
48
|
+
pointer-events: none !important;
|
|
49
|
+
user-select: none !important;
|
|
43
50
|
}
|
|
44
51
|
|
|
45
52
|
.slidev-vclick-fade {
|
|
46
|
-
|
|
53
|
+
opacity: 0.5;
|
|
47
54
|
}
|
|
48
55
|
|
|
49
56
|
.slidev-icon {
|
|
@@ -53,7 +60,56 @@ html {
|
|
|
53
60
|
}
|
|
54
61
|
|
|
55
62
|
.slidev-page {
|
|
56
|
-
|
|
63
|
+
position: relative;
|
|
64
|
+
top: 0;
|
|
65
|
+
left: 0;
|
|
66
|
+
right: 0;
|
|
67
|
+
width: 100%;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/* Note Clicks */
|
|
71
|
+
|
|
72
|
+
.slidev-note-with-clicks .slidev-note-fade {
|
|
73
|
+
color: #888888ab;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.slidev-note-click-mark {
|
|
77
|
+
user-select: none;
|
|
78
|
+
font-size: 0.7em;
|
|
79
|
+
display: inline-flex;
|
|
80
|
+
--uno: text-violet bg-violet/10 px1 font-mono rounded items-center border
|
|
81
|
+
border-transparent;
|
|
82
|
+
}
|
|
83
|
+
.slidev-note-click-mark.slidev-note-click-mark-active {
|
|
84
|
+
--uno: border border-violet;
|
|
85
|
+
}
|
|
86
|
+
.slidev-note-click-mark.slidev-note-click-mark-past {
|
|
87
|
+
filter: saturate(0);
|
|
88
|
+
opacity: 0.5;
|
|
89
|
+
}
|
|
90
|
+
.slidev-note-click-mark.slidev-note-click-mark-future {
|
|
91
|
+
opacity: 0.5;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.slidev-note-click-mark::before {
|
|
95
|
+
content: '';
|
|
96
|
+
display: inline-block;
|
|
97
|
+
--un-icon: url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 32 32' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M23 28a1 1 0 0 1-.71-.29l-6.13-6.14l-3.33 5a1 1 0 0 1-1 .44a1 1 0 0 1-.81-.7l-6-20A1 1 0 0 1 6.29 5l20 6a1 1 0 0 1 .7.81a1 1 0 0 1-.44 1l-5 3.33l6.14 6.13a1 1 0 0 1 0 1.42l-4 4A1 1 0 0 1 23 28m0-2.41L25.59 23l-7.16-7.15l5.25-3.5L7.49 7.49l4.86 16.19l3.5-5.25Z'/%3E%3C/svg%3E");
|
|
98
|
+
-webkit-mask: var(--un-icon) no-repeat;
|
|
99
|
+
mask: var(--un-icon) no-repeat;
|
|
100
|
+
-webkit-mask-size: 100% 100%;
|
|
101
|
+
mask-size: 100% 100%;
|
|
102
|
+
background-color: currentColor;
|
|
103
|
+
color: inherit;
|
|
104
|
+
width: 1.2em;
|
|
105
|
+
height: 1.2em;
|
|
106
|
+
opacity: 0.8;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.slidev-note-click-mark::after {
|
|
110
|
+
content: attr(data-clicks);
|
|
111
|
+
display: inline-block;
|
|
112
|
+
transform: translateY(0.1em);
|
|
57
113
|
}
|
|
58
114
|
|
|
59
115
|
/* Transform the position back for Rough Notation (v-mark) */
|
package/styles/katex.css
CHANGED
package/styles/layouts-base.css
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
.slidev-layout {
|
|
2
2
|
@apply px-14 py-10 text-[1.1rem] h-full;
|
|
3
3
|
|
|
4
|
-
pre,
|
|
4
|
+
pre,
|
|
5
|
+
code {
|
|
5
6
|
@apply select-text;
|
|
6
7
|
}
|
|
7
8
|
|
|
@@ -54,7 +55,9 @@
|
|
|
54
55
|
}
|
|
55
56
|
|
|
56
57
|
blockquote {
|
|
57
|
-
|
|
58
|
+
background: var(--slidev-code-background);
|
|
59
|
+
color: var(--slidev-code-foreground);
|
|
60
|
+
@apply text-sm px-2 py-1 border-primary border-l rounded;
|
|
58
61
|
}
|
|
59
62
|
|
|
60
63
|
blockquote > * {
|
|
@@ -66,7 +69,7 @@
|
|
|
66
69
|
}
|
|
67
70
|
|
|
68
71
|
tr {
|
|
69
|
-
@apply border-b border-
|
|
72
|
+
@apply border-b border-main;
|
|
70
73
|
}
|
|
71
74
|
|
|
72
75
|
th {
|
|
@@ -74,26 +77,28 @@
|
|
|
74
77
|
}
|
|
75
78
|
|
|
76
79
|
a {
|
|
77
|
-
@apply border-current border-b border-dashed hover:text
|
|
80
|
+
@apply border-current border-b border-dashed hover:text-primary hover:border-solid;
|
|
78
81
|
}
|
|
79
82
|
|
|
80
|
-
td,
|
|
83
|
+
td,
|
|
84
|
+
th {
|
|
81
85
|
@apply p-2 py-3;
|
|
82
86
|
}
|
|
83
87
|
|
|
84
|
-
b,
|
|
88
|
+
b,
|
|
89
|
+
strong {
|
|
85
90
|
@apply font-600;
|
|
86
91
|
}
|
|
87
92
|
|
|
88
93
|
kbd {
|
|
89
|
-
@apply border border-
|
|
94
|
+
@apply border border-main border-b-2 rounded;
|
|
90
95
|
@apply bg-gray-400 bg-opacity-5 py-0.5 px-1 text-xs font-mono;
|
|
91
96
|
}
|
|
92
97
|
}
|
|
93
98
|
|
|
94
99
|
.slidev-layout,
|
|
95
|
-
[dir=ltr],
|
|
96
|
-
.slidev-layout [dir=ltr] {
|
|
100
|
+
[dir='ltr'],
|
|
101
|
+
.slidev-layout [dir='ltr'] {
|
|
97
102
|
h1 {
|
|
98
103
|
@apply -ml-[0.05em] mr-0;
|
|
99
104
|
}
|
|
@@ -107,10 +112,10 @@
|
|
|
107
112
|
}
|
|
108
113
|
}
|
|
109
114
|
|
|
110
|
-
[dir=rtl],
|
|
111
|
-
.slidev-layout [dir=rtl] {
|
|
115
|
+
[dir='rtl'],
|
|
116
|
+
.slidev-layout [dir='rtl'] {
|
|
112
117
|
h1 {
|
|
113
|
-
@apply -mr-[0.05em] ml-0;
|
|
118
|
+
@apply -mr-[0.05em] ml-0;
|
|
114
119
|
}
|
|
115
120
|
|
|
116
121
|
h6 {
|
package/styles/vars.css
CHANGED
package/uno.config.ts
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
transformerDirectives,
|
|
9
9
|
transformerVariantGroup,
|
|
10
10
|
} from 'unocss'
|
|
11
|
+
import { variantMatcher } from '@unocss/preset-mini/utils'
|
|
11
12
|
|
|
12
13
|
export default defineConfig({
|
|
13
14
|
safelist: [
|
|
@@ -15,15 +16,26 @@ export default defineConfig({
|
|
|
15
16
|
'prose',
|
|
16
17
|
],
|
|
17
18
|
shortcuts: {
|
|
18
|
-
'bg-main': 'bg-white
|
|
19
|
+
'bg-main': 'bg-white dark:bg-[#121212]',
|
|
19
20
|
'bg-active': 'bg-gray-400/10',
|
|
20
|
-
'border-main': 'border-gray
|
|
21
|
+
'border-main': 'border-gray/20',
|
|
22
|
+
'text-main': 'text-[#181818] dark:text-[#ddd]',
|
|
23
|
+
'text-primary': 'color-$slidev-theme-primary',
|
|
24
|
+
'bg-primary': 'bg-$slidev-theme-primary',
|
|
25
|
+
'border-primary': 'border-$slidev-theme-primary',
|
|
21
26
|
'abs-tl': 'absolute top-0 left-0',
|
|
22
27
|
'abs-tr': 'absolute top-0 right-0',
|
|
23
28
|
'abs-b': 'absolute bottom-0 left-0 right-0',
|
|
24
29
|
'abs-bl': 'absolute bottom-0 left-0',
|
|
25
30
|
'abs-br': 'absolute bottom-0 right-0',
|
|
26
31
|
},
|
|
32
|
+
// Slidev Specific Variants, probably extrat to a preset later
|
|
33
|
+
variants: [
|
|
34
|
+
// `forward:` and `backward:` variant to selectively apply styles based on the direction of the slide
|
|
35
|
+
// For example, `forward:text-red` will only apply to the slides that are navigated forward
|
|
36
|
+
variantMatcher('forward', input => ({ prefix: `.slidev-nav-go-forward ${input.prefix}` })),
|
|
37
|
+
variantMatcher('backward', input => ({ prefix: `.slidev-nav-go-backward ${input.prefix}` })),
|
|
38
|
+
],
|
|
27
39
|
presets: [
|
|
28
40
|
presetUno(),
|
|
29
41
|
presetAttributify(),
|
package/utils.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { SlideRoute } from '@slidev/types'
|
|
2
|
+
import { configs } from './env'
|
|
2
3
|
|
|
3
|
-
export function getSlideClass(route?:
|
|
4
|
+
export function getSlideClass(route?: SlideRoute, extra = '') {
|
|
4
5
|
const classes = ['slidev-page', extra]
|
|
5
6
|
|
|
6
7
|
const no = route?.meta?.slide?.no
|
|
@@ -9,3 +10,15 @@ export function getSlideClass(route?: RouteRecordRaw, extra = '') {
|
|
|
9
10
|
|
|
10
11
|
return classes.filter(Boolean).join(' ')
|
|
11
12
|
}
|
|
13
|
+
|
|
14
|
+
export async function downloadPDF() {
|
|
15
|
+
const { saveAs } = await import('file-saver')
|
|
16
|
+
saveAs(
|
|
17
|
+
typeof configs.download === 'string'
|
|
18
|
+
? configs.download
|
|
19
|
+
: configs.exportFilename
|
|
20
|
+
? `${configs.exportFilename}.pdf`
|
|
21
|
+
: `${import.meta.env.BASE_URL}slidev-exported.pdf`,
|
|
22
|
+
`${configs.title}.pdf`,
|
|
23
|
+
)
|
|
24
|
+
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { ComputedRef } from 'vue'
|
|
2
|
-
import { computed } from 'vue'
|
|
3
|
-
import type { RouteLocationNormalizedLoaded } from 'vue-router'
|
|
4
|
-
import type { SlidevContext } from '../modules/context'
|
|
5
|
-
import { configs } from '../env'
|
|
6
|
-
import { useNav } from './useNav'
|
|
7
|
-
|
|
8
|
-
export function useContext(
|
|
9
|
-
route: ComputedRef<RouteLocationNormalizedLoaded>,
|
|
10
|
-
): SlidevContext {
|
|
11
|
-
const nav = useNav(route)
|
|
12
|
-
return {
|
|
13
|
-
nav,
|
|
14
|
-
configs,
|
|
15
|
-
themeConfigs: computed(() => configs.themeConfig),
|
|
16
|
-
}
|
|
17
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { createSharedComposable, useScriptTag } from '@vueuse/core'
|
|
2
|
-
import type { ComponentInternalInstance } from 'vue'
|
|
3
|
-
import { onMounted } from 'vue'
|
|
4
|
-
|
|
5
|
-
export const useTweetScript = createSharedComposable(
|
|
6
|
-
(vm: ComponentInternalInstance, create: () => void) =>
|
|
7
|
-
useScriptTag(
|
|
8
|
-
'https://platform.twitter.com/widgets.js',
|
|
9
|
-
() => {
|
|
10
|
-
if (vm.isMounted)
|
|
11
|
-
create()
|
|
12
|
-
else
|
|
13
|
-
onMounted(create, vm)
|
|
14
|
-
},
|
|
15
|
-
{ async: true },
|
|
16
|
-
),
|
|
17
|
-
)
|
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()
|