pptx-vanilla-viewer 0.5.1 → 0.6.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.
- package/CHANGELOG.md +2 -0
- package/README.md +10 -3
- package/dist/index.cjs +343 -97
- package/dist/index.d.ts +7941 -2051
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +343 -97
- package/dist/styles.css +1141 -0
- package/package.json +8 -6
- package/dist/index.d.cts +0 -2918
package/dist/index.d.cts
DELETED
|
@@ -1,2918 +0,0 @@
|
|
|
1
|
-
import { n, o, m, P, a, e, f, X, p, q, r, s, t, u, v, w, x, y, z, A, B, D, E, F, G, H, J, K, L, i, j, l, k, g, h, a0, ca } from './presentation-BfnrtJV1.js';
|
|
2
|
-
export { a as PptxElement, P as PptxSlide } from './presentation-BfnrtJV1.js';
|
|
3
|
-
import { ViewerTheme } from './theme/index.js';
|
|
4
|
-
export { ViewerTheme, ViewerThemeColors, defaultCssVars, defaultRadius, defaultThemeColors, themeToCssVars, vermilionDarkTheme, vermilionLightTheme } from './theme/index.js';
|
|
5
|
-
export { TranslationKey, keyToLabel, translationsEn } from 'pptx-viewer-shared/i18n';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Built-in theme presets modelled after common PowerPoint themes.
|
|
9
|
-
*
|
|
10
|
-
* Each preset provides:
|
|
11
|
-
* - A display name
|
|
12
|
-
* - A 12-colour scheme (dk1, dk2, lt1, lt2, accent1-6, hlink, folHlink)
|
|
13
|
-
* - A font scheme (major/heading + minor/body font families)
|
|
14
|
-
*
|
|
15
|
-
* These presets can be passed directly to
|
|
16
|
-
* {@link PptxHandlerCore.switchTheme} or the React `useThemeSwitching` hook
|
|
17
|
-
* to apply a complete theme in one step.
|
|
18
|
-
*
|
|
19
|
-
* @module pptx-types/theme-presets
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* A complete theme preset that can be applied to a presentation.
|
|
24
|
-
*
|
|
25
|
-
* @example
|
|
26
|
-
* ```ts
|
|
27
|
-
* import { THEME_PRESETS } from "pptx-viewer-core";
|
|
28
|
-
*
|
|
29
|
-
* const office = THEME_PRESETS.find(p => p.id === "office");
|
|
30
|
-
* await handler.switchTheme(office.colorScheme, office.fontScheme, office.name);
|
|
31
|
-
* ```
|
|
32
|
-
*/
|
|
33
|
-
interface PptxThemePreset {
|
|
34
|
-
/** Unique identifier for the preset. */
|
|
35
|
-
id: string;
|
|
36
|
-
/** Human-readable display name. */
|
|
37
|
-
name: string;
|
|
38
|
-
/** The 12-colour scheme. */
|
|
39
|
-
colorScheme: e;
|
|
40
|
-
/** Heading and body font families. */
|
|
41
|
-
fontScheme: f;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* SDK input types for the headless PPTX builder API.
|
|
46
|
-
*
|
|
47
|
-
* These types provide a simplified, ergonomic interface for creating
|
|
48
|
-
* presentation elements programmatically. Internal types (PptxElement,
|
|
49
|
-
* ShapeStyle, TextStyle) are the canonical model; these types are
|
|
50
|
-
* convenience wrappers that get mapped to the internal model by
|
|
51
|
-
* the builder functions.
|
|
52
|
-
*
|
|
53
|
-
* @module sdk/types
|
|
54
|
-
*/
|
|
55
|
-
|
|
56
|
-
/** Position and size in pixels. Converted to EMU internally when needed. */
|
|
57
|
-
interface ElementPosition {
|
|
58
|
-
x: number;
|
|
59
|
-
y: number;
|
|
60
|
-
width: number;
|
|
61
|
-
height: number;
|
|
62
|
-
rotation?: number;
|
|
63
|
-
}
|
|
64
|
-
type FillInput = {
|
|
65
|
-
type: 'solid';
|
|
66
|
-
color: string;
|
|
67
|
-
opacity?: number;
|
|
68
|
-
} | {
|
|
69
|
-
type: 'gradient';
|
|
70
|
-
angle?: number;
|
|
71
|
-
gradientType?: 'linear' | 'radial';
|
|
72
|
-
stops: Array<{
|
|
73
|
-
color: string;
|
|
74
|
-
position: number;
|
|
75
|
-
opacity?: number;
|
|
76
|
-
}>;
|
|
77
|
-
} | {
|
|
78
|
-
type: 'pattern';
|
|
79
|
-
preset: string;
|
|
80
|
-
foreground?: string;
|
|
81
|
-
background?: string;
|
|
82
|
-
} | {
|
|
83
|
-
type: 'image';
|
|
84
|
-
url: string;
|
|
85
|
-
mode?: 'stretch' | 'tile';
|
|
86
|
-
} | {
|
|
87
|
-
type: 'none';
|
|
88
|
-
};
|
|
89
|
-
interface StrokeInput {
|
|
90
|
-
color?: string;
|
|
91
|
-
width?: number;
|
|
92
|
-
dash?: i;
|
|
93
|
-
opacity?: number;
|
|
94
|
-
join?: 'round' | 'bevel' | 'miter';
|
|
95
|
-
cap?: 'flat' | 'rnd' | 'sq';
|
|
96
|
-
}
|
|
97
|
-
interface ShadowInput {
|
|
98
|
-
color?: string;
|
|
99
|
-
blur?: number;
|
|
100
|
-
offsetX?: number;
|
|
101
|
-
offsetY?: number;
|
|
102
|
-
opacity?: number;
|
|
103
|
-
}
|
|
104
|
-
interface TextStyleInput {
|
|
105
|
-
fontSize?: number;
|
|
106
|
-
fontFamily?: string;
|
|
107
|
-
bold?: boolean;
|
|
108
|
-
italic?: boolean;
|
|
109
|
-
underline?: boolean;
|
|
110
|
-
strikethrough?: boolean;
|
|
111
|
-
color?: string;
|
|
112
|
-
alignment?: 'left' | 'center' | 'right' | 'justify';
|
|
113
|
-
verticalAlignment?: 'top' | 'middle' | 'bottom';
|
|
114
|
-
lineSpacing?: number;
|
|
115
|
-
spaceBefore?: number;
|
|
116
|
-
spaceAfter?: number;
|
|
117
|
-
}
|
|
118
|
-
interface TextSegmentInput {
|
|
119
|
-
text: string;
|
|
120
|
-
style?: Partial<TextStyleInput>;
|
|
121
|
-
}
|
|
122
|
-
interface TextOptions extends Partial<ElementPosition> {
|
|
123
|
-
fontSize?: number;
|
|
124
|
-
fontFamily?: string;
|
|
125
|
-
bold?: boolean;
|
|
126
|
-
italic?: boolean;
|
|
127
|
-
underline?: boolean;
|
|
128
|
-
strikethrough?: boolean;
|
|
129
|
-
color?: string;
|
|
130
|
-
alignment?: 'left' | 'center' | 'right' | 'justify';
|
|
131
|
-
verticalAlignment?: 'top' | 'middle' | 'bottom';
|
|
132
|
-
lineSpacing?: number;
|
|
133
|
-
fill?: FillInput;
|
|
134
|
-
stroke?: StrokeInput;
|
|
135
|
-
shadow?: ShadowInput;
|
|
136
|
-
opacity?: number;
|
|
137
|
-
}
|
|
138
|
-
interface ShapeOptions extends Partial<ElementPosition> {
|
|
139
|
-
fill?: FillInput;
|
|
140
|
-
stroke?: StrokeInput;
|
|
141
|
-
text?: string;
|
|
142
|
-
textStyle?: Partial<TextStyleInput>;
|
|
143
|
-
adjustments?: Record<string, number>;
|
|
144
|
-
shadow?: ShadowInput;
|
|
145
|
-
opacity?: number;
|
|
146
|
-
}
|
|
147
|
-
interface ImageOptions extends Partial<ElementPosition> {
|
|
148
|
-
altText?: string;
|
|
149
|
-
cropLeft?: number;
|
|
150
|
-
cropTop?: number;
|
|
151
|
-
cropRight?: number;
|
|
152
|
-
cropBottom?: number;
|
|
153
|
-
opacity?: number;
|
|
154
|
-
}
|
|
155
|
-
interface TableInput {
|
|
156
|
-
rows: TableRowInput[];
|
|
157
|
-
columnWidths?: number[];
|
|
158
|
-
style?: string;
|
|
159
|
-
bandRows?: boolean;
|
|
160
|
-
bandColumns?: boolean;
|
|
161
|
-
firstRow?: boolean;
|
|
162
|
-
lastRow?: boolean;
|
|
163
|
-
firstCol?: boolean;
|
|
164
|
-
lastCol?: boolean;
|
|
165
|
-
}
|
|
166
|
-
interface TableRowInput {
|
|
167
|
-
cells: TableCellInput[];
|
|
168
|
-
height?: number;
|
|
169
|
-
}
|
|
170
|
-
interface TableCellInput {
|
|
171
|
-
text: string;
|
|
172
|
-
style?: Partial<TextStyleInput>;
|
|
173
|
-
fill?: FillInput;
|
|
174
|
-
gridSpan?: number;
|
|
175
|
-
rowSpan?: number;
|
|
176
|
-
}
|
|
177
|
-
interface TableOptions extends Partial<ElementPosition> {
|
|
178
|
-
}
|
|
179
|
-
interface ChartSeriesInput {
|
|
180
|
-
name: string;
|
|
181
|
-
values: number[];
|
|
182
|
-
color?: string;
|
|
183
|
-
}
|
|
184
|
-
interface ChartInput {
|
|
185
|
-
series: ChartSeriesInput[];
|
|
186
|
-
categories: string[];
|
|
187
|
-
title?: string;
|
|
188
|
-
hasLegend?: boolean;
|
|
189
|
-
legendPosition?: 't' | 'b' | 'l' | 'r' | 'tr';
|
|
190
|
-
grouping?: 'clustered' | 'stacked' | 'percentStacked';
|
|
191
|
-
}
|
|
192
|
-
interface ChartOptions extends Partial<ElementPosition> {
|
|
193
|
-
}
|
|
194
|
-
interface ConnectorOptions extends Partial<ElementPosition> {
|
|
195
|
-
type?: 'straight' | 'bent' | 'curved';
|
|
196
|
-
stroke?: StrokeInput;
|
|
197
|
-
startArrow?: j;
|
|
198
|
-
endArrow?: j;
|
|
199
|
-
from?: {
|
|
200
|
-
elementId: string;
|
|
201
|
-
site: number;
|
|
202
|
-
};
|
|
203
|
-
to?: {
|
|
204
|
-
elementId: string;
|
|
205
|
-
site: number;
|
|
206
|
-
};
|
|
207
|
-
}
|
|
208
|
-
interface MediaOptions extends Partial<ElementPosition> {
|
|
209
|
-
autoPlay?: boolean;
|
|
210
|
-
loop?: boolean;
|
|
211
|
-
volume?: number;
|
|
212
|
-
trimStartMs?: number;
|
|
213
|
-
trimEndMs?: number;
|
|
214
|
-
posterFrame?: string;
|
|
215
|
-
}
|
|
216
|
-
interface GroupOptions extends Partial<ElementPosition> {
|
|
217
|
-
}
|
|
218
|
-
type BackgroundInput = {
|
|
219
|
-
type: 'solid';
|
|
220
|
-
color: string;
|
|
221
|
-
} | {
|
|
222
|
-
type: 'gradient';
|
|
223
|
-
angle?: number;
|
|
224
|
-
stops: Array<{
|
|
225
|
-
color: string;
|
|
226
|
-
position: number;
|
|
227
|
-
}>;
|
|
228
|
-
} | {
|
|
229
|
-
type: 'image';
|
|
230
|
-
source: string;
|
|
231
|
-
};
|
|
232
|
-
interface TransitionInput {
|
|
233
|
-
type: k;
|
|
234
|
-
duration?: number;
|
|
235
|
-
direction?: string;
|
|
236
|
-
advanceAfterMs?: number;
|
|
237
|
-
}
|
|
238
|
-
interface AnimationInput {
|
|
239
|
-
preset: g;
|
|
240
|
-
trigger?: h;
|
|
241
|
-
duration?: number;
|
|
242
|
-
delay?: number;
|
|
243
|
-
}
|
|
244
|
-
interface PresentationOptions {
|
|
245
|
-
/** Slide width in EMU. Default: 12192000 (16:9 widescreen). */
|
|
246
|
-
width?: number;
|
|
247
|
-
/** Slide height in EMU. Default: 6858000 (16:9 widescreen). */
|
|
248
|
-
height?: number;
|
|
249
|
-
/** Theme configuration. */
|
|
250
|
-
theme?: PresentationThemeInput;
|
|
251
|
-
/** Presentation title (stored in docProps/core.xml). */
|
|
252
|
-
title?: string;
|
|
253
|
-
/** Presentation author. */
|
|
254
|
-
creator?: string;
|
|
255
|
-
/**
|
|
256
|
-
* Number of blank slides to include in the initial presentation.
|
|
257
|
-
* Default: 0 (no slides). Slides use the "Blank" layout.
|
|
258
|
-
*/
|
|
259
|
-
initialSlideCount?: number;
|
|
260
|
-
}
|
|
261
|
-
interface PresentationThemeInput {
|
|
262
|
-
name?: string;
|
|
263
|
-
colors?: {
|
|
264
|
-
dk1?: string;
|
|
265
|
-
lt1?: string;
|
|
266
|
-
dk2?: string;
|
|
267
|
-
lt2?: string;
|
|
268
|
-
accent1?: string;
|
|
269
|
-
accent2?: string;
|
|
270
|
-
accent3?: string;
|
|
271
|
-
accent4?: string;
|
|
272
|
-
accent5?: string;
|
|
273
|
-
accent6?: string;
|
|
274
|
-
hlink?: string;
|
|
275
|
-
folHlink?: string;
|
|
276
|
-
};
|
|
277
|
-
fonts?: {
|
|
278
|
-
majorFont?: string;
|
|
279
|
-
minorFont?: string;
|
|
280
|
-
};
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
/**
|
|
284
|
-
* Fluent builder for constructing slides with elements.
|
|
285
|
-
*
|
|
286
|
-
* Provides a chainable API for adding elements, setting slide properties,
|
|
287
|
-
* and building a complete {@link PptxSlide}.
|
|
288
|
-
*
|
|
289
|
-
* @module sdk/SlideBuilder
|
|
290
|
-
*/
|
|
291
|
-
|
|
292
|
-
/**
|
|
293
|
-
* Fluent builder for a single slide.
|
|
294
|
-
*
|
|
295
|
-
* @example
|
|
296
|
-
* ```ts
|
|
297
|
-
* const slide = new SlideBuilder(1)
|
|
298
|
-
* .addText("Hello World", { fontSize: 36, bold: true, x: 100, y: 50 })
|
|
299
|
-
* .addShape("roundRect", { fill: { type: "solid", color: "#4472C4" } })
|
|
300
|
-
* .setNotes("Remember to mention key points")
|
|
301
|
-
* .setBackground({ type: "solid", color: "#F5F5F5" })
|
|
302
|
-
* .build();
|
|
303
|
-
* ```
|
|
304
|
-
*/
|
|
305
|
-
declare class SlideBuilder {
|
|
306
|
-
private readonly slide;
|
|
307
|
-
/**
|
|
308
|
-
* @param slideNumber - 1-based slide number.
|
|
309
|
-
* @param layoutPath - Optional layout archive path.
|
|
310
|
-
* @param layoutName - Optional layout display name.
|
|
311
|
-
*/
|
|
312
|
-
constructor(slideNumber: number, layoutPath?: string, layoutName?: string);
|
|
313
|
-
/** Add a text box to the slide. */
|
|
314
|
-
addText(text: string | TextSegmentInput[], options?: TextOptions): this;
|
|
315
|
-
/** Add a shape to the slide. */
|
|
316
|
-
addShape(shapeType: string, options?: ShapeOptions): this;
|
|
317
|
-
/** Add a connector (line) to the slide. */
|
|
318
|
-
addConnector(options?: ConnectorOptions): this;
|
|
319
|
-
/** Add an image to the slide. */
|
|
320
|
-
addImage(source: string, options?: ImageOptions): this;
|
|
321
|
-
/** Add a table to the slide. */
|
|
322
|
-
addTable(input: TableInput, options?: TableOptions): this;
|
|
323
|
-
/** Add a chart to the slide. */
|
|
324
|
-
addChart(chartType: l, input: ChartInput, options?: ChartOptions): this;
|
|
325
|
-
/** Add a media element (video or audio) to the slide. */
|
|
326
|
-
addMedia(mediaType: 'video' | 'audio', source: string, options?: MediaOptions): this;
|
|
327
|
-
/** Add a group of elements to the slide. */
|
|
328
|
-
addGroup(children: a[], options?: GroupOptions): this;
|
|
329
|
-
/** Add a pre-built element directly. */
|
|
330
|
-
addElement(element: a): this;
|
|
331
|
-
/** Set slide background. */
|
|
332
|
-
setBackground(bg: BackgroundInput): this;
|
|
333
|
-
/** Set slide transition. */
|
|
334
|
-
setTransition(input: TransitionInput): this;
|
|
335
|
-
/** Add an animation to an element on this slide. */
|
|
336
|
-
addAnimation(elementId: string, input: AnimationInput): this;
|
|
337
|
-
/** Set speaker notes. */
|
|
338
|
-
setNotes(text: string): this;
|
|
339
|
-
/** Mark the slide as hidden. */
|
|
340
|
-
setHidden(hidden: boolean): this;
|
|
341
|
-
/** Assign the slide to a section. */
|
|
342
|
-
setSection(name: string, id?: string): this;
|
|
343
|
-
/**
|
|
344
|
-
* Add a freeform shape from SVG path data.
|
|
345
|
-
*
|
|
346
|
-
* Creates a custom-geometry shape element using the provided SVG path
|
|
347
|
-
* string and appends it to the slide's element list.
|
|
348
|
-
*
|
|
349
|
-
* @param pathData - An SVG path data string (e.g. `"M 0 0 L 100 50 L 50 100 Z"`).
|
|
350
|
-
* @param options - Optional position, styling, and size overrides.
|
|
351
|
-
* @returns The builder instance for chaining.
|
|
352
|
-
*
|
|
353
|
-
* @example
|
|
354
|
-
* ```ts
|
|
355
|
-
* new SlideBuilder(1)
|
|
356
|
-
* .addFreeform("M 0 0 C 33 0 66 100 100 100", {
|
|
357
|
-
* stroke: { color: "#FF0000", width: 2 },
|
|
358
|
-
* })
|
|
359
|
-
* .build();
|
|
360
|
-
* ```
|
|
361
|
-
*/
|
|
362
|
-
addFreeform(pathData: string, options?: ShapeOptions): this;
|
|
363
|
-
/**
|
|
364
|
-
* Add a pre-built element from any element builder (calls `.build()` for you).
|
|
365
|
-
*
|
|
366
|
-
* Accepts any object with a `build()` method that returns a {@link PptxElement},
|
|
367
|
-
* such as {@link TextBuilder}, {@link ShapeBuilder}, {@link ImageBuilder}, etc.
|
|
368
|
-
*
|
|
369
|
-
* @param builder - An element builder with a `.build()` method.
|
|
370
|
-
* @returns The builder instance for chaining.
|
|
371
|
-
*
|
|
372
|
-
* @example
|
|
373
|
-
* ```ts
|
|
374
|
-
* const title = TextBuilder.create("Hello").fontSize(36).bold();
|
|
375
|
-
* new SlideBuilder(1).addBuilderElement(title).build();
|
|
376
|
-
* ```
|
|
377
|
-
*/
|
|
378
|
-
addBuilderElement(builder: {
|
|
379
|
-
build(): a;
|
|
380
|
-
}): this;
|
|
381
|
-
/**
|
|
382
|
-
* Remove an element by its ID.
|
|
383
|
-
*
|
|
384
|
-
* Filters out the element with the given ID from the slide's element list.
|
|
385
|
-
* If no element matches, the slide is left unchanged.
|
|
386
|
-
*
|
|
387
|
-
* @param elementId - The unique ID of the element to remove.
|
|
388
|
-
* @returns The builder instance for chaining.
|
|
389
|
-
*
|
|
390
|
-
* @example
|
|
391
|
-
* ```ts
|
|
392
|
-
* const slide = new SlideBuilder(1)
|
|
393
|
-
* .addText("temp", { x: 0, y: 0 })
|
|
394
|
-
* .removeElement("txt_abc123_1")
|
|
395
|
-
* .build();
|
|
396
|
-
* ```
|
|
397
|
-
*/
|
|
398
|
-
removeElement(elementId: string): this;
|
|
399
|
-
/**
|
|
400
|
-
* Get the current list of elements on this slide.
|
|
401
|
-
*
|
|
402
|
-
* Returns a readonly view of the elements array. Useful for inspecting
|
|
403
|
-
* what has been added so far during the build process.
|
|
404
|
-
*
|
|
405
|
-
* @returns A readonly array of the slide's current elements.
|
|
406
|
-
*
|
|
407
|
-
* @example
|
|
408
|
-
* ```ts
|
|
409
|
-
* const builder = new SlideBuilder(1).addText("Hi");
|
|
410
|
-
* console.log(builder.getElements().length); // 1
|
|
411
|
-
* ```
|
|
412
|
-
*/
|
|
413
|
-
getElements(): readonly a[];
|
|
414
|
-
/**
|
|
415
|
-
* Get the number of elements on this slide.
|
|
416
|
-
*
|
|
417
|
-
* @returns The count of elements currently added to the slide.
|
|
418
|
-
*
|
|
419
|
-
* @example
|
|
420
|
-
* ```ts
|
|
421
|
-
* const builder = new SlideBuilder(1)
|
|
422
|
-
* .addText("A").addText("B");
|
|
423
|
-
* console.log(builder.elementCount); // 2
|
|
424
|
-
* ```
|
|
425
|
-
*/
|
|
426
|
-
get elementCount(): number;
|
|
427
|
-
/**
|
|
428
|
-
* Get the last added element (useful for getting its ID for animations).
|
|
429
|
-
*
|
|
430
|
-
* Returns `undefined` if the slide has no elements yet.
|
|
431
|
-
*
|
|
432
|
-
* @returns The most recently added element, or `undefined`.
|
|
433
|
-
*
|
|
434
|
-
* @example
|
|
435
|
-
* ```ts
|
|
436
|
-
* const builder = new SlideBuilder(1).addShape("rect");
|
|
437
|
-
* const shape = builder.getLastElement();
|
|
438
|
-
* if (shape) {
|
|
439
|
-
* builder.addAnimation(shape.id, { preset: "fadeIn" });
|
|
440
|
-
* }
|
|
441
|
-
* ```
|
|
442
|
-
*/
|
|
443
|
-
getLastElement(): a | undefined;
|
|
444
|
-
/**
|
|
445
|
-
* Set the slide name/title for organizational purposes.
|
|
446
|
-
*
|
|
447
|
-
* Stores an arbitrary name string on the slide object. This is useful
|
|
448
|
-
* for labeling slides in tooling or custom workflows.
|
|
449
|
-
*
|
|
450
|
-
* @param name - The display name to assign to the slide.
|
|
451
|
-
* @returns The builder instance for chaining.
|
|
452
|
-
*
|
|
453
|
-
* @example
|
|
454
|
-
* ```ts
|
|
455
|
-
* new SlideBuilder(1)
|
|
456
|
-
* .setName("Introduction")
|
|
457
|
-
* .addText("Welcome!")
|
|
458
|
-
* .build();
|
|
459
|
-
* ```
|
|
460
|
-
*/
|
|
461
|
-
setName(name: string): this;
|
|
462
|
-
/** Return the built {@link PptxSlide}. */
|
|
463
|
-
build(): P;
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
/**
|
|
467
|
-
* Factory for creating PPTX presentations from scratch.
|
|
468
|
-
*
|
|
469
|
-
* Generates a minimal valid OpenXML package (ZIP) containing all
|
|
470
|
-
* required parts (presentation.xml, theme, slide master, layouts,
|
|
471
|
-
* content types, relationships, and document properties). The
|
|
472
|
-
* generated package is then loaded by {@link PptxHandler} so that
|
|
473
|
-
* all existing editing and save operations work transparently.
|
|
474
|
-
*
|
|
475
|
-
* @module sdk/PresentationBuilder
|
|
476
|
-
*/
|
|
477
|
-
|
|
478
|
-
/** Result returned by {@link PresentationBuilder.create}. */
|
|
479
|
-
interface PresentationBuilderResult {
|
|
480
|
-
/** Initialized handler ready for editing and saving. */
|
|
481
|
-
handler: PptxHandler;
|
|
482
|
-
/** Parsed presentation data. */
|
|
483
|
-
data: m;
|
|
484
|
-
/** Convenience slide builder factory. */
|
|
485
|
-
createSlide: (layoutName?: string) => SlideBuilder;
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
/**
|
|
489
|
-
* Fluent interface for navigating and mutating a {@link PptxData} structure.
|
|
490
|
-
* Provides method-chaining access to slides, elements, and notes.
|
|
491
|
-
*/
|
|
492
|
-
interface IPptxXmlBuilder {
|
|
493
|
-
/** Navigate to a slide by zero-based index (Pascal-case alias). */
|
|
494
|
-
Slides(index: number): PptxSlideBuilder;
|
|
495
|
-
/** Navigate to a slide by zero-based index. */
|
|
496
|
-
slide(index: number): PptxSlideBuilder;
|
|
497
|
-
/** Navigate to a slide by zero-based index (plural alias). */
|
|
498
|
-
slides(index: number): PptxSlideBuilder;
|
|
499
|
-
/** Return the underlying presentation data. */
|
|
500
|
-
project(): m;
|
|
501
|
-
}
|
|
502
|
-
/**
|
|
503
|
-
* Root builder of the fluent PPTX editing API.
|
|
504
|
-
*
|
|
505
|
-
* Wraps a {@link PptxData} object and provides chainable accessors
|
|
506
|
-
* to navigate into slides, elements, and notes for in-place mutation.
|
|
507
|
-
*/
|
|
508
|
-
declare class PptxXmlBuilder implements IPptxXmlBuilder {
|
|
509
|
-
/** The presentation data being mutated. */
|
|
510
|
-
private readonly data;
|
|
511
|
-
/** @param data - The presentation data to wrap. */
|
|
512
|
-
constructor(data: m);
|
|
513
|
-
/**
|
|
514
|
-
* Factory method to create a builder from presentation data.
|
|
515
|
-
* @param data - The presentation data to wrap.
|
|
516
|
-
* @returns A new {@link PptxXmlBuilder} instance.
|
|
517
|
-
*/
|
|
518
|
-
static from(data: m): PptxXmlBuilder;
|
|
519
|
-
/** @inheritdoc */
|
|
520
|
-
Slides(index: number): PptxSlideBuilder;
|
|
521
|
-
/**
|
|
522
|
-
* Navigate to a slide by zero-based index.
|
|
523
|
-
* @param index - Zero-based slide index.
|
|
524
|
-
* @returns A {@link PptxSlideBuilder} for the requested slide.
|
|
525
|
-
* @throws Error if index is not an integer or is out of range.
|
|
526
|
-
*/
|
|
527
|
-
slide(index: number): PptxSlideBuilder;
|
|
528
|
-
/** @inheritdoc */
|
|
529
|
-
slides(index: number): PptxSlideBuilder;
|
|
530
|
-
/** Return the underlying {@link PptxData}. */
|
|
531
|
-
project(): m;
|
|
532
|
-
/** Pascal-case alias for {@link project}. */
|
|
533
|
-
Project(): m;
|
|
534
|
-
}
|
|
535
|
-
/**
|
|
536
|
-
* Fluent builder scoped to a single slide.
|
|
537
|
-
* Provides navigation to the slide's elements and notes.
|
|
538
|
-
*/
|
|
539
|
-
declare class PptxSlideBuilder {
|
|
540
|
-
/** The slide being operated on. */
|
|
541
|
-
private readonly slideValue;
|
|
542
|
-
/** Reference back to the root builder for chaining. */
|
|
543
|
-
private readonly rootBuilder;
|
|
544
|
-
/**
|
|
545
|
-
* @param slideValue - The slide data.
|
|
546
|
-
* @param rootBuilder - The parent builder.
|
|
547
|
-
*/
|
|
548
|
-
constructor(slideValue: P, rootBuilder: PptxXmlBuilder);
|
|
549
|
-
/** Navigate to the slide's notes builder (getter). */
|
|
550
|
-
get Notes(): PptxSlideNotesBuilder;
|
|
551
|
-
/** Navigate to the slide's notes builder. */
|
|
552
|
-
notes(): PptxSlideNotesBuilder;
|
|
553
|
-
/** Navigate to the slide's elements builder. */
|
|
554
|
-
elements(): PptxSlideElementsBuilder;
|
|
555
|
-
/** Return the underlying slide data. */
|
|
556
|
-
project(): P;
|
|
557
|
-
/** Pascal-case alias for {@link project}. */
|
|
558
|
-
Project(): P;
|
|
559
|
-
/** Navigate back to the root builder. */
|
|
560
|
-
done(): PptxXmlBuilder;
|
|
561
|
-
/** Pascal-case alias for {@link done}. */
|
|
562
|
-
Done(): PptxXmlBuilder;
|
|
563
|
-
}
|
|
564
|
-
/**
|
|
565
|
-
* Fluent builder for manipulating the elements array of a single slide.
|
|
566
|
-
* Supports adding, removing, and updating elements by ID.
|
|
567
|
-
*/
|
|
568
|
-
declare class PptxSlideElementsBuilder {
|
|
569
|
-
private readonly slideValue;
|
|
570
|
-
private readonly slideBuilder;
|
|
571
|
-
/**
|
|
572
|
-
* @param slideValue - The slide whose elements are being modified.
|
|
573
|
-
* @param slideBuilder - The parent slide builder for chaining.
|
|
574
|
-
*/
|
|
575
|
-
constructor(slideValue: P, slideBuilder: PptxSlideBuilder);
|
|
576
|
-
/**
|
|
577
|
-
* Append an element to the slide's element list.
|
|
578
|
-
* @param element - The element to add.
|
|
579
|
-
* @returns This builder for chaining.
|
|
580
|
-
*/
|
|
581
|
-
add(element: a): this;
|
|
582
|
-
/**
|
|
583
|
-
* Remove an element from the slide by its ID.
|
|
584
|
-
* @param elementId - The ID of the element to remove.
|
|
585
|
-
* @returns This builder for chaining.
|
|
586
|
-
*/
|
|
587
|
-
removeById(elementId: string): this;
|
|
588
|
-
/**
|
|
589
|
-
* Update an element in-place by ID using a transform function.
|
|
590
|
-
* @param elementId - The ID of the element to update.
|
|
591
|
-
* @param updater - A function that receives the current element and returns the replacement.
|
|
592
|
-
* @returns This builder for chaining.
|
|
593
|
-
*/
|
|
594
|
-
updateById(elementId: string, updater: (current: a) => a): this;
|
|
595
|
-
/** Return the current elements array. */
|
|
596
|
-
project(): a[];
|
|
597
|
-
/** Navigate back to the slide builder. */
|
|
598
|
-
done(): PptxSlideBuilder;
|
|
599
|
-
}
|
|
600
|
-
/**
|
|
601
|
-
* Fluent builder for manipulating speaker notes on a single slide.
|
|
602
|
-
* Supports adding, setting, clearing, and retrieving notes text.
|
|
603
|
-
*/
|
|
604
|
-
declare class PptxSlideNotesBuilder {
|
|
605
|
-
private readonly slideValue;
|
|
606
|
-
private readonly slideBuilder;
|
|
607
|
-
/**
|
|
608
|
-
* @param slideValue - The slide whose notes are being modified.
|
|
609
|
-
* @param slideBuilder - The parent slide builder for chaining.
|
|
610
|
-
*/
|
|
611
|
-
constructor(slideValue: P, slideBuilder: PptxSlideBuilder);
|
|
612
|
-
/**
|
|
613
|
-
* Append text to existing notes (separated by newline).
|
|
614
|
-
* @param text - The text to append.
|
|
615
|
-
* @returns This builder for chaining.
|
|
616
|
-
*/
|
|
617
|
-
add(text: string): this;
|
|
618
|
-
/** Pascal-case alias for {@link add}. */
|
|
619
|
-
Add(text: string): this;
|
|
620
|
-
/**
|
|
621
|
-
* Replace all notes with the given text.
|
|
622
|
-
* @param text - The replacement notes text. Empty string clears notes.
|
|
623
|
-
* @returns This builder for chaining.
|
|
624
|
-
*/
|
|
625
|
-
set(text: string): this;
|
|
626
|
-
/** Pascal-case alias for {@link set}. */
|
|
627
|
-
Set(text: string): this;
|
|
628
|
-
/** Remove all notes from the slide. */
|
|
629
|
-
clear(): this;
|
|
630
|
-
/** Pascal-case alias for {@link clear}. */
|
|
631
|
-
Clear(): this;
|
|
632
|
-
/** Return the current notes text, or `undefined` if none. */
|
|
633
|
-
get(): string | undefined;
|
|
634
|
-
/** Pascal-case alias for {@link get}. */
|
|
635
|
-
Get(): string | undefined;
|
|
636
|
-
/** Navigate back to the slide builder. */
|
|
637
|
-
done(): PptxSlideBuilder;
|
|
638
|
-
/** Pascal-case alias for {@link done}. */
|
|
639
|
-
Done(): PptxSlideBuilder;
|
|
640
|
-
/**
|
|
641
|
-
* Synchronize the `notesSegments` array from the plain-text notes string.
|
|
642
|
-
* Splits text on newlines and creates corresponding {@link TextSegment} entries
|
|
643
|
-
* with paragraph break markers between lines.
|
|
644
|
-
*/
|
|
645
|
-
private syncSegmentsFromNotes;
|
|
646
|
-
}
|
|
647
|
-
|
|
648
|
-
interface PptxHandlerLoadOptions {
|
|
649
|
-
eagerDecodeImages?: boolean;
|
|
650
|
-
password?: string;
|
|
651
|
-
/**
|
|
652
|
-
* Maximum total uncompressed bytes accepted from the input ZIP archive.
|
|
653
|
-
* Defaults to 500 MiB. When the sum of `_data.uncompressedSize` across
|
|
654
|
-
* all archive entries exceeds this cap, `load()` rejects with a
|
|
655
|
-
* {@link ZipBombError}. A hard cap of 65 536 archive entries also
|
|
656
|
-
* applies.
|
|
657
|
-
*/
|
|
658
|
-
maxUncompressedBytes?: number;
|
|
659
|
-
/**
|
|
660
|
-
* When `false` (default), relationship targets that resolve to
|
|
661
|
-
* `http://` or `https://` URLs are dropped from rendered slides
|
|
662
|
-
* (image, picture, background). Set to `true` to allow external image
|
|
663
|
-
* URLs to flow through to `<img src>`.
|
|
664
|
-
*
|
|
665
|
-
* Disabled by default to mitigate SSRF / privacy-leak vectors in
|
|
666
|
-
* server-side rendering and headless export pipelines.
|
|
667
|
-
*/
|
|
668
|
-
allowExternalImages?: boolean;
|
|
669
|
-
}
|
|
670
|
-
/** Output format for the save pipeline. */
|
|
671
|
-
type PptxSaveFormat = 'pptx' | 'ppsx' | 'pptm';
|
|
672
|
-
interface PptxHandlerSaveOptions {
|
|
673
|
-
headerFooter?: r;
|
|
674
|
-
presentationProperties?: s;
|
|
675
|
-
customShows?: t[];
|
|
676
|
-
sections?: u[];
|
|
677
|
-
coreProperties?: v;
|
|
678
|
-
appProperties?: w;
|
|
679
|
-
customProperties?: x[];
|
|
680
|
-
/** Updated notes master data to save back to notesMaster1.xml. */
|
|
681
|
-
notesMaster?: y;
|
|
682
|
-
/** Updated handout master data to save back to handoutMaster1.xml. */
|
|
683
|
-
handoutMaster?: z;
|
|
684
|
-
/**
|
|
685
|
-
* Updated slide masters to save back to ppt/slideMasters/slideMaster*.xml.
|
|
686
|
-
* Each entry in the array applies typed mutations (clrMap, hf flags,
|
|
687
|
-
* background) to the master at its `path`. Masters not listed here pass
|
|
688
|
-
* through verbatim from the original load.
|
|
689
|
-
*/
|
|
690
|
-
slideMasters?: A[];
|
|
691
|
-
/**
|
|
692
|
-
* Updated slide layouts to save back to ppt/slideLayouts/slideLayout*.xml.
|
|
693
|
-
* Each entry applies typed mutations (clrMapOverride, attrs, hf flags,
|
|
694
|
-
* background) to the layout at its `path`. Layouts not listed here pass
|
|
695
|
-
* through verbatim from the original load.
|
|
696
|
-
*/
|
|
697
|
-
slideLayouts?: B[];
|
|
698
|
-
/** Updated tag collections to save back to ppt/tags/tag*.xml. */
|
|
699
|
-
tags?: D[];
|
|
700
|
-
/** Photo album metadata to save back to `p:photoAlbum`. */
|
|
701
|
-
photoAlbum?: E;
|
|
702
|
-
/** East Asian line-break settings to save back to `p:kinsoku`. */
|
|
703
|
-
kinsoku?: F;
|
|
704
|
-
/** Write-protection verifier. Set to `null` to remove, `undefined` to preserve existing. */
|
|
705
|
-
modifyVerifier?: G | null;
|
|
706
|
-
/** View properties to save back to ppt/viewProps.xml. */
|
|
707
|
-
viewProperties?: H;
|
|
708
|
-
/**
|
|
709
|
-
* Table style edits to save back to `ppt/tableStyles.xml`. Pass the
|
|
710
|
-
* `tableStyleMap` from `PptxData` (optionally with edited entries)
|
|
711
|
-
* to persist user edits. The `def` GUID and any unmodelled XML are
|
|
712
|
-
* preserved verbatim. Omitting the option round-trips the original
|
|
713
|
-
* part untouched.
|
|
714
|
-
*/
|
|
715
|
-
tableStyles?: J;
|
|
716
|
-
/**
|
|
717
|
-
* Target output format.
|
|
718
|
-
* - `'pptx'` (default): Standard presentation.
|
|
719
|
-
* - `'ppsx'`: Slide-show file (opens in presentation mode).
|
|
720
|
-
* - `'pptm'`: Macro-enabled presentation (requires VBA data).
|
|
721
|
-
*/
|
|
722
|
-
outputFormat?: PptxSaveFormat;
|
|
723
|
-
/**
|
|
724
|
-
* Embedded fonts to write back (or add) to the saved PPTX.
|
|
725
|
-
*
|
|
726
|
-
* Pass the `embeddedFonts` array from `PptxData` to preserve existing
|
|
727
|
-
* embedded fonts during save. You can also add new fonts by including
|
|
728
|
-
* entries with `rawFontData` populated.
|
|
729
|
-
*
|
|
730
|
-
* When omitted, the save pipeline will automatically re-embed any
|
|
731
|
-
* fonts that were loaded from the original PPTX and have `rawFontData`
|
|
732
|
-
* preserved (i.e. the default is lossless round-trip).
|
|
733
|
-
*/
|
|
734
|
-
embeddedFonts?: K[];
|
|
735
|
-
/**
|
|
736
|
-
* OOXML conformance class for the saved output.
|
|
737
|
-
* - `'preserve'` (default): use the same conformance as the loaded file.
|
|
738
|
-
* - `'strict'`: force Strict Open XML (ISO/IEC 29500) namespace URIs.
|
|
739
|
-
* - `'transitional'`: force Transitional (ECMA-376) namespace URIs.
|
|
740
|
-
*/
|
|
741
|
-
conformance?: 'strict' | 'transitional' | 'preserve';
|
|
742
|
-
}
|
|
743
|
-
interface IPptxHandlerRuntime {
|
|
744
|
-
/**
|
|
745
|
-
* Release all resources held by this runtime (Blob URLs, caches, ZIP).
|
|
746
|
-
* After calling, the runtime cannot be used further.
|
|
747
|
-
*/
|
|
748
|
-
dispose(): void;
|
|
749
|
-
/**
|
|
750
|
-
* Revoke all Blob URLs created during image loading.
|
|
751
|
-
*/
|
|
752
|
-
revokeBlobUrls(): void;
|
|
753
|
-
getCompatibilityWarnings(): n[];
|
|
754
|
-
getLayoutOptions(): o[];
|
|
755
|
-
createXmlBuilder(data: m): PptxXmlBuilder;
|
|
756
|
-
Builder(data: m): PptxXmlBuilder;
|
|
757
|
-
setTemplateBackground(path: string, backgroundColor: string | undefined): void;
|
|
758
|
-
setPresentationTheme(themePath: string, applyToAllMasters?: boolean): Promise<void>;
|
|
759
|
-
getTemplateBackgroundColor(path: string): string | undefined;
|
|
760
|
-
updateThemeColorScheme(colorScheme: e): Promise<void>;
|
|
761
|
-
updateThemeFontScheme(fontScheme: f): Promise<void>;
|
|
762
|
-
updateThemeName(name: string): Promise<void>;
|
|
763
|
-
applyTheme(colorScheme: e, fontScheme: f, themeName?: string): Promise<void>;
|
|
764
|
-
load(data: ArrayBuffer, options?: PptxHandlerLoadOptions): Promise<m>;
|
|
765
|
-
getChartDataForGraphicFrame(slidePath: string, graphicFrame: X | undefined): Promise<p | undefined>;
|
|
766
|
-
getSmartArtDataForGraphicFrame(slidePath: string, graphicFrame: X | undefined): Promise<q | undefined>;
|
|
767
|
-
getImageData(imagePath: string): Promise<string | undefined>;
|
|
768
|
-
/**
|
|
769
|
-
* Extract a media file from the PPTX archive as an ArrayBuffer.
|
|
770
|
-
* Returns undefined if the file is not found.
|
|
771
|
-
*/
|
|
772
|
-
getMediaArrayBuffer(mediaPath: string): Promise<ArrayBuffer | undefined>;
|
|
773
|
-
save(slides: P[], options?: PptxHandlerSaveOptions): Promise<Uint8Array>;
|
|
774
|
-
exportSlides(slides: P[], options: L): Promise<Map<number, Uint8Array>>;
|
|
775
|
-
/**
|
|
776
|
-
* Get the available slide layouts for a specific slide, based on the
|
|
777
|
-
* slide's master. Scans the slide master's relationships to find all
|
|
778
|
-
* layouts that belong to it.
|
|
779
|
-
*
|
|
780
|
-
* @param slideIndex - Zero-based slide index.
|
|
781
|
-
* @param slides - Current slides array.
|
|
782
|
-
* @returns Array of layout options belonging to the same slide master.
|
|
783
|
-
*/
|
|
784
|
-
getAvailableLayoutsForSlide(slideIndex: number, slides: P[]): Promise<o[]>;
|
|
785
|
-
/**
|
|
786
|
-
* Resolve the editable template (master + layout) elements a slide
|
|
787
|
-
* inherits, each carrying a `master-` / `layout-` prefixed id. Excludes
|
|
788
|
-
* placeholders; returns only decorative shapes/pictures/graphic frames.
|
|
789
|
-
*
|
|
790
|
-
* @param slideId - The slide's archive path (`PptxSlide.id`).
|
|
791
|
-
*/
|
|
792
|
-
getTemplateElementsForSlide(slideId: string): Promise<a[]>;
|
|
793
|
-
/**
|
|
794
|
-
* Scan the loaded PPTX archive for all theme parts.
|
|
795
|
-
*/
|
|
796
|
-
getAvailableThemes(): Promise<Array<{
|
|
797
|
-
path: string;
|
|
798
|
-
name?: string;
|
|
799
|
-
}>>;
|
|
800
|
-
/**
|
|
801
|
-
* Apply a different layout to an existing slide by updating the slide's
|
|
802
|
-
* relationship to point to the new layout and re-parsing layout
|
|
803
|
-
* placeholders / background.
|
|
804
|
-
*
|
|
805
|
-
* @param slideIndex - Zero-based slide index.
|
|
806
|
-
* @param layoutPath - Archive path of the target layout
|
|
807
|
-
* (e.g. `ppt/slideLayouts/slideLayout2.xml`).
|
|
808
|
-
* @param slides - Current slides array.
|
|
809
|
-
* @returns The updated slide with new layout path, name, and background.
|
|
810
|
-
*/
|
|
811
|
-
applyLayoutToSlide(slideIndex: number, layoutPath: string, slides: P[]): Promise<P>;
|
|
812
|
-
}
|
|
813
|
-
|
|
814
|
-
/**
|
|
815
|
-
* Abstract factory contract for creating {@link IPptxHandlerRuntime}
|
|
816
|
-
* instances.
|
|
817
|
-
*
|
|
818
|
-
* Implement this interface to supply a custom runtime (e.g. a
|
|
819
|
-
* WASM-backed or test-double runtime) to {@link PptxHandlerCore}.
|
|
820
|
-
*/
|
|
821
|
-
interface IPptxHandlerRuntimeFactory {
|
|
822
|
-
/** Instantiate and return a new runtime implementation. */
|
|
823
|
-
createRuntime(): IPptxHandlerRuntime;
|
|
824
|
-
}
|
|
825
|
-
|
|
826
|
-
/**
|
|
827
|
-
* Type definitions for OOXML encryption and decryption.
|
|
828
|
-
*
|
|
829
|
-
* Contains all interfaces and type aliases used by the OOXML crypto modules.
|
|
830
|
-
*
|
|
831
|
-
* @module ooxml-crypto-types
|
|
832
|
-
*/
|
|
833
|
-
/** Supported encryption algorithms. */
|
|
834
|
-
type EncryptionAlgorithm = 'AES128' | 'AES256';
|
|
835
|
-
/** Encryption options for creating encrypted files. */
|
|
836
|
-
interface EncryptionOptions {
|
|
837
|
-
/** The encryption algorithm to use (defaults to AES256). */
|
|
838
|
-
algorithm?: EncryptionAlgorithm;
|
|
839
|
-
/** Number of hash iterations for key derivation (defaults to 100000). Lower values speed up tests. */
|
|
840
|
-
spinCount?: number;
|
|
841
|
-
}
|
|
842
|
-
|
|
843
|
-
/**
|
|
844
|
-
* Dependency injection options for {@link PptxHandlerCore}.
|
|
845
|
-
*
|
|
846
|
-
* Provide either `runtime` (an already-constructed runtime) or
|
|
847
|
-
* `runtimeFactory` (a factory that will be called once). When neither
|
|
848
|
-
* is supplied the default runtime is created automatically.
|
|
849
|
-
*
|
|
850
|
-
* @example
|
|
851
|
-
* ```ts
|
|
852
|
-
* // Use the default runtime:
|
|
853
|
-
* const core = new PptxHandlerCore();
|
|
854
|
-
*
|
|
855
|
-
* // Inject a custom runtime:
|
|
856
|
-
* const core = new PptxHandlerCore({ runtime: myRuntime });
|
|
857
|
-
*
|
|
858
|
-
* // Supply a factory for lazy creation:
|
|
859
|
-
* const core = new PptxHandlerCore({ runtimeFactory: myFactory });
|
|
860
|
-
* // => PptxHandlerCore instance with injected runtime
|
|
861
|
-
* ```
|
|
862
|
-
*/
|
|
863
|
-
interface PptxHandlerCoreDependencies {
|
|
864
|
-
runtime?: IPptxHandlerRuntime;
|
|
865
|
-
runtimeFactory?: IPptxHandlerRuntimeFactory;
|
|
866
|
-
}
|
|
867
|
-
/**
|
|
868
|
-
* Thin facade over the PPTX runtime implementation.
|
|
869
|
-
*
|
|
870
|
-
* All heavy parsing, serialisation, and XML manipulation is delegated to an
|
|
871
|
-
* {@link IPptxHandlerRuntime}. This surface stays stable and small so that
|
|
872
|
-
* callers remain decoupled from the runtime internals and host-specific
|
|
873
|
-
* runtime swaps (e.g. WASM vs Node) can be done transparently.
|
|
874
|
-
*
|
|
875
|
-
* @remarks
|
|
876
|
-
* - Constructed once per open document.
|
|
877
|
-
* - Errors from encrypted files are caught at `load()` time via
|
|
878
|
-
* {@link EncryptedFileError}.
|
|
879
|
-
* - `PptxXmlBuilder` instances returned by `createXmlBuilder()` / `Builder()`
|
|
880
|
-
* operate directly on the runtime’s in-memory ZIP.
|
|
881
|
-
*
|
|
882
|
-
* @example
|
|
883
|
-
* ```ts
|
|
884
|
-
* const handler = new PptxHandlerCore();
|
|
885
|
-
* const data = await handler.load(arrayBuffer);
|
|
886
|
-
* // ... mutate slides ...
|
|
887
|
-
* const out = await handler.save(data.slides);
|
|
888
|
-
* // => Uint8Array of the modified .pptx file
|
|
889
|
-
* ```
|
|
890
|
-
*/
|
|
891
|
-
declare class PptxHandlerCore {
|
|
892
|
-
private readonly runtime;
|
|
893
|
-
/**
|
|
894
|
-
* Create a new handler, optionally injecting a custom runtime.
|
|
895
|
-
*
|
|
896
|
-
* Resolution order:
|
|
897
|
-
* 1. `dependencies.runtime` — use as-is.
|
|
898
|
-
* 2. `dependencies.runtimeFactory` — call `createRuntime()` once.
|
|
899
|
-
* 3. Fall back to {@link createDefaultPptxHandlerRuntime}.
|
|
900
|
-
*
|
|
901
|
-
* @param dependencies - Optional runtime or factory override.
|
|
902
|
-
*
|
|
903
|
-
* @example
|
|
904
|
-
* ```ts
|
|
905
|
-
* const core = new PptxHandlerCore();
|
|
906
|
-
* // => PptxHandlerCore instance with default runtime
|
|
907
|
-
* ```
|
|
908
|
-
*/
|
|
909
|
-
constructor(dependencies?: PptxHandlerCoreDependencies);
|
|
910
|
-
/**
|
|
911
|
-
* Release all resources held by this handler instance.
|
|
912
|
-
*
|
|
913
|
-
* Revokes every Blob URL created for images/media, clears all
|
|
914
|
-
* in-memory caches, and releases the in-memory ZIP archive.
|
|
915
|
-
*
|
|
916
|
-
* Call this when the handler is no longer needed (e.g. component
|
|
917
|
-
* unmount) to free memory immediately rather than waiting for GC.
|
|
918
|
-
*
|
|
919
|
-
* After calling `dispose()`, do not call any other methods — create
|
|
920
|
-
* a new `PptxHandler` instance instead.
|
|
921
|
-
*/
|
|
922
|
-
dispose(): void;
|
|
923
|
-
/**
|
|
924
|
-
* Return any compatibility warnings detected during the most recent load.
|
|
925
|
-
*
|
|
926
|
-
* Warnings indicate features the editor cannot fully represent (e.g.
|
|
927
|
-
* SmartArt, 3-D effects, embedded OLE objects).
|
|
928
|
-
*
|
|
929
|
-
* @returns Array of {@link PptxCompatibilityWarning} objects.
|
|
930
|
-
*/
|
|
931
|
-
getCompatibilityWarnings(): n[];
|
|
932
|
-
/**
|
|
933
|
-
* Get the slide layout options available in the loaded presentation.
|
|
934
|
-
*
|
|
935
|
-
* Each option maps to a `<p:sldLayout>` inside the PPTX archive.
|
|
936
|
-
*
|
|
937
|
-
* @returns Array of {@link PptxLayoutOption} entries.
|
|
938
|
-
*/
|
|
939
|
-
getLayoutOptions(): o[];
|
|
940
|
-
/**
|
|
941
|
-
* Create a fluent XML builder scoped to the given presentation data.
|
|
942
|
-
*
|
|
943
|
-
* The builder provides a chainable API for constructing and inserting
|
|
944
|
-
* OpenXML nodes directly into the runtime’s in-memory ZIP.
|
|
945
|
-
*
|
|
946
|
-
* @param data - The parsed {@link PptxData} to bind the builder to.
|
|
947
|
-
* @returns A new {@link PptxXmlBuilder} instance.
|
|
948
|
-
*/
|
|
949
|
-
createXmlBuilder(data: m): PptxXmlBuilder;
|
|
950
|
-
/**
|
|
951
|
-
* Shorthand alias for {@link createXmlBuilder}.
|
|
952
|
-
*
|
|
953
|
-
* @param data - Parsed presentation data.
|
|
954
|
-
* @returns A {@link PptxXmlBuilder} instance.
|
|
955
|
-
*/
|
|
956
|
-
Builder(data: m): PptxXmlBuilder;
|
|
957
|
-
/**
|
|
958
|
-
* Register a background image for a specific template layout path.
|
|
959
|
-
*
|
|
960
|
-
* @param path - The internal PPTX path (e.g. `ppt/slideLayouts/slideLayout1.xml`).
|
|
961
|
-
* @param backgroundColor - Optional hex colour to render behind the image.
|
|
962
|
-
*/
|
|
963
|
-
setTemplateBackground(path: string, backgroundColor: string | undefined): void;
|
|
964
|
-
/**
|
|
965
|
-
* Retrieve the background colour previously set for a template layout.
|
|
966
|
-
*
|
|
967
|
-
* @param path - The internal PPTX layout path.
|
|
968
|
-
* @returns Hex colour string, or `undefined` if none was set.
|
|
969
|
-
*/
|
|
970
|
-
getTemplateBackgroundColor(path: string): string | undefined;
|
|
971
|
-
/**
|
|
972
|
-
* Replace the presentation’s theme by loading an external `.thmx` file.
|
|
973
|
-
*
|
|
974
|
-
* @param themePath - Absolute or relative path to the `.thmx` file.
|
|
975
|
-
* @param applyToAllMasters - Apply to every slide master (default `true`).
|
|
976
|
-
*
|
|
977
|
-
* @example
|
|
978
|
-
* ```ts
|
|
979
|
-
* await handler.setPresentationTheme("./themes/corporate.thmx");
|
|
980
|
-
* // => void — theme XML replaced in the in-memory ZIP
|
|
981
|
-
* ```
|
|
982
|
-
*/
|
|
983
|
-
setPresentationTheme(themePath: string, applyToAllMasters?: boolean): Promise<void>;
|
|
984
|
-
/**
|
|
985
|
-
* Modify the theme’s colour scheme (accent colours, background, text, etc.).
|
|
986
|
-
*
|
|
987
|
-
* @param colorScheme - A {@link PptxThemeColorScheme} with hex colour values.
|
|
988
|
-
*
|
|
989
|
-
* @example
|
|
990
|
-
* ```ts
|
|
991
|
-
* await handler.updateThemeColorScheme({
|
|
992
|
-
* dk1: "#1A1A2E", dk2: "#16213E",
|
|
993
|
-
* lt1: "#FFFFFF", lt2: "#E8E8E8",
|
|
994
|
-
* accent1: "#0F3460", accent2: "#533483",
|
|
995
|
-
* accent3: "#E94560", accent4: "#F0A500",
|
|
996
|
-
* });
|
|
997
|
-
* // => void — colour scheme updated in the in-memory theme XML
|
|
998
|
-
* ```
|
|
999
|
-
*/
|
|
1000
|
-
updateThemeColorScheme(colorScheme: e): Promise<void>;
|
|
1001
|
-
/**
|
|
1002
|
-
* Update the theme’s font scheme (heading + body typefaces).
|
|
1003
|
-
*
|
|
1004
|
-
* @param fontScheme - A {@link PptxThemeFontScheme} with font family names.
|
|
1005
|
-
*
|
|
1006
|
-
* @example
|
|
1007
|
-
* ```ts
|
|
1008
|
-
* await handler.updateThemeFontScheme({
|
|
1009
|
-
* majorFont: "Montserrat",
|
|
1010
|
-
* minorFont: "Open Sans",
|
|
1011
|
-
* });
|
|
1012
|
-
* // => void — font scheme updated in the in-memory theme XML
|
|
1013
|
-
* ```
|
|
1014
|
-
*/
|
|
1015
|
-
updateThemeFontScheme(fontScheme: f): Promise<void>;
|
|
1016
|
-
/**
|
|
1017
|
-
* Rename the presentation theme.
|
|
1018
|
-
*
|
|
1019
|
-
* @param name - New display name for the theme.
|
|
1020
|
-
*/
|
|
1021
|
-
updateThemeName(name: string): Promise<void>;
|
|
1022
|
-
/**
|
|
1023
|
-
* Apply a complete theme in one call (colour scheme + font scheme + optional name).
|
|
1024
|
-
*
|
|
1025
|
-
* This is a convenience wrapper over {@link updateThemeColorScheme},
|
|
1026
|
-
* {@link updateThemeFontScheme}, and {@link updateThemeName}.
|
|
1027
|
-
*
|
|
1028
|
-
* @param colorScheme - Colour definitions.
|
|
1029
|
-
* @param fontScheme - Font definitions.
|
|
1030
|
-
* @param themeName - Optional theme display name.
|
|
1031
|
-
*
|
|
1032
|
-
* @example
|
|
1033
|
-
* ```ts
|
|
1034
|
-
* await handler.applyTheme(
|
|
1035
|
-
* { dk1: "#000", lt1: "#FFF", accent1: "#0066CC", /* … *\/ },
|
|
1036
|
-
* { majorFont: "Helvetica", minorFont: "Arial" },
|
|
1037
|
-
* "Corporate 2025",
|
|
1038
|
-
* );
|
|
1039
|
-
* // => void — colour scheme, font scheme, and name applied atomically
|
|
1040
|
-
* ```
|
|
1041
|
-
*/
|
|
1042
|
-
applyTheme(colorScheme: e, fontScheme: f, themeName?: string): Promise<void>;
|
|
1043
|
-
/**
|
|
1044
|
-
* Switch the presentation's theme, updating both the underlying XML and
|
|
1045
|
-
* re-resolving all element colours in-place.
|
|
1046
|
-
*
|
|
1047
|
-
* This is the high-level API for theme switching: it updates the theme
|
|
1048
|
-
* data in the ZIP, then patches all resolved colours in the provided
|
|
1049
|
-
* `PptxData` so that elements immediately reflect the new colour scheme
|
|
1050
|
-
* without requiring a re-parse.
|
|
1051
|
-
*
|
|
1052
|
-
* @param data - The current parsed presentation data (mutated in-place for
|
|
1053
|
-
* convenience, but a new `PptxData` object is also returned).
|
|
1054
|
-
* @param colorScheme - New colour scheme (12 colours).
|
|
1055
|
-
* @param fontScheme - Optional new font scheme.
|
|
1056
|
-
* @param themeName - Optional theme display name.
|
|
1057
|
-
* @returns The updated PptxData with re-resolved colours.
|
|
1058
|
-
*
|
|
1059
|
-
* @example
|
|
1060
|
-
* ```ts
|
|
1061
|
-
* import { THEME_PRESETS } from "pptx-viewer-core";
|
|
1062
|
-
*
|
|
1063
|
-
* const ion = THEME_PRESETS.find(p => p.id === "ion")!;
|
|
1064
|
-
* const newData = await handler.switchTheme(
|
|
1065
|
-
* data,
|
|
1066
|
-
* ion.colorScheme,
|
|
1067
|
-
* ion.fontScheme,
|
|
1068
|
-
* ion.name,
|
|
1069
|
-
* );
|
|
1070
|
-
* // => PptxData with all colours updated to the Ion theme
|
|
1071
|
-
* ```
|
|
1072
|
-
*/
|
|
1073
|
-
switchTheme(data: m, colorScheme: e, fontScheme?: f, themeName?: string): Promise<m>;
|
|
1074
|
-
/**
|
|
1075
|
-
* Apply a built-in theme preset to the presentation.
|
|
1076
|
-
*
|
|
1077
|
-
* Convenience wrapper around {@link switchTheme} that accepts a
|
|
1078
|
-
* {@link PptxThemePreset} directly.
|
|
1079
|
-
*
|
|
1080
|
-
* @param data - The current parsed presentation data.
|
|
1081
|
-
* @param preset - One of the built-in presets from {@link THEME_PRESETS}.
|
|
1082
|
-
* @returns The updated PptxData.
|
|
1083
|
-
*
|
|
1084
|
-
* @example
|
|
1085
|
-
* ```ts
|
|
1086
|
-
* import { THEME_PRESETS } from "pptx-viewer-core";
|
|
1087
|
-
*
|
|
1088
|
-
* const preset = THEME_PRESETS.find(p => p.id === "facet")!;
|
|
1089
|
-
* const newData = await handler.switchThemePreset(data, preset);
|
|
1090
|
-
* ```
|
|
1091
|
-
*/
|
|
1092
|
-
switchThemePreset(data: m, preset: PptxThemePreset): Promise<m>;
|
|
1093
|
-
/**
|
|
1094
|
-
* Parse a PPTX file from an `ArrayBuffer` and return structured data.
|
|
1095
|
-
*
|
|
1096
|
-
* If the file is encrypted and a `password` is provided in `options`,
|
|
1097
|
-
* the file will be decrypted before parsing. If no password is provided
|
|
1098
|
-
* for an encrypted file, throws {@link EncryptedFileError}.
|
|
1099
|
-
*
|
|
1100
|
-
* @param data - Raw bytes of the `.pptx` file (may be encrypted OLE2).
|
|
1101
|
-
* @param options - Optional load-time settings, including `password`.
|
|
1102
|
-
* @returns Parsed {@link PptxData} containing slides, theme, layouts, etc.
|
|
1103
|
-
*
|
|
1104
|
-
* @example
|
|
1105
|
-
* ```ts
|
|
1106
|
-
* // Load an unencrypted file:
|
|
1107
|
-
* const pptx = await handler.load(buf.buffer);
|
|
1108
|
-
*
|
|
1109
|
-
* // Load a password-protected file:
|
|
1110
|
-
* const pptx = await handler.load(buf.buffer, { password: "secret" });
|
|
1111
|
-
* console.log(`${pptx.slides.length} slides loaded`);
|
|
1112
|
-
* ```
|
|
1113
|
-
*/
|
|
1114
|
-
load(data: ArrayBuffer, options?: PptxHandlerLoadOptions): Promise<m>;
|
|
1115
|
-
/**
|
|
1116
|
-
* Extract chart data from a graphic-frame XML node.
|
|
1117
|
-
*
|
|
1118
|
-
* @param slidePath - Internal archive path of the slide (e.g. `ppt/slides/slide1.xml`).
|
|
1119
|
-
* @param graphicFrame - Parsed XML object for the `<p:graphicFrame>` node.
|
|
1120
|
-
* @returns Chart data, or `undefined` if the frame is not a chart.
|
|
1121
|
-
*/
|
|
1122
|
-
getChartDataForGraphicFrame(slidePath: string, graphicFrame: X | undefined): Promise<p | undefined>;
|
|
1123
|
-
/**
|
|
1124
|
-
* Extract SmartArt data from a graphic-frame XML node.
|
|
1125
|
-
*
|
|
1126
|
-
* @param slidePath - Internal archive path of the slide.
|
|
1127
|
-
* @param graphicFrame - Parsed XML object for the `<p:graphicFrame>` node.
|
|
1128
|
-
* @returns SmartArt data, or `undefined` if the frame is not SmartArt.
|
|
1129
|
-
*/
|
|
1130
|
-
getSmartArtDataForGraphicFrame(slidePath: string, graphicFrame: X | undefined): Promise<q | undefined>;
|
|
1131
|
-
/**
|
|
1132
|
-
* Get the base64-encoded data URL for an embedded image.
|
|
1133
|
-
*
|
|
1134
|
-
* @param imagePath - Archive-relative path (e.g. `ppt/media/image1.png`).
|
|
1135
|
-
* @returns A `data:image/...;base64,...` string, or `undefined` if not found.
|
|
1136
|
-
*/
|
|
1137
|
-
getImageData(imagePath: string): Promise<string | undefined>;
|
|
1138
|
-
/**
|
|
1139
|
-
* Extract a media file from the PPTX archive as an ArrayBuffer.
|
|
1140
|
-
* Avoids the 33% base64 overhead of getImageData — prefer this for
|
|
1141
|
-
* audio/video media that will be played via Blob URLs.
|
|
1142
|
-
*/
|
|
1143
|
-
getMediaArrayBuffer(mediaPath: string): Promise<ArrayBuffer | undefined>;
|
|
1144
|
-
/**
|
|
1145
|
-
* Serialise current slides back into a PPTX byte array.
|
|
1146
|
-
*
|
|
1147
|
-
* @param slides - The (possibly mutated) slide array.
|
|
1148
|
-
* @param options - Optional save-time settings (e.g. thumbnail generation).
|
|
1149
|
-
* @returns `Uint8Array` of the complete `.pptx` file.
|
|
1150
|
-
*
|
|
1151
|
-
* @example
|
|
1152
|
-
* ```ts
|
|
1153
|
-
* const bytes = await handler.save(data.slides);
|
|
1154
|
-
* await fs.writeFile("output.pptx", Buffer.from(bytes));
|
|
1155
|
-
* // => Uint8Array written to disk as a valid .pptx file
|
|
1156
|
-
* ```
|
|
1157
|
-
*/
|
|
1158
|
-
save(slides: P[], options?: PptxHandlerSaveOptions): Promise<Uint8Array>;
|
|
1159
|
-
/**
|
|
1160
|
-
* Serialise slides and then encrypt the output with a password.
|
|
1161
|
-
*
|
|
1162
|
-
* This is a convenience method that calls {@link save} followed by
|
|
1163
|
-
* {@link encryptPptx}. The result is an OLE2 container suitable for
|
|
1164
|
-
* opening in Microsoft PowerPoint with a password prompt.
|
|
1165
|
-
*
|
|
1166
|
-
* @param slides - The (possibly mutated) slide array.
|
|
1167
|
-
* @param password - The password to encrypt with.
|
|
1168
|
-
* @param options - Optional save-time and encryption settings.
|
|
1169
|
-
* @returns `Uint8Array` of the encrypted OLE2 file.
|
|
1170
|
-
*
|
|
1171
|
-
* @example
|
|
1172
|
-
* ```ts
|
|
1173
|
-
* const bytes = await handler.saveEncrypted(data.slides, "secret");
|
|
1174
|
-
* await fs.writeFile("protected.pptx", Buffer.from(bytes));
|
|
1175
|
-
* // => Encrypted OLE2 file requiring password to open
|
|
1176
|
-
* ```
|
|
1177
|
-
*/
|
|
1178
|
-
saveEncrypted(slides: P[], password: string, options?: PptxHandlerSaveOptions & {
|
|
1179
|
-
encryption?: EncryptionOptions;
|
|
1180
|
-
}): Promise<Uint8Array>;
|
|
1181
|
-
/**
|
|
1182
|
-
* Get the slide layouts available for a specific slide.
|
|
1183
|
-
*
|
|
1184
|
-
* Returns layouts belonging to the same slide master as the given slide.
|
|
1185
|
-
* This is useful for building a layout picker UI scoped to the current
|
|
1186
|
-
* slide's master.
|
|
1187
|
-
*
|
|
1188
|
-
* @param slideIndex - Zero-based slide index.
|
|
1189
|
-
* @param slides - Current slides array.
|
|
1190
|
-
* @returns Array of {@link PptxLayoutOption} entries for the slide's master.
|
|
1191
|
-
*
|
|
1192
|
-
* @example
|
|
1193
|
-
* ```ts
|
|
1194
|
-
* const layouts = await handler.getAvailableLayoutsForSlide(0, data.slides);
|
|
1195
|
-
* console.log(layouts.map(l => l.name));
|
|
1196
|
-
* // => ["Title Slide", "Title and Content", "Blank", ...]
|
|
1197
|
-
* ```
|
|
1198
|
-
*/
|
|
1199
|
-
getAvailableLayoutsForSlide(slideIndex: number, slides: P[]): Promise<o[]>;
|
|
1200
|
-
/**
|
|
1201
|
-
* Resolve the editable template (master + layout) elements a slide
|
|
1202
|
-
* inherits, each carrying a `master-` / `layout-` prefixed id.
|
|
1203
|
-
*
|
|
1204
|
-
* This is the foundation for an "edit template/master" feature. The
|
|
1205
|
-
* returned elements are the decorative master/layout shapes the loader
|
|
1206
|
-
* already merges behind slide-authored content (master shapes behind,
|
|
1207
|
-
* layout shapes on top); placeholders are excluded. The same elements are
|
|
1208
|
-
* shared by every slide inheriting the layout/master, so editing one and
|
|
1209
|
-
* saving updates the shared part.
|
|
1210
|
-
*
|
|
1211
|
-
* To persist an edit, keep the mutated template element inside the
|
|
1212
|
-
* `slide.elements` array passed to {@link save}; the save writer reads
|
|
1213
|
-
* template elements from there and writes their shape XML back into the
|
|
1214
|
-
* owning layout/master `p:spTree`.
|
|
1215
|
-
*
|
|
1216
|
-
* @param slideId - The slide's archive path (the `PptxSlide.id`).
|
|
1217
|
-
* @returns Master + layout elements with prefixed ids (may be empty).
|
|
1218
|
-
*
|
|
1219
|
-
* @example
|
|
1220
|
-
* ```ts
|
|
1221
|
-
* const templateEls = await handler.getTemplateElementsForSlide(slide.id);
|
|
1222
|
-
* const logo = templateEls.find((e) => e.id.startsWith("master-"));
|
|
1223
|
-
* if (logo) {
|
|
1224
|
-
* logo.x += 10;
|
|
1225
|
-
* slide.elements = [...slide.elements, logo];
|
|
1226
|
-
* await handler.save(data.slides);
|
|
1227
|
-
* }
|
|
1228
|
-
* ```
|
|
1229
|
-
*/
|
|
1230
|
-
getTemplateElementsForSlide(slideId: string): Promise<a[]>;
|
|
1231
|
-
/**
|
|
1232
|
-
* Apply a different layout to an existing slide.
|
|
1233
|
-
*
|
|
1234
|
-
* Updates the slide's relationship to point to the new layout and
|
|
1235
|
-
* refreshes layout-derived properties (background, layout name).
|
|
1236
|
-
* The slide's own content elements are preserved.
|
|
1237
|
-
*
|
|
1238
|
-
* @param slideIndex - Zero-based slide index.
|
|
1239
|
-
* @param layoutPath - Archive path of the target layout
|
|
1240
|
-
* (e.g. `ppt/slideLayouts/slideLayout2.xml`).
|
|
1241
|
-
* @param slides - Current slides array (the slide at `slideIndex`
|
|
1242
|
-
* is replaced in-place).
|
|
1243
|
-
* @returns The updated {@link PptxSlide} with new layout metadata.
|
|
1244
|
-
*
|
|
1245
|
-
* @example
|
|
1246
|
-
* ```ts
|
|
1247
|
-
* const updated = await handler.applyLayoutToSlide(
|
|
1248
|
-
* 0,
|
|
1249
|
-
* "ppt/slideLayouts/slideLayout3.xml",
|
|
1250
|
-
* data.slides,
|
|
1251
|
-
* );
|
|
1252
|
-
* console.log(updated.layoutName);
|
|
1253
|
-
* // => "Two Content"
|
|
1254
|
-
* ```
|
|
1255
|
-
*/
|
|
1256
|
-
applyLayoutToSlide(slideIndex: number, layoutPath: string, slides: P[]): Promise<P>;
|
|
1257
|
-
/**
|
|
1258
|
-
* Scan the loaded PPTX archive for all theme parts (`ppt/theme/theme*.xml`)
|
|
1259
|
-
* and return their paths and display names.
|
|
1260
|
-
*/
|
|
1261
|
-
getAvailableThemes(): Promise<Array<{
|
|
1262
|
-
path: string;
|
|
1263
|
-
name?: string;
|
|
1264
|
-
}>>;
|
|
1265
|
-
/**
|
|
1266
|
-
* Export selected slides as individual PPTX files.
|
|
1267
|
-
*
|
|
1268
|
-
* Each entry in the returned map is keyed by slide index and contains a
|
|
1269
|
-
* standalone `Uint8Array` PPTX with only that slide.
|
|
1270
|
-
*
|
|
1271
|
-
* @param slides - Full slide array.
|
|
1272
|
-
* @param options - Export options (slide indexes, format, etc.).
|
|
1273
|
-
* @returns A `Map<slideIndex, Uint8Array>` of exported files.
|
|
1274
|
-
*
|
|
1275
|
-
* @example
|
|
1276
|
-
* ```ts
|
|
1277
|
-
* const exports = await handler.exportSlides(data.slides, {
|
|
1278
|
-
* slideIndexes: [0, 2],
|
|
1279
|
-
* });
|
|
1280
|
-
* for (const [idx, bytes] of exports) {
|
|
1281
|
-
* await fs.writeFile(`slide_${idx}.pptx`, Buffer.from(bytes));
|
|
1282
|
-
* }
|
|
1283
|
-
* // => Map<number, Uint8Array> — one standalone .pptx per exported slide
|
|
1284
|
-
* ```
|
|
1285
|
-
*/
|
|
1286
|
-
exportSlides(slides: P[], options: L): Promise<Map<number, Uint8Array>>;
|
|
1287
|
-
}
|
|
1288
|
-
|
|
1289
|
-
/**
|
|
1290
|
-
* Public facade for the PPTX editor handler.
|
|
1291
|
-
*
|
|
1292
|
-
* The implementation lives in `PptxHandlerCore` so this surface can stay small,
|
|
1293
|
-
* stable, and easy to replace with alternate implementations in the future.
|
|
1294
|
-
*/
|
|
1295
|
-
declare class PptxHandler extends PptxHandlerCore {
|
|
1296
|
-
/**
|
|
1297
|
-
* Create a new blank PPTX presentation from scratch.
|
|
1298
|
-
*
|
|
1299
|
-
* This is a convenience static method that delegates to
|
|
1300
|
-
* {@link PresentationBuilder.create}. The returned handler is fully
|
|
1301
|
-
* initialized and ready for editing, adding slides, and saving.
|
|
1302
|
-
*
|
|
1303
|
-
* @param options - Optional slide dimensions, theme, and metadata.
|
|
1304
|
-
* @returns Handler, parsed data, and a slide builder factory.
|
|
1305
|
-
*
|
|
1306
|
-
* @example
|
|
1307
|
-
* ```ts
|
|
1308
|
-
* const { handler, data, createSlide } = await PptxHandler.createBlank({
|
|
1309
|
-
* title: "My Deck",
|
|
1310
|
-
* theme: { colors: { accent1: "#FF6B6B" } },
|
|
1311
|
-
* });
|
|
1312
|
-
*
|
|
1313
|
-
* data.slides.push(
|
|
1314
|
-
* createSlide("Blank")
|
|
1315
|
-
* .addText("Hello", { fontSize: 36 })
|
|
1316
|
-
* .build()
|
|
1317
|
-
* );
|
|
1318
|
-
*
|
|
1319
|
-
* const bytes = await handler.save(data.slides);
|
|
1320
|
-
* ```
|
|
1321
|
-
*/
|
|
1322
|
-
static createBlank(options?: PresentationOptions): Promise<PresentationBuilderResult>;
|
|
1323
|
-
/**
|
|
1324
|
-
* Create a new PPTX presentation from scratch.
|
|
1325
|
-
*
|
|
1326
|
-
* Alias for {@link createBlank}. Generates a valid minimal OpenXML
|
|
1327
|
-
* package and returns a fully initialized handler ready for editing,
|
|
1328
|
-
* adding slides, and saving.
|
|
1329
|
-
*
|
|
1330
|
-
* @param options - Optional slide dimensions, theme, metadata,
|
|
1331
|
-
* and initial slide count.
|
|
1332
|
-
* @returns Handler, parsed data, and a slide builder factory.
|
|
1333
|
-
*
|
|
1334
|
-
* @example
|
|
1335
|
-
* ```ts
|
|
1336
|
-
* const { handler, data, createSlide } = await PptxHandler.create({
|
|
1337
|
-
* title: "Q4 Report",
|
|
1338
|
-
* initialSlideCount: 3,
|
|
1339
|
-
* theme: { colors: { accent1: "#FF6B6B" } },
|
|
1340
|
-
* });
|
|
1341
|
-
*
|
|
1342
|
-
* // The presentation already has 3 blank slides
|
|
1343
|
-
* console.log(data.slides.length); // => 3
|
|
1344
|
-
*
|
|
1345
|
-
* // Add more slides with content
|
|
1346
|
-
* data.slides.push(
|
|
1347
|
-
* createSlide("Blank")
|
|
1348
|
-
* .addText("Hello", { fontSize: 36 })
|
|
1349
|
-
* .build()
|
|
1350
|
-
* );
|
|
1351
|
-
*
|
|
1352
|
-
* const bytes = await handler.save(data.slides);
|
|
1353
|
-
* ```
|
|
1354
|
-
*/
|
|
1355
|
-
static create(options?: PresentationOptions): Promise<PresentationBuilderResult>;
|
|
1356
|
-
}
|
|
1357
|
-
|
|
1358
|
-
/**
|
|
1359
|
-
* Framework-agnostic public types shared by the viewer bindings.
|
|
1360
|
-
*
|
|
1361
|
-
* These were duplicated in the React (`types-ui.ts`) and Vue (`viewer/types.ts`)
|
|
1362
|
-
* packages; this is the canonical copy. Each binding layers its own
|
|
1363
|
-
* framework-specific prop/event/handle types on top of these.
|
|
1364
|
-
*/
|
|
1365
|
-
|
|
1366
|
-
/** Canvas dimensions in pixels. */
|
|
1367
|
-
interface CanvasSize {
|
|
1368
|
-
width: number;
|
|
1369
|
-
height: number;
|
|
1370
|
-
}
|
|
1371
|
-
/** Collaboration role within a session. */
|
|
1372
|
-
type CollaborationRole = 'owner' | 'collaborator' | 'viewer';
|
|
1373
|
-
/**
|
|
1374
|
-
* Collaboration transport.
|
|
1375
|
-
*
|
|
1376
|
-
* - `'websocket'` (default): y-websocket against `serverUrl`.
|
|
1377
|
-
* - `'webrtc'`: y-webrtc peer-to-peer; needs no document server. Peers meet
|
|
1378
|
-
* through the `signaling` servers (WebRTC signaling only, no document data)
|
|
1379
|
-
* and same-browser tabs additionally sync via BroadcastChannel even without
|
|
1380
|
-
* any signaling server, which makes this mode usable from static hosting.
|
|
1381
|
-
*/
|
|
1382
|
-
type CollaborationTransport = 'websocket' | 'webrtc';
|
|
1383
|
-
/**
|
|
1384
|
-
* Real-time collaboration configuration.
|
|
1385
|
-
*
|
|
1386
|
-
* The same shape is accepted by the React, Vue, and Angular bindings.
|
|
1387
|
-
*/
|
|
1388
|
-
interface CollaborationConfig {
|
|
1389
|
-
/** Unique identifier for the collaboration room (alphanumeric, hyphens, underscores). */
|
|
1390
|
-
roomId: string;
|
|
1391
|
-
/**
|
|
1392
|
-
* WebSocket server URL for the Yjs provider (e.g. "wss://collab.example.com").
|
|
1393
|
-
* Ignored (may be empty) when `transport` is `'webrtc'`.
|
|
1394
|
-
*/
|
|
1395
|
-
serverUrl: string;
|
|
1396
|
-
/** Transport to use. Defaults to `'websocket'`. */
|
|
1397
|
-
transport?: CollaborationTransport;
|
|
1398
|
-
/**
|
|
1399
|
-
* WebRTC signaling server URLs (only used when `transport` is `'webrtc'`).
|
|
1400
|
-
* Defaults to y-webrtc's built-in public signaling list. Same-browser tabs
|
|
1401
|
-
* sync via BroadcastChannel regardless of signaling availability.
|
|
1402
|
-
*/
|
|
1403
|
-
signaling?: string[];
|
|
1404
|
-
/** Display name for the local user. */
|
|
1405
|
-
userName: string;
|
|
1406
|
-
/** Avatar URL for the local user (optional). */
|
|
1407
|
-
userAvatar?: string;
|
|
1408
|
-
/** Hex colour for the local user's cursor/presence indicator. */
|
|
1409
|
-
userColor?: string;
|
|
1410
|
-
/** Optional authentication token sent with the WebSocket handshake. */
|
|
1411
|
-
authToken?: string;
|
|
1412
|
-
/** Role in the session; defaults to `'collaborator'`. */
|
|
1413
|
-
role?: CollaborationRole;
|
|
1414
|
-
/**
|
|
1415
|
-
* Elected-writer write-back callback (Area 3 of the C3 hardening plan).
|
|
1416
|
-
*
|
|
1417
|
-
* When the local user has `role: 'owner'`, the binding debounces changes and
|
|
1418
|
-
* serializes the current Y.Doc state to a PPTX byte array, then calls this
|
|
1419
|
-
* callback so the host can persist the snapshot. Only one writer (the owner)
|
|
1420
|
-
* does this; other collaborators never trigger write-back, eliminating the
|
|
1421
|
-
* last-save-wins problem.
|
|
1422
|
-
*/
|
|
1423
|
-
onWriteBack?: (bytes: Uint8Array) => void;
|
|
1424
|
-
/**
|
|
1425
|
-
* Debounce delay (ms) between the last Y.Doc change and the write-back
|
|
1426
|
-
* invocation. Defaults to 5000 ms. Set to 0 to write back on every change
|
|
1427
|
-
* (not recommended for large documents).
|
|
1428
|
-
*/
|
|
1429
|
-
writeBackDebounceMs?: number;
|
|
1430
|
-
}
|
|
1431
|
-
/** A neutral CSS map (framework `CSSProperties` are structurally compatible). */
|
|
1432
|
-
type CssStyleMap = Record<string, string | number>;
|
|
1433
|
-
|
|
1434
|
-
/**
|
|
1435
|
-
* `animation-authoring` — pure, immutable helpers for the editor's element
|
|
1436
|
-
* animation authoring UI (the Animations ribbon tab / animation panel).
|
|
1437
|
-
*
|
|
1438
|
-
* Animation data lives on the SLIDE (`PptxSlide.animations`), keyed by
|
|
1439
|
-
* `elementId`, NOT on the element itself. The authoring UI reads and emits the
|
|
1440
|
-
* entire slide-level `animations` array. Every function here returns a new
|
|
1441
|
-
* `PptxElementAnimation[]` without mutating its input, so they're trivially
|
|
1442
|
-
* unit-testable and safe to drive editor undo/redo from.
|
|
1443
|
-
*
|
|
1444
|
-
* Two families coexist here, both used across the bindings:
|
|
1445
|
-
*
|
|
1446
|
-
* - **Granular field setters** (`setAnimationEntrance` / `setTrigger` /
|
|
1447
|
-
* `setDuration` / … plus `reorderAnimationUp` / `removeAnimation`): the
|
|
1448
|
-
* Angular authoring panel + React's `useAnimationHandlers` model. They
|
|
1449
|
-
* upsert a single field on the element's entry, creating the entry with
|
|
1450
|
-
* sensible defaults when absent and removing it when all three effect
|
|
1451
|
-
* buckets become empty.
|
|
1452
|
-
* - **Group preset apply/remove** (`applyAnimationPreset` /
|
|
1453
|
-
* `removeElementAnimation`): the Vue ribbon model, a coarser
|
|
1454
|
-
* "set one of entrance/emphasis/exit, keep the rest" upsert.
|
|
1455
|
-
*
|
|
1456
|
-
* The option *catalogs* here are intentionally **value-only** (preset id +
|
|
1457
|
-
* nothing else): the human label / icon / i18n key for each option is
|
|
1458
|
-
* framework-specific (React uses `react-icons` + label keys, Angular uses
|
|
1459
|
-
* Unicode arrow glyphs + plain labels), so each binding maps these ids to its
|
|
1460
|
-
* own display metadata.
|
|
1461
|
-
*
|
|
1462
|
-
* Pure: imports only `pptx-viewer-core` types; no framework, no DOM.
|
|
1463
|
-
*
|
|
1464
|
-
* @module render/animation-authoring
|
|
1465
|
-
*/
|
|
1466
|
-
|
|
1467
|
-
/** One of the three animation buckets a preset can occupy on an element. */
|
|
1468
|
-
type AnimationGroup = 'entrance' | 'emphasis' | 'exit';
|
|
1469
|
-
|
|
1470
|
-
/**
|
|
1471
|
-
* Pure geometry helpers for the align / distribute editor operations.
|
|
1472
|
-
*
|
|
1473
|
-
* These functions operate over a list of slide elements (anything carrying the
|
|
1474
|
-
* `{ id, x, y, width, height }` bounding-box fields of {@link PptxElement}) and
|
|
1475
|
-
* return a `Map` keyed by element `id` describing the *new* position(s) for the
|
|
1476
|
-
* elements that need to move. Elements that already sit on the target edge (or
|
|
1477
|
-
* the two outer-most elements during distribution) are still included with
|
|
1478
|
-
* their unchanged coordinate so callers can apply the whole map uniformly — the
|
|
1479
|
-
* map only ever contains the axis that the operation touches.
|
|
1480
|
-
*
|
|
1481
|
-
* The helpers are deliberately framework-agnostic: no DOM, no Vue reactivity,
|
|
1482
|
-
* no side effects. The host wires them into the editor by feeding the current
|
|
1483
|
-
* selection in and applying the returned `Map` via its element-transform
|
|
1484
|
-
* operation (one batched history entry per call).
|
|
1485
|
-
*/
|
|
1486
|
-
/** Edge / centre that {@link alignElements} can snap a selection to. */
|
|
1487
|
-
type AlignEdge = 'left' | 'centerH' | 'right' | 'top' | 'middle' | 'bottom';
|
|
1488
|
-
|
|
1489
|
-
/**
|
|
1490
|
-
* "Change Case" text mutation (PowerPoint's Aa dropdown: Sentence case, lower,
|
|
1491
|
-
* UPPER, Capitalize Each Word, tOGGLE cASE). Unlike `textCaps` (a purely
|
|
1492
|
-
* visual `text-transform`-style render hint), these modes rewrite the actual
|
|
1493
|
-
* characters, matching PowerPoint's own behaviour. Framework-agnostic; no
|
|
1494
|
-
* framework imports.
|
|
1495
|
-
*/
|
|
1496
|
-
|
|
1497
|
-
type ChangeCaseMode = 'sentence' | 'lower' | 'upper' | 'capitalize' | 'toggle';
|
|
1498
|
-
|
|
1499
|
-
/**
|
|
1500
|
-
* collaboration-presence.ts: Pure, framework-agnostic logic for the real-time
|
|
1501
|
-
* collaboration subsystem (Yjs-backed presence + remote cursors).
|
|
1502
|
-
*
|
|
1503
|
-
* Everything here is a plain function with no framework / Yjs dependency, so it
|
|
1504
|
-
* can be unit-tested in isolation and shared across the React, Vue, and Angular
|
|
1505
|
-
* bindings. The bindings own the stateful provider lifecycle (creating the
|
|
1506
|
-
* Y.Doc / WebsocketProvider, wiring awareness listeners) and call into these
|
|
1507
|
-
* helpers to validate config, sanitise inbound awareness data, and project it
|
|
1508
|
-
* into render-ready view-models.
|
|
1509
|
-
*
|
|
1510
|
-
* Responsibilities:
|
|
1511
|
-
* - Validate the room id and detect mixed-content (ws:// from https) up front.
|
|
1512
|
-
* - Sanitise inbound awareness data (XSS, bounds, colour, avatar, room id).
|
|
1513
|
-
* - Map awareness state into a `RemoteCursor` view-model for rendering.
|
|
1514
|
-
* - Derive the presence list (remote users only, stale entries dropped).
|
|
1515
|
-
* - Deterministic per-user colour assignment + cursor label formatting.
|
|
1516
|
-
*
|
|
1517
|
-
* This mirrors the React `sanitize.ts` / `usePresenceTracking.ts` helpers and
|
|
1518
|
-
* the Angular `collaboration-helpers.ts` (which predates this shared copy).
|
|
1519
|
-
*/
|
|
1520
|
-
|
|
1521
|
-
/** Connection lifecycle states for the Yjs WebSocket provider. */
|
|
1522
|
-
type ConnectionStatus = 'disconnected' | 'connecting' | 'connected' | 'error';
|
|
1523
|
-
/** A single remote collaborator's cursor, in unscaled slide coordinates. */
|
|
1524
|
-
interface RemoteCursor {
|
|
1525
|
-
/** Stable id for the remote client (awareness clientId or peer id). */
|
|
1526
|
-
clientId: number | string;
|
|
1527
|
-
/** Display name shown in the label chip. */
|
|
1528
|
-
userName: string;
|
|
1529
|
-
/** Cursor + chip colour (any CSS colour string). */
|
|
1530
|
-
color: string;
|
|
1531
|
-
/** Unscaled slide-space X coordinate (px). */
|
|
1532
|
-
x: number;
|
|
1533
|
-
/** Unscaled slide-space Y coordinate (px). */
|
|
1534
|
-
y: number;
|
|
1535
|
-
/** Optional ids of elements this user has selected. */
|
|
1536
|
-
selectionIds?: string[];
|
|
1537
|
-
}
|
|
1538
|
-
/**
|
|
1539
|
-
* Presence data for a remote collaborator, sanitised from the awareness
|
|
1540
|
-
* protocol. Returned by {@link sanitizePresence}; coordinates are in unscaled
|
|
1541
|
-
* slide pixels, clamped to the supplied canvas bounds.
|
|
1542
|
-
*/
|
|
1543
|
-
interface SanitizedPresence {
|
|
1544
|
-
clientId: number;
|
|
1545
|
-
userName: string;
|
|
1546
|
-
userAvatar?: string;
|
|
1547
|
-
userColor: string;
|
|
1548
|
-
activeSlideIndex: number;
|
|
1549
|
-
cursorX: number;
|
|
1550
|
-
cursorY: number;
|
|
1551
|
-
lastUpdated: string;
|
|
1552
|
-
selectedElementId?: string;
|
|
1553
|
-
role?: CollaborationRole;
|
|
1554
|
-
}
|
|
1555
|
-
|
|
1556
|
-
/**
|
|
1557
|
-
* Pure, framework-agnostic helpers for freehand ink drawing, shared by every
|
|
1558
|
-
* binding. No framework imports, so these can be unit-tested without TestBed.
|
|
1559
|
-
*/
|
|
1560
|
-
|
|
1561
|
-
/** A 2D point in stage-local coordinates. */
|
|
1562
|
-
interface InkPoint {
|
|
1563
|
-
x: number;
|
|
1564
|
-
y: number;
|
|
1565
|
-
}
|
|
1566
|
-
/** Options for {@link strokeToInkElement}. */
|
|
1567
|
-
interface StrokeToInkElementOpts {
|
|
1568
|
-
points: InkPoint[];
|
|
1569
|
-
color: string;
|
|
1570
|
-
width: number;
|
|
1571
|
-
tool: 'pen' | 'highlighter' | 'freeform';
|
|
1572
|
-
}
|
|
1573
|
-
|
|
1574
|
-
/**
|
|
1575
|
-
* Pure helpers for the gradient picker editor control, shared by every binding.
|
|
1576
|
-
*
|
|
1577
|
-
* Readers extract current gradient values from a PptxElement (falling back to
|
|
1578
|
-
* sensible defaults), and patch-builders produce shallow-merge-ready
|
|
1579
|
-
* `Partial<PptxElement>` objects safe to pass to each binding's element-update
|
|
1580
|
-
* action.
|
|
1581
|
-
*
|
|
1582
|
-
* No framework imports; every type is concrete or `unknown` + narrowed.
|
|
1583
|
-
*/
|
|
1584
|
-
|
|
1585
|
-
/** A single gradient stop, mirroring the ShapeStyle array item shape. */
|
|
1586
|
-
interface GradientStop {
|
|
1587
|
-
color: string;
|
|
1588
|
-
position: number;
|
|
1589
|
-
opacity?: number;
|
|
1590
|
-
}
|
|
1591
|
-
/** The editable gradient state surfaced to the component. */
|
|
1592
|
-
interface GradientState {
|
|
1593
|
-
type: 'linear' | 'radial';
|
|
1594
|
-
/** Angle in degrees (only meaningful for linear). */
|
|
1595
|
-
angle: number;
|
|
1596
|
-
stops: GradientStop[];
|
|
1597
|
-
}
|
|
1598
|
-
/** In-memory clipboard payload stored when an element is copied or cut. */
|
|
1599
|
-
interface ElementClipboardPayload {
|
|
1600
|
-
element: a;
|
|
1601
|
-
isTemplate: boolean;
|
|
1602
|
-
}
|
|
1603
|
-
|
|
1604
|
-
/**
|
|
1605
|
-
* shape-preset-catalog.ts: the Insert > Shape picker catalogue shared by every
|
|
1606
|
-
* binding's toolbar/inspector.
|
|
1607
|
-
*
|
|
1608
|
-
* Pure data: each entry carries the preset geometry `type` (OOXML `a:prstGeom`
|
|
1609
|
-
* value the editor can insert), an English fallback `label`, the shared-i18n
|
|
1610
|
-
* `i18nKey`, and a framework-neutral icon descriptor ({@link ShapePresetGlyph}
|
|
1611
|
-
* name + optional utility-class modifier for rotation/skew). Each binding maps
|
|
1612
|
-
* the glyph name onto its own icon component/SVG.
|
|
1613
|
-
*
|
|
1614
|
-
* Order matters: bindings surface the first 12 entries as the quick "top
|
|
1615
|
-
* shapes" row, so new presets should be appended, not inserted.
|
|
1616
|
-
*
|
|
1617
|
-
* @module render/shape-preset-catalog
|
|
1618
|
-
*/
|
|
1619
|
-
/** Shape preset geometry types offered by the insert picker. */
|
|
1620
|
-
type ShapePresetType = 'rect' | 'roundRect' | 'ellipse' | 'cylinder' | 'rtArrow' | 'leftArrow' | 'upArrow' | 'downArrow' | 'triangle' | 'rtTriangle' | 'diamond' | 'parallelogram' | 'trapezoid' | 'pentagon' | 'hexagon' | 'octagon' | 'chevron' | 'star5' | 'star6' | 'star8' | 'plus' | 'heart' | 'cloud' | 'sun' | 'moon' | 'pie' | 'plaque' | 'teardrop' | 'line' | 'connector';
|
|
1621
|
-
interface AutosaveRecord {
|
|
1622
|
-
key: string;
|
|
1623
|
-
data: Uint8Array;
|
|
1624
|
-
timestamp: number;
|
|
1625
|
-
size: number;
|
|
1626
|
-
}
|
|
1627
|
-
|
|
1628
|
-
/**
|
|
1629
|
-
* Pure handout layout calculations, shared by every binding's print path.
|
|
1630
|
-
*
|
|
1631
|
-
* Handles distributing slides across pages, computing grid dimensions, and
|
|
1632
|
-
* positioning cells within A4 page space. No DOM/framework dependency: callers
|
|
1633
|
-
* render the resulting rectangles however their view layer prefers.
|
|
1634
|
-
*/
|
|
1635
|
-
/** Supported slides-per-page values. */
|
|
1636
|
-
type HandoutSlidesPerPage = 1 | 2 | 3 | 4 | 6 | 9;
|
|
1637
|
-
|
|
1638
|
-
/**
|
|
1639
|
-
* Pure print helpers shared by every binding's print path: settings validation,
|
|
1640
|
-
* slide-range / colour-filter resolution, page-count estimation, HTML markup
|
|
1641
|
-
* builders, escaping, and the full print-document assembler.
|
|
1642
|
-
*
|
|
1643
|
-
* No DOM side effects and no `window.print()`: everything is deterministic and
|
|
1644
|
-
* the binding writes the returned HTML string into a print window. The handout
|
|
1645
|
-
* grid geometry lives in `handout-layout`; this module reuses it.
|
|
1646
|
-
*
|
|
1647
|
-
* ng-packagr constraint honoured here (the Angular binding inlines this source
|
|
1648
|
-
* and compiles it through ng-packagr): NO `String.prototype.replaceAll`
|
|
1649
|
-
* (`escapeHtml` uses `.split(x).join(y)` instead).
|
|
1650
|
-
*/
|
|
1651
|
-
|
|
1652
|
-
/** What to print. */
|
|
1653
|
-
type PrintWhat = 'slides' | 'handouts' | 'notes' | 'outline';
|
|
1654
|
-
/** Page orientation for the printed output. */
|
|
1655
|
-
type PrintOrientation = 'portrait' | 'landscape';
|
|
1656
|
-
/** Colour mode for the printed output. */
|
|
1657
|
-
type PrintColorMode = 'color' | 'grayscale' | 'blackAndWhite';
|
|
1658
|
-
/** Slide range mode. */
|
|
1659
|
-
type PrintSlideRange = 'all' | 'current' | 'custom';
|
|
1660
|
-
/** Resolved print settings emitted on confirm. */
|
|
1661
|
-
interface PrintSettings {
|
|
1662
|
-
printWhat: PrintWhat;
|
|
1663
|
-
orientation: PrintOrientation;
|
|
1664
|
-
colorMode: PrintColorMode;
|
|
1665
|
-
frameSlides: boolean;
|
|
1666
|
-
slidesPerPage: HandoutSlidesPerPage;
|
|
1667
|
-
slideRange: PrintSlideRange;
|
|
1668
|
-
customRangeFrom: number;
|
|
1669
|
-
customRangeTo: number;
|
|
1670
|
-
}
|
|
1671
|
-
|
|
1672
|
-
/**
|
|
1673
|
-
* A tiny framework-free reactive store: `get` / `set(patch)` / `subscribe`.
|
|
1674
|
-
*
|
|
1675
|
-
* This is deliberately minimal (a few dozen lines, no external deps). It only
|
|
1676
|
-
* carries the vanilla binding's *view state*; all domain logic (parsing,
|
|
1677
|
-
* styles, geometry, text building) stays in `pptx-viewer-core` and
|
|
1678
|
-
* `pptx-viewer-shared`.
|
|
1679
|
-
*/
|
|
1680
|
-
/** Listener invoked after every state change with the next and previous state. */
|
|
1681
|
-
type StoreListener<T> = (state: T, previous: T) => void;
|
|
1682
|
-
interface Store<T extends object> {
|
|
1683
|
-
/** Current state snapshot (do not mutate). */
|
|
1684
|
-
get(): T;
|
|
1685
|
-
/** Shallow-merge a partial patch into the state and notify subscribers. */
|
|
1686
|
-
set(patch: Partial<T>): void;
|
|
1687
|
-
/** Subscribe to state changes; returns an unsubscribe function. */
|
|
1688
|
-
subscribe(listener: StoreListener<T>): () => void;
|
|
1689
|
-
}
|
|
1690
|
-
|
|
1691
|
-
/** `zoom` is either an explicit scale factor (1 = 100%) or fit-to-viewport. */
|
|
1692
|
-
type ZoomLevel = number | 'fit';
|
|
1693
|
-
/**
|
|
1694
|
-
* The Draw ribbon tab's active tool. `'select'` means normal editing gestures
|
|
1695
|
-
* (move/resize/rotate/inline-edit) apply on the stage; every other value
|
|
1696
|
-
* routes stage pointer events to the ink-drawing gesture controller instead
|
|
1697
|
-
* (see `editor-draw-gestures.ts`).
|
|
1698
|
-
*/
|
|
1699
|
-
type DrawTool = 'select' | 'pen' | 'highlighter' | 'eraser';
|
|
1700
|
-
/**
|
|
1701
|
-
* The vanilla viewer's reactive view state. Kept intentionally flat and small;
|
|
1702
|
-
* everything here is what the DOM render layer consumes.
|
|
1703
|
-
*/
|
|
1704
|
-
interface ViewerState {
|
|
1705
|
-
/** Parsed slides (image/media URLs already patched in by the load pipeline). */
|
|
1706
|
-
slides: P[];
|
|
1707
|
-
/** Slide canvas size in CSS pixels. */
|
|
1708
|
-
canvasSize: CanvasSize;
|
|
1709
|
-
/** Archive-path to displayable URL map for media + poster frames. */
|
|
1710
|
-
mediaDataUrls: Map<string, string>;
|
|
1711
|
-
/** Zero-based index of the visible slide. */
|
|
1712
|
-
currentSlide: number;
|
|
1713
|
-
/** Requested zoom (explicit factor or fit-to-viewport). */
|
|
1714
|
-
zoom: ZoomLevel;
|
|
1715
|
-
/** True while a load is in flight. */
|
|
1716
|
-
loading: boolean;
|
|
1717
|
-
/** Error message from the last failed load, or null. */
|
|
1718
|
-
error: string | null;
|
|
1719
|
-
/** True while presentation (fullscreen) mode is active. */
|
|
1720
|
-
presenting: boolean;
|
|
1721
|
-
/** True when editing interactions (select/move/resize/...) are enabled. */
|
|
1722
|
-
editable: boolean;
|
|
1723
|
-
/** Id of the selected element on the current slide, or null. */
|
|
1724
|
-
selectedElementId: string | null;
|
|
1725
|
-
/** True when the document has unsaved edits (cleared by a save). */
|
|
1726
|
-
dirty: boolean;
|
|
1727
|
-
/**
|
|
1728
|
-
* True while a pointer gesture (drag/resize/rotate) is in flight. Thumbnail
|
|
1729
|
-
* re-renders are deferred until the gesture ends.
|
|
1730
|
-
*/
|
|
1731
|
-
interactionActive: boolean;
|
|
1732
|
-
/**
|
|
1733
|
-
* True when the speaker-notes panel body is expanded. Persists across slide
|
|
1734
|
-
* navigation for the life of the viewer instance (in-memory only).
|
|
1735
|
-
*/
|
|
1736
|
-
notesExpanded: boolean;
|
|
1737
|
-
/** Remote collaborators currently in the session (empty when not collaborating). */
|
|
1738
|
-
remotePresences: SanitizedPresence[];
|
|
1739
|
-
/** Remote cursors visible on the current slide, projected from `remotePresences`. */
|
|
1740
|
-
cursors: RemoteCursor[];
|
|
1741
|
-
/** Client id of the peer the local user is following, or null when free. */
|
|
1742
|
-
followedClientId: number | null;
|
|
1743
|
-
/** In-memory clipboard payload from the last copy/cut, or null. */
|
|
1744
|
-
clipboardPayload: ElementClipboardPayload | null;
|
|
1745
|
-
/** Active Draw ribbon tool; `'select'` disables the ink-drawing gesture controller. */
|
|
1746
|
-
drawTool: DrawTool;
|
|
1747
|
-
/** Stroke colour for the pen/highlighter tools. */
|
|
1748
|
-
drawColor: string;
|
|
1749
|
-
/** Stroke width (px) for the pen/highlighter tools. */
|
|
1750
|
-
drawWidth: number;
|
|
1751
|
-
}
|
|
1752
|
-
|
|
1753
|
-
/**
|
|
1754
|
-
* Element-animation actions for the ribbon's Animations tab.
|
|
1755
|
-
*
|
|
1756
|
-
* Animation data lives on the SLIDE (`PptxSlide.animations`, keyed by
|
|
1757
|
-
* `elementId`), not on the element itself, matching how the presentation
|
|
1758
|
-
* playback state machine reads it (`buildClickGroups(slide.animations)` in
|
|
1759
|
-
* `animation/presentation-playback.ts`). Both actions target the currently
|
|
1760
|
-
* selected element and route through the shared `animation-authoring.ts`
|
|
1761
|
-
* "coarse group preset" model (`applyAnimationPreset` / `removeElementAnimation`),
|
|
1762
|
-
* the same one the Vue ribbon uses: applying a preset sets one of
|
|
1763
|
-
* entrance/emphasis/exit without touching the others; remove drops the whole
|
|
1764
|
-
* entry.
|
|
1765
|
-
*/
|
|
1766
|
-
interface AnimationActions {
|
|
1767
|
-
addAnimation(group: AnimationGroup, preset: g): void;
|
|
1768
|
-
removeAnimation(): void;
|
|
1769
|
-
}
|
|
1770
|
-
|
|
1771
|
-
/**
|
|
1772
|
-
* Z-order, align, flip, and group/ungroup actions for the ribbon's
|
|
1773
|
-
* Home > Arrange group.
|
|
1774
|
-
*
|
|
1775
|
-
* Align/distribute: the vanilla editor's selection model is single-element
|
|
1776
|
-
* only (see `state/viewer-state.ts`), so `alignElements` reaches the
|
|
1777
|
-
* single-selection "align to slide" mode ({@link alignToCanvas}), matching
|
|
1778
|
-
* PowerPoint's own behaviour when nothing else is selected. Multi-selection
|
|
1779
|
-
* "align to selection bounding box" / distribute (needing >= 2 / >= 3
|
|
1780
|
-
* elements, see `editor-arrange-mutations.ts`) is unreachable until a
|
|
1781
|
-
* multi-select model lands; `canDistribute` is therefore always `false` today
|
|
1782
|
-
* (see `editing-chrome-sync.ts`), a documented limitation rather than a bug.
|
|
1783
|
-
*
|
|
1784
|
-
* Group: needs >= 2 selected elements to be meaningful, so it too is
|
|
1785
|
-
* unreachable under single selection; `groupSelected` is a deliberate no-op
|
|
1786
|
-
* kept only so the ribbon button (permanently disabled, with an explanatory
|
|
1787
|
-
* title) has something to call. Ungroup works today: it applies to whichever
|
|
1788
|
-
* single `group` element is selected.
|
|
1789
|
-
*/
|
|
1790
|
-
interface ArrangeActions {
|
|
1791
|
-
bringForward(): void;
|
|
1792
|
-
sendBackward(): void;
|
|
1793
|
-
bringToFront(): void;
|
|
1794
|
-
sendToBack(): void;
|
|
1795
|
-
alignElements(edge: AlignEdge): void;
|
|
1796
|
-
flipHorizontal(): void;
|
|
1797
|
-
flipVertical(): void;
|
|
1798
|
-
groupSelected(): void;
|
|
1799
|
-
ungroupSelected(): void;
|
|
1800
|
-
}
|
|
1801
|
-
|
|
1802
|
-
/**
|
|
1803
|
-
* Slide-background actions for the ribbon's Design > Format Background panel.
|
|
1804
|
-
* Solid-colour fill only (matches the docked panel's scope: a single colour
|
|
1805
|
-
* input); clearing removes every background field so the slide falls back to
|
|
1806
|
-
* its layout/master background. Both mutations are history-integrated,
|
|
1807
|
-
* mirroring `editor-slide-actions.ts`.
|
|
1808
|
-
*/
|
|
1809
|
-
interface SlideBackgroundActions {
|
|
1810
|
-
setSlideBackgroundColor(color: string): void;
|
|
1811
|
-
clearSlideBackground(): void;
|
|
1812
|
-
}
|
|
1813
|
-
|
|
1814
|
-
/**
|
|
1815
|
-
* Cut/copy/paste actions for the ribbon's Home > Clipboard group, backed by
|
|
1816
|
-
* the shared `element-clipboard.ts` codec. The in-memory clipboard payload
|
|
1817
|
-
* lives on `ViewerState.clipboardPayload` (not a module-level variable) so
|
|
1818
|
-
* the ribbon's selection sync can reactively enable/disable the Paste button.
|
|
1819
|
-
*/
|
|
1820
|
-
interface ClipboardActions {
|
|
1821
|
-
copy(): void;
|
|
1822
|
-
cut(): void;
|
|
1823
|
-
paste(): void;
|
|
1824
|
-
}
|
|
1825
|
-
|
|
1826
|
-
/**
|
|
1827
|
-
* Ink stroke actions for the Draw ribbon tab: commit a freehand pen/
|
|
1828
|
-
* highlighter stroke as a new `InkPptxElement`, or erase an existing one.
|
|
1829
|
-
* Both mutations are history-integrated (push -> mutate -> commit), mirroring
|
|
1830
|
-
* `editor-background-actions.ts` and the `insertElement` helper in
|
|
1831
|
-
* `editor-edit-ops.ts`. The pointer-event lifecycle that accumulates a
|
|
1832
|
-
* stroke's points lives separately in `editor-draw-gestures.ts`; this module
|
|
1833
|
-
* only owns the resulting slide/history mutation.
|
|
1834
|
-
*/
|
|
1835
|
-
interface InkActions {
|
|
1836
|
-
/**
|
|
1837
|
-
* Build an `InkPptxElement` from a completed stroke (via the shared
|
|
1838
|
-
* `strokeToInkElement`) and append it to the current slide, selected.
|
|
1839
|
-
* A no-op when not editable, there is no current slide, or the stroke has
|
|
1840
|
-
* fewer than 2 points (shared helper returns `null`, matching a plain tap).
|
|
1841
|
-
*/
|
|
1842
|
-
commitStroke(stroke: StrokeToInkElementOpts): void;
|
|
1843
|
-
/**
|
|
1844
|
-
* Remove the ink element with `id` from the current slide (Draw tab's
|
|
1845
|
-
* eraser tool). Returns `true` when an ink element was found and removed;
|
|
1846
|
-
* `false` for a missing id, a non-ink element, or a read-only viewer (safe
|
|
1847
|
-
* to call from a generic stage hit-test without a pre-check).
|
|
1848
|
-
*/
|
|
1849
|
-
eraseInkElement(id: string): boolean;
|
|
1850
|
-
}
|
|
1851
|
-
|
|
1852
|
-
/**
|
|
1853
|
-
* Insert-element factories for the vanilla editor.
|
|
1854
|
-
*
|
|
1855
|
-
* The pure builders wrap the framework-agnostic core/shared factories
|
|
1856
|
-
* (`createTextElement`, `createShapeElement`, `createConnectorElement`,
|
|
1857
|
-
* `newTableElement`) and centre the new element on the slide canvas. The one
|
|
1858
|
-
* async helper (`pickImageElement`) owns the file-picker + `FileReader` DOM
|
|
1859
|
-
* side effects needed to turn a chosen image file into a data-URL image
|
|
1860
|
-
* element; it too returns a centred, ready-to-insert element.
|
|
1861
|
-
*/
|
|
1862
|
-
/** The element kinds the Insert ribbon tab can create directly. */
|
|
1863
|
-
type InsertKind = 'text' | 'table' | 'shape';
|
|
1864
|
-
|
|
1865
|
-
/**
|
|
1866
|
-
* Element-type-aware inspector actions: text vertical-align/wrap/autofit,
|
|
1867
|
-
* gradient fill + fill/stroke opacity, image brightness/contrast/saturation +
|
|
1868
|
-
* crop, and table-level header-row/banded-rows/cell-padding. Every method is a
|
|
1869
|
-
* thin `applyToSelected` wrapper around pure builders from `pptx-viewer-shared`
|
|
1870
|
-
* (or the local `patchShapeStyle`), mirroring `editor-text-actions.ts`.
|
|
1871
|
-
*
|
|
1872
|
-
* These extend the base position/size/rotation + flat fill/stroke inspector
|
|
1873
|
-
* that `editor-edit-ops.ts` already exposes; see `ui/inspector/` for the
|
|
1874
|
-
* per-element-type panels that call these.
|
|
1875
|
-
*/
|
|
1876
|
-
interface InspectorActions {
|
|
1877
|
-
setTextVerticalAlign(vAlign: NonNullable<a0['vAlign']>): void;
|
|
1878
|
-
setTextWrap(wrap: NonNullable<a0['textWrap']>): void;
|
|
1879
|
-
setAutoFitMode(mode: NonNullable<a0['autoFitMode']>): void;
|
|
1880
|
-
setFillOpacity(opacity: number): void;
|
|
1881
|
-
setStrokeOpacity(opacity: number): void;
|
|
1882
|
-
setGradientFill(state: GradientState): void;
|
|
1883
|
-
addGradientStop(color: string, position: number): void;
|
|
1884
|
-
removeGradientStop(index: number): void;
|
|
1885
|
-
updateGradientStop(index: number, changes: Partial<GradientState['stops'][number]>): void;
|
|
1886
|
-
setImageBrightness(value: number): void;
|
|
1887
|
-
setImageContrast(value: number): void;
|
|
1888
|
-
setImageSaturation(value: number): void;
|
|
1889
|
-
setImageCrop(edge: 'left' | 'top' | 'right' | 'bottom', value: number): void;
|
|
1890
|
-
setTableHeaderRow(enabled: boolean): void;
|
|
1891
|
-
setTableBandedRows(enabled: boolean): void;
|
|
1892
|
-
setTableCellPadding(padding: number): void;
|
|
1893
|
-
}
|
|
1894
|
-
|
|
1895
|
-
/**
|
|
1896
|
-
* New/duplicate/delete-slide actions for the ribbon's Home > Slides group,
|
|
1897
|
-
* backed by the shared `slide-operations.ts` factory. Every mutation is
|
|
1898
|
-
* history-integrated (matches the element-level actions in `editor-edit-ops`)
|
|
1899
|
-
* and renumbers `slideNumber` across the whole deck so it always matches the
|
|
1900
|
-
* array index (mirrors the Vue `useSlideOperations` contract).
|
|
1901
|
-
*/
|
|
1902
|
-
interface SlideActions {
|
|
1903
|
-
addSlide(): void;
|
|
1904
|
-
duplicateSlide(): void;
|
|
1905
|
-
deleteSlide(): void;
|
|
1906
|
-
}
|
|
1907
|
-
|
|
1908
|
-
/**
|
|
1909
|
-
* Character + paragraph formatting actions for the ribbon's Home > Font and
|
|
1910
|
-
* Home > Paragraph groups. Every method is a thin `applyToSelected` wrapper
|
|
1911
|
-
* around the pure builders in `editor-format-mutations.ts` /
|
|
1912
|
-
* `editor-paragraph-mutations.ts`; this file owns none of the mutation logic
|
|
1913
|
-
* itself, only the selection/history wiring shared by the whole action set.
|
|
1914
|
-
*/
|
|
1915
|
-
interface TextActions {
|
|
1916
|
-
toggleBold(): void;
|
|
1917
|
-
toggleItalic(): void;
|
|
1918
|
-
toggleUnderline(): void;
|
|
1919
|
-
toggleStrikethrough(): void;
|
|
1920
|
-
toggleTextShadow(): void;
|
|
1921
|
-
changeFontSize(delta: number): void;
|
|
1922
|
-
setFontSize(size: number): void;
|
|
1923
|
-
setFontFamily(family: string): void;
|
|
1924
|
-
setTextColor(color: string): void;
|
|
1925
|
-
setHighlightColor(color: string): void;
|
|
1926
|
-
setCharacterSpacing(value: number): void;
|
|
1927
|
-
changeCase(mode: ChangeCaseMode): void;
|
|
1928
|
-
clearFormatting(): void;
|
|
1929
|
-
toggleBulletList(): void;
|
|
1930
|
-
toggleNumberedList(): void;
|
|
1931
|
-
increaseIndent(): void;
|
|
1932
|
-
decreaseIndent(): void;
|
|
1933
|
-
setTextAlign(align: a0['align']): void;
|
|
1934
|
-
setLineSpacing(value: number): void;
|
|
1935
|
-
}
|
|
1936
|
-
|
|
1937
|
-
/**
|
|
1938
|
-
* Slide-transition actions for the ribbon's Transitions tab. Playback already
|
|
1939
|
-
* reads `PptxSlide.transition` (see `animation/presentation-playback.ts`), so
|
|
1940
|
-
* this only needs to write that same field, history-integrated like every
|
|
1941
|
-
* other ribbon mutation.
|
|
1942
|
-
*
|
|
1943
|
-
* `applyTransition` covers both the preset gallery buttons and the duration
|
|
1944
|
-
* input (the tab re-applies the currently-selected preset whenever the
|
|
1945
|
-
* duration changes), plus the "Apply to All Slides" checkbox: when
|
|
1946
|
-
* `applyToAll` is true every slide gets the same fresh `{ type, durationMs }`
|
|
1947
|
-
* transition; otherwise only the current slide is patched, preserving any
|
|
1948
|
-
* advanced fields (direction, sound, ...) it already carried.
|
|
1949
|
-
*/
|
|
1950
|
-
interface TransitionActions {
|
|
1951
|
-
applyTransition(type: k, durationMs: number, applyToAll: boolean): void;
|
|
1952
|
-
}
|
|
1953
|
-
|
|
1954
|
-
/** A geometry patch from the inspector (all fields optional). */
|
|
1955
|
-
interface GeometryPatch {
|
|
1956
|
-
x?: number;
|
|
1957
|
-
y?: number;
|
|
1958
|
-
width?: number;
|
|
1959
|
-
height?: number;
|
|
1960
|
-
rotation?: number;
|
|
1961
|
-
}
|
|
1962
|
-
/**
|
|
1963
|
-
* The full set of formatting / insert / arrange / clipboard / slide actions
|
|
1964
|
-
* exposed to the editing chrome (ribbon, inspector). Composed from the
|
|
1965
|
-
* focused per-concern action files (`editor-text-actions.ts`,
|
|
1966
|
-
* `editor-arrange-actions.ts`, `editor-clipboard-actions.ts`,
|
|
1967
|
-
* `editor-slide-actions.ts`) plus the shape/geometry/insert actions owned
|
|
1968
|
-
* directly here. Every mutating action is history-integrated (push -> mutate
|
|
1969
|
-
* -> commit) via the shared {@link EditorOps}.
|
|
1970
|
-
*/
|
|
1971
|
-
interface EditActions extends TextActions, ArrangeActions, ClipboardActions, SlideActions, SlideBackgroundActions, TransitionActions, AnimationActions, InspectorActions, InkActions {
|
|
1972
|
-
setShapeFill(color: string): void;
|
|
1973
|
-
setShapeStroke(color: string): void;
|
|
1974
|
-
setShapeStrokeWidth(width: number): void;
|
|
1975
|
-
/** Commit an inspector geometry edit (X/Y/W/H/rotation). */
|
|
1976
|
-
setGeometry(patch: GeometryPatch): void;
|
|
1977
|
-
insert(kind: InsertKind, shapeType?: ShapePresetType): void;
|
|
1978
|
-
insertImage(): Promise<void>;
|
|
1979
|
-
insertMedia(): Promise<void>;
|
|
1980
|
-
insertChart(chartType: l): void;
|
|
1981
|
-
insertSmartArt(layout: ca, defaultItems: string[]): void;
|
|
1982
|
-
insertEquation(omml: Record<string, unknown>): void;
|
|
1983
|
-
insertActionButton(shapeType: string): void;
|
|
1984
|
-
insertField(fieldType: string, value?: string): void;
|
|
1985
|
-
duplicateSelected(): void;
|
|
1986
|
-
deleteSelected(): void;
|
|
1987
|
-
}
|
|
1988
|
-
|
|
1989
|
-
/**
|
|
1990
|
-
* Find & Replace actions for the ribbon's Home > Editing group, backed by the
|
|
1991
|
-
* shared `find-replace.ts` helpers. A lean, docked-panel implementation:
|
|
1992
|
-
* `search` reports a match count for the query, `replaceCurrent` replaces the
|
|
1993
|
-
* first match, and `replaceAll` replaces every match; there is no in-canvas
|
|
1994
|
-
* match highlighting or "next/previous match" cursor (that needs per-match
|
|
1995
|
-
* selection/scroll wiring into the renderer, out of scope for this wave).
|
|
1996
|
-
* Every replace is history-integrated like every other editor action.
|
|
1997
|
-
*/
|
|
1998
|
-
interface FindReplaceActions {
|
|
1999
|
-
/** Count occurrences of `query` across all slides (does not mutate). */
|
|
2000
|
-
search(query: string, matchCase: boolean): number;
|
|
2001
|
-
/** Replace the first match of `query`; returns the number replaced (0 or 1). */
|
|
2002
|
-
replaceCurrent(query: string, replacement: string, matchCase: boolean): number;
|
|
2003
|
-
/** Replace every match of `query`; returns the number replaced. */
|
|
2004
|
-
replaceAll(query: string, replacement: string, matchCase: boolean): number;
|
|
2005
|
-
}
|
|
2006
|
-
|
|
2007
|
-
/**
|
|
2008
|
-
* Minimal i18n for the vanilla binding.
|
|
2009
|
-
*
|
|
2010
|
-
* The other bindings delegate to their framework's i18n runtime (react-i18next,
|
|
2011
|
-
* vue-i18n, ngx-translate) fed by the shared `pptx.*` dictionary. The vanilla
|
|
2012
|
-
* binding has no framework, so this module provides the one missing piece: a
|
|
2013
|
-
* `t(key, params)` lookup with `{{param}}` interpolation over the same shared
|
|
2014
|
-
* English dictionary, plus per-locale overrides supplied by the host.
|
|
2015
|
-
*
|
|
2016
|
-
* Resolution order: host dictionary for the active locale, then the built-in
|
|
2017
|
-
* English dictionary, then a humanised fallback derived from the key (shared
|
|
2018
|
-
* `keyToLabel`), so a missing key never renders as a raw `pptx.*` string.
|
|
2019
|
-
*/
|
|
2020
|
-
/** Translate a dotted `pptx.*` key with optional `{{param}}` interpolation. */
|
|
2021
|
-
type Translator = (key: string, params?: Record<string, string | number>) => string;
|
|
2022
|
-
/** Locale to flat `key: message` dictionary map supplied by the host. */
|
|
2023
|
-
type TranslationMessages = Record<string, Record<string, string>>;
|
|
2024
|
-
/**
|
|
2025
|
-
* Build a {@link Translator} for a locale. `messages[locale]` (when provided)
|
|
2026
|
-
* wins over the built-in English dictionary; English is always the fallback.
|
|
2027
|
-
*/
|
|
2028
|
-
declare function createTranslator(locale?: string, messages?: TranslationMessages): Translator;
|
|
2029
|
-
|
|
2030
|
-
/** Selection-derived state the inspector reflects, computed by `buildInspectorState`. */
|
|
2031
|
-
interface InspectorState {
|
|
2032
|
-
hasSelection: boolean;
|
|
2033
|
-
canShape: boolean;
|
|
2034
|
-
canText: boolean;
|
|
2035
|
-
isImage: boolean;
|
|
2036
|
-
isTable: boolean;
|
|
2037
|
-
x: number;
|
|
2038
|
-
y: number;
|
|
2039
|
-
width: number;
|
|
2040
|
-
height: number;
|
|
2041
|
-
rotation: number;
|
|
2042
|
-
fillColor: string | undefined;
|
|
2043
|
-
strokeColor: string | undefined;
|
|
2044
|
-
strokeWidth: number;
|
|
2045
|
-
fillOpacity: number;
|
|
2046
|
-
strokeOpacity: number;
|
|
2047
|
-
gradientEnabled: boolean;
|
|
2048
|
-
gradient: GradientState;
|
|
2049
|
-
vAlign: 'top' | 'middle' | 'bottom';
|
|
2050
|
-
textWrap: 'square' | 'none';
|
|
2051
|
-
autoFitMode: 'shrink' | 'normal' | 'none';
|
|
2052
|
-
imageBrightness: number;
|
|
2053
|
-
imageContrast: number;
|
|
2054
|
-
imageSaturation: number;
|
|
2055
|
-
cropLeft: number;
|
|
2056
|
-
cropTop: number;
|
|
2057
|
-
cropRight: number;
|
|
2058
|
-
cropBottom: number;
|
|
2059
|
-
tableHeaderRow: boolean;
|
|
2060
|
-
tableBandedRows: boolean;
|
|
2061
|
-
tableCellPadding: number;
|
|
2062
|
-
}
|
|
2063
|
-
interface Inspector {
|
|
2064
|
-
el: HTMLElement;
|
|
2065
|
-
update(state: InspectorState): void;
|
|
2066
|
-
setEditable(editable: boolean): void;
|
|
2067
|
-
}
|
|
2068
|
-
|
|
2069
|
-
/** State the panel needs to reflect: the slide to read notes from, and whether edits are allowed. */
|
|
2070
|
-
interface NotesPanelUpdate {
|
|
2071
|
-
slide: P | undefined;
|
|
2072
|
-
editable: boolean;
|
|
2073
|
-
}
|
|
2074
|
-
interface NotesPanel {
|
|
2075
|
-
el: HTMLElement;
|
|
2076
|
-
/**
|
|
2077
|
-
* Sync the panel to the given slide/editable state. The textarea's value is
|
|
2078
|
-
* only reseeded when the slide id actually changes (never on every render),
|
|
2079
|
-
* so an in-progress edit is never interrupted mid-typing.
|
|
2080
|
-
*/
|
|
2081
|
-
update(update: NotesPanelUpdate): void;
|
|
2082
|
-
/** Expand or collapse the notes body (header stays visible either way). */
|
|
2083
|
-
setExpanded(expanded: boolean): void;
|
|
2084
|
-
}
|
|
2085
|
-
|
|
2086
|
-
/** Draw tab state to reflect (current tool/colour/width). */
|
|
2087
|
-
interface RibbonDrawState {
|
|
2088
|
-
tool: DrawTool;
|
|
2089
|
-
color: string;
|
|
2090
|
-
width: number;
|
|
2091
|
-
}
|
|
2092
|
-
/** Nav-row state (prev/next/counter/zoom label). */
|
|
2093
|
-
interface RibbonNavState {
|
|
2094
|
-
current: number;
|
|
2095
|
-
total: number;
|
|
2096
|
-
zoomPercent: number;
|
|
2097
|
-
}
|
|
2098
|
-
/** Primary-row + tab-bar visibility state. */
|
|
2099
|
-
interface RibbonEditState {
|
|
2100
|
-
editable: boolean;
|
|
2101
|
-
canUndo: boolean;
|
|
2102
|
-
canRedo: boolean;
|
|
2103
|
-
}
|
|
2104
|
-
/** Selection-derived state the Home tab's Font/Paragraph/Arrange groups reflect. */
|
|
2105
|
-
interface RibbonSelectionState {
|
|
2106
|
-
hasClipboard: boolean;
|
|
2107
|
-
slideCount: number;
|
|
2108
|
-
}
|
|
2109
|
-
|
|
2110
|
-
interface Ribbon {
|
|
2111
|
-
el: HTMLElement;
|
|
2112
|
-
update(state: RibbonNavState): void;
|
|
2113
|
-
setEditState(state: RibbonEditState): void;
|
|
2114
|
-
setNotesExpanded(expanded: boolean): void;
|
|
2115
|
-
setAutosaveStatus(label: string, kind: 'idle' | 'saving' | 'saved' | 'error'): void;
|
|
2116
|
-
/** Show/hide the whole editing surface (Home/Insert tab content + find/replace). */
|
|
2117
|
-
setEditable(editable: boolean): void;
|
|
2118
|
-
/** Reflect the current selection across the Home tab's Font/Paragraph/Arrange groups. */
|
|
2119
|
-
updateSelection(selectedElement: a | undefined, extra: RibbonSelectionState): void;
|
|
2120
|
-
/** Reflect the current Draw tab tool/colour/width (store-driven). */
|
|
2121
|
-
setDrawState(state: RibbonDrawState): void;
|
|
2122
|
-
}
|
|
2123
|
-
|
|
2124
|
-
interface ThumbnailRail {
|
|
2125
|
-
el: HTMLElement;
|
|
2126
|
-
/** Rebuild the rail for a new slide list (uses `renderStage` per slide). */
|
|
2127
|
-
render(slides: P[], canvasSize: CanvasSize, renderStage: (slide: P, scale: number) => HTMLElement): void;
|
|
2128
|
-
/** Highlight the active slide and scroll it into view. */
|
|
2129
|
-
setActive(index: number): void;
|
|
2130
|
-
/** Show or hide the rail. */
|
|
2131
|
-
setVisible(visible: boolean): void;
|
|
2132
|
-
}
|
|
2133
|
-
|
|
2134
|
-
/** The viewer's static DOM skeleton plus the mutable overlay controls. */
|
|
2135
|
-
interface ViewerChrome {
|
|
2136
|
-
/** `.pptxv` root (focusable; keyboard navigation attaches here). */
|
|
2137
|
-
root: HTMLElement;
|
|
2138
|
-
/** The tabbed ribbon (primary row, nav row, tab bar + File/Home/Insert/View content); null when disabled. */
|
|
2139
|
-
ribbon: Ribbon | null;
|
|
2140
|
-
/** Property inspector panel; null when disabled. */
|
|
2141
|
-
inspector: Inspector | null;
|
|
2142
|
-
thumbnails: ThumbnailRail | null;
|
|
2143
|
-
/** Scrollable centring viewport around the stage. */
|
|
2144
|
-
viewport: HTMLElement;
|
|
2145
|
-
/** Box sized to `canvasSize * scale`; the rendered stage goes inside. */
|
|
2146
|
-
stageWrap: HTMLElement;
|
|
2147
|
-
/** Collapsible speaker-notes panel docked below the slide area. */
|
|
2148
|
-
notes: NotesPanel;
|
|
2149
|
-
setLoading(loading: boolean): void;
|
|
2150
|
-
setError(message: string | null): void;
|
|
2151
|
-
setEmpty(empty: boolean): void;
|
|
2152
|
-
setPresenting(presenting: boolean): void;
|
|
2153
|
-
}
|
|
2154
|
-
|
|
2155
|
-
interface PresentationController {
|
|
2156
|
-
/** Enter presentation mode (real Fullscreen API on the target element). */
|
|
2157
|
-
enter(): Promise<void>;
|
|
2158
|
-
/** Exit presentation mode. */
|
|
2159
|
-
exit(): Promise<void>;
|
|
2160
|
-
/** True while the target is the fullscreen element. */
|
|
2161
|
-
isActive(): boolean;
|
|
2162
|
-
/** Remove listeners. */
|
|
2163
|
-
dispose(): void;
|
|
2164
|
-
}
|
|
2165
|
-
|
|
2166
|
-
interface EditorController {
|
|
2167
|
-
/** (Re)wire listeners + overlay into the current chrome (after mount). */
|
|
2168
|
-
attachChrome(): void;
|
|
2169
|
-
detachChrome(): void;
|
|
2170
|
-
/** Called by the render controller after every stage render. */
|
|
2171
|
-
onStageRendered(): void;
|
|
2172
|
-
/** True while editing owns the keyboard (selection or inline editing). */
|
|
2173
|
-
capturesKeyboard(): boolean;
|
|
2174
|
-
/** Drop history/selection/dirty state (new content loaded). */
|
|
2175
|
-
reset(): void;
|
|
2176
|
-
setEditable(editable: boolean): void;
|
|
2177
|
-
undo(): void;
|
|
2178
|
-
redo(): void;
|
|
2179
|
-
canUndo(): boolean;
|
|
2180
|
-
canRedo(): boolean;
|
|
2181
|
-
deleteSelected(): void;
|
|
2182
|
-
duplicateSelected(): string | null;
|
|
2183
|
-
getSelectedElementId(): string | null;
|
|
2184
|
-
/** Switch the Draw ribbon tab's active tool (also clears selection when leaving `'select'`). */
|
|
2185
|
-
setDrawTool(tool: DrawTool): void;
|
|
2186
|
-
/** Set the pen/highlighter stroke colour used by the next committed stroke. */
|
|
2187
|
-
setDrawColor(color: string): void;
|
|
2188
|
-
/** Set the pen/highlighter stroke width used by the next committed stroke. */
|
|
2189
|
-
setDrawWidth(width: number): void;
|
|
2190
|
-
/** The formatting / insert / arrange actions for the editing chrome. */
|
|
2191
|
-
getEditActions(): EditActions;
|
|
2192
|
-
/** The Find & Replace actions for the ribbon's docked panel. */
|
|
2193
|
-
getFindReplaceActions(): FindReplaceActions;
|
|
2194
|
-
/** Commit the speaker-notes textarea's plain text onto the current slide. */
|
|
2195
|
-
commitNotes(notes: string): void;
|
|
2196
|
-
save(): Promise<Uint8Array>;
|
|
2197
|
-
downloadPptx(fileName?: string): Promise<void>;
|
|
2198
|
-
destroy(): void;
|
|
2199
|
-
}
|
|
2200
|
-
|
|
2201
|
-
/** Everything the controller needs after a stage (re)render. */
|
|
2202
|
-
interface SyncStageParams {
|
|
2203
|
-
doc: Document;
|
|
2204
|
-
/** The stage host (position: relative), for layering a transition overlay. */
|
|
2205
|
-
stageWrap: HTMLElement;
|
|
2206
|
-
/** The freshly rendered, fully-visible main stage node. */
|
|
2207
|
-
stage: HTMLElement;
|
|
2208
|
-
/** The slide the stage renders, or `undefined` when empty. */
|
|
2209
|
-
slide: P | undefined;
|
|
2210
|
-
/** Zero-based index of the rendered slide. */
|
|
2211
|
-
slideIndex: number;
|
|
2212
|
-
/** True only when the live (fullscreen) presentation stage is active. */
|
|
2213
|
-
presenting: boolean;
|
|
2214
|
-
}
|
|
2215
|
-
/**
|
|
2216
|
-
* The presentation-mode playback state machine for the vanilla binding.
|
|
2217
|
-
*
|
|
2218
|
-
* It owns the click-stepped animation cursor and the slide-transition overlay,
|
|
2219
|
-
* both driven by the shared framework-agnostic helpers. It is consulted from
|
|
2220
|
-
* two seams in the rebuild-per-change render flow:
|
|
2221
|
-
*
|
|
2222
|
-
* - {@link PresentationPlayback.syncStage} runs after every stage render:
|
|
2223
|
-
* on a slide entry it rebuilds the click groups, resets the step, hides
|
|
2224
|
-
* pending entrances, and (when the slide changed mid-show) plays the
|
|
2225
|
-
* incoming slide's transition over a snapshot of the outgoing stage.
|
|
2226
|
-
* - {@link PresentationPlayback.advance} runs on each forward navigation
|
|
2227
|
-
* key/tap while presenting: it reveals the next animation build in place
|
|
2228
|
-
* (no rebuild) and reports whether a build remained, so the caller only
|
|
2229
|
-
* advances the slide once the timeline is exhausted.
|
|
2230
|
-
*/
|
|
2231
|
-
interface PresentationPlayback {
|
|
2232
|
-
/**
|
|
2233
|
-
* Reveal the next on-click animation build for the current slide. Returns
|
|
2234
|
-
* `true` if a build was revealed (stay on the slide); `false` when the
|
|
2235
|
-
* slide's builds are exhausted (the caller should advance to the next slide).
|
|
2236
|
-
*/
|
|
2237
|
-
advance(): boolean;
|
|
2238
|
-
/** True when every click group on the current slide has been revealed. */
|
|
2239
|
-
isComplete(): boolean;
|
|
2240
|
-
/** Sync playback + transitions after a stage (re)render. */
|
|
2241
|
-
syncStage(params: SyncStageParams): void;
|
|
2242
|
-
/** Cancel any running transition and forget all per-slide state. */
|
|
2243
|
-
reset(): void;
|
|
2244
|
-
}
|
|
2245
|
-
|
|
2246
|
-
/** Discriminant values of the {@link PptxElement} union (`'text'`, `'chart'`, ...). */
|
|
2247
|
-
type PptxElementType = a['type'];
|
|
2248
|
-
/**
|
|
2249
|
-
* Everything an element renderer may need, passed to every renderer call.
|
|
2250
|
-
*
|
|
2251
|
-
* The context is immutable per slide render. Renderers must create DOM through
|
|
2252
|
-
* `context.document` (never the global `document`) so slides can render into
|
|
2253
|
-
* detached documents (tests, export pipelines).
|
|
2254
|
-
*/
|
|
2255
|
-
interface ElementRenderContext {
|
|
2256
|
-
/** Document used for all DOM creation. */
|
|
2257
|
-
readonly document: Document;
|
|
2258
|
-
/** The slide being rendered. */
|
|
2259
|
-
readonly slide: P;
|
|
2260
|
-
/** Full slide canvas size in CSS px (elements are positioned in this space). */
|
|
2261
|
-
readonly canvasSize: CanvasSize;
|
|
2262
|
-
/**
|
|
2263
|
-
* The scale the stage is rendered at (1 = 100%). The stage applies it via a
|
|
2264
|
-
* CSS transform, so renderers should lay out in unscaled canvas px; `scale`
|
|
2265
|
-
* is informational (e.g. for raster density decisions).
|
|
2266
|
-
*/
|
|
2267
|
-
readonly scale: number;
|
|
2268
|
-
/** Archive-path to displayable URL map for media + poster frames. */
|
|
2269
|
-
readonly mediaDataUrls: ReadonlyMap<string, string>;
|
|
2270
|
-
/** Shared-dictionary translator (`pptx.*` keys). */
|
|
2271
|
-
readonly t: Translator;
|
|
2272
|
-
/**
|
|
2273
|
-
* Opt-in flag: render `smartArt` elements as an extruded Three.js scene
|
|
2274
|
-
* instead of flat SVG (see `PptxViewerOptions.smartArt3D`). Defaults to
|
|
2275
|
-
* `false` when the option is unset.
|
|
2276
|
-
*/
|
|
2277
|
-
readonly smartArt3D: boolean;
|
|
2278
|
-
/**
|
|
2279
|
-
* True only for the live presentation stage (real Fullscreen API active):
|
|
2280
|
-
* media renderers use this to autoplay once mounted, matching PowerPoint's
|
|
2281
|
-
* slideshow behaviour. `false` for the editor canvas and thumbnail rail.
|
|
2282
|
-
*/
|
|
2283
|
-
readonly presenting: boolean;
|
|
2284
|
-
/** The registry in effect, for renderers that need to inspect it. */
|
|
2285
|
-
readonly registry: ElementRendererRegistry;
|
|
2286
|
-
/**
|
|
2287
|
-
* Render a child element through the registry (used by the group renderer
|
|
2288
|
-
* for recursion; custom renderers may nest elements the same way).
|
|
2289
|
-
*/
|
|
2290
|
-
renderElement(element: a, zIndex: number): HTMLElement | SVGElement | null;
|
|
2291
|
-
}
|
|
2292
|
-
/**
|
|
2293
|
-
* Renders one slide element to a DOM node (or `null` to render nothing).
|
|
2294
|
-
*
|
|
2295
|
-
* Contract:
|
|
2296
|
-
* - Position absolutely within the stage: apply the shared
|
|
2297
|
-
* `getContainerStyle(element, zIndex)` map (or equivalent) to the returned
|
|
2298
|
-
* root node.
|
|
2299
|
-
* - Set `dataset.elementId = element.id` on the root node.
|
|
2300
|
-
* - Create all DOM via `context.document`.
|
|
2301
|
-
* - Never mutate `element` or anything on the context.
|
|
2302
|
-
*/
|
|
2303
|
-
type ElementRenderer = (element: a, zIndex: number, context: ElementRenderContext) => HTMLElement | SVGElement | null;
|
|
2304
|
-
/**
|
|
2305
|
-
* Registry dispatching elements to renderers by their `type` discriminant.
|
|
2306
|
-
*
|
|
2307
|
-
* Additional element types are supported by registering a renderer for the
|
|
2308
|
-
* type; unregistered types fall through to the fallback renderer (a typed
|
|
2309
|
-
* placeholder box by default). See `render/elements/README.md` for the
|
|
2310
|
-
* step-by-step contract.
|
|
2311
|
-
*/
|
|
2312
|
-
interface ElementRendererRegistry {
|
|
2313
|
-
/** Register (or replace) the renderer for an element type. */
|
|
2314
|
-
register(type: PptxElementType, renderer: ElementRenderer): void;
|
|
2315
|
-
/** Remove the renderer for an element type (falls back afterwards). */
|
|
2316
|
-
unregister(type: PptxElementType): void;
|
|
2317
|
-
/** The renderer registered for a type, or `undefined`. */
|
|
2318
|
-
get(type: PptxElementType): ElementRenderer | undefined;
|
|
2319
|
-
/** True when a dedicated (non-fallback) renderer is registered. */
|
|
2320
|
-
has(type: PptxElementType): boolean;
|
|
2321
|
-
/** Replace the fallback renderer used for unregistered types. */
|
|
2322
|
-
setFallback(renderer: ElementRenderer): void;
|
|
2323
|
-
/** The renderer to use for a type: registered renderer or fallback. */
|
|
2324
|
-
resolve(type: PptxElementType): ElementRenderer;
|
|
2325
|
-
/** All types with a dedicated renderer (sorted, for tests/debugging). */
|
|
2326
|
-
registeredTypes(): PptxElementType[];
|
|
2327
|
-
}
|
|
2328
|
-
|
|
2329
|
-
/**
|
|
2330
|
-
* Create an empty {@link ElementRendererRegistry}.
|
|
2331
|
-
*
|
|
2332
|
-
* The default fallback renders nothing; `createDefaultRegistry()` (in
|
|
2333
|
-
* `./elements`) installs the built-in renderers plus the typed placeholder
|
|
2334
|
-
* fallback.
|
|
2335
|
-
*/
|
|
2336
|
-
declare function createElementRendererRegistry(): ElementRendererRegistry;
|
|
2337
|
-
|
|
2338
|
-
/**
|
|
2339
|
-
* Apply a shared `CssStyleMap` to an element. The shared builders emit a mix
|
|
2340
|
-
* of camelCase (`backgroundColor`) and kebab-case (`background-color`) keys;
|
|
2341
|
-
* both are normalised to `style.setProperty` calls.
|
|
2342
|
-
*/
|
|
2343
|
-
declare function applyStyleMap(el: HTMLElement | SVGElement, style: CssStyleMap): void;
|
|
2344
|
-
/** Create an element with an optional class and style map. */
|
|
2345
|
-
declare function createEl<K extends keyof HTMLElementTagNameMap>(doc: Document, tag: K, className?: string, style?: CssStyleMap): HTMLElementTagNameMap[K];
|
|
2346
|
-
/** Create a namespaced SVG element with optional attributes. */
|
|
2347
|
-
declare function createSvgEl<K extends keyof SVGElementTagNameMap>(doc: Document, tag: K, attrs?: Record<string, string | number | undefined>): SVGElementTagNameMap[K];
|
|
2348
|
-
|
|
2349
|
-
interface SlideStageOptions {
|
|
2350
|
-
document: Document;
|
|
2351
|
-
slide: P;
|
|
2352
|
-
canvasSize: CanvasSize;
|
|
2353
|
-
mediaDataUrls: ReadonlyMap<string, string>;
|
|
2354
|
-
registry: ElementRendererRegistry;
|
|
2355
|
-
t: Translator;
|
|
2356
|
-
/** Scale applied via CSS transform (default 1). */
|
|
2357
|
-
scale?: number;
|
|
2358
|
-
/** Opt-in WebGL SmartArt renderer flag; see `PptxViewerOptions.smartArt3D`. */
|
|
2359
|
-
smartArt3D?: boolean;
|
|
2360
|
-
/** True only for the live presentation stage; see `ElementRenderContext.presenting`. */
|
|
2361
|
-
presenting?: boolean;
|
|
2362
|
-
/**
|
|
2363
|
-
* True only for the main (interactive) canvas, never the thumbnail rail.
|
|
2364
|
-
* Marks every rendered element (recursively, including group children) with
|
|
2365
|
-
* `data-pptx-element="true"` and the stage itself with
|
|
2366
|
-
* `role="region" aria-roledescription="slide"` - the framework-neutral e2e
|
|
2367
|
-
* test hooks the React/Vue/Angular bindings also emit. Defaults to `false`.
|
|
2368
|
-
*/
|
|
2369
|
-
interactive?: boolean;
|
|
2370
|
-
}
|
|
2371
|
-
/**
|
|
2372
|
-
* Render one slide as a fixed-size stage: the resolved slide background plus
|
|
2373
|
-
* every element dispatched through the registry, scaled with a CSS transform
|
|
2374
|
-
* (`transform-origin: top left`), exactly like the other bindings' stages.
|
|
2375
|
-
*
|
|
2376
|
-
* The returned node is `canvasSize * scale` ON SCREEN but laid out at the
|
|
2377
|
-
* unscaled canvas size, so the caller should wrap it in a box sized to
|
|
2378
|
-
* `canvasSize * scale` (the viewer's stage host and thumbnails both do).
|
|
2379
|
-
*/
|
|
2380
|
-
declare function renderSlideStage(options: SlideStageOptions): HTMLElement;
|
|
2381
|
-
|
|
2382
|
-
/**
|
|
2383
|
-
* The registry the viewer uses by default.
|
|
2384
|
-
*
|
|
2385
|
-
* Dedicated renderers: `text`, `shape`, `image`, `picture`, `group`,
|
|
2386
|
-
* `connector`, `table`, `chart`, `smartArt`, `media`, `ink`, `ole`. The
|
|
2387
|
-
* remaining types (`contentPart`, `zoom`, `model3d`, `unknown`) fall through
|
|
2388
|
-
* to the typed placeholder fallback until their renderers land; see
|
|
2389
|
-
* `./README.md` for the contract to add one.
|
|
2390
|
-
*/
|
|
2391
|
-
declare function createDefaultRegistry(): ElementRendererRegistry;
|
|
2392
|
-
|
|
2393
|
-
interface RenderController {
|
|
2394
|
-
/** Re-render everything (used after a chrome rebuild). */
|
|
2395
|
-
renderAll(): void;
|
|
2396
|
-
/** Re-render the main stage + toolbar counters at the current state. */
|
|
2397
|
-
renderStage(): void;
|
|
2398
|
-
/** Rebuild the thumbnail rail from the current slide list. */
|
|
2399
|
-
renderThumbnails(): void;
|
|
2400
|
-
/** Resolve the requested zoom into a concrete scale factor. */
|
|
2401
|
-
effectiveScale(): number;
|
|
2402
|
-
/**
|
|
2403
|
-
* Presentation-mode animation/transition playback, driven by the stage
|
|
2404
|
-
* rebuild flow. Navigation (`viewer-controls`) consults `advance()` so a
|
|
2405
|
-
* "next" first steps the on-click animation timeline before advancing slides.
|
|
2406
|
-
*/
|
|
2407
|
-
readonly presentationPlayback: PresentationPlayback;
|
|
2408
|
-
}
|
|
2409
|
-
|
|
2410
|
-
/**
|
|
2411
|
-
* Debounced autosave for the vanilla viewer, layered on the shared IndexedDB
|
|
2412
|
-
* recovery store (`pptx-viewer-shared/autosave-store`).
|
|
2413
|
-
*
|
|
2414
|
-
* Semantics mirror the React/Vue bindings: a local edit marks the document
|
|
2415
|
-
* dirty; a debounce timer then re-serializes the deck through
|
|
2416
|
-
* `PptxHandler.save` and persists it under `filePath` via
|
|
2417
|
-
* `saveAutosaveSnapshot` (evicting the oldest record on quota exhaustion). The
|
|
2418
|
-
* recovery blob is a crash-safety net only; it never clears the editor's dirty
|
|
2419
|
-
* flag or stands in for the user's real Save.
|
|
2420
|
-
*
|
|
2421
|
-
* On construction it probes `getAutosaveSnapshot(filePath)` and, when a snapshot
|
|
2422
|
-
* from a previous session exists, offers it back through `onRecovery` so the
|
|
2423
|
-
* host can decide whether to restore it (e.g. via `loadFile`).
|
|
2424
|
-
*/
|
|
2425
|
-
type AutosaveStatus = 'idle' | 'saving' | 'saved' | 'error';
|
|
2426
|
-
|
|
2427
|
-
/**
|
|
2428
|
-
* share-helpers.ts: pure (framework-free) helpers for the Share dialog.
|
|
2429
|
-
*
|
|
2430
|
-
* Mirrors the Vue `ShareDialog.vue` / Angular `share-helpers.ts` form
|
|
2431
|
-
* validation and config-assembly logic (see `useCollaborationWiring.onShareStart`
|
|
2432
|
-
* for the `role: 'collaborator'` config this produces). No DOM here so it is
|
|
2433
|
-
* trivially unit-testable; the DOM builder lives in `ui/share-dialog.ts`.
|
|
2434
|
-
*/
|
|
2435
|
-
/** Prefilled values for the Share form fields. */
|
|
2436
|
-
interface ShareDefaults {
|
|
2437
|
-
roomId?: string;
|
|
2438
|
-
userName?: string;
|
|
2439
|
-
serverUrl?: string;
|
|
2440
|
-
}
|
|
2441
|
-
|
|
2442
|
-
/** Per-slide progress callback: `(currentSlideIndex, totalSlides)`. */
|
|
2443
|
-
type ExportProgress = (current: number, total: number) => void;
|
|
2444
|
-
|
|
2445
|
-
/**
|
|
2446
|
-
* Animated-GIF export for the vanilla binding. All slides are captured (one
|
|
2447
|
-
* frame per slide) via the injected `rasterizeSlide`, then encoded with the
|
|
2448
|
-
* shared pure-JS GIF89a encoder (`pptx-viewer-shared` `gif-encoder`: median-cut
|
|
2449
|
-
* quantisation + LZW). Frame timing comes from the shared `planGifFrames`
|
|
2450
|
-
* planner and oversized captures are downscaled via `clampGifDimensions`; only
|
|
2451
|
-
* the DOM capture / canvas scaling / Blob download driver lives here.
|
|
2452
|
-
*/
|
|
2453
|
-
/** Options for the animated-GIF export (all slides, one frame per slide). */
|
|
2454
|
-
interface ExportGifOptions {
|
|
2455
|
-
/**
|
|
2456
|
-
* Duration each slide is shown, in milliseconds (default 2000). Per-slide
|
|
2457
|
-
* overrides can be supplied via {@link ExportGifOptions.slideTimingsMs}.
|
|
2458
|
-
*/
|
|
2459
|
-
slideDurationMs?: number;
|
|
2460
|
-
/**
|
|
2461
|
-
* Per-slide duration overrides in milliseconds (index maps to slide index,
|
|
2462
|
-
* e.g. rehearsed timings). Flows through the shared `planGifFrames` plan
|
|
2463
|
-
* into per-frame GIF delays.
|
|
2464
|
-
*/
|
|
2465
|
-
slideTimingsMs?: number[];
|
|
2466
|
-
/**
|
|
2467
|
-
* Cap on the longer side of the encoded frames, in pixels (default 1920).
|
|
2468
|
-
* Captured canvases larger than this are downscaled before quantisation,
|
|
2469
|
-
* keeping encode time and file size manageable.
|
|
2470
|
-
*/
|
|
2471
|
-
maxDimension?: number;
|
|
2472
|
-
/** Capture-phase progress callback: `(currentSlide, totalSlides)`. */
|
|
2473
|
-
onProgress?: ExportProgress;
|
|
2474
|
-
/** Abort the export early; the capture loop checks this between slides. */
|
|
2475
|
-
signal?: AbortSignal;
|
|
2476
|
-
}
|
|
2477
|
-
|
|
2478
|
-
/**
|
|
2479
|
-
* Print for the vanilla binding, assembled entirely from the shared print
|
|
2480
|
-
* module (`pptx-viewer-shared` `print-document`): `validatePrintSettings`,
|
|
2481
|
-
* `computeSlideIndices` / `computeColorFilter`, the `build*Html` body markup
|
|
2482
|
-
* builders, and the DOMPurify-hardened `buildPrintHtmlDocument` assembler.
|
|
2483
|
-
* Only the drivers live here: rasterising the selected slides to data URLs and
|
|
2484
|
-
* writing the document into a print window. Vanilla port of Vue's `usePrint`
|
|
2485
|
-
* raster path (slides / notes / handouts / outline).
|
|
2486
|
-
*/
|
|
2487
|
-
/**
|
|
2488
|
-
* Open a print window for a complete HTML document and trigger printing.
|
|
2489
|
-
* Returns `false` when the window could not be opened (popup blocker).
|
|
2490
|
-
*/
|
|
2491
|
-
type OpenPrintWindow = (htmlDocument: string) => boolean;
|
|
2492
|
-
/**
|
|
2493
|
-
* Options for `print`: any subset of the shared `PrintSettings` (unspecified
|
|
2494
|
-
* fields fall back to `DEFAULT_PRINT_SETTINGS`, i.e. all slides, landscape,
|
|
2495
|
-
* full colour) plus progress/abort and a print-window override.
|
|
2496
|
-
*/
|
|
2497
|
-
interface PrintOptions extends Partial<PrintSettings> {
|
|
2498
|
-
/** Rasterisation progress callback: `(currentSlide, totalSlidesToPrint)`. */
|
|
2499
|
-
onProgress?: ExportProgress;
|
|
2500
|
-
/** Abort before the window opens; checked between slide captures. */
|
|
2501
|
-
signal?: AbortSignal;
|
|
2502
|
-
/**
|
|
2503
|
-
* Override how the assembled document is opened (e.g. write it into a
|
|
2504
|
-
* hidden iframe). Popup-blocker caveat: the default opener uses
|
|
2505
|
-
* `window.open`, which browsers typically only allow inside a user
|
|
2506
|
-
* gesture, so call `print()` from a click handler; when the popup is
|
|
2507
|
-
* blocked the returned promise resolves `false`.
|
|
2508
|
-
*/
|
|
2509
|
-
openPrintWindow?: OpenPrintWindow;
|
|
2510
|
-
}
|
|
2511
|
-
|
|
2512
|
-
/**
|
|
2513
|
-
* WebM video export for the vanilla binding, driven by the shared `video-plan`
|
|
2514
|
-
* module: `planVideoSegments` (per-slide segment timing + frame counts),
|
|
2515
|
-
* `fpsToFrameIntervalMs` (draw-loop pacing), and `pickSupportedMimeType` over
|
|
2516
|
-
* `WEBM_MIME_CANDIDATES` (MediaRecorder codec selection). Only the browser
|
|
2517
|
-
* driver lives here: capture each slide to a canvas, replay the canvases onto
|
|
2518
|
-
* a recording canvas fed to `captureStream()` + `MediaRecorder`, and download
|
|
2519
|
-
* the resulting Blob. Vanilla port of React's `exportAllSlidesAsVideo`.
|
|
2520
|
-
*/
|
|
2521
|
-
/** Options for the WebM video export (all slides). */
|
|
2522
|
-
interface ExportVideoOptions {
|
|
2523
|
-
/** Duration each slide is held, in milliseconds (default 3000). */
|
|
2524
|
-
slideDurationMs?: number;
|
|
2525
|
-
/** Per-slide duration overrides in milliseconds (index maps to slide index). */
|
|
2526
|
-
slideTimingsMs?: number[];
|
|
2527
|
-
/** Recording frame rate in frames per second (default 30). */
|
|
2528
|
-
fps?: number;
|
|
2529
|
-
/** MediaRecorder video bitrate in bits per second (default 5,000,000). */
|
|
2530
|
-
videoBitsPerSecond?: number;
|
|
2531
|
-
/** Capture-phase progress callback: `(currentSlide, totalSlides)`. */
|
|
2532
|
-
onProgress?: ExportProgress;
|
|
2533
|
-
/** Recording-phase progress callback: `(currentSlide, totalSlides)`. */
|
|
2534
|
-
onRecordProgress?: ExportProgress;
|
|
2535
|
-
/** Abort the export early; checked between slides and between frames. */
|
|
2536
|
-
signal?: AbortSignal;
|
|
2537
|
-
}
|
|
2538
|
-
|
|
2539
|
-
/** Options for the multi-slide PDF export (progress + cooperative cancel). */
|
|
2540
|
-
interface ExportPdfOptions {
|
|
2541
|
-
/** Capture-phase progress callback: `(currentSlide, totalSlides)`. */
|
|
2542
|
-
onProgress?: ExportProgress;
|
|
2543
|
-
/** Abort the export early; the loop checks this between slides. */
|
|
2544
|
-
signal?: AbortSignal;
|
|
2545
|
-
}
|
|
2546
|
-
|
|
2547
|
-
/**
|
|
2548
|
-
* Content sources accepted by the vanilla viewer: raw bytes, a Blob/File, or
|
|
2549
|
-
* a URL string to fetch.
|
|
2550
|
-
*/
|
|
2551
|
-
type PptxViewerSource = ArrayBuffer | Uint8Array | Blob | string;
|
|
2552
|
-
|
|
2553
|
-
/** Callbacks mirroring the Vue component's emits. */
|
|
2554
|
-
interface PptxViewerCallbacks {
|
|
2555
|
-
/** Fired after a presentation loads successfully. */
|
|
2556
|
-
onLoad?: (info: {
|
|
2557
|
-
slideCount: number;
|
|
2558
|
-
canvasSize: CanvasSize;
|
|
2559
|
-
}) => void;
|
|
2560
|
-
/** Fired when a load fails (message is already localised/best-effort). */
|
|
2561
|
-
onError?: (message: string, error: unknown) => void;
|
|
2562
|
-
/** Fired when the active slide changes (zero-based index). */
|
|
2563
|
-
onSlideChange?: (index: number) => void;
|
|
2564
|
-
/** Fired when the effective zoom scale changes (1 = 100%). */
|
|
2565
|
-
onZoomChange?: (scale: number) => void;
|
|
2566
|
-
/** Fired when presentation (fullscreen) mode is entered or exited. */
|
|
2567
|
-
onPresentationChange?: (presenting: boolean) => void;
|
|
2568
|
-
/** Fired after any document mutation (move, resize, edit, undo, ...). */
|
|
2569
|
-
onChange?: () => void;
|
|
2570
|
-
/** Fired when the unsaved-edits flag flips (a save resets it). */
|
|
2571
|
-
onDirtyChange?: (dirty: boolean) => void;
|
|
2572
|
-
/** Fired when the selected element changes (`null` = no selection). */
|
|
2573
|
-
onSelectionChange?: (elementId: string | null) => void;
|
|
2574
|
-
/** Fired on every autosave lifecycle transition (`saving`/`saved`/`error`). */
|
|
2575
|
-
onAutosaveStatus?: (status: AutosaveStatus) => void;
|
|
2576
|
-
/**
|
|
2577
|
-
* Offered a recovery snapshot found in the shared IndexedDB store on start
|
|
2578
|
-
* (a previous session's autosave for the same `autosaveFilePath`). The host
|
|
2579
|
-
* decides whether to restore it, e.g. `viewer.loadFile(record.data)`.
|
|
2580
|
-
*/
|
|
2581
|
-
onAutosaveRecovery?: (record: AutosaveRecord) => void;
|
|
2582
|
-
/** Fired on every collaboration connection-status transition. */
|
|
2583
|
-
onCollaborationStatus?: (status: ConnectionStatus) => void;
|
|
2584
|
-
}
|
|
2585
|
-
interface PptxViewerOptions extends PptxViewerCallbacks {
|
|
2586
|
-
/**
|
|
2587
|
-
* The presentation to open: raw `.pptx` bytes (ArrayBuffer / Uint8Array),
|
|
2588
|
-
* a Blob/File, or a URL string to fetch. Omit to start empty and call
|
|
2589
|
-
* `loadFile` / `loadUrl` later.
|
|
2590
|
-
*/
|
|
2591
|
-
source?: PptxViewerSource;
|
|
2592
|
-
/** Viewer chrome theme (shared `ViewerTheme`: colors, radius, CSS vars). */
|
|
2593
|
-
theme?: ViewerTheme;
|
|
2594
|
-
/** UI locale (default `'en'`). Dictionaries come from `messages`. */
|
|
2595
|
-
locale?: string;
|
|
2596
|
-
/**
|
|
2597
|
-
* Per-locale `pptx.*` message dictionaries. English falls back to the
|
|
2598
|
-
* built-in shared dictionary; other locales fall back to English.
|
|
2599
|
-
*/
|
|
2600
|
-
messages?: TranslationMessages;
|
|
2601
|
-
/** Zero-based slide to show after load (default 0). */
|
|
2602
|
-
initialSlide?: number;
|
|
2603
|
-
/**
|
|
2604
|
-
* Enable editing (default `false`): click to select, drag/resize/rotate,
|
|
2605
|
-
* inline text editing, keyboard shortcuts, undo/redo, and the toolbar
|
|
2606
|
-
* Save button. Toggle later via `setEditable`.
|
|
2607
|
-
*/
|
|
2608
|
-
editable?: boolean;
|
|
2609
|
-
/**
|
|
2610
|
-
* Legacy flag superseded by {@link editable}; kept so existing option
|
|
2611
|
-
* objects stay type-valid. It has no effect.
|
|
2612
|
-
*/
|
|
2613
|
-
readOnly?: boolean;
|
|
2614
|
-
/** Show the toolbar (default `true`). */
|
|
2615
|
-
showToolbar?: boolean;
|
|
2616
|
-
/** Show the thumbnail sidebar (default `true`). */
|
|
2617
|
-
showThumbnails?: boolean;
|
|
2618
|
-
/**
|
|
2619
|
-
* Build the editing format toolbar row (bold/fill/insert/z-order); default
|
|
2620
|
-
* `true`. The row is only *visible* while editing is enabled.
|
|
2621
|
-
*/
|
|
2622
|
-
showFormatToolbar?: boolean;
|
|
2623
|
-
/**
|
|
2624
|
-
* Build the property inspector panel (position/size/fill/line); default
|
|
2625
|
-
* `true`. Only *visible* while editing is enabled.
|
|
2626
|
-
*/
|
|
2627
|
-
showInspector?: boolean;
|
|
2628
|
-
/**
|
|
2629
|
-
* Custom element-renderer registry. Defaults to `createDefaultRegistry()`;
|
|
2630
|
-
* pass your own (or mutate the default via `getRegistry()`) to add or
|
|
2631
|
-
* override element renderers.
|
|
2632
|
-
*/
|
|
2633
|
-
registry?: ElementRendererRegistry;
|
|
2634
|
-
/**
|
|
2635
|
-
* Opt-in WebGL SmartArt renderer (default `false`): renders `smartArt`
|
|
2636
|
-
* elements as an extruded Three.js scene instead of the flat SVG layout.
|
|
2637
|
-
* `three` is an optional peer dependency, lazily imported only when this is
|
|
2638
|
-
* `true`; when it is unavailable or the scene fails to mount, the SVG
|
|
2639
|
-
* renderer is used instead. Set once at construction (no runtime setter,
|
|
2640
|
-
* mirroring the Vue/React/Angular bindings).
|
|
2641
|
-
*/
|
|
2642
|
-
smartArt3D?: boolean;
|
|
2643
|
-
/**
|
|
2644
|
-
* Enable debounced autosave (default `false`): after each local edit the deck
|
|
2645
|
-
* is re-serialized and stashed in the shared IndexedDB recovery store as a
|
|
2646
|
-
* crash-safety net (it never replaces the user's real Save). The toolbar shows
|
|
2647
|
-
* a small status pill; a snapshot from a prior session is offered through
|
|
2648
|
-
* {@link PptxViewerCallbacks.onAutosaveRecovery}.
|
|
2649
|
-
*/
|
|
2650
|
-
autosave?: boolean;
|
|
2651
|
-
/** Debounce window (ms) between an edit and the persisted snapshot (default 2000). */
|
|
2652
|
-
autosaveIntervalMs?: number;
|
|
2653
|
-
/** IndexedDB recovery key for autosave (default `'presentation.pptx'`). */
|
|
2654
|
-
autosaveFilePath?: string;
|
|
2655
|
-
/**
|
|
2656
|
-
* Start a real-time collaboration session immediately (Yjs over y-websocket
|
|
2657
|
-
* or serverless y-webrtc). Local edits publish to peers and remote edits
|
|
2658
|
-
* merge in granularly; a `role: 'viewer'` config forces read-only. Start or
|
|
2659
|
-
* stop a session later with {@link PptxViewerInstance.startCollaboration} /
|
|
2660
|
-
* {@link PptxViewerInstance.stopCollaboration}.
|
|
2661
|
-
*
|
|
2662
|
-
* Note: media/OLE/3D/ink binary payloads are not carried over the wire (a
|
|
2663
|
-
* shared codec limitation), and a remote update replaces the whole local
|
|
2664
|
-
* slide array, so a joiner's host-provided media can degrade.
|
|
2665
|
-
*/
|
|
2666
|
-
collaboration?: CollaborationConfig;
|
|
2667
|
-
/**
|
|
2668
|
-
* Prefilled values for the built-in Share/Broadcast dialogs' form fields
|
|
2669
|
-
* (e.g. a host-generated display name), mirroring the Vue binding's
|
|
2670
|
-
* `shareDefaults` prop. The broadcast dialog uses `userName` as the
|
|
2671
|
-
* presenter's display name.
|
|
2672
|
-
*/
|
|
2673
|
-
shareDefaults?: ShareDefaults;
|
|
2674
|
-
}
|
|
2675
|
-
/** The viewer handle returned by `createPptxViewer`. */
|
|
2676
|
-
interface PptxViewerInstance {
|
|
2677
|
-
/** Load a presentation from bytes or a Blob/File (replaces the current one). */
|
|
2678
|
-
loadFile(file: Blob | ArrayBuffer | Uint8Array): Promise<void>;
|
|
2679
|
-
/** Fetch and load a presentation from a URL. */
|
|
2680
|
-
loadUrl(url: string): Promise<void>;
|
|
2681
|
-
/** Go to the next slide (no-op on the last slide). */
|
|
2682
|
-
next(): void;
|
|
2683
|
-
/** Go to the previous slide (no-op on the first slide). */
|
|
2684
|
-
prev(): void;
|
|
2685
|
-
/** Jump to a zero-based slide index (clamped). */
|
|
2686
|
-
goToSlide(index: number): void;
|
|
2687
|
-
/** Number of slides in the loaded presentation (0 when none). */
|
|
2688
|
-
getSlideCount(): number;
|
|
2689
|
-
/** Zero-based index of the visible slide. */
|
|
2690
|
-
getCurrentSlide(): number;
|
|
2691
|
-
/** Effective zoom scale (1 = 100%), after fit resolution. */
|
|
2692
|
-
getZoom(): number;
|
|
2693
|
-
/** Set an explicit zoom scale, or `'fit'` for fit-to-viewport. */
|
|
2694
|
-
setZoom(zoom: ZoomLevel): void;
|
|
2695
|
-
zoomIn(): void;
|
|
2696
|
-
zoomOut(): void;
|
|
2697
|
-
zoomToFit(): void;
|
|
2698
|
-
/** Apply a new viewer theme (pass `undefined` to reset to defaults). */
|
|
2699
|
-
setTheme(theme: ViewerTheme | undefined): void;
|
|
2700
|
-
/** Switch the UI locale (rebuilds the chrome labels). */
|
|
2701
|
-
setLocale(locale: string): void;
|
|
2702
|
-
/** Enter presentation mode (real Fullscreen API). */
|
|
2703
|
-
enterPresentation(): Promise<void>;
|
|
2704
|
-
/** Exit presentation mode. */
|
|
2705
|
-
exitPresentation(): Promise<void>;
|
|
2706
|
-
/** Enable or disable editing at runtime (disabling clears the selection). */
|
|
2707
|
-
setEditable(editable: boolean): void;
|
|
2708
|
-
/** Undo the last edit (no-op when the undo stack is empty). */
|
|
2709
|
-
undo(): void;
|
|
2710
|
-
/** Redo the last undone edit (no-op when the redo stack is empty). */
|
|
2711
|
-
redo(): void;
|
|
2712
|
-
canUndo(): boolean;
|
|
2713
|
-
canRedo(): boolean;
|
|
2714
|
-
/** Serialise the (edited) presentation to `.pptx` bytes and clear dirty. */
|
|
2715
|
-
save(): Promise<Uint8Array>;
|
|
2716
|
-
/** `save()` + trigger a browser download (default `presentation.pptx`). */
|
|
2717
|
-
downloadPptx(fileName?: string): Promise<void>;
|
|
2718
|
-
/** Delete the selected element (no-op without a selection). */
|
|
2719
|
-
deleteSelected(): void;
|
|
2720
|
-
/** Id of the selected element, or `null`. */
|
|
2721
|
-
getSelectedElementId(): string | null;
|
|
2722
|
-
/**
|
|
2723
|
-
* Export a slide as a PNG download (defaults to the current slide). Renders
|
|
2724
|
-
* the slide off-screen at scale 1 and rasterises it with `html2canvas-pro`
|
|
2725
|
-
* (dynamically imported), so the first call pays a one-time load cost.
|
|
2726
|
-
*/
|
|
2727
|
-
exportSlidePng(index?: number): Promise<void>;
|
|
2728
|
-
/**
|
|
2729
|
-
* Export every slide as a multi-page PDF download (one slide per page).
|
|
2730
|
-
* `jspdf` is dynamically imported on first use.
|
|
2731
|
-
*/
|
|
2732
|
-
exportPdf(options?: ExportPdfOptions): Promise<void>;
|
|
2733
|
-
/**
|
|
2734
|
-
* Export every slide as an animated GIF download (one frame per slide,
|
|
2735
|
-
* `slideDurationMs` per frame). Slides are captured off-screen like
|
|
2736
|
-
* `exportSlidePng` and encoded with the shared pure-JS GIF89a encoder.
|
|
2737
|
-
*/
|
|
2738
|
-
exportGif(options?: ExportGifOptions): Promise<void>;
|
|
2739
|
-
/**
|
|
2740
|
-
* Export every slide as a WebM video download: each captured slide is held
|
|
2741
|
-
* for its configured duration on a canvas stream recorded by
|
|
2742
|
-
* `MediaRecorder` (codec picked from the shared WebM candidates).
|
|
2743
|
-
*/
|
|
2744
|
-
exportVideo(options?: ExportVideoOptions): Promise<void>;
|
|
2745
|
-
/**
|
|
2746
|
-
* Assemble the printable document (slides / notes / handouts / outline)
|
|
2747
|
-
* and open it in a new print window. Resolves `false` when the popup was
|
|
2748
|
-
* blocked: browsers typically only allow `window.open` inside a user
|
|
2749
|
-
* gesture, so call this from a click handler (or pass a custom
|
|
2750
|
-
* `openPrintWindow` that writes into an iframe you own).
|
|
2751
|
-
*/
|
|
2752
|
-
print(options?: PrintOptions): Promise<boolean>;
|
|
2753
|
-
/** The element-renderer registry in effect (extension point). */
|
|
2754
|
-
getRegistry(): ElementRendererRegistry;
|
|
2755
|
-
/**
|
|
2756
|
-
* Escape hatch: the live `pptx-viewer-core` handler for the loaded file
|
|
2757
|
-
* (or `null`). Enables advanced operations (save, markdown conversion,
|
|
2758
|
-
* archive access) without extra APIs here.
|
|
2759
|
-
*/
|
|
2760
|
-
getHandler(): PptxHandler | null;
|
|
2761
|
-
/**
|
|
2762
|
-
* Start (or restart) a real-time collaboration session. Resolves once the
|
|
2763
|
-
* transport is created; connection status arrives via
|
|
2764
|
-
* {@link PptxViewerCallbacks.onCollaborationStatus}.
|
|
2765
|
-
*/
|
|
2766
|
-
startCollaboration(config: CollaborationConfig): Promise<void>;
|
|
2767
|
-
/** Stop the active collaboration session (no-op when none is running). */
|
|
2768
|
-
stopCollaboration(): void;
|
|
2769
|
-
/** Current collaboration connection status (`'disconnected'` when inactive). */
|
|
2770
|
-
getCollaborationStatus(): ConnectionStatus;
|
|
2771
|
-
/** Force an immediate autosave snapshot (no-op when autosave is disabled). */
|
|
2772
|
-
autosaveNow(): Promise<void>;
|
|
2773
|
-
/** Tear down DOM, listeners, Blob URLs, and the core handler. */
|
|
2774
|
-
destroy(): void;
|
|
2775
|
-
}
|
|
2776
|
-
|
|
2777
|
-
/** The mutable pieces `PptxViewer` owns for one chrome mount lifecycle. */
|
|
2778
|
-
interface ChromeLifecycle {
|
|
2779
|
-
chrome: ViewerChrome;
|
|
2780
|
-
presentation: PresentationController;
|
|
2781
|
-
detachKeyboard: () => void;
|
|
2782
|
-
resizeObserver: ResizeObserver | null;
|
|
2783
|
-
appliedThemeVars: string[];
|
|
2784
|
-
}
|
|
2785
|
-
/** The subset of `PptxViewer` needed to build its `MountChromeDeps`. */
|
|
2786
|
-
interface ChromeHost {
|
|
2787
|
-
doc: Document;
|
|
2788
|
-
container: HTMLElement;
|
|
2789
|
-
t: Translator;
|
|
2790
|
-
options: PptxViewerOptions;
|
|
2791
|
-
store: Store<ViewerState>;
|
|
2792
|
-
renderer: RenderController;
|
|
2793
|
-
lifecycle: ChromeLifecycle;
|
|
2794
|
-
editor: {
|
|
2795
|
-
commitNotes(notes: string): void;
|
|
2796
|
-
getEditActions(): EditActions;
|
|
2797
|
-
getFindReplaceActions(): FindReplaceActions;
|
|
2798
|
-
setDrawTool(tool: DrawTool): void;
|
|
2799
|
-
setDrawColor(color: string): void;
|
|
2800
|
-
setDrawWidth(width: number): void;
|
|
2801
|
-
};
|
|
2802
|
-
prev(): void;
|
|
2803
|
-
next(): void;
|
|
2804
|
-
zoomIn(): void;
|
|
2805
|
-
zoomOut(): void;
|
|
2806
|
-
zoomToFit(): void;
|
|
2807
|
-
undo(): void;
|
|
2808
|
-
redo(): void;
|
|
2809
|
-
downloadPptx(): Promise<void>;
|
|
2810
|
-
toggleNotes(): void;
|
|
2811
|
-
goToSlide(index: number): void;
|
|
2812
|
-
getSlideCount(): number;
|
|
2813
|
-
enterPresentation(): Promise<void>;
|
|
2814
|
-
exitPresentation(): Promise<void>;
|
|
2815
|
-
exportSlidePng(): Promise<void>;
|
|
2816
|
-
exportPdf(): Promise<void>;
|
|
2817
|
-
exportGif(): Promise<void>;
|
|
2818
|
-
exportVideo(): Promise<void>;
|
|
2819
|
-
print(): Promise<boolean>;
|
|
2820
|
-
setTheme(theme: ViewerTheme | undefined): void;
|
|
2821
|
-
}
|
|
2822
|
-
|
|
2823
|
-
/** The export slice of the public viewer API (see `PptxViewerInstance`). */
|
|
2824
|
-
interface ViewerExportApi {
|
|
2825
|
-
/** Export a single slide as a PNG download. Defaults to the current slide. */
|
|
2826
|
-
exportSlidePng(index?: number): Promise<void>;
|
|
2827
|
-
/** Export every slide as a multi-page PDF download (one slide per page). */
|
|
2828
|
-
exportPdf(options?: ExportPdfOptions): Promise<void>;
|
|
2829
|
-
/** Export every slide as an animated GIF download (one frame per slide). */
|
|
2830
|
-
exportGif(options?: ExportGifOptions): Promise<void>;
|
|
2831
|
-
/** Export every slide as a WebM video download (MediaRecorder). */
|
|
2832
|
-
exportVideo(options?: ExportVideoOptions): Promise<void>;
|
|
2833
|
-
/** Open the assembled print document in a print window (`false` = blocked). */
|
|
2834
|
-
print(options?: PrintOptions): Promise<boolean>;
|
|
2835
|
-
}
|
|
2836
|
-
interface ExportLifecycle extends ViewerExportApi {
|
|
2837
|
-
/** Remove the off-screen capture stage from the DOM. */
|
|
2838
|
-
destroy(): void;
|
|
2839
|
-
}
|
|
2840
|
-
/**
|
|
2841
|
-
* Base class implementing the export slice of `PptxViewerInstance` by
|
|
2842
|
-
* delegating to the instance's {@link ExportLifecycle}. `PptxViewer` extends
|
|
2843
|
-
* this, so new export formats are wired here (and in the export controller)
|
|
2844
|
-
* without growing the size-capped `PptxViewer.ts`.
|
|
2845
|
-
*/
|
|
2846
|
-
declare abstract class ViewerExportHost implements ViewerExportApi {
|
|
2847
|
-
protected abstract readonly exporter: ExportLifecycle;
|
|
2848
|
-
exportSlidePng(index?: number): Promise<void>;
|
|
2849
|
-
exportPdf(options?: ExportPdfOptions): Promise<void>;
|
|
2850
|
-
exportGif(options?: ExportGifOptions): Promise<void>;
|
|
2851
|
-
exportVideo(options?: ExportVideoOptions): Promise<void>;
|
|
2852
|
-
print(options?: PrintOptions): Promise<boolean>;
|
|
2853
|
-
}
|
|
2854
|
-
|
|
2855
|
-
/**
|
|
2856
|
-
* The zero-framework PowerPoint viewer. Construct via {@link createPptxViewer}:
|
|
2857
|
-
* builds chrome inside `container`, loads `options.source` when given, and
|
|
2858
|
-
* re-renders through a tiny reactive store.
|
|
2859
|
-
*/
|
|
2860
|
-
declare class PptxViewer extends ViewerExportHost implements PptxViewerInstance, ChromeHost {
|
|
2861
|
-
readonly container: HTMLElement;
|
|
2862
|
-
readonly doc: Document;
|
|
2863
|
-
readonly options: PptxViewerOptions;
|
|
2864
|
-
readonly store: Store<ViewerState>;
|
|
2865
|
-
readonly renderer: RenderController;
|
|
2866
|
-
t: Translator;
|
|
2867
|
-
lifecycle: ChromeLifecycle;
|
|
2868
|
-
editor: EditorController;
|
|
2869
|
-
protected readonly exporter: ExportLifecycle;
|
|
2870
|
-
private readonly loading;
|
|
2871
|
-
private readonly registry;
|
|
2872
|
-
private readonly sessions;
|
|
2873
|
-
private readonly controls;
|
|
2874
|
-
private destroyed;
|
|
2875
|
-
constructor(container: HTMLElement, options?: PptxViewerOptions);
|
|
2876
|
-
loadFile(file: Blob | ArrayBuffer | Uint8Array): Promise<void>;
|
|
2877
|
-
loadUrl(url: string): Promise<void>;
|
|
2878
|
-
next(): void;
|
|
2879
|
-
prev(): void;
|
|
2880
|
-
goToSlide(index: number): void;
|
|
2881
|
-
getSlideCount(): number;
|
|
2882
|
-
getCurrentSlide(): number;
|
|
2883
|
-
getZoom(): number;
|
|
2884
|
-
setZoom(zoom: ZoomLevel): void;
|
|
2885
|
-
zoomIn(): void;
|
|
2886
|
-
zoomOut(): void;
|
|
2887
|
-
zoomToFit(): void;
|
|
2888
|
-
/** Expand/collapse the speaker-notes panel; persists for the instance's life. */
|
|
2889
|
-
toggleNotes(): void;
|
|
2890
|
-
setTheme(theme: ViewerTheme | undefined): void;
|
|
2891
|
-
setLocale(locale: string): void;
|
|
2892
|
-
setEditable(editable: boolean): void;
|
|
2893
|
-
undo(): void;
|
|
2894
|
-
redo(): void;
|
|
2895
|
-
canUndo(): boolean;
|
|
2896
|
-
canRedo(): boolean;
|
|
2897
|
-
save(): Promise<Uint8Array>;
|
|
2898
|
-
downloadPptx(fileName?: string): Promise<void>;
|
|
2899
|
-
deleteSelected(): void;
|
|
2900
|
-
getSelectedElementId(): string | null;
|
|
2901
|
-
enterPresentation(): Promise<void>;
|
|
2902
|
-
exitPresentation(): Promise<void>;
|
|
2903
|
-
getRegistry(): ElementRendererRegistry;
|
|
2904
|
-
getHandler(): PptxHandler | null;
|
|
2905
|
-
startCollaboration(config: CollaborationConfig): Promise<void>;
|
|
2906
|
-
stopCollaboration(): void;
|
|
2907
|
-
getCollaborationStatus(): ConnectionStatus;
|
|
2908
|
-
autosaveNow(): Promise<void>;
|
|
2909
|
-
destroy(): void;
|
|
2910
|
-
private remountChrome;
|
|
2911
|
-
}
|
|
2912
|
-
/** Create a PowerPoint viewer inside `container` (see {@link PptxViewerOptions}). */
|
|
2913
|
-
declare function createPptxViewer(container: HTMLElement, options?: PptxViewerOptions): PptxViewerInstance;
|
|
2914
|
-
|
|
2915
|
-
/** The complete viewer stylesheet text (for hosts that self-manage CSS). */
|
|
2916
|
-
declare function getViewerCss(): string;
|
|
2917
|
-
|
|
2918
|
-
export { type AutosaveRecord, type AutosaveStatus, type CollaborationConfig, type CollaborationRole, type CollaborationTransport, type ConnectionStatus, type CssStyleMap, type ElementRenderContext, type ElementRenderer, type ElementRendererRegistry, type ExportGifOptions, type ExportPdfOptions, type ExportProgress, type ExportVideoOptions, type OpenPrintWindow, type PptxElementType, PptxHandler, PptxViewer, type PptxViewerCallbacks, type PptxViewerInstance, type PptxViewerOptions, type PptxViewerSource, type PrintOptions, type SlideStageOptions, type TranslationMessages, type Translator, type ViewerState, type ZoomLevel, applyStyleMap, createDefaultRegistry, createEl, createElementRendererRegistry, createPptxViewer, createSvgEl, createTranslator, getViewerCss, renderSlideStage };
|