feat: 书库导入导出/图片变体/书籍搜索/小组件运行时等

新增:
- 书库导入导出(library_import/library_export)及测试
- 图片变体生成(image_variants)与响应式图片(responsiveImage)
- 书籍搜索(bookSearch)+ BookSearch/LibrarySearchGrid 组件
- 小组件运行时(widgetRuntime)与静态检查(widgetLint)
- 上传缓存中间件(upload_cache)与字体 CSS 提取脚本

其它:
- 后端 handlers/services 全量调整
- 前端页面、组件、库函数与配置更新
This commit is contained in:
2026-10-01 03:06:05 +08:00
parent 7fbd6ba699
commit ff2ab286fb
141 changed files with 7527 additions and 1407 deletions

View File

@@ -376,6 +376,11 @@ html[data-lv-fx="off"] .lv-text {
hsl(var(--cover-h) 28% 16%);
}
/* 书库页标题:书香气衬线(宋体/楷体回退) */
.j13-library-title {
font-family: "Songti SC", "STSong", "SimSun", "Noto Serif CJK SC", serif;
}
/* 全站悬停即显提示气泡(配合 TipHost + data-tip,替代原生 title 延迟) */
.j13-tip-bubble {
position: fixed;
@@ -2421,14 +2426,23 @@ html.dark .j13-board-trigger.is-invalid .j13-board-trigger-hint {
height: 32px;
padding: 0 8px;
}
/* 窄屏(手机端)编辑工具栏:收成单行核心工具 + 「更多」菜单(评论栏与正文编辑器共用) */
/* 窄屏(手机端)编辑工具栏:收成单行核心工具 + 「更多」菜单(评论栏与正文编辑器共用)。
空间不足时允许「编写/预览」折到第二行,不能让固定宽按钮溢出后与模式切换重叠 */
.j13-md-editor.is-narrow .j13-md-toolbar {
flex-wrap: nowrap;
flex-wrap: wrap;
gap: 2px;
row-gap: 6px;
padding: 2px 0 8px;
}
.j13-md-editor.is-narrow .j13-md-tool-groups {
flex-wrap: nowrap;
/* 默认 min-width:0 会让本组被压缩、内部按钮溢出到模式切换下方;
内容宽度作为最小宽,放不下时把右侧切换挤到下一行 */
min-width: max-content;
}
.j13-md-editor.is-narrow .j13-md-toolbar-end {
/* 单行时左侧 flex-1 已把它顶到右侧;折行后在第二行保持右对齐 */
margin-left: auto;
}
.j13-md-editor.is-narrow .j13-md-tool {
width: 30px;
@@ -6489,29 +6503,23 @@ a.j13-mention-token:hover {
background: var(--accent-soft);
color: var(--accent);
}
.badge-pin {
display: inline-flex;
align-items: center;
gap: 4px;
font-size: 12px;
font-weight: 500;
padding: 4px 11px;
background: var(--clay-soft);
color: var(--clay);
border-radius: 4px;
white-space: nowrap;
}
/* 置顶 / 推荐:图标徽章(无文字,配 title/aria-label),全站统一,节省标题空间 */
.badge-pin,
.badge-rec {
display: inline-flex;
align-items: center;
gap: 4px;
font-size: 12px;
font-weight: 500;
padding: 4px 11px;
justify-content: center;
width: 20px;
height: 20px;
border-radius: 6px;
}
.badge-pin {
background: var(--clay-soft);
color: var(--clay);
}
.badge-rec {
background: var(--gold-soft);
color: var(--gold);
border-radius: 4px;
white-space: nowrap;
}
.badge-pending {
display: inline-flex;
@@ -8206,6 +8214,15 @@ a.j13-mention-token:hover {
}
}
/* 书库全书搜索:正文命中样式由 BookSearch 运行时注入 ::highlight() 规则
(构建器 CSS 压缩器不识别该伪元素);.j13-find-mark 仅用于搜索弹窗片段预览 */
.j13-find-mark {
background: color-mix(in srgb, var(--accent) 24%, transparent);
color: inherit;
border-radius: 3px;
padding: 0 0.1em;
}
/* ============================================================
Markdown 正文
============================================================ */
@@ -8763,6 +8780,14 @@ html.dark .prose-content pre[data-theme] span {
}
}
/* 移动端聚焦评论框(主评论/回复/编辑)时隐藏回顶浮钮:
虚拟键盘弹起后浮钮会贴近输入区造成遮挡与误触,失焦后自动恢复 */
@media (max-width: 1023px) {
body:has(#comments .j13-md-textarea:focus) .j13-back-top {
display: none;
}
}
/* 首页移动端:板块条白底上贴页头(#main 顶部不留白,板块条与帖子框连成一张白纸) */
@media (max-width: 1023px) {
body:has(.j13-fluid-home) #main {
@@ -9284,12 +9309,12 @@ button.cmt-edited {
background: color-mix(in srgb, var(--accent) 18%, transparent);
}
/* 评论内联回复表单:出现在目标评论正下方 */
/* 评论内联回复表单:与楼层块同级全宽显示(DOM 见 CommentSection 列表 map)。
前侧间距由 .cmt-item 的 padding-bottom 提供 */
.cmt-reply-form {
padding: 12px 14px;
border-radius: 14px;
background: var(--panel-2);
margin-top: 8px;
}
/* 评论区编辑器:矮输入区,底栏含提交 */
@@ -9312,12 +9337,32 @@ button.cmt-edited {
flex-wrap: wrap;
}
@container (max-width: 420px) {
/* 手机端评论栏:工具按钮收到 30px(与 is-narrow 一致),「编写/预览」收成图标,
保证核心工具与「更多」单行排开不与模式切换重叠;
极端窄宽(<340px)放不下时,模式切换整体换到第二行而不是压在「更多」上 */
.cmt-md-editor .j13-md-editor.is-comment .j13-md-toolbar {
flex-wrap: wrap;
row-gap: 6px;
}
.cmt-md-editor .j13-md-editor.is-comment .j13-md-tool {
width: 36px;
height: 36px;
width: 30px;
height: 30px;
}
.cmt-md-editor .j13-md-editor.is-comment .j13-md-tool-groups {
flex: 1 0 auto;
min-width: min-content;
}
.cmt-md-editor .j13-md-toolbar-end {
margin-left: auto;
}
.cmt-md-editor .j13-md-mode button {
padding: 0 6px;
width: 30px;
padding: 0;
gap: 0;
justify-content: center;
}
.cmt-md-editor .j13-md-mode-text {
display: none;
}
}
@@ -9943,15 +9988,12 @@ html.j13-reduce-chrome .j13-att-card.is-fresh {
outline-offset: -2px;
}
/* ── 侧栏管理:站长自定义工具容器 ──
/* ── 侧栏管理:站长自定义工具容器(Shadow DOM 宿主) ──
不附加面板底色/边框,视觉完全交给工具自带的 HTML/CSS;
仅保证在侧栏列内不横向溢出。 */
仅保证在侧栏列内不横向溢出,工具内容隔离在 shadow 内(见 widgetRuntime)。 */
.j13-widget-body {
min-width: 0;
}
.j13-widget-body > .j13-widget-html {
min-width: 0;
}
/* ── 抖音表情(douyin-emoji):编辑器弹层面板 / 聊天面板 / 行内图片 ── */
.j13-emoji-picker {