Repository navigation
fix(engine-dom): adoptNode 物化 DOMParser 快照产物,修 bilibili nano 播放器容器空壳挂载 - #129
Merged
Merged
Conversation
t8q(site-compat bilibili-20261002-r1 P7):DOMParser 快照式实现的本地产物 (_zwParseEl/_zwMEl 形态)经 adoptNode 后 identity no-op,append 进主文档后 无 .style 等 HTMLElement 接口、序列化空壳、不进查询索引——真站 nano 播放器 容器模板挂载后 7 条 TypeError(setting 'webkitTransform'/'display'/'right'、 reading 'removeProperty'/'style')、<video> 0 个。违反 DOM Standard concept-node-adopt「node 完整搬入本文档」语义。 最小通用修复(2 文件,复用既有设施不引入新机制): - part03: _zwMEl 构造打 non-enumerable __zwIsMEl 标记(工厂产物为 plain 对象无共享 prototype 可 instanceof;non-enumerable 防 for-in/序列化扩散) - part06: adoptNode 顶部物化分支——识别 _zwParseEl 实例或 __zwIsMEl===true 的元素节点,经 _ensureMutTree lazy 桥 + 既有 _wcRebuildAsHandle 重建为 handle 树真 wrapper;物化不可行回落既有分支零变化;同文档真元素 identity 保持(R192 语义不变)、Document 入参仍抛 NotSupportedError 验证: - 新增双钉(js_dom_bridge_tests/part18):主钉复刻真站链(parse→adopt→ 相对查询→append→序列化)style/relQ/parentQ/serial 六断言 + 变体钉 (后代物化属性保真/子树 Text+Comment 保真/identity 保持/docThrow); 红态实跑(style:undefined|parentQ:miss|li:bad|text:bad|comment:bad)→ 修复后双绿 - zero-engine lib 全量 2959P/0F(RUST_MIN_STACK=33554432) - WPT 相邻套零回归:Document-adoptNode 4/4、Element-tagName 6/6、 Node-normalize 4/4、Node-cloneNode-document-with-doctype 3/3、 processing-instruction-attributes 全 P、MutationObserver-textContent 4P/0F、Document-createElement-namespace 51P/0F - 真站复跑(headless 探针):display/right/removeProperty 空壳簇消除, mountHTML 空壳 <div></div> → 完整 bpx-player-container→video-wrap→ <video> 树,videos 0→1;players=0 未起播(剩余错误归因 innerHTML/ 相对查询模板链产物无接口的下一层缺陷,已记池不虚报) - make test 全量 exit 0;fmt 零 diff;clippy -D warnings 双腿(默认 v8 + quickjs no-default)零 warning Co-Authored-By: Claude Code <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: 1a1e76e6-51c3-43f5-bbbf-6a77830b33a9) |
PR #129 双审查两独立首轮(测试有效性 + 缺陷,均 APPROVE_WITH_NITS)统一返修: - 物化成功返回副本前,经原父 removeChild 摘除原节点(spec concept-node-adopt 第 1 步)——不摘则 adopt 退化为复制(站点双引用消费时内容重复;快照文档 body.firstChild 仍返原节点)。try/catch 包裹,失败不阻断(回落旧状态)。 同时消审查②#1 复制面与 #2 快照残留主体。ownerDocument 收窄方案经源码 考古证伪弃用:R3019 懒桥根 _zwMEl(snap,null) 无 owner 章回落主 document, 收窄会误杀真站主链。 - docThrow 断言收紧为 e.name==='NotSupportedError'(审查①#1,防异常类型 退化逃逸;shim DOMException 第二参直设 name)。 - 主钉新增 snapGone 断言(adopt 后快照 body.firstChild 不再返原节点)。 - 测试序列修正:adopt 有摘除副作用,后代臂/根臂改用独立文档(真 DOM 同 序列同样互扰,修复前 identity no-op 无副作用掩盖了测试假设错误)。 - PR 正文根因②措辞修正:空壳产生在 mutation-apply 挂载消费路径。 审查记录项转池:裸 Text/Comment 物化、XML ns 丢失、二次 adopt 副本; Node-mutation-adoptNode "simple append of foreign div with text" Fail 经 main 基线对照(/tmp 备份+md5+cp 变异法)定谳既有失败非本 PR 引入。 复验:zero-engine lib 2959P/0F;fmt 零 diff;clippy -D warnings 双腿 (v8+quickjs)零 warning;WPT Document-adoptNode 4/4(含摘除语义下 Document 抛错/DocumentType 断言);r3 真站探针与 r2 逐项一致。 Co-Authored-By: Claude Code <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: 93d54040-f0b6-44bb-b0e8-df4cfb3b369a) |
4 tasks done
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.
fix(engine-dom): adoptNode 物化 DOMParser 快照产物,修 nano 播放器容器空壳挂载
问题
bilibili 视频页(未登录公开面)nano 播放器初始化时 console 报 7 条同形态错误:
TypeError: Cannot set properties of undefined (setting 'webkitTransform'/'display'/'right')、Cannot read properties of undefined (reading 'removeProperty'/'style')——元素已挂载但.style为 undefined;探针 census 显示播放器容器序列化为空壳<div></div>,<video>元素 0 个。站点链路(bundle 静态解剖):nano 模板引擎以
tr.t = document.adoptNode(new DOMParser().parseFromString(tpl.trim(), 'text/html').body.firstChild)构造容器模板树,随后 append 进主文档并对树内元素执行样式操作。根因
ZeroWeb 的 DOMParser 是快照式只读实现(
_zwParsedDoc/_zwParseEl),doc.body.firstChild经 R3019 lazy 桥返回本地产物节点(_zwMEl形态)。adoptNode对该形态 identity no-op,产物 append 后:.style等 HTMLElement 接口 → 真站 7 条 TypeError 全部落在此面;<div></div>(快照树自身的 innerHTML 读不空,空壳产生在挂载消费路径);违反 DOM Standard §concept-node-adopt「node 完整搬入本文档」语义。
修复(2 文件,最小通用)
js_dom_shim/part03.js:_zwMEl构造时打 non-enumerable__zwIsMEl标记(工厂产物是 plain 对象,无共享 prototype 可 instanceof;non-enumerable 防止 for-in/序列化扩散)。js_dom_shim/part06.js:adoptNode顶部新增物化分支——识别_zwParseEl实例或__zwIsMEl === true的元素节点(nodeType 1、无__zwHandle/__zwSelector身份),经既有_ensureMutTree()lazy 桥 + 既有_wcRebuildAsHandle(WC-M2 重建器)重建为 handle 树真 wrapper(同回合完整接口,mutation 异步 apply 与 createElement 同时序);物化不可行时回落既有分支,行为零变化。同文档真元素 adoptNode 仍保持 identity(原 R192 语义不变),Document 入参仍抛NotSupportedError。不引入新机制:识别标记与重建器均为既有设施的最小接线。
验证
js_dom_bridge_tests/part18.rs新增 2 测):主钉复刻真站链(DOMParser 模板 → adoptNode → 相对查询 → append → 序列化),断言style:object|styleSet:function|tag:DIV|relQ:hit|parentQ:hit|serial:hit;变体钉覆盖快照后代物化+属性保真、物化子树 Text/Comment 保真、同文档 identity 保持、Document 抛错。红态实跑确认(style:undefined|parentQ:miss|li:bad|text:bad|comment:bad),修复后双绿。RUST_MIN_STACK=33554432深嵌套既有要求)。display×2/right/removeProperty空壳簇全部消除;<div></div>推进为完整bpx-player-container → primary-area → video-area → video-perch → video-wrap → <video>树,videos 0→1;返修(双审查两独立首轮统一返修)
两份首轮均为 APPROVE_WITH_NITS(4+5 项非阻断)。采纳返修:
removeChild摘除,失败不阻断(回落旧状态)。同时消除首轮②的发现 Bump actions/github-script from 7 to 9 #1(复制面)与 Bump actions/download-artifact from 4 to 8 #2(快照残留)主体。e.name === 'NotSupportedError',防异常类型退化逃逸。body.firstChild不再返回原节点(摘除语义钉住)。审查发现的记录项(不在本切片修):顶层裸 Text/Comment 快照直接 adopt 不物化(
_zwMText/_zwMComment无识别标记,扩域另立切片);XML 文档 adopt 丢 namespace/大小写(_wcRebuildAsHandle既有限制);同节点二次 adopt 产生新副本(无物化映射表,记池)。既有失败披露:
dom/nodes/Node-mutation-adoptNode.html :: simple append of foreign div with text(createHTMLDocument 的 createElement 产物跨文档 append 后 ownerDocument identity 断言)在 main 基线(81a7014db,无本 PR 改动)同样 Fail——既有失败,非本 PR 引入,已记入问题池。返修后复验:zero-engine lib 2959P/0F、fmt 零 diff、clippy 双腿零 warning、WPT Document-adoptNode 4/4(含摘除语义下的 "Adopting a Document should throw"/"Explicitly adopting a DocumentType")、r3 真站一致。
截图
无适用画面:本修复改的是 DOM 接口语义(元素接口完整性),非视觉呈现面;验证经 headless CDP 探针采集,无 GUI 窗口可截。挂载状态证据以探针 census 序列化文本为准(上节 r1→r2 对比)。
测试计划
cargo test -p zero-engine(lib 全量 2959P/0F)cargo fmt --all -- --check/cargo clippy --workspace --all-targets -- -D warnings(默认 + quickjs 双腿)make test全量🤖 Generated with Claude Code
Note
Medium Risk
Changes core
document.adoptNodebehavior for parser snapshot nodes; regression tests cover identity and Document errors, but DOM adoption paths are easy to break subtly.Overview
Fixes bilibili-style flows where
document.adoptNodeis used on DOMParser snapshot nodes (parseFromString→body.firstChild). Previously those nodes were returned unchanged, so after append they lacked.style, serialized as empty shells, and did not participate in queries.adoptNodenow detects snapshot / local mutable-tree elements (_zwParseElor non-enumerable__zwIsMEl) and materializes them into real handle-backed element wrappers via_ensureMutTree+_wcRebuildAsHandle, removing the original node from the snapshot tree per spec. Same-document handle elements still get identity return; adopting a Document still throwsNotSupportedError.Two Rust bridge tests (
t8q_*) lock the site chain: style API, detach from parser doc, subtree query/serialize after append, plus variants (text/comment, descendant adopt, identity regression).Reviewed by Cursor Bugbot for commit 93be92e. Bugbot is set up for automated code reviews on this repo. Configure here.