feat(desktop): deliver font settings to plugin sandboxes
This commit is contained in:
1 parent
ba6b74beea
commit
b1b99eccfb
15 files changed
+309
-25
No files matched your search
+20
-1
@@ -1,5 +1,5 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { buildPluginAppearance, FALLBACK_APPEARANCE_COLORS, readAppearanceTokens } from "./pluginAppearance";
|
||||
import { buildPluginAppearance, buildPluginEditorAppearance, FALLBACK_APPEARANCE_COLORS, readAppearanceTokens } from "./pluginAppearance";
|
||||
|
||||
describe("buildPluginAppearance", () => {
|
||||
it("uses the pearl (white) fallback tokens for light and the .dark tokens for dark", () => {
|
||||
@@ -32,3 +32,22 @@ describe("buildPluginAppearance", () => {
|
||||
expect(() => readAppearanceTokens()).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe("buildPluginEditorAppearance", () => {
|
||||
it("carries the editor font family, size and SQL syntax theme", () => {
|
||||
expect(buildPluginEditorAppearance({ fontFamily: "Fira Code", fontSize: 13, theme: "one-dark" })).toEqual({
|
||||
fontFamily: "Fira Code",
|
||||
fontSize: 13,
|
||||
theme: "one-dark",
|
||||
});
|
||||
});
|
||||
|
||||
it("returns undefined unless every field is usable (no partial snapshots)", () => {
|
||||
expect(buildPluginEditorAppearance({})).toBeUndefined();
|
||||
expect(buildPluginEditorAppearance({ fontFamily: "Fira Code" })).toBeUndefined();
|
||||
expect(buildPluginEditorAppearance({ fontFamily: "Fira Code", fontSize: 13 })).toBeUndefined();
|
||||
expect(buildPluginEditorAppearance({ fontFamily: "Fira Code", fontSize: 0, theme: "one-dark" })).toBeUndefined();
|
||||
expect(buildPluginEditorAppearance({ fontFamily: "Fira Code", fontSize: Number.NaN, theme: "one-dark" })).toBeUndefined();
|
||||
expect(buildPluginEditorAppearance({ fontFamily: " ", fontSize: 13, theme: "one-dark" })).toBeUndefined();
|
||||
});
|
||||
});
|
||||
@@ -1,6 +1,11 @@
|
||||
// 插件沙箱外观快照:读取 DBX 根节点的设计令牌(随 .dark / 调色板类
|
||||
// 实时变化)加编辑器字体设置,组装成插件契约里的 appearance 对象,
|
||||
// 供 PluginHostBridge 在 init 下发、主题变化时实时推送。
|
||||
// 插件沙箱外观契约与快照工具:PluginAppearance 描述宿主下发的 appearance
|
||||
// 对象(1.0 部分下发、1.1 theme 通道只带颜色令牌);buildPluginAppearance
|
||||
// 组装快照,buildPluginEditorAppearance 产出结构化 editor 字段。实际推送
|
||||
// 链路在 PluginWorkbenchHost.currentBridgeTheme → PluginHostBridge.updateTheme。
|
||||
|
||||
import type { PluginEditorAppearance } from "./pluginHostBridge";
|
||||
|
||||
export type { PluginEditorAppearance } from "./pluginHostBridge";
|
||||
|
||||
export interface PluginAppearanceColors {
|
||||
background: string;
|
||||
@@ -16,8 +21,26 @@ export interface PluginAppearanceColors {
|
||||
export interface PluginAppearance {
|
||||
colorScheme: "light" | "dark";
|
||||
colors: PluginAppearanceColors;
|
||||
// terminal.fontFamily comes from the host's --font-mono token. It is a
|
||||
// mirror of the editor font for read-only following; terminal.fontSize is
|
||||
// NOT delivered and stays plugin-owned (the SSH terminal, for one, has its
|
||||
// own zoom that persists per workbench). The full editor settings — family,
|
||||
// size and SQL syntax theme — are delivered structured as `editor`.
|
||||
terminal: { fontFamily: string; fontSize: number };
|
||||
ui?: { fontFamily: string };
|
||||
editor?: PluginEditorAppearance;
|
||||
}
|
||||
|
||||
/** Structured editor appearance for the bridge theme: SQL editor settings that
|
||||
* have no CSS-token carrier (the size is a number, the syntax theme an id).
|
||||
* Returns undefined unless every field is usable, so snapshots for hosts with
|
||||
* incomplete settings stay unchanged instead of carrying partial data. */
|
||||
export function buildPluginEditorAppearance(editor: { fontFamily?: string; fontSize?: number; theme?: string }): PluginEditorAppearance | undefined {
|
||||
const fontFamily = typeof editor.fontFamily === "string" && editor.fontFamily.trim() ? editor.fontFamily : undefined;
|
||||
const fontSize = typeof editor.fontSize === "number" && Number.isFinite(editor.fontSize) && editor.fontSize > 0 ? editor.fontSize : undefined;
|
||||
const theme = typeof editor.theme === "string" && editor.theme.trim() ? editor.theme : undefined;
|
||||
if (!fontFamily || fontSize === undefined || !theme) return undefined;
|
||||
return { fontFamily, fontSize, theme };
|
||||
}
|
||||
|
||||
// camelCase 字段 → DBX globals.css 的 CSS 令牌名。
|
||||
|
||||
@@ -490,6 +490,11 @@ describe("PluginHostBridge", () => {
|
||||
|
||||
bridge.updateTheme({ appearance: "light", tokens: {} });
|
||||
expect(messages[1]).toMatchObject({ type: "env", locale: "en", theme: { appearance: "light", tokens: {} } });
|
||||
|
||||
// The structured editor snapshot rides along on every theme push.
|
||||
const editor = { fontFamily: "Fira Code", fontSize: 13, theme: "one-dark" };
|
||||
bridge.updateTheme({ appearance: "light", tokens: {}, editor });
|
||||
expect(messages[2]).toMatchObject({ type: "env", locale: "en", theme: { appearance: "light", tokens: {}, editor } });
|
||||
});
|
||||
|
||||
it("routes host.saveFile transfers through the host save dialog and reports cancellation", async () => {
|
||||
|
||||
@@ -10,10 +10,21 @@ const MAX_BRIDGE_BINARY_BYTES = 8 * 1024 * 1024;
|
||||
// plugin iframe to disk and never traverse plugin frames.
|
||||
const MAX_BRIDGE_SAVE_BYTES = 512 * 1024 * 1024;
|
||||
|
||||
/** Structured editor appearance: SQL editor settings that have no CSS-token
|
||||
* carrier (font size is a number, the syntax theme an id). Font families are
|
||||
* additionally mirrored as `--font-sans` / `--font-mono` root tokens. */
|
||||
export interface PluginEditorAppearance {
|
||||
fontFamily: string;
|
||||
fontSize: number;
|
||||
theme: string;
|
||||
}
|
||||
|
||||
export interface PluginBridgeTheme {
|
||||
appearance: "light" | "dark";
|
||||
/** Resolved DBX design tokens (`--color-*`, `--radius-*`, ...) for the current theme. */
|
||||
/** Resolved DBX design tokens (`--color-*`, `--radius-*`, `--font-*`, ...) for the current theme. */
|
||||
tokens: Record<string, string>;
|
||||
/** Editor appearance snapshot. Optional: older in-flight snapshots omit it. */
|
||||
editor?: PluginEditorAppearance;
|
||||
}
|
||||
|
||||
export interface PluginWorkbenchContext {
|
||||
|
||||
Reference in new issue
Block a user