
Slate Browser 的下一个系统级动作以 openExample 就绪契约为核心攻克零宽字符与 IME 渲染/输入策略证明赛道【免费下载链接】plateRich-text editor with AI and shadcn/ui项目地址: https://gitcode.com/GitHub_Trending/pl/plate本文以仓库内 docs/plans/2026-04-04-slate-browser-next-system-move.md 为主干融合 docs/slate-browser/ 下的配套研究文档完整还原这次系统级动作的决策过程、API 分期、落地清单与验证命令并给出可供直接引用的源码级依据。导读在 Slate v2 /slate-browser的第一个公开包 tranche 落地之后下一步做什么成为决定浏览器证明browser proof体系走向的关键问题。本文基于该计划文档完整梳理其结论最高杠杆的系统级动作不是跨浏览器、也不是性能而是先把openExample(...)打磨成真正的就绪契约readiness contract再用它搭建渲染器/输入策略renderer/input-policy证明赛道专门攻克零宽字符、空状态与 IME 敏感行为。读完本文你将掌握slate-browser三阶段 API tranche 的全部落地形态、选择书签selection bookmark接缝的设计动机、本地验证命令清单以及该决策如何服务于slate-v2管文档真相、slate-browser管浏览器证明、未来plate-v2管投影与产品化的整体系统目标。一、文档定位一份条件性后续动作指南该计划文档在开头就明确了自己的属性这是条件性的后续动作指南而不是 Slate v2 项目当前的默认队列。换句话说它不是 roadmap 本身roadmap 真相见 docs/slate-v2/ 中链接的 master-roadmap 文档体系而是回答一个更窄的问题如果slate-browser工作在第一波公开包 tranche 之后重新开启最高杠杆的定向动作是什么文档同时给出了完整的执行背景Context与六个阶段Phases完成将原内部文档树迁入docs/且不丢失已有docs/*内容完成更新内部文档对docs的引用完成阅读相关文档与包/测试文件完成综合出slate-browser/slate-v2的最强下一步完成为该动作直接修改文档完成同一轮内验证文档迁移与文档同步。从后续docs/analysis/editor-global-systems-objective.md、docs/slate-browser/next-api-candidates.md、docs/slate-browser/next-api-candidates-matrix.md、docs/slate-browser/four-way-api-deep-dive.md 等产出物可以看出这些阶段全部按期闭环。二、关键发现Findings合并而非重命名文档用一组Findings记录了调研结论其中最重要的几条是现有docs/已包含活跃内容analysis/、plans/、solutions/、performance/、table/原内部文档树还额外带有plans/、slate-browser/、slate-v2、slate-issues与额外的solutions/子树——这是一次合并merge不是重命名rename当前slate-browser公共 tranche 已落地在.tmp/slate-v2最高杠杆的下一步不是跨浏览器也不是性能优先最好的下一步是更强的openExample(...)就绪契约然后是针对零宽字符与 IME 敏感行为的渲染器/输入策略证明赛道。这些结论并非拍脑袋而是经过了文档重读、包/测试文件审阅、以及一轮跨仓库系统扫描覆盖 Lexical、edix、rich-textarea、Premirror、Pretext、TanStack DB、urql、VS Code、LSP之后收敛出来的。三、更大的图景三层系统分工该计划把下一步动作放在了一个显式的系统目标之下详见 docs/analysis/editor-global-systems-objective.mdslate-v2负责文档真相document truth——文档语义、操作、事务、不可变提交快照slate-browser负责浏览器证明browser proof——分层测试车道、示例挂载真相、把选区与剪贴板当作一等公民、Chromium 优先的 IME 证明未来plate-v2负责投影projections、执行管道pipelines、托管服务、布局系统与产品化。系统目标文档还给出了完整的九层责任分层栈文档引擎平面slate-v2、运行时与渲染平面slate-react-v2、浏览器证明平面slate-browser、投影与派生数据平面未来plate-v2、执行管道平面未来plate-v2、托管特性与协议平面未来plate-v2、布局与测量平面未来plate-v2、轻量表面平面未来plate-v2、产品化平面未来plate-v2。计划文档中记录的最强跨域参照系cross-domain imports也与之对应参照对象借鉴方向TanStack DB投影存储projection storesurql执行管道execution pipelinesVS Code LSP托管语义服务hosted semantic servicesPremirror Pretext布局与测量系统layout and measurementrich-textarea / edix轻量表面lightweight surfaces文档特别强调一条纪律从每个参照仓库偷对的理念但让每一层待在它的车道上——这正是判断下一步该做什么、不该做什么的总纲。四、下一批 API 候选的排序与三段式分期计划文档给出了slate-browser下一批 API 候选的显式排序ready契约editor.selection.select(...)editor.get.blockTexts()/assert.blockTexts(...)editor.snapshot()容错选区断言tolerant selection assertionsHTML 归一化选项HTML normalization options真实剪贴板读取助手real clipboard read helpers更晚的路径导向定位器path-oriented locators配套的 docs/slate-browser/next-api-candidates-matrix.md 给出了每个候选的详细评审状态、候选形态、证据来源、消除的痛点、风险与规则并据此划出阶段切分Phase 1ready、selection.select(...)、blockTexts、snapshot()Phase 2容错选区断言、HTML 归一化选项、可能的get.selectedText()Phase 3真实剪贴板读取、替代表面作用域alternate-surface scoping、路径导向定位器4.1 当前测试痛点数据API 存在的理由矩阵文档统计了当前 Playwright 示例套件中的重复噪音裸page.goto(...)23 处裸getByRole(textbox)41 处裸selectText()7 处裸 DOM 选区手术document.createRange/window.getSelection()/addRange(...)5 处裸boundingBox()断言2 处这套数据正是下一个 API 应该消除高频噪音设置而不是再添一个可爱助手名的量化依据。4.2 四个现在就发的 API 候选形态①ready契约最强取自 Lexical 的initialize(...)纪律但不复制其整体臃肿const editor await openExample(page, custom-placeholder, { ready: { editor: visible, placeholder: visible, text: /Type something/, selection: settled, selector: #document-outline, }, });可选表单harness 内await editor.ready({ selection: { anchor: { path: [0, 0], offset: 0 }, focus: { path: [0, 0], offset: 0 }, }, });它消除的痛点临时page.goto(...)、对占位符/文本/额外选择器的一次性等待、隐藏的选区稳定selection-settle时序。强规则优先一个ready对象而不是更多顶层waitForX布尔值风险是变成厨房水槽规则是保持狭窄、只做就绪。②editor.selection.select(...)最强 Slate 风格候选await editor.selection.select({ anchor: { path: [0, 0], offset: 0 }, focus: { path: [0, 0], offset: 5 }, });以及便捷形态与伴随方法await editor.selection.collapse({ path: [0, 0], offset: 0 }); await editor.selection.selectBlock([1]);它解决的悖论是当前 harness 能断言语义选区却不能创建语义选区——测试被迫回退到裸 DOM Range 手术。强规则选区设置语义优先鼠标手势留给交互测试而非基础设置。③editor.get.blockTexts()/editor.assert.blockTexts(...)最佳语义 getter取自 edixexpect(await editor.get.blockTexts()).toEqual([alpha, beta]); await editor.assert.blockTexts([alpha, beta]);伴随窄 getter 与选中文本expect(await editor.get.textAt([1])).toBe(beta); expect(await editor.get.selectedText()).toBe(wise quote);它优于扁平的get.text()对许多 Slate 测试而言过于有损也比裸 HTML 更贴近 Slate 语义、比 DOM 琐碎更稳定。强规则停在块级文本语义不要在这里添加伪造的 DOM 到 Slate JSON 反序列化。④editor.snapshot()最高价值的调试 API灵感来自use-editable的getState()const snapshot await editor.snapshot(); expect(snapshot).toEqual({ text: Hello, blockTexts: [Hello], selection: { anchor: { path: [0, 0], offset: 5 }, focus: { path: [0, 0], offset: 5 }, }, domSelection: { anchorNodeText: Hello, anchorOffset: 5, focusNodeText: Hello, focusOffset: 5, }, });矩阵文档给出的预期载荷还包括selectedText、placeholderShape。强规则快照只聚合既有真相不发明新的隐藏状态——这也是未来 agent-native 产物捕获的燃料。4.3 第二波候选容错选区断言取自 Lexicaloffset 可以是精确值或区间[min, max]await editor.assert.selection({ anchor: { path: [0, 0], offset: [0, 1] }, focus: { path: [0, 0], offset: [0, 1] }, });DOM 侧对应await editor.assert.domSelection({ anchorOffset: [0, 1], focusOffset: [0, 1], });HTML 归一化选项挂在htmlEquals上而不是新增一堆近似重复方法await editor.assert.htmlEquals(expectedHtml, { ignoreClasses: true, ignoreInlineStyles: true, ignoreDir: true, });4.4 第三波候选真实剪贴板读取edix 已证明navigator.clipboard.read()在浏览器测试中有用await editor.clipboard.copy(); expect(await editor.clipboard.readText()).toContain(Hello); expect(await editor.clipboard.readHtml()).toContain(p);替代表面作用域iframe / shadow DOM当前套件已有 iframe.test.ts 与 shadow-dom.test.ts 所述压力与路径导向定位器const editor await openExample(page, iframe, { surface: iframe }); await editor.path([1]).click({ clickCount: 3 }); await editor.textNode([0, 0]).click();4.5 明确拒绝的 API两份候选文档都列出了不要加清单openFixture(...)没有真实 fixture 车道示例挂载真相仍是正确接缝editor.driver()通用驱动逃生舱会摧毁 Slate 风格 API 的意义伪造的合成公开粘贴助手真实浏览器剪贴板写入 真实粘贴手势已经存在一个巨型EditorDriver抽象当前后端是 Playwright-first现在假装不是就是抽象角色扮演。五、四方深度对比谁还在贡献 API 思想计划文档记录了4-way deep dive针对 Lexical、ProseMirror、Tiptap、edix 四家的聚焦对照完整版见 docs/slate-browser/four-way-api-deep-dive.md。其结论Bottom Line FirstLexical仍是助手 API 的最强来源就绪契约、容错选区断言、HTML 归一化选项、剪贴板序列化纪律、人类可读期望选区构建器ProseMirror是最强的接缝/不变量来源——不提供最漂亮的 API但提供最好的不变量和一个严肃的后期 API选区书签selection bookmarksedix仍贡献少量高价值语义 gettergetText、getSelection、getSelectedRect、getSelectedTextTiptap主要是 DX 与产品化验证者不是助手 API 矿藏。这次深潜materially changed one thingProseMirror 暴露了一个真实的后期候选——editor.selection.bookmark()/capture()——但前提是它必须有真实的 Slate 侧书签/range-ref 接缝支撑而不是 Playwright 伪造品。六、当前状态盘点三个 Phase 已全部落地计划文档的 Findings 明确记录了已落地在代码里的清单对应实现位于.tmp/slate-v2/packages/slate-browser/src/playwright/index.ts配套 red/green 覆盖在.tmp/slate-v2/playwright/integration/examples/slate-browser-helpers.test.ts这些路径是计划文档记录的当时状态Phase 1 已落地ready契约editor.selection.select(...)editor.selection.collapse(...)editor.get.blockTexts()editor.assert.blockTexts(...)editor.snapshot()Phase 2 已落地容错选区断言容错 DOM 选区断言editor.get.selectedText()归一化的editor.assert.htmlEquals(..., options?)Phase 3 已落地真实剪贴板读取editor.clipboard.readText()、editor.clipboard.readHtml()替代表面作用域surface.frame、surface.scope路径导向定位器editor.locator.block(...)、editor.locator.text(...)选择书签接缝也已落地editor.selection.capture(...)editor.selection.bookmark(...)editor.selection.resolve(...)editor.selection.restore(...)editor.selection.unref(...)文档特别强调这个接缝由真实编辑器RangeRef语义支撑暴露在根表面上而不是一个伪造的仅限 Playwright 的快照别名——为此还在旧Editable根与slate-dom-v2挂载根上暴露了刻意设计的浏览器测试句柄让slate-browser能创建真正的RangeRef支撑选区书签。七、决策标准与五个方向研判文档 docs/slate-browser/next-system-move.md 给出了下一步动作的决策标准下一步应直接帮助证明剩余的slate-v2浏览器面向接缝提升测试诚实度而不是抽象数量让未来的跨浏览器与性能车道更轻松在第二个后端真实存在之前避免伪造车道中立的 API 设计。基于此文档对五个候选方向逐一研判方向 1更强的openExample(...)就绪契约——最强动作。理由每个剩余的浏览器面向证明都以挂载示例为起点当前openExample(...)有用但仍单薄就绪状态目前被描述为几个等待而不是一个真正的契约。它应该保持openExample(...)作为唯一路由入口、让就绪显式且有意为之、区分页面导航 / 编辑器根可见性 / 示例特定挂载状态 / 选区敏感就绪。它不应该变成Lexical 体量的厨房水槽初始化器、通用 runner 抽象、新的公开openFixture(...)。强立场偷 Lexical 的设置纪律不复制它的整个initialize(...)大块。方向 2跨浏览器车道——重要但不是第一。现在做它输的原因文档已拒绝伪造的跨浏览器 IME 抽象剧场Chromium 仍是 IME 与剪贴板重负载示例证明的诚实第一车道没有更锋利的就绪契约跨浏览器车道只会给你更宽的 flake。最佳姿态就绪契约落地后加test:slate-browser:cross先从非 IME 证明开始占位符可见性、语义选区归一化、普通剪贴板行为不要从 Safari/WebKit IME 英雄主义开始。方向 3性能/精度车道——应该做但要等下一个正确性接缝钉死之后。Premirror 与 Pretext 是车道命名与基准诚实度的正确影响源但正确性目标停止漂移后性能车道才值钱得多。最佳后期形态test:slate-browser:perf可能还有test:slate-browser:accuracy。强立场渲染器/输入策略证明赛道存在之前不上性能车道。方向 4弱化 Playwright 特定公开边界——今天做是错的。理由当前只有一个真实公开后端slate-browser/playwright现在构建通用EditorDriver是抽象角色扮演包已经有正确的切分core/browser放车道中立名词playwright放后端特定 harness。规则保持 API 名词编辑器形状在第二个后端真实之前保持后端表面显式。方向 5发布姿态——此刻最不重要。包形状已经真实包承诺仍应保守发布策略不会解锁下一个slate-v2接缝。最佳姿态在公开 API 之上再落地一个真实证明车道之前保持包 experimental/private。八、具体动作批次与目标接缝计划的最终推荐是两个连续动作把openExample(...)变成真正的就绪契约用该契约搭建第一个渲染器/输入策略证明赛道。该赛道应瞄准当前未解决的接缝这也是本次系统级动作最终要钉死的四大目标空块占位符策略empty block placeholder policy零宽字符渲染策略zero-width rendering policy哨兵文本周围的选区归一化selection normalization around sentinel text空/零宽敏感起点上的 IME 提交行为IME commit behavior on empty and zero-width-sensitive starts具体 trancheDo this next收紧OpenExampleOptions让就绪语义替代临时等待为零宽 / 空状态 / IME 邻近行为添加就绪敏感的浏览器回归只有在那之后才向外分支到test:slate-browser:cross、test:slate-browser:perf可能还有test:slate-browser:accuracy。8.1 反规则清单文档明确列出不要先做这些重新引入openFixture(...)添加伪造的公开合成粘贴助手发明车道中立 driver 抽象从跨浏览器 IME 剧场开始把发布语义变成主要架构决策九、分层测试框架与命令体系该动作植根于 docs/slate-browser/overview.md 确立的分层测试框架世界观一个 runner 统治一切是陷阱速度、保真度与覆盖想要不同的工具Layer 0 核心快速测试纯模型/变换/选区/投影语义Layer 1 DOM 契约测试浏览器支撑的契约测试未来方向是 Vitest browser Playwright providerLayer 2 示例集成测试Playwright断言真实示例表面上的真实编辑器行为Lane A IME/组合Chromium Playwright CDPjsdom 组合测试不够Lane B Agent 原生dev-browser/agent-browser后期扩展接缝Lane C 性能显式基准脚本。slate-browser在该体系中的角色是master roadmap 的专家测试/证明车道不拥有 roadmap 真相或队列顺序但喂养已产出工件义务proof ledger。计划文档记录的可信本地命令包括均为当时仓库根命令yarn workspace slate-browser testyarn test:slate-browser:e2e:localyarn test:slate-browser:bookmarks:localPLAYWRIGHT_BASE_URLhttp://localhost:3200 yarn test:slate-browser:e2ePLAYWRIGHT_BASE_URLhttp://localhost:3200 yarn test:slate-browser:imePLAYWRIGHT_BASE_URLhttp://localhost:3200 yarn test:slate-browser:clipboardPLAYWRIGHT_BASE_URLhttp://localhost:3200 yarn test:slate-browser:anchorsyarn lint:typescriptROLLUP_PACKAGESslate-browser,slate-react,slate-dom-v2 yarn build:rollup其中两条本地置信命令yarn test:slate-browser:e2e:local、yarn test:slate-browser:bookmarks:local是新接入的计划文档记录书签接缝验证时因共享的:3200服务器对应用运行时改动不是可信目标因此用全新本地站点服务器http://localhost:3210验证并修复了本地 Playwright runner 路径新增scripts/run-slate-browser-local.sh并在.tmp/slate-v2/package.json接入 fresh-server 本地命令。十、执行进度从文档迁移到书签验证的一日闭环计划文档的 Progress 日志2026-04-04完整记录了这次动作从调研到验证的闭环加载task、learnings-researcher、goal workflow、major-task对照当前docs/与原内部文档树映射迁移前的重叠将原内部文档树迁入docs/并重写过期内部路径引用重读 Slate v2 /slate-browser文档、学习文档、包文件与示例测试新增 docs/slate-browser/next-system-move.md 并从slate-browser/slate-v2概览文档链接它验证旧内部文档树消失、无陈旧路径引用残留运行跨仓库系统扫描Lexical、edix、rich-textarea、Premirror、Pretext、TanStack DB、urql、VS Code、LSP新增 docs/analysis/editor-global-systems-objective.md 并链接新增 docs/slate-browser/next-api-candidates.md 与 docs/slate-browser/next-api-candidates-matrix.md完成 Lexical / ProseMirror / Tiptap / edix 四方对照新增 docs/slate-browser/four-way-api-deep-dive.md依次实现 Phase 1、Phase 2、Phase 3 的slate-browserPlaywright tranche并逐波补充 red/green 覆盖暴露浏览器测试句柄、落地书签接缝用:3210fresh-server 验证并以yarn test:slate-browser:e2e:local跑完全部 helper 套件。十一、结论这份下一系统级动作文档的核心判断可以用三句话收束公开包 tranche 已经完成——slate-browser已从一次性 spike 变成带公开拆分的真实 workspace 包slate-browser、slate-browser/core、slate-browser/browser、slate-browser/playwright下一步不是更多表面积而是两件事在openExample(...)上建立更锋利的就绪契约再用该契约搭建渲染器/输入策略证明赛道钉死空块占位符、零宽渲染、哨兵文本选区归一化与 IME 提交行为这四大接缝这是通往诚实跨浏览器、性能与发布决策的最干净路径——只有当正确性车道停止漂移test:slate-browser:cross与test:slate-browser:perf才有意义而只有由真实RangeRef语义支撑的选择书签接缝才能让选区在历史、注释锚点与 transform 存续测试中成为一等公民。对任何想要继续深入研究slate-browser体系的人建议按此顺序阅读先读 docs/slate-browser/overview.md 建立分层框架观再读 docs/slate-browser/next-api-candidates.md 与 docs/slate-browser/next-api-candidates-matrix.md 理解 API 排序依据然后读 docs/slate-browser/four-way-api-deep-dive.md 对照四方结论最后回到 docs/slate-browser/next-system-move.md 与本文所依据的计划文档即可完整还原这次系统级动作的决策全貌。【免费下载链接】plateRich-text editor with AI and shadcn/ui项目地址: https://gitcode.com/GitHub_Trending/pl/plate创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考