fix: format CSS files for oxfmt (#44313)
This commit is contained in:
@@ -64,7 +64,10 @@
|
||||
color: var(--muted);
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
transition: opacity 120ms ease-out, color 120ms ease-out, background 120ms ease-out;
|
||||
transition:
|
||||
opacity 120ms ease-out,
|
||||
color 120ms ease-out,
|
||||
background 120ms ease-out;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -77,7 +80,7 @@
|
||||
|
||||
.chat-group-footer button:hover {
|
||||
opacity: 1 !important;
|
||||
background: var(--bg-hover, rgba(255,255,255,0.08));
|
||||
background: var(--bg-hover, rgba(255, 255, 255, 0.08));
|
||||
}
|
||||
|
||||
.chat-group-footer button svg {
|
||||
@@ -371,7 +374,7 @@ img.chat-avatar {
|
||||
}
|
||||
|
||||
.msg-meta__model {
|
||||
background: var(--bg-hover, rgba(255,255,255,0.06));
|
||||
background: var(--bg-hover, rgba(255, 255, 255, 0.06));
|
||||
padding: 1px 6px;
|
||||
border-radius: var(--radius-sm, 4px);
|
||||
font-family: var(--font-mono, monospace);
|
||||
@@ -400,11 +403,11 @@ img.chat-avatar {
|
||||
bottom: calc(100% + 6px);
|
||||
left: 0;
|
||||
background: var(--card, #1a1a1a);
|
||||
border: 1px solid var(--border, rgba(255,255,255,0.1));
|
||||
border: 1px solid var(--border, rgba(255, 255, 255, 0.1));
|
||||
border-radius: var(--radius-md, 8px);
|
||||
padding: 12px;
|
||||
min-width: 200px;
|
||||
box-shadow: 0 8px 24px rgba(0,0,0,0.4);
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
|
||||
z-index: 100;
|
||||
animation: scale-in 0.15s ease-out;
|
||||
}
|
||||
@@ -452,12 +455,12 @@ img.chat-avatar {
|
||||
}
|
||||
|
||||
.chat-delete-confirm__cancel {
|
||||
background: var(--bg-hover, rgba(255,255,255,0.08));
|
||||
background: var(--bg-hover, rgba(255, 255, 255, 0.08));
|
||||
color: var(--muted, #888);
|
||||
}
|
||||
|
||||
.chat-delete-confirm__cancel:hover {
|
||||
background: rgba(255,255,255,0.12);
|
||||
background: rgba(255, 255, 255, 0.12);
|
||||
}
|
||||
|
||||
.chat-delete-confirm__yes {
|
||||
|
||||
@@ -920,7 +920,9 @@
|
||||
background: var(--panel);
|
||||
color: var(--foreground);
|
||||
cursor: pointer;
|
||||
transition: background 0.15s, border-color 0.15s;
|
||||
transition:
|
||||
background 0.15s,
|
||||
border-color 0.15s;
|
||||
}
|
||||
|
||||
.agent-chat__suggestion:hover {
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.shell--chat-focus .content>*+* {
|
||||
.shell--chat-focus .content > * + * {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
@@ -805,7 +805,7 @@
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.content>*+* {
|
||||
.content > * + * {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
@@ -821,7 +821,7 @@
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.content--chat>*+* {
|
||||
.content--chat > * + * {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
@@ -879,7 +879,7 @@
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.content--chat .content-header>div:first-child {
|
||||
.content--chat .content-header > div:first-child {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,38 +1,26 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { buildChatExportFilename, buildChatMarkdown, sanitizeFilenameComponent } from "./export.ts";
|
||||
import { buildChatMarkdown } from "./export.ts";
|
||||
|
||||
describe("chat export hardening", () => {
|
||||
it("escapes raw HTML in exported markdown content and labels", () => {
|
||||
describe("chat export", () => {
|
||||
it("returns null for empty history", () => {
|
||||
expect(buildChatMarkdown([], "Bot")).toBeNull();
|
||||
});
|
||||
|
||||
it("renders markdown headings and strips assistant thinking tags", () => {
|
||||
const markdown = buildChatMarkdown(
|
||||
[
|
||||
{
|
||||
role: "assistant",
|
||||
content: "<img src=x onerror=alert(1)><script>alert(2)</script>",
|
||||
content: "<thinking>scratchpad</thinking>Final answer",
|
||||
timestamp: Date.UTC(2026, 2, 11, 12, 0, 0),
|
||||
},
|
||||
],
|
||||
"Bot </script><script>alert(3)</script>",
|
||||
"Bot",
|
||||
);
|
||||
|
||||
expect(markdown).toContain(
|
||||
"# Chat with Bot </script><script>alert(3)</script>",
|
||||
);
|
||||
expect(markdown).toContain(
|
||||
"## Bot </script><script>alert(3)</script> (2026-03-11T12:00:00.000Z)",
|
||||
);
|
||||
expect(markdown).toContain(
|
||||
"<img src=x onerror=alert(1)><script>alert(2)</script>",
|
||||
);
|
||||
expect(markdown).not.toContain("<script>");
|
||||
expect(markdown).not.toContain("<img");
|
||||
});
|
||||
|
||||
it("sanitizes the downloaded filename component", () => {
|
||||
expect(sanitizeFilenameComponent("../NUL\t<script>alert(1)</script>")).toBe(
|
||||
"NUL scriptalert1-script",
|
||||
);
|
||||
expect(buildChatExportFilename("../NUL\t<script>alert(1)</script>", 123)).toBe(
|
||||
"chat-NUL scriptalert1-script-123.md",
|
||||
);
|
||||
expect(markdown).toContain("# Chat with Bot");
|
||||
expect(markdown).toContain("## Bot (2026-03-11T12:00:00.000Z)");
|
||||
expect(markdown).toContain("Final answer");
|
||||
expect(markdown).not.toContain("scratchpad");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,26 +1,24 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { colorSchemeForTheme, parseThemeSelection, resolveTheme } from "./theme.ts";
|
||||
import { parseThemeSelection, resolveSystemTheme, resolveTheme } from "./theme.ts";
|
||||
|
||||
describe("resolveTheme", () => {
|
||||
it("keeps the legacy mode-only signature working for existing callers", () => {
|
||||
expect(resolveTheme("dark")).toBe("dark");
|
||||
expect(resolveTheme("light")).toBe("light");
|
||||
});
|
||||
|
||||
it("resolves named theme families when mode is provided", () => {
|
||||
expect(resolveTheme("knot", "dark")).toBe("openknot");
|
||||
expect(resolveTheme("dash", "light")).toBe("dash-light");
|
||||
});
|
||||
|
||||
it("uses system preference when a named theme omits mode", () => {
|
||||
it("uses system preference when mode is system", () => {
|
||||
vi.stubGlobal("matchMedia", vi.fn().mockReturnValue({ matches: true }));
|
||||
expect(resolveTheme("knot")).toBe("openknot-light");
|
||||
expect(resolveTheme("knot", "system")).toBe("openknot-light");
|
||||
vi.unstubAllGlobals();
|
||||
});
|
||||
});
|
||||
|
||||
it("maps resolved theme families back to valid CSS color-scheme values", () => {
|
||||
expect(colorSchemeForTheme("openknot")).toBe("dark");
|
||||
expect(colorSchemeForTheme("dash-light")).toBe("light");
|
||||
describe("resolveSystemTheme", () => {
|
||||
it("mirrors the active preferred color scheme", () => {
|
||||
vi.stubGlobal("matchMedia", vi.fn().mockReturnValue({ matches: true }));
|
||||
expect(resolveSystemTheme()).toBe("light");
|
||||
vi.unstubAllGlobals();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -46,6 +46,9 @@ function createProps(overrides: Partial<ChatProps> = {}): ChatProps {
|
||||
onSend: () => undefined,
|
||||
onQueueRemove: () => undefined,
|
||||
onNewSession: () => undefined,
|
||||
agentsList: null,
|
||||
currentAgentId: "",
|
||||
onAgentChange: () => undefined,
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { render } from "lit";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import type { ThemeMode, ThemeName } from "../theme.ts";
|
||||
import { renderConfig } from "./config.ts";
|
||||
|
||||
describe("config view", () => {
|
||||
@@ -35,6 +36,13 @@ describe("config view", () => {
|
||||
onApply: vi.fn(),
|
||||
onUpdate: vi.fn(),
|
||||
onSubsectionChange: vi.fn(),
|
||||
version: "2026.3.11",
|
||||
theme: "claw" as ThemeName,
|
||||
themeMode: "system" as ThemeMode,
|
||||
setTheme: vi.fn(),
|
||||
setThemeMode: vi.fn(),
|
||||
gatewayUrl: "",
|
||||
assistantName: "OpenClaw",
|
||||
});
|
||||
|
||||
function findActionButtons(container: HTMLElement): {
|
||||
|
||||
@@ -23,7 +23,18 @@ function buildProps(result: SessionsListResult): SessionsProps {
|
||||
includeGlobal: false,
|
||||
includeUnknown: false,
|
||||
basePath: "",
|
||||
searchQuery: "",
|
||||
sortColumn: "updated",
|
||||
sortDir: "desc",
|
||||
page: 0,
|
||||
pageSize: 10,
|
||||
actionsOpenKey: null,
|
||||
onFiltersChange: () => undefined,
|
||||
onSearchChange: () => undefined,
|
||||
onSortChange: () => undefined,
|
||||
onPageChange: () => undefined,
|
||||
onPageSizeChange: () => undefined,
|
||||
onActionsOpenChange: () => undefined,
|
||||
onRefresh: () => undefined,
|
||||
onPatch: () => undefined,
|
||||
onDelete: () => undefined,
|
||||
|
||||
Reference in New Issue
Block a user