统一登录、工作区、待办、设置和管理页面的视觉语言,补充 Markdown 预览、皮肤切换及移动端体验。 Co-Authored-By: Codex <noreply@anthropic.com>
55 lines
1.6 KiB
TypeScript
55 lines
1.6 KiB
TypeScript
import DOMPurify from "dompurify";
|
|
import type { PageMeta } from "@silverbulletmd/silverbullet/type/index";
|
|
import { encodePageURI } from "@silverbulletmd/silverbullet/lib/ref";
|
|
import {
|
|
isLocalURL,
|
|
resolveMarkdownLink,
|
|
} from "@silverbulletmd/silverbullet/lib/resolve";
|
|
import { parseMarkdown } from "../markdown_parser/parser.ts";
|
|
import { renderMarkdownToHtml } from "../markdown_renderer/markdown_render.ts";
|
|
import { fsEndpoint } from "../spaces/constants.ts";
|
|
|
|
type Sanitize = (html: string) => string;
|
|
|
|
export function resolvePlainleafPreviewUrl(
|
|
currentPage: string,
|
|
baseUrl: string,
|
|
url: string,
|
|
type: "link" | "image",
|
|
): string {
|
|
if (!isLocalURL(url)) return url;
|
|
const mediaPrefix = `${fsEndpoint.slice(1)}/`;
|
|
const sourceUrl =
|
|
type === "image" && url.startsWith(mediaPrefix)
|
|
? url.slice(mediaPrefix.length)
|
|
: url;
|
|
const path = resolveMarkdownLink(currentPage, decodeURI(sourceUrl));
|
|
if (type === "image") {
|
|
return `${baseUrl.replace(/\/*$/, "")}${fsEndpoint}/${encodePageURI(path)}`;
|
|
}
|
|
return path;
|
|
}
|
|
|
|
export function renderPlainleafMarkdownPreview(
|
|
text: string,
|
|
allPages: PageMeta[],
|
|
translateUrls: (url: string, type: "link" | "image") => string,
|
|
sanitize: Sanitize = (html) =>
|
|
DOMPurify.sanitize(html, {
|
|
USE_PROFILES: { html: true },
|
|
FORBID_TAGS: ["script", "style", "iframe", "object", "embed"],
|
|
FORBID_ATTR: ["srcdoc"],
|
|
}),
|
|
): string {
|
|
const html = renderMarkdownToHtml(
|
|
parseMarkdown(text),
|
|
{
|
|
smartHardBreak: true,
|
|
shortWikiLinks: true,
|
|
translateUrls,
|
|
},
|
|
allPages,
|
|
);
|
|
return sanitize(html);
|
|
}
|