Skip to content

Commit a22b969

Browse files
authored
feat: support for sandbox page customization (#42)
1 parent 29263d8 commit a22b969

File tree

3 files changed

+41
-9
lines changed

3 files changed

+41
-9
lines changed

src/Repl.vue

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,14 @@ export interface Props {
1414
sfcOptions?: SFCOptions
1515
layout?: string
1616
ssr?: boolean
17+
previewOptions?: {
18+
headHTML?: string
19+
bodyHTML?: string
20+
customCode?: {
21+
importCode?: string
22+
useCode?: string
23+
}
24+
}
1725
}
1826
1927
const props = withDefaults(defineProps<Props>(), {
@@ -22,7 +30,15 @@ const props = withDefaults(defineProps<Props>(), {
2230
showCompileOutput: true,
2331
showImportMap: true,
2432
clearConsole: true,
25-
ssr: false
33+
ssr: false,
34+
previewOptions: () => ({
35+
headHTML: '',
36+
bodyHTML: '',
37+
customCode: {
38+
importCode: '',
39+
useCode: '',
40+
},
41+
}),
2642
})
2743
2844
const { store } = props
@@ -48,6 +64,7 @@ provide('store', store)
4864
provide('autoresize', props.autoResize)
4965
provide('import-map', toRef(props, 'showImportMap'))
5066
provide('clear-console', toRef(props, 'clearConsole'))
67+
provide('preview-options', props.previewOptions)
5168
</script>
5269

5370
<template>

src/output/Preview.vue

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,15 @@ import srcdoc from './srcdoc.html?raw'
1414
import { PreviewProxy } from './PreviewProxy'
1515
import { compileModulesForPreview } from './moduleCompiler'
1616
import { Store } from '../store'
17+
import { Props } from '../Repl.vue'
1718
1819
const props = defineProps<{ show: boolean; ssr: boolean }>()
1920
2021
const store = inject('store') as Store
2122
const clearConsole = inject('clear-console') as Ref<boolean>
23+
24+
const previewOptions = inject('preview-options') as Props['previewOptions']
25+
2226
const container = ref()
2327
const runtimeError = ref()
2428
const runtimeWarning = ref()
@@ -85,10 +89,12 @@ function createSandbox() {
8589
if (!importMap.imports.vue) {
8690
importMap.imports.vue = store.state.vueRuntimeURL
8791
}
88-
const sandboxSrc = srcdoc.replace(
89-
/<!--IMPORT_MAP-->/,
90-
JSON.stringify(importMap)
91-
)
92+
const sandboxSrc = srcdoc
93+
.replace(/<!--IMPORT_MAP-->/, JSON.stringify(importMap))
94+
.replace(
95+
/<!-- PREVIEW-OPTIONS-HEAD-HTML -->/,
96+
previewOptions?.headHTML || ''
97+
)
9298
sandbox.srcdoc = sandboxSrc
9399
container.value.appendChild(sandbox)
94100
@@ -196,7 +202,9 @@ async function updatePreview() {
196202
}
197203
app.config.warnHandler = () => {}
198204
window.__ssr_promise__ = _renderToString(app).then(html => {
199-
document.body.innerHTML = '<div id="app">' + html + '</div>'
205+
document.body.innerHTML = '<div id="app">' + html + '</div>' + \`${
206+
previewOptions?.bodyHTML || ''
207+
}\`
200208
}).catch(err => {
201209
console.error("SSR Error", err)
202210
})
@@ -213,9 +221,13 @@ async function updatePreview() {
213221
)
214222
215223
const codeToEval = [
216-
`window.__modules__ = {}\nwindow.__css__ = ''\n` +
217-
`if (window.__app__) window.__app__.unmount()\n` +
218-
(isSSR ? `` : `document.body.innerHTML = '<div id="app"></div>'`),
224+
`window.__modules__ = {};window.__css__ = '';` +
225+
`if (window.__app__) window.__app__.unmount();` +
226+
(isSSR
227+
? ``
228+
: `document.body.innerHTML = '<div id="app"></div>' + \`${
229+
previewOptions?.bodyHTML || ''
230+
}\``),
219231
...modules,
220232
`document.getElementById('__sfc-styles').innerHTML = window.__css__`
221233
]
@@ -226,6 +238,7 @@ async function updatePreview() {
226238
`import { ${
227239
isSSR ? `createSSRApp` : `createApp`
228240
} as _createApp } from "vue"
241+
${previewOptions?.customCode?.importCode || ''}
229242
const _mount = () => {
230243
const AppComponent = __modules__["${mainFile}"].default
231244
AppComponent.name = 'Repl'
@@ -234,6 +247,7 @@ async function updatePreview() {
234247
app.config.unwrapInjectedRef = true
235248
}
236249
app.config.errorHandler = e => console.error(e)
250+
${previewOptions?.customCode?.useCode || ''}
237251
app.mount('#app')
238252
}
239253
if (window.__ssr_promise__) {

src/output/srcdoc.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
88
}
99
</style>
10+
<!-- PREVIEW-OPTIONS-HEAD-HTML -->
1011
<style id="__sfc-styles"></style>
1112
<script>
1213
(() => {

0 commit comments

Comments
 (0)