pptx-vanilla-viewer 0.1.2 → 0.2.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 +84 -0
- package/README.md +23 -25
- package/dist/index.cjs +744 -66
- package/dist/index.d.cts +601 -109
- package/dist/index.d.ts +601 -109
- package/dist/index.js +744 -66
- package/package.json +10 -2
package/dist/index.d.cts
CHANGED
|
@@ -1368,9 +1368,144 @@ interface CanvasSize {
|
|
|
1368
1368
|
width: number;
|
|
1369
1369
|
height: number;
|
|
1370
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
|
+
}
|
|
1371
1431
|
/** A neutral CSS map (framework `CSSProperties` are structurally compatible). */
|
|
1372
1432
|
type CssStyleMap = Record<string, string | number>;
|
|
1373
1433
|
|
|
1434
|
+
/**
|
|
1435
|
+
* collaboration-presence.ts: Pure, framework-agnostic logic for the real-time
|
|
1436
|
+
* collaboration subsystem (Yjs-backed presence + remote cursors).
|
|
1437
|
+
*
|
|
1438
|
+
* Everything here is a plain function with no framework / Yjs dependency, so it
|
|
1439
|
+
* can be unit-tested in isolation and shared across the React, Vue, and Angular
|
|
1440
|
+
* bindings. The bindings own the stateful provider lifecycle (creating the
|
|
1441
|
+
* Y.Doc / WebsocketProvider, wiring awareness listeners) and call into these
|
|
1442
|
+
* helpers to validate config, sanitise inbound awareness data, and project it
|
|
1443
|
+
* into render-ready view-models.
|
|
1444
|
+
*
|
|
1445
|
+
* Responsibilities:
|
|
1446
|
+
* - Validate the room id and detect mixed-content (ws:// from https) up front.
|
|
1447
|
+
* - Sanitise inbound awareness data (XSS, bounds, colour, avatar, room id).
|
|
1448
|
+
* - Map awareness state into a `RemoteCursor` view-model for rendering.
|
|
1449
|
+
* - Derive the presence list (remote users only, stale entries dropped).
|
|
1450
|
+
* - Deterministic per-user colour assignment + cursor label formatting.
|
|
1451
|
+
*
|
|
1452
|
+
* This mirrors the React `sanitize.ts` / `usePresenceTracking.ts` helpers and
|
|
1453
|
+
* the Angular `collaboration-helpers.ts` (which predates this shared copy).
|
|
1454
|
+
*/
|
|
1455
|
+
|
|
1456
|
+
/** Connection lifecycle states for the Yjs WebSocket provider. */
|
|
1457
|
+
type ConnectionStatus = 'disconnected' | 'connecting' | 'connected' | 'error';
|
|
1458
|
+
interface AutosaveRecord {
|
|
1459
|
+
key: string;
|
|
1460
|
+
data: Uint8Array;
|
|
1461
|
+
timestamp: number;
|
|
1462
|
+
size: number;
|
|
1463
|
+
}
|
|
1464
|
+
|
|
1465
|
+
/**
|
|
1466
|
+
* Pure handout layout calculations, shared by every binding's print path.
|
|
1467
|
+
*
|
|
1468
|
+
* Handles distributing slides across pages, computing grid dimensions, and
|
|
1469
|
+
* positioning cells within A4 page space. No DOM/framework dependency: callers
|
|
1470
|
+
* render the resulting rectangles however their view layer prefers.
|
|
1471
|
+
*/
|
|
1472
|
+
/** Supported slides-per-page values. */
|
|
1473
|
+
type HandoutSlidesPerPage = 1 | 2 | 3 | 4 | 6 | 9;
|
|
1474
|
+
|
|
1475
|
+
/**
|
|
1476
|
+
* Pure print helpers shared by every binding's print path: settings validation,
|
|
1477
|
+
* slide-range / colour-filter resolution, page-count estimation, HTML markup
|
|
1478
|
+
* builders, escaping, and the full print-document assembler.
|
|
1479
|
+
*
|
|
1480
|
+
* No DOM side effects and no `window.print()`: everything is deterministic and
|
|
1481
|
+
* the binding writes the returned HTML string into a print window. The handout
|
|
1482
|
+
* grid geometry lives in `handout-layout`; this module reuses it.
|
|
1483
|
+
*
|
|
1484
|
+
* ng-packagr constraint honoured here (the Angular binding inlines this source
|
|
1485
|
+
* and compiles it through ng-packagr): NO `String.prototype.replaceAll`
|
|
1486
|
+
* (`escapeHtml` uses `.split(x).join(y)` instead).
|
|
1487
|
+
*/
|
|
1488
|
+
|
|
1489
|
+
/** What to print. */
|
|
1490
|
+
type PrintWhat = 'slides' | 'handouts' | 'notes' | 'outline';
|
|
1491
|
+
/** Page orientation for the printed output. */
|
|
1492
|
+
type PrintOrientation = 'portrait' | 'landscape';
|
|
1493
|
+
/** Colour mode for the printed output. */
|
|
1494
|
+
type PrintColorMode = 'color' | 'grayscale' | 'blackAndWhite';
|
|
1495
|
+
/** Slide range mode. */
|
|
1496
|
+
type PrintSlideRange = 'all' | 'current' | 'custom';
|
|
1497
|
+
/** Resolved print settings emitted on confirm. */
|
|
1498
|
+
interface PrintSettings {
|
|
1499
|
+
printWhat: PrintWhat;
|
|
1500
|
+
orientation: PrintOrientation;
|
|
1501
|
+
colorMode: PrintColorMode;
|
|
1502
|
+
frameSlides: boolean;
|
|
1503
|
+
slidesPerPage: HandoutSlidesPerPage;
|
|
1504
|
+
slideRange: PrintSlideRange;
|
|
1505
|
+
customRangeFrom: number;
|
|
1506
|
+
customRangeTo: number;
|
|
1507
|
+
}
|
|
1508
|
+
|
|
1374
1509
|
/**
|
|
1375
1510
|
* Minimal i18n for the vanilla binding.
|
|
1376
1511
|
*
|
|
@@ -1394,6 +1529,154 @@ type TranslationMessages = Record<string, Record<string, string>>;
|
|
|
1394
1529
|
*/
|
|
1395
1530
|
declare function createTranslator(locale?: string, messages?: TranslationMessages): Translator;
|
|
1396
1531
|
|
|
1532
|
+
/**
|
|
1533
|
+
* A tiny framework-free reactive store: `get` / `set(patch)` / `subscribe`.
|
|
1534
|
+
*
|
|
1535
|
+
* This is deliberately minimal (a few dozen lines, no external deps). It only
|
|
1536
|
+
* carries the vanilla binding's *view state*; all domain logic (parsing,
|
|
1537
|
+
* styles, geometry, text building) stays in `pptx-viewer-core` and
|
|
1538
|
+
* `pptx-viewer-shared`.
|
|
1539
|
+
*/
|
|
1540
|
+
/** Listener invoked after every state change with the next and previous state. */
|
|
1541
|
+
type StoreListener<T> = (state: T, previous: T) => void;
|
|
1542
|
+
interface Store<T extends object> {
|
|
1543
|
+
/** Current state snapshot (do not mutate). */
|
|
1544
|
+
get(): T;
|
|
1545
|
+
/** Shallow-merge a partial patch into the state and notify subscribers. */
|
|
1546
|
+
set(patch: Partial<T>): void;
|
|
1547
|
+
/** Subscribe to state changes; returns an unsubscribe function. */
|
|
1548
|
+
subscribe(listener: StoreListener<T>): () => void;
|
|
1549
|
+
}
|
|
1550
|
+
|
|
1551
|
+
/** `zoom` is either an explicit scale factor (1 = 100%) or fit-to-viewport. */
|
|
1552
|
+
type ZoomLevel = number | 'fit';
|
|
1553
|
+
/**
|
|
1554
|
+
* The vanilla viewer's reactive view state. Kept intentionally flat and small;
|
|
1555
|
+
* everything here is what the DOM render layer consumes.
|
|
1556
|
+
*/
|
|
1557
|
+
interface ViewerState {
|
|
1558
|
+
/** Parsed slides (image/media URLs already patched in by the load pipeline). */
|
|
1559
|
+
slides: P[];
|
|
1560
|
+
/** Slide canvas size in CSS pixels. */
|
|
1561
|
+
canvasSize: CanvasSize;
|
|
1562
|
+
/** Archive-path to displayable URL map for media + poster frames. */
|
|
1563
|
+
mediaDataUrls: Map<string, string>;
|
|
1564
|
+
/** Zero-based index of the visible slide. */
|
|
1565
|
+
currentSlide: number;
|
|
1566
|
+
/** Requested zoom (explicit factor or fit-to-viewport). */
|
|
1567
|
+
zoom: ZoomLevel;
|
|
1568
|
+
/** True while a load is in flight. */
|
|
1569
|
+
loading: boolean;
|
|
1570
|
+
/** Error message from the last failed load, or null. */
|
|
1571
|
+
error: string | null;
|
|
1572
|
+
/** True while presentation (fullscreen) mode is active. */
|
|
1573
|
+
presenting: boolean;
|
|
1574
|
+
/** True when editing interactions (select/move/resize/...) are enabled. */
|
|
1575
|
+
editable: boolean;
|
|
1576
|
+
/** Id of the selected element on the current slide, or null. */
|
|
1577
|
+
selectedElementId: string | null;
|
|
1578
|
+
/** True when the document has unsaved edits (cleared by a save). */
|
|
1579
|
+
dirty: boolean;
|
|
1580
|
+
/**
|
|
1581
|
+
* True while a pointer gesture (drag/resize/rotate) is in flight. Thumbnail
|
|
1582
|
+
* re-renders are deferred until the gesture ends.
|
|
1583
|
+
*/
|
|
1584
|
+
interactionActive: boolean;
|
|
1585
|
+
/**
|
|
1586
|
+
* True when the speaker-notes panel body is expanded. Persists across slide
|
|
1587
|
+
* navigation for the life of the viewer instance (in-memory only).
|
|
1588
|
+
*/
|
|
1589
|
+
notesExpanded: boolean;
|
|
1590
|
+
}
|
|
1591
|
+
|
|
1592
|
+
/**
|
|
1593
|
+
* Insert-element factories for the vanilla editor.
|
|
1594
|
+
*
|
|
1595
|
+
* The pure builders wrap the framework-agnostic core/shared factories
|
|
1596
|
+
* (`createTextElement`, `createShapeElement`, `createConnectorElement`,
|
|
1597
|
+
* `newTableElement`) and centre the new element on the slide canvas. The one
|
|
1598
|
+
* async helper (`pickImageElement`) owns the file-picker + `FileReader` DOM
|
|
1599
|
+
* side effects needed to turn a chosen image file into a data-URL image
|
|
1600
|
+
* element; it too returns a centred, ready-to-insert element.
|
|
1601
|
+
*/
|
|
1602
|
+
/** The shape/text/table element kinds the insert menu can create directly. */
|
|
1603
|
+
type InsertKind = 'text' | 'rect' | 'ellipse' | 'line' | 'table';
|
|
1604
|
+
|
|
1605
|
+
/** The selection-derived state the toolbar reflects (enable/disable + values). */
|
|
1606
|
+
interface FormatSelectionState {
|
|
1607
|
+
hasSelection: boolean;
|
|
1608
|
+
canText: boolean;
|
|
1609
|
+
canShape: boolean;
|
|
1610
|
+
bold: boolean;
|
|
1611
|
+
italic: boolean;
|
|
1612
|
+
underline: boolean;
|
|
1613
|
+
fontSize: number;
|
|
1614
|
+
textColor: string | undefined;
|
|
1615
|
+
highlightColor: string | undefined;
|
|
1616
|
+
fillColor: string | undefined;
|
|
1617
|
+
strokeColor: string | undefined;
|
|
1618
|
+
}
|
|
1619
|
+
interface FormatToolbar {
|
|
1620
|
+
el: HTMLElement;
|
|
1621
|
+
/** Reflect the current selection (enable/disable controls + seed values). */
|
|
1622
|
+
update(state: FormatSelectionState): void;
|
|
1623
|
+
/** Show/hide the whole row (editing mode on/off). */
|
|
1624
|
+
setEditable(editable: boolean): void;
|
|
1625
|
+
}
|
|
1626
|
+
|
|
1627
|
+
/** A geometry patch from the inspector (all fields optional). */
|
|
1628
|
+
interface GeometryPatch {
|
|
1629
|
+
x?: number;
|
|
1630
|
+
y?: number;
|
|
1631
|
+
width?: number;
|
|
1632
|
+
height?: number;
|
|
1633
|
+
rotation?: number;
|
|
1634
|
+
}
|
|
1635
|
+
/**
|
|
1636
|
+
* The formatting / insert / arrange actions exposed to the editing chrome
|
|
1637
|
+
* (format toolbar, inspector, insert menu). Every mutating action is
|
|
1638
|
+
* history-integrated (push -> mutate -> commit) via the shared {@link EditorOps}.
|
|
1639
|
+
*/
|
|
1640
|
+
interface EditActions {
|
|
1641
|
+
toggleBold(): void;
|
|
1642
|
+
toggleItalic(): void;
|
|
1643
|
+
toggleUnderline(): void;
|
|
1644
|
+
changeFontSize(delta: number): void;
|
|
1645
|
+
setFontSize(size: number): void;
|
|
1646
|
+
setTextColor(color: string): void;
|
|
1647
|
+
setHighlightColor(color: string): void;
|
|
1648
|
+
setShapeFill(color: string): void;
|
|
1649
|
+
setShapeStroke(color: string): void;
|
|
1650
|
+
setShapeStrokeWidth(width: number): void;
|
|
1651
|
+
/** Commit an inspector geometry edit (X/Y/W/H/rotation). */
|
|
1652
|
+
setGeometry(patch: GeometryPatch): void;
|
|
1653
|
+
insert(kind: InsertKind): void;
|
|
1654
|
+
insertImage(): Promise<void>;
|
|
1655
|
+
bringForward(): void;
|
|
1656
|
+
sendBackward(): void;
|
|
1657
|
+
bringToFront(): void;
|
|
1658
|
+
sendToBack(): void;
|
|
1659
|
+
}
|
|
1660
|
+
|
|
1661
|
+
/** Selection-derived state the inspector reflects. */
|
|
1662
|
+
interface InspectorState {
|
|
1663
|
+
hasSelection: boolean;
|
|
1664
|
+
canShape: boolean;
|
|
1665
|
+
x: number;
|
|
1666
|
+
y: number;
|
|
1667
|
+
width: number;
|
|
1668
|
+
height: number;
|
|
1669
|
+
rotation: number;
|
|
1670
|
+
fillColor: string | undefined;
|
|
1671
|
+
strokeColor: string | undefined;
|
|
1672
|
+
strokeWidth: number;
|
|
1673
|
+
}
|
|
1674
|
+
interface Inspector {
|
|
1675
|
+
el: HTMLElement;
|
|
1676
|
+
update(state: InspectorState): void;
|
|
1677
|
+
setEditable(editable: boolean): void;
|
|
1678
|
+
}
|
|
1679
|
+
|
|
1397
1680
|
/** State the panel needs to reflect: the slide to read notes from, and whether edits are allowed. */
|
|
1398
1681
|
interface NotesPanelUpdate {
|
|
1399
1682
|
slide: P | undefined;
|
|
@@ -1442,6 +1725,12 @@ interface Toolbar {
|
|
|
1442
1725
|
setEditState(state: ToolbarEditState): void;
|
|
1443
1726
|
/** Reflect the notes panel's expanded/collapsed state on the Notes button. */
|
|
1444
1727
|
setNotesExpanded(expanded: boolean): void;
|
|
1728
|
+
/**
|
|
1729
|
+
* Show the autosave status pill. `label` is the (already localized) text;
|
|
1730
|
+
* `kind` drives the styling hook (`is-saving` / `is-error`). An empty label
|
|
1731
|
+
* hides the pill.
|
|
1732
|
+
*/
|
|
1733
|
+
setAutosaveStatus(label: string, kind: 'idle' | 'saving' | 'saved' | 'error'): void;
|
|
1445
1734
|
}
|
|
1446
1735
|
|
|
1447
1736
|
/** The viewer's static DOM skeleton plus the mutable overlay controls. */
|
|
@@ -1449,6 +1738,10 @@ interface ViewerChrome {
|
|
|
1449
1738
|
/** `.pptxv` root (focusable; keyboard navigation attaches here). */
|
|
1450
1739
|
root: HTMLElement;
|
|
1451
1740
|
toolbar: Toolbar | null;
|
|
1741
|
+
/** Editing format toolbar (bold/fill/insert/z-order); null when disabled. */
|
|
1742
|
+
formatToolbar: FormatToolbar | null;
|
|
1743
|
+
/** Property inspector panel; null when disabled. */
|
|
1744
|
+
inspector: Inspector | null;
|
|
1452
1745
|
thumbnails: ThumbnailRail | null;
|
|
1453
1746
|
/** Scrollable centring viewport around the stage. */
|
|
1454
1747
|
viewport: HTMLElement;
|
|
@@ -1473,6 +1766,78 @@ interface PresentationController {
|
|
|
1473
1766
|
dispose(): void;
|
|
1474
1767
|
}
|
|
1475
1768
|
|
|
1769
|
+
interface EditorController {
|
|
1770
|
+
/** (Re)wire listeners + overlay into the current chrome (after mount). */
|
|
1771
|
+
attachChrome(): void;
|
|
1772
|
+
detachChrome(): void;
|
|
1773
|
+
/** Called by the render controller after every stage render. */
|
|
1774
|
+
onStageRendered(): void;
|
|
1775
|
+
/** True while editing owns the keyboard (selection or inline editing). */
|
|
1776
|
+
capturesKeyboard(): boolean;
|
|
1777
|
+
/** Drop history/selection/dirty state (new content loaded). */
|
|
1778
|
+
reset(): void;
|
|
1779
|
+
setEditable(editable: boolean): void;
|
|
1780
|
+
undo(): void;
|
|
1781
|
+
redo(): void;
|
|
1782
|
+
canUndo(): boolean;
|
|
1783
|
+
canRedo(): boolean;
|
|
1784
|
+
deleteSelected(): void;
|
|
1785
|
+
duplicateSelected(): string | null;
|
|
1786
|
+
getSelectedElementId(): string | null;
|
|
1787
|
+
/** The formatting / insert / arrange actions for the editing chrome. */
|
|
1788
|
+
getEditActions(): EditActions;
|
|
1789
|
+
/** Commit the speaker-notes textarea's plain text onto the current slide. */
|
|
1790
|
+
commitNotes(notes: string): void;
|
|
1791
|
+
save(): Promise<Uint8Array>;
|
|
1792
|
+
downloadPptx(fileName?: string): Promise<void>;
|
|
1793
|
+
destroy(): void;
|
|
1794
|
+
}
|
|
1795
|
+
|
|
1796
|
+
/** Everything the controller needs after a stage (re)render. */
|
|
1797
|
+
interface SyncStageParams {
|
|
1798
|
+
doc: Document;
|
|
1799
|
+
/** The stage host (position: relative), for layering a transition overlay. */
|
|
1800
|
+
stageWrap: HTMLElement;
|
|
1801
|
+
/** The freshly rendered, fully-visible main stage node. */
|
|
1802
|
+
stage: HTMLElement;
|
|
1803
|
+
/** The slide the stage renders, or `undefined` when empty. */
|
|
1804
|
+
slide: P | undefined;
|
|
1805
|
+
/** Zero-based index of the rendered slide. */
|
|
1806
|
+
slideIndex: number;
|
|
1807
|
+
/** True only when the live (fullscreen) presentation stage is active. */
|
|
1808
|
+
presenting: boolean;
|
|
1809
|
+
}
|
|
1810
|
+
/**
|
|
1811
|
+
* The presentation-mode playback state machine for the vanilla binding.
|
|
1812
|
+
*
|
|
1813
|
+
* It owns the click-stepped animation cursor and the slide-transition overlay,
|
|
1814
|
+
* both driven by the shared framework-agnostic helpers. It is consulted from
|
|
1815
|
+
* two seams in the rebuild-per-change render flow:
|
|
1816
|
+
*
|
|
1817
|
+
* - {@link PresentationPlayback.syncStage} runs after every stage render:
|
|
1818
|
+
* on a slide entry it rebuilds the click groups, resets the step, hides
|
|
1819
|
+
* pending entrances, and (when the slide changed mid-show) plays the
|
|
1820
|
+
* incoming slide's transition over a snapshot of the outgoing stage.
|
|
1821
|
+
* - {@link PresentationPlayback.advance} runs on each forward navigation
|
|
1822
|
+
* key/tap while presenting: it reveals the next animation build in place
|
|
1823
|
+
* (no rebuild) and reports whether a build remained, so the caller only
|
|
1824
|
+
* advances the slide once the timeline is exhausted.
|
|
1825
|
+
*/
|
|
1826
|
+
interface PresentationPlayback {
|
|
1827
|
+
/**
|
|
1828
|
+
* Reveal the next on-click animation build for the current slide. Returns
|
|
1829
|
+
* `true` if a build was revealed (stay on the slide); `false` when the
|
|
1830
|
+
* slide's builds are exhausted (the caller should advance to the next slide).
|
|
1831
|
+
*/
|
|
1832
|
+
advance(): boolean;
|
|
1833
|
+
/** True when every click group on the current slide has been revealed. */
|
|
1834
|
+
isComplete(): boolean;
|
|
1835
|
+
/** Sync playback + transitions after a stage (re)render. */
|
|
1836
|
+
syncStage(params: SyncStageParams): void;
|
|
1837
|
+
/** Cancel any running transition and forget all per-slide state. */
|
|
1838
|
+
reset(): void;
|
|
1839
|
+
}
|
|
1840
|
+
|
|
1476
1841
|
/** Discriminant values of the {@link PptxElement} union (`'text'`, `'chart'`, ...). */
|
|
1477
1842
|
type PptxElementType = a['type'];
|
|
1478
1843
|
/**
|
|
@@ -1620,79 +1985,137 @@ declare function renderSlideStage(options: SlideStageOptions): HTMLElement;
|
|
|
1620
1985
|
*/
|
|
1621
1986
|
declare function createDefaultRegistry(): ElementRendererRegistry;
|
|
1622
1987
|
|
|
1988
|
+
interface RenderController {
|
|
1989
|
+
/** Re-render everything (used after a chrome rebuild). */
|
|
1990
|
+
renderAll(): void;
|
|
1991
|
+
/** Re-render the main stage + toolbar counters at the current state. */
|
|
1992
|
+
renderStage(): void;
|
|
1993
|
+
/** Rebuild the thumbnail rail from the current slide list. */
|
|
1994
|
+
renderThumbnails(): void;
|
|
1995
|
+
/** Resolve the requested zoom into a concrete scale factor. */
|
|
1996
|
+
effectiveScale(): number;
|
|
1997
|
+
/**
|
|
1998
|
+
* Presentation-mode animation/transition playback, driven by the stage
|
|
1999
|
+
* rebuild flow. Navigation (`viewer-controls`) consults `advance()` so a
|
|
2000
|
+
* "next" first steps the on-click animation timeline before advancing slides.
|
|
2001
|
+
*/
|
|
2002
|
+
readonly presentationPlayback: PresentationPlayback;
|
|
2003
|
+
}
|
|
2004
|
+
|
|
1623
2005
|
/**
|
|
1624
|
-
*
|
|
2006
|
+
* Debounced autosave for the vanilla viewer, layered on the shared IndexedDB
|
|
2007
|
+
* recovery store (`pptx-viewer-shared/autosave-store`).
|
|
1625
2008
|
*
|
|
1626
|
-
*
|
|
1627
|
-
*
|
|
1628
|
-
*
|
|
1629
|
-
* `
|
|
2009
|
+
* Semantics mirror the React/Vue bindings: a local edit marks the document
|
|
2010
|
+
* dirty; a debounce timer then re-serializes the deck through
|
|
2011
|
+
* `PptxHandler.save` and persists it under `filePath` via
|
|
2012
|
+
* `saveAutosaveSnapshot` (evicting the oldest record on quota exhaustion). The
|
|
2013
|
+
* recovery blob is a crash-safety net only; it never clears the editor's dirty
|
|
2014
|
+
* flag or stands in for the user's real Save.
|
|
2015
|
+
*
|
|
2016
|
+
* On construction it probes `getAutosaveSnapshot(filePath)` and, when a snapshot
|
|
2017
|
+
* from a previous session exists, offers it back through `onRecovery` so the
|
|
2018
|
+
* host can decide whether to restore it (e.g. via `loadFile`).
|
|
1630
2019
|
*/
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
get(): T;
|
|
1636
|
-
/** Shallow-merge a partial patch into the state and notify subscribers. */
|
|
1637
|
-
set(patch: Partial<T>): void;
|
|
1638
|
-
/** Subscribe to state changes; returns an unsubscribe function. */
|
|
1639
|
-
subscribe(listener: StoreListener<T>): () => void;
|
|
1640
|
-
}
|
|
2020
|
+
type AutosaveStatus = 'idle' | 'saving' | 'saved' | 'error';
|
|
2021
|
+
|
|
2022
|
+
/** Per-slide progress callback: `(currentSlideIndex, totalSlides)`. */
|
|
2023
|
+
type ExportProgress = (current: number, total: number) => void;
|
|
1641
2024
|
|
|
1642
|
-
/** `zoom` is either an explicit scale factor (1 = 100%) or fit-to-viewport. */
|
|
1643
|
-
type ZoomLevel = number | 'fit';
|
|
1644
2025
|
/**
|
|
1645
|
-
*
|
|
1646
|
-
*
|
|
2026
|
+
* Animated-GIF export for the vanilla binding. All slides are captured (one
|
|
2027
|
+
* frame per slide) via the injected `rasterizeSlide`, then encoded with the
|
|
2028
|
+
* shared pure-JS GIF89a encoder (`pptx-viewer-shared` `gif-encoder`: median-cut
|
|
2029
|
+
* quantisation + LZW). Frame timing comes from the shared `planGifFrames`
|
|
2030
|
+
* planner and oversized captures are downscaled via `clampGifDimensions`; only
|
|
2031
|
+
* the DOM capture / canvas scaling / Blob download driver lives here.
|
|
1647
2032
|
*/
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
slides: P[];
|
|
1651
|
-
/** Slide canvas size in CSS pixels. */
|
|
1652
|
-
canvasSize: CanvasSize;
|
|
1653
|
-
/** Archive-path to displayable URL map for media + poster frames. */
|
|
1654
|
-
mediaDataUrls: Map<string, string>;
|
|
1655
|
-
/** Zero-based index of the visible slide. */
|
|
1656
|
-
currentSlide: number;
|
|
1657
|
-
/** Requested zoom (explicit factor or fit-to-viewport). */
|
|
1658
|
-
zoom: ZoomLevel;
|
|
1659
|
-
/** True while a load is in flight. */
|
|
1660
|
-
loading: boolean;
|
|
1661
|
-
/** Error message from the last failed load, or null. */
|
|
1662
|
-
error: string | null;
|
|
1663
|
-
/** True while presentation (fullscreen) mode is active. */
|
|
1664
|
-
presenting: boolean;
|
|
1665
|
-
/** True when editing interactions (select/move/resize/...) are enabled. */
|
|
1666
|
-
editable: boolean;
|
|
1667
|
-
/** Id of the selected element on the current slide, or null. */
|
|
1668
|
-
selectedElementId: string | null;
|
|
1669
|
-
/** True when the document has unsaved edits (cleared by a save). */
|
|
1670
|
-
dirty: boolean;
|
|
2033
|
+
/** Options for the animated-GIF export (all slides, one frame per slide). */
|
|
2034
|
+
interface ExportGifOptions {
|
|
1671
2035
|
/**
|
|
1672
|
-
*
|
|
1673
|
-
*
|
|
2036
|
+
* Duration each slide is shown, in milliseconds (default 2000). Per-slide
|
|
2037
|
+
* overrides can be supplied via {@link ExportGifOptions.slideTimingsMs}.
|
|
1674
2038
|
*/
|
|
1675
|
-
|
|
2039
|
+
slideDurationMs?: number;
|
|
1676
2040
|
/**
|
|
1677
|
-
*
|
|
1678
|
-
*
|
|
2041
|
+
* Per-slide duration overrides in milliseconds (index maps to slide index,
|
|
2042
|
+
* e.g. rehearsed timings). Flows through the shared `planGifFrames` plan
|
|
2043
|
+
* into per-frame GIF delays.
|
|
1679
2044
|
*/
|
|
1680
|
-
|
|
2045
|
+
slideTimingsMs?: number[];
|
|
2046
|
+
/**
|
|
2047
|
+
* Cap on the longer side of the encoded frames, in pixels (default 1920).
|
|
2048
|
+
* Captured canvases larger than this are downscaled before quantisation,
|
|
2049
|
+
* keeping encode time and file size manageable.
|
|
2050
|
+
*/
|
|
2051
|
+
maxDimension?: number;
|
|
2052
|
+
/** Capture-phase progress callback: `(currentSlide, totalSlides)`. */
|
|
2053
|
+
onProgress?: ExportProgress;
|
|
2054
|
+
/** Abort the export early; the capture loop checks this between slides. */
|
|
2055
|
+
signal?: AbortSignal;
|
|
1681
2056
|
}
|
|
1682
2057
|
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
2058
|
+
/**
|
|
2059
|
+
* Print for the vanilla binding, assembled entirely from the shared print
|
|
2060
|
+
* module (`pptx-viewer-shared` `print-document`): `validatePrintSettings`,
|
|
2061
|
+
* `computeSlideIndices` / `computeColorFilter`, the `build*Html` body markup
|
|
2062
|
+
* builders, and the DOMPurify-hardened `buildPrintHtmlDocument` assembler.
|
|
2063
|
+
* Only the drivers live here: rasterising the selected slides to data URLs and
|
|
2064
|
+
* writing the document into a print window. Vanilla port of Vue's `usePrint`
|
|
2065
|
+
* raster path (slides / notes / handouts / outline).
|
|
2066
|
+
*/
|
|
2067
|
+
/**
|
|
2068
|
+
* Open a print window for a complete HTML document and trigger printing.
|
|
2069
|
+
* Returns `false` when the window could not be opened (popup blocker).
|
|
2070
|
+
*/
|
|
2071
|
+
type OpenPrintWindow = (htmlDocument: string) => boolean;
|
|
2072
|
+
/**
|
|
2073
|
+
* Options for `print`: any subset of the shared `PrintSettings` (unspecified
|
|
2074
|
+
* fields fall back to `DEFAULT_PRINT_SETTINGS`, i.e. all slides, landscape,
|
|
2075
|
+
* full colour) plus progress/abort and a print-window override.
|
|
2076
|
+
*/
|
|
2077
|
+
interface PrintOptions extends Partial<PrintSettings> {
|
|
2078
|
+
/** Rasterisation progress callback: `(currentSlide, totalSlidesToPrint)`. */
|
|
2079
|
+
onProgress?: ExportProgress;
|
|
2080
|
+
/** Abort before the window opens; checked between slide captures. */
|
|
2081
|
+
signal?: AbortSignal;
|
|
2082
|
+
/**
|
|
2083
|
+
* Override how the assembled document is opened (e.g. write it into a
|
|
2084
|
+
* hidden iframe). Popup-blocker caveat: the default opener uses
|
|
2085
|
+
* `window.open`, which browsers typically only allow inside a user
|
|
2086
|
+
* gesture, so call `print()` from a click handler; when the popup is
|
|
2087
|
+
* blocked the returned promise resolves `false`.
|
|
2088
|
+
*/
|
|
2089
|
+
openPrintWindow?: OpenPrintWindow;
|
|
2090
|
+
}
|
|
2091
|
+
|
|
2092
|
+
/**
|
|
2093
|
+
* WebM video export for the vanilla binding, driven by the shared `video-plan`
|
|
2094
|
+
* module: `planVideoSegments` (per-slide segment timing + frame counts),
|
|
2095
|
+
* `fpsToFrameIntervalMs` (draw-loop pacing), and `pickSupportedMimeType` over
|
|
2096
|
+
* `WEBM_MIME_CANDIDATES` (MediaRecorder codec selection). Only the browser
|
|
2097
|
+
* driver lives here: capture each slide to a canvas, replay the canvases onto
|
|
2098
|
+
* a recording canvas fed to `captureStream()` + `MediaRecorder`, and download
|
|
2099
|
+
* the resulting Blob. Vanilla port of React's `exportAllSlidesAsVideo`.
|
|
2100
|
+
*/
|
|
2101
|
+
/** Options for the WebM video export (all slides). */
|
|
2102
|
+
interface ExportVideoOptions {
|
|
2103
|
+
/** Duration each slide is held, in milliseconds (default 3000). */
|
|
2104
|
+
slideDurationMs?: number;
|
|
2105
|
+
/** Per-slide duration overrides in milliseconds (index maps to slide index). */
|
|
2106
|
+
slideTimingsMs?: number[];
|
|
2107
|
+
/** Recording frame rate in frames per second (default 30). */
|
|
2108
|
+
fps?: number;
|
|
2109
|
+
/** MediaRecorder video bitrate in bits per second (default 5,000,000). */
|
|
2110
|
+
videoBitsPerSecond?: number;
|
|
2111
|
+
/** Capture-phase progress callback: `(currentSlide, totalSlides)`. */
|
|
2112
|
+
onProgress?: ExportProgress;
|
|
2113
|
+
/** Recording-phase progress callback: `(currentSlide, totalSlides)`. */
|
|
2114
|
+
onRecordProgress?: ExportProgress;
|
|
2115
|
+
/** Abort the export early; checked between slides and between frames. */
|
|
2116
|
+
signal?: AbortSignal;
|
|
1692
2117
|
}
|
|
1693
2118
|
|
|
1694
|
-
/** Per-slide progress callback: `(currentSlideIndex, totalSlides)`. */
|
|
1695
|
-
type ExportProgress = (current: number, total: number) => void;
|
|
1696
2119
|
/** Options for the multi-slide PDF export (progress + cooperative cancel). */
|
|
1697
2120
|
interface ExportPdfOptions {
|
|
1698
2121
|
/** Capture-phase progress callback: `(currentSlide, totalSlides)`. */
|
|
@@ -1707,13 +2130,6 @@ interface ExportPdfOptions {
|
|
|
1707
2130
|
*/
|
|
1708
2131
|
type PptxViewerSource = ArrayBuffer | Uint8Array | Blob | string;
|
|
1709
2132
|
|
|
1710
|
-
/**
|
|
1711
|
-
* Public API types for the vanilla (zero-framework) PowerPoint viewer.
|
|
1712
|
-
*
|
|
1713
|
-
* Derived from the Vue binding's `PowerPointViewerProps` / emits, translated
|
|
1714
|
-
* to plain options + callback functions (there is no framework event system
|
|
1715
|
-
* to emit through).
|
|
1716
|
-
*/
|
|
1717
2133
|
/** Callbacks mirroring the Vue component's emits. */
|
|
1718
2134
|
interface PptxViewerCallbacks {
|
|
1719
2135
|
/** Fired after a presentation loads successfully. */
|
|
@@ -1735,6 +2151,16 @@ interface PptxViewerCallbacks {
|
|
|
1735
2151
|
onDirtyChange?: (dirty: boolean) => void;
|
|
1736
2152
|
/** Fired when the selected element changes (`null` = no selection). */
|
|
1737
2153
|
onSelectionChange?: (elementId: string | null) => void;
|
|
2154
|
+
/** Fired on every autosave lifecycle transition (`saving`/`saved`/`error`). */
|
|
2155
|
+
onAutosaveStatus?: (status: AutosaveStatus) => void;
|
|
2156
|
+
/**
|
|
2157
|
+
* Offered a recovery snapshot found in the shared IndexedDB store on start
|
|
2158
|
+
* (a previous session's autosave for the same `autosaveFilePath`). The host
|
|
2159
|
+
* decides whether to restore it, e.g. `viewer.loadFile(record.data)`.
|
|
2160
|
+
*/
|
|
2161
|
+
onAutosaveRecovery?: (record: AutosaveRecord) => void;
|
|
2162
|
+
/** Fired on every collaboration connection-status transition. */
|
|
2163
|
+
onCollaborationStatus?: (status: ConnectionStatus) => void;
|
|
1738
2164
|
}
|
|
1739
2165
|
interface PptxViewerOptions extends PptxViewerCallbacks {
|
|
1740
2166
|
/**
|
|
@@ -1769,6 +2195,16 @@ interface PptxViewerOptions extends PptxViewerCallbacks {
|
|
|
1769
2195
|
showToolbar?: boolean;
|
|
1770
2196
|
/** Show the thumbnail sidebar (default `true`). */
|
|
1771
2197
|
showThumbnails?: boolean;
|
|
2198
|
+
/**
|
|
2199
|
+
* Build the editing format toolbar row (bold/fill/insert/z-order); default
|
|
2200
|
+
* `true`. The row is only *visible* while editing is enabled.
|
|
2201
|
+
*/
|
|
2202
|
+
showFormatToolbar?: boolean;
|
|
2203
|
+
/**
|
|
2204
|
+
* Build the property inspector panel (position/size/fill/line); default
|
|
2205
|
+
* `true`. Only *visible* while editing is enabled.
|
|
2206
|
+
*/
|
|
2207
|
+
showInspector?: boolean;
|
|
1772
2208
|
/**
|
|
1773
2209
|
* Custom element-renderer registry. Defaults to `createDefaultRegistry()`;
|
|
1774
2210
|
* pass your own (or mutate the default via `getRegistry()`) to add or
|
|
@@ -1784,6 +2220,30 @@ interface PptxViewerOptions extends PptxViewerCallbacks {
|
|
|
1784
2220
|
* mirroring the Vue/React/Angular bindings).
|
|
1785
2221
|
*/
|
|
1786
2222
|
smartArt3D?: boolean;
|
|
2223
|
+
/**
|
|
2224
|
+
* Enable debounced autosave (default `false`): after each local edit the deck
|
|
2225
|
+
* is re-serialized and stashed in the shared IndexedDB recovery store as a
|
|
2226
|
+
* crash-safety net (it never replaces the user's real Save). The toolbar shows
|
|
2227
|
+
* a small status pill; a snapshot from a prior session is offered through
|
|
2228
|
+
* {@link PptxViewerCallbacks.onAutosaveRecovery}.
|
|
2229
|
+
*/
|
|
2230
|
+
autosave?: boolean;
|
|
2231
|
+
/** Debounce window (ms) between an edit and the persisted snapshot (default 2000). */
|
|
2232
|
+
autosaveIntervalMs?: number;
|
|
2233
|
+
/** IndexedDB recovery key for autosave (default `'presentation.pptx'`). */
|
|
2234
|
+
autosaveFilePath?: string;
|
|
2235
|
+
/**
|
|
2236
|
+
* Start a real-time collaboration session immediately (Yjs over y-websocket
|
|
2237
|
+
* or serverless y-webrtc). Local edits publish to peers and remote edits
|
|
2238
|
+
* merge in granularly; a `role: 'viewer'` config forces read-only. Start or
|
|
2239
|
+
* stop a session later with {@link PptxViewerInstance.startCollaboration} /
|
|
2240
|
+
* {@link PptxViewerInstance.stopCollaboration}.
|
|
2241
|
+
*
|
|
2242
|
+
* Note: media/OLE/3D/ink binary payloads are not carried over the wire (a
|
|
2243
|
+
* shared codec limitation), and a remote update replaces the whole local
|
|
2244
|
+
* slide array, so a joiner's host-provided media can degrade.
|
|
2245
|
+
*/
|
|
2246
|
+
collaboration?: CollaborationConfig;
|
|
1787
2247
|
}
|
|
1788
2248
|
/** The viewer handle returned by `createPptxViewer`. */
|
|
1789
2249
|
interface PptxViewerInstance {
|
|
@@ -1843,6 +2303,26 @@ interface PptxViewerInstance {
|
|
|
1843
2303
|
* `jspdf` is dynamically imported on first use.
|
|
1844
2304
|
*/
|
|
1845
2305
|
exportPdf(options?: ExportPdfOptions): Promise<void>;
|
|
2306
|
+
/**
|
|
2307
|
+
* Export every slide as an animated GIF download (one frame per slide,
|
|
2308
|
+
* `slideDurationMs` per frame). Slides are captured off-screen like
|
|
2309
|
+
* `exportSlidePng` and encoded with the shared pure-JS GIF89a encoder.
|
|
2310
|
+
*/
|
|
2311
|
+
exportGif(options?: ExportGifOptions): Promise<void>;
|
|
2312
|
+
/**
|
|
2313
|
+
* Export every slide as a WebM video download: each captured slide is held
|
|
2314
|
+
* for its configured duration on a canvas stream recorded by
|
|
2315
|
+
* `MediaRecorder` (codec picked from the shared WebM candidates).
|
|
2316
|
+
*/
|
|
2317
|
+
exportVideo(options?: ExportVideoOptions): Promise<void>;
|
|
2318
|
+
/**
|
|
2319
|
+
* Assemble the printable document (slides / notes / handouts / outline)
|
|
2320
|
+
* and open it in a new print window. Resolves `false` when the popup was
|
|
2321
|
+
* blocked: browsers typically only allow `window.open` inside a user
|
|
2322
|
+
* gesture, so call this from a click handler (or pass a custom
|
|
2323
|
+
* `openPrintWindow` that writes into an iframe you own).
|
|
2324
|
+
*/
|
|
2325
|
+
print(options?: PrintOptions): Promise<boolean>;
|
|
1846
2326
|
/** The element-renderer registry in effect (extension point). */
|
|
1847
2327
|
getRegistry(): ElementRendererRegistry;
|
|
1848
2328
|
/**
|
|
@@ -1851,6 +2331,18 @@ interface PptxViewerInstance {
|
|
|
1851
2331
|
* archive access) without extra APIs here.
|
|
1852
2332
|
*/
|
|
1853
2333
|
getHandler(): PptxHandler | null;
|
|
2334
|
+
/**
|
|
2335
|
+
* Start (or restart) a real-time collaboration session. Resolves once the
|
|
2336
|
+
* transport is created; connection status arrives via
|
|
2337
|
+
* {@link PptxViewerCallbacks.onCollaborationStatus}.
|
|
2338
|
+
*/
|
|
2339
|
+
startCollaboration(config: CollaborationConfig): Promise<void>;
|
|
2340
|
+
/** Stop the active collaboration session (no-op when none is running). */
|
|
2341
|
+
stopCollaboration(): void;
|
|
2342
|
+
/** Current collaboration connection status (`'disconnected'` when inactive). */
|
|
2343
|
+
getCollaborationStatus(): ConnectionStatus;
|
|
2344
|
+
/** Force an immediate autosave snapshot (no-op when autosave is disabled). */
|
|
2345
|
+
autosaveNow(): Promise<void>;
|
|
1854
2346
|
/** Tear down DOM, listeners, Blob URLs, and the core handler. */
|
|
1855
2347
|
destroy(): void;
|
|
1856
2348
|
}
|
|
@@ -1874,6 +2366,7 @@ interface ChromeHost {
|
|
|
1874
2366
|
lifecycle: ChromeLifecycle;
|
|
1875
2367
|
editor: {
|
|
1876
2368
|
commitNotes(notes: string): void;
|
|
2369
|
+
getEditActions(): EditActions;
|
|
1877
2370
|
};
|
|
1878
2371
|
prev(): void;
|
|
1879
2372
|
next(): void;
|
|
@@ -1890,39 +2383,44 @@ interface ChromeHost {
|
|
|
1890
2383
|
exitPresentation(): Promise<void>;
|
|
1891
2384
|
}
|
|
1892
2385
|
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
/**
|
|
1898
|
-
|
|
1899
|
-
/**
|
|
1900
|
-
|
|
1901
|
-
/**
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
deleteSelected(): void;
|
|
1909
|
-
duplicateSelected(): string | null;
|
|
1910
|
-
getSelectedElementId(): string | null;
|
|
1911
|
-
/** Commit the speaker-notes textarea's plain text onto the current slide. */
|
|
1912
|
-
commitNotes(notes: string): void;
|
|
1913
|
-
save(): Promise<Uint8Array>;
|
|
1914
|
-
downloadPptx(fileName?: string): Promise<void>;
|
|
2386
|
+
/** The export slice of the public viewer API (see `PptxViewerInstance`). */
|
|
2387
|
+
interface ViewerExportApi {
|
|
2388
|
+
/** Export a single slide as a PNG download. Defaults to the current slide. */
|
|
2389
|
+
exportSlidePng(index?: number): Promise<void>;
|
|
2390
|
+
/** Export every slide as a multi-page PDF download (one slide per page). */
|
|
2391
|
+
exportPdf(options?: ExportPdfOptions): Promise<void>;
|
|
2392
|
+
/** Export every slide as an animated GIF download (one frame per slide). */
|
|
2393
|
+
exportGif(options?: ExportGifOptions): Promise<void>;
|
|
2394
|
+
/** Export every slide as a WebM video download (MediaRecorder). */
|
|
2395
|
+
exportVideo(options?: ExportVideoOptions): Promise<void>;
|
|
2396
|
+
/** Open the assembled print document in a print window (`false` = blocked). */
|
|
2397
|
+
print(options?: PrintOptions): Promise<boolean>;
|
|
2398
|
+
}
|
|
2399
|
+
interface ExportLifecycle extends ViewerExportApi {
|
|
2400
|
+
/** Remove the off-screen capture stage from the DOM. */
|
|
1915
2401
|
destroy(): void;
|
|
1916
2402
|
}
|
|
2403
|
+
/**
|
|
2404
|
+
* Base class implementing the export slice of `PptxViewerInstance` by
|
|
2405
|
+
* delegating to the instance's {@link ExportLifecycle}. `PptxViewer` extends
|
|
2406
|
+
* this, so new export formats are wired here (and in the export controller)
|
|
2407
|
+
* without growing the size-capped `PptxViewer.ts`.
|
|
2408
|
+
*/
|
|
2409
|
+
declare abstract class ViewerExportHost implements ViewerExportApi {
|
|
2410
|
+
protected abstract readonly exporter: ExportLifecycle;
|
|
2411
|
+
exportSlidePng(index?: number): Promise<void>;
|
|
2412
|
+
exportPdf(options?: ExportPdfOptions): Promise<void>;
|
|
2413
|
+
exportGif(options?: ExportGifOptions): Promise<void>;
|
|
2414
|
+
exportVideo(options?: ExportVideoOptions): Promise<void>;
|
|
2415
|
+
print(options?: PrintOptions): Promise<boolean>;
|
|
2416
|
+
}
|
|
1917
2417
|
|
|
1918
2418
|
/**
|
|
1919
|
-
* The zero-framework PowerPoint viewer. Construct via {@link createPptxViewer}
|
|
1920
|
-
*
|
|
1921
|
-
*
|
|
1922
|
-
* tiny reactive store. All parsing lives in `pptx-viewer-core`; all pure
|
|
1923
|
-
* render logic in `pptx-viewer-shared`.
|
|
2419
|
+
* The zero-framework PowerPoint viewer. Construct via {@link createPptxViewer}:
|
|
2420
|
+
* builds chrome inside `container`, loads `options.source` when given, and
|
|
2421
|
+
* re-renders through a tiny reactive store.
|
|
1924
2422
|
*/
|
|
1925
|
-
declare class PptxViewer implements PptxViewerInstance, ChromeHost {
|
|
2423
|
+
declare class PptxViewer extends ViewerExportHost implements PptxViewerInstance, ChromeHost {
|
|
1926
2424
|
readonly container: HTMLElement;
|
|
1927
2425
|
readonly doc: Document;
|
|
1928
2426
|
readonly options: PptxViewerOptions;
|
|
@@ -1931,9 +2429,11 @@ declare class PptxViewer implements PptxViewerInstance, ChromeHost {
|
|
|
1931
2429
|
t: Translator;
|
|
1932
2430
|
lifecycle: ChromeLifecycle;
|
|
1933
2431
|
editor: EditorController;
|
|
2432
|
+
protected readonly exporter: ExportLifecycle;
|
|
1934
2433
|
private readonly loading;
|
|
1935
|
-
private readonly exportLifecycle;
|
|
1936
2434
|
private readonly registry;
|
|
2435
|
+
private readonly sessions;
|
|
2436
|
+
private readonly controls;
|
|
1937
2437
|
private destroyed;
|
|
1938
2438
|
constructor(container: HTMLElement, options?: PptxViewerOptions);
|
|
1939
2439
|
loadFile(file: Blob | ArrayBuffer | Uint8Array): Promise<void>;
|
|
@@ -1960,30 +2460,22 @@ declare class PptxViewer implements PptxViewerInstance, ChromeHost {
|
|
|
1960
2460
|
save(): Promise<Uint8Array>;
|
|
1961
2461
|
downloadPptx(fileName?: string): Promise<void>;
|
|
1962
2462
|
deleteSelected(): void;
|
|
1963
|
-
exportSlidePng(index?: number): Promise<void>;
|
|
1964
|
-
exportPdf(options?: ExportPdfOptions): Promise<void>;
|
|
1965
2463
|
getSelectedElementId(): string | null;
|
|
1966
2464
|
enterPresentation(): Promise<void>;
|
|
1967
2465
|
exitPresentation(): Promise<void>;
|
|
1968
2466
|
getRegistry(): ElementRendererRegistry;
|
|
1969
2467
|
getHandler(): PptxHandler | null;
|
|
2468
|
+
startCollaboration(config: CollaborationConfig): Promise<void>;
|
|
2469
|
+
stopCollaboration(): void;
|
|
2470
|
+
getCollaborationStatus(): ConnectionStatus;
|
|
2471
|
+
autosaveNow(): Promise<void>;
|
|
1970
2472
|
destroy(): void;
|
|
1971
2473
|
private remountChrome;
|
|
1972
2474
|
}
|
|
1973
|
-
/**
|
|
1974
|
-
* Create a PowerPoint viewer inside `container`.
|
|
1975
|
-
*
|
|
1976
|
-
* ```ts
|
|
1977
|
-
* import { createPptxViewer } from 'pptx-vanilla-viewer';
|
|
1978
|
-
* const viewer = createPptxViewer(document.querySelector('#host')!, {
|
|
1979
|
-
* source: '/deck.pptx',
|
|
1980
|
-
* onSlideChange: (i) => console.log('slide', i + 1),
|
|
1981
|
-
* });
|
|
1982
|
-
* ```
|
|
1983
|
-
*/
|
|
2475
|
+
/** Create a PowerPoint viewer inside `container` (see {@link PptxViewerOptions}). */
|
|
1984
2476
|
declare function createPptxViewer(container: HTMLElement, options?: PptxViewerOptions): PptxViewerInstance;
|
|
1985
2477
|
|
|
1986
2478
|
/** The complete viewer stylesheet text (for hosts that self-manage CSS). */
|
|
1987
2479
|
declare function getViewerCss(): string;
|
|
1988
2480
|
|
|
1989
|
-
export { type CssStyleMap, type ElementRenderContext, type ElementRenderer, type ElementRendererRegistry, type ExportPdfOptions, type ExportProgress, type PptxElementType, PptxHandler, PptxViewer, type PptxViewerCallbacks, type PptxViewerInstance, type PptxViewerOptions, type PptxViewerSource, type SlideStageOptions, type TranslationMessages, type Translator, type ViewerState, type ZoomLevel, applyStyleMap, createDefaultRegistry, createEl, createElementRendererRegistry, createPptxViewer, createSvgEl, createTranslator, getViewerCss, renderSlideStage };
|
|
2481
|
+
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 };
|