| 1 | import { throttledWatch } from '@vueuse/core' |
| 2 | import { useNav } from '../composables/useNav' |
| 3 | import { isDark } from '../logic/dark' |
| 4 | |
| 5 | export function useEmbeddedControl() { |
| 6 | const nav = useNav() |
| 7 | const clientId = `${Date.now()}` |
| 8 | |
| 9 | window.addEventListener('message', ({ data }) => { |
| 10 | if (data && data.target === 'slidev') { |
| 11 | if (data.type === 'navigate') { |
| 12 | if (data.no || data.clicks) { |
| 13 | nav.go(+data.no, +data.clicks || 0) |
| 14 | } |
| 15 | else if (typeof data.operation === 'string') { |
| 16 | const fn = nav[data.operation as keyof typeof nav] |
| 17 | if (typeof fn === 'function') |
| 18 | (fn as any)(...(data.args ?? [])) |
| 19 | } |
| 20 | } |
| 21 | else if (data.type === 'css-vars') { |
| 22 | const root = document.documentElement |
| 23 | for (const [key, value] of Object.entries(data.vars || {})) |
| 24 | root.style.setProperty(key, value as any) |
| 25 | } |
| 26 | else if (data.type === 'color-schema') { |
| 27 | isDark.value = data.color === 'dark' |
| 28 | } |
| 29 | } |
| 30 | }) |
| 31 | |
| 32 | if (nav.isEmbedded.value) { |
| 33 | throttledWatch( |
| 34 | [nav.currentSlideNo, nav.clicks, nav.hasNext, nav.hasPrev, nav.hasPrimarySlide], |
| 35 | ([no, clicks, hasNext, hasPrev, hasPrimarySlide]) => { |
| 36 | if (!hasPrimarySlide) |
| 37 | return |
| 38 | window.parent.postMessage( |
| 39 | { |
| 40 | target: 'slidev', |
| 41 | clientId, |
| 42 | navState: { |
| 43 | no, |
| 44 | clicks, |
| 45 | hasNext, |
| 46 | hasPrev, |
| 47 | }, |
| 48 | }, |
| 49 | '*', |
| 50 | ) |
| 51 | }, |
| 52 | { |
| 53 | throttle: 50, |
| 54 | immediate: true, |
| 55 | }, |
| 56 | ) |
| 57 | } |
| 58 | } |
| 59 |