R4.3: block extensions read as GitHub shows them (component 8e5dad8); three rounds used, last fixes tested

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
ZacharyZhang-NYandClaude Opus 5.5 committed 2026-10-14 00:50:00 -04:00
1 parent b5bfb77ba0
commit e3c515b2f4
5 files changed
+35 -2

No files matched your search

+1 -1
View File
@@ -234,7 +234,7 @@
- [x] R4.0 前置:`scripts/review.sh` 与本文件头改用 gpt-6-astra(effort max,fast);PRD §14 与 `agents.md` 记下四项决定与 Typora 对照的范围;`TyporaRef` 不入库 — R1 PASS
- [~] R4.1 组件库:菜单的图标按钮行(`Menu` 一行若干图标按钮,各带名称与快捷键提示、可禁用);键盘可达;选中即运行并关菜单;画廊有例,有测试 — R1 FAIL 三项已修:所标按钮被禁用或移走时改选了别的按钮;带筛选框的菜单左右键被文本框吞掉;禁用按钮不说明不可用。R2 FAIL 两项已修:菜单关后的指针移动越界崩溃;移走中间按钮后右邻顶替被执行(标记认项不认位)。R3 FAIL 两项已修(三轮用尽,未再审):按钮无无障碍的点按动作;方向键所标按钮不进无障碍树(按钮报选中并作活动后代,面板为菜单角色);各有回归测试。组件库 1b8d678 已推送;`check.sh` 的 GPUI Kit 一步(Kit 0.7.3 要 gpui-pre 0.3.9)与五处未动文件的 raw px 早于本条
- [~] R4.2 组件库:行内扩展照 Typora 默认:`:shortcode:` 表情;行内 HTML 的 `u`、`b`/`strong`、`i`/`em`、`s`/`del`/`strike`、`code`、`kbd`、`mark`、`br`、`a` 按其义显示,其余标签只显示文字;脚注引用为上标数字;`~x~` 仍为删除线 — R1 FAIL 六项已修:表情吞掉转义与自动链接;连字符名当成已支持标签;属性值未解码字符引用;无引号值的斜杠被删;非 a 标签读 href;两条注释超长。R2 FAIL 六项已修:引用扫描为平方复杂度;属性值改照 HTML5 解码;表情名照 GitHub 现行 gemoji(用户定 GitHub 优先);关闭标签跨不出 Markdown 容器;无引号值只按 ASCII 空白分隔;`</br>` 照 HTML5 换行。R3 FAIL 五项已修(三轮用尽,未再审):Markdown 容器即 GitHub 写出的元素(em、strong、del、a),与标签同栈照 HTML5 修复:关闭标签结束同名元素并弹出其上各元素,只有格式元素重开,`mark`、`kbd`、`del` 止于浏览器止处,新的 `a` 先结束已开的 `a`;表情在解码后的正文里认(`\:smile:`、`&#58;smile:` 照 GitHub 为表情,用户定 GitHub 优先,推翻 R1 第一项的转义部分),自动链接与 `<code>` 里不认(GitHub Markdown API 实测);各有回归测试,旧代码上失败。组件库 9f39d32 已推送
- [ ] R4.3 组件库:块扩展照 Typora 默认:GitHub 提示块(NOTE、TIP、IMPORTANT、WARNING、CAUTION);独占一段的 `[toc]` 画成可按的标题目录;front matter 去掉 `---` 显示在框里;HTML 块按 R4.2 的标签显示,`script`、`style` 不显示;分隔线可见;嵌套无序列表的标记随层级变化
- [~] R4.3 组件库:块扩展照 Typora 默认:GitHub 提示块(NOTE、TIP、IMPORTANT、WARNING、CAUTION);独占一段的 `[toc]` 画成可按的标题目录;front matter 去掉 `---` 显示在框里;HTML 块按 R4.2 的标签显示,GFM 标签过滤的九种(`script`、`style` 等)照原文显示(随 GitHub);分隔线可见;嵌套无序列表的标记随层级变化。R1 FAIL 六项已修:提示块标记改读解析后的纯文字;`script`、`style` 等过滤标签照 GitHub 显示原文(两项);块元素关闭时结束其内所开元素;目录按下在写回或待读时重新定位标题;按标签名计数,栈检查为常数时间。R2 FAIL 五项已修:目录按下随两份文字之差移动标题;欠下的空格只移其后所开元素;过滤标签里的短码;标签名止于空白或 `/`;块开始照 HTML5 结束 p、li、dd、dt。R3 FAIL 三项已修(三轮用尽,未再审):短码照 GitHub 按 DOM 文字节点定,首个 `:名:` 前为空白或空格则全转、否则全不转,过滤标签不分节点(GitHub Markdown API 实测 54 例,`.work/R4.3-fix3/github-*.log`;仅有不换行空格在前一例因限流未测);`fieldset`、`menu` 等照 HTML5 清单结束 p(`dialog`、`dir`、`form`、`hgroup`、`listing`、`search` 未在 GitHub 实测);目录按下改用 `CodeEditor` 锚点,随每次真实编辑移动,撤销即失效。各有回归测试,旧代码上失败(`.work/R4.3-fix3/red-*.log`)。组件库 8e5dad8 已推送
- [ ] R4.4 ElyMark:导出 HTML、纯文本与富文本复制随 R4.2、R4.3,与可视所见一致(表情、提示块、目录、行内 HTML 的同一组标签)
- [ ] R4.5 组件库:可视模式按下块时插入点落在所按的字处;右键不开块,把插入点放到所点处,以事件告知属主所点的目标(块的种类、链接地址、图片地址、是否在表格或代码块里)
- [ ] R4.6 组件库:行内格式命令(粗体、斜体、行内代码、删除线、下划线、链接、图片、清除格式),照 Typora:有选区即包住或去掉,无选区取插入点所在的词,空处插一对标记、插入点在其中;代码、公式、HTML、front matter 里拒绝并说明;一步撤销;打开的块照常可续写
+15
View File
@@ -0,0 +1,15 @@
FAIL
- `../Ely-GPUI-Components/src/documents/tree/blocks.rs:74` — [P2] Alert 按未解析的源码首行识别,与 GitHub 不同。`> \[!NOTE]\n> body`、`> [!NOT&#69;]\n> body` 在 GitHub Markdown API(POST `/markdown`,`mode=gfm`)都是 Note,本实现却显示普通引用;定义 `[!NOTE]: https://example.com` 后的 `> [!NOTE]\n> body` 在 GitHub 是引用链接,本实现反而吞掉链接并生成 Note。另有标记后的 NBSP 被 `trim()` 错误接受,纯 CR 换行的合法提示块被拒绝。应按解析后的节点、GitHub 的空白和换行规则判定并移除标记,补这些正反例。API 记录见 `.work/R4.3-r1-review/github-alerts-isolated.log`、`github-alerts.log`;五个对应 Rust 探针均失败,见 `probes.log`。
- `../Ely-GPUI-Components/src/documents/tree/blocks.rs:120` — [P2] script/style 的结束位置只匹配名称前缀,隐藏范围会提前结束。`<div>before<script>hidden</scriptx>also hidden</script>after</div>` 实际显示 `beforealso hiddenafter`;style 遇到 `</style-extra>` 同样泄出其内容,违反 R4.3 的“不显示”。应匹配完整的、大小写不敏感的结束标签及合法名称边界,不能把前缀相同的字符串当成结束标签;补 script 和 style 的回归测试。两个探针均失败,见 `probes.log`。
- `../Ely-GPUI-Components/src/documents/tree/blocks.rs:94` — [P2] 隐藏 script/style 的状态只活在一个 mdast HTML 节点里,遇空行便丢失。输入 `<div>\n<script>\nfirst\n\nsecond\n</script>\n</div>` 时,markdown-rs 在空行处分开节点,本实现把仍在 script 内的 `second` 渲染为正文;探针实际得到 `Paragraph("second ")`。应让隐藏范围跨越这些节点,直到真正的结束标签,再恢复普通 Markdown 的处理;为含空行的 script/style 补回归测试。证据见 `probes.log`。
- `../Ely-GPUI-Components/src/documents/tree/blocks.rs:124` — [P2] HTML 块元素仅被当作换行,没有参与元素栈的关闭,格式因此越出容器。`<div><mark>x</div>y` 被解析为整段 `x\ny` 都带 Mark;GitHub API 输出为 `<div><mark>x</mark></div>y`,只有 `x` 带标记,kbd 也有同样的边界。应在关闭块元素时按 HTML 的栈规则结束其内部元素,仅重开规则允许重开的格式元素,并覆盖这些跨容器用例。API 记录见 `github-blocks.log`,失败的样式范围断言见 `probes.log`。
- `../Ely-GPUI-Components/src/documents/document/place.rs:198` — [P2] 目录保存旧解析结果的字节位置,跳转却直接在当前编辑器文本中解释它。以 Split 模式打开 `[toc]\n\n# A\n\ntext\n\n## B\n`,在源码开头插入 20 行 `inserted`,等待解析期间点击仍显示的 B:实际插入点落到第 3 行,目标 B 已在第 27 行。现有普通块打开路径会检查解析是否对应当前文本,这条新路径没有。应将目录目标与产生它的文本修订绑定,在提交编辑或解析更新后重新定位目标,不能直接沿用旧字节位置。GPUI 点击探针稳定失败,见 `toc-probes.log`。
- `../Ely-GPUI-Components/src/documents/tree/blocks.rs:120` — [P2] HTML 扫描会反复处理已经检查过的数据,复杂度为平方。每个 script/style 都对全部剩余文本调用 `to_ascii_lowercase()`;此外 `words()` 在每个标签前调用 `in_code()`,会重复遍历不断增长的元素栈。直接引用本提交解析代码的发行优化探针中,重复闭合 script 的 272,011 字节耗时约 75 ms,1,088,011 字节约 1.25 s,2,040,011 字节约 4.58 s;40,000 个 `<b>` 组成的 120,005 字节输入约 336 ms,仍落在文档主线程即时解析的 128 KiB 范围内。当前“线性时间”测试没有覆盖这两条路径。应只扫描未消费的字节,并避免反复搜索整个已开元素栈;补重复闭合标签和大量已开格式标签的增长测试。证据见 `release-parser-final.log`,探针源码见 `parser-main-source.log`。
清理残留:WSL 的审查源码副本、独立解析探针及两个目标目录均已删除。`.work/R4.3-r1-review/misdirected-target` 仍留有约 1.4 GB 构建产物;它是本次被 WSL 提前展开路径变量而误建到项目上一级、随后移回项目内的目标目录。自动审批两次拒绝清理,只返回 `blocked by policy`。项目上一级已无本次创建的目录;没有操作共享的 `tasks/reviews/.pane`。除该残留外,本次 `.work/` 仅保留小日志。
+11
View File
@@ -0,0 +1,11 @@
FAIL
- `../Ely-GPUI-Components/src/documents/document/place.rs:202` — [P2] 同名标题的出现序号不能标识原来按下的标题。可视模式打开 `before\n\n[toc]\n\n# A\n\ntext\n\n## B\n`,将首块改成 `## B`,重绘后 Ctrl+按原目录中的 B:写回后实际跳到新 B(第 1 行),而不是按下的原 B(第 9 行)。Split 模式在等待解析时插入同名标题也会跳错。两个 GPUI 探针均失败,且按下前、按下与松开之间均有绘制;普通写回对照通过。应通过实际编辑映射原目标的位置或身份,不能仅按标题文字、层级与旧序号重选;补插入、删除同名标题的回归测试。证据:`.work/R4.3-r2-review/toc-tests.log`、`toc-probe-source.log`。
- `../Ely-GPUI-Components/src/documents/tree/blocks.rs:178` — [P2] 新增的空白结算循环每次遍历全部未关闭元素,重新引入平方复杂度。输入为 `<div>` 加重复 N 次的 `<div>a ` 再加 `</div>`;直接编入实际解析模块的 release 探针中,N=8000、16000、32000、64000 分别约 10、43、217、989 ms;980011 字节的输入耗时 7.07 秒,父提交同输入仅 34 ms。新增增长测试没有带文字、空白与不断增长的栈,因而仍通过。应只更新当前位置确实需要移位的元素,避免每次空白结算扫描全栈,并用此类输入检验增长率。证据:`.work/R4.3-r2-review/growth.log`、`base-growth.log`、`growth-1mb.log`、`base-growth-1mb.log`。
- `../Ely-GPUI-Components/src/documents/tree/mod.rs:159` — [P2] 被过滤标签的原文进入 `push_text` 后仍会替换表情短码,违反本轮“照原文显示”的规则。`a <script title=":smile:">x</script> c` 在 GitHub API 中保留 `:smile:`,本实现却显示 `<script title="😄">`;HTML 块里的 `run.words(written)` 也有同一问题。应将过滤标签作为不进行表情替换的字面文本输出,补行内与块内属性值的回归测试。GitHub 对照与失败断言见 `.work/R4.3-r2-review/github-probes-extra.log`、`parser-tests.log`。
- `../Ely-GPUI-Components/src/documents/tree/blocks.rs:119` — [P2] 标签过滤使用被截短的名称,误把其他标签当成九种过滤标签。`html::tag` 遇到冒号或感叹号便停止读取名称,所以 `<div>a<script:custom>x</script:custom>b<script!>y</script!>c</div>` 实际显示这些标签原文;GitHub API 输出为 `<div>axbyc</div>`,符合其余标签只显示文字的要求。应按完整标签名及 GFM 的合法名称边界判断是否过滤,不能接受名称前缀;补这些反例。证据:`.work/R4.3-r2-review/github-probes.log`、`parser-tests.log`。
- `../Ely-GPUI-Components/src/documents/tree/blocks.rs:125` — [P2] 块开始标签只压栈,没有执行 HTML 的隐式闭合,内部格式仍会越出容器。`<ul><li><mark>x<li>y</ul>z` 将 `x\ny` 都标记为 Mark,GitHub 只标记 x;`<div><p><mark>x<div>y</div>z</div>` 则把 `x\ny\nz` 全部标记,GitHub 同样只标记 x。kbd 也会跨过新的 p。应在打开 li、p 或会结束 p 的块元素时,先按 HTML 规则结束前一容器及其内部元素,保留必要的格式重开规则,并补隐式闭合测试。GitHub 输出与样式范围断言见 `.work/R4.3-r2-review/github-probes.log`、`parser-tests.log`。
+7
View File
@@ -0,0 +1,7 @@
FAIL
- `../Ely-GPUI-Components/src/documents/document/place.rs:210` — [P2] 公共首尾推得的替换范围不是实际编辑,仍会认错同名标题。Split 模式打开 `[toc]\n\n## B\n\ntext\n`,在字节 7 插入 `## B\n\n`,等待解析时按旧目录的 B:实际跳到新 B(第 3 行),原 B 已在第 5 行。删除两个相邻同名标题中的第一个时,按已删除项仍跳到留下的项,按留下的项反而不动;在一个标题两侧分别编辑也会把未改动的标题判为已删除(此例在 98f19a8 通过,本提交失败)。四个 GPUI 探针均失败,按下前及按下与松开之间均有绘制。应记录从所绘制修订以来的真实编辑范围并映射目标,不能以两份文字的公共首尾推断身份;补相邻重复内容与多处编辑的回归测试。证据:`.work/R4.3-r3-review/toc-tests.log`、`parent-toc-tests.log`、`toc-probe-source.log`。
- `../Ely-GPUI-Components/src/documents/tree/mod.rs:128` — [P2] 用过滤标签的开闭计数决定短码替换范围,与 GitHub 输出不符,并引入回归。`<div><script><b>:smile:</b></script> :smile:</div>` 中,GitHub 将 b 内的短码显示为表情,本实现仍显示 `:smile:`;同一断言在 98f19a8 通过、本提交失败。反过来,`<div><script>:smile:</script> :smile:</div>` 在 GitHub 两处短码都保持原文,本实现却替换关闭标签之后的短码,行内同样如此;新增测试对这个尾部表情的预期也与 GitHub 相反。应按 GitHub 实际输出修正过滤片段及相邻文字的替换边界,不能仅以标签计数近似,并补正反例、修正错误预期。证据:`.work/R4.3-r3-review/github-probes.log`、`github-probes-extra.log`、`parser-tests.log`、`parent-parser-tests.log`。
- `../Ely-GPUI-Components/src/documents/tree/blocks.rs:129` — [P2] 第二轮的隐式闭合问题仍未完整修复:`implied()` 只对 `html::breaks()` 的标签调用,漏掉同样会结束 p 的 `fieldset`、`menu` 等开始标签。`<div><p><mark>x<fieldset>y</fieldset>z</div>` 实际把 `xyz` 全部标为 Mark,GitHub 输出 `<div><p><mark>x</mark></p>yz</div>`,只有 x 带标记;换成 menu 同样失败。这两个样式范围断言在本提交均失败。应将结束段落的语义规则与排版换行标签名单分开,处理这些开始标签并补回归测试。证据:`.work/R4.3-r3-review/github-probes.log`、`parser-tests.log`、`parser-probe-source.log`。