Files
trade-message-center/.trellis/tasks/09-14-centralize-dom-interactions/design.md
T

3.3 KiB

非观测 DOM 边界设计

Boundary

apps/chrome-extension/src/onetalk/main-page/dom/ 是本任务中 OneTalk MAIN-world 非观测 DOM 访问的唯一所有者。它是 OneTalk 专属的页面适配边界,不提升到 src/lib/,也不与 Popup 共用。

main-page/
├── dom/
│   ├── selection.ts             # selected 会话和标题节点的 DOM 读取
│   ├── selection-events.ts      # document click 订阅
│   ├── react-file-uploader.ts   # file input 到 React uploader 的窄适配
│   ├── action-status-tooltip.ts # extension-owned 状态浮层
│   └── conversation-id-copy.ts  # extension-owned 复制按钮
├── page-context.ts              # URL/页面运行时身份与 selection 领域投影
├── image-send.ts                # 媒体发送状态机和结果语义
└── page-script-entry.ts         # 组合入口

buyer-fact-observer/contact-observer/ 不移动、不改 import、不改测试;它们仍自行拥有被动观察和投影。

Responsibilities

现有责任 新 DOM 所有者 保留的业务所有者
selected [data-cid]、标题定位 dom/selection.ts page-context.tsnone/single/multiple/unavailable 语义
document click 刷新 identity dom/selection-events.ts page-bridge/main.ts 的 hello/retry/bridge 生命周期
找到 file input 并上溯 React uploader dom/react-file-uploader.ts image-send.ts 的请求截止、上传拦截和 delivery result
tooltip DOM 创建、重挂载和销毁 dom/action-status-tooltip.ts connection/history 组件对 tooltip facade 的调用
复制按钮 DOM 创建、更新和移除 dom/conversation-id-copy.ts 当前会话 ID 可信来源及 Clipboard 成功/失败语义

移动只改变 DOM 适配层归属。公开函数签名、stable error/reason、桥接 message、SDK 发送和页面可见行为必须不变。

Testing Library decision

@testing-library/dom@testing-library/user-event 是测试依赖,而不是 MAIN-world 自动化引擎。现有代码没有主动操作 OneTalk UI 的业务命令;把 user-event 打进生产包既不能产生 trusted event,也会增加无消费者的 bundle 依赖。

测试层新增由 jsdom 创建和销毁的真实 DOM fixture,以 Testing Library 的 role/name 查询和 userEvent.setup().click 覆盖 extension-owned 复制按钮。项目的 Node >=22.22.2 基线满足当前 jsdom 的 Node 要求;每个测试必须显式传入 fixture document,并在结束时恢复替换过的全局对象。现有手写 fixture 仍可保留给页面结构异常、MutationObserver 和边界错误的单元测试。未来新增真实页面动作时,另行定义动作契约、失败语义和运行时策略,不能把测试工具直接暴露给 Bridge command。

Compatibility and rollback

  • 入口仍从 page-script-entry.ts 安装同名控件,MAIN/ISOLATED 入口和 Manifest 不变。
  • 所有新导入必须保持 MAIN entry 的 IIFE + inlineDynamicImports 构建约束;Testing Library 仅被 test 文件导入,不能进入该入口依赖图。
  • 这是可逆目录/依赖重构:若语义回归,恢复原 import 路径和 DOM adapter 文件即可;不得通过并行旧/新实现作运行时 fallback。