思源笔记 v3.1.15 深度解析:鸿蒙系统支持、数据库增强与开发者 API 扩展
【免费下载链接】siyuanAn open-source, privacy-first, self-hosted knowledge workspace where humans and AI agents work together 开源、隐私优先、自托管的知识工作空间,让人与智能体在此协作项目地址: https://gitcode.com/GitHub_Trending/si/siyuan
导读
思源笔记(SiYuan)v3.1.15 是 3.1.x 系列中一个里程碑式的版本,核心亮点是正式支持鸿蒙(HarmonyOS)系统,并围绕数据库(属性视图)、编辑器交互、搜索与导出等高频场景进行了大量打磨。本文以官方变更记录为主线,结合仓库源码逐项剖析各改进背后的实现原理,帮助开发者理解鸿蒙端内核的启动链路、/api/filetree/moveDocsByID新 API 的调用约定,以及Protyle.disable/enable等插件能力的底层机制,同时为普通用户梳理 v3.1.15 带来的实操价值。
一、鸿蒙系统支持:内核如何跨端启动
v3.1.15 的最大变化是新增对鸿蒙系统的支持(对应 issue #13184)。思源的知识库数据以标准 Markdown 格式存储,内核采用 Go 编写,这使得同一套内核逻辑可以借助 cgo 编译为不同移动平台的动态库,鸿蒙支持正是沿用了这一跨端架构。
在仓库中可以看到专为鸿蒙准备的编译入口 kernel/harmony/kernel.go:它通过//export注解向鸿蒙侧(ArkTS/NAPI)导出 Go 函数,核心启动函数StartKernel的调用链为:
SetTimezone依据时区 ID 设置time.Local,失败时回退到CST(东八区);- 设置
util.Mode = "prod"、记录鸿蒙系统版本号与本地 IP 列表; - 调用
util.BootMobile完成移动端工作空间与资源初始化; model.InitConf()加载配置;- 启动
server.Serve(false, ...)提供 HTTP API 服务; - 在后台 goroutine 中依次完成外观初始化、数据库(含历史库、资源内容库)建库、同步数据引导、笔记本装载、闪卡加载与定时任务启动。
与 Android/iOS 端的 kernel/mobile/kernel.go 相比,鸿蒙入口保持了几乎一致的初始化顺序,区别在于通过StartKernelFast提供了快速启动模式(仅起 HTTP 服务),以及GetExportFilePath中对加密导出路径增加了受控注册表校验与路径穿越防护(path traversal拦截、IsSubPath边界检查),体现了移动端导出安全性的统一收敛。
实操提示:鸿蒙版本的使用体验与移动端保持一致,数据可通过思源账号或 WebDAV 等同步方式与桌面端互通;由于内核是同一套,桌面端创建的文档、数据库在鸿蒙端无需任何转换即可直接读写。
二、数据库(属性视图)增强
v3.1.15 针对数据库做了四项改进,覆盖单元格定位、输入、年份解析与描述交互。
2.1 单元格定位与编辑输入框大小(#12708)
此改进优化了点击数据库单元格时的定位精度以及编辑输入框的尺寸表现,尤其对长文本、日期等类型在窄屏(移动端/鸿蒙端)下的编辑体验影响明显。相关渲染逻辑集中在 app/src/protyle/render/av 目录,其中日期等单元格的展示统一由dayjs按YYYY-MM-DD(纯日期)或YYYY-MM-DD HH:mm(含时间)格式输出(见 cell.ts),输入框的宽度与位置计算直接决定了编辑时是否遮挡相邻列。
2.2 支持少于 4 位的年份(#13252)
此前数据库日期字段只支持四位年份,输入999、99这类短年份时会异常。本次改进在前后端同时放开了限制:
- 前端渲染层使用
dayjs解析内容并格式化,短年份能够被正确识别; - 内核侧 kernel/av/value.go 通过
contentTime.Format("2006-01-02")/"2006-01-02 15:04"输出规范化的日期字符串,同时 kernel/av/filter.go 中基于time.Date的日期过滤与相对日期(年/月/周/日)计算对任意年份值均能正确推导区间。
使用建议:历史文献、纪元前年份等场景现在可以放心录入,无需补齐前导零。
2.3 描述交互改进(#13262)与移除当前块(#13375)
- 描述交互:优化了数据库描述(简介)的添加与编辑流程,交互更跟手;
- 属性面板支持移除当前块:在文档属性面板的数据库视图中,可直接将当前块从数据库移除,底层通过块操作事务完成,相关块操作封装见 kernel/api/block_op.go。
三、编辑器与交互体验改进
3.1 粘贴时移除折叠标题的折叠状态(#13232)
此前将折叠标题下的内容复制粘贴到新位置后,粘贴出的标题会保留折叠标记,导致新位置出现"内容被隐藏"的困惑。修复方案是在编辑器事务处理折叠标题操作(action === "foldHeading")时,对折叠节点调用removeFoldHeading(item)(见 app/src/protyle/wysiwyg/transaction.ts)。
removeFoldHeading的实现位于 app/src/protyle/util/heading.ts:它读取标题的data-subtype获取标题级别,然后遍历后续兄弟节点,凡属于该标题子级(级别更深)的节点一律移除,直到遇到同级别或更高级别的节点为止——这正是"展开标题并剥离其被折叠子树"的标准做法。
3.2 Alt+M 隐藏/显示窗口(#12656)
改进后Alt+M快捷键在桌面端可快速隐藏/显示主窗口,便于临时让出屏幕空间。该快捷键由内核快捷键配置驱动,相关配置定义见 kernel/model/shortcuts.go,用户可在"设置 → 快捷键"中自定义触发键。
3.3 其他交互打磨
- 文档标签添加交互(#13311):优化了标签输入与确认流程;
- 工具提示改进(#13326):统一了 hover 提示的显示时机与位置,避免遮挡内容;
- 改进设置外观优先级(#13404):外观相关配置(主题、字体、图标等)的加载优先级更加明确;
- 改进系统字体加载(#13356):优化了系统字体枚举与回退策略;
- Linux 鼠标中键关闭标签页误触发粘贴修复(#13395):修复了中键关闭标签页时误触发粘贴事件的问题。
四、搜索、剪藏与导出改进
4.1 搜索相关(#13343、#13348、#13364)
- 搜索高亮改进(#13343):优化了匹配文本的高亮渲染,减少多关键词、长文本场景下的样式错位;高亮逻辑集中在 app/src/search/util.ts,通过
mark/markHL维护 Range 集合,并配合highlightById实现结果定位; - 模板搜索改进(#13348):模板弹窗内的搜索匹配更准确;
- 简化搜索结果中的文档块路径(#13364):去掉了冗余路径层级,结果列表更清爽;
- HTML 标签搜索转义问题修复(#13354):修复了搜索
<div>这类 HTML 标签时转义不当导致的漏匹配; - 点击行级标签后未找到结果修复(#13351):行级标签(行内标签)点击跳转搜索不再落空。
4.2 剪藏与浏览器扩展(#13355、#13366)
- HTML 剪藏改进:优化了网页正文提取的整洁度,减少无用标签残留;
- 浏览器剪藏扩展新增实验性功能:剪藏扩展(Web Clipper)在 v3.1.15 中引入若干实验性能力,需在扩展设置中手动开启。
4.3 导出改进(#13331、#13349、#13365)
- 导出块引用改进(#13331):优化了块引用的导出呈现(如引用块编号与锚文本);
- 导出 PDF 时代码块分页(#13349):长代码块在 PDF 分页时不再被生硬截断;
- 修复导出 .docx 有序列表序号不正确(#13365):修复了嵌套有序列表在 Word 文档中的编号错乱。
4.4 音频与资源支持(#13386、#13368、#13388)
- 支持 flac 音频播放:内核在 kernel/util/path.go 中维护的资源类型白名单
SiYuanAssetsAudio由{".mp3", ".wav", ".ogg", ".m4a"}扩展为包含".flac",此后 flac 文件会被正确识别为音频资源并在编辑器中以内嵌音频块播放; - 修复以
.结尾的文件名被视为缺失资源(#13368):修复了资源名以点结尾时的误判; - 修复图像 URL 含
%时无法双击预览(#13388):修复了带百分号编码的网络图片无法放大预览的问题。
五、同步与移动端缺陷修复
v3.1.15 修复了若干数据可靠性问题:
- 完全手动同步模式导致数据冲突(#13387):在"完全手动"同步策略下,修复了可能产生数据冲突的场景,建议仍以默认自动同步为主;
- 移动端数据历史文档下滑时被关闭(#13347):修复了移动端数据历史列表中滑动浏览文档时的异常关闭。
六、开发者:新增 API 与 Protyle 扩展点
6.1 新内核 API:/api/filetree/moveDocsByID(#13247)
该版本为开发者新增了按 ID 移动文档的内核 API,与既有/api/filetree/moveDocs(按路径移动)互补。其实现位于 kernel/api/filetree.go,处理流程为:
- 解析请求参数
fromIDs(文档 ID 数组)与toID(目标文档 ID 或笔记本 ID); - 逐一校验 ID 合法性(
InvalidIDPattern),并通过model.LoadTreeByBlockID将每个 ID 解析为文档树; - 对
fromIDs去重后得到fromPaths; - 目标侧:若
toID是文档,则取其所在笔记本与路径;若toID是笔记本,则以笔记本根目录"/"为目标; - 最终调用
model.MoveDocs(fromPaths, toNotebook, toPath, callback)完成移动,失败时返回closeTimeout: 7000提示前端延迟关闭弹窗。
请求示例:
{ "fromIDs": ["20210808180117-6v0mkxr", "20211226090932-5lcq56f"], "toID": "20230405172236-pg3l9eu" }该 API 尤其适合插件在只知道块 ID、不知道具体路径的场景下批量整理文档。
6.2 Protyle 新增disable/enable方法(#13391)
前端 Protyle 类新增了两个公开方法(见 app/src/protyle/index.ts),插件可据此在运行时冻结/恢复编辑器交互:
protyle.disable():调用disabledProtyle,隐藏 gutter、工具栏、选区、提示等 UI 元素,设置contenteditable="false",并锁定面包屑的撤销/重做按钮(详见 app/src/protyle/util/onGet.ts);protyle.enable():调用enableProtyle反向恢复,但若元素带有disabled-forever="true"标记则保持禁用;移动端还会处理输入法弹出相关的readonly切换(详见 app/src/protyle/util/onGet.ts)。
典型用法:在自定义渲染(如幻灯片、演示模式)或需要短暂禁止用户输入时调用disable(),退出时调用enable()即可无损恢复。
6.3 其他开发者向变更
- 改进选区后按键行为(#13027):选择块或表格单元格后,
Backspace、Delete、Tab、Shift+Tab的操作语义更稳定,避免误删或意外跳格; - 移除编辑器输入控制台日志(#13346):清理了编辑器输入路径上的调试日志,降低性能开销。
七、总结
思源笔记 v3.1.15 通过鸿蒙系统支持打通了又一条移动端战线(内核入口见 kernel/harmony/kernel.go),同时以数据库、编辑器、搜索、导出与同步的 20 余项改进夯实了日常使用体验。对开发者而言,/api/filetree/moveDocsByID与Protyle.disable/enable提供了更便捷的文档整理与编辑器控制能力;对普通用户而言,短年份日期、flac 音频、折叠粘贴等细节修复让数据录入与整理更加顺畅。该版本是 3.1.x 分支上兼顾功能扩展与稳定性收敛的代表性版本,建议所有思源用户升级体验。
【免费下载链接】siyuanAn open-source, privacy-first, self-hosted knowledge workspace where humans and AI agents work together 开源、隐私优先、自托管的知识工作空间,让人与智能体在此协作项目地址: https://gitcode.com/GitHub_Trending/si/siyuan
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考