Files
blog/public/admin/preview-style.js
T
wait4xandGLM-5.3 b99e6e744b chore(spec): 归档 blog-5l——三任务收敛(预览一致性/排版提醒/瞬间置顶隐藏)
Spec: 2026-11-05_blog-5l-admin-preview-moments

Co-authored-by: GLM-5.3
2026-11-05 10:03:34 +08:00

56 lines
2.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 后台预览一致性(5l T1):把站点排版效果注入 Sveltia 预览窗格。
*
* 现状问题:markdown 里的排版类(font- 字体、c-/ink- 颜色)在预览里是素文本——
* 类名随 DOM 保留(typography-editor 的 toPreview 输出带 class),但预览
* 文档没有站点 CSS,颜色字体全部不可见。
*
* 方案(官方口子,勿改成 iframe hack——见 spec 5l §2.5):
* 1. 基础富文本排版 + 全部排版类 CSS 从 window.TYPOGRAPHY_CLASSES
* **运行时生成**(清单单一事实源:typography-classes.js 改一处,
* 选择面板与预览自动同步),raw 模式注入;
* 2. 自托管艺术字体挂切片 CSS(public/fonts/<family>/fonts.css,
* unicode-range 按需取片——预览里只拉用到的字所落在的切片,不整包)。
*
* serif/kai/kuaile 的 CSS 经 Vite ?url 打包成哈希名,后台引不到稳定 URL,
* 预览走字体栈里的系统回退(Kaiti SC/Songti)——近似可见,文档已注明。
* 加载顺序:须在 typography-classes.js 之后、CMS init 之前(index.html 固定序)。
*/
(function () {
const CLASSES = window.TYPOGRAPHY_CLASSES;
if (!CLASSES || !window.CMS || !window.CMS.registerPreviewStyle) return;
/** 预览基调:近似站点 .rich 的通用排版(目标是类效果可见,非像素级还原) */
const baseCss = [
'p{margin:.6em 0;line-height:1.75}',
'h1,h2,h3,h4{font-weight:600;line-height:1.4;margin:1.2em 0 .5em}',
'h2{font-size:1.3em}h3{font-size:1.15em}',
'ul,ol{padding-left:1.5em;margin:.6em 0}li{margin:.25em 0}',
'a{color:#3454d1;text-decoration:underline}',
'blockquote{margin:.8em 0;padding:.2em 1em;border-left:3px solid #e6e7eb;color:#6b6e78}',
"code{font-family:'JetBrains Mono',ui-monospace,monospace;font-size:.92em;background:#f2f3f5;padding:.1em .35em;border-radius:4px}",
'img{max-width:100%}',
'hr{border:none;border-top:1px solid #e6e7eb;margin:1.5em 0}',
'strong{font-weight:700}',
].join('');
/** 排版类规则:清单驱动(swatch/ family 即预览所用值,亮态口径) */
const rules = [];
for (const f of CLASSES.font || []) {
if (f.family) rules.push(`.${f.cls}{font-family:${f.family}}`);
}
for (const c of CLASSES.color || []) {
if (c.swatch) rules.push(`.${c.cls}{color:${c.swatch}}`);
}
window.CMS.registerPreviewStyle(baseCss + rules.join(''), { raw: true });
// 字体切片(URL 模式):预览文档自己的 @font-face;去重后逐个挂
const seen = new Set();
for (const f of CLASSES.font || []) {
if (!f.css || seen.has(f.css)) continue;
seen.add(f.css);
window.CMS.registerPreviewStyle(f.css);
}
})();