@web-ppt/editor 0.5.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/CHANGELOG.md +274 -0
  2. package/LICENSE +21 -0
  3. package/README.md +473 -0
  4. package/dist/adapter-format-painter.d.ts +15 -0
  5. package/dist/adapter-link.d.ts +3 -0
  6. package/dist/adapter-options.d.ts +6 -0
  7. package/dist/adapter-recovery.d.ts +14 -0
  8. package/dist/adapter-selection-pane.d.ts +22 -0
  9. package/dist/adapter-text-search.d.ts +28 -0
  10. package/dist/animation-preview.d.ts +26 -0
  11. package/dist/dom-identity.d.ts +17 -0
  12. package/dist/dom-patch.d.ts +9 -0
  13. package/dist/editor-keyboard.d.ts +13 -0
  14. package/dist/editor.js +6332 -0
  15. package/dist/element-clipboard.d.ts +23 -0
  16. package/dist/format-painter-types.d.ts +32 -0
  17. package/dist/format-painter-view.d.ts +17 -0
  18. package/dist/format-painter.d.ts +21 -0
  19. package/dist/framework-adapter-binding.d.ts +4 -0
  20. package/dist/framework-adapter-state.d.ts +9 -0
  21. package/dist/framework-adapter-types.d.ts +114 -0
  22. package/dist/framework-adapter.d.ts +2 -0
  23. package/dist/image-crop-gesture.d.ts +40 -0
  24. package/dist/image-insertion.d.ts +46 -0
  25. package/dist/index.d.ts +28 -0
  26. package/dist/indexeddb-recovery-store.d.ts +30 -0
  27. package/dist/keyboard-context.d.ts +8 -0
  28. package/dist/keyboard-delete.d.ts +7 -0
  29. package/dist/keyboard-history.d.ts +7 -0
  30. package/dist/keyboard-layer.d.ts +7 -0
  31. package/dist/keyboard-nudge.d.ts +10 -0
  32. package/dist/keyboard-owner.d.ts +5 -0
  33. package/dist/marquee-gesture.d.ts +31 -0
  34. package/dist/move-gesture.d.ts +34 -0
  35. package/dist/placeholder-overlay.d.ts +3 -0
  36. package/dist/pointer-gesture.d.ts +37 -0
  37. package/dist/recovery-session.d.ts +24 -0
  38. package/dist/recovery-store.d.ts +64 -0
  39. package/dist/resize-geometry.d.ts +19 -0
  40. package/dist/resize-gesture.d.ts +30 -0
  41. package/dist/rotation-geometry.d.ts +9 -0
  42. package/dist/rotation-gesture.d.ts +33 -0
  43. package/dist/selection-body-properties.d.ts +3 -0
  44. package/dist/selection-combine.d.ts +10 -0
  45. package/dist/selection-handles.d.ts +3 -0
  46. package/dist/selection-hit.d.ts +8 -0
  47. package/dist/selection-overlay.d.ts +13 -0
  48. package/dist/selection-pane-types.d.ts +18 -0
  49. package/dist/selection-pane.d.ts +3 -0
  50. package/dist/session-state.d.ts +20 -0
  51. package/dist/session.d.ts +24 -0
  52. package/dist/slide-dom-renderer.d.ts +22 -0
  53. package/dist/slide-dom-update.d.ts +13 -0
  54. package/dist/slide-editor-commands.d.ts +76 -0
  55. package/dist/slide-editor-dom.d.ts +2 -0
  56. package/dist/slide-editor-events.d.ts +20 -0
  57. package/dist/slide-editor-keyboard-events.d.ts +39 -0
  58. package/dist/slide-editor-types.d.ts +90 -0
  59. package/dist/slide-editor.d.ts +3 -0
  60. package/dist/slide-link-controller.d.ts +26 -0
  61. package/dist/slide-pointer-controller.d.ts +43 -0
  62. package/dist/snap-guides.d.ts +3 -0
  63. package/dist/snap.d.ts +60 -0
  64. package/dist/source-fingerprint.d.ts +9 -0
  65. package/dist/table-insertion.d.ts +7 -0
  66. package/dist/text-autofit.d.ts +18 -0
  67. package/dist/text-clipboard-controller.d.ts +32 -0
  68. package/dist/text-clipboard.d.ts +7 -0
  69. package/dist/text-dom.d.ts +30 -0
  70. package/dist/text-editor-context.d.ts +13 -0
  71. package/dist/text-editor-target.d.ts +10 -0
  72. package/dist/text-editor-types.d.ts +30 -0
  73. package/dist/text-editor-view.d.ts +4 -0
  74. package/dist/text-editor.d.ts +51 -0
  75. package/dist/text-input-plan.d.ts +20 -0
  76. package/dist/text-search-highlight.d.ts +18 -0
  77. package/dist/text-search-index.d.ts +11 -0
  78. package/dist/text-search-types.d.ts +41 -0
  79. package/dist/text-search-view.d.ts +33 -0
  80. package/dist/text-search.d.ts +46 -0
  81. package/dist/transform-frame.d.ts +14 -0
  82. package/dist/transition-preview.d.ts +24 -0
  83. package/package.json +54 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,274 @@
1
+ # 更新日志
2
+
3
+ 本文件记录对使用者可见的变化。版本号遵循 [语义化版本](https://semver.org/lang/zh-CN/)。
4
+
5
+ ## 未发布
6
+
7
+ ## 0.5.0-beta.1 - 2026-08-27
8
+
9
+ ### 新增
10
+
11
+ - `@web-ppt/edit-core`、`@web-ppt/editor` 与框架适配层新增元素动画编辑闭环:稳定
12
+ `SlideId` / `ElementId` 时间线支持来源恢复、显式清空、撤销恢复、删除/复制页联动,以及
13
+ view/edit 共用的无副作用即时预览。首个安全目录覆盖入场/退场的 appear、fade、fly、wipe、zoom、
14
+ dissolve,强调 spin/grow 和 2–256 顶点运动路径;复杂 MCE、build、扩展或条件时间树会标记
15
+ `sourceReadonly`,只有调用方明确整条替换才写回;公开 `MAX_ANIMATION_STEPS=128`,保证允许写入的
16
+ 最重时间线仍能在有界解析预算内完整回读。
17
+ - 元素动画保存按 OOXML 官方 preset/filter 重建规范 `p:tnLst`,保留 timing 根属性、`bldLst`、
18
+ `extLst` 与无关 MCE,并精确回读 trigger、delay、duration、方向和路径。真实 Chrome 实测 60 元素
19
+ 启动、200 页批量提交、单页反馈 p95 为 0.8/3.5/0.4ms;确定性 5 页固件及 LibreOffice 打开验证通过。
20
+
21
+ - `@web-ppt/editor` 新增显式启用的纯浏览器自动保存:完整源字节 SHA-256 把同内容输入绑定到同一日志,
22
+ IndexedDB 以串行批次原子追加恢复帧,并按分块数、总估算字节、记录数和保留期压缩清理。`openEditor`
23
+ 在解析和挂载前完成 restore/discard/cancel 决策,clean 尾帧不提示;adapter 与 React/Vue 共用
24
+ `recovering + onRecovery` seam;原子代际占位拒绝旧页面在 discard 后复活日志。真实 Chrome 中 50MB
25
+ 指纹为 42.2ms,1,000 帧写入/关闭重开恢复为 131.5/14.9ms,压缩后 10 个分块,同步提交增量 0.000ms。
26
+
27
+ - `@web-ppt/edit-core` 新增版本化 `RecoveryFrame`、`Editor.subscribeRecovery()` 与
28
+ `restoreRecoveryFrames()`:事务、撤销/重做、非历史写入、选区、保存点、图片资源和身份水位都能按
29
+ 严格序号写成纯 JSON。会话图片 URL 在 patch 中先变成保留 token,资源闭包缺失会原子拒绝;回放先在
30
+ 写时复制模型上完整验真,并拒绝身份水位倒退,坏尾帧不会污染目标;恢复保留选区与脏状态,
31
+ 但不伪造旧历史。未订阅时普通编辑零日志深拷贝。210 页 / 50MB 基准中,1,000 帧为 316.3KB,
32
+ JSON 往返 1.6ms、回放 269.9ms;`@web-ppt/editor.openEditor()` 可在挂载前透传同一日志。
33
+
34
+ - `renderSlideToSvg` 新增 `RenderOptions.idPrefix`。指定后,同一页与同一前缀会生成
35
+ 逐字节相同的 SVG,供编辑器增量更新和确定性比较使用;省略时仍维持全局唯一 id,
36
+ 主视图与缩略图同时挂载不会发生 defs 冲突。
37
+ - 新增 `renderElementToSvg(element, options) → { markup, defs }`。编辑器可用每元素唯一的
38
+ 稳定 `idPrefix` 只重渲脏元素,并在同一次 DOM 更新中替换它自己的节点与 defs;
39
+ 整页与元素入口复用同一分发和两条文本路径,不存在第二套近似渲染器。
40
+ - 新增无 DOM 的 `renderTextBodyToHtml(text, width, height, options)`。屏幕预览和后续
41
+ contenteditable 覆盖层共用同一份段落、run、CJK 标点、分栏与 autofit 排版;默认输出
42
+ 可反解的编辑标记,并隔离危险链接协议,原生 SVG 文本导出路径保持独立。
43
+ - 新增纯函数 `layoutText(text, width, height, options)`。它与原生 `<text>` 输出共用断行、
44
+ CJK 挤压、分栏、行距及 autofit,并公开段落/run 身份、UTF-16 字符区间与光标停靠点,
45
+ 供 Safari engine 模式命中选区;竖排返回仿射变换,公式保持原子,测量器可注入。
46
+ - `renderTextBodyToHtml` 新增 `{ layout: 'engine' }`:直接把 `layoutText()` 的视觉行与源 UTF-16
47
+ 半开区间序列化为绝对定位、禁止二次断行的可编辑 HTML。`@web-ppt/editor` 的 `textMode: 'svg'`
48
+ 以及 `auto` Safari 降级现在让静态 SVG 与 `contenteditable` 共用这组行盒;硬换行、空 run/段、
49
+ 项目符号、RTL、竖排、分栏、公式和裸 autofit 在进入、输入、提交与退出时保持同一布局。真实
50
+ Chrome 的 2,000 字符完整上屏多轮 p95 为 8.3–17.8ms、行盒最大偏差 0.009px;editor 入口为
51
+ 27.46KB gzip。
52
+ - `parse` 新增完全可选的 `edit` / `keepPackage`:前者保留页与元素的 OOXML 回写锚点、
53
+ 占位符身份,后者通过 `Presentation.package` 保留原始 ZIP 与解压 part。默认解析的
54
+ 对象形状和资源生命周期不变;`dispose()` 会同时释放保留的原包。
55
+ - `.pptx` 与 `.ppt` 的编辑解析会额外保留预设形状的 `preset + adj` 语义(OOXML 含
56
+ 版式/母版继承),并新增纯函数 `resolveGeomPath`;编辑投影改变宽高后可重新求值路径,
57
+ 不再复用解析期烘焙的几何。
58
+ - 新增无 DOM、无框架的 `@web-ppt/edit-core`:把解析结果转换为带稳定身份与分数 z 序的
59
+ 扁平 `EditDoc`,以 `src` / `ovr` 分离源值和用户改动,并通过 `toSlide` 投影回现有
60
+ 渲染 Schema。元素、组祖先和页面缓存按修改路径精确失效;图表、SmartArt、OLE、
61
+ 墨迹与媒体只开放框架级变换,内部派生节点不可误编辑。
62
+ - `@web-ppt/edit-core` 新增无 DOM 的 `Editor`、可 JSON 序列化的 `SetXfrm` 与双向 patch。
63
+ 事务失败整体回滚;撤销/重做恢复选区,同路径改动按 500ms 分组,远端 origin 不进入本地历史,
64
+ 默认保留 200 组 / 8MB。固定种子 200 条命令通过撤销、重做与 JSON 回放全等,500 条非法命令
65
+ 不污染文档;210 页实测 200 组撤销/重做含脏页重渲均约 0.5ms/次,历史约 64KB。
66
+ - 新增按需入口 `@web-ppt/edit-core/xml`:无 DOM 的保留型 XML 树支持 UTF-8 / UTF-16
67
+ 字节回环、限定名与 namespace URI 查询、属性最小改写和 OOXML sequence 有序插入;声明、
68
+ 注释、PI、前缀、属性顺序、自闭合形态及 `AlternateContent` 不被重建。默认编辑模型入口为
69
+ 8.28KB gzip,保存期 XML 入口独立为 7.14KB gzip。
70
+ - 新增按需入口 `@web-ppt/edit-core/opc`:无修改保存复用原始字节;脏 part 定点重压,净条目的
71
+ 本地头、extra field 与压缩流逐字直通。新增/删除 part、重复保存和确定性输出均有契约;zip64、
72
+ 数据描述符、存档注释、加密条目、未知压缩与多磁盘格式会给出原因并整包重压。入口为 4.27KB gzip,
73
+ 210 页 / 50.6MB 修改并序列化 3 页后的实测保存为 84.0ms;保存结果可随文档或独立释放。
74
+ - 新增 M0 自动门禁:29 份固件(含吸附、加密 OOXML、RC4 `.ppt` 与 hardcases)的只读链路和
75
+ 编辑投影分别在独立进程渲染,两条文本路径共 232 对原始 SVG 指纹必须完全一致;
76
+ 210 页基准同时强制检查默认路径零编辑状态、编辑常驻内存增量、文本行盒与提交重渲预算。
77
+ - `@web-ppt/editor` 在编辑模式直接消费浏览器 SVG 命中:组默认选外层,双击 / Escape
78
+ 逐层进退,Alt+点击按 `elementsFromPoint` z 序循环;选择只更新交互层,多视图各自拥有监听器。
79
+ - `@web-ppt/editor` 公开元素本地 / 幻灯片 / 屏幕坐标变换,并为普通、旋转翻转和嵌套组元素绘制
80
+ OBB、8 个缩放柄与旋转柄。手柄尺寸不随 zoom 变化;真实 Chrome 三档缩放的最大矩阵偏差为
81
+ 0.000px,9 个手柄的位置与尺寸最大偏差同为 0.000px,60 元素页完整选择框上屏 p95 为 0.100ms。
82
+ - `@web-ppt/editor` 支持主指针拖动单选与多选:3px 阈值后以 pointer capture 和 rAF 合并幽灵帧,
83
+ 松手只提交一个可撤销 `SetXfrm` 事务;嵌套旋转翻转组按各自父空间换算。取消、丢失捕获、切页、
84
+ view 模式和销毁均不写模型。真实 Chrome 嵌套幽灵偏差 0.000px,60 元素拖动帧 p95 0.100ms。
85
+ - `@web-ppt/editor` 绑定 8 个恒屏幕尺寸缩放柄,支持单选/多选、旋转翻转与嵌套组、Shift 等比、
86
+ Alt 中心缩放及过锚翻面;移动与缩放共用可回收的 pointer capture/rAF 状态机,松手一次提交并可
87
+ 精确保存。真实 Chrome 三档 zoom 的手柄/锚点最大偏差 0.009px,缩放帧 p95 0.100ms;60 个
88
+ 45° 元素的近奇异多选缩放 p95 0.600ms。
89
+ - `@web-ppt/editor` 绑定旋转柄:单选按元素父空间处理自身翻转与多层旋转/翻转组,多选围绕共同 AABB
90
+ 中心同步旋转;角度跨 ±180° 连续累计,Shift 可动态吸附 15°,松手以一个事务精确保存。真实 Chrome
91
+ 三档 zoom 的嵌套/多选幽灵最大偏差为 0.000/0.009px,60 元素旋转帧 p95 0.300ms,可信 pointer
92
+ capture 与撤销门禁通过。
93
+ - `@web-ppt/editor` 的移动手势新增屏幕 6px 吸附:画布中线/边缘、显式页边距、同组兄弟边缘/中线与
94
+ 横纵等距按稳定优先级逐轴裁决;`Ctrl` 可动态关闭,视图也可用 `snapping` / `setSnapping()` 全局切换。
95
+ 对齐线和双向等距箭头只进入 interaction SVG,取消零提交。真实 Chrome 三档 zoom、缩放组和等距线
96
+ 最大偏差均为 0.000px,60 元素吸附帧 p95 0.200ms,可信 pointer capture 与撤销门禁通过;editor
97
+ 发布入口实测为 15.87KB gzip。
98
+
99
+ ## 0.4.5
100
+
101
+ ### 修复
102
+
103
+ - **`@web-ppt/viewer-core` 与 `@web-ppt/fonts` 的 npm 页面在 0.4.4 里仍是中文**。
104
+ 包内容是对的(tarball 里躺着英文版),错的是 npm 用来渲染页面的那份元数据。
105
+
106
+ 原因是 npm 认哪个文件当 README 并不看「是不是叫 README.md」:
107
+ `@npmcli/package-json` 用 `{README,README.*}` 去 glob 再取第一个像 markdown
108
+ 的命中,而 0.4.4 引入的 `README.zh-CN.md` 同样匹配 `README.*`,实测还排在
109
+ `README.md` 前面。`files` 只挡住了 tarball,挡不住元数据。
110
+
111
+ 本地化 README 改用连字符(`README-zh-CN.md`),并在 `sync-package-docs.mjs`
112
+ 里加了守卫:包目录里出现 `README.*` 旁支就直接让发布失败。
113
+
114
+ ## 0.4.4
115
+
116
+ 本版没有代码改动,只动文档——但 npm 上看到的东西全变了,所以值得单独发一版。
117
+
118
+ ### 变更
119
+
120
+ - **npm 页面改英文**。三个包的 README 与 `description` 之前全是中文,
121
+ 而 npm 的读者以国际开发者为主,等于最有说服力的能力矩阵对他们不存在。
122
+ 现在 `@web-ppt/core` 的 npm 页取仓库的 `README.en.md`,另两个包各自
123
+ 维护英文版,中文移到同目录的 `README.zh-CN.md`,两边顶部互链。
124
+
125
+ GitHub 首页仍是中文,两个入口各自面向自己的人群。
126
+
127
+ - **README 首屏补了演示 GIF 与定位段**。GIF 由 `npm run demo-gif` 录制,
128
+ 录的是仓库自己生成的 `fixtures/showcase.pptx`,引擎改了重跑即可,
129
+ 不是一次性的手工录屏。
130
+
131
+ ## 0.4.3
132
+
133
+ ### 变更
134
+
135
+ - **静态画面改回动画终态**,撤销 0.4.1 里改成初始态的那次调整。
136
+
137
+ 对齐 PowerPoint 的模型:普通视图与缩略图看到的是「这一页演完的样子」,
138
+ 按 F5 进入演示才从第一步开始建。所以**进全屏时画面跳一次是预期行为**,
139
+ 不是 bug —— 0.4.1 当时是把这个跳变当成缺陷去消除的,方向错了。
140
+
141
+ 「不能简单摊开全画」这条不变:一页里入场与退场的元素属于不同时刻,
142
+ 全画出来等于把几帧叠在一起。全员退场的收尾页终态是空白,那种情况仍然
143
+ 退回全部可见。
144
+
145
+ ## 0.4.2
146
+
147
+ ### 修复
148
+
149
+ - **动画目标是「组」时,整组藏不住**。`visibility` 和 `display:none` 不一样:
150
+ 它虽然继承,但后代显式写 `visible` 会把祖先的 `hidden` 顶掉。查看器原本给
151
+ 隐藏集之外的每个元素都写死 `visible`,于是组藏了、组里每个形状却各自写着
152
+ `visible`,整组照常显示——看着就像「预览显示的还是动画终态」。
153
+
154
+ 现在不在隐藏集里就清空这条声明,让继承自然生效。之前只在动画目标为叶子形状
155
+ 的样本上验过,那种结构没有子元素,所以一直没暴露。
156
+
157
+ ## 0.4.1
158
+
159
+ 全是中文排版的修正。四处都由同一份小学课件暴露出来,每一处都拿 PowerPoint
160
+ 自己写进文件的 `spAutoFit` 框高做的判据 —— 那个高度是它按实际行数算完存下来的,
161
+ 等于文件自己作证该排几行。
162
+
163
+ ### 修复
164
+
165
+ - **CJK 标点挤压**。汉字和全角标点都占一整格,但标点的墨迹只占半格
166
+ (`,` `。` 的墨在左半格,`(` `《` 在右半格)。一行放不下时 PowerPoint 会把
167
+ 这些空半格挤掉,我们没做,于是多断出一行。规则取「放不下才挤」:放得下时
168
+ 保持全角。两条渲染路径算同一笔账——原生 `<text>` 用逐字符 `dx`,
169
+ HTML 用负边距,都与字体无关,不依赖字体是否提供 `halt` 半角替换字形。
170
+
171
+ 顺带一句:这类问题**换字体救不了**。所有中文字体的方格一样大,黑体、
172
+ PingFang、思源黑体量出来完全相同
173
+ - **量不到字时的中文估宽**。回退估算原本把每个字符都当 0.55em,中文因此窄掉
174
+ 将近一半。Node / jsdom 里恒走这条路,于是**自动缩放对中文一直缩不够**——
175
+ autofit 固件实测旧值排出来 204px、框只有 140px,仍然溢出;按全角整格算
176
+ 之后是 146px
177
+ - **百分比行距的基准**。`lnSpc/spcPct` 是「单倍行距」的百分比,而单倍行距是
178
+ **字体的行高**(≈1.2em),不是字号。把 150% 直接当 CSS `line-height:1.5` 用,
179
+ 每行矮两成。中文文档里 1.5 倍行距是标配,影响面不小;行距偏紧还会连累
180
+ 自动缩放与居中 / 底对齐文本的位置
181
+ - **静态画面改取动画初始态**(原本取终态)。缩略图、主视图、进演示模式后的
182
+ 第一帧现在是同一个画面,不再「先把这页演完、再从头演一遍」。
183
+ 「不能全部画出来」的理由不变:一页里入场与退场的元素属于不同时刻,摊开画
184
+ 等于把几帧叠在一起。例外从「全员退场的收尾页」换成「整页都带入场动画的
185
+ 封面页」——那种情况初始态一片空白,退回全部可见
186
+
187
+ ### 其它
188
+
189
+ - 测试:1848 → **1873 项断言**,快照 160 → 162 个。`sample-autofit.pptx` 补一页
190
+ 把百分比行距与绝对行距放在一起对照——之前 17 个固件里没有一个用过
191
+ `spcPct`,这条路径从没被走过
192
+ - `@web-ppt/viewer-core` 与 `@web-ppt/fonts` 本版无改动,跟随版本号对齐
193
+
194
+ ## 0.4.0
195
+
196
+ 本版围绕**字体**:嵌入字体此前从来没有真正生效过,替换字体则完全没有。
197
+ 顺带修掉一个让静态画面把动画的几帧叠在一起的问题。
198
+
199
+ ### 新增
200
+
201
+ - **嵌入字体真的能用了**。PowerPoint 的 `ppt/fonts/*.fntdata` 不是裸 TTF,是 EOT 容器,
202
+ 而且实测**全部**开着 MTX 压缩(POI 语料 6/6、ORCID 样本 10/10)。此前把这段字节
203
+ 原样当 `font/ttf` 塞进 `@font-face`,浏览器一个都不认,只在控制台留一行
204
+ `invalid sfntVersion`。现在 core 自己剥容器(含异或混淆),MTX 解压走
205
+ `setFontDecoder()` 注入——官网接的是 [`mtx-decompressor`](https://www.npmjs.com/package/mtx-decompressor) 的 `eotToTtf`,
206
+ core 本身仍然只依赖 fflate。解不出来就跳过这个字体,不再塞浏览器注定拒绝的字节
207
+ - **`collectFonts(slides)`**:统计若干页用到哪些字体、每个字体要渲染哪些字。
208
+ 纯函数、只依赖 `types.ts`,`.ppt` 链路同样适用,Worker 里能跑
209
+ - **新包 [`@web-ppt/fonts`](packages/fonts)**(gzip 2.8KB,**包里零字节字体**):
210
+ 文件没带字体、本机也没装时的兜底。拉丁换**度量兼容**的免费字体
211
+ (Calibri→Carlito、Arial→Arimo 等,前进宽度逐字相等,断行与 PowerPoint 对齐),
212
+ 中文换思源系 / 霞鹜文楷。切片指向钉死版本的 fontsource,按 `unicode-range` 只下用到的那几片
213
+ - **`Viewer.refresh()`**:重渲当前页而不动页码与动画进度。网络字体到货后必须重渲——
214
+ 排版是同步的、加载是异步的,首帧一定是按回退字体断的行
215
+
216
+ ### 修复
217
+
218
+ - **静态渲染取动画终态,而不是「全部可见」**。一页里入场与退场的元素属于不同时刻,
219
+ 全画出来等于把几帧叠在一起:ORCID 那份样本的第 7 页三段文字本该逐条替换,
220
+ 叠起来一个字都读不出。终态会清空整页时(全员退场的收尾页)退回全部可见
221
+ - **run 没写 `a:latin` 时落到主题的 minorFont**。ECMA-376 的继承链最后一站就是
222
+ `fontScheme/minorFont`,此前直接当「没有字体」,渲染掉到 CSS 通用回退上,
223
+ 字宽与 PowerPoint 对不齐。真实文件大多在母版 txStyles 里写了 `+mn-lt` 所以少见,
224
+ 但这是「断行对不齐」的一个隐藏来源
225
+ - 字体栈去重:主题的 ea 字体常常正好是回退列表里的 `PingFang SC`,之前会拼出重复项
226
+
227
+ ### 其它
228
+
229
+ - 测试:1689 → **1848 项断言**,快照 158 → 160 个;新增 `sample-embedfont.pptx`
230
+ 覆盖嵌入字体的四种容器形态(未压缩 EOT / 未压缩+异或 / MTX 压缩 / 裸 TTF)
231
+ - `@web-ppt/core` gzip 84KB 不变;`@web-ppt/viewer-core` 6.8KB → 7.4KB
232
+ - 两个既有包的 peer 依赖同步升到 `^0.4.0`
233
+
234
+ ## 0.3.0
235
+
236
+ 本版把 ECMA-376 的几处主要缺口补齐,并首次拿 **Apache POI 的 242 个公开测试文件**跑批验证:
237
+ 排除 22 个故意损坏的模糊测试样本后,真实文件成功率 **210/220 = 95.5%**。
238
+
239
+ ### 新增
240
+
241
+ - **预设几何补齐到规范全集**:163 → **187 个**。此前缺的 24 个走的是
242
+ `PRESETS[name] ?? PRESETS.rect`,会**静默画成矩形**,不报错也不进 `unsupported`——
243
+ `accentCallout*` 这类常见形状出现即无声画错
244
+ - **运动路径动画**:`p:animMotion@path` 此前从未被读取,`presetClass="path"` 一律退化成淡入。
245
+ 现按弧长等距重采样成位移点,播放层走 linear 缓动(PowerPoint 的路径动画是匀速)
246
+ - **切换效果 21 → 41 种**:补上 PowerPoint 2010+ 的全部 19 种 p14 扩展,以及 p159 的
247
+ **morph**——按形状 id 在前后两页之间配对做几何补间,不是淡入淡出
248
+ - **数学公式 OMML 真排版**:此前只把 `m:t` 拼成一行文字(分式变成 `a+b/2c`)。
249
+ 现做完整箱模型排版,覆盖分式 / 根式 / 上下标 / 大算符 / 定界符 / 矩阵 / 重音 / 极限等 12 类结构
250
+ - **加密文档**:
251
+ - `.pptx` 标准加密(AES-ECB)与敏捷加密(AES-CBC 分段)
252
+ - `.ppt` 老式 RC4 CryptoAPI(40 / 56 / 128 位)
253
+ - 用法 `parse(input, { password })`;密码错误抛 `WrongPasswordError`,与「文件损坏」区分开
254
+ - **PICT(Apple QuickDraw)解码器**:Mac 版 PowerPoint 存的 OLE 预览与图片此前只能是裂图
255
+ - **SmartArt 无缓存 drawing part 时自行排布**:python-pptx / Google Slides 导出的文件
256
+ 常常只写数据与版式定义,此前只能得到灰色占位框。现支持线性 / 循环 / 金字塔 / 层级 /
257
+ 蛇形 / 辐射六种布局族
258
+
259
+ ### 修复
260
+
261
+ - `borderCallout2` 的引线是三点**开放**子路径,会被 `fill` 补成实心楔形——引线画成了黑三角
262
+ - 后台标签页的 `document.timeline` 是暂停的,`Animation.finished` 永不 resolve,
263
+ 切换的收尾逻辑(移除旧图层)就永远不执行,配合自动换片会让图层持续堆积
264
+ - OLE 预览优先读 `p:oleObj` 内嵌的 `p:pic`(Office 2010+ 的主要写法),旧式 VML 快照作为后备
265
+
266
+ ### 其它
267
+
268
+ - `@web-ppt/core` gzip 68KB → 84KB(新增的解码器与公式排版;加密与 PICT 走 hook 注入,可 tree-shake)
269
+ - 测试:1298 → **1689 项断言**,快照 142 → 158 个
270
+ - `@web-ppt/viewer-core` 的 peer 依赖同步升到 `^0.3.0`
271
+
272
+ ## 0.2.0 及更早
273
+
274
+ 见 [提交历史](https://github.com/unStone/web-ppt/commits/master)。
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 unStone
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.