Skip to content

feat(project): htmlPreview 命令决定 HTML 文件预览的站点根目录与每个请求服务的内容 - #42

Merged
xiaoyumuxi merged 4 commits into
mainfrom
feat/html-preview-site
Nov 14, 2026
Merged

xiaoyumuxi merged 4 commits into
mainfrom
feat/html-preview-site

Conversation

@xiaoyumuxi

@xiaoyumuxi xiaoyumuxi commented Nov 14, 2026 •

Copy link
Copy Markdown
Contributor

关联

桌面端 Viva 开始在编辑器旁预览 HTML 文件(.html、.htm、.xhtml),桌面端 PR:1lck/Lithe-IDEA#1923(Draft,已把 PINNED_CORE_REVISION 固定到本 PR 的合入提交 f88bc49)。预览页会运行文件里的脚本,所以它请求的每个路径能不能读、读到什么,都由 Core 决定,前端只照 Core 的回答服务。

改动

  • 新增命令 htmlPreview.site:给出 HTML 文件按静态站点预览时的根目录、文件在站点里的地址和服务时用的内容类型。
    • 请求带 documentPath 和可选的 workspaceRoot。根目录的取法和 markdown.resolveReference 的范围相同:文档在工作区里时是工作区,否则是文档所在目录。
    • 返回 { root, address, mime }。address 是文档从根开始的路径,每一段都做百分号编码;mime 按扩展名取,比如 text/html; charset=utf-8。
    • documentPath 不是绝对路径时返回 invalid_request。
  • 新增命令 htmlPreview.resolveRequest:判定预览页的一个请求该服务什么。请求在上面两个参数之外再带 path,也就是 web 引擎报来的路径:已解码、用 / 分隔、不带查询串和片段,根目录为空串。Core 不会再解码一次。返回按 kind 区分:
    • document:路径指向文档本身,不管用的是什么名字。前端服务编辑器里的文本,所以没保存的修改也能看到。
    • file:已存在的普通文件,带规范路径 path 和 mime。
    • directory:目录下的 index.html 是根里的普通文件时返回这个,前端给一个把浏览器带到该 index.html 的页面。
    • denied:前端回 403。以下两类路径返回它:
      • 名字以 . 开头的路径。文档所在目录本身经过的那几层隐藏目录除外,所以 .github/pages 里的页面能加载它的邻居,但读不到 .git/config。
      • 扩展名是 jks、key、keystore、p12、pem、pfx 的密钥或证书。
    • none:前端回 404。
  • 判定规则:
    • 路径从根按字面解析,按字面和解析符号链接之后都必须在根里。
    • 含 \、: 或 NUL 的段一律 none。
    • mime 按扩展名查表:文本类型统一带 UTF-8,未知扩展名是 application/octet-stream。
  • markdown_reference.rs 里算范围的代码抽成 document_scope,join_lexically 和 within 改为 crate 内可见,两个命令和 Markdown 引用判定共用同一套范围规则,Markdown 的行为不变。
  • 实现在 rust/crates/project/src/html_preview.rs。两个命令在分发器、命令表和请求追踪里同步登记。
  • 共享 fixture rust/fixtures/editor/html-preview-v1.json:一组工作区文件,加 3 个用例,共 28 个请求,另有无效的文档路径。3 个用例是工作区里的页面、隐藏目录里的页面(能读自己所在目录,读不到其他隐藏目录)和工作区外的页面。Core 的分发器测试与桌面端 TestHTMLPreviewSharedFixture 读同一份文件。
  • 契约 rust/contracts/application-boundary.md:
    • 新增 “Embedded HTML preview” 一节:页面显示编辑器当前文本,其余文件按两个命令的回答服务;不通过站点写文件,预览关闭后不保留页面存储,站外导航按 markdown.resolveReference 的链接规则处理;页面打不开时只有 HTML 文件退回纯文本。该节链接到上面的 fixture。
    • 修正 “External HTML preview” 一节(在系统浏览器中打开):原文写两端产品都有、只列 .html / .htm、不保存缓冲区,现在改为桌面端、.html / .htm / .xhtml / .svg,打开前先保存未保存的修改。
  • 契约 rust/contracts/rust-core-api.md:命令表新增两行;新增“HTML file preview”一节,写明请求、返回的每种 kind 和判定规则,并写明前端不能信任页面的任何请求:只服务命令给出的内容,不通过站点写文件,页面的顶层导航按 markdown.resolveReference 的链接规则处理。

验证

  • cargo test -p lithe-project --lib html_preview:4 个测试通过,分别是 the_site_is_the_workspace_with_the_document_addressed_from_its_root、requests_serve_the_document_files_and_folders_of_the_site、requests_stay_inside_the_root_and_out_of_hidden_files_and_keys、links_are_resolved_before_the_root_and_hidden_names_are_checked。
  • cargo test -p lithe-project --lib markdown:12 个测试通过,说明抽出 document_scope 之后 Markdown 引用判定不变。
  • html_preview_commands_match_shared_fixture:逐个跑 fixture 的用例,经分发器调用两个命令,与 fixture 的期望逐项比对。
  • 合并 main(feat(project): markdown.outline 按标题输出 Markdown 的文档结构树 #41 markdown.outline)之后重跑:cargo test -p lithe-project(85 个)、cargo test -p lithe-core(790 个)全部通过。
  • cargo fmt --all -- --check、cargo clippy -p lithe-project -p lithe-core --all-targets -- -D warnings:通过。
  • 桌面端链接本 PR 的提交(与合入提交 f88bc49 的树相同),-race 跑完全部 55 个 Go 包,含读取同一份 fixture 的 TestHTMLPreviewSharedFixture;之后固定到 f88bc49 又跑了一次 HTML 预览相关测试,结果见 feat(desktop): HTML 文件在编辑器旁预览页面,按工作区静态站点加载并实时更新 1lck/Lithe-IDEA#1923。

本 PR 不涉及插件契约、能力版本和插件函数协议,所以不需要更新协议记录。

新增 htmlPreview.site 与 htmlPreview.resolveRequest:站点根目录与 markdown.resolveReference 的范围一致;请求按字面和解析符号链接后都必须留在根目录内,隐藏路径与密钥、证书文件拒绝,文档本身由编辑器文本服务。
# Conflicts:
#	rust/contracts/rust-core-api.md
#	rust/crates/core/src/runtime/dispatcher.rs
#	rust/crates/project/src/lib.rs
…记内嵌 HTML 预览

分发器测试读 rust/fixtures/editor/html-preview-v1.json:工作区里的页面、隐藏目录里的页面、工作区之外的页面三组用例,以及相对路径的 invalid_request。桌面端测试读同一份 fixture。

application-boundary.md 新增 Embedded HTML preview 一节;External HTML preview 改为当前桌面端的行为:先保存未保存的修改再用系统浏览器打开,范围含 .xhtml 和 .svg。
@xiaoyumuxi
xiaoyumuxi marked this pull request as ready for review November 14, 2026 12:04
@xiaoyumuxi
xiaoyumuxi merged commit f88bc49 into main Nov 14, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant