web-doc 0.6.2 → 0.8.0

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 (201) hide show
  1. package/THIRD_PARTY_NOTICES.md +33 -1
  2. package/dist/adapters/docx-images.d.ts +13 -4
  3. package/dist/adapters/docx-images.js +3 -0
  4. package/dist/adapters/docx-paragraphs.d.ts +65 -0
  5. package/dist/adapters/docx-paragraphs.js +165 -0
  6. package/dist/adapters/docx-prepass.d.ts +17 -0
  7. package/dist/adapters/docx-prepass.js +230 -0
  8. package/dist/adapters/office.d.ts +31 -5
  9. package/dist/adapters/office.js +60 -29
  10. package/dist/adapters/pdf.d.ts +9 -0
  11. package/dist/adapters/pdf.js +10 -0
  12. package/dist/assets/pdfium/pdfium.wasm +0 -0
  13. package/dist/contracts.d.ts +53 -2
  14. package/dist/edit/ai/outline.d.ts +47 -0
  15. package/dist/edit/ai/outline.js +338 -0
  16. package/dist/edit/ai/targets.d.ts +16 -0
  17. package/dist/edit/ai/targets.js +309 -0
  18. package/dist/edit/ai/tools.d.ts +28 -0
  19. package/dist/edit/ai/tools.js +605 -0
  20. package/dist/edit/ai/types.d.ts +175 -0
  21. package/dist/edit/ai/types.js +1 -0
  22. package/dist/edit/assets.d.ts +23 -0
  23. package/dist/edit/assets.js +75 -0
  24. package/dist/edit/docx/elements.d.ts +6 -0
  25. package/dist/edit/docx/elements.js +90 -0
  26. package/dist/edit/docx/engine.d.ts +57 -0
  27. package/dist/edit/docx/engine.js +547 -0
  28. package/dist/edit/docx/handlers.d.ts +3 -0
  29. package/dist/edit/docx/handlers.js +15 -0
  30. package/dist/edit/docx/ids.d.ts +45 -0
  31. package/dist/edit/docx/ids.js +101 -0
  32. package/dist/edit/docx/model.d.ts +94 -0
  33. package/dist/edit/docx/model.js +350 -0
  34. package/dist/edit/docx/operations.d.ts +47 -0
  35. package/dist/edit/docx/operations.js +3 -0
  36. package/dist/edit/docx/provider.d.ts +16 -0
  37. package/dist/edit/docx/provider.js +37 -0
  38. package/dist/edit/docx/schemas.d.ts +6 -0
  39. package/dist/edit/docx/schemas.js +192 -0
  40. package/dist/edit/docx/session.d.ts +48 -0
  41. package/dist/edit/docx/session.js +467 -0
  42. package/dist/edit/docx/structure-ops.d.ts +6 -0
  43. package/dist/edit/docx/structure-ops.js +529 -0
  44. package/dist/edit/docx/style.d.ts +45 -0
  45. package/dist/edit/docx/style.js +375 -0
  46. package/dist/edit/docx/table-ops.d.ts +4 -0
  47. package/dist/edit/docx/table-ops.js +241 -0
  48. package/dist/edit/docx/text-ops.d.ts +40 -0
  49. package/dist/edit/docx/text-ops.js +491 -0
  50. package/dist/edit/docx/text.d.ts +34 -0
  51. package/dist/edit/docx/text.js +284 -0
  52. package/dist/edit/docx/tracked.d.ts +52 -0
  53. package/dist/edit/docx/tracked.js +347 -0
  54. package/dist/edit/docx/types.d.ts +206 -0
  55. package/dist/edit/docx/types.js +1 -0
  56. package/dist/edit/docx/write.d.ts +64 -0
  57. package/dist/edit/docx/write.js +375 -0
  58. package/dist/edit/engine.d.ts +128 -0
  59. package/dist/edit/engine.js +1 -0
  60. package/dist/edit/history.d.ts +77 -0
  61. package/dist/edit/history.js +123 -0
  62. package/dist/edit/ooxml/names.d.ts +20 -0
  63. package/dist/edit/ooxml/names.js +61 -0
  64. package/dist/edit/ooxml/opc.d.ts +50 -0
  65. package/dist/edit/ooxml/opc.js +150 -0
  66. package/dist/edit/ooxml/package.d.ts +82 -0
  67. package/dist/edit/ooxml/package.js +233 -0
  68. package/dist/edit/ooxml/patch.d.ts +51 -0
  69. package/dist/edit/ooxml/patch.js +250 -0
  70. package/dist/edit/ooxml/transaction.d.ts +39 -0
  71. package/dist/edit/ooxml/transaction.js +316 -0
  72. package/dist/edit/ooxml/worker.d.ts +8 -0
  73. package/dist/edit/ooxml/worker.js +12 -0
  74. package/dist/edit/ooxml/writer.d.ts +21 -0
  75. package/dist/edit/ooxml/writer.js +187 -0
  76. package/dist/edit/ooxml/xml.d.ts +74 -0
  77. package/dist/edit/ooxml/xml.js +451 -0
  78. package/dist/edit/ooxml/zip.d.ts +54 -0
  79. package/dist/edit/ooxml/zip.js +280 -0
  80. package/dist/edit/operations.d.ts +19 -0
  81. package/dist/edit/operations.js +137 -0
  82. package/dist/edit/pdf/engine/compact.d.ts +6 -0
  83. package/dist/edit/pdf/engine/compact.js +442 -0
  84. package/dist/edit/pdf/engine/document.d.ts +95 -0
  85. package/dist/edit/pdf/engine/document.js +868 -0
  86. package/dist/edit/pdf/engine/elements.d.ts +45 -0
  87. package/dist/edit/pdf/engine/elements.js +313 -0
  88. package/dist/edit/pdf/engine/existing-text.d.ts +4 -0
  89. package/dist/edit/pdf/engine/existing-text.js +424 -0
  90. package/dist/edit/pdf/engine/fonts.d.ts +78 -0
  91. package/dist/edit/pdf/engine/fonts.js +466 -0
  92. package/dist/edit/pdf/engine/geometry.d.ts +36 -0
  93. package/dist/edit/pdf/engine/geometry.js +97 -0
  94. package/dist/edit/pdf/engine/handler.d.ts +21 -0
  95. package/dist/edit/pdf/engine/handler.js +108 -0
  96. package/dist/edit/pdf/engine/images.d.ts +33 -0
  97. package/dist/edit/pdf/engine/images.js +188 -0
  98. package/dist/edit/pdf/engine/layout.d.ts +23 -0
  99. package/dist/edit/pdf/engine/layout.js +177 -0
  100. package/dist/edit/pdf/engine/operations.d.ts +67 -0
  101. package/dist/edit/pdf/engine/operations.js +3 -0
  102. package/dist/edit/pdf/engine/pages.d.ts +6 -0
  103. package/dist/edit/pdf/engine/pages.js +98 -0
  104. package/dist/edit/pdf/engine/pdfium.d.ts +195 -0
  105. package/dist/edit/pdf/engine/pdfium.js +249 -0
  106. package/dist/edit/pdf/engine/shapes.d.ts +4 -0
  107. package/dist/edit/pdf/engine/shapes.js +183 -0
  108. package/dist/edit/pdf/engine/tables.d.ts +44 -0
  109. package/dist/edit/pdf/engine/tables.js +315 -0
  110. package/dist/edit/pdf/engine/text-box.d.ts +71 -0
  111. package/dist/edit/pdf/engine/text-box.js +317 -0
  112. package/dist/edit/pdf/engine/text-layout.d.ts +28 -0
  113. package/dist/edit/pdf/engine/text-layout.js +67 -0
  114. package/dist/edit/pdf/engine/transform.d.ts +5 -0
  115. package/dist/edit/pdf/engine/transform.js +137 -0
  116. package/dist/edit/pdf/provider.d.ts +35 -0
  117. package/dist/edit/pdf/provider.js +92 -0
  118. package/dist/edit/pdf/range-map.d.ts +16 -0
  119. package/dist/edit/pdf/range-map.js +107 -0
  120. package/dist/edit/pdf/schemas.d.ts +11 -0
  121. package/dist/edit/pdf/schemas.js +291 -0
  122. package/dist/edit/pdf/selection.d.ts +5 -0
  123. package/dist/edit/pdf/selection.js +152 -0
  124. package/dist/edit/pdf/session.d.ts +63 -0
  125. package/dist/edit/pdf/session.js +312 -0
  126. package/dist/edit/pdf/types.d.ts +336 -0
  127. package/dist/edit/pdf/types.js +1 -0
  128. package/dist/edit/pptx/elements.d.ts +74 -0
  129. package/dist/edit/pptx/elements.js +301 -0
  130. package/dist/edit/pptx/engine.d.ts +37 -0
  131. package/dist/edit/pptx/engine.js +466 -0
  132. package/dist/edit/pptx/geometry.d.ts +72 -0
  133. package/dist/edit/pptx/geometry.js +193 -0
  134. package/dist/edit/pptx/handler.d.ts +7 -0
  135. package/dist/edit/pptx/handler.js +99 -0
  136. package/dist/edit/pptx/handlers.d.ts +3 -0
  137. package/dist/edit/pptx/handlers.js +21 -0
  138. package/dist/edit/pptx/image-table-ops.d.ts +5 -0
  139. package/dist/edit/pptx/image-table-ops.js +233 -0
  140. package/dist/edit/pptx/model.d.ts +69 -0
  141. package/dist/edit/pptx/model.js +170 -0
  142. package/dist/edit/pptx/operations.d.ts +50 -0
  143. package/dist/edit/pptx/operations.js +11 -0
  144. package/dist/edit/pptx/provider.d.ts +17 -0
  145. package/dist/edit/pptx/provider.js +40 -0
  146. package/dist/edit/pptx/schemas.d.ts +6 -0
  147. package/dist/edit/pptx/schemas.js +220 -0
  148. package/dist/edit/pptx/session.d.ts +54 -0
  149. package/dist/edit/pptx/session.js +145 -0
  150. package/dist/edit/pptx/shape-ops.d.ts +10 -0
  151. package/dist/edit/pptx/shape-ops.js +486 -0
  152. package/dist/edit/pptx/slide-ops.d.ts +6 -0
  153. package/dist/edit/pptx/slide-ops.js +353 -0
  154. package/dist/edit/pptx/style.d.ts +31 -0
  155. package/dist/edit/pptx/style.js +181 -0
  156. package/dist/edit/pptx/text-ops.d.ts +13 -0
  157. package/dist/edit/pptx/text-ops.js +267 -0
  158. package/dist/edit/pptx/text-write.d.ts +67 -0
  159. package/dist/edit/pptx/text-write.js +293 -0
  160. package/dist/edit/pptx/text.d.ts +41 -0
  161. package/dist/edit/pptx/text.js +99 -0
  162. package/dist/edit/pptx/types.d.ts +232 -0
  163. package/dist/edit/pptx/types.js +1 -0
  164. package/dist/edit/schema.d.ts +11 -0
  165. package/dist/edit/schema.js +275 -0
  166. package/dist/edit/session.d.ts +77 -0
  167. package/dist/edit/session.js +943 -0
  168. package/dist/edit/sessions.d.ts +8 -0
  169. package/dist/edit/sessions.js +1 -0
  170. package/dist/edit/types.d.ts +290 -0
  171. package/dist/edit/types.js +1 -0
  172. package/dist/edit/worker-engine.d.ts +31 -0
  173. package/dist/edit/worker-engine.js +91 -0
  174. package/dist/fonts/THIRD_PARTY_NOTICES.md +3 -0
  175. package/dist/fonts/manifest.json +6 -1
  176. package/dist/fonts/noto-sans-latin-cyrillic.ttf +0 -0
  177. package/dist/fonts.d.ts +2 -0
  178. package/dist/fonts.js +4 -0
  179. package/dist/fuzzy-alignment.d.ts +11 -4
  180. package/dist/fuzzy-alignment.js +3 -9
  181. package/dist/headless.d.ts +5 -1
  182. package/dist/headless.js +8 -1
  183. package/dist/index.d.ts +10 -2
  184. package/dist/index.js +16 -2
  185. package/dist/limits.js +6 -0
  186. package/dist/ooxml-edit-worker.d.ts +1 -0
  187. package/dist/ooxml-edit-worker.js +8 -0
  188. package/dist/pdf-edit-worker.d.ts +1 -0
  189. package/dist/pdf-edit-worker.js +35 -0
  190. package/dist/spreadsheet-viewport.d.ts +5 -0
  191. package/dist/spreadsheet-viewport.js +11 -0
  192. package/dist/ui.js +7 -0
  193. package/dist/viewer.d.ts +6 -0
  194. package/dist/viewer.js +293 -19
  195. package/dist/viewport.d.ts +13 -0
  196. package/dist/viewport.js +126 -1
  197. package/dist/worker-protocol.d.ts +39 -2
  198. package/dist/workers/fuzzy-search-worker.js +1 -1
  199. package/dist/workers/ooxml-edit-worker.js +9212 -0
  200. package/dist/workers/pdf-edit-worker.js +10847 -0
  201. package/package.json +3 -3
@@ -0,0 +1,74 @@
1
+ import type { OoxmlPackage } from "../ooxml/package.js";
2
+ import type { XmlElement, XmlPart } from "../ooxml/xml.js";
3
+ import { type Matrix, type PlacedFrame, type Xfrm } from "./geometry.js";
4
+ import type { DeckModel, SlideRecord } from "./model.js";
5
+ import { type StyleSource } from "./style.js";
6
+ import { type TextModel } from "./text.js";
7
+ import type { PptxElement, PptxPlaceholder } from "./types.js";
8
+ /** What the engine knows about one element beyond what it reports. */
9
+ export interface ShapeRecord {
10
+ readonly element: PptxElement;
11
+ readonly slide: SlideRecord;
12
+ readonly part: XmlPart;
13
+ /** The element node in the slide part (`p:sp`, `p:pic`, …). */
14
+ readonly node: XmlElement;
15
+ readonly cNvPr: XmlElement;
16
+ readonly cNvPrId: number;
17
+ /** The element's own `a:xfrm` or `p:xfrm` node, when it has one. */
18
+ readonly xfrmNode?: XmlElement;
19
+ /** The frame in the element's own space (EMU), inherited when `inherited` is true. */
20
+ readonly xfrm?: Xfrm;
21
+ readonly inherited: boolean;
22
+ /** Transform from the element's space to slide space. */
23
+ readonly parents: Matrix;
24
+ readonly placed?: PlacedFrame;
25
+ readonly txBody?: XmlElement;
26
+ readonly spPr?: XmlElement;
27
+ readonly text?: TextModel;
28
+ /** Inside the fallback branch of `mc:AlternateContent`. */
29
+ readonly readOnly: boolean;
30
+ readonly parent?: ShapeRecord;
31
+ }
32
+ export interface SlideElements {
33
+ readonly slide: SlideRecord;
34
+ readonly pageIndex: number;
35
+ readonly part: XmlPart;
36
+ /** Document order, groups before their children. */
37
+ readonly records: readonly ShapeRecord[];
38
+ byId(id: string): ShapeRecord | undefined;
39
+ }
40
+ /** A placeholder of a layout or master, for inheritance. */
41
+ export interface PlaceholderRecord {
42
+ readonly part: XmlPart;
43
+ readonly node: XmlElement;
44
+ readonly type: string;
45
+ readonly idx?: number;
46
+ readonly xfrm?: Xfrm;
47
+ readonly lstStyle?: XmlElement;
48
+ }
49
+ export interface PlaceholderTable {
50
+ readonly part: XmlPart;
51
+ readonly placeholders: readonly PlaceholderRecord[];
52
+ /** `p:txStyles` of a master. */
53
+ readonly txStyles?: XmlElement;
54
+ }
55
+ /** The placeholders of a layout or master part. */
56
+ export declare function readPlaceholders(pkg: OoxmlPackage, partName: string, signal?: AbortSignal): Promise<PlaceholderTable>;
57
+ export declare function placeholderOf(part: XmlPart, node: XmlElement): PptxPlaceholder | undefined;
58
+ /** Placeholder types that share position and style: titles, and body-like content. */
59
+ export declare function placeholderFamily(type: string): string;
60
+ /** The placeholder a slide placeholder inherits from: same idx first, then the same family. */
61
+ export declare function matchPlaceholder(table: PlaceholderTable | undefined, ph: PptxPlaceholder): PlaceholderRecord | undefined;
62
+ export interface InheritanceSources {
63
+ layout?: PlaceholderTable;
64
+ master?: PlaceholderTable;
65
+ /** `p:defaultTextStyle` of the presentation. */
66
+ defaults?: StyleSource;
67
+ }
68
+ /** Reads every element of a slide. */
69
+ export declare function readSlideElements(pkg: OoxmlPackage, model: DeckModel, slide: SlideRecord, pageIndex: number, sources: InheritanceSources, signal?: AbortSignal): Promise<SlideElements>;
70
+ /** The list-style chain of a shape, in priority order. */
71
+ export declare function listStylesOf(context: {
72
+ readonly part: XmlPart;
73
+ readonly sources: InheritanceSources;
74
+ }, txBody: XmlElement, placeholder: PptxPlaceholder | undefined): StyleSource[];
@@ -0,0 +1,301 @@
1
+ import { groupMatrix, IDENTITY, multiply, placeFrame, readXfrm, } from "./geometry.js";
2
+ import { resolveTextStyle, readShapeStyle } from "./style.js";
3
+ import { firstTextRun, readTableCells, readTextModel, } from "./text.js";
4
+ /*
5
+ * The elements of a slide, read from its XML: every child of the shape tree
6
+ * with its frame (own, or inherited from the layout and master for a
7
+ * placeholder, mapped through enclosing groups), its text and its styles.
8
+ */
9
+ const TABLE_URI = "http://schemas.openxmlformats.org/drawingml/2006/table";
10
+ /** The placeholders of a layout or master part. */
11
+ export async function readPlaceholders(pkg, partName, signal) {
12
+ const part = await pkg.xml(partName, signal);
13
+ const placeholders = [];
14
+ const spTree = part.find("spTree");
15
+ if (spTree)
16
+ for (const node of spTree.children) {
17
+ if (node.local !== "sp")
18
+ continue;
19
+ const ph = placeholderOf(part, node);
20
+ if (!ph)
21
+ continue;
22
+ const spPr = node.children.find((child) => child.local === "spPr");
23
+ const xfrm = readXfrm(part, spPr?.children.find((child) => child.local === "xfrm"));
24
+ const txBody = node.children.find((child) => child.local === "txBody");
25
+ const lstStyle = txBody?.children.find((child) => child.local === "lstStyle");
26
+ placeholders.push({
27
+ part,
28
+ node,
29
+ type: ph.type,
30
+ ...(ph.idx !== undefined ? { idx: ph.idx } : {}),
31
+ ...(xfrm ? { xfrm } : {}),
32
+ ...(lstStyle ? { lstStyle } : {}),
33
+ });
34
+ }
35
+ const txStyles = part.find("txStyles");
36
+ return { part, placeholders, ...(txStyles ? { txStyles } : {}) };
37
+ }
38
+ export function placeholderOf(part, node) {
39
+ const nv = node.children.find((child) => child.local.startsWith("nv") && child.local.endsWith("Pr"));
40
+ const nvPr = nv?.children.find((child) => child.local === "nvPr");
41
+ const ph = nvPr?.children.find((child) => child.local === "ph");
42
+ if (!ph)
43
+ return undefined;
44
+ const idxValue = part.attribute(ph, "idx");
45
+ const idx = idxValue === undefined ? undefined : Number(idxValue);
46
+ return {
47
+ type: part.attribute(ph, "type") ?? "body",
48
+ ...(idx !== undefined && Number.isInteger(idx) ? { idx } : {}),
49
+ };
50
+ }
51
+ /** Placeholder types that share position and style: titles, and body-like content. */
52
+ export function placeholderFamily(type) {
53
+ switch (type) {
54
+ case "title":
55
+ case "ctrTitle":
56
+ return "title";
57
+ case "body":
58
+ case "subTitle":
59
+ case "obj":
60
+ return "body";
61
+ default:
62
+ return type;
63
+ }
64
+ }
65
+ /** The placeholder a slide placeholder inherits from: same idx first, then the same family. */
66
+ export function matchPlaceholder(table, ph) {
67
+ if (!table)
68
+ return undefined;
69
+ const family = placeholderFamily(ph.type);
70
+ if (ph.idx !== undefined) {
71
+ const byIdx = table.placeholders.filter((item) => item.idx === ph.idx);
72
+ const same = byIdx.find((item) => placeholderFamily(item.type) === family);
73
+ if (same)
74
+ return same;
75
+ if (byIdx[0] && family === "body")
76
+ return byIdx[0];
77
+ }
78
+ return table.placeholders.find((item) => placeholderFamily(item.type) === family);
79
+ }
80
+ /** Reads every element of a slide. */
81
+ export async function readSlideElements(pkg, model, slide, pageIndex, sources, signal) {
82
+ const part = await pkg.xml(slide.part, signal);
83
+ const fonts = await model.themeFonts(slide.layout?.master);
84
+ const walk = { records: [], counts: new Map() };
85
+ const spTree = part.find("spTree");
86
+ const context = { slide, pageIndex, part, sources, fonts };
87
+ if (spTree)
88
+ walkTree(context, spTree, IDENTITY, undefined, false, walk);
89
+ const byId = new Map(walk.records.map((record) => [record.element.id, record]));
90
+ return {
91
+ slide,
92
+ pageIndex,
93
+ part,
94
+ records: walk.records,
95
+ byId: (id) => byId.get(id),
96
+ };
97
+ }
98
+ function walkTree(context, container, parents, parent, readOnly, walk) {
99
+ for (const node of container.children) {
100
+ switch (node.local) {
101
+ case "sp":
102
+ case "pic":
103
+ case "graphicFrame":
104
+ case "cxnSp":
105
+ case "grpSp": {
106
+ const record = readRecord(context, node, parents, parent, readOnly, walk);
107
+ if (!record)
108
+ break;
109
+ walk.records.push(record);
110
+ if (node.local === "grpSp")
111
+ walkTree(context, node, record.xfrm ? multiply(parents, groupMatrix(record.xfrm)) : parents, record, readOnly, walk);
112
+ break;
113
+ }
114
+ case "AlternateContent": {
115
+ const fallback = node.children.find((child) => child.local === "Fallback");
116
+ if (fallback)
117
+ walkTree(context, fallback, parents, parent, true, walk);
118
+ break;
119
+ }
120
+ default:
121
+ break;
122
+ }
123
+ }
124
+ }
125
+ function readRecord(context, node, parents, parent, readOnly, walk) {
126
+ const { part, slide } = context;
127
+ const nv = node.children.find((child) => child.local.startsWith("nv") && child.local.endsWith("Pr"));
128
+ const cNvPr = nv?.children.find((child) => child.local === "cNvPr");
129
+ if (!cNvPr)
130
+ return undefined;
131
+ const cNvPrId = Number(part.attribute(cNvPr, "id") ?? NaN);
132
+ if (!Number.isInteger(cNvPrId))
133
+ return undefined;
134
+ const seen = (walk.counts.get(cNvPrId) ?? 0) + 1;
135
+ walk.counts.set(cNvPrId, seen);
136
+ const id = `${slide.key}:${cNvPrId}${seen > 1 ? `#${seen}` : ""}`;
137
+ const name = part.attribute(cNvPr, "name") ?? "";
138
+ const hidden = part.attribute(cNvPr, "hidden") === "1";
139
+ const placeholder = placeholderOf(part, node);
140
+ let kind;
141
+ let xfrmHolder;
142
+ switch (node.local) {
143
+ case "sp":
144
+ kind = "shape";
145
+ xfrmHolder = node.children.find((child) => child.local === "spPr");
146
+ break;
147
+ case "pic":
148
+ kind = "image";
149
+ xfrmHolder = node.children.find((child) => child.local === "spPr");
150
+ break;
151
+ case "cxnSp":
152
+ kind = "connector";
153
+ xfrmHolder = node.children.find((child) => child.local === "spPr");
154
+ break;
155
+ case "grpSp":
156
+ kind = "group";
157
+ xfrmHolder = node.children.find((child) => child.local === "grpSpPr");
158
+ break;
159
+ default: {
160
+ const data = node.children
161
+ .find((child) => child.local === "graphic")
162
+ ?.children.find((child) => child.local === "graphicData");
163
+ kind =
164
+ data && part.attribute(data, "uri") === TABLE_URI ? "table" : "other";
165
+ xfrmHolder = node;
166
+ break;
167
+ }
168
+ }
169
+ const xfrmNode = node.local === "graphicFrame"
170
+ ? node.children.find((child) => child.local === "xfrm")
171
+ : xfrmHolder?.children.find((child) => child.local === "xfrm");
172
+ let xfrm = readXfrm(part, xfrmNode);
173
+ let inherited = false;
174
+ if (!xfrm && placeholder && !parent) {
175
+ xfrm =
176
+ matchPlaceholder(context.sources.layout, placeholder)?.xfrm ??
177
+ matchPlaceholder(context.sources.master, placeholder)?.xfrm;
178
+ inherited = xfrm !== undefined;
179
+ }
180
+ const placed = xfrm ? placeFrame(xfrm, parents) : undefined;
181
+ const spPr = node.children.find((child) => child.local === "spPr");
182
+ const txBody = kind === "shape"
183
+ ? node.children.find((child) => child.local === "txBody")
184
+ : undefined;
185
+ const text = txBody ? readTextModel(part, txBody) : undefined;
186
+ const zero = { x: 0, y: 0, width: 0, height: 0 };
187
+ const bounds = placed?.bounds ?? zero;
188
+ const operations = readOnly ? [] : operationsFor(kind, txBody !== undefined);
189
+ let elementText = text?.text;
190
+ let table;
191
+ if (kind === "table") {
192
+ const tbl = part.find("tbl", node);
193
+ const rows = tbl
194
+ ? readTableCells(part, tbl).map((row) => row.map((cell) => cell.model.text))
195
+ : [];
196
+ table = { rows };
197
+ elementText = rows.map((row) => row.join("\t")).join("\n");
198
+ }
199
+ const element = {
200
+ id,
201
+ kind,
202
+ pageIndex: context.pageIndex,
203
+ bounds,
204
+ ...(placed && placed.frame.rotation !== 0
205
+ ? { rotation: placed.frame.rotation }
206
+ : {}),
207
+ ...(placed ? { frame: placed.frame } : {}),
208
+ ...(elementText !== undefined ? { text: elementText } : {}),
209
+ ...(parent ? { parentId: parent.element.id } : {}),
210
+ operations,
211
+ name,
212
+ ...(placeholder ? { placeholder } : {}),
213
+ ...(text && txBody
214
+ ? { textStyle: textStyleOf(context, placeholder, txBody, text) }
215
+ : {}),
216
+ ...(kind === "shape" || kind === "connector"
217
+ ? { shapeStyle: readShapeStyle(part, spPr) }
218
+ : {}),
219
+ ...(table ? { table } : {}),
220
+ ...(hidden ? { hidden: true } : {}),
221
+ };
222
+ return {
223
+ element,
224
+ slide,
225
+ part,
226
+ node,
227
+ cNvPr,
228
+ cNvPrId,
229
+ ...(xfrmNode ? { xfrmNode } : {}),
230
+ ...(xfrm ? { xfrm } : {}),
231
+ inherited,
232
+ parents,
233
+ ...(placed ? { placed } : {}),
234
+ ...(txBody ? { txBody } : {}),
235
+ ...(spPr ? { spPr } : {}),
236
+ ...(text ? { text } : {}),
237
+ readOnly,
238
+ ...(parent ? { parent } : {}),
239
+ };
240
+ }
241
+ function operationsFor(kind, hasText) {
242
+ const geometry = ["moveElement", "resizeElement", "deleteElement"];
243
+ switch (kind) {
244
+ case "shape":
245
+ return [
246
+ ...(hasText ? ["replaceText", "setTextStyle"] : []),
247
+ "setShapeStyle",
248
+ ...geometry,
249
+ ];
250
+ case "connector":
251
+ return ["setShapeStyle", ...geometry];
252
+ case "table":
253
+ return ["setTableCell", ...geometry];
254
+ default:
255
+ return geometry;
256
+ }
257
+ }
258
+ /** The list-style chain of a shape, in priority order. */
259
+ export function listStylesOf(context, txBody, placeholder) {
260
+ const lists = [];
261
+ const own = txBody.children.find((child) => child.local === "lstStyle");
262
+ if (own)
263
+ lists.push({ part: context.part, node: own });
264
+ const { layout, master, defaults } = context.sources;
265
+ if (placeholder) {
266
+ const fromLayout = matchPlaceholder(layout, placeholder);
267
+ if (fromLayout?.lstStyle)
268
+ lists.push({ part: fromLayout.part, node: fromLayout.lstStyle });
269
+ const fromMaster = matchPlaceholder(master, placeholder);
270
+ if (fromMaster?.lstStyle)
271
+ lists.push({ part: fromMaster.part, node: fromMaster.lstStyle });
272
+ }
273
+ if (master?.txStyles) {
274
+ const family = placeholder ? placeholderFamily(placeholder.type) : "other";
275
+ const styleName = family === "title"
276
+ ? "titleStyle"
277
+ : family === "body"
278
+ ? "bodyStyle"
279
+ : "otherStyle";
280
+ const style = master.txStyles.children.find((child) => child.local === styleName);
281
+ if (style)
282
+ lists.push({ part: master.part, node: style });
283
+ }
284
+ if (defaults)
285
+ lists.push(defaults);
286
+ return lists;
287
+ }
288
+ function textStyleOf(context, placeholder, txBody, text) {
289
+ const first = firstTextRun(text);
290
+ const paragraph = first?.paragraph ?? text.paragraphs[0];
291
+ const rPr = first?.run.rPr ?? paragraph?.endParaRPr;
292
+ return resolveTextStyle({
293
+ ...(rPr ? { rPr: { part: context.part, node: rPr } } : {}),
294
+ ...(paragraph?.pPr
295
+ ? { pPr: { part: context.part, node: paragraph.pPr } }
296
+ : {}),
297
+ level: paragraph?.level ?? 0,
298
+ lists: listStylesOf(context, txBody, placeholder),
299
+ fonts: context.fonts,
300
+ });
301
+ }
@@ -0,0 +1,37 @@
1
+ import type { ResourceLimits } from "../../contracts.js";
2
+ import type { EditEngine, EngineBatch, EngineChange, MaterializedDocument, MaterializeOptions, RestoreTarget } from "../engine.js";
3
+ import { OoxmlPackage } from "../ooxml/package.js";
4
+ import type { EditFindOptions, EditOperation, ElementQuery, OperationIssue, PagePoint, TextTarget } from "../types.js";
5
+ import { DeckModel } from "./model.js";
6
+ import type { PptxElement, PptxLayoutInfo, PptxSlideInfo } from "./types.js";
7
+ /** The reads behind `getSlides` and `getLayouts`, beyond the core engine interface. */
8
+ export interface PptxEngineReads {
9
+ slides(signal: AbortSignal): Promise<readonly PptxSlideInfo[]>;
10
+ layouts(signal: AbortSignal): Promise<readonly PptxLayoutInfo[]>;
11
+ }
12
+ export declare class PptxEditEngine implements EditEngine, PptxEngineReads {
13
+ #private;
14
+ readonly schemas: import("../types.js").OperationSchemaSet;
15
+ private constructor();
16
+ /** Opens the package and reads the deck index, so a broken deck fails here. */
17
+ static open(bytes: Uint8Array, limits: ResourceLimits, signal?: AbortSignal): Promise<PptxEditEngine>;
18
+ /** The package behind the engine, for tests and the operations. */
19
+ get package(): OoxmlPackage;
20
+ get pageCount(): number;
21
+ /** The deck index at the current revision. */
22
+ model(signal?: AbortSignal): Promise<DeckModel>;
23
+ validate(operations: readonly EditOperation[], signal: AbortSignal): Promise<readonly OperationIssue[]>;
24
+ /** Plain operation arrays, as the unit tests pass them, become the next batch. */
25
+ apply(input: EngineBatch | readonly EditOperation[], signal: AbortSignal): Promise<EngineChange>;
26
+ materialize(purposeOrSignal?: "show" | "save" | AbortSignal, options?: MaterializeOptions, signal?: AbortSignal): Promise<Uint8Array>;
27
+ materializeDocument(purposeOrSignal?: "show" | "save" | AbortSignal, _options?: MaterializeOptions, signal?: AbortSignal): Promise<MaterializedDocument>;
28
+ restore(input: RestoreTarget | readonly (readonly EditOperation[])[], signal: AbortSignal): Promise<void>;
29
+ putAsset(id: string, data: Uint8Array, _signal: AbortSignal): Promise<void>;
30
+ getElements(query: ElementQuery, signal: AbortSignal): Promise<readonly PptxElement[]>;
31
+ getElement(id: string, signal: AbortSignal): Promise<PptxElement | undefined>;
32
+ elementsAt(pageIndex: number, point: PagePoint, signal: AbortSignal): Promise<readonly PptxElement[]>;
33
+ findText(query: string, options: EditFindOptions, signal: AbortSignal): Promise<readonly TextTarget[]>;
34
+ slides(signal: AbortSignal): Promise<readonly PptxSlideInfo[]>;
35
+ layouts(signal: AbortSignal): Promise<readonly PptxLayoutInfo[]>;
36
+ dispose(): Promise<void>;
37
+ }