Repository navigation
feat: Callout Live 形态收口——BlockWrapper 容器与引用内完整渲染(T04–T07) - #678
Conversation
用户发布后观感复核提出四项 Live 形态差距,本轮完成方案探查与开票,
不含生产代码变更。
## 探查结论(真实 Chromium + 生产控制器 + 产物 CSS)
- **行级垂直 padding 落点竞态**:给 callout 标题行注入真实
padding-top/bottom 后行盒高度 21px→39px,同一坐标的点击落点在两次
独立运行中分别命中第 3 行与第 4 行。CM6 按真实 DOM 高度记账,
浏览器异步布局造成高度表与 posAtCoords 之间的窗口期。据此否证
「把 --callout-padding 上下分量直接落到 .cm-line」的直觉方案。
- **引用内围栏/公式块零加工**:围栏行有 .vsidian-code-line 底色但无
语言标签/高亮/行号;公式块完全不渲染。成因是 mermaid.ts 的
indentColumns 只计空格与 Tab、math.ts 用 trim 后 startsWith('$$')。
进一步查明「剥前缀即可」不成立——会触发 replace 区间重叠、block
widget 定位到引用前缀、缩进列对齐三处冲突。
- **嵌套 callout 无层次**:data-callout 取最内层导致外层正文行被染成
内层类型色,各层 padding-left 同为 24px 无深度区分。
- **两项待决策**(整标题点击折叠、光标进入退化引用块)经核对与
callout.md §4.1 既有决策直接冲突,按用户要求本轮不动。
## 开票
批次总票 #668,子票 V01/#669、V02/#670、T02/#671。V01 与 V02 为有
明确退出条件的验证票,不以票关闭代替结论通过。
## 文件树
docs/research/callout-live-refinement-probe.md 经 file-tree 技能登记
(tree_tool.py add + check --strict)。check --strict 残留三项告警
(codeCardClickOffset.mjs / codeCardClickOffsetFixture.ts /
calloutCommands.test.ts)为 main 基线已有漏登记,见
docs/specs/integration-test-groups.md,不在本次范围扩大修复。
不同类型 callout 的标题此前与正文同色,只靠图标形状区分。原因是标题行 只读 --callout-title-color(默认 inherit),缺「标题容器取类型色」一层。 ## 实现 按 Obsidian 1.14.4 app.css 的两层分工对齐: - 标题层 `.callout-title` 取 `--callout-color`(类型色) - 内层 `.callout-title-inner` 取 `--callout-title-color`(保持 inherit) 关键取舍:**不把 --callout-title-color 的默认值改成类型色**。该变量是 用户片段覆盖标题文字的入口,改默认会破坏其语义;两层各司其职,覆盖 前者只改标题文字、不动类型色。Live 与阅读两侧同款结构,同一 data-callout 值两端计算色一致。 ## 联动生效 `calloutMenuPreview.paintTypeRow` 本已有「标题色 ≠ 基准色才落菜单文案」 的分支,因两者此前恒等而从未走到;本票后自动点亮。 ## 测试 TDD 先红后绿: - `calloutCssContract` 扩 3 例(标题层类型色 / 内层保 inherit 语义 / 阅读侧两层结构),改前 3 红、改后 21/21 绿 - `calloutTypes` 浏览器套件扩绘制层断言(27 类型标题计算色各自等于类型色、 内层继承、至少 6 种不同色、片段覆盖 --callout-title-color 只作用于内层 而标题层不变、Live 与阅读两端同值一致) 其间修了两处自引入的测试缺陷:变量名与文件既有 `overrideStyle` 重名; Live 侧复检后未切回阅读模式,破坏后续依赖阅读态的嵌套用例。 ## 验证 - 全量 vitest 10113 例:10109 通过,4 例 i18nBundleBytes 失败为 「构建产物缺失」——`npm run compile` 后复验 8/8 通过 - `check:stylecontract` 八项零失败;样式指南 234 条目重新生成 - 浏览器 `calloutTypes` 全绿(27 类型 × 明暗 × 图标 × 嵌套/列表编辑 × malformed × 阅读侧) ## 文档 styleContract 的 callout 条目 states 与 var-callout-color 条目 purpose 补标题着色语义;CHANGELOG Unreleased 记用户可见变更;人工验证清单登记 A85(明暗主题下 13 类型标题色可辨度、富标题链接可读性、片段覆盖观感)。 代理自检不等于人工验收。
V02(#670)验证完成:完整卡片形态在引用容器内不可行,降级形态可行。 ## 关键更正(前序报告判断有误) 前序探查报告称「卡片 replace 与 QuoteMark hideDeco 同区间重叠,CM6 严格 禁止」——**这条是错的**。本轮独立复核(裸 CM6 四种区间形态在 Chromium 实测)确认:replace 区间重叠**不抛错,静默取并集**。源码层面 `PointDecoration.range` 仅在 `from > to` 或零宽 replace 时抛 `RangeError`,与重叠无关。 前序报告对缩进偏移的归因也不准确:不是「缩进值算错」,而是 **CSS 特异性 平局**——callout 规则与卡片 edge 规则同为 (1,5,0) 且靠后胜出,抢走中间 代码行的 padding-left 而 text-indent 存活。故调 --vsidian-code-indent 修 不好(两处引用同一变量,差值恒定 14px)。 **结论不变但依据更换**:完整卡片仍不可行,真正原因是—— 1. block widget 宽度由 .cm-content 决定,卡头横带在引用内必然跨出容器 左缘(实测 x=70 vs 容器内容 x=94) 2. 上述特异性平局 ## 降级形态 只发语法高亮可行且零缺陷(零 replace、零缩进计算、零行号列),代价是 丢弃卡头横带与行号。是否采用待决策。 ## 公式粒度修正 「引用内公式不渲染」需分开看:行内 $x^2$ 与单行 $$x^2$$ **已正常渲染**, 只有多行 $$ 块不工作。前序报告笼统列为一项,现按实测细化。 ## 文档 - 新增 docs/research/callout-live-refinement-probe2-v02.md(经 file-tree 登记) - 更正 probe.md §3.3 第 2、3 条,加 2026-10-31 更正块并指向 V02 - perf/2026-09-mermaid-rendering.md 已知限制第 1 条改写(原文「剥前缀即可」 不成立) - perf/2026-09-math-rendering.md 已知差异补公式粒度说明 src/ 零变更(V02 为验证票,只产出结论)。
V01(#669)验证完成:四路线实测,选定路线 D(块级间隔 widget)。 ## 关键更正:落点偏移不是竞态,是确定性失效 前序报告称行级垂直 padding 的落点偏移是「浏览器异步布局竞态」——**归因 错误**。实测同一坐标连续 20 次点击,热态下 20/20 全部错行到下一行,3 秒 内模型偏差恒为 24px 不变。这不是抖动。 真正根因是 **.cm-content 的 min-height: 100% 高度门控**:CM6 的 measure() 只在 contentDOMHeight != domRect.height 时重测行高(源码 @codemirror/view 6362 行核实)。短文档内容被钳在视口高度,给行加 padding 不改变 .cm-content 自身高度,模型永不重测。长文档超出视口反而不受影响——意味着**短笔记( callout 主要场景)必然踩坑,而手工打字时看起来正常**(真实键入产生事务 会置 mustMeasureContent)。 生产现成的 scheduleSnippetMeasure 对该问题完全无效。 归因差异影响取路:若是竞态,等待或补重测即可;既然不是,必须换承载层。 ## 四路线判定 | 路线 | 落点 | 承载间距 | 判定 | | 真实 padding | 热态确定性 FAIL | 是 | 不通过 | | 伪元素撑高 | 同型 FAIL(越 strut 后) | 是 | 不通过 | | 绝对定位伪元素 / box-shadow | PASS | 否(零间距) | 不满足需求 | | **块级间隔 widget** | **全矩阵 PASS** | **是** | **通过** | 选定 D:唯一同时满足真实间距与落点确定性,且间隔可放在标题行与正文首行 之间(实测间距 7.25→15.25px),直接对应「标题与正文无留白」这条需求。 构建成本与基线持平(2101 行/700 callout:init 119ms vs 基线 120ms)。 实施前提 5 条(widget 须经 StateField、需自备底色、间隔区不可放光标、 --callout-padding 上下分量映射、折叠时同步退场)已写入报告 §5.2。 ## 顺带发现:嵌套是既有缺陷,不只是观感 data-callout 一旦被内层覆盖就不恢复,三层嵌套下外层尾段被染成最内层 类型。后果:既有片段 [data-callout='note'] 只能命中第 1、2 行,「给最外层 加样式」的片段无法达成。推荐逐层通道 data-callout-lN(零破坏既有片段且 能修复该缺陷);深度类方案给不了类型归属。 ## 文档 - 新增 docs/research/callout-live-refinement-probe2-v01.md(file-tree 登记) - 更正 probe.md §2.3 竞态归因与 §4.2 嵌套说明 src/ 零变更(验证票只产出结论)。
V01/V02 报告的 tree.json 登记已提交,但渲染产物 AGENTS.md 的简版树块 漏在暂存区外。本提交补齐,使 tree.json 与渲染结果一致。
- 验证 CM6 原生 BlockWrapper(@codemirror/view 6.43.13)在生产 WebviewSyncController 链路上承载可编辑 callout 与完整子块 - 结论:路线条件可行;V02 两条硬约束(block widget 宽度归属、 CSS 特异性平局)被 wrapper 结构性化解,引用内完整代码卡 + 多行公式组合实测通过(20 次点击口径) - 钉死机制事实:行归属两端含端点须行对齐区间、边界空间入 heightmap 记账而垂直 margin 不入(长文档确定性错行对照实验)、 Lezer 嵌套 Blockquote node.to 吃外层尾行(data-callout 内层 胜出既有缺陷的根源实证)、widget 在 wrapper 内部不分裂 - 记录实施前置清单(margin 禁令、区间派生口径、扫描器前缀 剥离蓝本、liveMath 标记锚点适配、token 逐行映射、公开契约 迁移)与视觉缺口(公式源文泄漏、高亮错位、行号盒外定位) - 探针件一次性已删;三轮日志与截图留存 out/test/callout-wrapper/ (gitignored);临时扫描器补丁已回滚并复跑验证无残留
- 用户复核 s3 截图提出两点:盒内边距观感缺失、代码行号向左支出盒外 - 视觉子代理逐像素复核 + DOM 级 computed 测量(临时补丁重建 bundle 实测后已回滚,工作树干净)双路钉死成因 - 行号支出 = 悬挂缩进塌陷:行级卡 padding-left 与 text-indent:-38px 两式不同源(quiet/探针规则清零前者、后者存活),首行起点被拉到 行盒外 38px,行号甩出 wrapper 盒;与 V02 特异性平局同族, 迁移时两式必须同源消费 --vsidian-code-indent - 内边距观感 = 两层反差:wrapper 外框留白充分(26/26/14/14),但 行级 quiet 背景块内部左 0-1px、上 3px、下 4px 贴边——上下分量 按现行纪律不落行(行级类不改行高),容器背景上移 wrapper 是必修项 - 两项从「样式迁移设计项」升格为实施票必修
实施前复核发现 §2.4/§5.2 的关键定性错误:嵌套 Blockquote 内层节点 to 覆盖外层尾行不是 Lezer 缺陷,是 CommonMark 懒延续(带较少 > 的行剥去 外层标记后可延续内层末段)。证据:test/unit/calloutParity.test.ts F17/F38/F44 以 markdown-it token map 双端对拍钉住同一区间,Reading 同 渲染在内层;T01 syntax-parity.json F17 同型。 - 撤回「data-callout 内层胜出是既有缺陷」判定;V01 §4.1 真实遗留诉求 是分层样式可达性(data-callout-lN 类提案),归样式契约票 - 撤销 §5.2「引用深度向下扫描」派生方案:它把懒延续行截到外层,与 Reading 分叉。改为直接消费解析器节点区间(from 对齐标题行行首、to 取尾行行尾),列表内 callout v1 不接 wrapper - §3 S1 与 §7 同步标注勘误口径
#672(#668 批次):把探针验证的容器结构接入生产——新模块 liveCalloutWrap 以 StateField 派生 wrapper 区间,经 EditorView.blockWrappers 装配(块级 结构禁止插件发射,StateField 是 CM6 唯一合法通道)。 区间口径(探针报告 §5.1/§5.2 勘误后): - 直接消费解析器节点区间(识别单一事实源 calloutOfBlockquote): from 对齐标题行行首(内层 node.from 落在第二个 > 上,直接使用会使 内层标题行逃出内层盒——探针 S1 实证)、to 取节点尾行行尾 - 懒延续行(含带较少 > 前缀的外层行)留在内层容器,与 Reading 双端 一致(calloutParity F17/F38/F44) - rank = 60 − 10 × 引用深度(外层大内层小);树复用 liveDecorationsField 增量结果,纯选区事务不重建 - 边界:列表内 callout 与引用嵌入实例不接 wrapper(v1 维持行级形态); frontmatter 区域 fmEnd 守卫 装配:syncController.rootOwnedViewExtensions(根正文独有);结构层只挂 内部类 vsidian-callout-wrap + data-callout-depth,公开类名与视觉迁移归 T05(#673);wrapper 禁垂直 margin 纪律见报告 §5.1。 测试: - 单测 liveCalloutWrap.test.ts 14 例:纯函数矩阵(嵌套/懒延续/兄弟/ 列表排除/紧贴降级/fmEnd)+ 增量对拍 + 纯选区不重建 + rank - 浏览器套件 calloutWrap:结构/嵌套/懒延续归属、4×20 同坐标点击、 标题行首击(光标进入后标记显形改行几何,连击属显隐语义——实测钉住)、 wrapper 内真实键入、热样式结构保持 + 模式往返冷重建后 padding 记账 精确、长文档视口入场(先滚后等——ADR-0005 视口外不实例化)、零页面错误 - 回归:calloutPaint/Types/Fold/Plan/Icon/RefEmbed/Menu 7 套件全绿 报告同步:S1 热样式结论收窄——运行中改 wrapper padding 短文档下 coordsAtPos↔posAtCoords 不自愈(scroll/空事务/视口 resize/沉降点击实测 无效,偏移恰为新增边界空间),冷重建后恢复;片段热更新测量刷新为 T05 设计项。fixture init 版本自增(同版本 init 去重,对齐宿主协议)。 Close #672
#673(#668 批次):非列表内 callout 的容器视觉从行级拼贴迁 BlockWrapper 承载,公开契约同步迁移(探针报告 §4.4「内边距没留」的根治)。 契约迁移(style-contract 流程:修改前已固定旧契约条目,无入口删除/ 降级,check:stylecontract 8 项零失败,无需基线豁免重锚): - wrapper 挂 .callout 主类 + data-callout 类型 + data-callout-depth (公开分层入口:嵌套 wrapper DOM 天然承载 .callout .callout 后代 选择器——V01 §4.2 data-callout-lN 提案免新增属性族) - 行级让位:非列表内 callout 行不再挂 .callout 与 data-callout(防 片段双命中/双绘制);.callout-title/.callout-content/quiet/圆角行类 照挂(quiet 只承担紫条静默) - 嵌入保护:calloutWrapFacet 开关驱动发射让位——引用嵌入实例不装配 wrapper(行级全形态保留),修复首版「嵌入视图既无 wrapper 又无行级 视觉」的裸形态缺陷 - 列表内 callout v1 维持行级全形态(边界如实登记) CSS:wrapper 消费 --callout-padding 四向真内边距、border 三件套四边 完整(此前 Live 仅左缘近似)、圆角、双通道底色——与阅读容器同款; wrapper 禁垂直 margin 纪律写入条目(探针 S1b/S1c);blend 仍不承诺 Live(边界登记)。热更新测量刷新边界实测(styles 变更坐标映射不自愈) 写入条目 states。 条目与指南:callout / var-callout-color / limit-callout 三条目 purpose/dom/states 修订 + 英文文案同步;gen:styleguide 产物重生成。 测试: - 单测:liveCallout 断言迁 wrapper 契约(+嵌入形态保留用例)、 liveCalloutWrap 补 13 类型/别名/未知类型矩阵;受影响面 165+31 例全绿 - 浏览器:7 个 callout 族套件断言迁移后全绿(行级 data-callout 断言 改 wrapper/嵌套 DOM 承载;calloutIcon 边框断言升级为四边完整消费) - 发现并修复 fixture 既有 bug:calloutFold/calloutWrap fixture init 版本恒 1 被宿主协议去重(多段 re-init 一直在旧文档上跑);calloutFold 九段随之暴露「长流程后 re-init 失效 + reading 挂载窗口依赖」—— 九段显式 SKIP(不静默降级),根因独立跟踪 #676 - 外围:codeCardClickOffset / chromeContract 零回归 Close #673(热更新测量刷新的工程接线与双主题截图对照随 T05 收尾票补, 当前边界已如实写入契约条目)
#674(Callout Live 收口批次):把 BlockWrapper 探针 S3 验证过的「剥引用 前缀识别」从临时补丁落成生产代码——引用内围栏与多行公式此前不识别 (遇 > 前缀整行跳过),是 #670 完整渲染的内容前提。 - src/shared/math.ts - 新增引用前缀工具单一事实源:stripQuotePrefix(剥全部层,返回裸行/ 层数/剥除长度)与 stripQuoteLayers(剥恰好 n 层,不足返回 null), 每层 `>` + 可选一个空格(CommonMark blockquote 标记消耗口径) - 新增 ContentLineMapEntry:扫描产物内容段 → 原文行偏移映射条目 (折算式 lineStart + prefixLen + (offset − contentOffset)),T07 token 着色与装饰锚定的换算输入,随扫描产物一并产出 - scanMathRanges 块模式前缀感知:开启判定输入裸行(from/to 折算回 全文坐标、tex 剥前缀);内容/闭合行剥开启行层数,层数不足的断开行 原样吃进(跨容器延续——对齐 @vscode/markdown-it-katex 的 src 级 贪婪,实测 `> $$\nx\n> $$` 插件 content 含断开行);行内路径一行 不动(原行原坐标),MathOccurrence 增 lineMap(行内命中为空数组) - src/shared/mermaid.ts - scanFencesDetailed 前缀感知:识别输入为剥前缀裸行(缩进/围栏判定 口径不变),from/to 保持全文坐标、code 剥前缀;开闭同容器——闭合 行剥开启层数后须是纯闭合围栏,层数不足即容器断开、未闭合终止不产出 (对齐 CommonMark 核心规则:markdown-it 引用内 fence 断开处自动 闭合,live 降级显源码方向安全),断开行落回普通重扫不吞行 - FenceSpan/OpenFence 增 lineMap,OpenFence 增 depth(跨批续扫的同 容器判定依据);前缀工具与映射条目复用 math.ts,不建第二份 - src/webview(消费方接线) - liveMermaid/liveMath 增量重建的窗口外保留项携带 lineMap,且锚点 lineStart 随编辑 mapPos 映射(与 from/to 同源——liveMath 既有 编辑序列对拍暴露过锚点残留旧坐标的缺陷,已修并有钉子用例) - liveMath scanOpenIncrement 开启/闭合判定改用剥前缀裸行(增量 延伸与全量扫描对 `> $$` 同口径) - 测试(TDD:先红后绿,两矩阵 21 个新用例先行失败后转绿) - mermaidFence/mathScan:1/2/3 层与不定长前缀、> 无空格、同容器 开闭、未闭合降级、字面 >(含顶层围栏内容行不剥钉子)、相对缩进 0-3/4 列与 Tab、跨扫描窗口与跨容器边界续扫、lineMap 逐段锚定 - liveMermaid/liveMath:引用内固定编辑序列(前缀加深、容器断开、 闭合删除、行内共存)每步增量 vs 全量逐字段对拍;窗口外保留项 lineStart 映射钉子 - readingMath/readingMermaid:同例双端对拍一致(含容器断开延续); 三处已知差异如实钉住不追赶——空内容块阅读渲染空公式(既有差异随 前缀平移)、引用内 Tab 阅读出 fence(markdown-it 引用内不折算 4 列,live 保守不识别)、容器断开围栏阅读自动闭合出空容器 Close #674
T04(#672)/T05(#673)code-review 可执行项收口,含一处防雷与两处契约 半边补实;登记不修项见正文末。 ## 样式(src/webview/main.css) - **T05-P1 让位规则排除代码卡行(防雷)**:T06 起引用内围栏被扫描器识别, callout 内代码卡内容行同挂 quiet + code-card-line,行级让位规则 (1,5,0) 命中会清零卡行规则 (1,4,0) 的 padding-left 而负 text-indent 存活——悬挂缩进塌陷、行号甩出 wrapper 盒外、卡底色一并被清(探针 报告 §4.3 形态,一次性探针实测复现:修复前行号 x64 甩出盒左缘 x70、 padding-left 0px / text-indent -38px)。让位规则追加 :not(.vsidian-code-card-line) 排除后实测恢复同源对(38px/-38px)、 行号入盒、卡底色回归;紫条回归基础引用规则,与「普通引用内代码卡行」 同形态(T06 统一语义),观感复核点登记 A86。 - **T05-P2 wrapper 容器规则补 margin: 0**:探针 S1b/S1c 钉死的垂直 margin 禁令此前只有契约注释半边——常见 Obsidian 片段 `.callout { margin: 10px 0 }` (0,1,0) 命中 Live wrapper 会触发确定性 点击错行;规则侧显式归零后片段 margin 不再进入落点记账。 ## 契约(src/shared/styleContract.ts + styleContractEn.ts,指南产物再生成) - callout 条目 purpose/dom 同步登记上述两处接缝(双语):margin 禁令的 规则半边、让位规则的 :not 排除与卡行规则族的承载关系。条目 target 与类名 token 未动,无需基线重锚(entry-comparison 零失败)。 - 指南产物随 compile 链再生成入库(styleGuideData.ts / style-reference.*)。 ## 测试 - **T05-S1**:calloutCssContract 补 wrapper 两条规则的契约断言(容器 margin/padding/border/radius/双通道底色 + 让位规则 :not 防雷与四项 让位声明)——契约条目 verification 已登记的「T05 wrapper 容器视觉与 行级让位」单元覆盖落为真实存在。 - **T04 评审四项**(liveCalloutWrap.ts):删自建 WRAP_DESCEND_NAMES 改 import liveDecorations 导出的 CALLOUT_CONTAINER_NAMES(消除可漂移的 第二份集合);descend else-if 分支恒真参数简化为直传 true、inList 时 先判再识别(跳过列表内声明白扫描);calloutWrapRank 深度边界登记 (CM6 侧 clamp [0,100] 使 >6 层饱和 0,同 rank 嵌套由区间 tie-break 维持——rank 未写入公开契约,不预钳制);浏览器 calloutWrap 补列表内 正文行 wrapDepth=null 直接断言(此前仅由 count=3 间接排除)。 ## 文档 - **T05-P3**:manual-verification 登记 A86——探针 §4.5 存疑项(复制 按钮图标可辨度、标题旁小蓝点成因)与修复后新形态(卡行紫条、嵌套 观感)的人工验收条目。 ## 登记不修(评审裁定,不在本提交范围) - T05-S2 列表排除两处判定形态不同(遍历 flag vs path 数组,注释已声明 同口径)——等列表内 callout 接 wrapper 票统一; - T05-S3 emitForRange 16 参收拢——独立重构票; - T04 区间换算下沉 shared——两行收益小; - T05-P4 双主题截图 + 热更新刷新——由编排层开票。 验证:compile 零错误;定向单测 95 例全绿(calloutCssContract 23 + liveCalloutWrap 15 + liveCallout 31 + styleContract/styleGuideGen 26); check:stylecontract 八项零失败;浏览器 calloutPaint/calloutIcon/ calloutTypes/calloutWrap 四套件通过;防雷探针 before/after 取证落 out/test/callout-codecard-probe/(日志 t05-review-*.log)。
#675(Callout Live 收口批次末票):T06 让引用内围栏/公式被扫描识别后, 消费端 token 着色仍按「行首即裸内容起点」直加映射,第二行起错位逐行 累积(探针 §4.2 实证);math 装饰锚定经生产装配实证已被 T06 的 from/to 前缀折算顺带覆盖(探针 §4.1 泄漏系当时补丁形态),本票钉住并在 wrapper 下完成组合验证。 - src/shared/math.ts - 新增 mapContentOffsetToDoc:裸内容串 offset → 原文全文 offset 的 逐段折算(ContentLineMapEntry 语义的单一消费入口),FenceSpan 与 MathOccurrence 两族内容段共用,消费端不建第二份映射;二分查找, 长块 token 总量 O(n log n);空 lineMap 返回 -1(调用方丢弃) - src/webview/liveCodeCard.ts - token 着色改逐行前缀感知映射:seg.from/seg.to 经 mapContentOffsetToDoc(fence.lineMap, …) 折算回原文坐标,替换 openLine.to + 1 + tokenOffset 直加(引用内每行前缀不等长且逐行 累积错位;顶层无前缀时折算与直加等价,零回归) - src/webview/liveMath.ts(无实现改动,实证 + 钉住) - 生产装配浏览器探针实证:引用内多行公式整块被跨行 replace 覆盖、 KaTeX 成型无源文泄漏(textContent 中的源文是 KaTeX annotation 的 正常组成);探针 §4.1 的泄漏系当时临时补丁未折算 from/to,T06 生产实现已正确——本票以单测钉住锚定语义,不重复实现 - 测试(TDD:token 矩阵 4 用例先红——『> con』右移与跨行累积错位, 实现后转绿) - liveCodeCard.test:引用内 token 对位矩阵(一层前缀两行、> > 与 > 无空格不定长、内容行缩进折算、空内容行零长段、顶层对照) - mathScan.test:mapContentOffsetToDoc 纯函数契约(段内/段尾归属、 零长段不劫持、空表 -1、FenceSpan 同语义折算) - liveMath.test:引用内锚定矩阵(多行块 replace/mark 从开行 $$ 到 闭行 $$ 尾不吞开行前缀、行内原行坐标、单行块段内折算) - calloutWrap 浏览器套件扩 T07 组合场景:引用内代码卡 + 多行公式 + 嵌套 callout 单一 wrapper 承载;绘制层断言卡 chrome/行号入盒 (T05 防雷)/token 对位/公式无泄漏/前缀全隐/尾部不吞(S3); 20 同坐标点击、折叠展开往返、复制内容剥前缀、增量键入与删字符 后装饰仍对;截图留证 out/test/t07-callout-combo-*.png 已知边界(如实):点击序列中光标离开代码块时围栏行由显形恢复清空、 行高变化致下方行上移是显隐语义(非 wrapper 缺陷),套件按「几何落地 后再连击」编排;公式 widget 点击定位落在块端点是 CM6 inline replace 的 posAtDOM 语义。 验证:compile 零错误;单测全量 10180+196 全绿(分支单测终检);浏览器 codeCardChrome/codeCardClickOffset/mermaidPaint/calloutWrap 四套件 通过(token 对位与公式无泄漏断言含绘制层)。 Close #675
T07(f5bd1070)code-review 三项轻微发现的处置: - mathScan 手算注释钉正:闭行前段 lineStart 误写 16,实为 17 (17 = 第 3 行行首 11 + 行长 5 + 换行 1;16 是第 3 行末换行符 位置),改为正确坐标并就地注明换算依据。其余行(0/5/11)与 FenceSpan 注释(8/22、offset 12)逐项复核无误,测试断言本身 引用实际计算值不受影响。 - calloutWrap combo 场景补 emptyFenceRows 断言:该字段此前是 evaluate 返回但未断言的死观测。实测取证(2026-10-31,报告 out/test/browser-runs/run-vz15HW/)确认文档 13 行无空行时空 文本行恰为 2——正是两个围栏行(```js / ```)被 replace 清空 的形态。补 `equal(2)` 断言钉住:quotePrefixed 只抓 > 残留, 围栏行 replace 失效时 ``` 残留不以 > 开头会逃过既有断言,此 处是唯一观测点。 - 「换行」项登记为未验证、不在组合场景补断言:Live 代码卡 chrome 只装 copy/fold 两键(liveCodeCard.ts),buildWrapButton 仅阅读侧(readingCodeCard #191)消费——Live 引用内不存在 「卡内换行开关」入口;且观测 wrap 需长行文本,改 T07_DOC 文 本会波及 linenos/keywords/copy 等一串锚定断言,成本超出一个 断言。#191 折行本体已由 codeCardChrome.mjs 顶层(阅读态 nowrap 联动)覆盖,引用内 Live wrap 形态留待编排层在 #675 关闭评论记录。
ONEGAYI
left a comment
There was a problem hiding this comment.
PR 审查 · 首审 · R1
仓库/PR:#678
快照:head 02bc09351668e05eb3bc1cdf5a90584332bf77ac;base/merge-base 3d70cb36ca6c29cabcd718eaaaf7e5dd5718ecb5。45 文件,完整 Git 工作树;先核对 reviews/全部原线程为空,发布前仍是同 head/open。
依据:#668、#672–#675 及其修订评论,#676/#677 边界;本 head AGENTS.md、style-contract 技能、callout 规格与 ADR-0023;用户指定 PR 发布规范。
结论
已完成两轴亲审,确认两项实现问题,见本轮行内线程。全量单测通过不覆盖这两种输入边界。本 COMMENT 不是合并批准或完整宿主/视觉验收。
Spec
- vsidianPR678-001 · P2 · exists:wrapper 的后代让位规则误清除其内部列表 Callout 的保留行级视觉。
- vsidianPR678-002 · P3 · exists:续扫将一个空内容行当零行,新增引用围栏的增量渲染/复制丢掉首个空行。顶层同类缺口基线已有,归本次新增能力的验收遗漏,不冒称全新底层回归。
- 容器区间消费解析器节点、行对齐、懒延续归属与 Reading 一致;不恢复已撤回的“解析器区间缺陷”判断。列表/嵌入不装 wrapper、标题文字编辑/箭头折叠与光标行为的既定边界不因本轮扩展。
- 扫描产物随行携带映射、窗口外 lineMap 随 changes 平移;token 消费使用同一折算入口。除上述002外,原定向矩阵通过。公式跨引用边界的贪婪口径与围栏不同,按既有 Reading 引擎区分,不误合并两套规则。
- #677 热 padding/border 更新后的坐标刷新未完成,只有冷重建后精度;不能把当前浏览器脚本的模式往返对照写成热更新直接通过。引用内 wrap 组合、列表/表格/图片/嵌入回归与 A85/A86 仍有明确未验范围。
Standards
未另登记独立新 Standards 缺陷;样式类名/变量/指南生成链有对照,检查器通过不等于 DOM 关系与绘制兼容全部成立(001即反例)。
保留以下未闭环证据边界:
- #676 九段 re-init/挂载问题以显式 SKIP 绕过,末尾“全部通过”不表示该场景执行;旧 fixture 同版本去重造成旧文档上断言的历史不注销。这里已有独立票,不重复创造根因或宣称产品根因已知。
- perf 文档仍包含 V02 时“完整卡不可行/只高亮待决策”和引用块未渲染的阶段性文字,应结合后续 BlockWrapper 报告与本 PR 理解,不能据旧探针宣布当前能力不可行,也不能把阶段报告当验收。
- 未将票面“用户授权”转成新的推送、合并、重跑或发布权限。
本方验证
Linux Node24.22.1,完整精确 head 工作树:
- compile(生成器/esbuild/tsc)通过,生成产物无跟踪文件变化;git diff --check通过。
- Vitest 10177 passed / 3 skipped(443 pass文件、1 skip文件);Node 189 passed / 7 skipped,共196,不写“196全部通过”。
- check:stylecontract 8项通过;本地部分新tag未获取有明确warning,未据此确认新版本发行。
- 全量使用既有依赖目录,逐项比对 lock 所有非optional包版本无差异;随后独立临时安装锁定版本/完整性(只将下载host换为官方npm,产品lock未改),当前11个相关测试文件 363 passed,base相应10文件 293 passed。
- 额外生产 scanner/StateField/header载荷探针确认002;原wrapper区间/行装饰输出加受控DOM与CSS层叠对照确认001。不是物理剪贴板、真实输入或浏览器绘制验证。
- 首次依赖安装因默认cache目录不可写/下载与安装目录冲突失败保留,独立新目录与可写cache后成功;不是产品失败。自制StateField探针首次混入两份CM state报Unrecognized extension,统一同一模块后完成复现,首败保留。未改产品代码。
- 浏览器 calloutWrap 启动首次因缺Chromium失败;官方浏览器下载得到无效/截断ZIP,安装未完成。本方未运行成功真实Chromium/VSCode/Windows、物理鼠标/IME/截图或10万行性能;作者浏览器成功记录不计入本方。
- 精确head CI 41207424198仍在运行,已见style-contract/API/text-appearance/敏感组成功,主browser/unit/集成分片尚未全终态;继续观察,不重跑,不称全绿。
所有测试首败与基线保留。本次只发 COMMENT 与两条行内,不自动 resolve。
人工验收(2026-10-31)两项反馈修复: - 多行选区只显光标行 `>`(Obsidian 为选区覆盖行全部显形): liveDecorations 新增 selectionRevealsLineMarkers 谓词——空选区 维持 #296 端点语义(层级编辑入口不变,callout 标题 marker 保持 整行区间),非空选区与所在行相交即显形该行源文标记;表格上下文 刻意不随改判放宽(格内拖选跨格纳入引用符号是 #296 三轮已修缺陷, 表格三处前缀谓词与 QuoteMark 于表格行维持纯端点语义——表格行 形态按 GFM 树实测 nextSibling/parent 为 Table 判定,path 不含 Table)。QuoteMark/ListMark/callout 标题 marker 三处换用。 - callout 代码块内换行不补 `> `(裸行掉出引用容器): listEditing 的代码上下文排除改为「仅顶层(行无引用前缀)」—— 引用内围栏行 Enter 延续完整引用前缀(嵌套 `> > ` 同理); 顶层围栏维持 #119 字面编辑边界不动。 测试:listEditing/liveDecorations 各加 describe(红→绿:引用内 围栏延续 2 例 + 顶层不接管钉住;选区覆盖 3 例 + 空选区分寸/表格 端点/callout 标题钉住 3 例);全量单测 EXIT=0;浏览器 calloutPaint/calloutTypes/calloutWrap/blockquoteTablePaint 绿—— 其中两处「拖选逐字节等于源区间」断言改覆盖语义(from 精确、 to 容差 1:拖选路径标记显形右移、释放像素映射左偏的机械伴生)。 规格:blockquote-table.md 补端点语义范围改判记录(非表格行)。 关联 #668(批次)、A86 人工验收
人工验收判定:卡行左缘紫条是双重强调——卡片自带边界视觉(底色/ 边框),Obsidian 的 callout 内代码块亦无标记条。基础引用行规则 (#143 紫条/左内边距/底色)加 :not(.vsidian-code-card-line) 排除 卡行;与 T05 让位规则的 :not 防雷互为姊妹排除(卡行不受任何引用 行基础视觉作用)。 契约:quoteBar/callout/headingPaint 三处 CSS 契约断言的选择器 形态同步;check:stylecontract 八项零失败(token 只增,免重锚)。 manual-verification:A86 转「部分验证」,登记本轮处置(③移除 + 选区覆盖显形 + 围栏换行延续)与待续验项(①②④)。 关联 #668(批次)、A86-③
ONEGAYI
left a comment
There was a problem hiding this comment.
R2 亲审增量
Head 66e461096f8a9e69d20449e672ffd5205efe4bbf;base/merge-base 3d70cb36ca6c29cabcd718eaaaf7e5dd5718ecb5。对R1的02bc0935新增2提交12文件,已核对原reviews/全部线程。
Spec
- 新增 vsidianPR678-003 P2 exists:引用围栏内形似列表的代码被当Markdown列表续写,生产EditorView/jsdom对照复现,见本轮行内。
- 001列表内Callout被wrapper让位规则清空、002空内容行续扫漏换行均仍exists;相关根因代码未改,范围未变,不重复原线程评论。
- 非表格选区改为覆盖行显形、表格保持端点语义,以及代码卡移除引用紫条,与本轮更新规格/人工反馈记录相符;不把作者人工验收记录冒充本方视觉验收。A86①②④、#676/#677边界继续保留。
Standards
未确认额外独立Standards缺陷。两项浏览器拖选断言放宽为终点左偏≤1,已在规格登记,但本方未独立验证像素偏移因果或真实拖选体验,不能因此宣称真宿主回归完成。
验证
本方Node24.22.1、精确Git工作树:相关5文件Vitest 167pass;compile通过;diff --check通过。复用依赖目录,锁文件全部非optional包版本逐项相符。003追加原EditorView/jsdom探针确证自动插入列表mark,旧head不接管;另一个空代码行探针两版均返回false,不能误当新回归。
首次命令指向已不存在的旧deps目录失败;改用版本核对后的目录。首次compile被本方临时探针未使用import阻断,移出探针后原产品compile通过,首次日志保留,非产品失败/flaky。无产品代码修改。
未重跑全量、真实VSCode/Windows/IME/物理键盘/剪贴板或本机Chromium绘制;云浏览器限制保留。CI run41218289253当前12jobs成功、browser仍运行,将继续核验终态,不重跑CI。旧head13/13成功保留,不能覆盖新增问题。
本次COMMENT不表示required approval或合并批准。
用户验收反馈(2026-11-01):长按 backspace 删空引用/callout 正文后,
OS 自动重复会继续一层层剥掉整段引用结构,需要防护。
- 判定信号:keydown 的 repeat 属性区分长按自动重复(true)与手动
单发(false);经 capture 阶段原生监听记录(ViewPlugin 挂
contentDOM keydown capture),无条件先于 keymap 冒泡处理。
- 防护点(stripListLayer 前置拦截,吞键无变更):
1) 引用前缀右端(原将一次剥层);
2) callout 标记右端(] 或吞并尾空格处,原将由默认路径逐字符吃掉
[!type]);标记右端不在 prefixEnd,判定置于 prefixEnd 收口之前。
- 范围限引用结构(prefix.quote 非空):纯列表行剥层节奏不变;
正文中间的真正内容删除不拦;选区/多光标/IME 组合维持不接管。
- 手动单发语义不变:前缀剥层一次一层,callout 标记手动删除仍为
默认逐字符(增强为一次删整段标记留待反馈)。
测试:listEditing 新 describe 六例(红→绿:拦截 3 + 手动剥层/纯
列表不防护/正文不误伤钉住 3,装配补 keymap.of(defaultKeymap) 使
默认删除路径真实在场);calloutWrap 浏览器补真长按场景——CDP
Input.dispatchKeyEvent autoRepeat 连发删空后停在前缀、手动单发
剥层清空(Playwright keyboard 不产生 repeat,真实长按语义只能经
CDP 直发)。全量单测 EXIT=0。
规格:keybindings.md #119 段补防护语义。
关联 #668(批次)
逐条修复行级评审(R1/R2 三线程): - **PR678-001(P2)**:让位规则误伤列表内 callout 的行级保留形态 ——外层 wrapper 后代中的列表内 callout 行被清成透明/零缩进/无条, 行级全形态(唯一容器视觉)消失。修:让位规则追加 :not(.callout) (wrapper 接管行在 wrapped 分支摘除行级 .callout,排除面精准); 契约断言同步 + liveCallout 补「外层 wrapper 内列表 callout 行挂 .callout」装饰断言。 - **PR678-002(P3)**:续扫把「一个空内容行」误当零行(code 空串 歧义)——增量产物与全量分叉、复制载荷少换行。修:以 lineMap 条目 数消歧(多行全空时 code 为 '\n…' 非空不歧义);补一个空行与多空行 跨批对拍两例(评审复现路径)。 - **PR678-003(P2)**:引用内围栏把代码字面列表标记当 Markdown 续 写(`> - literal` 行尾 Enter 误插 `> - `)。修:围栏成员资格按 FencedCode 区间判定(链式判定漏裸 `>` 行——其 quote 属 QuoteMark, 实测树形态钉住),ctx 携带 inFence;Enter 只延续 quote(规范补空 格,有序/任务形态同禁),Backspace 不做结构剥层(纯字面)、长按 防护点前移到 quote 右端;空代码行不走空项退出。补七例红→绿 (含普通引用列表回归钉住)。 验证:全量单测 EXIT=0(新增 10 例);compile 绿;浏览器 calloutPaint/calloutTypes/calloutWrap/blockquoteTablePaint/codeCardChrome 五套件绿;check:stylecontract 八项零失败(token 只增免重锚)。 浏览器「外层 wrapper 内列表 callout」真实绘制断言随 P2 回归票 (引用内列表 wrapper 场景 fixture 改动波及既有坐标断言,另行落地)。
ONEGAYI
left a comment
There was a problem hiding this comment.
R3 亲审复审
Head 878420b0a067db24b321ce5dd362e203ab148083;base/merge-base 3d70cb36ca6c29cabcd718eaaaf7e5dd5718ecb5。相对已审415148a3增量1提交7文件,原reviews/三线程及作者回复已读。
Spec
vsidianPR678-001/002/003均fixed(各原触发范围),已沿原线程分别补充证据,未resolve。001排除行级.callout保留形态,002续扫保留一个空内容行及复制载荷,003围栏字面mark不再做Markdown列表续写。未发现新增独立证实问题。
Standards
未发现新增独立问题。001真实绘制断言仍待后续场景覆盖;不得因选择器/装饰层通过就称浏览器视觉验收完成。#676/#677、A86其他观感边界保留。旧quoteBarPaint拖选断言失败不由这三项修复自动注销。
本方验证
Node24.22.1、精确Git工作树;相关4文件 145pass,compile及diffcheck通过。额外2项独立探针通过:原StateField增量/全量+实际HeaderWidget.code载荷对照;生产CSS选择器的DOM.matches保留/让位/代码卡三种分类。复用版本逐项核对相符的依赖,无产品修改。
未重跑全量、实际浏览器绘制/VSCode/Windows/物理剪贴板/OS长按;作者五浏览器套件成功是作者证据。前轮66e46109与415148a3的CI均12成功1失败,quoteBarPaint实际from4/to16、预期from4/to18的首败日志和artifact保留,未称flaky。
当前CI41220290364仍运行,继续只读核验终态,不重跑CI。本次COMMENT不表示required approval或合并批准。
CI browser job 的 quoteBarPaint 在 quote-list 场景断言失败 (to=16 vs 期望 18)。根因探针定量确认:A86 选区覆盖显形 (2026-10-31 用户拍板)使拖选中 QuoteMark 显形、正文右移一个 前缀宽(14px = 2 字符位),终点像素取自显形前布局故命中 to-2;quote 场景 from 贴 QuoteMark 右端、起始即显形无偏移, 故仅 quote-list 挂红。行为符合改判语义,断言残留 #143 时代 的逐字节口径——与 calloutPaint/calloutTypes 已改两处同型, 本文件当时漏同步。 - 断言改覆盖语义:起点精确命中 + 终点容差 ≤2(探针定量的 显形前缀宽度折算字符位),注释记录依据与场景差异 - 本地复现红(run-A1IYpW)→ 修复后全场景绿(run-YuJ36W)
用户宿主验收(A87,2026-11-01)两项反馈: 1. 显形态的 > 与 [!xx] 以转义符式透明度弱化(opacity 0.55, 随主题前景适配明暗)。liveDecorations 新增 syntaxMarkDeco: QuoteMark(含表格端点显形分支)与 callout 声明(含吞并尾 空格)显形时发射;区间只包纯语法——标题文字与正文不进灰化, 「不伤非语法部分」由区间来源保证。隐藏态照旧渲染 widget。 2. 行内代码加 1px inset 细边线(用户拍板方案 A):固定灰底在 部分 callout 容器底色上对比不足,边线与容器底色解耦(VSCode 官方 Markdown 预览的 code 同为底色+边线组合)。box-shadow inset 不占布局;Live(--vsidian-live-code-border)与阅读 (--vsidian-reading-code-border,链结构对齐底色变量)双模式 同步,底色维持不动。 - 单测:liveDecorations 新 5 例(显形灰化区间/标题不挂/隐藏态 钉住/表格端点/正文不挂)红→绿 - 浏览器绘制断言(calloutPaint):拖选覆盖态 > 与 [!note] 的 computed opacity=0.55、标题正文不进灰化;callout 内行内代码 双模式 1px 边线 computed 在场、底色维持 - 全量单测 10210 例 / compile / 契约八项 / calloutPaint 全绿
ONEGAYI
left a comment
There was a problem hiding this comment.
R4 亲审复审
Head 0acbc5be6fc1c3facae27716e8f98c706e193b9b;base/merge-base 3d70cb36ca6c29cabcd718eaaaf7e5dd5718ecb5。相对已审8e23d654为1提交4文件;发布前已复核open/head及reviews无并发新增,全部3原线程已读(作者已resolve,本方未操作)。
Spec
新增 vsidianPR678-004 · P3 · exists:阅读侧新增行内代码边线同时作用于pre里的块级code,与本提交限定行内、注释声称块级已重置的边界不符,见行内证据。001–003原修复未被本增量修改。
显形QuoteMark与callout声明弱化范围独立于标题正文,新增5种区间断言通过。A87依据为本提交描述;固定head人工验收文档尚无A87,作者宿主反馈不记为本方验收。
Standards
未另建独立Standards缺陷。新增浏览器断言核对computed opacity与boxShadow,不只是DOM存在;但未覆盖块级代码负向边界。旧#676/#677与A86未验边界保留。
本方验证与边界
完整Git固定head,liveDecorations单文件100pass(含新增5例);JS语法与diff检查通过。基于两条原样生产CSS规则、相同jsdom DOM的旧head/新head对照:旧inline和pre code均无shadow,新二者均获得inset1px规则,pre reset只重置font/background/padding,未重置shadow。这是CSS适用关系和受控DOM证据,不冒充真实Chromium绘制/VSCode/Windows验收;未重跑全量业务测试。作者全量10210/浏览器成功仅作者证据。
当前CI41259429892仍运行,继续只读跟至终态,不重跑。本轮仅COMMENT与一个新独立线程,不是合并批准。
| background-color: var(--vsidian-reading-code-background); | ||
| /* A87(2026-11-01)与 live 侧 .vsidian-inline-code 同步的 1px 边线 | ||
| (callout 容器底色上的可辨性;pre 内块级 code 已重置不承边线) */ | ||
| box-shadow: inset 0 0 0 1px var(--vsidian-reading-code-border, rgba(128, 128, 128, 0.4)); |
There was a problem hiding this comment.
vsidianPR678-004 · P3 · Spec:行内代码边线泄漏到阅读态块级代码
本提交/A87描述限定「行内代码加1px inset边线」,注释还明确称pre内块级code已重置。但此选择器匹配所有code,包括pre code;上方4238–4242的更具体规则仅设置font-family/background/padding,没有box-shadow,因此不能覆盖本新增属性。
触发:Reading中普通围栏/缩进代码的pre>code,尤其关闭代码卡时保留的朴素产物(readingCodeCard.ts明示两开关皆关不触碰)。影响:块级代码文本也多出本应仅用于行内代码的细框;不是只有callout内inline被改变。
本方原样两条CSS+同一jsdom DOM对照:旧8e23d654 inline/pre两者shadow为空,新0acbc5be两者都为inset 0 0 0 1px var(...)。全源码未见其他pre code shadow重置;这是受控CSS/DOM证据,未冒充宿主截图。
建议将新增规则限于非pre行内code,或在pre code明确重置box-shadow;补阅读态inline正向与fenced/indented块级code负向(含代码卡开关)的computed样式断言。
There was a problem hiding this comment.
vsidianPR678-004 · 修复 e2d01f2 · 待复审
- 修复:e2d01f25
pre code重置规则显式补box-shadow: none(采纳备选二:块级排除集中在既有重置点,行内选择器保持简单形态)。审查证据链确认无误——A87 一轮我加的 box-shadow 层叠进 pre>code,既有重置规则未声明该属性盖不住,块级代码被套行内细框。 - 验证:calloutPaint 浏览器套件新增负向矩阵——fixture 增顶层缩进代码块,断言阅读态 fenced(callout 内 ```md)与缩进(顶层 4 空格)两类
pre>code的 computed boxShadow === 'none';行内 code 正向断言同步升级(边线 alpha ≥ 0.6)。全套件绿(run-IapGf5);全量单测 10210 例 / compile / 契约八项绿。 - 边界:审查建议的「代码卡开关两态」宿主变体未在浏览器 fixture 覆盖——fixture 走朴素 reading 渲染(无卡开关链路),朴素产物即负向断言对象;卡开启态的块级呈现走 code-card 容器(无 code 元素直挂边线路径),泄漏面不适用。人工验收随 A87 轮宿主重验覆盖。
There was a problem hiding this comment.
vsidianPR678-004 · 复审 e2d01f2 · fixed(原pre code边线泄漏范围)
既有pre code规则新增box-shadow:none,特异性高于通用code规则,块级不再继承新增行内边线。原样生产两条CSS+同一jsdom DOM对拍:旧0acbc5be inline/pre均为inset1px,新head inline仍为inset1px、pre为none。新增浏览器负向检查同时覆盖fenced/缩进两类pre code,源码已读,本方未在Chromium执行;作者run-IapGf5成功仍为作者证据。
本方精确head readingCodeCard/liveDecorations合计172pass,JS语法/diff通过。代码卡开关宿主变体未本方验收;本次确认原CSS层叠缺口修复,不扩大为全部A87视觉验收。保留首轮失败证据,不resolve。
There was a problem hiding this comment.
vsidianPR678-004 · 修复 685cce1 · 待复审
- 处置:随行内代码边线整体撤除(用户验收澄清:三轮边线误实现在行内代码上,诉求对象是 callout 内的代码块卡片;误向实现连同本线程所述泄漏面一并移除——live/阅读 box-shadow、--vsidian-reading-code-border 变量、pre code 重置全撤,浏览器断言同步撤净)。
- 边界:本线程问题不复存在(无泄漏源);代码卡壳边线为正确对象的新实现(卡行 inset 线 + header border,--vsidian-code-card-border),calloutPaint/codeCardChrome computed 断言在场。
- 关联:005(整篇围栏无尾换行的折叠遗漏)同提交修复,见 005 线程。
There was a problem hiding this comment.
vsidianPR678-004 · 复审 685cce1 · fixed(泄漏源整体撤除)
本轮撤除Live/Reading行内code的新增box-shadow与变量,连同pre code重置一起回退,原泄漏源已不存在。此前e2d的限定重置修复证据仍保留;当前是需求对象从行内代码改为代码块卡壳后的撤除,不称原行内边线功能继续验收通过。新卡行inset/header/Reading卡壳边线源码与computed测试已读,本方未执行真实绘制。作者对需求澄清的记录不扩大本方操作权限。
A87 二轮验收反馈 + PR 复审 P3 一并修复: 1. 边线可见度(验收反馈「白底上灰字」):0.4 透明灰叠 14% 灰底 同色系形同虚设——默认链改主题边框色 --vscode-editorWidget-border(实色、亮暗自适应),末级 fallback 提到 0.6。live(--vsidian-live-code-border)与阅读 (--vsidian-reading-code-border)双模式同链。 2. PR678-004(P3):行内边线泄漏到阅读态块级代码——code 规则的 box-shadow 层叠进 pre>code(既有 pre code 重置规则未声明该属性 盖不住),围栏/缩进块级代码四周被套行内细框。pre code 重置规则 显式补 box-shadow: none。 - 浏览器断言(calloutPaint):边线 alpha ≥ 0.6 钉住可见度;新增 fenced 与缩进两类块级 code 的 shadow=none 负向断言(004 复审 要求的负向矩阵) - 全量单测 10210 例 / compile / 契约八项 / calloutPaint 全绿
ONEGAYI
left a comment
There was a problem hiding this comment.
R5 亲审复审
Head e2d01f250ede0ecd644d3822c0e7489852727167;base/merge-base 3d70cb36ca6c29cabcd718eaaaf7e5dd5718ecb5。相对0acbc5be为1提交2文件。全部原线程/作者004回复已读,发布前复核同head/open且无并发新review。
Spec
vsidianPR678-004 fixed(原块级code细框泄漏),已沿原线程回复证据;001–003既有修复未改变。未发现新增独立证实问题。行内边线默认改为主题边框色,fallback alpha0.6;不以透明度门槛断言替代所有主题下的实际对比度/用户观感验收。
Standards
新增fenced与缩进块级code的computed boxShadow负向断言,与inline正向断言配对;未发现独立Standards问题。实际代码卡开关宿主变体未执行,作者浏览器fixture走朴素Reading产物,边界保持明确。
本方验证
Node24.22.1,固定完整Git工作树:readingCodeCard/liveDecorations两文件 172pass;原样生产CSS两规则旧/新jsdom对拍,inline保留边线、pre从inset1px变none;JS语法、git diff --check通过。未改产品代码,未重跑全量/真实Chromium/VSCode/Windows或物理输入。作者10210/compile/契约/browser记录不计作本方执行。
旧0acbc5be CI41259429892已cancelled(取消前12job成功、browser未完成),不称绿、不归flaky;新CI41259958425仍运行,继续只读核验终态,不重跑。所有旧失败证据保留。本轮仅COMMENT,不APPROVE/resolve。
用户宿主验收(A87 三轮,2026-11-01)两项: 1. 光标在代码卡内点击折叠:收起并自动旁落光标(对齐 calloutFold 的 migrateSelectionForCalloutFold 模式)。根因:isFolded 被 editing 判定(selectionTouchesRange 闭区间)压住——光标在卡内 时点击折叠「块根本折不上」。codeCardState 新增 migrateSelectionForCodeCardFold(触及语义与装饰层一致:空选区 闭区间、非空开区间相交;落点 = 隐藏区间外紧贴卡头的块上一行 行尾,文档首行围栏退块后);toggleFold 事务同携旁落,effect 值归一为围栏起始位置(fold 集合标识键)。 2. 行内代码边线参照系改判(验收质询「较于全局背景还是临近 callout」):原默认链的主题 widget token(editorWidget-border) 不感知容器且部分主题下值不可用(实际无边框)——弃用。默认改 不透明中灰 rgb(127,127,127):对比对象是紧贴底色(14% 灰叠容器 底),亮底呈深线、暗底呈亮线,任何容器底上拉开至少一档。 - 单测:liveCodeCard 新 5 例(纯函数 4 + 装饰组合「事务同携折叠 与旁落后收起真实呈现」)红→绿 - 浏览器:codeCardChrome 新真实点击场景(点代码行进卡→点折叠→ 收起在场 + 光标旁落块外 + 不被编辑态压回);calloutPaint 边线 alpha 断言随不透明中灰保持 - 全量单测 10215 例 / compile / 契约八项 / 双浏览器套件全绿
ONEGAYI
left a comment
There was a problem hiding this comment.
R6 亲审复审
Head 86bbaf62ba8c99d2388017b583b460a1a63745fd;base/merge-base仍3d70cb36ca6c29cabcd718eaaaf7e5dd5718ecb5。相对e2d01f25为1提交5文件,全部原线程及提交规格已读,发布前仍同head/open,无并发新review。
Spec
新增 vsidianPR678-005 · P3 · exists:折叠旁落修复遗漏「围栏占满文档且末尾无换行」输入,落点被钳到围栏闭区间内,折叠仍被editing压回。属于本次明示修复范围的遗漏,旧版卡内点击本就不能折叠,不伪称本提交首次造成。见行内实际StateField/装饰证据。001–004原修复不变。
行内边线改不透明中灰,不再依赖主题widget变量;保留用户实际明暗/容器观感验收边界,不把固定灰色当作任意背景必然有对比。
Standards
未另建独立Standards缺陷。新增浏览器用例只覆盖块前有文字的旁落场景;新增纯函数首行用例的docLength=20、fenceTo=7仍预留了块后空间,未触及005。
本方验证与边界
精确Git工作树,原liveCodeCard 112pass(包含新5例)。额外3项生产StateField/mermaidFencesField/迁移函数/CodeCardHeaderWidget组合探针:块前有文字、末尾有换行两例通过;仅整篇围栏无末尾换行一例失败,from0/to13/docLength13/landing13,fold集合已标记而header.folded=false。合计114pass/1fail,失败保留,不归flaky。JS语法/diff检查通过,未改产品代码,临时测试已移除。
未执行实际浏览器/VSCode/Windows/物理点击或全量测试;作者10215/双浏览器成功仅作者证据。旧e2d01f25 CI41259958425仍运行,新head CI41260685363待运行,继续只读核验,不重跑。本轮仅COMMENT及新独立线程,不是合并批准。
| fenceTo: number, | ||
| docLength: number, | ||
| ): EditorSelection | null { | ||
| const landing = fenceFrom > 0 ? fenceFrom - 1 : Math.min(fenceTo + 1, docLength) |
There was a problem hiding this comment.
vsidianPR678-005 · P3 · Spec:整篇围栏无尾换行时旁落仍留在块内,折叠修复未生效
触发:文档仅为三行 js / x() / ,末尾无换行(13字符),光标位于x()后点击代码卡折叠。
本函数取Math.min(fenceTo+1,docLength)=13,但围栏是[0,13];liveCodeCard.ts550/554的selectionTouchesRange对空选区按闭区间判断,landing13仍editing=true,isFolded被压成false。用户仍看到展开态,不能完成本提交A87三轮所承诺的卡内点击折叠。
本方精确head生产EditorState、mermaidFencesField、迁移函数与codeCardDecorations组合:from0/to13/length13/landing13,fold effect已写入而CodeCardHeaderWidget.folded=false;同一探针在尾部增加换行或块前增加普通行均true。原112项liveCodeCard测试通过,但新增首行用例人为留出块后空间,没有覆盖整篇围栏。
这是已有卡内无法折叠问题的本轮修复遗漏,不说成新引入的原始问题。请为无块外合法位置定义可实现的折叠/选区策略(不应靠偷偷改源文制造空行),并补完整StateField/真实点击的EOF无换行与有换行对照。
There was a problem hiding this comment.
vsidianPR678-005 · 修复 685cce1 · 待复审
- 修复:editing 触及右界收一位——
fence.to === doc.length(整篇围栏无尾换行)时,块级 editing 判定用[fence.from, fence.to-1]:光标恰在块尾边界(head===fence.to===docLength)物理处于收起 replace 区间 [0, fence.to) 右界外、源码可见,不算编辑抑制;块外无合法位置的文档至此可收起。selectionTouchesRange 共享谓词本体未动(其余消费点语义不变)。旁落落点公式未动(该场景 min(fenceTo+1, docLength)=fenceTo,配合触及收窄后即为合法落点)。 - 键入安全:插入发生在边界外——回车起新行后围栏仍闭合、收起保持、新行内容在收起区间外可见(新增单测断言);直接贴闭围栏行尾打字母会破坏闭合围栏语法、卡正确退场显源码(源文语义,非隐藏输入),已在测试注释中澄清。
- 验证:liveCodeCard 新三例(无尾换行收起 / 有尾换行对照回归 / 收起态键入安全)红→绿,115 例全过;全量单测 10218 / compile / 契约八项 / calloutPaint + codeCardChrome 浏览器全绿(codeCardChrome 含真实点击折叠旁落场景)。
- 边界:真实点击的 EOF 无换行专用浏览器场景未单独落 fixture(现有点击场景的块前有内容、落 fenceFrom-1 路径已测;无尾换行路径由 StateField 单测钉住)——需要时随 P2 回归票补。
There was a problem hiding this comment.
vsidianPR678-005 · 复审 685cce1 · 部分修复/仍开放(边界问题转移)
已修部分:原整篇围栏无尾换行、卡内点击后空光标落EOF的案例现在能收起,本方原生产StateField组合探针转绿。
残留/转移:liveCodeCard.ts555把fence.to统一减1后,不只排除了EOF空光标,还截短了非空选区相交范围。对同一13字符文档,折叠后设置EditorSelection.single(12,13)(选中最后一个闭围栏反引号,亦可对应EOF处Shift+Left),本方原codeCardDecorations产出的header.folded仍true;实际已选中的源码字符仍被收起装饰遮住。原范围[0,13]下该非空选区与块相交,应临时展开;这是修复引出的边界转移,不另建重复ID。
精确head原115项liveCodeCard测试通过;额外原005探针通过、末字符非空选区探针失败,合计116pass/1fail。受控jsdom/生产StateField,不是真实键盘/宿主验收。建议只对空选区且head===fence.to===doc.length放宽右端点;非空选区继续使用真实[fence.from,fence.to)相交语义,并覆盖正反向选区及多光标。迁移源码:https://github.com/ONEGAYI/vsidian/blob/685cce1419a98911901bbff304d90606c00955ef/src/webview/liveCodeCard.ts#L555-L557 。不resolve。
There was a problem hiding this comment.
vsidianPR678-005 · 复审 d6808da · fixed(原EOF折叠及末字符选区转移范围)
新增blockEditingTouches只豁免空选区head===to===docLength,非空选区恢复真实[from,to)相交,其他块内空光标继续抑制折叠,未再统一截短右界。本方原生产StateField组合先执行卡内折叠旁落,再分别设置正向末字符选区、反向Shift+Left形态、真实启用allowMultipleSelections的两光标、单独EOF空光标,4例全部通过;多光标确认实际ranges.length=2,避免单光标配置吞掉场景。
原liveCodeCard与codeCardPaintCssContract两文件141pass,另4探针共145pass。原R6/R7失败保留,当前确认上述范围修复,不等于真实键盘/VSCode/浏览器观感验收;线程不resolve。
There was a problem hiding this comment.
vsidianPR678-005 · 修复 d6808da · 待复审
- 修复(边界转移收口):块级触及判定重写为 blockEditingTouches(liveCodeCard 模块级函数),放弃「fence.to 统一收窄」——唯一放行点是「空选区且 head === fence.to === doc.length」(原 005 主场景,物理在收起 replace 区间右界外);空选区其余位置维持闭区间(编辑便利语义)、非空选区维持真实开区间相交(与共享谓词一致,正反向/多光标语义不变)。选中最后闭围栏字符的源码选区恢复临时展开。
- 验证:按复审建议补正反向选区与多光标单例(正向 [12,13] / 反向 [13,12](EOF Shift+Left 形态)/ 多光标块内空光标 → 展开;EOF 空光标单独在场 → 收起保持),liveCodeCard 116 例全过;全量单测 10219 / compile / 契约八项 / calloutPaint + codeCardChrome 全绿。
- 另(同提交,验收截图反馈):卡壳边线统一 inset shadow 机制(header 顶/左/右与分隔线从 border 迁 shadow——border 与 shadow 拼接的接角 1px 错位是不连续观感来源);分隔线原 editorGroup-border token 不可视,换 --vsidian-code-card-border 同源色;codeCardPaintCssContract 契约同步(验收驱动变更,理由随测试注明)。main 前移(PR test: 修正真实 Ctrl 手势并补引用表格回归与文件树 #680)已 merge 跟进(tree.json 经技能两阶段合并,零待决)。
A87 三轮把 --vsidian-reading-code-border 定义处 fallback 改为 rgb(127,127,127),但使用点(.vsidian-reading-block code 的 box-shadow)仍是一轮的 rgba(128,128,128,0.4)。定义在场时使用点 fallback 是死码、无行为差异(浏览器断言核实),但两处不一致—— 将来定义链变化时旧透明值会诈尸。对齐为同值并注明理由。 calloutPaint 全绿;产物重建核实边线两处均为 rgb(127,127,127)。
验收澄清(2026-11-01 四轮):用户诉求对象是 callout 内的**代码块 卡片**底色可辨性,前三轮误实现在行内代码上。本轮撤误向实现、 在正确对象上落地;另修复 PR678-005(复审 P3)。 1. 撤除行内代码边线(三轮误向):live/阅读两处 box-shadow、 --vsidian-reading-code-border 变量、pre code 重置(004 随撤—— 泄漏源已不存在)及对应浏览器断言全撤;显形标记灰化与代码卡 折叠旁落(真实需求)保留。 2. 代码卡壳外缘 1px 边线(用户拍板方向,正确对象):卡底色与 callout 容器底色部分类型对比不足——行级左右线用 inset box-shadow(不占行高,同紫条先例),底行加底线,header 顶/ 左/右实色 border(border-box 不扩尺寸),阅读卡容器 border 一圈。不透明中灰 rgb(127,127,127),参照系=临近容器底色 (亮底深线/暗底亮线),变量 --vsidian-code-card-border 可调, 双模式同步。 3. PR678-005:整篇围栏无尾换行(块外无合法位置)时旁落落点 min(fenceTo+1, docLength) 退回块尾、闭区间触及误判 editing、 收起永远被压。修复:块尾即文档末尾时 editing 触及右界收一位 (光标恰在块尾边界物理处于收起 replace 区间右界外、源码可 见,不算编辑抑制);插入发生在边界外、新字符可见,无隐藏 输入窗口。有尾换行/块后有内容时语义零变化。 - 单测:005 三例(无尾换行收起/有尾换行对照/收起态键入安全, 含贴闭围栏行尾打字破坏围栏语法卡正确退场的语义澄清) - 浏览器:calloutPaint 卡行左右线+header 边线 computed 断言; codeCardChrome 阅读卡壳 border 断言;行内代码断言撤净 - 全量单测 10218 例 / compile / 契约八项 / 双浏览器套件全绿
ONEGAYI
left a comment
There was a problem hiding this comment.
R7 亲审复审
Head 685cce1419a98911901bbff304d90606c00955ef;base/merge-base 3d70cb36ca6c29cabcd718eaaaf7e5dd5718ecb5。相对374cf6ef为1提交5文件,原五线程及作者004/005回复已读,发布前仍同head/open。
Spec
- vsidianPR678-004 fixed(泄漏源整体撤除):行内code边线及变量撤回,需求对象按作者本轮澄清改为代码卡壳。已沿原线程明确这次撤除与此前限定重置的差别。
- vsidianPR678-005 部分修复/仍开放:原EOF空光标现在可折叠;但右界统一减1也缩短非空选区相交面,选中末尾闭围栏最后一个反引号仍保持收起,源码选区被隐藏。缺口转移至liveCodeCard.ts555–557,原线程已列触发/影响/建议;不笼统标fixed、不另建重复ID。
- 001–003原修复未变。新卡壳边线有Live行级/header与Reading容器computed断言;固定灰色不能证明任意主题/容器背景的视觉对比度,人工观感边界保留。
Standards
未另建独立Standards问题。旧inline边线测试撤回与功能撤除一致;不能把撤回后的结果写成旧inline功能验收完成。EOF真实键盘专用fixture仍未加入,作者明确只在StateField覆盖,不冒充本方浏览器执行。
本方验证
完整固定Git树、Node24.22.1:原liveCodeCard 115pass;额外生产StateField/围栏表/迁移/装饰组合2探针中原005转绿、末字符非空选区失败,合计 116pass/1fail,首败保留非flaky。tsc --noEmit、两mjs语法、diff检查通过。未重跑全量/真实Chromium/VSCode/Windows/物理输入,未改产品;作者10218/双浏览器通过仅作者证据。
旧374cf6ef CI41261048680已核验13/13job成功(含browser124715368687),该head仍包含005旧缺口,CI绿不注销缺陷。当前685cce14 CI41262071376仍运行,继续只读观察,不重跑。本轮COMMENT不是APPROVE,不resolve。
验收反馈(截图标注)与复审「部分修复」一并处理: 1. 边线连续性 + 分隔线可视(验收标注「不是连续线段」「分解线 依然不可视」):header 顶/左/右 border 与底部分隔线统一迁 inset box-shadow——与卡行边线同机制同色,消除 border 与 shadow 拼接的接角 1px 错位(连续感来源);分隔线原 editorGroup-border 主题 token 在用户主题不可视(探针 fallback 0.35 透明灰实证同族问题),一并换 --vsidian-code-card-border 同源色。codeCardPaintCssContract 契约同步(变更理由:验收 反馈点名,非顺手放宽)。 2. PR678-005 五轮(复审边界转移):四轮把 fence.to 统一收窄 误伤了非空选区——折叠后选中最后闭围栏字符(EOF Shift+Left 形态)仍被收起遮挡。重写为块级触及判定 blockEditingTouches: 唯一放行点是「空选区且 head === fence.to === docLength」 (物理在收起 replace 区间右界外);空选区其余位置维持闭区间、 非空选区维持真实开区间相交(正反向/多光标语义与共享谓词 一致)。selectionTouchesRange 共享谓词不再被本路径消费。 - 单测:005 五轮例(末字符正向/反向选区展开、多光标、EOF 空光标 收起不回归);契约断言更新 - 浏览器:calloutPaint header 四段 shadow 同源断言 + 分隔线不再 走 border;codeCardChrome 阅读卡壳 border 断言保持 - 全量单测 10219 例 / compile / 契约八项 / 双浏览器套件全绿
tree.json 经 file-tree merge 两阶段合并(自动合并 11 项,零待决), render + check --strict 通过。#680 变更(blockquoteTablePaint/ contextMenu 测试修正 + 文件树登记)与本分支改动零文件重叠。
ONEGAYI
left a comment
There was a problem hiding this comment.
R8 亲审复审(含main同步)
最终head 042abcd8ca6bdee3a49fd101b22ed79de8866be6;base/merge-base已前移至 a2598a0e1547a24902ebb446dc11a83114b265fd(#680)。先审d6808da4五文件修复,再核对main合并;同步没有改变src生产树。原五线程与作者005回复均已读,发布前同head/open,无并发新增overview。
Spec
vsidianPR678-005 fixed(EOF折叠及末字符非空选区转移范围)。已沿原线程回复4434050880:只有EOF空光标获豁免,正/反向非空选区与实际启用的多光标均按真实相交展开。001–004此前修复/撤除范围保持,无新增证实独立缺陷。
卡头与卡行边线统一inset shadow,分隔线改同源色;旧border-bottom断言随明示视觉方案迁移,不把computed属性存在扩大为接角/任意主题实机观感通过。
Standards
未发现新增独立问题。main带入的四个文档/测试文件逐blob与已审#680合并树一致;tree.json深比较只新增3项登记、更新3项测试说明,严格检查通过。生产src相对d6808da4无差异,未把main同步误当新的产品修复。
本方验证与边界
- d6808da:原liveCodeCard/codeCardPaintCssContract 141pass,额外4项原生产StateField组合探针全过,共145pass。正向末字符、反向Shift+Left形态、allowMultipleSelections=true且确认2个ranges、EOF空光标逐项对照;原R6/R7失败保留。
- 最终042abcd8:上述两文件加contextMenu/contextMenuDom/tableCellInput共5文件 301pass;file-tree strict与diff检查通过。d6808da4 tsc及mjs语法通过;main仅测试/文档增量,未冒称最终head重新跑compile或全量。
- 未改产品,临时探针已移除。没有真实Chromium/VSCode/Windows/物理键盘或完整视觉验收;作者10219/双浏览器成功不计本方执行。
- 上轮685cce14 CI41262071376已13/13成功,不注销当时005转移缺陷;当前042abcd8 CI41262784250运行中,继续只读至终态,不重跑。
本轮仅一个COMMENT总览与005原线程回复,不APPROVE、不resolve。
## 问题 宿主验收截图标注「不是连续线段」:代码卡头部横带与首围栏行接缝处, 卡壳左右边线各向内凹出一道弧,观感上边框在此断成两段。 ## 根因(探针实测,非推测) 沿卡壳左缘逐扫描线取边线外缘像素 x(dpr=2): - 头部横带段:x 恒定 12(一条竖线) - 接缝下方:x 17 → 8 连续内凹,跨 12 设备像素(6 CSS 像素)后回正 这份内凹来自 `.vsidian-code-card-edge-top` 自带的 `border-top-left-radius: 6px`。 该规则是 #79 卡片初版留下的——当时没有头部横带,首行自己承担顶边圆角; #81 引入头部横带后,顶边圆角已改由头部 `border-radius: 6px 6px 0 0` 承担 (`styleContract` 的 `live-code-card-edge` 条目原文即写明「顶边圆角由头部 横带承担」),但首行这层圆角没撤。两层圆角叠加的结果,就是头部外圆角之后 紧接着一道内凹。 对照探针:把首行顶角圆角置 0 后,接缝下方左缘从 x 8 起全程恒定,右缘同理。 ## 变更 - `src/webview/main.css`:`.vsidian-code-card-edge-top` 的 `border-top-left-radius` / `border-top-right-radius` 由 6px 改为 0,注释记录根因与唯一承担者 - `test/unit/codeCardPaintCssContract.test.ts`:原断言钉住「首行顶角 6px」, 改钉「首行顶角 0 + 尾行底角 6px」 - `test/browser/calloutPaint.mjs`:新增像素层断言——截图沿卡壳左缘逐扫描线 取边线外缘 x,中段(跳过首尾圆角过渡带)必须去重后单值,且不得出现边线 缺行。这是用户真正看到的「连续/断裂」,CSS 层断言抓不住 ## 验证 - `npm run compile` 通过 - `npm run test:unit`:444 文件 / 10219 用例全绿 - `npm run check:stylecontract`:八项零失败 - 浏览器套件 calloutPaint / codeCardChrome / codeCardClickOffset / quoteBarPaint 全绿
## 背景 对 bbf0f59(A87 六轮:首围栏行顶角改直角)执行 review-loops 三轮 审查修复循环。首轮子代理审查发现 4 项 P3(无 P0-P2),第二轮复核后 修复,第三轮复核确认全部关闭、无新问题。 ## 审查发现与处置 - F1 像素断言只测左缘:右缘镜像补证(独立裁剪 + 独立全套断言) - F2 暗像素阈值 180 有假绿路径(暗底下背景全列命中 → x=0 单值空转绿): 断言升级为「单值 + 无缺行 + 落预期带」,阈值放宽至 190(容纳 1px 劈列 的 ~50% 抗锯齿混色 ≈184,两侧底色 ≈230/240 仍不命中) - F3 styleContract example 8px 与实现 6px 存量漂移:example 对齐 6px, purpose 补「首行顶角为直角」;三份生成产物随 compile 同步再生成 - F4 契约正则可前缀匹配 0.5px:值边界锚定到分号 - N1 落带按 dpr=1 硬编码(套件将来设 dpr=2 会全面假红,仓内有先例): 带中心按位图宽自标定(左 bandWidth/2、右 -1,±2 劈列容差) - N2 非对称暗底(卡内暗卡外亮)下「取暗像素」范式失效:属范式固有边界, 换对比式检测与问题规模不相称,注释留档不修代码 - N3 循环内 const window 遮蔽惯用名:改名 midRows ## 验证 - 检测力实证:CSS 临时回 6px 时套件红——computed 断言先红;跳过其后 由像素断言独立红(左缘 x 去重 [6,9,8,7],正是内凹台阶);dpr=2 探针 同状态两侧中段 x 集合均非单值(左 [12,21,18,17,15,14,13]、 右 [11,2,5,6,7,8,9,10])。还原后绿 - npm run compile 通过(产物再生成一致) - vitest codeCardPaintCssContract + styleContract 43 用例绿; node --test checkStyleContract 绿;npm run check:stylecontract 八项零失败 - calloutPaint 浏览器套件绿;产物代码零改动(main.css 与上提交逐字节一致)
版本内容(Unreleased 段转正为 1.6.1 - 2026-11-01,顶部重建空 Unreleased 段): - 改进:Live Callout 容器形态收口(#672/#673)、引用内代码块与公式 完整渲染(#674/#675)、标题按类型着色(#671)、连续删除防护、 行内代码细边线与代码卡壳边线连续化 - 修复:表格格内输入选区竞态(#667)、代码卡头部间距点击偏移 - 补账:v1.6.0 以来随 PR #678/#681 落地但未登记 Unreleased 的用户 可见变更全部入册;验收轮观感修复按约定并入所属主题组 版本与产物: - package.json version 1.6.1;样式指南随版本段重生成(版本戳) - API 嗅探:CHANGELOG-API Unreleased 为空、API 事实源 v1.6.0..HEAD 零 diff——无 API 版本动作,只发本体(API 停留 1.4.0) - checkStyleContract 基线复验:8 项零失败(候选 v1.6.1)
概述
#668 Callout Live 形态收口批次主体:Live 嵌套 callout 改由 CM6 原生 BlockWrapper 承载容器视觉(间距/边框/圆角/类型色),引用内围栏代码块与多行公式达成完整渲染(代码卡全功能 + KaTeX),不采用降级方案。
提交链
ebdec116/928f6685/80fda0e9BlockWrapper 路线探针报告(含懒延续归属勘误)212091bdT04 BlockWrapper 容器结构(区间消费解析器节点区间、rank 60−10×深度、根正文独占装配)0a75a8c6T05 容器视觉迁移(.callout/data-callout/data-callout-depth 迁 wrapper、行级让位 + facet 嵌入保护、公开样式契约重锚)5da4d111T06 扫描器前缀剥离(scanFencesDetailed/scanMathRanges 块模式前缀感知、ContentLineMapEntry 逐行映射、增量对拍)e77ece63T04/T05 评审修复(让位规则 :not 防雷、契约台账坐实、wrapper margin:0、A86 登记)f5bd1070T07 消费端收口(mapContentOffsetToDoc token 逐行折算、组合验证)02bc0935T07 评审微修流程与质量
implement-spec 后台编排:每票实施后双轴 code-review(Standards + Spec,钉死提交区间只读评审),发现全部闭环——评审净捕获 1 契约台账登记失实(补断言坐实)、1 特异性雷(让位规则将在引用内代码卡上复现行号甩出盒外,修复有前后取证)、1 增量坐标残留真缺陷;登记不修项均有理由留档。
验证
遗留(不随本 PR)
#676(calloutFold 九段 re-init 根因)、#677(双主题截图 + 热更新测量刷新)、P2(引用内列表/表格/图片/嵌入 wrapper 回归,未开票)。
Close #669
Close #670
Close #672
Close #673
Close #674
Close #675