Repository navigation
feat(desktop): HTML 文件在编辑器旁预览页面,按工作区静态站点加载并实时更新 - #1923
Merged
Merged
Conversation
HTML、HTM、XHTML 文件和 SVG 一样有源码 / 两者 / 仅预览三种模式。页面在单独的 lithe-site 协议和临时存储里打开,每个请求由 Core 的 htmlPreview.resolveRequest 决定;编辑后约 150 毫秒重新加载并回到原滚动位置。工具栏有后退、前进、重新加载和在浏览器中打开。打不开站点页时只有 HTML 文件退回纯文本。
htmlPreview.site 与 htmlPreview.resolveRequest 的期望改由 Core 的 rust/fixtures/editor/html-preview-v1.json 给出,桌面端测试与 Core 测试读同一份。 PINNED_CORE_REVISION 升到 Lithe-core-rust#42 合并 main(#41)后的 659805e。
#42 已 squash 合入 main,合入提交与原分支 659805e 的树相同。
xiaoyumuxi
marked this pull request as ready for review
November 14, 2026 12:24
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
htmlPreview.site与htmlPreview.resolveRequest,附共享 fixturerust/fixtures/editor/html-preview-v1.json)PR 类型 / Type
改动说明 / What changes
背景 / Why
迁移到 Viva 桌面端后,
.html文件只能当纯文本打开,看不到页面(旧 macOS 端有内嵌 HTML 预览)。#1903 已经让 Markdown、SVG、PDF、图片走系统 web 引擎,这次让 HTML 文件也在编辑器旁显示页面:页面按工作区静态站点加载样式、脚本和图片,编辑时实时更新。哪些请求能读、读哪个文件由 Rust Core 决定,平台层只负责读文件和交给 web view。改动 / Changes
HTML 文件的双栏预览(
desktop/internal/workbench/html_preview.go,新文件).html、.htm、.xhtml文件(虚拟文档除外)在有 web 引擎时以“源码 + 页面”双栏打开,标签栏末尾复用 SVG 的三态切换:源码 / 两者 / 仅预览。htmlPreview.site);Core 返回失败时该文件显示“无法预览此 HTML 文件。”,并记录一次html_preview_site失败日志。followDocumentLink,用系统应用打开,页面停在原处。站点页(
desktop/internal/webpreview/site.go,新文件;webpreview.go)SitePage:单独的lithe-site://site/协议,开启Ephemeral。Cookie、localStorage 等不落盘,关闭预览后不保留,也不与其他 HTML 文件或 Markdown 预览(lithe-preview)共享。htmlPreview.resolveRequest:file读磁盘文件,单个文件上限 64 MiB,超过返回 413;directory返回跳转到index.html的页面;denied返回 403(如/.env、私钥文件);none返回 404。web_preview_request。Follow,脚本自动跳到站外的导航被取消;window.open在页面内打开,开往站外的每秒最多交给Follow一次(Windows 不区分是否由用户触发)。Page新增Reload、Back、Forward;Config新增Address(文档在站点里的地址)和Request(请求交给谁判定);Page改为通过内部webView接口使用*app.WebView,站点测试用替身代替系统 web view。Core 客户端(
desktop/internal/core/html_preview.go,新文件)HTMLPreviewSite(document, workspace)和ResolveHTMLPreviewRequest(document, workspace, path),分别对应 Core 的两个命令。TestHTMLPreviewSharedFixture通过contractfixture.CoreFixture读取固定 Core 检出里的editor/html-preview-v1.json,与 Core 自己的测试用同一份用例:工作区内页面、隐藏目录、工作区外页面、无效文档路径。其他 workbench 改动
preview_pages.go:站点页打不开时只设置siteFailed,HTML 文件之后都以源码显示,Markdown、SVG、PDF、图片预览不受影响;其他页面打不开仍设置failed。打开失败记录web_preview_open,页面资源失败按阶段记录web_preview_<stage>。previewView接口加上Reload、Back、Forward。documents.go:文档新增html预览状态;editor_view.go:HTML 文件可预览时绘制双栏,标签栏显示三态切换。viewer_image.go:查看器工具栏新增actions,可在缩放之后追加按钮;HTML 预览用它放后退、前进、重新加载和在浏览器中打开(最后一个复用已有词条desktop.editorMenu.openInBrowser和已有的openInBrowser)。browser_preview.go、markdown_preview.go:只更新注释,说明 HTML 文件现在也在编辑器旁显示页面。markdown_web_test.go:测试替身记录SetDocument的 MIME,以及Reload、Back、Forward的调用次数。界面文案(
shared/i18n/)desktop.htmlPreview.back、.forward、.reload、.tooLarge、.failed,并重新生成desktop/internal/i18n/shared.generated.go。文档与记录
2026-11-14-web-view-previews.md新增 HTML 预览一节:单独协议、临时存储、请求由 Core 判定、导航规则,以及被否方案(复用lithe-preview、持久存储、localhost HTTP 服务、允许远程主框架)。2026-10-22-html-preview-embedded-browser.md补充 Viva 端的现状和与旧 macOS 内嵌浏览器的差距。embedded-viewers.json:两端的证据路径加入 HTML 预览的实现和测试,验证动作和说明补充 HTML 预览。docs/viva-migration.md:HTML 预览从“未迁移”改为已迁移,并列出缺少的功能。Core 固定版本
scripts/desktop/build-desktop-core.sh的PINNED_CORE_REVISION升到 f88bc49(Lithe-core-rust#42 在 main 上的 squash 合入提交),注释说明这次固定带来的命令。不在本 PR 范围内 / Out of scope
/开头的绝对路径找不到文件,Windows 也会留下临时存储的 profile 目录。两者都是 Viva 的限制,需要在 Lithe-IDEA/Lithe-viva 修,Lithe 不加绕过代码。LITHE_CORE_RUST_DIR共用 Cargo 目标目录,切换来源后可能继续链接旧库。已提交 [Bug] 桌面端 Core 构建在固定检出与 LITHE_CORE_RUST_DIR 之间切换后,继续暂存并链接上一份 Core 的静态库 #1922,本 PR 不修。类型专属:feat
多平台对齐
Lithe 的目标是 macOS 与 Windows 能力对齐。必须选下面一项:
platform-specific),理由:说明:实现是 Viva 两端共用的 Go 代码,Windows 走 WebView2。Windows 实机还没有验证,矩阵中验证状态如实保持
pending。范围检查 / Scope checks
功能矩阵 / Feature matrix
shared/platform-feature-matrix/features/embedded-viewers.json:两端的实现状态和验证状态、证据路径、owner、验证动作都如实填写;没有运行验证的保持pending./scripts/platform-feature-matrix/verify-platform-feature-matrix.sh;改了平台实现路径的,还运行了./scripts/platform-feature-matrix/verify-platform-feature-matrix-change.sh origin/preview HEAD.artifacts/下生成的矩阵视图插件归属 / Plugin ownership
develop-lithe第三节“插件归属与宿主零依赖”的自查命令,结果为空shared/i18n/;插件的构建步骤、资源路径和补丁没有写进scripts/resources/、docs/ci-builds.md、Agent Note 或 Skilllithe-preview/ 插件页路径统一日志系统 / Structured logging
app.notification.operation_failed(operation字段是自由取值的标识),通过现有的a.emit(operationFailedLevel, operationFailedEvent, operationFailedFields(op, err))记录,取值为html_preview_site、web_preview_open、web_preview_request(另有已有的web_preview_file、web_preview_resolve、web_preview_message);没有新增事件声明,没有print、直接写 stderr 或手写事件 IDaskHTMLSite记录一次,页面请求失败只在serveSite记录;逐个请求的成功不记日志operationFailedFields的error字段输出scripts/logging/,本 PR 没有涉及界面文案 / i18n
shared/i18n/补齐中英词条,运行node scripts/i18n/generate-i18n.mjs并提交生成结果,没有手改生成文件;Viva 代码通过desktop/internal/i18n/的接口读取node scripts/i18n/verify-app-language-localization.mjs和node scripts/i18n/generate-i18n.mjs --check,没有放宽脚本或扩大豁免名单逻辑归属 / Logic placement
index.html的跳转、MIME 判定都在 Core 的htmlPreview.site/htmlPreview.resolveRequest,共享 fixture 随 Core 大哥这是要一己之力做一个 idea 编辑器吗 #42 先合入;平台层只读文件、交给 web view 和绘制工具栏性能与内存 / Performance and memory
previewPagesKept(6)上限,关闭文件或项目时释放;没有新增轮询(编辑后的更新是 150 毫秒的一次性延时);单个文件读取上限 64 MiB,交给页面的文本上限 8 MiBa.background在后台执行、结果回到界面线程应用,页面请求的 Core 解析和文件读取在 goroutine 里完成;交给页面的是当前文档文本,不跨 C ABI 传整个工作区设置 / Settings
N/A:没有新增或修改设置项、设置页或对话框选项。
插件契约 / Plugin contract
htmlPreview.*),不属于插件契约、能力版本或插件函数协议scripts/desktop/build-desktop-core.sh的PINNED_CORE_REVISION已升到 f88bc49,桌面端测试经scripts/desktop/desktop-go.sh读到的就是这份 Core 和它的editor/html-preview-v1.jsonfixturesdk-e2e.mjs:没有修改插件后端协议发行包与资源 / Bundle and resources
./scripts/desktop/verify/verify-runtime-bundle-immutability.sh无用代码与重构 / Dead code and refactoring
验证 / Verification
scripts/desktop/desktop-go.sh test -race ./...(LITHE_CORE_RUST_DIR指向 659805e,与 f88bc49 树相同)scripts/desktop/desktop-go.sh test ./internal/workbench ./internal/webpreview ./internal/core -run 'Viewer|SVG|HTML|Site|ImageFit|ImageCanvas|Checkerboard|Serves|Navigation|ReadFile' -count=1(固定的 f88bc49)gofmt -l(改动的 Go 文件)develop-lithe要求的两种模式)node scripts/i18n/generate-i18n.mjs --check、node scripts/i18n/verify-app-language-localization.mjs./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.shcargo fmt --check、cargo clippy、cargo test -p lithe-project(85)、cargo test -p lithe-core(790)新增测试:
TestHTMLFileShowsItsPageBesideTheSource、TestHTMLFileIsTextWhereItsPageCannotOpen、TestHTMLFileIsTextWithoutAWebEngineTestSiteServesWhatCoreResolvesAndTheFileFromTheEditor、TestSiteKeepsTheMainFrameOnTheSite、TestSiteWindowsLoadInPlaceOrGoToFollowAtMostOncePerInterval、TestSiteShowsEachTextAndKeepsItsScroll、TestSitePageTakesNoMessageButItsPosition、TestSitePathDecodesAddressesOfTheSiteOnlyTestHTMLPreviewSharedFixture未能执行的检查和原因:
/开头的绝对路径的现状,以及临时 profile 目录的残留情况。提交前确认 / Final checks
preview创建;目标分支:feat、fix、docs 为preview,release 以发布流程要求为准(基于 059d878;之后的 fix(desktop): 卸载插件前等待构建、VCS 和调试会话退出 #1921 没有改动本 PR 的文件).build/、target/、dist/、.artifacts/等产物,没有凭据、个人路径和未脱敏的日志或截图