Repository navigation
feat(desktop): Markdown 目录改为 web view 页内的浮动大纲 - #1912
Merged
Merged
Conversation
- web view 页在右上角显示大纲面板:标题栏加分隔线,按层级缩进,
有子标题的行可折叠,当前章节随页面滚动高亮,点行或方向键加回车跳转;
固定行高虚拟化,只创建视口附近的行;折叠状态按稳定键保存,重新渲染后保留。
- 宿主与页面新增 outline{open} 消息:目录按钮打开或关闭面板,
页面内按 Escape 关闭时回报宿主同步按钮。
- 目录按钮改为可展开样式,打开时高亮。
- 修复原生弹出列表 PadSides 参数顺序错误导致的行重叠和缩进缺失,
按最浅标题级别计算缩进,并补回归测试。
xiaoyumuxi
marked this pull request as ready for review
November 14, 2026 09:29
23 of 26 tasks
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
PR 类型 / Type
改动说明 / What changes
背景 / Why
Markdown 预览的“目录”弹层很难用:条目互相重叠,各级标题也没有缩进,看不出层级。它是 Viva 弹出列表,选中一个标题就关闭,没法一边看目录一边在章节之间跳转,也不知道自己读到了哪一节。
这次参考 Typora 的“大纲”面板:有 web 引擎时,目录由 web view 页面自己画,固定在右上角,按层级缩进,可以折叠,并高亮当前章节。同时修复原生弹出列表的重叠问题。
改动 / Changes
web view 页面的大纲(
desktop/internal/webpreview/assets/)markdown.html:新增<aside id="outline">,包含标题栏和role="tree"的列表。markdown.css:右上角浮动面板,宽min(280px, 100vw - 24px),有圆角和阴影,分深浅两套底色。标题栏用大字,下面加分隔线。每行高 28px,悬停时加底色;当前章节用强调色的浅底和强调色文字;有子标题的行左侧带折叠箭头,展开时旋转 90°;超长标题用省略号截断;键盘焦点显示内描边。markdown.js:scrolled,宿主照常把源码带到同一行。aria-activedescendant指向当前行,每行带aria-level、aria-posinset、aria-setsize、aria-expanded、aria-selected。outline{open:false}。宿主与页面的协议
outline{open},用来打开或关闭大纲。页面 ready 时,宿主按当前按钮状态重发一次,因为页面 ready 之前发出的消息会丢失。outline{open},在用户从页面里关闭大纲时发送。宿主只更新按钮状态,不回发。webpreview.Message新增Open字段,并更新了消息说明注释。outline,复用已有词条desktop.markdown.contents,没有新增 i18n 词条。目录按钮(
desktop/internal/workbench/markdown_preview.go)Expandable、Expanded)。打开时用激活底色和正文色图标,关闭时只在悬停时显示底色,并带提示文字。showContents,统一修改打开状态。web 页会同时收到outline消息。没有标题或文件过大时,按钮不显示,大纲也会关闭。原生弹出列表修复(Linux 或 web view 打不开时使用)
PadSides(top, right, bottom, left)的参数顺序传错,左缩进被传到了其他边,导致各行重叠,也没有缩进。修复后按参数顺序传值。markdownContentsIndent),左右各留 8 点(markdownContentsInset)。测试
TestMarkdownContentsIndentsHeadingsByLevel,检查原生弹出列表的行不重叠、每深一级多缩进 12 点、同级对齐,以及按钮的展开状态。修复前这个测试会失败:"Usage" at {859 197 36 20} overlaps "Keys" at {859 199 28 20}。TestMarkdownWebPageRendersCoreHTMLAndScrollsWithTheSource的目录部分,检查以下几点:outline{open:false}。outline{open:true},宿主不再画标题。scroll。文档
markdown-preview-outline:更新了能力描述,证据补上 web 页文件,并改写备注和验收步骤。两端仍是implemented / pending。2026-11-14-web-view-previews.md补充了以下内容:不在本 PR 范围内 / Out of scope
类型专属:feat
多平台对齐
pending。platform-specific),理由:范围检查 / Scope checks
功能矩阵 / Feature matrix
shared/platform-feature-matrix/features/markdown-preview-outline.json:能力描述、两端证据(加入 web 页 html/js/css、markdown_web.go、webpreview.go和两个测试文件)、备注和验收步骤。两端都还没有整机验收,状态保持implemented / 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
N/A:没有新增生命周期里程碑、操作终态、降级或失败路径。大纲的打开、关闭、折叠和跳转都是高频视图交互,不记日志。
界面文案 / i18n
desktop.markdown.contents,由宿主经i18n.Shared取出后通过 setup 传给页面;按钮提示文字也用这个词条。node scripts/i18n/verify-app-language-localization.mjs(通过)和node scripts/i18n/generate-i18n.mjs --check(en-US、zh-CN 均 11125/11125),没有放宽脚本或扩大豁免名单逻辑归属 / Logic placement
markdown.render输出中带源码行的标题,原生页用源码标题。这次只新增标题树、折叠和当前章节高亮,都属于视图呈现,且依赖页面逐帧的滚动位置,所以写在页面脚本里,不进 Core。macOS 和 Windows 共用同一份脚本。Agent Note 记录了这一取舍。性能与内存 / Performance and memory
outline消息,标题列表沿用已有的rendered消息,没有额外传输。desktop/internal/editor/**、editorview/**),没有运行editor-bench.sh。也没有新增运行时或依赖。设置 / Settings
N/A:没有新增或修改设置项。
插件契约 / Plugin contract
N/A:没有改插件契约、能力版本、插件函数协议或宿主方法。
outline是桌面端和自己内嵌页面之间的消息,不对插件开放。发行包与资源 / Bundle and resources
./scripts/desktop/verify/verify-runtime-bundle-immutability.sh(通过)无用代码与重构 / Dead code and refactoring
验证 / Verification
scripts/desktop/desktop-go.sh test ./internal/workbench ./internal/webpreview -count=1(完整两个包,不加过滤)TestMarkdownContentsIndentsHeadingsByLevel"Usage" at {859 197 36 20} overlaps "Keys" at {859 199 28 20};修复后通过markdown.html/js/css,由测试脚本模拟宿主发送 setup、render、outline,并通过 CDP 断言(约 100 个标题)• 显示与标题
• 只创建视口附近的行
• 层级与缩进
• 行不重叠
• 箭头折叠且不滚动页面
• 点行跳转并回报
scrolled• 方向键、回车和
aria-activedescendant• 滚动时更新当前章节,折叠时高亮上级
• 重新渲染后保留折叠
• 树滚到底部
• Escape 关闭并回报
outline{open:false}• 无标题时隐藏
node scripts/i18n/verify-app-language-localization.mjs、node scripts/i18n/generate-i18n.mjs --check./scripts/desktop/verify/verify-runtime-bundle-immutability.sh./scripts/platform-feature-matrix/verify-platform-feature-matrix.sh、verify-platform-feature-matrix-change.sh origin/preview HEAD./scripts/agent-notes/verify-agent-notes.shgofmt -l、node --check markdown.js未能执行的检查和原因:
提交前确认 / Final checks
preview(7c036b3b8)创建;目标分支:preview.build/、target/、dist/、.artifacts/等产物,没有凭据、个人路径和未脱敏的日志或截图