|
@@ -8,7 +8,7 @@ import { vUnwrap } from '../lib/unwrap'
|
|
|
*/
|
|
*/
|
|
|
import {computed, ref, watch } from 'vue'
|
|
import {computed, ref, watch } from 'vue'
|
|
|
import { t } from '../i18n/zh'
|
|
import { t } from '../i18n/zh'
|
|
|
-import { FUS_SUBS, cmsHtml, eventsHtml, loopHtml, matrixHtml, portalCmsDoc, unitsHtml } from '../lib/vib'
|
|
|
|
|
|
|
+import { FUS_SUBS, cmsHtml, eventsHtml, loopHtml, matrixHtml, portalCmsHtml, unitsHtml } from '../lib/vib'
|
|
|
import { PORTAL_CSS } from '../lib/portalSections'
|
|
import { PORTAL_CSS } from '../lib/portalSections'
|
|
|
|
|
|
|
|
const props = defineProps<{ d: any; sub?: string | null; cms?: any }>()
|
|
const props = defineProps<{ d: any; sub?: string | null; cms?: any }>()
|
|
@@ -30,17 +30,22 @@ watch(sub, async (s) => {
|
|
|
}
|
|
}
|
|
|
}, { immediate: true })
|
|
}, { immediate: true })
|
|
|
const cmsData = computed<any>(() => props.cms ?? cmsLocal.value)
|
|
const cmsData = computed<any>(() => props.cms ?? cmsLocal.value)
|
|
|
|
|
+/** ★P73 用 **Shadow DOM** 渲染门户「振动·CMS」:门户 CSS 在其中隔离生效,
|
|
|
|
|
+ * 不依赖 iframe/srcdoc/blob(前几种在真机上均可能有环境差异)。 */
|
|
|
|
|
+const cmsHost = ref<HTMLElement | null>(null)
|
|
|
|
|
+function renderCmsShadow(): void {
|
|
|
|
|
+ const host = cmsHost.value
|
|
|
|
|
+ if (!host) return
|
|
|
|
|
+ const root = host.shadowRoot || host.attachShadow({ mode: 'open' })
|
|
|
|
|
+ root.innerHTML = '<style>' + PORTAL_CSS + '</style>' + portalCmsHtml(props.d, cmsData.value)
|
|
|
|
|
+}
|
|
|
|
|
+watch([() => props.sub, () => props.d, cmsData], () => { if (props.sub === 'portal_cms') renderCmsShadow() },
|
|
|
|
|
+ { immediate: true, flush: 'post' })
|
|
|
|
|
+
|
|
|
const F = computed<any>(() => props.d?.fus)
|
|
const F = computed<any>(() => props.d?.fus)
|
|
|
|
|
|
|
|
/** ★P71 门户「振动·CMS」整页文档(同源 iframe)—— 用门户 CSS 渲染,chip 为按窗实时值 */
|
|
/** ★P71 门户「振动·CMS」整页文档(同源 iframe)—— 用门户 CSS 渲染,chip 为按窗实时值 */
|
|
|
const portalCmsSrc = computed<string>(() => portalCmsDoc(props.d, cmsData.value, PORTAL_CSS))
|
|
const portalCmsSrc = computed<string>(() => portalCmsDoc(props.d, cmsData.value, PORTAL_CSS))
|
|
|
-/** ★P72 用 **Blob URL** 装进 iframe(与门户整页同一手法;真机上比 srcdoc 可靠)。 */
|
|
|
|
|
-const cmsBlobUrl = ref<string>('')
|
|
|
|
|
-watch(portalCmsSrc, (html) => {
|
|
|
|
|
- const old = cmsBlobUrl.value
|
|
|
|
|
- cmsBlobUrl.value = URL.createObjectURL(new Blob([html], { type: 'text/html;charset=utf-8' }))
|
|
|
|
|
- if (old) { try { URL.revokeObjectURL(old) } catch { /* ignore */ } }
|
|
|
|
|
-}, { immediate: true })
|
|
|
|
|
|
|
|
|
|
const bodyHtml = computed(() => {
|
|
const bodyHtml = computed(() => {
|
|
|
const f = F.value
|
|
const f = F.value
|
|
@@ -62,8 +67,7 @@ const bodyHtml = computed(() => {
|
|
|
<button v-for="s in FUS_SUBS" :key="s" class="pill" :class="{ on: s === sub }" :data-fsub="s"
|
|
<button v-for="s in FUS_SUBS" :key="s" class="pill" :class="{ on: s === sub }" :data-fsub="s"
|
|
|
@click="emit('sub', s)">{{ t('fus.sub.' + s) }}</button>
|
|
@click="emit('sub', s)">{{ t('fus.sub.' + s) }}</button>
|
|
|
</div>
|
|
</div>
|
|
|
- <iframe v-if="sub === 'portal_cms'" class="portal-cms-frame" title="振动 · CMS"
|
|
|
|
|
- :src="cmsBlobUrl" style="width:100%;height:1080px;border:0;display:block"></iframe>
|
|
|
|
|
|
|
+ <div v-if="sub === 'portal_cms'" ref="cmsHost" class="portal-cms-shadow" data-fsub-host="portal_cms"></div>
|
|
|
<div v-else class="unwrap-host" v-html="bodyHtml"></div>
|
|
<div v-else class="unwrap-host" v-html="bodyHtml"></div>
|
|
|
</section>
|
|
</section>
|
|
|
</template>
|
|
</template>
|