样式生成器预览放到iframe,防止影响到外面网页

pull/157/head
John Smith 1 year ago
parent 0f17dfdec7
commit fd1518db1d

@ -262,6 +262,9 @@ export default class ChatClientTest {
} else { } else {
sleepTime = randInt(0, 400) sleepTime = randInt(0, 400)
} }
if (this.timerId) {
window.clearTimeout(this.timerId)
}
this.timerId = window.setTimeout(this.onTimeout.bind(this), sleepTime) this.timerId = window.setTimeout(this.onTimeout.bind(this), sleepTime)
} }

@ -32,11 +32,16 @@ export default {
} }
}, },
data() { data() {
let customStyleElement = document.createElement('style')
document.head.appendChild(customStyleElement)
return { return {
config: chatConfig.deepCloneDefaultConfig(), config: chatConfig.deepCloneDefaultConfig(),
chatClient: null, chatClient: null,
textEmoticons: [], //
pronunciationConverter: null, pronunciationConverter: null,
textEmoticons: [], //
customStyleElement, //
} }
}, },
computed: { computed: {
@ -79,12 +84,18 @@ export default {
// OBSOBS // OBSOBS
document.addEventListener('visibilitychange', this.onVisibilityChange) document.addEventListener('visibilitychange', this.onVisibilityChange)
} }
window.addEventListener('message', this.onWindowMessage)
}, },
beforeDestroy() { beforeDestroy() {
window.removeEventListener('message', this.onWindowMessage)
document.removeEventListener('visibilitychange', this.onVisibilityChange) document.removeEventListener('visibilitychange', this.onVisibilityChange)
if (this.chatClient) { if (this.chatClient) {
this.chatClient.stop() this.chatClient.stop()
} }
document.head.removeChild(this.customStyleElement)
}, },
methods: { methods: {
onVisibilityChange() { onVisibilityChange() {
@ -105,6 +116,7 @@ export default {
} }
try { try {
//
await initChatClientPromise await initChatClientPromise
} catch (e) { } catch (e) {
this.$message.error({ this.$message.error({
@ -199,11 +211,29 @@ export default {
this.textEmoticons = await chat.getTextEmoticons() this.textEmoticons = await chat.getTextEmoticons()
}, },
start() { //
this.chatClient.start() onWindowMessage(event) {
}, if (event.origin !== window.location.origin) {
stop() { console.warn(`消息origin错误${event.origin} != ${window.location.origin}`)
this.chatClient.stop() return
}
let { type, data } = event.data
switch (type) {
case 'roomSetCustomStyle':
this.customStyleElement.innerText = data.css
break
case 'roomStartClient':
if (this.chatClient) {
this.chatClient.start()
}
break
case 'roomStopClient':
if (this.chatClient) {
this.chatClient.stop()
}
break
}
}, },
onAddText(data) { onAddText(data) {

@ -28,16 +28,16 @@
<div :style="{ position: 'relative', top: `${exampleTop}px` }"> <div :style="{ position: 'relative', top: `${exampleTop}px` }">
<el-form inline style="line-height: 40px"> <el-form inline style="line-height: 40px">
<el-form-item :label="$t('stylegen.playAnimation')" style="margin: 0"> <el-form-item :label="$t('stylegen.playAnimation')" style="margin: 0">
<el-switch v-model="playAnimation" @change="onPlayAnimationChange"></el-switch> <el-switch v-model="playAnimation" @change="setExampleRoomClientStart"></el-switch>
</el-form-item> </el-form-item>
<el-form-item :label="$t('stylegen.backgrounds')" style="margin: 0 0 0 30px"> <el-form-item :label="$t('stylegen.backgrounds')" style="margin: 0 0 0 30px">
<el-switch v-model="exampleBgLight" :active-text="$t('stylegen.light')" :inactive-text="$t('stylegen.dark')"></el-switch> <el-switch v-model="exampleBgLight" :active-text="$t('stylegen.light')" :inactive-text="$t('stylegen.dark')"></el-switch>
</el-form-item> </el-form-item>
</el-form> </el-form>
<div id="example-container" :class="{ light: exampleBgLight }"> <div id="example-container" :class="{ light: exampleBgLight }">
<div id="fakebody"> <iframe id="example-room-iframe" ref="exampleRoomIframe"
<room ref="room"></room> :src="exampleRoomUrl" frameborder="0" @load="onExampleRoomLoad"
</div> ></iframe>
</div> </div>
</div> </div>
</el-col> </el-col>
@ -52,17 +52,11 @@ import LineLike from './LineLike'
export default { export default {
name: 'StyleGenerator', name: 'StyleGenerator',
components: { components: { Legacy, LineLike },
Legacy,
LineLike,
Room: () => import('@/views/Room'),
},
data() { data() {
let styleElement = document.createElement('style')
document.head.appendChild(styleElement)
// //
// --\ // --\
// -> subComponentResults -> subComponentResult -> inputResult -> 0.5s -> debounceResult -> exampleCss // -> subComponentResults -> subComponentResult -> inputResult -> 0.5s -> debounceResult
return { return {
// //
subComponentResults: { subComponentResults: {
@ -75,20 +69,18 @@ export default {
// //
debounceResult: '', debounceResult: '',
styleElement,
exampleTop: 0, exampleTop: 0,
playAnimation: true, playAnimation: true,
exampleBgLight: false exampleBgLight: false
} }
}, },
computed: { computed: {
exampleRoomUrl() {
return this.$router.resolve({ name: 'test_room', query: { lang: this.$i18n.locale } }).href
},
// //
subComponentResult() { subComponentResult() {
return this.subComponentResults[this.activeTab] return this.subComponentResults[this.activeTab]
},
// CSS
exampleCss() {
return this.debounceResult.replace(/^body\b/gm, '#fakebody')
} }
}, },
watch: { watch: {
@ -98,9 +90,7 @@ export default {
inputResult: _.debounce(function(val) { inputResult: _.debounce(function(val) {
this.debounceResult = val this.debounceResult = val
}, 500), }, 500),
exampleCss(val) { debounceResult: 'setExampleRoomCustomCss'
this.styleElement.innerText = val
}
}, },
mounted() { mounted() {
this.debounceResult = this.inputResult = this.subComponentResult this.debounceResult = this.inputResult = this.subComponentResult
@ -109,8 +99,6 @@ export default {
}, },
beforeDestroy() { beforeDestroy() {
this.$parent.$el.removeEventListener('scroll', this.onParentScroll) this.$parent.$el.removeEventListener('scroll', this.onParentScroll)
document.head.removeChild(this.styleElement)
}, },
methods: { methods: {
onParentScroll(event) { onParentScroll(event) {
@ -120,13 +108,22 @@ export default {
this.exampleTop = event.target.scrollTop this.exampleTop = event.target.scrollTop
} }
}, },
onPlayAnimationChange(value) {
if (value) { onExampleRoomLoad() {
this.$refs.room.start() this.setExampleRoomCustomCss(this.debounceResult)
} else { this.setExampleRoomClientStart(this.playAnimation)
this.$refs.room.stop() },
} setExampleRoomCustomCss(css) {
this.sendMessageToExampleRoom('roomSetCustomStyle', { css })
}, },
setExampleRoomClientStart(isStart) {
this.sendMessageToExampleRoom(isStart ? 'roomStartClient' : 'roomStopClient')
},
sendMessageToExampleRoom(type, data = null) {
let msg = { type, data }
this.$refs.exampleRoomIframe.contentWindow.postMessage(msg, window.location.origin)
},
copyResult() { copyResult() {
this.$refs.result.select() this.$refs.result.select()
document.execCommand('Copy') document.execCommand('Copy')
@ -181,8 +178,9 @@ export default {
-webkit-gradient(linear, 0 0, 100% 100%, color-stop(.75, transparent), color-stop(.75, #eee)); -webkit-gradient(linear, 0 0, 100% 100%, color-stop(.75, transparent), color-stop(.75, #eee));
} }
#fakebody { #example-room-iframe {
outline: 1px #999 dashed; outline: 1px #999 dashed;
width: 100%;
height: 100%; height: 100%;
} }
</style> </style>

Loading…
Cancel
Save