feat(reader): PDF 改 pdf.js 渲染+斜体 bug 根治+评论假挂载修复+排版类
【T1 PDF 内置阅读重做】iframe 对 arXiv PDF 实测 ERR_ABORTED(浏览器 PDF
插件策略差异)→ pdfjs-dist 6.4.299 客户端 canvas 渲染:只在 /papers/
动态 import(worker ?url 打包,不进全站 bundle);文档一次取回 + IO
懒渲染(rootMargin 400px)+ 页占位 aspect-ratio 防跳动 + 12s 首屏兜底 +
微信 UA 直接兜底;工具条页码/缩放/翻页/下载/arXiv/授权声明保留。红线:
PDF 由访客浏览器直取 arXiv(CORS * 实测),仓内零副本。真页实测:
13 页 canvas 全绘制、首屏墨迹像素非空、零 console 错误。
【T2 斜体排版 bug 真凶】global.css 的 `.prose-* p > em:only-child
{ display:block; text-align:center }` 图注样式按"斜体独占段"自动命中,
把所有正文独占段斜体变成块级居中。改:图注用显式 .fig-cap 驱动 + 补
em/i { display:inline; font-style:italic } 基线;media-sample 迁移新写法,
指南注明旧写法失效原因。实测独占段与行内斜体均 display:inline/italic。
【T3 评论"假挂载"真 bug】原 initArtalk 一进来就置 mounted=true——脚本
404/被拦截时把空容器误标已挂载,5s 兜底被绕过,正是"评论区一直空着"的
来源之一。改为库就绪才算成功;另加三触发路径(IO 主 + 锚点点击 + 滚到
页底 2s 兜底)、5s 失败提示+重试钮、软导航重挂、成功打
data-artalk-mounted=1 供 E2E。
【T4 文章排版类 + 安全白名单】11 个受限类(ink-1/2/3/muted/accent、
font-serif/kai/sans/mono、drop-cap、quote-line、fig-cap)全走 tokens 禁
任意 hex;新增 rehype-class-whitelist.ts:className 白名单 + 剥离 style
与 on*;实测注入用例只剩 class="ink-2",style/onclick 全无。新坑入档:
markdown raw HTML 在 hast 是 type:'raw' 节点、白名单插件看不见 span,必须
先 rehype-raw 再过滤 → 插件链 [rehypeRaw, rehypeClassWhitelist,
rehypeLinkCards]。新依赖:pdfjs-dist、rehype-raw。
车道:op-artalk(T1 6/6、T2 2/2、T3 3/3、T4 6/6);收编复验:build 46 页、
E2E 37/37、四专项 playwright 实测(PDF 13 canvas/斜体 inline/白名单净化/
评论 mounted 标记)
验证: node v26.13.0 + astro 7.4.4 构建 46 页 exit 0;E2E 37/37 PASS
Spec: none (阅读体验四件,车道级交付)
Co-authored-by: GLM-5.3
This commit is contained in:
1 parent
328ab68f18
commit
280654f9e3
11 files changed
+621
-55
No files matched your search
+41
-2
@@ -146,8 +146,10 @@ pre code { background: none; border: none; padding: 0; font-size: inherit; }
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
/* 图注约定:紧跟媒体的 *斜体独立段* 视为图注(写作指南 docs/写作指南.md) */
|
||||
.prose-reading p > em:only-child, .prose-tech p > em:only-child {
|
||||
/* 图注:**显式类驱动**(`<p class="fig-cap">说明</p>`)。此前按 `p > em:only-child` 自动命中,
|
||||
把正文里任何独占成段的斜体都变成块级居中——用户实测的排版 bug(斜体单独一行并居中)由此而来。 */
|
||||
.prose-reading p.fig-cap, .prose-tech p.fig-cap,
|
||||
.prose-reading p.fig-cap em, .prose-tech p.fig-cap em {
|
||||
display: block;
|
||||
text-align: center;
|
||||
font-size: 0.85em;
|
||||
@@ -155,7 +157,44 @@ pre code { background: none; border: none; padding: 0; font-size: inherit; }
|
||||
color: var(--ink-3);
|
||||
margin-top: -0.6em;
|
||||
margin-bottom: 1.2em;
|
||||
font-style: normal;
|
||||
}
|
||||
/* 行内斜体基线:不换行、不居中(正常强调语义) */
|
||||
.prose-reading em, .prose-tech em,
|
||||
.prose-reading i, .prose-tech i {
|
||||
display: inline;
|
||||
font-style: italic;
|
||||
}
|
||||
/* ── 受限排版类(文章内通过 <span class> 使用;rehype 白名单只放行这些类名) ──
|
||||
颜色一律走 tokens,亮暗双态都可读;禁任意 hex/内联样式(保持灰阶骨架)。 */
|
||||
.prose-reading .ink-1, .prose-tech .ink-1 { color: var(--ink-1); }
|
||||
.prose-reading .ink-2, .prose-tech .ink-2 { color: var(--ink-2); }
|
||||
.prose-reading .ink-3, .prose-tech .ink-3 { color: var(--ink-3); }
|
||||
.prose-reading .ink-muted, .prose-tech .ink-muted { color: var(--ink-4); }
|
||||
.prose-reading .ink-accent, .prose-tech .ink-accent { color: var(--accent); }
|
||||
.prose-reading .font-serif, .prose-tech .font-serif { font-family: var(--font-serif); }
|
||||
.prose-reading .font-kai, .prose-tech .font-kai { font-family: var(--font-kai); }
|
||||
.prose-reading .font-sans, .prose-tech .font-sans { font-family: var(--font-sans); }
|
||||
.prose-reading .font-mono, .prose-tech .font-mono { font-family: var(--font-mono); font-size: 0.92em; }
|
||||
/* 文学常用:首字下沉(书评开篇)与金句块(引文式的独立强调段) */
|
||||
.prose-reading p.drop-cap::first-letter, .prose-tech p.drop-cap::first-letter {
|
||||
float: left;
|
||||
font-family: var(--font-serif);
|
||||
font-size: 3.1em;
|
||||
line-height: 1;
|
||||
padding-right: 0.08em;
|
||||
margin-top: 0.05em;
|
||||
color: var(--paper-ink);
|
||||
}
|
||||
.prose-reading .quote-line, .prose-tech .quote-line {
|
||||
display: block;
|
||||
font-family: var(--font-kai);
|
||||
color: var(--paper-ink);
|
||||
border-left: 2px solid var(--paper-line);
|
||||
padding-left: 0.9em;
|
||||
margin: 1.4em 0;
|
||||
}
|
||||
|
||||
/* 视频与音频:原生标签,markdown raw HTML 直书(指南有模板) */
|
||||
.prose-reading video, .prose-tech video,
|
||||
.prose-reading audio, .prose-tech audio {
|
||||
|
||||
Reference in new issue
Block a user