For AI agents: the complete documentation index is available at https://a3s-lab.github.io/Office/docs/0.307.0/llms.txt, the full documentation bundle is available at https://a3s-lab.github.io/Office/docs/0.307.0/llms-full.txt, and this page is available as Markdown at https://a3s-lab.github.io/Office/docs/0.307.0/components/document.md.

DocumentEditor

DocumentEditor 用于编辑需要分页的 DOCX 兼容文档、报告和长篇内容。 TipTap 负责逻辑文档与选区,A3S Office 内核负责确定性分页、文本塑形和文件语义。

长文档 DOM 测量采用协作式调度。编辑器以 32 毫秒为上限分片测量规范的顶层块,只在块之间 让出事件循环;受控文档发生变化时会中止旧任务。只有完整测量才会更新可复用分页快照, Worker/WASM 布局结果仍是最终依据。

属性

属性类型必填默认值说明
contentDocumentContent受控文档内容。
onChange(content: DocumentContent) => void返回完整的新内容。
collaborationOfficeCollaborationSession使用已经初始化的 Yjs Document 作为规范值;comment 开放评论记录,经过认证的 suggest 开放署名文字建议,但都不能直接修改规范正文。
presenceOfficeCollaborationPresence发布本地选区,显示远端光标、选区与成员导航;必须属于同一个 collaboration 会话。
artifactIdstring在线 PDF 导出使用的稳定宿主 ID。
previewbooleanfalse使用同一分页结果的只读渲染。
saveStatusstring'Saved automatically'由宿主管理的保存状态。
fileActionsreadonly OfficeFileAction[][]宿主文件操作。
extensionsExtensions[]名称不重复的附加 TipTap Extension。
kernelWasmUrlstring内置内核覆盖 Office 排版内核地址。
layoutFontsreadonly DocumentLayoutFont[]内置字体浏览器与塑形内核共用、并显示在字体菜单中的字体。
onAgentRequest(request: EditorAgentRequest) => void | Promise<void>把类型化编辑请求发送给宿主 AI 流程。
onReviewConflict(event: DocumentReviewConflictEvent) => void报告规范受控更新改变审核范围的冲突。
getSelectionMenuItemsGetDocumentSelectionMenuItems内置菜单完全替换选中文本后的右键菜单。
theme'light' | 'dark' | 'system''system'配色模式。

内容结构

字段类型说明
type'document'内容类型标识。
htmlstring与结构化模型一起保存的兼容表示。
modelWorkDocumentModel带版本的 TipTap 文档树,也是精确编辑源。
pageSize'a4' | 'letter'默认纸张;分节可以覆盖。
pageColorstringDOCX 与 PDF 导出保留的页面颜色。
orientation, margins, columns文档布局字段分节覆盖前的默认布局。
pageChromeWorkDocumentPageChrome首页、奇数页、偶数页的页眉、页脚和页码。
trackChangesboolean是否记录修订。
changeDecisionsWorkDocumentChangeDecision[]协作修订接受/拒绝后的不可变共享审计记录。
commentsWorkDocumentComment[]批注、回复与解决状态。
bibliographyWorkDocumentBibliography引用样式与文献记录。

输入法与受控更新

中文、日文、韩文等组合输入在进行期间由浏览器持有。DocumentEditor 不会通过 onChange 发布拼音等预编辑文字;compositionend 后会先等待 ProseMirror 完成 DOM 结算,再一次性发布完整的最终文档。

如果宿主在组合输入期间传入另一份受控 content,编辑器会把替换延后到组合输入结算。 最终本地输入会先通知宿主,仍然有效的宿主版本随后完成协调。宿主不需要为输入法增加 专用 debounce 或事件过滤器。

原生大小写效果

“开始”功能区的“大小写效果”菜单用一个互斥字符格式状态提供常规、全部大写和小型大写。 Cmd/Ctrl+Shift+A 切换全部大写,Cmd/Ctrl+Shift+K 切换小型大写。正文、页眉页脚、 格式刷、字符格式修订和撤销共用同一组 TipTap 命令与元数据。

编辑器不会改写语义正文。全部大写由 text-transform: uppercase 渲染,小型大写由 font-variant-caps: small-caps 渲染。DOCX 导入、导出和重新打开会保留原生 w:capsw:smallCaps,包括明确重置和 w:rPrChange 中的旧格式。

包含这两种效果的段落会有意使用浏览器行测量。大写转换可能让渲染字形数量与源 UTF-16 偏移不再一一对应,小型大写也会改变字体度量;浏览器作为这些段落的最终依据可以避免错误 分页,其余符合条件的段落仍使用 Worker/WASM 塑形。

原生分脚本字体

Writer 会分别保留 WordprocessingML 的四个 w:rFonts 字体槽:asciihAnsieastAsiacs。每个槽都独立保存准确的直接字体、可选主题引用,以及浏览器实际解析的 字体;w:hint 继续作为原生元数据保留。样式继承只负责计算有效字体,不会改写尚未修改的 直接字体或主题身份。包含多种文字的同一运行会被拆成有界 TextStyle 片段,分别处理拉丁 ASCII、高 ANSI、东亚和复杂文字;中性标点仍跟随相邻文字。

Cmd/Ctrl+D 或“开始”功能区会打开“字体高级设置”,分别提供拉丁文字、东亚文字和复杂 文字字体。拉丁文字控件会同时更新 asciihAnsi;“开始”字体选择器表达“所有文字” 意图,会同时更新四个槽。三个控件分别判断混合选区,并支持“跟随样式”。预览会按文字片段 使用对应草稿字体。字体、缩放、间距、字距调整、着重号、隐藏文字、字符边框、空心、阴影、 阳文、阴文或位置的任意组合在应用时都会恢复保存的选区,并只生成一个事务和一条撤销记录。

正文、页眉、页脚、脚注、尾注、格式刷、字符格式修订、严格或过渡 DOCX 导入、准确导出与 重开共用同一类型模型。修改一个字体槽不会破坏其他槽未修改的主题引用。重复或错位元素、 多余或伪造属性、包含子节点或文本的叶节点、未知值,以及超过 127 个字符的字体名都会安全 拒绝并进入兼容性诊断。DOM 在 data-office-script-fonts 中保存经过校验的 JSON,在 data-office-script-font-slot 中保存当前片段;CSS 只使用解析后的字体,因此浏览器字体替代 不会改写原生文件身份。

原生 OpenType 排版

Writer 为普通文字与结构化公式共用一个封闭的 Office 2010 OpenType 模型。它会保留全部 16 种原生 w14:ligatures 组合,w14:numFormdefaultliningoldStyle 数字字形,w14:numSpacingdefaultproportionaltabular 数字间距, w14:stylisticSets 的 1 到 20 规范样式集 ID,以及明确启用或重置上下文替代的 w14:cntxtAlts 值。每个属性独立继承;格式错误、重复、错位、包含子节点或文本、 越界或命名空间伪造的值都会安全拒绝。

