mirror of
https://github.com/openclaw/openclaw.git
synced 2026-10-03 09:39:25 +00:00
* feat(macos): show page favicons on Mac tabs in the chat side panel Mac tabs only showed a favicon when the Gateway's hostname lookup could fetch /favicon.ico, so sites that declare their icon via <link rel=icon> kept the generic Mac icon and a proxy timeout hid it for five minutes. The macOS app now reads the page-declared icon itself: after a main-frame navigation finishes, DashboardNativeBrowserHost runs a generated page script (browser-favicon-script.ts, produced into Swift by the inspect script generator) via callAsyncJavaScript that tries link[rel~=icon], apple-touch-icon, then /favicon.ico with a byte cap and one deadline, and pushes the resulting data URL with tab state. Navigation clears the icon and advances a generation so late results never attach to a new page. The bridge validates the optional favicon field; the hosted-tabs contract's explicit favicon wins over the hostname lookup in the header and in the browser panel's own strip. Agent browser tabs are unchanged. * fix(ci): register native browser script generator with Knip
57 lines
2 KiB
TypeScript
57 lines
2 KiB
TypeScript
#!/usr/bin/env node
|
|
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import { browserFaviconScript } from "../ui/src/components/browser/browser-favicon-script.ts";
|
|
import { browserInspectScript } from "../ui/src/components/browser/browser-inspect-script.ts";
|
|
import { resolveRepoRoot } from "./lib/repo-root.mjs";
|
|
|
|
const args = new Set(process.argv.slice(2));
|
|
if ([...args].some((arg) => arg !== "--check" && arg !== "--write") || args.size > 1) {
|
|
console.error("Use either --check or --write.");
|
|
process.exit(1);
|
|
}
|
|
const repoRoot = resolveRepoRoot(import.meta.url);
|
|
const scripts = [
|
|
{ name: "BrowserInspectScript", file: "browser-inspect-script.ts", source: browserInspectScript },
|
|
{ name: "BrowserFaviconScript", file: "browser-favicon-script.ts", source: browserFaviconScript },
|
|
];
|
|
for (const script of scripts) {
|
|
const outputPath = path.join(
|
|
repoRoot,
|
|
`apps/macos/Sources/OpenClaw/${script.name}.generated.swift`,
|
|
);
|
|
// Avoid both raw-string terminators and Swift interpolation in the page source.
|
|
let delimiter = "#";
|
|
while (script.source.includes(`"""${delimiter}`) || script.source.includes(`\\${delimiter}`)) {
|
|
delimiter += "#";
|
|
}
|
|
const source = script.source
|
|
.split("\n")
|
|
.map((line) => ` ${line}`)
|
|
.join("\n");
|
|
const generated = `// Generated file. Do not edit directly.
|
|
// Source: ui/src/components/browser/${script.file}
|
|
// Regenerate: pnpm gen:browser-inspect-script:swift
|
|
|
|
enum ${script.name} {
|
|
static let source = ${delimiter}"""
|
|
${source}
|
|
"""${delimiter}
|
|
}
|
|
`;
|
|
const current = fs.existsSync(outputPath) ? fs.readFileSync(outputPath, "utf8") : null;
|
|
if (args.has("--check")) {
|
|
if (current !== generated) {
|
|
console.error(
|
|
`Out of date ${path.relative(repoRoot, outputPath)}.\nRun: pnpm gen:browser-inspect-script:swift`,
|
|
);
|
|
process.exit(1);
|
|
}
|
|
console.log(`OK ${path.relative(repoRoot, outputPath)}`);
|
|
} else {
|
|
if (current !== generated) {
|
|
fs.writeFileSync(outputPath, generated);
|
|
}
|
|
console.log(`Wrote ${path.relative(repoRoot, outputPath)}`);
|
|
}
|
|
}
|