feat: implement plugin frame cleanup on unload and enhance iframe handling

This commit is contained in:
shiyu
2026-05-06 23:30:20 +08:00
parent bd24d7eeeb
commit deddbdf585
3 changed files with 41 additions and 32 deletions

View File

@@ -24,6 +24,16 @@ function getPluginStylePaths(plugin: PluginItem): string[] {
return styles.filter((s) => typeof s === 'string' && s.trim().length > 0);
}
function unloadPluginFrame(iframe: HTMLIFrameElement | null) {
if (!iframe) return;
try {
iframe.contentWindow?.postMessage({ type: 'foxel-plugin:unload' }, window.location.origin);
} catch {
void 0;
}
iframe.src = 'about:blank';
}
/**
* 插件宿主组件 - 文件打开模式
* 使用 iframe 隔离渲染与样式,避免插件污染宿主 DOM/CSS。
@@ -66,7 +76,10 @@ export const PluginAppHost: React.FC<PluginAppHostProps> = ({
};
window.addEventListener('message', onMessage);
return () => window.removeEventListener('message', onMessage);
return () => {
window.removeEventListener('message', onMessage);
unloadPluginFrame(iframeRef.current);
};
}, [plugin.key]);
return (
@@ -118,7 +131,10 @@ export const PluginAppOpenHost: React.FC<PluginAppOpenHostProps> = ({ plugin, on
};
window.addEventListener('message', onMessage);
return () => window.removeEventListener('message', onMessage);
return () => {
window.removeEventListener('message', onMessage);
unloadPluginFrame(iframeRef.current);
};
}, [plugin.key]);
return (

View File

@@ -364,12 +364,27 @@ async function main() {
await mountError();
window.addEventListener('beforeunload', () => {
const runCleanup = () => {
try {
cleanup?.();
} catch {
void 0;
}
cleanup = null;
};
window.addEventListener('message', (ev) => {
if (ev.origin !== window.location.origin) return;
if (ev.source !== window.parent) return;
const data = ev.data as any;
if (!data || typeof data !== 'object') return;
if (data.type !== 'foxel-plugin:unload') return;
runCleanup();
root.innerHTML = '';
});
window.addEventListener('beforeunload', () => {
runCleanup();
});
}