跳到正文

阶段一百一十三:画布直接编辑与双模式 ​

实现范围 ​

设计器画布接入 React/TypeScript 与 ProseMirror,继续编辑同一份 XML 和资源包。默认“便捷编辑”呈现模板原文及变量标记,活动输入保留浏览器草稿,完成编辑后更新引擎分页;“精确排版”呈现绑定测试数据后的 Java 引擎结果,输入经防抖刷新。切换模式不替换活动编辑 DOM,也不改变源码、资源或撤销记录。

画布支持正文、富文本和行内单元格直接输入,单段页眉/页脚编辑,框选、多选、组移动、坐标及尺寸属性、缩放/旋转手柄和 PNG/JPEG 粘贴。自动占位/固定位置是组件属性;默认组件及新粘贴图片参与正文流,拖动显示插入线并排序,不隐式转换为固定框。动态表格、列表和循环/条件按整个语义模板排序,同级多选保持源码顺序。拖柄、上移/下移按钮和 Alt+方向键提供等价入口。

顶层段落、图片段落和表格可显式转换为固定框,保留有效段落样式;框支持固定、剩余空间填充和内容自动高度,以及文档物理页选择。只有固定组件显示“遮盖正文/上下避让”:前者保留正文原布局,后者在 Java 引擎中保留上方内容、排除相交的纵向区间,再从下方续排。固定恢复为自动占位时使用附近正文位置。ID 保持属性第一项,组件排版属性紧随其后。

同页相邻的普通段落和标题共用连续文字编辑区,支持跨段光标、选区和段落合并;变量、字段、链接和 XML 对象保留原结构。选区附近显示浮动格式工具条,折叠光标时隐藏;块旁提供前/后插入和组件菜单,插入段落后直接编辑新内容。连续输入和拆段使用稳定 ID,混合文字格式写成合法的单层 span。合并及动态表格单元格从 IR 几何映射回模板,绑定结果不覆盖模板表达式。

结构和几何修改先更新画布与源草稿,再异步校准 Java 版式;服务返回前仍可选择、编辑及撤销,旧响应不覆盖后续修改。拖动显示移动预览、占位框或固定对齐吸附线;文字提交、组件插入、排序和几何修改进入工作台操作历史。复制和删除遵循组件外框,单元格编辑完成后操作整表;循环副本保留绑定并重映射其内部引用。设计和边界见 ADR-0107及操作指南。

构建与回归 ​

powershell
.\gradlew.bat build sbom publishLocalBundle apiCheck :examples:pageOverlays
.\scripts\verify_local_consumer.ps1
.\gradlew.bat :export4j-designer:test :export4j-designer:installDist :export4j-designer:distZip
npm --prefix export4j-designer/frontend test
python scripts/verify_designer_studio.py
python scripts/verify_page_overlays.py

使用 JDK 21、Gradle Wrapper 9.4.1、Node.js 24 和锁文件固定的前端依赖。浏览器检查使用 Playwright 1.64.1 与 Chrome;独立文件检查使用固定验证 requirements 及 Poppler。基础能力的完整工程验证中,构建、SBOM、本地 Maven 发布、隔离调用方和 API 检查通过;全仓 1,848 项 Java 测试无失败、错误或跳过,其中设计器 38 项。API 比较为零不兼容声明、零第三方类型泄漏,新增声明 49 项。本轮交互回归与该次完整工程验证分别记录。

浏览器包携带完整第三方 MIT 许可;运行依赖与原始许可独立登记,不进入 Java 库 POM/BOM。使用官方 npm 公告接口检查运行依赖,结果为零已知公告;该结果不代表不存在未知漏洞。

基础浏览器与输出验收 ​

