fix(plugin): close plugin tabs safely and hide load flash

This commit is contained in:
t8y2 committed 2026-09-13 13:08:15 +08:00
1 parent bcd1aafb33
commit 5ed03ca2b2
8 files changed
+66 -13

No files matched your search

+21
View File
@@ -291,11 +291,32 @@ describe("PluginHostBridge", () => {
expect(document).toContain("window.dbxPlugin");
expect(document).toContain("get locale() { return locale; }");
expect(document).toContain("openFilesystem");
expect(document).toContain("shortcut: 'closeTab'");
expect(document).toContain("connect-src 'none'");
expect(document).toContain(".dbx-btn");
expect(document).toContain("var(--color-background");
});
it("forwards the plugin close-tab shortcut to the host", () => {
const target = { postMessage: vi.fn() } as unknown as Window;
const closeTab = vi.fn();
const bridge = new PluginHostBridge(plugin(), workbench, {}, () => target, {
invoke: vi.fn(),
notify: vi.fn(),
sendBinary: vi.fn(),
readAsset: vi.fn(),
closeTab,
});
expect(
bridge.handleWindowMessage({
source: target,
data: { source: "dbx-plugin", version: 1, type: "shortcut", shortcut: "closeTab" },
} as MessageEvent),
).toBe(true);
expect(closeTab).toHaveBeenCalledOnce();
});
it("opens connect-src only for declared host.network origins", () => {
const allowed = pluginSandboxDocument("<html><head></head><body></body></html>", ["host.events", "host.network:https://api.vendor.com", "host.network:https://metrics.vendor.com:8443", "host.network:http://insecure.vendor.com", "host.network:https://evil.vendor.com/path"]);
expect(allowed).toContain("connect-src https://api.vendor.com https://metrics.vendor.com:8443;");
@@ -28,6 +28,7 @@ export interface PluginHostBridgeApi {
readAsset(pluginId: string, path: string): Promise<PluginUiAssetPayload>;
openWorkbench?(pluginId: string, contributionId: string, context?: PluginWorkbenchContext): Promise<void> | void;
openFilesystem?(pluginId: string, providerId: string, context?: PluginWorkbenchContext): Promise<void> | void;
closeTab?(): Promise<void> | void;
}
interface PluginRequestMessage {
@@ -68,6 +69,10 @@ export class PluginHostBridge {
this.sendInit();
return true;
}
if (event.data.type === "shortcut" && event.data.shortcut === "closeTab") {
void this.api.closeTab?.();
return true;
}
if (event.data.type !== "request" || !validRequestMessage(event.data)) return false;
void this.handleRequest(event.data, target);
return true;
@@ -397,6 +402,13 @@ function pluginSdkSource(): string {
dispatchEvent(new CustomEvent('dbx-plugin-binary', { detail: payload }));
}
});
addEventListener('keydown', (event) => {
const key = typeof event.key === 'string' ? event.key.toLowerCase() : '';
if (key !== 'w' || (!event.metaKey && !event.ctrlKey) || event.altKey || event.shiftKey || event.isComposing) return;
event.preventDefault();
event.stopPropagation();
parent.postMessage({ source: '${PLUGIN_MESSAGE_SOURCE}', version: ${BRIDGE_VERSION}, type: 'shortcut', shortcut: 'closeTab' }, '*');
}, true);
parent.postMessage({ source: '${PLUGIN_MESSAGE_SOURCE}', version: ${BRIDGE_VERSION}, type: 'ready' }, '*');
})();`;
}