2e14873f2d
Track application source and tests; exclude local env, user workspaces, and runtime data via .gitignore. Co-authored-by: Cursor <cursoragent@cursor.com>
52 lines
2.2 KiB
JavaScript
52 lines
2.2 KiB
JavaScript
function escapeMetaAttribute(value) {
|
|
return String(value ?? '')
|
|
.replaceAll('&', '&')
|
|
.replaceAll('"', '"')
|
|
.replaceAll('<', '<');
|
|
}
|
|
|
|
export function parseMindspaceCoverMeta(html) {
|
|
const tag = String(html).match(/<meta[^>]*name=["']mindspace-cover["'][^>]*>/i)?.[0];
|
|
if (!tag) return null;
|
|
const contentMatch =
|
|
tag.match(/content=(["'])([\s\S]*?)\1/i) ?? tag.match(/content=["']([^"']+)["']/i);
|
|
const raw = contentMatch?.[2] ?? contentMatch?.[1];
|
|
if (!raw) return null;
|
|
try {
|
|
return JSON.parse(raw.replaceAll('"', '"'));
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
export function upsertMindspaceCoverMeta(html, coverMeta) {
|
|
const payload = { ...(parseMindspaceCoverMeta(html) ?? {}), ...coverMeta };
|
|
const metaTag = `<meta name="mindspace-cover" content="${escapeMetaAttribute(JSON.stringify(payload))}">`;
|
|
const source = String(html ?? '');
|
|
|
|
if (/<meta[^>]*name=["']mindspace-cover["'][^>]*>/i.test(source)) {
|
|
return source.replace(/<meta[^>]*name=["']mindspace-cover["'][^>]*>/i, metaTag);
|
|
}
|
|
if (/<head[^>]*>/i.test(source)) {
|
|
return source.replace(/<head([^>]*)>/i, `<head$1>\n ${metaTag}`);
|
|
}
|
|
if (/<html[^>]*>/i.test(source)) {
|
|
return source.replace(/<html([^>]*)>/i, `<html$1><head>${metaTag}</head>`);
|
|
}
|
|
return `<!doctype html><html lang="zh-CN"><head>${metaTag}</head><body>${source}</body></html>`;
|
|
}
|
|
|
|
export function normalizeCoverMetaSuggestion(raw) {
|
|
const payload = raw && typeof raw === 'object' ? raw : {};
|
|
const next = {};
|
|
if (payload.tag != null) next.tag = String(payload.tag).trim().slice(0, 12);
|
|
if (payload.emoji != null) next.emoji = String(payload.emoji).trim().slice(0, 4);
|
|
if (payload.accent != null) next.accent = String(payload.accent).trim();
|
|
if (payload.accent2 != null) next.accent2 = String(payload.accent2).trim();
|
|
if (payload.subtitle != null) next.subtitle = String(payload.subtitle).trim().slice(0, 80);
|
|
if (payload.cover != null) next.cover = String(payload.cover).trim().slice(0, 512);
|
|
if (payload.image != null && !next.cover) next.cover = String(payload.image).trim().slice(0, 512);
|
|
if (payload.mood != null) next.mood = String(payload.mood).trim().slice(0, 24);
|
|
return next;
|
|
}
|