场景结果
原位输入单击只选择,双击或 F2 编辑;中文输入、混合颜色、加粗和变量保留;引擎预览更新后活动编辑 DOM 相同
模式切换便捷模式活动输入期间没有预览请求;编辑中来回切换保留草稿、编辑 DOM 和内容,完成后校验布局
拆段和历史Enter 后继续输入不重复插入段落;撤销/重做恢复整个修改
表格和页区单元格只修改其模板,不误选空 ID 节点;单段页眉/页脚可直接编辑;Java 回归覆盖合并格和动态行定位
固定框自动高度、剩余宽度和物理页 2 写入模板,补足第二页;移动后保留原有 12 pt 正文字号
对象操作长按约 350 ms 或直接拖柄;自动占位排序、固定位置自由移动,操作保留组件属性;快速划动不改变位置,Esc 放弃拖动;固定缩放可命中整条边缘,顶部扩展保留底边
正文避让切换固定组件 OVERLAP/AVOID 改变真实正文布局,固定坐标不变;PDF 独立坐标检查确认表格移至对象下方,内容没有重复或丢失
动态与多选排序从动态表格单元格及拖柄排序,保留 items/as 和模板变量;同级多选整体移动,普通方向键不转换排版方式;Alt+方向键及上下移动按钮排序
列表选择单击保留整个列表的单一外框;双击仍可编辑单项模板,拖动后的下一次单击正常生效
剪贴板和保存图片资源实际嵌入 ZIP;缩放改变显示尺寸,原始像素字节保留;模板变量继续存在
响应布局980 px 宽工作台没有横向溢出;浏览器无脚本错误

17 个浏览器场景通过,共 18 个测试节点(含父场景),无失败或跳过。浏览器真实下载两页 PDF、两页 SVG ZIP 和两页 PNG ZIP。pypdf 独立确认正文、表格、重复页眉/页脚、目标页唯一性、实际绘制字号及坐标;Poppler/PDFium 渲染全部两页,resvg 独立渲染两页 SVG,并与 PNG 对照。以 PDFium 为参考,经 1 px 模糊后的最大平均通道误差为 0.198,变化像素占比小于 0.32%;全部页面经过视觉复查。另下载一页正文避让 PDF,独立检查固定组件坐标、表格文本位于组件下方及来源唯一性;双渲染平均通道误差小于 0.207,变化像素占比小于 0.32%。模板 ZIP 独立解包确认变量表达式、图片资源、80×40 原始像素与缩放后显示尺寸。

密集动态表格另使用三页样例检查,从中间单元格长按拖至前一正文组件;插入线可见,拖后完整表格子树、绑定路径和迭代变量不变,没有新增固定框,组件排版属性紧随 ID 显示。Java 回归另覆盖重复避让区前后续排、自动高度、跨页目标、表格行、脚注、原生文本/列/语义表格区域流,以及相同图层跨节复用时的目标校验。

既有页面图层验证继续通过,包括图层遮挡顺序、主题、页码字段、继承、明确损失策略、PNG 与五页 PDF 双渲染。工作区保存/重开检查 XML、测试数据及资源条目逐项相同,组件恢复为正文流另检查撤销/重做与资源不变。截图、下载、备份及原始日志保留在忽略的 build/verification/designer-studio/。

连续编辑与即时交互回归 ​

浏览器套件扩展为 29 个场景,继续使用真实 Java 服务、Chrome 输入和实际下载。默认测试自行启动 --port=0 的隔离进程;也可用 EXPORT4J_STUDIO_URL 指定测试专用实例,用 EXPORT4J_STUDIO_OUTPUT 指定本轮产物目录。设置 EXPORT4J_STUDIO_SCENARIOS 可按场景名正则执行定向回归,无匹配时失败。这些参数用于隔离验收,不复用正在编辑的工作区。

本轮 Java 模块回归为组件 380 项、设计器 38 项,均通过;完整工程验证的范围和数字沿用上节既有记录。