Cmd/Ctrl+D 或“开始”功能区会打开“字体高级设置”,分别提供连字、数字字形、数字间距、 样式集和上下文替代控件。每个控件独立显示混合选区状态与“跟随样式”值。应用时只修改每个 选中运行中用户触碰过的属性,保留其他直接 OpenType 设置,恢复打开弹窗时保存的选区,并把 OpenType、分脚本字体和其他高级字符设置合并成一个事务及一条撤销记录。实时预览与正文使用 同一套规范 CSS 投影。

正文、页眉、页脚、脚注、尾注、批注、格式刷、字符格式修订与拒绝修订共用同一类型模型。 DOCX 导出会按规范顺序写出 w14 属性,声明所需命名空间与 mc:Ignorable 标记,并在重开 后保留当前值和旧值。兼容性诊断会指出不支持或无效的源值。DOM 在 data-office-opentype-features 中保存规范 JSON,CSS 通过 font-feature-settingsfont-variant-ligaturesfont-variant-numeric 投影。启用塑形的段落使用浏览器权威 行测量,避免字形替代让源 UTF-16 偏移与分页不同步。

原生字符间距

Writer 用一个有符号原生 w:spacing 值保存字符间距,范围为 -31,680 到 31,680 twips, 每 20 twips 等于 1 磅。Cmd/Ctrl+D 或“开始”功能区会打开“字体高级设置”,提供标准、 加宽、紧缩以及 0.05–1,584 磅的精确间距值。混合选区在用户明确选择模式之前保持不变。 应用会恢复打开弹窗时保存的选区,并只生成一条撤销记录;取消和 Escape 不修改文档, 并把焦点还给编辑器。

正文和页眉页脚编辑器共用同一条 TipTap 命令,显式零值与继承间距保持区分。格式刷、字符 格式修订、撤销、DOCX 导入、导出和重新打开,以及 w:rPrChange 中的旧格式都会保留准确 有符号值。DOM 使用 data-office-character-spacing-twips 保存原生值,CSS 只通过 letter-spacing 投影显示效果,不改写文字。排版内核会应用相同的线性字宽调整,因此符合 条件的段落仍然使用 Worker/WASM 路径。

原生字符水平缩放

Writer 用一个 1% 到 600% 的原生 w:w 整数保存字符水平缩放。缺少该属性时仍然继承, 显式 100% 会作为直接重置保留,空的 <w:w/> 按原生规则解释为 100%。严格与过渡 WordprocessingML 共用同一个有界整数模型;格式错误、小数、重复、包含子节点、越界或 命名空间伪造的属性都会安全拒绝。

Cmd/Ctrl+D 或“开始”功能区会打开“字体高级设置”,其中“缩放”字段接受准确整数范围。 缩放、间距和基线位置分别判断混合选区;修改任意组合并应用后,会恢复保存的选区,且只 生成一个事务和一条撤销记录。字符缩放没有独立标准快捷键,因此 Writer 不会虚构一个。

正文、页眉、页脚、格式刷、字符格式修订、拒绝修订恢复、DOCX 导入/导出/重新打开以及 w:rPrChange 中的旧格式都会保留准确值。DOM 使用 data-office-character-scale-percent 保存原生值,并通过 CSS font-stretch 投影。 在 Worker/WASM 文字排版协议能够传递准确逐运行水平缩放之前,非 100% 的运行会明确使用 浏览器行测量,其余符合条件的段落仍走确定性内核路径。

原生字距调整

Writer 用一个 0 到 3,277 半磅单位的原生 w:kern 阈值保存字距调整。 正值会在有效 w:sz 字号大于或等于阈值时启用字对调整,因此 24 表示 12 磅。显式零值表示所有字号都启用。直接属性缺失时继续按样式层级继承, 整个层级都缺失 w:kern 时则保持关闭。

共享的 Cmd/Ctrl+D “字体高级设置”弹窗提供字距调整复选框,以及 0–1,638.5 磅、按 0.5 磅递增的准确阈值。新建直接格式默认为 12 磅。缩放、 间距、字距调整、着重号和基线位置分别判断混合选区,并可在一个事务中同时提交。 取消勾选只会清除直接字距调整;应用会恢复保存的选区,并只生成一条撤销记录。 该能力没有独立标准快捷键,因此 Writer 不会虚构一个。

正文、页眉、页脚、脚注、尾注、继承样式、格式刷、字符格式修订、拒绝修订恢复、 DOCX 导入、导出、重新打开以及 w:rPrChange 中的旧格式都会保留准确半磅值。 严格与过渡文档都会安全拒绝缺值、重复、嵌套、含文本、多余属性、小数、负数、越界和 命名空间伪造。兼容性诊断会分别报告有效值和被拒绝值。

DOM 用 data-office-kerning-threshold-half-points 保存阈值,并把实际状态投影为 CSS font-kerning: normalnone。编辑、预览和 PDF 表面默认关闭字距调整, 再共用该投影。同一有效布尔状态会传入 Worker/WASM 文字排版,避免分页和绘制对 字对宽度产生不一致判断。

原生东亚着重号

Writer 用一个封闭的原生 w:em 状态保存着重号:nonedotcommacircleunderDot。直接属性缺失时,会继续按运行、字符样式、段落样式和文档默认值继承。 显式 none 与移除直接格式不同,它会有意覆盖并关闭继承的着重号。

共享的 Cmd/Ctrl+D “字体高级设置”弹窗提供“跟随样式”“无”“上方圆点”“上方逗号” “上方圆圈”和“下方圆点”。着重号、缩放、间距、字距调整和基线位置分别保留混合选区 状态。“跟随样式”只移除直接属性,“无”则写入原生重置值。应用会恢复保存的选区和焦点, 并把所有已修改字符属性作为一个事务和一条撤销记录提交。Writer 没有对应的独立标准 快捷键,因此命令目录不会虚构一个。

正文、页眉、页脚、脚注、尾注、继承样式、格式刷、字符格式修订、拒绝修订恢复、严格或 过渡 DOCX 导入、导出、重新打开,以及 w:rPrChange 中的旧格式都会保留准确值。缺值、未知 标记、重复或嵌套元素、带文本的叶节点、多余属性和命名空间伪造都会安全拒绝,并进入兼容性 诊断。

DOM 使用 data-office-emphasis-mark 保存状态。CSS text-emphasis-styletext-emphasis-position 会把效果投影为文字上方的实心圆点、逗号或空心圆圈,或者文字 下方的实心圆点。可见着重号会让段落使用浏览器权威行测量,以计入普通行框之外的字形。 只有最终计算出的标准与 WebKit 着重号样式都为空或 none 时,显式“无”才继续使用 Worker/WASM 路径,因此宿主 CSS 覆盖不会造成分页判断不一致。

原生隐藏文字

Writer 使用一个三态 TextStyle 属性保存隐藏文字。移除直接属性后,会继续按运行、字符 样式、段落样式和文档默认值继承。true 写入原生 w:vanishfalse 写入显式 w:vanish w:val="0" 重置,确保继承的隐藏格式在导出和重新打开后仍保持可见。

共享的 Cmd/Ctrl+D “字体高级设置”弹窗会分别处理隐藏文字、缩放、间距、字距调整、 着重号和基线位置。混合选区在用户修改“隐藏文字”复选框前保持不变;应用会恢复保存的 选区,并把所有已修改属性作为一个事务和一条撤销记录提交。标准 Cmd/Ctrl+Shift+H 快捷键调用同一类型化命令;TipTap 冲突的突出显示绑定已禁用。

