diff --git a/src/renderer/context/embed.ts b/src/renderer/context/embed.ts index 3a14e964..36ddbade 100644 --- a/src/renderer/context/embed.ts +++ b/src/renderer/context/embed.ts @@ -1,6 +1,6 @@ -import { useBus } from '@fe/support/bus' import { debounce } from 'lodash-es' -import { defineComponent, h, onBeforeUnmount, onMounted, ref, watch } from 'vue' +import { defineComponent, h, onBeforeUnmount, onMounted, PropType, ref, watch } from 'vue' +import { useBus } from '@fe/support/bus' export function buildSrc (html: string, title = '') { return `/embed/?_t=${Date.now()}&title=${encodeURIComponent(title)}&html=${encodeURIComponent(html)}` @@ -14,7 +14,8 @@ export const IFrame = defineComponent({ default: 500 }, html: String, - iframeProps: Object + iframeProps: Object, + onLoad: Function as PropType<(iframe: HTMLIFrameElement) => void> }, setup (props) { const url = ref('') @@ -54,7 +55,7 @@ export const IFrame = defineComponent({ // 注入变量 win.resize = resize win.ctx = window.ctx - props.iframeProps?.onLoad?.call(frame) + props.onLoad?.(frame) } return () => url.value ? h('iframe', { @@ -63,8 +64,8 @@ export const IFrame = defineComponent({ frameBorder: '0', width: '100%', height: '100px', - ...props.iframeProps, onLoad, + ...props.iframeProps, }) : null } }) diff --git a/src/renderer/plugins/markdown-applet.ts b/src/renderer/plugins/markdown-applet.ts index e8780bcf..305bb0ff 100644 --- a/src/renderer/plugins/markdown-applet.ts +++ b/src/renderer/plugins/markdown-applet.ts @@ -1,97 +1,9 @@ -import { defineComponent, h, onBeforeUnmount, onMounted, ref, watch } from 'vue' +import { h } from 'vue' import CryptoJS from 'crypto-js' -import { debounce } from 'lodash-es' import dayjs from 'dayjs' import Markdown from 'markdown-it' -import { useBus } from '@fe/support/bus' import { Plugin } from '@fe/context/plugin' -import { getThemeName } from '@fe/context/theme' - -let cssText = '' - -const Applet = defineComponent({ - name: 'applet', - props: { - id: String, - code: String, - title: String, - }, - setup (props) { - const bus = useBus() - const iframe = ref() - const srcdoc = ref('') - - const setSrcdoc = () => { - const theme = getThemeName() - srcdoc.value = ` - - - - - - ${props.code} - - ` - } - - onMounted(setSrcdoc) - watch(() => props.code, debounce(setSrcdoc, 1000)) - bus.on('theme.change', setSrcdoc) - - onBeforeUnmount(() => { - bus.off('theme.change', setSrcdoc) - }) - - const onLoad = function (this: HTMLIFrameElement) { - const resize = () => { - iframe.value!.height = iframe.value!.contentDocument!.documentElement.scrollHeight + 'px' - bus.emit('global.resize') - } - resize() - - const win = iframe.value!.contentWindow as any - - // 注入变量 - win.resize = resize - win.appletFrame = this - win.appletId = props.id - win.CryptoJS = CryptoJS - win.dayjs = dayjs - win.ctx = window.ctx - - // 调用初始化方法 - win.init && win.init() - } - - return () => { - return h('fieldset', {}, [ - h('legend', {}, `Applet: ${props.title}`), - h('div', - { class: 'applet' }, - h('iframe', { - ref: iframe, - srcdoc: srcdoc.value, - class: 'applet-iframe', - frameBorder: '0', - width: '100%', - height: '20px', - onLoad, - }) - ) - ]) - } - } -}) +import { IFrame } from '@fe/context/embed' const MarkdownItPlugin = (md: Markdown) => { const temp = md.renderer.rules.fence!.bind(md.renderer.rules) @@ -108,40 +20,43 @@ const MarkdownItPlugin = (md: Markdown) => { const appletId = `applet-${hash}-${idx}` const appletTitle = firstLine.replace('', '').replace('--applet--', '').trim() - return h(Applet, { - id: appletId, - title: appletTitle, - code, - }) as any - } -} + const html = ` + -export function getCssText () { - return [].slice.call(window.document.styleSheets) - .map((styleSheet: CSSStyleSheet) => [].slice.call(styleSheet.cssRules)) - .flat() - .filter((cssRule: any) => - ( - cssRule.conditionText && ( - cssRule.conditionText === 'screen' || - cssRule.conditionText.includes('prefers-color-scheme') - ) - ) || ( - cssRule.selectorText && ( - cssRule.selectorText.startsWith('html') || - cssRule.selectorText.startsWith(':root') || - cssRule.selectorText.startsWith('::') - ) + ${code} + ` + + return h('fieldset', {}, [ + h('legend', {}, `Applet: ${appletTitle}`), + h('div', + { class: 'applet' }, + h(IFrame, { + html, + debounce: 1000, + onLoad (iframe: HTMLIFrameElement) { + const win = iframe.contentWindow as any + win.appletId = appletId + win.CryptoJS = CryptoJS + win.dayjs = dayjs + win.init?.() + win.resize() + }, + iframeProps: { + class: 'applet-iframe', + height: '20px', + } + }), ) - ) - .map((cssRule: CSSRule) => cssRule.cssText) - .join('\n') + ]) as any + } } export default { name: 'applet', register: ctx => { - cssText = getCssText() ctx.markdown.registerPlugin(MarkdownItPlugin) } } as Plugin diff --git a/src/renderer/plugins/markdown-drawio.ts b/src/renderer/plugins/markdown-drawio.ts index abf827f3..28296727 100644 --- a/src/renderer/plugins/markdown-drawio.ts +++ b/src/renderer/plugins/markdown-drawio.ts @@ -1,6 +1,7 @@ import Markdown from 'markdown-it' import { defineComponent, h, ref, watch } from 'vue' import { Plugin } from '@fe/context/plugin' +import { IFrame } from '@fe/context/embed' import * as api from '@fe/support/api' import { useBus } from '@fe/support/bus' import { openInNewWindow } from '@fe/utils' @@ -46,18 +47,17 @@ const Drawio = defineComponent({ button('新窗口打开', () => openInNewWindow('查看图形', srcdoc.value)), ] ), - h( - 'iframe', - { - ref: iframe, + h(IFrame, { + html: srcdoc.value, + onLoad (frame) { + iframe.value = frame + resize() + }, + iframeProps: { class: 'drawio', - frameBorder: '0', - width: '100%', height: '300px', - srcdoc: srcdoc.value, - onLoad: resize - } - ), + }, + }) ]) } })