场景核对内容
连续编辑同页跨段选区加下划线,连续按 Ctrl+End、Home、Backspace 从第二段段首合并;撤销/重做保留变量、页码字段、原有粗体和段落属性,完成编辑保留操作的组件
文字与属性活动文字输入后调整侧栏对齐/字号,再继续输入;文字和属性均保留,后续文字会话可独立撤销
浮动及块旁工具折叠光标不显示格式浮条;选择文字后显示;前/后插入进入新段落,替换默认文案且不修改邻段;菜单可创建副本并用 Esc 关闭
即时让位便捷编辑新增三行并设置 24 pt,后续表格命中区域即时下移;引擎页数、已保存源码及版本不变,期间没有预览请求,完成后重新校准
拖动反馈松开前显示正文流占位框与移动预览,或固定对象对齐线;源码在释放后改变,拖动不切换组件排版属性,多选应用相同吸附增量
异步操作历史暂停一次真实 apply 请求,继续文字提交、固定属性、两次撤销及重做;页面不锁定,放行后实际服务源码等于最终本地状态
资源写入上传真实 PNG 并暂缓实际响应;活动草稿先提交,写入期间正文只读,新增按键不改变草稿,放行后可继续输入,资源及前后文字一起保存
表格与绑定多段富文本粘贴折为格内换行,不增加单元格或列;编辑格后复制/删除作用于整表;循环副本保留 items/as、原文变量及内部目标关系
跨页及恢复跨页文字明确编辑完整原文;多页缩为单页后仍可编辑;非法 XML 保留有效画布和草稿,修正后重新预览并提交
分节插入在第二页取消选择后从空白入口插入,新段属于该页分节,根节点不混入正文;按钮位于可点击的留白

29 个浏览器场景全部通过,共 30 个测试节点(含父场景),无失败或跳过,浏览器无脚本错误。快速段首合并序列另独立执行三次,均保留合并、撤销/重做和内嵌对象;测试不插入固定等待或手工修改编辑器选区。

独立检查使用本轮浏览器下载目录:

powershell
python scripts/verify_designer_studio.py `
  --source-directory build/verification/designer-studio/interaction-final/browser `
  --output-directory build/verification/designer-studio/interaction-final/independent

独立解析、渲染及视觉复查通过:两页固定目标 PDF/SVG/PNG、一页正文避让 PDF 和一页循环副本 PDF,全部 PDF 页使用 Poppler/PDFium 对照。循环副本中的两条记录分别出现两次,四个引用指向不同的内部目标;双渲染最大平均通道误差为 0.268,变化像素占比小于 0.413%。连续编辑 ZIP 独立解包后保留合并段落、变量、页码字段和混合格式;图片 ZIP 保留 80×40 原始像素及改变后的显示尺寸;资源写入 ZIP 保留上传前草稿、恢复后的输入和 8×6 原始 PNG 像素,未写入只读期间的按键。本轮未自动刷新视觉基线。

边界 ​

便捷模式是近似文字显示,精确分页及导出以 Java 引擎为准;直接输入时的活动文字编辑层仍由浏览器排版。此次中文输入检查使用浏览器 insertText 和编辑 DOM 保持断言,未验证每种操作系统输入法。同页相邻普通段落和标题可连续编辑;跨页段落明确提示“跨页段落 · 编辑完整原文”,不把单页片段的点击位置当成完整原文的精确光标位置。复杂页区、嵌套模板及未提供直接命中的结构继续通过属性/XML 编辑。

便捷编辑的临时让位只作用于同页后续正文,页脚保持固定。新增行造成的真实分页在完成编辑或精确预览时由 Java 重新计算,浏览器临时位置不作为导出几何。

固定对象的上下避让覆盖正文全宽,不提供对象左右环绕;组缩放对各对象应用相同尺寸增量,不承诺完整成组变换。生成目录与指定物理页或上下避让组合明确拒绝。DOCX/HTML/Markdown 的几何映射继续执行各格式既有损失策略。此次没有实际运行远端 CI、跨平台浏览器或正式发布,也不据此扩大平台兼容矩阵。