正文、页眉、页脚、脚注、尾注、继承样式、格式刷、字符格式修订、拒绝修订恢复、严格或 过渡 DOCX 导入/导出/重新打开,以及 w:rPrChange 中的旧格式都会保留准确状态。空属性 以及小写的 10onofftruefalse 会被接受;未知大小写或标记、重复、 子节点、文本、多余属性、错位元素和命名空间伪造都会安全拒绝并进入兼容性诊断。未修改的 评论 XML 只进行源保留,这一边界不表示支持富评论正文编辑。

DOM 使用 data-office-hidden-text="true|false" 保存状态。隐藏文字默认不显示;“视图” 功能区的“显示隐藏文字”只会在可编辑 Writer 表面揭示内容,并添加传统点状下划线。只读 预览和独立 PDF 捕获始终隐藏内容。包含隐藏文字的段落使用浏览器权威行测量,避免不可见 字形进入 Worker/WASM 字宽模型。

原生空心、阴影、阳文与阴文

Writer 使用四个独立、可空的 TextStyle 属性保存原生 w:outlinew:shadoww:embossw:imprint。移除直接属性后,会继续按运行、字符样式、段落样式和文档 默认值继承。true 写入原生启用属性,false 写入显式 w:val="0" 重置,确保继承效果 在导出和重新打开后仍保持关闭。

空心与阴影可以同时启用。阳文与空心、阴影、阴文互斥;阴文与空心、阴影、阳文互斥。 共享的 Cmd/Ctrl+D “字体高级设置”弹窗分别保留四项的混合选区状态。启用互斥效果时, 界面会自动清除所有冲突项并把这些清除标记为已修改,因此“应用”会把完整、无冲突的结果 作为一个事务和一条撤销记录提交。Writer 没有对应的独立标准快捷键,所以命令目录不会 虚构一个。

正文、页眉、页脚、脚注、尾注、文档默认值、继承样式、格式刷、字符格式修订、拒绝修订 恢复、严格或过渡 DOCX 导入/导出/重新打开,以及 w:rPrChange 中的旧格式都会保留准确 值。空属性以及小写的 10onofftruefalse 会被接受;未知大小写或 标记、重复、嵌套或带文本的叶节点、多余属性、错位元素、命名空间伪造和冲突启用组合都会 安全拒绝并进入兼容性诊断。

DOM 使用 data-office-legacy-text-outlinedata-office-legacy-text-shadowdata-office-legacy-text-embossdata-office-legacy-text-imprint 保存显式 true|false 值。CSS 用有界描边投影空心,用有界偏移投影阴影,并用方向相反的明暗偏移 投影阳文与阴文。浏览器与 PDF 因此提供受控视觉近似,不声称与桌面引擎逐像素一致。这四种 效果只改变绘制,其他条件符合的段落仍走 Worker/WASM 排版路径。打开 Playground 的 “文字效果”模板即可查看四种状态,并把合法的“空心 + 阴影”组合切换为互斥效果。

原生字符边框

Writer 使用一个类型化原生 w:bdr 值保存字符边框。模型会保留 WordprocessingML 的 25 种可见线型,以及显式 nilnone 重置;同时保留直接颜色或带 tint/shade 的主题 颜色、2 到 96 个八分之一磅单位的宽度、0 到 31 磅的文字间距,以及显式阴影和框架标志。 导入后的 nilnone 即使都不绘制,也仍然保持不同语义。

“开始”功能区的字体组提供直接“字符边框”开关。共享的 Cmd/Ctrl+D“字体高级设置”弹窗 会保持未修改的混合选区,并区分“跟随样式”“显式无边框”和可编辑边框。线型、颜色、 0.25–12 磅且以 0.125 磅递增的准确宽度、整数间距、阴影与框架,会与其他已修改字符属性 一起通过一个事务和一条撤销记录提交。格式刷复用同一个 Mark。Writer 没有对应的独立标准 快捷键,因此命令目录不会虚构一个。

文档默认值、段落和字符样式、正文、页眉、页脚、脚注、尾注、字符格式修订、严格或过渡 DOCX 导入、准确导出与重开都会保留语义值。格式错误、重复、错位、命名空间伪造、带子节点 或文本、多余属性、艺术边框、越界以及无法解析主题颜色的输入都会安全拒绝并进入兼容性 诊断。w:rPrChange 中的旧格式使用同一个有界解析与导出路径。

DOM 在 data-office-run-border 中保存校验后的 JSON,并通过 CSS 投影四边边框、间距、 阴影和跨片段克隆。可见边框和内边距会改变行内几何,因此相关段落使用浏览器权威行测量; 显式 nilnone 仍可走 Worker/WASM。浏览器与 PDF 的线型绘制属于有界视觉近似, OOXML 语义则保持准确。打开 Playground 的“字符边框”模板即可体验完整设置与单步撤销。

原生字符底纹

Writer 使用一个类型化原生 w:shd 值保存字符底纹,不再把它压扁为浏览器背景色。模型会 保留 WordprocessingML 的全部图案、直接或自动前景色与背景色、彼此独立且带 tint/shade 的 themeColorthemeFill 引用,以及显式 nil 重置。同一主题通道同时带 tint 和 shade 时,浏览器绘制遵循原生 tint 优先级,导出仍保留两个属性。

共享的 Cmd/Ctrl+D“字体高级设置”弹窗会独立判断底纹混合状态,并区分“跟随样式”、 “显式无底纹”和可编辑底纹。图案、前景色与背景色可分别修改;解析颜色未改变时继续保留 主题身份,选择直接颜色只替换对应通道。底纹会与其他已修改字体属性通过一个事务和一条 撤销记录提交,格式刷复用同一个语义 TextStyle 值。

文档默认值、段落和字符样式、条件表格样式、正文、页眉、页脚、脚注、尾注、字符格式修订、 严格或过渡 DOCX 导入、准确导出与重开共用同一解析器。格式错误、重复、错位、命名空间 伪造、带子节点或文本、多余属性以及无法解析主题颜色的叶节点会安全闭合为显式 nil,并 进入兼容性诊断。w:rPrChange 中的旧值使用同一个有界模型。

DOM 在 data-office-run-shading 中保存校验后的 JSON。CSS 对实心、条纹、交叉、细线和 百分比图案提供有界投影,并克隆跨行片段。底纹只改变绘制,因此符合条件的段落仍走 Worker/WASM 排版。原生 w:highlight 保持为独立 Mark,并在显示时优先于底纹,但不会删除 底层底纹语义。打开 Playground 的“字符底纹”模板即可编辑完整模型并验证单步撤销。

原生校对语言

Writer 会分别保留原生 w:lang 的三个语言槽:拉丁文字 w:val、东亚文字 w:eastAsia 与双向文字 w:bidi。原生 w:noProof 是另一项独立的三态值:移除直接值 表示跟随当前样式,false 表示显式参与校对,true 表示排除校对。它不会被压平为整个 文档共用的浏览器拼写检查开关。

“审阅”功能区在“拼写检查”旁提供“设置校对语言”。可访问弹窗接受有界 BCP 47 语言标记, 分别报告三个槽的混合状态,未修改的槽保持原值,并为每个语言槽和校对状态提供“跟随样式”。 “应用”会恢复捕获的选区与焦点,把所有已修改字段放入一个 TipTap 事务和一条撤销记录; 编辑页眉或页脚时复用同一模型。

文档默认值、段落和字符样式、正文、页眉、页脚、脚注、尾注、字符格式修订、拒绝修订恢复、 严格或过渡 DOCX 导入/导出/重开,以及 w:rPrChange 中的旧格式都会保留准确语言槽和显式 状态。格式错误、重复、错位、嵌套、带文本、多余属性、命名空间伪造、无效语言标记或无效 开关值会安全拒绝,并进入兼容性诊断。

DOM 在 data-office-proofing-languages 中保存规范语言 JSON,在 data-office-no-proof="true|false" 中保存显式状态,并投影有效的 langspellcheck 属性。有效语言还会随每个 Worker 排版运行传入 Rust/WASM,并在 RustyBuzz 塑形前写入缓冲区。 这会保留与语言相关的塑形行为,但不声称内置拼写词典、语法或翻译服务。打开 Playground 的 “校对语言”模板即可查看拉丁、东亚、双向文字、显式参与校对和排除校对示例。

原生字符基线位置

同一个“字体高级设置”弹窗会把标准、提升或降低保存为一个有符号原生 w:position 值, 范围为 -3,168 到 3,168 个半磅单位。一个半磅单位等于 0.5 磅,因此位置值支持 0.5–1,584 磅的精确幅度。缩放、位置与间距分别判断混合选区;即使同时修改三项,应用也 只提交一个事务并生成一条撤销记录。

正文、页眉页脚、格式刷、字符格式修订以及 w:rPrChange 中的旧格式共用同一个 TipTap 属性,显式零值与继承值保持区分。过渡 DOCX 接受有符号整数;严格 DOCX 还接受能够准确 换算为半磅整数的通用度量。格式错误、重复、越界或命名空间伪造的属性都会安全拒绝。 导出和重新打开会写回准确原生值,包括 w:position w:val="0"

DOM 使用 data-office-character-position-half-points 保存原生值,并通过 --work-document-character-position 暴露准确磅值;CSS 再以数值 vertical-align 投影。 当 w:positionw:vertAlign 同时存在时,原生上下标优先显示;移除上下标后,保留的 基线偏移会重新生效。在 Worker/WASM 文字排版协议能够传递逐运行基线偏移之前,这类段落 会明确回退到浏览器行测量,其余符合条件的段落仍走确定性内核路径。

实时评论模式

传入已经初始化、带认证 Actor 且 mode: 'comment' 的 Document 协作会话,可以在不开放 正文编辑的情况下创建选区评论。审阅者可以创建线程、回复、解决或重开,并且只能删除 自己拥有的记录。线程、选区 Mark、Actor 归属和脱离锚点状态会持久化到 Yjs/Yrs;远端 审核变化不会进入本地撤销历史。浏览器、CLI/MCP 与 A3S Boot 的完整授权流程见 多人实时协作

实时建议模式

传入已经初始化、带认证 Actor 且 mode: 'suggest' 的 Document 协作会话,可以创建署名 插入、删除与替换建议。编辑器会强制记录文字修订,不显示普通格式、评论与最终决定控件, 并且只允许当前 Actor 撤回自己的建议。规范文字、结构、非建议格式、选项、评论和其他 Actor 的建议都保持受保护状态。

edit 参与者在修订面板中接受或拒绝建议。可见修改和一条不可变 WorkDocumentChangeDecision 会在同一个 Yjs 事务中提交。记录保留建议与决定双方的 Actor、名称和时间,并通过 content.changeDecisions 返回;第二个冲突决定会失败关闭。 A3S Boot 参考服务还会在持久化和广播之前,通过 Yrs 重复执行同一套语义授权。完整浏览器 与后端契约,以及当前原生 CLI/MCP 的限制,见 使用 suggest 模式提出修订

字符格式修订

开启修订后,对已有文字应用直接字符格式会创建一条 formatting 修订。有界模型覆盖粗体、 斜体、下划线、删除线、上下标、字体、字号、文字颜色、高亮、字符缩放、字符间距、字距调整阈值、着重号、隐藏文字、字符边框、空心、阴影、阳文、阴文、基线位置、全部大写、小型大写和 Word 文档网格状态。仍处于待处理插入修订中的文字继续归属于该插入,不会再嵌套一条格式修订。

修订保存准确的旧直接 Mark,同时用新 Mark 渲染选中文字。接受只移除修订包装并保留新 格式;拒绝恢复旧 Mark 并移除包装,不改变任何字符。两种操作都只产生一个事务;清除 直接格式也不会删除评论或修订 Mark。

受支持的严格或过渡 DOCX w:rPrChange 会导入为同一张审核卡,保留作者、可选日期、 当前格式和旧格式;导出时重新写成原生 w:rPrChange。不支持、格式错误、重复或命名空间 伪造的运行属性修订继续进入结构诊断,不会被误解为可编辑状态。

在协作中,修订 Mark 与接受/拒绝审计记录都通过标准 Yjs v1 更新传输。Yrs 会校验有界 格式快照并读取 formatting 决定记录;经过认证的 suggest 会话必须保留已有格式修订, 不能创建或改写它。完整边界见 同步字符格式修订A3S Boot 后端。在 Playground 中依次点击 体验格式修订审阅查看修订(3),即可审核“格式”卡。

要查看成对的原生移动语义,请点击 体验移动修订,再打开 审阅。该演示把源侧与目标 侧合并为一张 移动 卡;接受保留目标文字,拒绝保留源文字,并在窄屏上使用同一套模态 审阅面板。

原生下划线格式

Writer 可以创作并重新打开全部 18 种原生 WordprocessingML 下划线值:nonesinglewordsdoublethickdotteddottedHeavydashdashedHeavydashLongdashLongHeavydotDashdashDotHeavydotDotDashdashDotDotHeavywavewavyHeavywavyDouble。 开始功能区、选区工具栏与页眉页脚共用一个可访问的拆分控件;下划线颜色支持自动颜色、 直接 RGB,以及保留的 theme/tint/shade 身份。

Cmd/Ctrl+U 会关闭任意已启用样式,或从关闭状态启用 singleCmd/Ctrl+Shift+D 切换 doubleCmd/Ctrl+Shift+W 切换仅字下划线。 格式刷、字符格式修订、撤销、DOCX 导出与重开都会保留准确的类型化状态,包括用于覆盖 继承格式的显式 none

原生删除线格式

Writer 使用一个 none | single | double 类型化 Mark 保存无删除线、单删除线与双删除线。 开始功能区、选区工具栏和页眉页脚功能区共用同一个可访问拆分控件,紧凑页眉页脚工具栏 保留直接切换按钮。正文、页眉页脚、格式刷、字符格式修订、撤销、DOCX 导出与重开都会 保留准确样式,包括用于覆盖继承格式的显式 none

DOCX 导入会在每一层样式和直接格式中分别跟踪 w:strikew:dstrike,再按双删除线 优先于单删除线的规则解析。导出会同时写入两个属性,因此从继承的双删除线切换到单删除线, 或清除任一继承状态后,重新打开文件都不会恢复过期格式。CSS 只投影实线或双线删除效果, 不会改写文字,也不会让原本符合条件的段落退出 Worker/WASM 排版路径。

传统 Office 没有为 Writer 删除线定义直接快捷键,因此命令目录不会宣传快捷键。 编辑器同时禁用 TipTap 无关的 Mod+Shift+S 绑定;请使用功能区或选区工具栏。

选择工具栏控件

浮动 Writer 选区工具栏与周围操作共用紧凑、随主题变化的按钮基线。下划线和删除线拆分控件 会显式重置浏览器原生按钮外观,在主操作和下拉入口之间保持一条像素分隔线,并继续沿用开始 功能区的悬停、按下、焦点和键盘语义。这样浏览器默认的 outset 边框不会改变工具栏密度,两个 控件也不会看起来像彼此无关的小组件。

段落格式修订

开启修订后,段落命令会给每个受影响的段落或标题创建独立的 paragraph-formatting 修订。有界快照覆盖对齐、文字方向、左右及首行或悬挂缩进、 段前段后间距、行距与规则、段中不分页、与下段同页、段前分页、孤行控制、同样式段落 间距、Outline Level、制表位、边框、底纹和默认折叠状态。一次跨段命令共享稳定修订 身份;未决状态下再次修改格式仍保留第一次修改前的完整快照,不会重置审核起点。

接受会保留当前段落属性,只移除审核元数据。拒绝会恢复完整旧段落属性,不改动正文或 行内 Mark。原格式命令、接受与拒绝分别形成独立撤销边界;旧快照损坏或不是规范形式时 会失败关闭,不会只恢复一部分属性。

受支持的严格或过渡 DOCX w:pPrChange 会导入为“段落格式”卡,保留作者、可选日期、 当前属性和完整的受支持旧属性快照;导出会重新生成原生 w:pPrChange,并移除全部私有 传输标记。重复、格式错误、命名空间伪造或包含不支持属性的段落属性修订继续进入结构 诊断。

节点元数据与不可变 changeKind: "paragraph-formatting" 决定记录都使用标准 Yjs v1 更新。Yrs 能读取该决定类型,让浏览器创建的修订跨重启、重复和乱序投递后继续存在, 并拒绝 suggest 更新创建或改写段落审核元数据。完整链路见 同步段落格式修订。Playground 的第二张卡就是 “段落格式”;拒绝后会恢复旧对齐、缩进、间距和行距,同时保留正文与独立的字符格式 修订。

有序列表编号修订

开启修订后,修改有序列表的十进制、小写/大写字母、小写/大写罗马数字样式,或修改 起始编号,会为完整列表范围创建一条 numbering 修订。第一次修改会保存规范且有界的 原样式、起始值、嵌套层级与保留的 Office 编号身份;未决状态下继续修改仍保留该审核 基线,不会重新取样。

接受会保留当前列表属性,只移除审核元数据;拒绝会恢复完整旧编号快照,不改动任何 列表文字。原命令与每次决定分别形成一步撤销边界。修订面板只显示一张 编号格式 卡, 不会把原生文件中每个列表项的记录误导性地拆成一叠段落修订。

受支持的严格或过渡 DOCX w:numberingChange 会导入明确的单层与有界多层十进制、字母、 罗马数字与项目符号(nfc 23)定义(当前 w:ilvl)。w:original 中的兄弟级别可携带其他 ST_NumberFormat 值作为不透明先验文本。只有作者、日期、编号身份、层级、格式、后缀和旧值序列都一致时,连续的逐项记录 才会合并成一个原子列表意图。导出会在 w:numPr 下重新写入连续的原生记录,启用 w:trackRevisions,并移除全部私有标记。格式错误、重复、冲突、不支持的当前级 图片格式或命名空间伪造的记录继续作为结构诊断处理。

单个快照上限为 64 KiB,原生导入/导出最多处理 65,536 条记录。跟踪器会先检查结构型 ReplaceAroundStep,所以普通输入不会扫描有序列表。列表元数据与不可变 changeKind: "numbering" 决定使用标准 Yjs v1 更新;Yrs 能在持久化和重启后投影它们, 并拒绝 suggest 更新删除或改写该修订。完整链路见 同步有序列表编号修订。Playground 的第三张卡 是 编号格式;拒绝会恢复原罗马数字编号并保留全部列表项,撤销则恢复未决修订。

整段段落标记修订

Word 会同时使用正文中的直接 w:insw:del 包装,以及 w:pPr/w:rPr 下对应的段落标记记录来表示整段插入或删除。仅当修订类型、作者、UTC 时间、命名空间和直接段落结构一致时,A3S Office 才会把这个有界纯文字形态导入为一项 插入或删除审核记录。过渡与严格 Word 命名空间都受支持。正文和段落标记的数字 ID 会分别 严格校验但不要求相同,以兼容原生生产者的实际形态;重复的浏览器身份会安全重新分配。

“修订”窗格只显示一张卡,不会误导性地拆成正文修订和一项空结构修订。接受插入段落或 拒绝删除段落会保留完整块;拒绝插入或接受删除会移除完整块。每项决定只形成一个事务和一条 撤销边界。导出会写入正文修订和独立的原生段落标记修订、启用修订跟踪、移除私有标记,重开 DOCX 后仍保持相同的原子语义。导入和导出最多接纳 65,536 条记录。

孤立的段落标记可能表示段落分隔符合并或拆分。当相邻段落也是符合条件的纯文本段落时, Work 会导入可审阅的 paragraph-break 修订(接受/拒绝时执行合并,并以仅标记的 DOCX 形状导出);否则不会被猜测成整段修订。正文包装旁可出现未跟踪的纯文本兄弟 run (含空/rPr-only),仍作为一项原子整段修订导入。安全的关系绑定外部超链接 (解析到 http/https/mailtor:id)与无关系内部链接一并准入。受支持的 行内 DrawingML 图片(带已解析图片 r:embedwp:inline)与可见文本一并准入;当唯一 内容即为该类图片时,整段段落标记包装与段落分隔符相邻段落也可准入仅含图片正文。 标记包装旁可出现未跟踪、受支持的行内 DrawingML 图片兄弟(镜像未跟踪纯文本兄弟)。 浮动锚点、空或畸形绘图、未解析嵌入、 未解析或不安全的超链接、类型/作者/时间不一致、格式错误或命名空间伪造的属性、 不支持节点以及超出上限的输入会保留在结构兼容路径并明确诊断。

移动修订

Word 会用成对的 w:moveFromw:moveTo 记录一段文字的移动。A3S Office 只把有界的纯文字子集导入为一条 move 审核身份:两侧必须拥有相同的数字 ID、作者、 日期和文字。过渡与严格 Word 命名空间都受支持,浏览器 Mark 会分别保留 fromto 角色。修订面板只显示一张 移动 卡,并把目标位置作为定位范围,因此不会把 源位置与目标位置之间无关的正文一并选中。

接受移动会删除源文字并保留目标文字;拒绝会删除目标文字并保留源文字。两条路径都会 在一条原子事务中同时处理成对的两侧,形成一步撤销边界和一条不可变的 changeKind: "move" 协作决定。若两侧文字不同,面板仍会用“源文字 → 目标文字”显示 诊断摘要,但实际处理会失败关闭,直到配对有效。

DOCX 导出时先让 docx 写入临时负数身份,再把包装改写为带共享正数 ID、作者和 UTC 日期的原生 w:moveFromw:moveTo。成对侧唯一夹住的 companion w:move*Range* 书签也会往返,即使目标侧位于源侧之后的分节,正文级 Start/End 夹住一张恰好在一个 w:tc 内含受支持纯文本移动的 w:tbl(单单元格表,或多单元格表且兄弟单元格仅含未跟踪 纯文本),至多一个简单 w:sdt(可带 w:sdtPr chrome)含有该移动的段落或表格,或移动 祖先至多两层且均含受支持纯文本移动的 w:tbl。重新打开后仍会得到同一张审核卡,不会泄露 data-document-change 或临时身份。导入/导出最多处理 65,536 个移动侧,每条移动文字 上限为 1,000,000 个字符。普通文字以外的富运行内容、更深嵌套表、移动旁的嵌套表、SDT 与 嵌套表组合、嵌套或旁路 SDT sandwich、兄弟单元格中的跟踪修订、把分节符夹进 sandwich 的 范围标记、未配对标记、关系绑定对象、格式错误元数据、重复身份会保留在结构兼容路径并明确 报告,不会被压平成不精确的可编辑移动。Compare / 同文档纯文本推断移动在导出时也会生成 companion w:move*Range* 书签,并使用确定性的 rangeId / rangeName;跨分节与表格/ 复杂 Compare 移动仍失败闭合。

当前“比较文档”可以在同一简单段落或标题中推断移动;如果两个对齐的简单文字块属于同一 分节,也可以在段落之间配对范围。两种路径都要求唯一词法范围在对齐删除/插入块中各出现一次, 文字格式一致且分隔空白可安全携带。准入的推断对会像原生移动一样导出 companion 范围书签。 任意源/目标差异、重复或格式不一致的候选、富文本、跨分节范围、表格和超出上限的文字仍会 生成确定性的插入/删除修订或诊断。需要更广泛的精确移动审核语义时,请使用原生配对移动或 显式的浏览器移动 Mark。

Playground 的 体验移动修订 按钮提供一个可重复的纯文字样例,便于在不导入文件的情况下 检查这套原子接受/拒绝交互。

文档比较与合并

“审阅”功能区现在提供一级 比较文档合并文档 工作流。比较会把当前受控文档 视为原稿,并把导入的 .docx.html.htm.txt 文件视为修订稿。确定性的 分节、块对齐与词元差异会生成现有可审阅的插入、删除、字符格式和段落格式修订。如果 一个词法范围在同一简单段落或标题,或同一分节内对齐的简单文字块的删除块和插入块中各只出现 一次,“比较”还会生成一条成对的 move 移动修订。只有文字格式一致且分隔空白能够安全随 范围携带时才会配对;重复词、格式不一致、富文本、跨分节范围、表格和超出上限的文字会保留 为普通修订或明确诊断。准入的推断对会随原生 w:moveFrom / w:moveTo 一并导出 companion w:move*Range* 书签,并使用确定性的 rangeId / rangeName。所选修订者会写入 每条生成修订,文件名作为有界事务元数据保存,全部结果只通过一次受控 onChange 发布, 一次撤销即可恢复比较前文档。比较成功后,“修订”窗格会自动打开,可以继续使用现有命令 逐项定位、接受或拒绝。

合并采用不同的失败关闭契约。导入的审阅副本必须已经包含修订,当前文档不能有未处理 修订,而且在不可变快照上拒绝导入副本的全部修订后,必须准确重建当前基线。当前有界 路径支持行内插入与删除、字符格式和段落格式修订,并保留当前段落身份。缺少修订、旧 格式快照损坏、基线不一致或存在结构块修订时,当前文档不会改变,并会返回本地化诊断。

每个版本最多可以比较 1,024 个块,两份文档文字合计最多 1,000,000 个字符。块对齐和 每次行内差异最多分配约 110 万个矩阵单元。两份文档必须拥有相同分节数量和页面布局 属性。未变化的复杂块可以原样通过,但发生变化的表格、列表、图片、公式、内容控件、 空结构块或其他复杂树不会被压平为容易误导的纯文字差异。任一比较输入中已有修订、 不支持的审阅标记和分节布局变化也会失败关闭。

生成的行内修订会导出为原生 w:insw:del,字符格式修订导出为 w:rPrChange,段落格式修订导出为 w:pPrChange;导出并重开后仍会保留修订者、 日期、文字和旧格式快照。浏览器新建的插入或删除段落还会使用块容器元数据,使拒绝 插入块或接受删除块时能够移除整个容器。当容器是准确的纯文字段落,且全部文字都属于 同一插入或删除修订时,导出现在会把它映射为上文的原生段落标记形态,重开后仍保留原子 块决定。孤立段落分隔符合并/拆分语义、混合内容和其他结构变化仍会失败关闭并明确报告, 不会被描述成完整结构比较保真。

在 Playground 中打开 文档比较 模板,选择“审阅”→ 比较文档,再导入修订 文件即可走通公开路径。仅本地 A3S Test 套件还会导入专用的跨段样例,验证一张移动卡、 两侧范围标记和原子拒绝。聚焦组件测试、DOCX 重开、响应式 Playwright 与 word-document-comparison.acl 套件共同覆盖受控发布、审核决定、焦点恢复、可访问性以及 空浏览器诊断。Actions 与 Pages 不安装或调用 A3S Test。

DOCX 文字与文档网格保真

导入的分节布局会保留可选的 WorkDocumentGrid,包括 OOXML 网格类型和以磅为单位的行间距; 文字运行会保留明确声明的 snapToGrid。这些属性在编辑和 DOCX 导出后仍然存在;没有文档 网格的源文件不会被文档生成器补入默认网格。

对于 Word 自动行距,浏览器会把原始段落倍数与解析后字体的实测 传统 Office 行进高度组合使用。 这些渲染指标属于内部兼容数据;导出仍使用原始 OOXML 段落倍数,因此浏览器校准不会改写 文档的行距语义。

原生可更新目录

Writer 把目录保存为可选择、不可直接改写的类型化块,不会把生成结果压成普通正文。 “引用”选项卡中的“插入或自定义目录”复用现有大纲,可选择 1 到 9 级语义标题或原生大纲 级别段落,并保留超链接、页码显示、页码右对齐,以及点线、短横线、下划线或无前导符。 每次插入或修改选项只提交一个 TipTap 事务和一条撤销记录。传统 Writer 没有为该命令定义 独立直接快捷键,因此命令目录不会虚构一个。

每个目录项保存有界标题、级别、页码和稳定目标。入选项缺少原生段落身份时,会在插入或 修改目录的同一事务中获得身份,因此插入目录不会让自身链接失效,一次撤销也会同时恢复 两项变化。页码来自 PAGE 域使用的同一套实时 Worker/WASM 分页解析器。“更新目录”会在一个 事务内从这两个来源重新生成全部目录块,因此修改标题或分页不会产生第二套标题或页码状态。 每个目录块最多缓存 512 项,超出部分会明确标记为截断,不会写入无界节点属性。

DOCX 导出会写入原生 w:sdt 目录内容控件、可更新 TOC 域、缓存目录项、内部标题书签和 所选前导符。导入与重开支持常见的 TOC \\o "1-3" \\h \\z \\u 子集、完整级别范围的 页码隐藏,以及页码不右对齐时的空格分隔。无法无损表示的自定义 \\t 样式映射、部分 页码范围、错误级别范围和其他分隔符不会被静默近似,而会进入兼容性诊断。每个导入目录 独立匹配缓存项,因此多个目录可以重复指向同一个标题。Playground 的 “可更新目录”模板可以直接验证编辑、导航、更新、导出和重开全流程。

原生文档索引

Writer 把每个已标记索引项保存为可选择的行内原子节点,并把生成结果保存为独立、可选择且 不可直接改写的类型化块。“引用”选项卡中的“标记索引项”会读取当前选中文字,并可设置主 索引项、次索引项、交叉引用,以及当前页码的粗体或斜体意图。“插入或自定义索引”支持一到 四栏、缩进式或连续式布局、页码对齐,以及点线、短横线、下划线或无前导符。传统 Writer 没有为这些命令定义独立直接快捷键,因此命令目录不会虚构快捷键。

生成块会排序规范化后的索引项,合并同一页上的重复项,同时在合并后的页码链接中保留全部 稳定标记目标。点击页码会选中对应正文标记。页码只读取 PAGE 域使用的同一套实时 Worker/WASM 解析器,因此分页或重排不会产生第二套页码模型。标记、编辑、插入、自定义和 显式更新全部索引分别只提交一个 TipTap 事务和一条撤销记录。文档最多读取 2,048 个标记并 缓存 512 个生成行;超过任一边界时会明确显示截断,不会写入无界节点属性。

DOCX 导出会写入原生 w:fldSimple XE 项,以及包含实时 INDEX 域与 Index1/Index2 缓存行的真实 w:sdt 内容控件。主次索引项、交叉引用、页码粗体/斜体、栏数、连续式布局、 对齐和前导符可经过导出、导入、重开和第二次导出保留。导入接受可无损表示的常见 XE \\b\\i\\tINDEX \\c\\e\\r 子集。索引范围、自定义索引类型、 区域设置开关、损坏字段和其他不支持的开关会明确进入兼容性诊断,不会被静默近似。 Playground 的“原生索引”模板可以直接验证标记、导航、更新、导出和重开全流程。

内置导航

“视图”选项卡会在宽屏打开固定的标题导航,在窄屏打开可管理焦点的抽屉。 导航搜索同时覆盖标题与正文,按当前章节组织结果,高亮所有命中项,并把编辑器选区 移动到目标位置,但不会增加撤销记录。窄屏选择结果后,抽屉先关闭,再把焦点和精确 文本范围还给正文。

“页面”视图显示实时物理页面缩略图。超过 48 页时只挂载最多 24 个连续页面按钮,并在 需要时额外保留当前页和键盘游标页。物理滚动占位保持完整文档距离,Home 和 End 可以 直接到达首尾页,无需同时挂载全部页面。

标题和全文搜索集合超过 48 条后也使用同一窗口机制:最多挂载 32 个连续条目,并在窗口 外稀疏保留当前项、选中项和键盘游标项。原生滚动距离、全局列表序号、方向键遍历、 Home/End 和精确搜索选区都不会丢失。长距离搜索跳转会在选区生效的一帧内使用即时滚动, 随后恢复编辑器原有滚动样式。

引用与题注

“引用”选项卡可以插入和更新类型化目录与原生索引,并可插入题注、交叉引用、脚注、尾注、 页码字段、日期与文献引用。 删除或移动题注会在同一事务中更新相关交叉引用:有效目标会重新编号,目标缺失时显示 Missing reference,而不是继续显示过期编号。一次撤销会同时恢复题注与引用字段。

常用实时字段

“插入”功能区还提供有界的 Word 常用字段:PAGENUMPAGESSECTIONSECTIONPAGESDATETIMENUMWORDSNUMCHARS。页码与节号字段读取包含该原子的实测物理页;字数 字段只统计可见正文并排除生成的字段结果,字符数包含空格但不把换行分隔符算入字符。更新 按钮和 F9 会在同一条受控事务中刷新所有可更新字段,重排后不会留下部分过期的结果。

页码、节号和书签目标页码字段还接受 WPS 发出的确定性数字开关:Arabic、大写/小写 Roman、 大写/小写 alphabetic 以及 Ordinal。WPS 复杂字段通常会追加 \\* MERGEFORMAT;该尾部会 保留在原生指令中,不改变实时结果。Commander 的 wps-fields-probe 可以捕获本机 WPS 字段指令,便于本地兼容性复核。另可使用 wps-ui-probe --profile shell|fields|all 捕获 Writer 外壳和字段原生命令 ID 的 UI/UX 参考 JSON;它是隔离证据,不是产品运行时依赖。

“插入”功能区的字段入口是命令菜单(Popover + menuitem),不是 OfficeSelect: 闭合标签保持「插入域」,选择字段类型后立即插入,不再依赖假选择状态。

“字段设置”按钮位于快速字段菜单旁,插入和编辑都使用同一个有界模型。页码和节号提供阿拉伯、 大写/小写 Roman、大写/小写 alphabetic 与 Ordinal;日期和时间提供中文、ISO、英文长日期、24 小时及 12 小时预设。编辑书签目标页码时会保持稳定目标身份,并可明确切换 WPS 超链接开关。 现有 MERGEFORMAT 尾部会保留;如果导入的时间格式不在预设中,会显示为保留源格式的选项, 直到用户主动选择新格式。确定只产生一次受控文档更新并把焦点还给正文;窄屏“插入”功能区滚动后 也能打开同一弹窗。

在“交叉引用”弹窗中选中书签后,可以插入实时 PAGEREF 字段,而不是静态引用。字段同时保存 书签稳定身份和当前名称,书签在保持身份的规范化过程中重命名时会跟随更新;目标被删除后会 显示 Missing reference。原生 DOCX 边界只接受确定性的行内子集(适用时允许 \\h、数字开关与 \\* MERGEFORMAT);嵌套、损坏、不支持的开关或缺失目标会保留缓存文字,并进入兼容性诊断, 不会伪装成可编辑语义。

图片属性

选中正文图片后会打开“图片”功能区。常用环绕、对齐、90° 旋转和水平/垂直翻转命令可以 直接使用,“图片属性”弹窗则统一编辑厘米宽高、每张图片独立的纵横比锁定、环绕方式、位置、 文字距离、旋转、翻转和替代文字,并适配手机视口。

