修复plyaground的bug
parent
2790776723
commit
e3df7f6eee
|
@ -21,13 +21,15 @@ export default {
|
||||||
watch: {
|
watch: {
|
||||||
code(v) {
|
code(v) {
|
||||||
let doc = this.$view.state.doc
|
let doc = this.$view.state.doc
|
||||||
|
let { anchor } = this.$view.state.selection.main
|
||||||
|
|
||||||
this.$view.dispatch({
|
this.$view.dispatch({
|
||||||
changes: {
|
changes: {
|
||||||
from: 0,
|
from: 0,
|
||||||
to: doc.length,
|
to: doc.length,
|
||||||
insert: v
|
insert: v
|
||||||
}
|
},
|
||||||
|
selection: { anchor } // 恢复之前的光标位置
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -49,12 +51,12 @@ export default {
|
||||||
EditorView.lineWrapping,
|
EditorView.lineWrapping,
|
||||||
// 监听代码变化
|
// 监听代码变化
|
||||||
EditorView.updateListener.of(v => {
|
EditorView.updateListener.of(v => {
|
||||||
let value = v.state.doc.toString().trim()
|
let value = v.state.doc.toString()
|
||||||
if (!this.$last || value === this.$last) {
|
if (!this.$last || value.trim() === this.$last) {
|
||||||
this.$last = value
|
this.$last = value.trim()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.$last = value
|
this.$last = value.trim()
|
||||||
this.$emit('change', value, lang)
|
this.$emit('change', value, lang)
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
|
@ -75,5 +77,6 @@ export default {
|
||||||
.cm-editor {
|
.cm-editor {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
outline: none !important;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
<CodeEditor lang="css" :code="css" @change="updateCode" />
|
<CodeEditor lang="css" :code="css" @change="updateCode" />
|
||||||
</wc-tab>
|
</wc-tab>
|
||||||
</wc-tabs>
|
</wc-tabs>
|
||||||
<Preview :code="preview" />
|
<Preview ref="preview" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -23,35 +23,6 @@ import Preview from './views/preview.vue'
|
||||||
|
|
||||||
import { gzip, ungzip } from '@bytedo/gzip'
|
import { gzip, ungzip } from '@bytedo/gzip'
|
||||||
|
|
||||||
const template = `<!doctype html>
|
|
||||||
<html lang="zh-CN">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
|
|
||||||
<link rel="stylesheet" href="//jscdn.ink/@bd/ui/latest/css/reset-basic.css">
|
|
||||||
{{css}}
|
|
||||||
<script async src="//jscdn.ink/es-module-shims/1.6.3/es-module-shims.wasm.js"><\/script>
|
|
||||||
<script type="importmap">${JSON.stringify({
|
|
||||||
imports: {
|
|
||||||
vue: '//jscdn.ink/vue/3.2.47/vue.runtime.esm-browser.prod.js',
|
|
||||||
'vue-router': '//jscdn.ink/@bytedo/vue-router/4.1.6/vue-router.js',
|
|
||||||
fetch: '//jscdn.ink/@bytedo/fetch/latest/next.js',
|
|
||||||
'@bytedo/editor': '//jscdn.ink/@bytedo/editor/latest/index.js',
|
|
||||||
'@bytedo/gzip': '//jscdn.ink/@bytedo/gzip/latest/index.js',
|
|
||||||
'@bd/core': '//jscdn.ink/@bd/core/latest/index.js'
|
|
||||||
}
|
|
||||||
})}<\/script>
|
|
||||||
<script type="module">
|
|
||||||
{{js}}
|
|
||||||
<\/script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
{{html}}
|
|
||||||
<\/body>
|
|
||||||
<\/html>
|
|
||||||
`
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { Topbar, CodeEditor, Preview },
|
components: { Topbar, CodeEditor, Preview },
|
||||||
data() {
|
data() {
|
||||||
|
@ -93,22 +64,21 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
updateCode(code, lang) {
|
updateCode(code, lang) {
|
||||||
|
let { html, js, css } = this
|
||||||
|
let codez
|
||||||
this[lang] = code
|
this[lang] = code
|
||||||
this.updatePreview(true)
|
|
||||||
|
codez = gzip(JSON.stringify({ html, js, css, [lang]: code }))
|
||||||
|
|
||||||
|
this.$needUpdate = false
|
||||||
|
location.hash = codez
|
||||||
|
|
||||||
|
this.$refs.preview.render({ [lang]: code })
|
||||||
},
|
},
|
||||||
updatePreview(sync) {
|
updatePreview(sync) {
|
||||||
let { html, js, css } = this
|
let { html, js, css } = this
|
||||||
|
|
||||||
if (sync) {
|
this.$refs.preview.render({ html, js, css })
|
||||||
let code = gzip(JSON.stringify({ html, js, css }))
|
|
||||||
this.$needUpdate = false
|
|
||||||
location.hash = code
|
|
||||||
}
|
|
||||||
|
|
||||||
this.preview = template
|
|
||||||
.replace('{{css}}', css)
|
|
||||||
.replace('{{html}}', html)
|
|
||||||
.replace('{{js}}', js)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,31 +3,56 @@
|
||||||
<div class="loading">
|
<div class="loading">
|
||||||
<span class="thumb" :style="{ width: progress + '%' }"></span>
|
<span class="thumb" :style="{ width: progress + '%' }"></span>
|
||||||
</div>
|
</div>
|
||||||
<iframe class="web" ref="preview"></iframe>
|
<iframe class="web" ref="view"></iframe>
|
||||||
</main>
|
</main>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { nextTick } from 'vue'
|
import { nextTick } from 'vue'
|
||||||
|
|
||||||
|
const template = `<!doctype html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
|
||||||
|
<link rel="stylesheet" href="//jscdn.ink/@bd/ui/latest/css/reset-basic.css">
|
||||||
|
<style name="css"></style>
|
||||||
|
<script async src="//jscdn.ink/es-module-shims/1.6.3/es-module-shims.wasm.js"><\/script>
|
||||||
|
<script type="importmap">${JSON.stringify({
|
||||||
|
imports: {
|
||||||
|
vue: '//jscdn.ink/vue/3.2.47/vue.runtime.esm-browser.prod.js',
|
||||||
|
'vue-router': '//jscdn.ink/@bytedo/vue-router/4.1.6/vue-router.js',
|
||||||
|
fetch: '//jscdn.ink/@bytedo/fetch/latest/next.js',
|
||||||
|
'@bytedo/editor': '//jscdn.ink/@bytedo/editor/latest/index.js',
|
||||||
|
'@bytedo/gzip': '//jscdn.ink/@bytedo/gzip/latest/index.js',
|
||||||
|
'@bd/core': '//jscdn.ink/@bd/core/latest/index.js'
|
||||||
|
}
|
||||||
|
})}<\/script>
|
||||||
|
</head>
|
||||||
|
<body><\/body>
|
||||||
|
<\/html>
|
||||||
|
`
|
||||||
|
|
||||||
let startTime = 0
|
let startTime = 0
|
||||||
|
let pending = false
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
|
||||||
code: ''
|
|
||||||
},
|
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
progress: 0
|
progress: 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
mounted() {
|
||||||
code(v) {
|
this.$code = {}
|
||||||
// console.log(v)
|
|
||||||
this.updatePreview(v)
|
try {
|
||||||
}
|
let doc = this.$refs.view.contentDocument
|
||||||
|
doc.open()
|
||||||
|
doc.write(template)
|
||||||
|
doc.close()
|
||||||
|
} catch (e) {}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -39,26 +64,47 @@ export default {
|
||||||
let _time = stamp - startTime
|
let _time = stamp - startTime
|
||||||
|
|
||||||
// _time / 2000 * 100 %
|
// _time / 2000 * 100 %
|
||||||
this.progress = ~~(_time / 20)
|
this.progress = ~~(_time / 10)
|
||||||
|
|
||||||
if (_time > 2000) {
|
if (pending && _time > 1000) {
|
||||||
this.progress = 0
|
this.progress = 0
|
||||||
let doc = this.$refs.preview.contentDocument
|
let doc = this.$refs.view.contentDocument
|
||||||
|
|
||||||
|
for (let k in this.$code) {
|
||||||
|
switch (k) {
|
||||||
|
case 'html':
|
||||||
|
doc.body.innerHTML = this.$code[k]
|
||||||
|
break
|
||||||
|
case 'js':
|
||||||
|
if (doc.head.children.namedItem('js')) {
|
||||||
|
doc.head.children.namedItem('js').textContent = this.$code[k]
|
||||||
|
} else {
|
||||||
|
let script = document.createElement('script')
|
||||||
|
script.name = 'js'
|
||||||
|
script.type = 'module'
|
||||||
|
script.textContent = this.$code[k]
|
||||||
|
doc.head.append(script)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 'css':
|
||||||
|
doc.head.children.namedItem('css').textContent = this.$code[k]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pending = false
|
||||||
|
|
||||||
try {
|
|
||||||
doc.open()
|
|
||||||
doc.write(this.code)
|
|
||||||
doc.close()
|
|
||||||
} catch (e) {}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
requestAnimationFrame(this.loading)
|
requestAnimationFrame(this.loading)
|
||||||
},
|
},
|
||||||
|
|
||||||
updatePreview(html) {
|
render(code = {}) {
|
||||||
startTime = 0
|
startTime = 0
|
||||||
|
pending = true
|
||||||
this.progress = 0
|
this.progress = 0
|
||||||
|
this.$code = code
|
||||||
|
|
||||||
requestAnimationFrame(this.loading)
|
requestAnimationFrame(this.loading)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue