@web-ppt/edit-core 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 (179) hide show
  1. package/CHANGELOG.md +274 -0
  2. package/LICENSE +21 -0
  3. package/README.md +474 -0
  4. package/dist/animation-catalog.d.ts +21 -0
  5. package/dist/body-properties.d.ts +8 -0
  6. package/dist/body-property-schema.d.ts +3 -0
  7. package/dist/change-classification.d.ts +10 -0
  8. package/dist/clipboard-binary.d.ts +4 -0
  9. package/dist/clipboard-links.d.ts +11 -0
  10. package/dist/clipboard-source.d.ts +23 -0
  11. package/dist/clipboard.d.ts +4 -0
  12. package/dist/commands/add-image.d.ts +4 -0
  13. package/dist/commands/add-shape.d.ts +4 -0
  14. package/dist/commands/add-slide-identity.d.ts +8 -0
  15. package/dist/commands/add-slide-template.d.ts +9 -0
  16. package/dist/commands/add-slide.d.ts +3 -0
  17. package/dist/commands/add-table.d.ts +4 -0
  18. package/dist/commands/align-elements.d.ts +4 -0
  19. package/dist/commands/apply-format.d.ts +4 -0
  20. package/dist/commands/clipboard-types.d.ts +91 -0
  21. package/dist/commands/direct-format-patches.d.ts +8 -0
  22. package/dist/commands/dispatch.d.ts +7 -0
  23. package/dist/commands/duplicate-slide.d.ts +3 -0
  24. package/dist/commands/edit-text.d.ts +3 -0
  25. package/dist/commands/element-effects.d.ts +5 -0
  26. package/dist/commands/element-fill.d.ts +5 -0
  27. package/dist/commands/element-image-content.d.ts +17 -0
  28. package/dist/commands/element-interaction.d.ts +11 -0
  29. package/dist/commands/element-link.d.ts +5 -0
  30. package/dist/commands/element-name.d.ts +8 -0
  31. package/dist/commands/element-order.d.ts +7 -0
  32. package/dist/commands/element-stroke.d.ts +5 -0
  33. package/dist/commands/element-text.d.ts +6 -0
  34. package/dist/commands/element-transform.d.ts +5 -0
  35. package/dist/commands/element-tree.d.ts +8 -0
  36. package/dist/commands/fit-text-shape.d.ts +3 -0
  37. package/dist/commands/format-painter-types.d.ts +17 -0
  38. package/dist/commands/image-format.d.ts +7 -0
  39. package/dist/commands/image-resource.d.ts +4 -0
  40. package/dist/commands/insert-row.d.ts +3 -0
  41. package/dist/commands/insertion-rect.d.ts +9 -0
  42. package/dist/commands/paste-elements.d.ts +4 -0
  43. package/dist/commands/paste-resources.d.ts +18 -0
  44. package/dist/commands/patch.d.ts +6 -0
  45. package/dist/commands/remove-slide.d.ts +3 -0
  46. package/dist/commands/replace-image.d.ts +3 -0
  47. package/dist/commands/replace-text.d.ts +5 -0
  48. package/dist/commands/set-animations.d.ts +3 -0
  49. package/dist/commands/set-body-props.d.ts +3 -0
  50. package/dist/commands/set-crop.d.ts +3 -0
  51. package/dist/commands/set-effects.d.ts +3 -0
  52. package/dist/commands/set-fill.d.ts +3 -0
  53. package/dist/commands/set-flip.d.ts +4 -0
  54. package/dist/commands/set-link.d.ts +3 -0
  55. package/dist/commands/set-para-props.d.ts +3 -0
  56. package/dist/commands/set-run-props.d.ts +3 -0
  57. package/dist/commands/set-slide-properties.d.ts +7 -0
  58. package/dist/commands/set-stroke.d.ts +3 -0
  59. package/dist/commands/set-xfrm.d.ts +3 -0
  60. package/dist/commands/set-z.d.ts +5 -0
  61. package/dist/commands/slide-image.d.ts +4 -0
  62. package/dist/commands/slide-layout.d.ts +8 -0
  63. package/dist/commands/slide-notes.d.ts +8 -0
  64. package/dist/commands/slide-order.d.ts +7 -0
  65. package/dist/commands/slide-property-types.d.ts +135 -0
  66. package/dist/commands/slide-property.d.ts +20 -0
  67. package/dist/commands/slide-tree.d.ts +6 -0
  68. package/dist/commands/spid.d.ts +4 -0
  69. package/dist/commands/table-row.d.ts +5 -0
  70. package/dist/commands/text-target.d.ts +25 -0
  71. package/dist/commands/types.d.ts +509 -0
  72. package/dist/commands/xfrm.d.ts +8 -0
  73. package/dist/data-validation.d.ts +7 -0
  74. package/dist/document.d.ts +17 -0
  75. package/dist/dynamic-slide-fields.d.ts +6 -0
  76. package/dist/edit-core.js +5321 -0
  77. package/dist/editor.d.ts +38 -0
  78. package/dist/element-ancestry.d.ts +3 -0
  79. package/dist/element-name.d.ts +4 -0
  80. package/dist/element-order.d.ts +7 -0
  81. package/dist/field-text.d.ts +3 -0
  82. package/dist/fractional-index.d.ts +10 -0
  83. package/dist/history.d.ts +50 -0
  84. package/dist/hyperlink.d.ts +10 -0
  85. package/dist/image-content.d.ts +7 -0
  86. package/dist/image-resource-history.d.ts +6 -0
  87. package/dist/index-D4ZTaYOa.js +706 -0
  88. package/dist/index.d.ts +46 -0
  89. package/dist/insertion-DabLme_U.js +5471 -0
  90. package/dist/insertion-invariants.d.ts +5 -0
  91. package/dist/layout-assets.d.ts +10 -0
  92. package/dist/layout-projection.d.ts +24 -0
  93. package/dist/layout-text-rebase.d.ts +3 -0
  94. package/dist/model-invariants.d.ts +5 -0
  95. package/dist/notes-part.d.ts +2 -0
  96. package/dist/opc/bytes.d.ts +1 -0
  97. package/dist/opc/crc32.d.ts +1 -0
  98. package/dist/opc/index.d.ts +3 -0
  99. package/dist/opc/package-owner.d.ts +4 -0
  100. package/dist/opc/patch.d.ts +6 -0
  101. package/dist/opc/types.d.ts +12 -0
  102. package/dist/opc/zip.d.ts +28 -0
  103. package/dist/opc-owner-protocol.d.ts +5 -0
  104. package/dist/opc.js +5 -0
  105. package/dist/paragraph-properties.d.ts +4 -0
  106. package/dist/paragraph-property-schema.d.ts +4 -0
  107. package/dist/patch-DO8497wO.js +322 -0
  108. package/dist/projection.d.ts +19 -0
  109. package/dist/recovery-identity.d.ts +35 -0
  110. package/dist/recovery-types.d.ts +30 -0
  111. package/dist/recovery.d.ts +28 -0
  112. package/dist/run-links.d.ts +3 -0
  113. package/dist/run-properties.d.ts +4 -0
  114. package/dist/run-property-schema.d.ts +3 -0
  115. package/dist/save/animation.d.ts +6 -0
  116. package/dist/save/background-image.d.ts +8 -0
  117. package/dist/save/clipboard-parts.d.ts +11 -0
  118. package/dist/save/drawing-color.d.ts +2 -0
  119. package/dist/save/duplicate-slide-parts.d.ts +15 -0
  120. package/dist/save/effects.d.ts +6 -0
  121. package/dist/save/hyperlink.d.ts +18 -0
  122. package/dist/save/image-content.d.ts +4 -0
  123. package/dist/save/index.d.ts +5 -0
  124. package/dist/save/insertion.d.ts +14 -0
  125. package/dist/save/layout-fallback-source.d.ts +4 -0
  126. package/dist/save/layout-fallback.d.ts +7 -0
  127. package/dist/save/materialize.d.ts +5 -0
  128. package/dist/save/name.d.ts +5 -0
  129. package/dist/save/notes.d.ts +12 -0
  130. package/dist/save/order.d.ts +5 -0
  131. package/dist/save/remove-element.d.ts +4 -0
  132. package/dist/save/remove-slide-parts.d.ts +11 -0
  133. package/dist/save/shape-format.d.ts +14 -0
  134. package/dist/save/slide-parts.d.ts +11 -0
  135. package/dist/save/slide-properties.d.ts +4 -0
  136. package/dist/save/table.d.ts +7 -0
  137. package/dist/save/text-body.d.ts +4 -0
  138. package/dist/save/text.d.ts +6 -0
  139. package/dist/save/transition.d.ts +4 -0
  140. package/dist/save/xfrm.d.ts +22 -0
  141. package/dist/save/xml-element.d.ts +3 -0
  142. package/dist/save.js +1559 -0
  143. package/dist/selection-pane.d.ts +18 -0
  144. package/dist/selection.d.ts +11 -0
  145. package/dist/session-assets.d.ts +20 -0
  146. package/dist/shape-effects.d.ts +6 -0
  147. package/dist/shape-fill.d.ts +12 -0
  148. package/dist/shape-stroke.d.ts +9 -0
  149. package/dist/slide-animation.d.ts +15 -0
  150. package/dist/slide-background-source.d.ts +13 -0
  151. package/dist/slide-notes.d.ts +2 -0
  152. package/dist/slide-properties.d.ts +4 -0
  153. package/dist/slide-transition.d.ts +19 -0
  154. package/dist/space.d.ts +47 -0
  155. package/dist/table-cell.d.ts +10 -0
  156. package/dist/table-direct-markup.d.ts +3 -0
  157. package/dist/table-insertion-policy.d.ts +5 -0
  158. package/dist/table-row-append-validation.d.ts +3 -0
  159. package/dist/table-rows.d.ts +12 -0
  160. package/dist/text-model.d.ts +28 -0
  161. package/dist/text-override-projection.d.ts +8 -0
  162. package/dist/text-override-validation.d.ts +7 -0
  163. package/dist/text-position.d.ts +8 -0
  164. package/dist/text-search-types.d.ts +46 -0
  165. package/dist/text-search.d.ts +5 -0
  166. package/dist/transaction-validation.d.ts +5 -0
  167. package/dist/types.d.ts +519 -0
  168. package/dist/xml/index.d.ts +9 -0
  169. package/dist/xml/mutate.d.ts +7 -0
  170. package/dist/xml/namespace.d.ts +5 -0
  171. package/dist/xml/nodes.d.ts +22 -0
  172. package/dist/xml/order.d.ts +15 -0
  173. package/dist/xml/qname.d.ts +15 -0
  174. package/dist/xml/query.d.ts +10 -0
  175. package/dist/xml/state.d.ts +30 -0
  176. package/dist/xml/tree.d.ts +8 -0
  177. package/dist/xml/types.d.ts +46 -0
  178. package/dist/xml.js +19 -0
  179. package/package.json +67 -0
@@ -0,0 +1,519 @@
1
+ import type { Effects, ElementBase, Fill, GeomSpec, ImageElement, OpcPackage, Paragraph, PlaceholderDirectFlags, Presentation, ShapeCreationDefaults, ShapeElement, Slide, Stroke, Transition, TableCreationDefaults, SlideElement, SlideLayoutTemplate, TextBody, TextRun } from '@web-ppt/core';
2
+ import type { EmphasisAnimationEffect, EntranceExitAnimationEffect } from './animation-catalog';
3
+ export type ElementId = string;
4
+ export type SlideId = string;
5
+ export type FractionalIndex = string;
6
+ export type EditableKind = 'full' | 'frame' | 'none';
7
+ export interface TableCellAddress {
8
+ readonly r: number;
9
+ readonly c: number;
10
+ }
11
+ /** 来源行沿用坐标;新增行把稳定 rowId 编进 key,避免并发追加改变文字归属。 */
12
+ export type TableCellKey = `${number}:${number}` | `@${number}:${string}:${number}`;
13
+ export type TableCellRowRef = number | TableRowId;
14
+ export interface ElementInsertionSource {
15
+ readonly markup: string;
16
+ readonly namespaces: Readonly<Record<string, string>>;
17
+ /** 来源 spid 字符串 → 目标 part 新 spid。 */
18
+ readonly spids: Readonly<Record<string, number>>;
19
+ readonly relationships?: readonly ElementInsertionRelationship[];
20
+ readonly resources?: readonly ElementInsertionResource[];
21
+ }
22
+ export interface ElementInsertionRelationship {
23
+ readonly sourceId: string;
24
+ readonly targetId: string;
25
+ readonly type: string;
26
+ readonly target: string;
27
+ readonly targetMode?: 'External';
28
+ }
29
+ export interface ElementInsertionResource {
30
+ readonly targetPart: string;
31
+ readonly hash: string;
32
+ readonly mime: string;
33
+ readonly extension: string;
34
+ readonly bytes: string;
35
+ /** true 表示该 part 由本编辑会话生成,撤销后保存必须删除。 */
36
+ readonly created: boolean;
37
+ }
38
+ /** 图片替换与新增元素共用关系/媒体闭包,但不伪装成一棵新插入 XML 树。 */
39
+ export interface ElementImageReplacement {
40
+ readonly src: string;
41
+ readonly relationships: readonly ElementInsertionRelationship[];
42
+ /** 大字节只在文档资源表存一份;历史 Patch 仅携带哈希引用。 */
43
+ readonly resourceHash: string;
44
+ /** 新建/粘贴图片的来源关系已被新 blip 取代;保存时不能继续把它当活跃引用。 */
45
+ readonly suppressedRelationshipId?: string;
46
+ }
47
+ /** 页面背景会克隆未知扩展;因此除主图片外还要持有扩展引用的完整关系/资源闭包。 */
48
+ export interface SlideImageBackground extends ElementImageReplacement {
49
+ readonly imageRelationshipId: string;
50
+ readonly resourceHashes: readonly string[];
51
+ /** 存在时必须能回证为当前页的真实 OPC 背景来源;是否保留 DPI 由此推导。 */
52
+ readonly sourcePart?: string;
53
+ }
54
+ export type SlideSource = Omit<Slide, 'elements' | 'editInfo'>;
55
+ export type SlideOverrides = Omit<Partial<SlideSource>, 'animations'> & {
56
+ /** 稳定元素身份只存在编辑模型;投影时才恢复易失的数值 spid。 */
57
+ animations?: readonly EditAnimationStep[];
58
+ };
59
+ type BaseOverrideKey = 'x' | 'y' | 'w' | 'h' | 'rot' | 'flipH' | 'flipV' | 'effects' | 'name' | 'scene3d';
60
+ export type LinkTarget = {
61
+ readonly kind: 'external';
62
+ readonly href: string;
63
+ } | {
64
+ readonly kind: 'slide';
65
+ readonly slideId: SlideId;
66
+ };
67
+ /** 相对放映动作没有稳定目标页;可展示和跟随,但不能冒充可编辑 LinkTarget。 */
68
+ export interface RelativeLinkSource {
69
+ readonly kind: 'relative';
70
+ readonly action: 'next' | 'previous' | 'first' | 'last';
71
+ }
72
+ export interface UnsupportedLinkSource {
73
+ readonly kind: 'unsupported';
74
+ }
75
+ export type LinkSourceValue = LinkTarget | RelativeLinkSource | UnsupportedLinkSource;
76
+ export type LinkOverride = LinkTarget | {
77
+ readonly kind: 'none';
78
+ };
79
+ export interface ElementLinkState {
80
+ readonly value: LinkSourceValue | null;
81
+ readonly source: LinkSourceValue | null;
82
+ readonly mixed: boolean;
83
+ readonly sourceMixed: boolean;
84
+ readonly direct: boolean;
85
+ /** true 表示来源只能原样保留;设置新覆盖仍是显式、安全的替换。 */
86
+ readonly sourceReadonly: boolean;
87
+ readonly followable: boolean;
88
+ }
89
+ /**
90
+ * 只允许覆盖可写字段。`path` / `clipPath` 是由 geom 与当前尺寸算出的派生值,
91
+ * `id` / `editInfo` 则属于源文件身份,二者都不能进入覆盖层。
92
+ */
93
+ export type ElementOverrides = Partial<Pick<ElementBase, BaseOverrideKey>> & {
94
+ /** 缺少字段表示来源;none 表示明确移除,不能用 undefined 混淆二者。 */
95
+ link?: LinkOverride;
96
+ /** 显式无填充用 Fill.none;缺少该字段才表示恢复来源/主题。 */
97
+ fill?: Exclude<Fill, {
98
+ type: 'image';
99
+ }>;
100
+ stroke?: ShapeElement['stroke'] | ImageElement['stroke'];
101
+ openGeom?: ShapeElement['openGeom'];
102
+ src?: ImageElement['src'];
103
+ crop?: ImageElement['crop'];
104
+ alpha?: ImageElement['alpha'];
105
+ filter?: ImageElement['filter'];
106
+ text?: TextOverride;
107
+ /** 来源格按坐标、新增格按稳定行身份稀疏覆盖,避免结构 rebase 迁移文字。 */
108
+ tableCells?: Record<TableCellKey, TableCellOverrides>;
109
+ /** 表格行使用稳定身份稀疏追加;不复制整张 rows,未来可沿同一身份扩展中间插入。 */
110
+ tableRows?: Record<TableRowId, TableRowInsertion>;
111
+ };
112
+ export interface ElementFillState {
113
+ readonly value: Fill | null;
114
+ readonly mixed: boolean;
115
+ /** 任一目标存在直接覆盖时为 true;UI 可据此启用“恢复默认”。 */
116
+ readonly direct: boolean;
117
+ }
118
+ export interface SlideBackgroundState {
119
+ readonly value: Fill | null;
120
+ readonly source: Fill | null;
121
+ readonly mixed: boolean;
122
+ readonly sourceMixed: boolean;
123
+ readonly direct: boolean;
124
+ }
125
+ export interface SlideHiddenState {
126
+ readonly value: boolean;
127
+ readonly source: boolean;
128
+ readonly mixed: boolean;
129
+ readonly sourceMixed: boolean;
130
+ readonly direct: boolean;
131
+ }
132
+ export interface SlideLayoutState {
133
+ readonly value: string | null;
134
+ readonly source: string | null;
135
+ readonly mixed: boolean;
136
+ readonly sourceMixed: boolean;
137
+ readonly direct: boolean;
138
+ }
139
+ export interface SlideNotesState {
140
+ readonly value: string;
141
+ readonly source: string;
142
+ readonly mixed: boolean;
143
+ readonly sourceMixed: boolean;
144
+ readonly direct: boolean;
145
+ }
146
+ export interface SlideTransitionState {
147
+ readonly value: Transition | null;
148
+ readonly source: Transition | null;
149
+ readonly mixed: boolean;
150
+ readonly sourceMixed: boolean;
151
+ readonly direct: boolean;
152
+ }
153
+ interface EditAnimationBase {
154
+ readonly target: ElementId;
155
+ readonly trigger: 'click' | 'withPrev' | 'afterPrev';
156
+ readonly delayMs: number;
157
+ readonly durationMs: number;
158
+ }
159
+ export type EditAnimationStep = EditAnimationBase & ({
160
+ readonly kind: 'entrance' | 'exit';
161
+ readonly effect: Exclude<EntranceExitAnimationEffect, 'fly' | 'wipe' | 'zoom'>;
162
+ readonly dir?: never;
163
+ readonly motionPath?: never;
164
+ } | {
165
+ readonly kind: 'entrance' | 'exit';
166
+ readonly effect: 'fly' | 'wipe';
167
+ readonly dir?: 'l' | 'r' | 'u' | 'd';
168
+ readonly motionPath?: never;
169
+ } | {
170
+ readonly kind: 'entrance' | 'exit';
171
+ readonly effect: 'zoom';
172
+ readonly dir?: 'in' | 'out';
173
+ readonly motionPath?: never;
174
+ } | {
175
+ readonly kind: 'emphasis';
176
+ readonly effect: EmphasisAnimationEffect;
177
+ readonly dir?: never;
178
+ readonly motionPath?: never;
179
+ } | {
180
+ readonly kind: 'motion';
181
+ readonly effect?: never;
182
+ readonly dir?: never;
183
+ readonly motionPath: readonly (readonly [number, number])[];
184
+ });
185
+ export interface SlideAnimationState {
186
+ readonly value: readonly EditAnimationStep[];
187
+ readonly source: readonly EditAnimationStep[];
188
+ readonly mixed: boolean;
189
+ readonly sourceMixed: boolean;
190
+ readonly direct: boolean;
191
+ /** true 表示来源含不可稳定寻址或尚未开放的时间树节点;未触碰时仍会原样保留。 */
192
+ readonly sourceReadonly: boolean;
193
+ }
194
+ export interface ElementStrokeState {
195
+ readonly value: Stroke | null;
196
+ readonly mixed: boolean;
197
+ /** 任一目标存在直接覆盖时为 true;显式无描边同样属于直接覆盖。 */
198
+ readonly direct: boolean;
199
+ }
200
+ export interface ElementEffectsState {
201
+ readonly value: Effects;
202
+ readonly mixed: boolean;
203
+ /** 空对象也是直接效果:它用于屏蔽版式或主题继承。 */
204
+ readonly direct: boolean;
205
+ }
206
+ export type ImageCrop = NonNullable<ImageElement['crop']>;
207
+ export interface ElementCropState {
208
+ readonly value: ImageElement['crop'];
209
+ readonly mixed: boolean;
210
+ /** 全零裁剪仍是直接格式;只有 SetCrop(null) 才恢复来源。 */
211
+ readonly direct: boolean;
212
+ }
213
+ export interface TableCellOverrides {
214
+ text?: TextOverride;
215
+ }
216
+ export type TableRowId = string;
217
+ export interface TableRowInsertion {
218
+ readonly order: FractionalIndex;
219
+ }
220
+ export interface TextMark {
221
+ readonly from: number;
222
+ readonly to: number;
223
+ readonly props: Omit<TextRun, 'text'>;
224
+ /** 公式在编辑字符串里只占一个原子,线性文本另存用于投影与导出。 */
225
+ readonly atomText?: string;
226
+ /** 来源身份让保存层尽量复用原始 rPr / fld / 公式节点。 */
227
+ readonly source?: {
228
+ readonly paragraph: number;
229
+ readonly run: number;
230
+ };
231
+ /** 只有来源内容本身能克隆 fld/公式;新输入只借 source 继承 rPr。 */
232
+ readonly preserveSource?: true;
233
+ /** 用户对来源 rPr 的稀疏覆盖;null 表示删除直接格式、回到继承。 */
234
+ readonly runOverrides?: RunPropertyOverrides;
235
+ /** 删除直接格式后用于恢复继承所得的有效值;只含字符格式 P0 字段。 */
236
+ readonly inheritedProps?: RunProperties;
237
+ /** 继承字体可能分别含 latin/ea/cs,不能为面板的单字体值而丢掉回退栈。 */
238
+ readonly inheritedFonts?: readonly string[];
239
+ /** 只说明来源链接不可安全编辑,不携带原始 action 或危险 URL。 */
240
+ readonly sourceLinkReadonly?: true;
241
+ }
242
+ export interface RunProperties {
243
+ readonly font: string | null;
244
+ readonly size: number;
245
+ readonly b: boolean;
246
+ readonly i: boolean;
247
+ readonly u: boolean;
248
+ readonly strike: boolean;
249
+ }
250
+ export interface RunPropertyOverrides {
251
+ readonly font?: string | null;
252
+ readonly size?: number | null;
253
+ readonly b?: boolean | null;
254
+ readonly i?: boolean | null;
255
+ readonly u?: boolean | null;
256
+ readonly strike?: boolean | null;
257
+ /** null 恢复来源;none 明确去掉选区链接。 */
258
+ readonly link?: LinkOverride | null;
259
+ }
260
+ /** 外部富文本进入模型前的最小白名单;不允许携带 OOXML 来源或 DOM 身份。 */
261
+ export interface TextFragmentMark {
262
+ readonly from: number;
263
+ readonly to: number;
264
+ readonly props: RunPropertyOverrides;
265
+ }
266
+ export interface TextFragmentParagraph {
267
+ readonly text: string;
268
+ readonly marks: readonly TextFragmentMark[];
269
+ }
270
+ export interface TextFragment {
271
+ readonly paragraphs: readonly TextFragmentParagraph[];
272
+ }
273
+ export interface RunPropertyState<T> {
274
+ readonly value: T | null;
275
+ readonly mixed: boolean;
276
+ }
277
+ export interface RunPropertiesState {
278
+ readonly font: RunPropertyState<string>;
279
+ readonly size: RunPropertyState<number>;
280
+ readonly b: RunPropertyState<boolean>;
281
+ readonly i: RunPropertyState<boolean>;
282
+ readonly u: RunPropertyState<boolean>;
283
+ readonly strike: RunPropertyState<boolean>;
284
+ }
285
+ export type RunLinkState = ElementLinkState;
286
+ export interface ParagraphPropertyOverrides {
287
+ readonly align?: Paragraph['align'] | null;
288
+ readonly lineHeight?: number | null;
289
+ readonly spaceBefore?: number | null;
290
+ readonly spaceAfter?: number | null;
291
+ readonly marginLeft?: number | null;
292
+ readonly indent?: number | null;
293
+ }
294
+ export interface ParagraphProperties {
295
+ readonly align: Paragraph['align'];
296
+ readonly lineHeight: number | null;
297
+ readonly spaceBefore: number;
298
+ readonly spaceAfter: number;
299
+ readonly marginLeft: number;
300
+ readonly indent: number;
301
+ }
302
+ export interface ParagraphPropertiesState {
303
+ readonly align: RunPropertyState<Paragraph['align']>;
304
+ readonly lineHeight: RunPropertyState<number>;
305
+ readonly spaceBefore: RunPropertyState<number>;
306
+ readonly spaceAfter: RunPropertyState<number>;
307
+ readonly marginLeft: RunPropertyState<number>;
308
+ readonly indent: RunPropertyState<number>;
309
+ }
310
+ export type TextBodyAutoFit = 'none' | 'normal' | 'shape';
311
+ export interface TextBodyProperties {
312
+ readonly anchor: TextBody['anchor'];
313
+ readonly insets: readonly [number, number, number, number];
314
+ readonly wrap: boolean;
315
+ readonly vert: NonNullable<TextBody['vert']>;
316
+ readonly anchorCtr: boolean;
317
+ readonly columns: number;
318
+ readonly columnGap: number;
319
+ readonly autoFit: TextBodyAutoFit;
320
+ }
321
+ export interface TextBodyPropertyOverrides {
322
+ readonly anchor?: TextBodyProperties['anchor'] | null;
323
+ readonly insets?: TextBodyProperties['insets'] | null;
324
+ readonly wrap?: boolean | null;
325
+ readonly vert?: TextBodyProperties['vert'] | null;
326
+ readonly anchorCtr?: boolean | null;
327
+ readonly columns?: number | null;
328
+ readonly columnGap?: number | null;
329
+ readonly autoFit?: TextBodyAutoFit | null;
330
+ }
331
+ export interface FlatTextParagraph {
332
+ readonly text: string;
333
+ readonly props: Omit<Paragraph, 'runs'>;
334
+ readonly marks: readonly TextMark[];
335
+ readonly sourceParagraph?: number;
336
+ /** 用户对来源 pPr 的稀疏覆盖;null 表示删除直接格式、回到继承。 */
337
+ readonly paragraphOverrides?: ParagraphPropertyOverrides;
338
+ /** 删除直接段落格式后恢复的继承有效值。 */
339
+ readonly inheritedParagraphProps?: ParagraphProperties;
340
+ /** 来源 pPr 的直接字段集合,用于区分“删除直设”与严格 no-op。 */
341
+ readonly directParagraphProps?: Readonly<Partial<Record<keyof ParagraphProperties, true>>>;
342
+ }
343
+ export type TextBodyOverride = Omit<TextBody, 'paragraphs' | 'editInfo'>;
344
+ export type TextOverride = {
345
+ readonly kind: 'empty';
346
+ /** 清空文字后仍保留 bodyPr 的有效值,属性面板不能因此失去编辑入口。 */
347
+ readonly body?: TextBodyOverride;
348
+ readonly bodyOverrides?: TextBodyPropertyOverrides;
349
+ } | {
350
+ readonly kind: 'flat';
351
+ readonly body: TextBodyOverride;
352
+ /** 只记录用户触碰过的 bodyPr 字段;null 表示清除本层直设。 */
353
+ readonly bodyOverrides?: TextBodyPropertyOverrides;
354
+ readonly paragraphs: readonly FlatTextParagraph[];
355
+ };
356
+ export interface ElementMeta {
357
+ geom?: GeomSpec;
358
+ ph?: {
359
+ type: string;
360
+ idx?: string;
361
+ };
362
+ placeholderDirect?: PlaceholderDirectFlags;
363
+ /** 旧版式解绑时需要固定的继承效果;普通未编辑投影仍沿用 core 既有语义。 */
364
+ placeholderInheritedEffects?: Effects;
365
+ origin?: {
366
+ part: string;
367
+ spid: number;
368
+ };
369
+ locked?: boolean;
370
+ /** 来源文件只禁止移动;与宿主设置的通用 locked 分开,避免误伤其他编辑。 */
371
+ moveLocked?: boolean;
372
+ /** 空文字形状的编辑格式入口;首次输入后由 flat override 接管。 */
373
+ textTemplate?: TextBody;
374
+ /** 会话中新建的元素没有保存基线宿主;撤销时不能把它误记成来源删除。 */
375
+ created?: boolean;
376
+ /** 新建普通形状的 p:style 使用主题引用;换母版时其有效默认值必须重新求值。 */
377
+ themeDefaultShape?: true;
378
+ /** 页眉页脚字段的内容属于页面,几何与空白格式仍来自当前版式。 */
379
+ fieldPlaceholder?: true;
380
+ /** 仅新建树根携带;保存从初始基线重建时据此重新插入宿主。 */
381
+ insertion?: ElementInsertionSource;
382
+ /** 只承载当前有效替换资源;历史中的旧闭包不会污染活跃 OPC 图。 */
383
+ imageReplacement?: ElementImageReplacement;
384
+ hiddenByUser?: boolean;
385
+ editable: EditableKind;
386
+ /** true 表示节点只来自母版/版式投影,不属于 slide XML 的可持久内容树。 */
387
+ inherited?: true;
388
+ /** 来源存在无法安全映射的链接;覆盖层缺失时查询为只读来源。 */
389
+ sourceLinkReadonly?: true;
390
+ }
391
+ export interface ElementRecord {
392
+ id: ElementId;
393
+ parent: SlideId | ElementId;
394
+ /** 解析得到的来源绘制序;编辑命令不得修改 */
395
+ z: FractionalIndex;
396
+ /** 仅当用户改变层级时存在;删除后重新落回来源序可以释放这份稀疏状态 */
397
+ order?: FractionalIndex;
398
+ /** 解析得到的源值;编辑命令不得修改 */
399
+ src: SlideElement;
400
+ /** 仅保存用户明确改过的字段 */
401
+ ovr: ElementOverrides;
402
+ meta: ElementMeta;
403
+ /** 只有 group 存在;顺序与 z 严格一致 */
404
+ children?: ElementId[];
405
+ }
406
+ /** 已删除根只保留最小写回锚点;完整子树由历史 patch 持有,避免模型重复占用内存。 */
407
+ export interface RemovedElementRecord {
408
+ id: ElementId;
409
+ parent: SlideId | ElementId;
410
+ meta: ElementMeta;
411
+ /** 删除树在来源 slide part 中占用的全部 spid;保存期用它清理 timing/build 悬空引用。 */
412
+ sourceSpids?: readonly number[];
413
+ }
414
+ export interface SlideRecord {
415
+ id: SlideId;
416
+ src: SlideSource;
417
+ ovr: SlideOverrides;
418
+ /** 来源查询使用稳定元素身份;原始数值动画仍留在 src 供未触碰投影与字节直通。 */
419
+ sourceAnimations?: readonly EditAnimationStep[];
420
+ sourceAnimationsReadonly?: true;
421
+ /** 大字节留在 imageResources;页面历史只持有这个关系闭包与哈希。 */
422
+ backgroundImage?: SlideImageBackground;
423
+ children: ElementId[];
424
+ /** 页序变化时只需失效这些动态字段及祖先,避免把页尾全部元素推给视图订阅者。 */
425
+ dynamicSlideNumbers: ElementId[];
426
+ /** 相对页序动作或稳定 part 跳转;插页后由投影层重新解析目标序号。 */
427
+ dynamicSlideLinks: ElementId[];
428
+ origin: {
429
+ part: string;
430
+ } | null;
431
+ notes?: SlideNotesBinding;
432
+ layoutId?: string;
433
+ /** 首次打开或创建时的版式来源;layoutId 改变不应覆写这份查询/撤销基线。 */
434
+ sourceLayoutId?: string;
435
+ /** 解析期已确认背景来自 slide XML,而非旧版式的有效值。 */
436
+ sourceDirectBackground?: true;
437
+ /** 解析期已确认转场来自 slide XML。 */
438
+ sourceDirectTransition?: true;
439
+ /** 来源页面自身屏蔽母版图形;只换关系不能改变这一页级语义。 */
440
+ sourceHideMasterShapes?: true;
441
+ /** 仅会话中新页存在;保存层据此物化 OPC part 与 presentation 引用。 */
442
+ creation?: SlideCreation;
443
+ /** 解析期已在当前页主题/颜色映射上求值,新增形状无需理解 OOXML 主题。 */
444
+ defaultShape?: ShapeCreationDefaults;
445
+ /** 解析期已在当前页主题/默认表样式上求值,新增表格无需理解 OOXML 样式层。 */
446
+ defaultTable?: TableCreationDefaults;
447
+ }
448
+ export interface SlideNotesBinding {
449
+ readonly sourcePart?: string;
450
+ readonly targetPart: string;
451
+ readonly relationshipId: string;
452
+ }
453
+ export interface SlideCreation {
454
+ readonly layoutPart: string;
455
+ readonly layoutRelationshipId: string;
456
+ /** 页面副本从该不可变来源 part 起步;副本链在命令期展平,避免保存依赖页序。 */
457
+ readonly duplicateSourcePart?: string;
458
+ /** 副本链展平到最初 notes 基线,目标 notes 因而不依赖中间副本是否已物化。 */
459
+ readonly duplicateNotesSourcePart?: string;
460
+ readonly duplicateNotesPart?: string;
461
+ /** 来源基线中已在复制时删除的宿主;新增宿主仍由 insertion 的存活树决定。 */
462
+ readonly duplicateRemovedSpids?: readonly number[];
463
+ /** 结构删除只需根 spid;动画引用还可能指向已随组删除的后代。 */
464
+ readonly duplicateRemovedAnimationSpids?: readonly number[];
465
+ readonly presentationSlideId: number;
466
+ readonly presentationRelationshipId: string;
467
+ /** 锚点页在 presentation.xml 中的数值 id;section 写回以它定位。 */
468
+ readonly sectionAfterSlideId?: number;
469
+ }
470
+ export interface EditDocMeta {
471
+ width: number;
472
+ height: number;
473
+ source: Presentation['source'];
474
+ /** true 表示缺少可靠写回上下文,只能安全查看 */
475
+ readonly: boolean;
476
+ }
477
+ /** 会话内身份分配状态必须随文档持久化,否则恢复后会复用旧 id。 */
478
+ export interface EditIdentity {
479
+ prefix: string;
480
+ nextSlide: number;
481
+ nextElement: number;
482
+ /** part 内 cNvPr@id 分配状态;首次新增时才从保留 XML 求最大值。 */
483
+ nextSpid: Record<string, number>;
484
+ /** 四项均惰性初始化,未使用新增/复制页能力时不扫描任何保存期身份。 */
485
+ nextSlidePart?: number;
486
+ nextNotesPart?: number;
487
+ nextPresentationSlideId?: number;
488
+ nextPresentationRelationship?: number;
489
+ }
490
+ /** 只保存首次触碰的 XML part;必须随文档 structuredClone 才能在 Worker 中正确撤销后保存。 */
491
+ export interface EditSaveState {
492
+ baselines: Record<string, Uint8Array>;
493
+ createdParts: string[];
494
+ /** 首次打开时的页 part 顺序;用 O(n) 纯数据比较识别页序编辑,不让普通保存解析 presentation.xml。 */
495
+ sourceSlideParts: string[];
496
+ }
497
+ export interface EditDoc {
498
+ meta: EditDocMeta;
499
+ identity: EditIdentity;
500
+ slides: Record<SlideId, SlideRecord>;
501
+ slideOrder: SlideId[];
502
+ layouts: Record<string, SlideLayoutTemplate>;
503
+ layoutOrder: string[];
504
+ elements: Record<ElementId, ElementRecord>;
505
+ removedElements: Record<ElementId, RemovedElementRecord>;
506
+ /** 会话图片按内容寻址;未被当前元素引用的条目仍可供历史逆向 Patch 恢复。 */
507
+ imageResources: Record<string, ElementInsertionResource>;
508
+ readonly package: OpcPackage | null;
509
+ saveState: EditSaveState;
510
+ }
511
+ export interface CreateDocOptions {
512
+ /** 测试、协同或外部存储需要可预测身份时显式指定;省略时每份文档自动唯一 */
513
+ idPrefix?: string;
514
+ }
515
+ export interface ProjectionInvalidation {
516
+ dirtyElements: Set<ElementId>;
517
+ dirtySlides: Set<SlideId>;
518
+ }
519
+ export {};
@@ -0,0 +1,9 @@
1
+ /** 保存期按需加载的无 DOM 保留型 XML 树。 */
2
+ export { parseXmlTree, serializeXmlTree, serializeXmlTreeBytes } from './tree';
3
+ export { removeXmlAttribute, setXmlAttribute } from './mutate';
4
+ export { createXmlElement, createXmlText, removeXmlChild, reorderXmlChildren } from './nodes';
5
+ export { insertXmlChild, insertXmlInOrder, OOXML_CHILD_ORDER } from './order';
6
+ export { findXmlAttribute, findXmlChild, findXmlDescendant, xmlElementChildren } from './query';
7
+ export type { CreateXmlElementOptions } from './nodes';
8
+ export type { XmlNameSelector } from './query';
9
+ export type { XmlAttribute, XmlCdata, XmlComment, XmlDeclaration, XmlDocument, XmlElement, XmlNode, XmlProcessingInstruction, XmlQuote, XmlText, } from './types';
@@ -0,0 +1,7 @@
1
+ import type { XmlAttribute, XmlElement, XmlQuote } from './types';
2
+ /** 按限定名设置属性;已有属性保持原位置、空白与引号,新属性追加到现有属性之后。 */
3
+ export declare function setXmlAttribute(element: XmlElement, name: string, value: string, quote?: XmlQuote): XmlAttribute;
4
+ /** 删除限定名完全相同的属性;不存在时不产生脏标记。 */
5
+ export declare function removeXmlAttribute(element: XmlElement, name: string): boolean;
6
+ /** tree.ts 使用;只重写发生变化的属性值和新增/删除属性。 */
7
+ export declare function serializeElementOpen(element: XmlElement): string;
@@ -0,0 +1,5 @@
1
+ import type { XmlElement } from './types';
2
+ /** 返回节点挂入指定父元素后限定名所代表的 URI,不要求先改变树结构。 */
3
+ export declare function namespaceUriOnAttach(parent: XmlElement, child: XmlElement): string | null;
4
+ /** xmlns 改变会影响整棵后代;集中重绑,避免查询读到陈旧的展开名。 */
5
+ export declare function rebindXmlNamespaces(element: XmlElement, inherited?: ReadonlyMap<string, string>): void;
@@ -0,0 +1,22 @@
1
+ import type { XmlElement, XmlNode, XmlQuote } from './types';
2
+ export interface CreateXmlElementOptions {
3
+ attributes?: readonly (readonly [name: string, value: string, quote?: XmlQuote])[];
4
+ selfClosing?: boolean;
5
+ }
6
+ /** 创建尚未挂树的 XML 元素;限定名由调用方决定,不强行改写文件已有前缀。 */
7
+ export declare function createXmlElement(name: string, options?: CreateXmlElementOptions): XmlElement;
8
+ /** 克隆到未挂载树;元素会重建,叶节点保留原始词法,避免丢失注释、CDATA 与处理指令。 */
9
+ export declare function cloneXmlNode(source: XmlElement): XmlElement;
10
+ export declare function cloneXmlNode(source: XmlNode): XmlNode;
11
+ /** 子树离开来源祖先时,把有效前缀物化到新根,避免未知扩展序列化成未绑定 QName。 */
12
+ export declare function cloneXmlNodeWithNamespaceClosure(source: XmlElement): XmlElement;
13
+ /** 在指定节点前插入;before 省略时追加。格式化空白由原父节点保持,不凭空重排已有内容。 */
14
+ export declare function insertXmlChildUnchecked(parent: XmlElement, child: XmlNode, before?: XmlNode | null): number;
15
+ /** 从父元素移除节点;节点可随后重新挂载。 */
16
+ export declare function removeXmlChild(parent: XmlElement, child: XmlNode): boolean;
17
+ /** 原槽位替换为零到多个节点;相邻未知节点与格式化空白均保持原位。 */
18
+ export declare function replaceXmlChildren(parent: XmlElement, current: XmlNode, replacements: readonly XmlNode[]): void;
19
+ /** 只替换指定既有节点占据的槽位;缩进文本与其它兼容性节点原地保留。 */
20
+ export declare function reorderXmlChildren(parent: XmlElement, ordered: readonly XmlNode[]): boolean;
21
+ /** 创建纯文本节点;序列化时按 XML 文本规则转义。 */
22
+ export declare function createXmlText(value: string): XmlNode;
@@ -0,0 +1,15 @@
1
+ import type { XmlElement, XmlNode } from './types';
2
+ type OrderGroups = readonly (readonly string[])[];
3
+ interface ChildOrderSchema {
4
+ readonly groups: OrderGroups;
5
+ }
6
+ /** ECMA-376 中编辑路径会触及的复杂类型 sequence;展开名允许任意前缀且不会误伤同名 XML。 */
7
+ export declare const OOXML_CHILD_ORDER: Readonly<Record<string, ChildOrderSchema>>;
8
+ /**
9
+ * 按 OOXML sequence 插入元素。已知容器遇到未知子元素会拒绝,避免静默生成 PowerPoint 要修复的包。
10
+ * 同一互斥组的替换由调用方先删除旧节点;这里只保证位置,不猜测用户意图。
11
+ */
12
+ export declare function insertXmlInOrder(parent: XmlElement, child: XmlElement): number;
13
+ /** 通用节点入口;已登记的 OOXML 容器会强制元素走 schema 顺序,不能由调用方绕过。 */
14
+ export declare function insertXmlChild(parent: XmlElement, child: XmlNode, before?: XmlNode | null): number;
15
+ export {};
@@ -0,0 +1,15 @@
1
+ export declare const XML_NS = "http://www.w3.org/XML/1998/namespace";
2
+ export declare const XMLNS_NS = "http://www.w3.org/2000/xmlns/";
3
+ export declare const DRAWINGML_NS = "http://schemas.openxmlformats.org/drawingml/2006/main";
4
+ export declare const PRESENTATIONML_NS = "http://schemas.openxmlformats.org/presentationml/2006/main";
5
+ export declare const POWERPOINT_2010_NS = "http://schemas.microsoft.com/office/powerpoint/2010/main";
6
+ export declare const MARKUP_COMPATIBILITY_NS = "http://schemas.openxmlformats.org/markup-compatibility/2006";
7
+ export declare const OFFICE_MATH_NS = "http://schemas.openxmlformats.org/officeDocument/2006/math";
8
+ export declare const OFFICE_RELATIONSHIPS_NS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
9
+ export declare function isXmlQName(name: string): boolean;
10
+ export declare function assertXmlQName(name: string, kind: '元素' | '属性'): void;
11
+ export declare const splitQName: (name: string) => {
12
+ prefix: string | null;
13
+ localName: string;
14
+ };
15
+ export declare function namespaceForQName(name: string, namespaces: ReadonlyMap<string, string>, attribute: boolean): string | null;
@@ -0,0 +1,10 @@
1
+ import type { XmlAttribute, XmlElement } from './types';
2
+ export interface XmlNameSelector {
3
+ localName: string;
4
+ /** 省略表示任意命名空间;显式 null 只匹配无命名空间。 */
5
+ namespaceUri?: string | null;
6
+ }
7
+ export declare function xmlElementChildren(parent: XmlElement, selector?: XmlNameSelector): XmlElement[];
8
+ export declare function findXmlChild(parent: XmlElement, selector: XmlNameSelector): XmlElement | null;
9
+ export declare function findXmlDescendant(parent: XmlElement, selector: XmlNameSelector): XmlElement | null;
10
+ export declare function findXmlAttribute(element: XmlElement, selector: XmlNameSelector): XmlAttribute | null;
@@ -0,0 +1,30 @@
1
+ import type { XmlAttribute, XmlDocument, XmlElement, XmlNode } from './types';
2
+ export interface XmlNodeState {
3
+ raw: string;
4
+ parent: XmlDocument | XmlElement | null;
5
+ dirty: boolean;
6
+ }
7
+ export interface XmlAttributeState {
8
+ source: boolean;
9
+ present: boolean;
10
+ changed: boolean;
11
+ /** 起点含属性名前的空白,删除时不会留下双空格。 */
12
+ start: number;
13
+ nameStart: number;
14
+ valueStart: number;
15
+ valueEnd: number;
16
+ end: number;
17
+ }
18
+ export interface XmlElementState extends XmlNodeState {
19
+ openRaw: string;
20
+ closeRaw: string;
21
+ sourceSelfClosing: boolean;
22
+ sourceAttributes: XmlAttribute[];
23
+ namespaces: ReadonlyMap<string, string>;
24
+ }
25
+ export declare const nodeStates: WeakMap<XmlNode | XmlDocument, XmlNodeState>;
26
+ export declare const elementStates: WeakMap<XmlElement, XmlElementState>;
27
+ export declare const attributeStates: WeakMap<XmlAttribute, XmlAttributeState>;
28
+ export declare function nodeState(node: XmlDocument | XmlNode): XmlNodeState;
29
+ export declare function elementState(element: XmlElement): XmlElementState;
30
+ export declare function markXmlDirty(node: XmlDocument | XmlNode): void;
@@ -0,0 +1,8 @@
1
+ import type { XmlDocument, XmlNode } from './types';
2
+ export declare function serializeXmlNode(node: XmlNode): string;
3
+ /** 解析为可定点修改的保留型树;不依赖 DOM,可在 Worker 中运行。 */
4
+ export declare function parseXmlTree(source: string | Uint8Array): XmlDocument;
5
+ /** 未修改树逐字节回环;修改后的节点只重写自身最小语法片段。 */
6
+ export declare function serializeXmlTree(document: XmlDocument): string;
7
+ /** 按输入 part 的 UTF-8 / UTF-16 字节序与 BOM 编码;未修改时连原始字节也不重建。 */
8
+ export declare function serializeXmlTreeBytes(document: XmlDocument): Uint8Array;