一次确定只产生一条撤销记录,并且只改动用户实际编辑过的字段。导入图片的像素尺寸如果 只是以两位小数厘米显示,会原样保留。取消或 Escape 不修改文档,图片仍保持选中,键盘 焦点会回到“图片属性”按钮。旋转有意限制为 90° 的整数倍,让编辑器、预览、PDF 捕获和 原生 DOCX a:xfrm 投影共享同一个可预测模型。任意角度或格式错误的 DrawingML 变换会由 兼容性诊断明确报告并归一化,不会伪装成精确可编辑值。

可编辑文本框

“插入”功能区新增有界的“文本框”块。选中文本框后会打开上下文“文本框”功能区,桌面和 紧凑 Web 使用同一套可预测控制:嵌入文字或浮于文字上方、毫米宽高、相对于页面/栏/页边距 或段落的位置与偏移、填充与轮廓、内边距、顶端/居中/底端垂直对齐,以及五种明确形状:矩形、 圆角矩形、椭圆、菱形和三角形。每次确定都只产生一条类型化文档更新和一步撤销。选中的形状会 同步显示在控件标签和页面上;窄屏功能区滚动后仍可发现,撤销/重做也会保留。文本框保留富文本 行内内容和换行,可作为隔离块选中;分页解析器会保持整个文本框在同一页,避免把它拆到两张物理页上。

原生文件边界保持小而明确。支持的 DOCX WordprocessingML 文本框使用带 txBox="1" 或文本主体的 wps:wsp;WPS 通常还会用 mc:AlternateContent 包裹它们。独立绘图且使用五种支持形状之一时, 几何尺寸、嵌入/浮动布局、偏移、填充、轮廓、内边距、垂直锚点、文字和稳定绘图属性 ID 都会通过 同一个可编辑模型往返。实时页面、只读预览和 PDF 捕获也使用同一形状投影。段落中独立的文本框 绘图会转换为可编辑内容;如果段落同时包含其他文字、只有 VML 的连接符、任意或不支持的形状、 形状内容损坏,或出现其他不支持的 DrawingML 分支,则保留普通兼容路径,并由 docx.text-boxes 诊断明确报告,不会静默宣称无损编辑。

导入到编辑器的边界也有独立回归保护:data-text-box-* 属性会先进入 TipTap 结构化模型再挂载 实时页面,因此有效的 WPS 形状不会悄悄退回默认矩形尺寸。发布夹具和浏览器测试覆盖五种形状、 桌面与紧凑视口中的发现性、可访问性、视口容纳以及干净的控制台/页面错误证据。

当前有界连接符切片已经把独立直线、肘形和曲线连接符纳入可编辑内容。上下文“连接符”功能区提供一个 类型化连接符类型控件,以及实线、虚线、点线和点划线、类型化的无箭头、三角、隐形、菱形、圆形和开放 端点箭头,并与线条颜色、粗细、布局、偏移和端点百分比一起工作。类型值分别驱动实时 SVG 的 line、 路由 polyline 或二次曲线 path,并同时驱动撤销/重做、紧凑控件、WPS VML 导入和原生 DrawingML 导出/重新打开。

WPS 边界仍然明确。本机 WPS 12.0 COM 探针显示,Shapes.AddConnector 会写成带 o:spt="32"3337(分别对应 #_x0000_t323337)的传统 VML v:shape,并在虚线连接符上报告原生 DashStyle=4,以及有界的 COM 3/4 箭头参考,而不是带文字主体的 wps:wsp。VML dashstylestartarrow/endarrow 与 DrawingML a:prstDasha:headEnda:tailEnd 会映射到同一个有界模型(classic 映射为隐形箭头,未知值归一化为 无箭头)。任意路由点编辑、长尾线型或箭头样式、混合段落、任意或格式损坏的绘图,以及超出三种类型模型的端点/路由语义仍保持失败即诊断的兼容边界, 不会伪装成精确编辑。确定性夹具、word-connector-editor.aclword-wps-connector-boundary.aclword-wps-connector-kinds.acl 覆盖创建和导入路径,并保留截图、可访问性、控制台和页面错误证据。docx.connectors 诊断会把 不支持的源分支继续暴露给宿主。

原生内容控件

“插入”功能区新增有界的行内“内容控件”流程,用于文档模板和审阅表单。响应式弹窗把一次 编辑意图集中在一起:选择纯文本或富文本,填写显示名称和程序标签,按需允许多行文字,选择 边框、标签或隐藏边框外观,并可设置不依赖主题的颜色。选中已有控件后会打开同一个弹窗编辑 元数据;控件的可访问文本框名称会跟随显示名称或程序标签。

内容锁和控件锁由编辑器事务边界强制执行,而不是只靠 CSS。内容锁会拒绝输入、粘贴和普通 元数据写入;控件锁会阻止替换或删除,但仍允许声明的内容编辑路径。需要解锁的删除或属性修改 必须通过显式类型化命令请求。插入、修改属性和删除各自产生一条文档事务和一步撤销。

原生 DOCX 合同保持小而明确。过渡或严格 WordprocessingML 中直接位于段落的 w:sdt,可以 往返纯文本或富文本行内运行、别名、标签、原生锁值、多行文字、无冲突身份以及 Word 2012 外观和颜色。空控件会保留为空的可编辑范围。数据绑定、占位符、重复区域、日期/下拉/图片/表单 控件、块级或嵌套控件以及关系绑定语义不在此模型中;它们会保留为安全的可编辑文字(或在导入时 安全失败),并产生 docx.content-controls.unsupported 诊断,不会伪装成精确可编辑能力。

自定义选区菜单

菜单工厂会收到不可变的选区快照,其中包含精确文本、结构化片段、前后文、全文纯文本、 同步 HTML 与当前受控内容,同时提供能检测冲突的编辑命令。

import type {
  DocumentContent,
  GetDocumentSelectionMenuItems,
} from '@a3s-lab/office/core';
import { DocumentEditor } from '@a3s-lab/office/react';

const getSelectionMenuItems: GetDocumentSelectionMenuItems = (snapshot) => [
  {
    id: 'rewrite',
    label: '润色',
    onSelect: async (context) => {
      const replacement = await rewriteWithModel({
        selection: snapshot.selection.text,
        before: snapshot.selection.beforeText,
        after: snapshot.selection.afterText,
        document: snapshot.document.text,
      });
      context.commands.replaceText(replacement);
    },
  },
];

export function Editor(props: {
  content: DocumentContent;
  onChange: (content: DocumentContent) => void;
}) {
  return (
    <DocumentEditor
      {...props}
      getSelectionMenuItems={getSelectionMenuItems}
    />
  );
}

异步操作需要返回 Promise。编辑器会在无关事务发生后重新映射原选区;如果选中的文本 本身已经变化,后续 replaceText 会返回 stale-selection,不会改错内容。

“询问 AI”这类开放操作,应先在宿主界面收集用户问题,再发出请求。Playground 的实现 会打开独立问题输入框;提交后仍可查看所附上下文,但不会用整篇上下文占满助手消息流。

Extension

extensions 接收 TipTap Extension。数组引用应保持稳定,每个 Extension 必须使用 唯一名称。如果自定义 Node 或 Mark 需要经过 DOCX 导入导出后仍然存在,还要提供相应 文件语义。详见扩展机制