Repository navigation
feat(desktop): Markdown 预览改用 web view,新增 SVG 与 PDF 预览,图片查看器对齐旧 macOS 标准 - #1903
Merged
Merged
Conversation
- 新增 internal/webpreview:页面与 KaTeX、mhchem、Highlight.js、Mermaid、markmap 内嵌进二进制, 经 lithe-preview 协议提供;页面只能读宿主允许的内容,跳转交回宿主,不联网、不写发行目录 - Markdown 预览在有 web 引擎时用 Core markdown.render 的 HTML 显示内嵌 HTML、SVG、数学、图表与代码高亮, 链接和图片按 Core markdown.resolveReference 解析,源码与页面按源码行双向同步滚动;Linux 保留原生渲染 - 目录按钮移到标签栏,web 页与原生页共用 - SVG 文件以源码与图片双栏打开,编辑后 150 毫秒内更新并保持缩放与滚动,画不出时保留上一张图 - PDF 用 web 引擎自带的查看器显示;没有 web 引擎时提示用外部应用打开 - 图片查看器按旧 macOS 规则重做:34 点工具栏、宽 × 高 · 大小、适配留 24 点边距且不放大、 25%–400% 每步 25%、16 点棋盘格;新增 WebP、BMP、TIFF、HEIC、HEIF;Linux 用 Go 画布执行同一套规则 - 新增放大、缩小、图片失败图标与对应中英词条 - 悬浮提示里的链接也按 Core markdown.resolveReference 打开,删除 Go 侧的链接与图片路径解析 - Core 固定版本升到 Lithe-core-rust#37 的合入提交 2c1fed1(同时带上 #36) - 更新功能矩阵与 Agent Note 2026-11-14-web-view-previews
xiaoyumuxi
marked this pull request as ready for review
November 14, 2026 06:34
Lithe Review结论: ❓ 审查未完成 已由服务器取消。可以重新评论 |
fakeToolchainLoader.Save 在 effect 协程里原地改写 snapshot.Tools 的 Pin, 而设置页绘制时读的 t.snapshot.Tools 与它共用同一个底层数组,-race 下偶发报错。 真实的 Save 会重新读取项目、不改传入的快照;测试替身改为先复制 Tools 再改。
This was referenced Nov 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
关联 Issue / Linked issue
markdown.resolveReference)PR 类型 / Type
改动说明 / What changes
背景 / Why
Viva 原生的 Markdown 组件只排版 Markdown 本身。README 里常见的内嵌 HTML(徽章、
align、details)、内嵌<svg>、数学公式、Mermaid 和代码高亮都显示不出来,旧 macOS 版本用 WKWebView 能显示这些,迁移到 Viva 后成了功能倒退。图片查看器只能解码 PNG、JPEG、GIF;SVG 只能当文本看;PDF 只能交给外部应用。图片查看的交互也和旧 macOS 查看器(MediaViewerView.swift)不一致。Viva 0.2.2 起提供 web view,本 PR 让编辑区的这几类预览在有系统 web 引擎时(macOS 的 WKWebView、Windows 的 WebView2)显示在内嵌 web view 里。页面能读什么文件由宿主和 Core 决定,页面不联网、不写发行目录。Linux 没有 web 引擎,继续用原生渲染。
改动 / Changes
web view 预览基础设施(新包
desktop/internal/webpreview)markdown.html/js/css、image.html/js/css)以及 KaTeX 0.16.0(含字体和 mhchem)、Highlight.js 11.5.1、Mermaid 11.14.0、D3 6.7.0、markmap 0.14 用go:embed编进二进制,经应用自己的lithe-preview协议提供,不访问 CDN。这些文件取自旧 macOS 客户端已有的 vendor 目录和对应的 npm 包,版本、来源和许可证见assets/THIRD_PARTY_NOTICES.md。文档用到哪个库才加载哪个库。res/<base64url(src)>:宿主先问 Core 这个src指向哪里、能不能加载,再读文件回答;http/https图片由宿主经应用代理下载,放进所有页面共用的内存 LRU(最多 64 张、48 MiB),失败的下载下次重试。Cache-Control: no-store。workbench/preview_pages.go):标签打开期间页面一直存在;这一帧没有声明的页面隐藏起来,保留滚动位置和排版。隐藏页面最多保留 6 个,超出时关闭隐藏最久的那个。关闭项目时关闭全部页面。窗口的 web host 还没就绪、系统没有 web 引擎、或页面打开失败时,回落到原生预览。Markdown 预览(
markdown_web.go、markdown_preview.go、markdown_images.go)markdown.render过滤后的 HTML:内嵌 HTML、内嵌 SVG、数学、Mermaid、markmap 和代码高亮都能显示。渲染在后台进行,同一时刻只有一次,渲染期间的多次编辑合并成一次;渲染失败时保留上一版页面。markdown.resolveReference解析:点工作区内的文件就在编辑器打开,点#标题就跳到那个标题,外部地址交给系统浏览器;图片只加载 Core 判定在文档范围内、确实是图片的文件。原生页面也改用同一个解析。Go 侧原来的markdownImageSource、markdownLinkTargetOf和readBounded已删除。SVG 预览(
svg_preview.go).svg文件和 Markdown 一样分源码、图片两栏打开,标签栏末尾可切换源码 / 两者 / 仅图片。PDF 预览(
viewer.go、viewer_web.go).pdf不再只是“用外部应用打开”,而是在标签里用 web 引擎自带的 PDF 查看器显示,上限 256 MiB。没有 web 引擎时仍提示用外部应用打开。图片查看器对齐旧 macOS 标准(
viewer_image.go、assets/image.js、viewer_view.go)其他
pluginsemantics_hover.go)里的链接也按markdown.resolveReference判定后再交给系统浏览器。desktop/internal/core/markdown.go新增ResolveMarkdownReference客户端封装。zoom-in、zoom-out、image-off三个 Lucide 图标(generate-desktop-icons.sh重新生成icons.go)。shared.generated.go。PINNED_CORE_REVISION升到 Lithe-core-rust#37 的合入提交2c1fed1,同时带上 适配 macOS 13 并修复应用图标尺寸过大问题 #36(插件设置包内翻译)。feat(desktop): 构建选项新增忽略路径,默认跳过所有以 . 开头的文件夹 #1902 合入 preview 时也改了这一行(固定到 [Bug] 多模块spring boot的项目中.worktree导致的崩溃问题 #35),本 PR 已合并最新 preview 并解决冲突:固定版本保留包含 [Bug] 多模块spring boot的项目中.worktree导致的崩溃问题 #35 的2c1fed1,注释保留 feat(desktop): 构建选项新增忽略路径,默认跳过所有以 . 开头的文件夹 #1902 对 [Bug] 多模块spring boot的项目中.worktree导致的崩溃问题 #35 的完整说明。settingswindow的fakeToolchainLoader.Save在 effect 协程里原地改写snapshot.Tools[i].Pin,而设置页绘制时读的t.snapshot.Tools与它共用同一个底层数组,-race下TestToolchainDraftSavesOnlyExplicitChanges偶发报数据竞争。真实的Save会重新读取项目、不改传入的快照;测试替身改为先slices.Clone再改。只改测试代码,见单独的提交。.agents/notes/implemented/architecture/2026-11-14-web-view-previews.md,记录页面的读取边界、生命周期上限、图片规则的两份实现和被否方案。不在本 PR 范围内 / Out of scope
markdown-rendering矩阵已注明)。类型专属:feat
多平台对齐
pending;解码失败时会落到“无法显示”和“用外部应用打开”。platform-specific),理由:范围检查 / Scope checks
功能矩阵 / Feature matrix
shared/platform-feature-matrix/features/<id>.json:embedded-viewers(两端 partial / pending,补证据和 Viva 验证步骤,并改掉了原来“二进制文件被拒绝”的过时说明)、markdown-rendering、markdown-images-links、markdown-preview-outline(目录按钮位置);未在真机验证的保持pending./scripts/platform-feature-matrix/verify-platform-feature-matrix.sh(224 条通过)和./scripts/platform-feature-matrix/verify-platform-feature-matrix-change.sh origin/preview HEAD(通过).artifacts/下生成的矩阵视图统一日志系统 / Structured logging
app.notification.operation_failed(a.emit(operationFailedLevel, operationFailedEvent, operationFailedFields(...))),操作名为web_preview_<阶段>、web_preview_open、markdown_render;没有print、直接写 stderr 或手写事件 IDscripts/logging/generate-log-events.mjs和scripts/logging/verify-log-usage.mjs在当前仓库中已不存在(shared/logging/也已移除),无法运行界面文案 / i18n
shared/i18n/补齐中英词条,运行node scripts/i18n/generate-i18n.mjs并提交生成结果,没有手改生成文件;页面里的文案也由宿主经 i18n 取出后传给页面node scripts/i18n/verify-app-language-localization.mjs(通过)和node scripts/i18n/generate-i18n.mjs --check(合并 preview 后 en-US、zh-CN 均 11125/11125),没有放宽脚本或扩大豁免名单逻辑归属 / Logic placement
markdown.render)、链接与图片能否跟随或加载(markdown.resolveReference)都在 Rust Core,先在 Core feat(macos): add macOS 13 compatibility #32、[Bug] 所有 Maven 项目都提示 "No Maven project detected" — MavenScanPayload 字段名大小写不匹配导致解码失败 #37 合入;平台层只做 web view、文件读取和呈现性能与内存 / Performance and memory
markdownPreviewMaxBytes,沿用原值)不渲染;SVG 和图片只传当前标签的一个文件desktop/internal/editor/**、editorview/**),没有运行editor-bench.sh;大 Markdown 文件预览的帧率([Bug] Windows 打开 3.76 MB / 6.8 万行 Markdown 文档切换到预览后,界面帧率跌到 1–3 fps 并持续数分钟卡死 #1380 场景)未测量。二进制增加约 4.3 MiB 内嵌资源(主要是 Mermaid、KaTeX 字体和 Highlight.js),只在页面需要时读取,不影响启动;每个打开的页面占一份 web 引擎内存,由 6 个隐藏页面的上限约束设置 / Settings
N/A:没有新增或修改设置项。
插件契约 / Plugin contract
N/A:没有改插件契约、能力版本、插件函数协议或宿主方法。
markdown.resolveReference是桌面端调用的 Core 方法,不属于插件契约;Core 固定版本已升到包含它的2c1fed1。发行包与资源 / Bundle and resources
%LOCALAPPDATA%\<应用>\WebView2),WKWebView 的数据在用户的~/Library;页面不用临时配置,避免 WebView2 每个临时页面留下一份配置目录。已运行./scripts/desktop/verify/verify-runtime-bundle-immutability.sh(通过)worktree-resources.json无用代码与重构 / Dead code and refactoring
markdownImageSource、markdownLinkTargetOf、workbench 的readBounded、只服务于旧解码路径的字段;.pdf、.webp、.heic、.tif、.tiff、.bmp移出外部应用列表验证 / Verification
scripts/desktop/desktop-go.sh test -race -count=1 ./...(Core0de67c1,即 #37 合入前的分支提交)scripts/desktop/desktop-go.sh test -race -count=1 ./...(Core2c1fed1,当前固定版本,合并 #1902 之前)scripts/desktop/desktop-go.sh test -race -count=1 ./...(Core2c1fed1,合并最新 preview 之后)settingswindow的TestToolchainDraftSavesOnlyExplicitChanges报数据竞争(#1799 起就有的测试替身问题,见“其他”最后第二条),已在b508356修复scripts/desktop/desktop-go.sh test -race -count=5 ./internal/settingswindow/(修复之后);修复前同一测试-race -count=20未能复现,属于偶发.agents/skills/write-stable-tests/scripts/verify-test-stability.sh --base origin/previewgofmt -l .、go vet ./...(desktop)node --check检查markdown.js、image.jsnode scripts/i18n/verify-app-language-localization.mjs、node scripts/i18n/generate-i18n.mjs --check./scripts/platform-feature-matrix/verify-platform-feature-matrix.sh、verify-platform-feature-matrix-change.sh origin/preview HEAD./scripts/agent-notes/verify-agent-notes.sh./scripts/desktop/verify/verify-runtime-bundle-immutability.shnode scripts/desktop/validate-pins.mjs2c1fed1可达,Viva 固定版本可解析cargo testmarkdown 12 项、dispatcher project 72 项,cargo fmt --check,cargo clippy(在 Lithe-core-rust#37)主要的新测试:
webpreview_test.go(只回答干净路径和内嵌文件、跳转拦截、图片只按 Core 解析结果提供、读文件不跟随链接并限制大小、远程图片共享下载与失败重试)、markdown_web_test.go(随编辑渲染并与源码同步滚动、链接与图片按 Core 解析、隐藏页面上限、打不开时回落原生)、viewer_test.go(图片页与工具栏、PDF 查看器、超过上限的提示、适配留边距且不放大、围绕指针缩放与平移、棋盘格、没有 web 引擎时的 Go 画布)、svg_preview_test.go(源码旁显示图片并跟随编辑、从未画成功时显示失败、没有 web 引擎时按文本打开)。未能执行的检查和原因:
提交前确认 / Final checks
preview(445346b6b)创建,已合并最新preview(37eb69423,feat(desktop): 构建选项新增忽略路径,默认跳过所有以 . 开头的文件夹 #1902);目标分支为preview.build/、target/、dist/、.artifacts/等产物,没有凭据、个人路径和未脱敏的日志或截图