import { create } from "zustand"; interface PreviewPopoutState { pipWindow: Window | null; container: HTMLElement | null; openPopout: () => Promise; dockPopout: () => void; } function copyStylesInto({ pipWindow }: { pipWindow: Window }) { const styleNodes = document.head.querySelectorAll( "style, link[rel='stylesheet']", ); for (const node of styleNodes) { if (node instanceof HTMLStyleElement) { pipWindow.document.head.appendChild(node.cloneNode(true)); } else if (node instanceof HTMLLinkElement) { const link = pipWindow.document.createElement("link"); link.rel = "stylesheet"; link.href = node.href; pipWindow.document.head.appendChild(link); } } } function preparePipDocument({ pipWindow }: { pipWindow: Window }) { pipWindow.document.documentElement.className = document.documentElement.className; pipWindow.document.documentElement.style.height = "100%"; pipWindow.document.body.className = document.body.className; pipWindow.document.body.style.margin = "0"; pipWindow.document.body.style.height = "100%"; pipWindow.document.body.style.overflow = "hidden"; pipWindow.document.title = "Preview"; copyStylesInto({ pipWindow }); } export const usePreviewPopoutStore = create()( (set, get) => ({ pipWindow: null, container: null, openPopout: async () => { if (get().container !== null) { return; } if (!("documentPictureInPicture" in window)) { return; } const pip = window.documentPictureInPicture; if (!pip) { return; } const pipWindow = await pip.requestWindow(); preparePipDocument({ pipWindow }); const container = pipWindow.document.createElement("div"); container.style.width = "100%"; container.style.height = "100%"; pipWindow.document.body.appendChild(container); pipWindow.addEventListener( "pagehide", () => { set({ pipWindow: null, container: null }); }, { once: true }, ); set({ pipWindow, container }); }, dockPopout: () => { const { pipWindow } = get(); if (pipWindow && !pipWindow.closed) { pipWindow.close(); } set({ pipWindow: null, container: null }); }, }), );