pptx-react-viewer 3.12.0 → 3.14.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 +48 -0
- package/dist/{AiChatPanel-TXCDQDHD.js → AiChatPanel-42X7I5I2.js} +32 -32
- package/dist/AiChatPanel-42X7I5I2.js.br +0 -0
- package/dist/AiChatPanel-42X7I5I2.js.gz +0 -0
- package/dist/{AiChatPanel-SCA4RLFI.mjs → AiChatPanel-NJBUCO4X.mjs} +11 -11
- package/dist/AiChatPanel-NJBUCO4X.mjs.br +0 -0
- package/dist/AiChatPanel-NJBUCO4X.mjs.gz +0 -0
- package/dist/{Area3DChartScene-YAK6W2J5.js → Area3DChartScene-IDS5APPJ.js} +2 -2
- package/dist/Area3DChartScene-IDS5APPJ.js.br +0 -0
- package/dist/Area3DChartScene-IDS5APPJ.js.gz +0 -0
- package/dist/{Area3DChartScene-NSV5AIMM.mjs → Area3DChartScene-TFZPHEZ6.mjs} +1 -1
- package/dist/Area3DChartScene-TFZPHEZ6.mjs.br +0 -0
- package/dist/Area3DChartScene-TFZPHEZ6.mjs.gz +0 -0
- package/dist/{Bar3DChartScene-WNBEX3TN.js → Bar3DChartScene-C3CQCKB6.js} +2 -2
- package/dist/Bar3DChartScene-C3CQCKB6.js.br +0 -0
- package/dist/Bar3DChartScene-C3CQCKB6.js.gz +0 -0
- package/dist/{Bar3DChartScene-DFJ7XK3Q.mjs → Bar3DChartScene-L3VXO7BS.mjs} +1 -1
- package/dist/{Bar3DChartScene-DFJ7XK3Q.mjs.br → Bar3DChartScene-L3VXO7BS.mjs.br} +0 -0
- package/dist/Bar3DChartScene-L3VXO7BS.mjs.gz +0 -0
- package/dist/{Line3DChartScene-TK6RPGET.mjs → Line3DChartScene-UM4ZJJSY.mjs} +1 -1
- package/dist/{Line3DChartScene-TK6RPGET.mjs.br → Line3DChartScene-UM4ZJJSY.mjs.br} +0 -0
- package/dist/Line3DChartScene-UM4ZJJSY.mjs.gz +0 -0
- package/dist/{Line3DChartScene-PXA6WAQG.js → Line3DChartScene-YU4M3VMW.js} +2 -2
- package/dist/Line3DChartScene-YU4M3VMW.js.br +0 -0
- package/dist/Line3DChartScene-YU4M3VMW.js.gz +0 -0
- package/dist/{Model3DScene-7FZSQ3SP.mjs → Model3DScene-YEWZQAN5.mjs} +1 -1
- package/dist/Model3DScene-YEWZQAN5.mjs.br +0 -0
- package/dist/Model3DScene-YEWZQAN5.mjs.gz +0 -0
- package/dist/{Model3DScene-FJQOUWCV.js → Model3DScene-YRRNSOYK.js} +2 -2
- package/dist/Model3DScene-YRRNSOYK.js.br +0 -0
- package/dist/Model3DScene-YRRNSOYK.js.gz +0 -0
- package/dist/{PieChart3DScene-KKZTAIFB.mjs → PieChart3DScene-2OBYYK55.mjs} +1 -1
- package/dist/{PieChart3DScene-KKZTAIFB.mjs.br → PieChart3DScene-2OBYYK55.mjs.br} +0 -0
- package/dist/PieChart3DScene-2OBYYK55.mjs.gz +0 -0
- package/dist/{PieChart3DScene-P25IGVT6.js → PieChart3DScene-GH4X3W3E.js} +2 -2
- package/dist/PieChart3DScene-GH4X3W3E.js.br +0 -0
- package/dist/PieChart3DScene-GH4X3W3E.js.gz +0 -0
- package/dist/{SurfaceChart3DScene-LWJCERTR.mjs → SurfaceChart3DScene-DYG5I5UP.mjs} +1 -1
- package/dist/{SurfaceChart3DScene-LWJCERTR.mjs.br → SurfaceChart3DScene-DYG5I5UP.mjs.br} +0 -0
- package/dist/SurfaceChart3DScene-DYG5I5UP.mjs.gz +0 -0
- package/dist/{SurfaceChart3DScene-36MT6QAK.js → SurfaceChart3DScene-J5CAPHVA.js} +2 -2
- package/dist/SurfaceChart3DScene-J5CAPHVA.js.br +0 -0
- package/dist/SurfaceChart3DScene-J5CAPHVA.js.gz +0 -0
- package/dist/{chunk-T7MY5L3O.js → chunk-7OMXJNYI.js} +1568 -1416
- package/dist/chunk-7OMXJNYI.js.br +0 -0
- package/dist/chunk-7OMXJNYI.js.gz +0 -0
- package/dist/{chunk-AARQTIMN.js → chunk-7Z7AY4MH.js} +772 -580
- package/dist/chunk-7Z7AY4MH.js.br +0 -0
- package/dist/chunk-7Z7AY4MH.js.gz +0 -0
- package/dist/{chunk-ZOEKVSSU.mjs → chunk-EZ3EI2VM.mjs} +323 -171
- package/dist/chunk-EZ3EI2VM.mjs.br +0 -0
- package/dist/chunk-EZ3EI2VM.mjs.gz +0 -0
- package/dist/{chunk-WRHPPTYF.mjs → chunk-GQMVEUHM.mjs} +356 -165
- package/dist/chunk-GQMVEUHM.mjs.br +0 -0
- package/dist/chunk-GQMVEUHM.mjs.gz +0 -0
- package/dist/{chunk-O27KNZLJ.js → chunk-H4LMXJ2Z.js} +169 -169
- package/dist/chunk-H4LMXJ2Z.js.br +0 -0
- package/dist/chunk-H4LMXJ2Z.js.gz +0 -0
- package/dist/{chunk-C2BDHCL2.mjs → chunk-HADPGII2.mjs} +47276 -43466
- package/dist/chunk-HADPGII2.mjs.br +0 -0
- package/dist/chunk-HADPGII2.mjs.gz +0 -0
- package/dist/{chunk-45AVHO7M.js → chunk-INKQT4SQ.js} +5 -5
- package/dist/chunk-INKQT4SQ.js.br +0 -0
- package/dist/chunk-INKQT4SQ.js.gz +0 -0
- package/dist/{chunk-3WK4AE52.js → chunk-MH4VFSDL.js} +47294 -43466
- package/dist/chunk-MH4VFSDL.js.br +0 -0
- package/dist/chunk-MH4VFSDL.js.gz +0 -0
- package/dist/{chunk-HXDNYDRJ.mjs → chunk-OVOXRK7D.mjs} +4 -4
- package/dist/chunk-OVOXRK7D.mjs.br +0 -0
- package/dist/chunk-OVOXRK7D.mjs.gz +0 -0
- package/dist/{chunk-2FSNTJVI.mjs → chunk-YFYSY7ZL.mjs} +1 -1
- package/dist/chunk-YFYSY7ZL.mjs.br +0 -0
- package/dist/chunk-YFYSY7ZL.mjs.gz +0 -0
- package/dist/index.js +45 -45
- package/dist/index.js.br +0 -0
- package/dist/index.js.gz +0 -0
- package/dist/index.mjs +5 -5
- package/dist/index.mjs.br +0 -0
- package/dist/index.mjs.gz +0 -0
- package/dist/internals.d.ts +33 -1
- package/dist/internals.d.ts.map +1 -1
- package/dist/internals.js +78 -78
- package/dist/internals.js.br +0 -0
- package/dist/internals.js.gz +0 -0
- package/dist/internals.mjs +3 -3
- package/dist/internals.mjs.br +0 -0
- package/dist/internals.mjs.gz +0 -0
- package/dist/pptx-viewer.css +1 -1
- package/dist/pptx-viewer.css.br +0 -0
- package/dist/pptx-viewer.css.gz +0 -0
- package/dist/viewer/index.js +26 -26
- package/dist/viewer/index.js.br +0 -0
- package/dist/viewer/index.js.gz +0 -0
- package/dist/viewer/index.mjs +5 -5
- package/dist/viewer/index.mjs.br +0 -0
- package/dist/viewer/index.mjs.gz +0 -0
- package/package.json +3 -1
- package/dist/AiChatPanel-SCA4RLFI.mjs.br +0 -0
- package/dist/AiChatPanel-SCA4RLFI.mjs.gz +0 -0
- package/dist/AiChatPanel-TXCDQDHD.js.br +0 -0
- package/dist/AiChatPanel-TXCDQDHD.js.gz +0 -0
- package/dist/Area3DChartScene-NSV5AIMM.mjs.br +0 -0
- package/dist/Area3DChartScene-NSV5AIMM.mjs.gz +0 -0
- package/dist/Area3DChartScene-YAK6W2J5.js.br +0 -0
- package/dist/Area3DChartScene-YAK6W2J5.js.gz +0 -0
- package/dist/Bar3DChartScene-DFJ7XK3Q.mjs.gz +0 -0
- package/dist/Bar3DChartScene-WNBEX3TN.js.br +0 -0
- package/dist/Bar3DChartScene-WNBEX3TN.js.gz +0 -0
- package/dist/Line3DChartScene-PXA6WAQG.js.br +0 -0
- package/dist/Line3DChartScene-PXA6WAQG.js.gz +0 -0
- package/dist/Line3DChartScene-TK6RPGET.mjs.gz +0 -0
- package/dist/Model3DScene-7FZSQ3SP.mjs.br +0 -0
- package/dist/Model3DScene-7FZSQ3SP.mjs.gz +0 -0
- package/dist/Model3DScene-FJQOUWCV.js.br +0 -0
- package/dist/Model3DScene-FJQOUWCV.js.gz +0 -0
- package/dist/PieChart3DScene-KKZTAIFB.mjs.gz +0 -0
- package/dist/PieChart3DScene-P25IGVT6.js.br +0 -0
- package/dist/PieChart3DScene-P25IGVT6.js.gz +0 -0
- package/dist/SurfaceChart3DScene-36MT6QAK.js.br +0 -0
- package/dist/SurfaceChart3DScene-36MT6QAK.js.gz +0 -0
- package/dist/SurfaceChart3DScene-LWJCERTR.mjs.gz +0 -0
- package/dist/chunk-2FSNTJVI.mjs.br +0 -0
- package/dist/chunk-2FSNTJVI.mjs.gz +0 -0
- package/dist/chunk-3WK4AE52.js.br +0 -0
- package/dist/chunk-3WK4AE52.js.gz +0 -0
- package/dist/chunk-45AVHO7M.js.br +0 -0
- package/dist/chunk-45AVHO7M.js.gz +0 -0
- package/dist/chunk-AARQTIMN.js.br +0 -0
- package/dist/chunk-AARQTIMN.js.gz +0 -0
- package/dist/chunk-C2BDHCL2.mjs.br +0 -0
- package/dist/chunk-C2BDHCL2.mjs.gz +0 -0
- package/dist/chunk-HXDNYDRJ.mjs.br +0 -0
- package/dist/chunk-HXDNYDRJ.mjs.gz +0 -0
- package/dist/chunk-O27KNZLJ.js.br +0 -0
- package/dist/chunk-O27KNZLJ.js.gz +0 -0
- package/dist/chunk-T7MY5L3O.js.br +0 -0
- package/dist/chunk-T7MY5L3O.js.gz +0 -0
- package/dist/chunk-WRHPPTYF.mjs.br +0 -0
- package/dist/chunk-WRHPPTYF.mjs.gz +0 -0
- package/dist/chunk-ZOEKVSSU.mjs.br +0 -0
- package/dist/chunk-ZOEKVSSU.mjs.gz +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
3
|
+
var chunkH4LMXJ2Z_js = require('./chunk-H4LMXJ2Z.js');
|
|
4
|
+
var chunkMH4VFSDL_js = require('./chunk-MH4VFSDL.js');
|
|
5
5
|
var chunk3AJ54EAB_js = require('./chunk-3AJ54EAB.js');
|
|
6
6
|
var react = require('react');
|
|
7
7
|
var reactI18next = require('react-i18next');
|
|
@@ -9,7 +9,7 @@ var reactI18next = require('react-i18next');
|
|
|
9
9
|
function useVirtualizedSlides({
|
|
10
10
|
totalItems,
|
|
11
11
|
itemHeight,
|
|
12
|
-
overscan =
|
|
12
|
+
overscan = chunkMH4VFSDL_js.DEFAULT_VIRTUAL_OVERSCAN
|
|
13
13
|
}) {
|
|
14
14
|
const scrollContainerRef = react.useRef(null);
|
|
15
15
|
const [scrollTop, setScrollTop] = react.useState(0);
|
|
@@ -39,7 +39,7 @@ function useVirtualizedSlides({
|
|
|
39
39
|
resizeObserver?.disconnect();
|
|
40
40
|
};
|
|
41
41
|
}, []);
|
|
42
|
-
const range =
|
|
42
|
+
const range = chunkMH4VFSDL_js.computeVirtualRange(totalItems, itemHeight, scrollTop, viewportHeight, overscan);
|
|
43
43
|
const safeItemHeight = Math.max(itemHeight, 1);
|
|
44
44
|
const scrollToIndex = react.useCallback(
|
|
45
45
|
(index, behavior = "smooth") => {
|
|
@@ -80,7 +80,7 @@ function usePresenceTracking({
|
|
|
80
80
|
}) {
|
|
81
81
|
const [remoteUsers, setRemoteUsers] = react.useState([]);
|
|
82
82
|
const projectorRef = react.useRef(null);
|
|
83
|
-
projectorRef.current ??=
|
|
83
|
+
projectorRef.current ??= chunkMH4VFSDL_js.createPresenceProjector();
|
|
84
84
|
const projector = projectorRef.current;
|
|
85
85
|
const lastBroadcastRef = react.useRef(0);
|
|
86
86
|
const pendingBroadcastRef = react.useRef(null);
|
|
@@ -105,7 +105,7 @@ function usePresenceTracking({
|
|
|
105
105
|
awareness.setLocalStateField("presence", state);
|
|
106
106
|
lastBroadcastRef.current = Date.now();
|
|
107
107
|
};
|
|
108
|
-
if (elapsed >=
|
|
108
|
+
if (elapsed >= chunkMH4VFSDL_js.BROADCAST_THROTTLE_MS) {
|
|
109
109
|
if (pendingBroadcastRef.current) {
|
|
110
110
|
clearTimeout(pendingBroadcastRef.current);
|
|
111
111
|
pendingBroadcastRef.current = null;
|
|
@@ -115,7 +115,7 @@ function usePresenceTracking({
|
|
|
115
115
|
pendingBroadcastRef.current = setTimeout(() => {
|
|
116
116
|
pendingBroadcastRef.current = null;
|
|
117
117
|
flush();
|
|
118
|
-
},
|
|
118
|
+
}, chunkMH4VFSDL_js.BROADCAST_THROTTLE_MS - elapsed);
|
|
119
119
|
}
|
|
120
120
|
},
|
|
121
121
|
[awareness, userName, userColor, userAvatar, role]
|
|
@@ -195,7 +195,7 @@ function useYjsProvider({ config }) {
|
|
|
195
195
|
const departureRef = react.useRef(null);
|
|
196
196
|
const gateRef = react.useRef(null);
|
|
197
197
|
if (!gateRef.current) {
|
|
198
|
-
gateRef.current =
|
|
198
|
+
gateRef.current = chunkMH4VFSDL_js.createSyncGate(() => setSynced(true));
|
|
199
199
|
}
|
|
200
200
|
const teardown = react.useCallback(() => {
|
|
201
201
|
if (timeoutRef.current) {
|
|
@@ -215,7 +215,7 @@ function useYjsProvider({ config }) {
|
|
|
215
215
|
const buildCleanup = react.useCallback(
|
|
216
216
|
(provider, yDoc) => () => {
|
|
217
217
|
announceDeparture();
|
|
218
|
-
|
|
218
|
+
chunkMH4VFSDL_js.clearLocalAwareness(provider.awareness);
|
|
219
219
|
provider.destroy();
|
|
220
220
|
yDoc.destroy();
|
|
221
221
|
setDoc(null);
|
|
@@ -240,9 +240,9 @@ function useYjsProvider({ config }) {
|
|
|
240
240
|
if (config.authToken) {
|
|
241
241
|
opts.password = config.authToken;
|
|
242
242
|
}
|
|
243
|
-
const roomId =
|
|
243
|
+
const roomId = chunkMH4VFSDL_js.validateRoomId(config.roomId);
|
|
244
244
|
const provider = new WebrtcProvider(roomId, yDoc, opts);
|
|
245
|
-
departureRef.current =
|
|
245
|
+
departureRef.current = chunkMH4VFSDL_js.createDepartureChannel(roomId, provider.awareness);
|
|
246
246
|
setDoc(yDoc);
|
|
247
247
|
setAwareness(provider.awareness);
|
|
248
248
|
setClientId(provider.awareness.clientID);
|
|
@@ -284,13 +284,13 @@ function useYjsProvider({ config }) {
|
|
|
284
284
|
if (!config) {
|
|
285
285
|
return;
|
|
286
286
|
}
|
|
287
|
-
const roomId =
|
|
288
|
-
const transport = config.transport ??
|
|
287
|
+
const roomId = chunkMH4VFSDL_js.validateRoomId(config.roomId);
|
|
288
|
+
const transport = config.transport ?? chunkMH4VFSDL_js.resolveTransportForServerUrl(config.serverUrl);
|
|
289
289
|
if (transport === "webrtc") {
|
|
290
290
|
await initWebrtc();
|
|
291
291
|
return;
|
|
292
292
|
}
|
|
293
|
-
if (
|
|
293
|
+
if (chunkMH4VFSDL_js.isMixedContentBlocked(config.serverUrl)) {
|
|
294
294
|
console.warn(
|
|
295
295
|
`[pptx-viewer] Refusing to connect: insecure ws:// server "${config.serverUrl}" is blocked from a secure (https) page. Use a wss:// URL.`
|
|
296
296
|
);
|
|
@@ -304,7 +304,7 @@ function useYjsProvider({ config }) {
|
|
|
304
304
|
const provider = new WebsocketProvider(config.serverUrl, roomId, yDoc, {
|
|
305
305
|
params: config.authToken ? { token: config.authToken } : void 0
|
|
306
306
|
});
|
|
307
|
-
departureRef.current =
|
|
307
|
+
departureRef.current = chunkMH4VFSDL_js.createDepartureChannel(roomId, provider.awareness);
|
|
308
308
|
let connected = false;
|
|
309
309
|
const handleStatus = (event) => {
|
|
310
310
|
if (event.status === "connected") {
|
|
@@ -344,7 +344,7 @@ function useYjsProvider({ config }) {
|
|
|
344
344
|
provider.off("status", handleStatus);
|
|
345
345
|
provider.off("sync", handleSynced);
|
|
346
346
|
announceDeparture();
|
|
347
|
-
|
|
347
|
+
chunkMH4VFSDL_js.clearLocalAwareness(provider.awareness);
|
|
348
348
|
provider.destroy();
|
|
349
349
|
yDoc.destroy();
|
|
350
350
|
setDoc(null);
|
|
@@ -353,7 +353,7 @@ function useYjsProvider({ config }) {
|
|
|
353
353
|
cleanupRef.current = null;
|
|
354
354
|
setStatus("error");
|
|
355
355
|
}
|
|
356
|
-
},
|
|
356
|
+
}, chunkMH4VFSDL_js.CONNECTION_TIMEOUT_MS);
|
|
357
357
|
}
|
|
358
358
|
setDoc(yDoc);
|
|
359
359
|
setAwareness(provider.awareness);
|
|
@@ -362,7 +362,7 @@ function useYjsProvider({ config }) {
|
|
|
362
362
|
provider.off("status", handleStatus);
|
|
363
363
|
provider.off("sync", handleSynced);
|
|
364
364
|
announceDeparture();
|
|
365
|
-
|
|
365
|
+
chunkMH4VFSDL_js.clearLocalAwareness(provider.awareness);
|
|
366
366
|
provider.destroy();
|
|
367
367
|
yDoc.destroy();
|
|
368
368
|
setDoc(null);
|
|
@@ -388,7 +388,7 @@ function useYjsProvider({ config }) {
|
|
|
388
388
|
]);
|
|
389
389
|
react.useEffect(() => {
|
|
390
390
|
init();
|
|
391
|
-
const disposeTeardown =
|
|
391
|
+
const disposeTeardown = chunkMH4VFSDL_js.registerCollaborationTeardown({
|
|
392
392
|
leave: teardown,
|
|
393
393
|
rejoin: init
|
|
394
394
|
});
|
|
@@ -409,7 +409,7 @@ function useCollaborativeState({
|
|
|
409
409
|
canvasWidth,
|
|
410
410
|
canvasHeight
|
|
411
411
|
}) {
|
|
412
|
-
const userColor =
|
|
412
|
+
const userColor = chunkMH4VFSDL_js.sanitizeColor(config?.userColor, "#6366f1");
|
|
413
413
|
const { status, awareness, doc, clientId, synced, retry } = useYjsProvider({ config });
|
|
414
414
|
const { remoteUsers, broadcastPresence } = usePresenceTracking({
|
|
415
415
|
awareness,
|
|
@@ -527,8 +527,8 @@ function useEditorHistory(input) {
|
|
|
527
527
|
width: canvasSize.width,
|
|
528
528
|
height: canvasSize.height,
|
|
529
529
|
activeSlideIndex,
|
|
530
|
-
slides: slides.map(
|
|
531
|
-
templateElementsBySlideId:
|
|
530
|
+
slides: slides.map(chunkMH4VFSDL_js.cloneSlide),
|
|
531
|
+
templateElementsBySlideId: chunkMH4VFSDL_js.cloneTemplateElementsBySlideId(templateElementsBySlideId),
|
|
532
532
|
...actionLabel ? { actionLabel } : {}
|
|
533
533
|
};
|
|
534
534
|
},
|
|
@@ -541,9 +541,9 @@ function useEditorHistory(input) {
|
|
|
541
541
|
width: snapshot.width,
|
|
542
542
|
height: snapshot.height
|
|
543
543
|
});
|
|
544
|
-
setSlides(snapshot.slides.map(
|
|
544
|
+
setSlides(snapshot.slides.map(chunkMH4VFSDL_js.cloneSlide));
|
|
545
545
|
setTemplateElementsBySlideId(
|
|
546
|
-
|
|
546
|
+
chunkMH4VFSDL_js.cloneTemplateElementsBySlideId(snapshot.templateElementsBySlideId)
|
|
547
547
|
);
|
|
548
548
|
setActiveSlideIndex(Math.min(snapshot.activeSlideIndex, maxSlideIndex));
|
|
549
549
|
setSelectedElementIds([]);
|
|
@@ -582,8 +582,8 @@ function useEditorHistory(input) {
|
|
|
582
582
|
const currentSnapshot = buildHistorySnapshot();
|
|
583
583
|
historyFutureRef.current.push(currentSnapshot);
|
|
584
584
|
isApplyingHistoryRef.current = true;
|
|
585
|
-
const nextSnapshot =
|
|
586
|
-
lastHistorySnapshotRef.current =
|
|
585
|
+
const nextSnapshot = chunkH4LMXJ2Z_js.cloneHistorySnapshot(previousSnapshot);
|
|
586
|
+
lastHistorySnapshotRef.current = chunkH4LMXJ2Z_js.cloneHistorySnapshot(nextSnapshot);
|
|
587
587
|
lastHistorySerializedRef.current = serializeDocument(nextSnapshot);
|
|
588
588
|
applyHistorySnapshot(nextSnapshot);
|
|
589
589
|
updateHistoryAvailability();
|
|
@@ -604,8 +604,8 @@ function useEditorHistory(input) {
|
|
|
604
604
|
const currentSnapshot = buildHistorySnapshot();
|
|
605
605
|
historyPastRef.current.push(currentSnapshot);
|
|
606
606
|
isApplyingHistoryRef.current = true;
|
|
607
|
-
const targetSnapshot =
|
|
608
|
-
lastHistorySnapshotRef.current =
|
|
607
|
+
const targetSnapshot = chunkH4LMXJ2Z_js.cloneHistorySnapshot(nextSnapshot);
|
|
608
|
+
lastHistorySnapshotRef.current = chunkH4LMXJ2Z_js.cloneHistorySnapshot(targetSnapshot);
|
|
609
609
|
lastHistorySerializedRef.current = serializeDocument(targetSnapshot);
|
|
610
610
|
applyHistorySnapshot(targetSnapshot);
|
|
611
611
|
updateHistoryAvailability();
|
|
@@ -623,7 +623,7 @@ function useEditorHistory(input) {
|
|
|
623
623
|
historyPastRef.current = [];
|
|
624
624
|
historyFutureRef.current = [];
|
|
625
625
|
if (initialSnapshot) {
|
|
626
|
-
const clonedInitial =
|
|
626
|
+
const clonedInitial = chunkH4LMXJ2Z_js.cloneHistorySnapshot(initialSnapshot);
|
|
627
627
|
lastHistorySnapshotRef.current = clonedInitial;
|
|
628
628
|
lastHistorySerializedRef.current = serializeDocument(clonedInitial);
|
|
629
629
|
} else {
|
|
@@ -671,19 +671,19 @@ function useEditorHistory(input) {
|
|
|
671
671
|
}
|
|
672
672
|
const previousSnapshot = lastHistorySnapshotRef.current;
|
|
673
673
|
if (!previousSnapshot) {
|
|
674
|
-
lastHistorySnapshotRef.current =
|
|
674
|
+
lastHistorySnapshotRef.current = chunkH4LMXJ2Z_js.cloneHistorySnapshot(snapshot);
|
|
675
675
|
lastHistorySerializedRef.current = serialized;
|
|
676
676
|
lastCheapHashRef.current = cheapHash;
|
|
677
677
|
updateHistoryAvailability();
|
|
678
678
|
return;
|
|
679
679
|
}
|
|
680
680
|
onDirtyRef.current?.();
|
|
681
|
-
historyPastRef.current.push(
|
|
681
|
+
historyPastRef.current.push(chunkH4LMXJ2Z_js.cloneHistorySnapshot(previousSnapshot));
|
|
682
682
|
while (historyPastRef.current.length > Math.max(1, maxHistoryEntries)) {
|
|
683
683
|
historyPastRef.current.shift();
|
|
684
684
|
}
|
|
685
685
|
historyFutureRef.current = [];
|
|
686
|
-
lastHistorySnapshotRef.current =
|
|
686
|
+
lastHistorySnapshotRef.current = chunkH4LMXJ2Z_js.cloneHistorySnapshot(snapshot);
|
|
687
687
|
lastHistorySerializedRef.current = serialized;
|
|
688
688
|
lastCheapHashRef.current = cheapHash;
|
|
689
689
|
updateHistoryAvailability();
|
|
@@ -743,9 +743,9 @@ function useZoomViewport({
|
|
|
743
743
|
const canvasStageRef = react.useRef(null);
|
|
744
744
|
const canvasViewportRef = react.useRef(null);
|
|
745
745
|
const renderScaleRef = react.useRef(1);
|
|
746
|
-
const wheelBufferRef = react.useRef(
|
|
746
|
+
const wheelBufferRef = react.useRef(chunkMH4VFSDL_js.createWheelStepBuffer());
|
|
747
747
|
const storeRef = react.useRef(null);
|
|
748
|
-
storeRef.current ??=
|
|
748
|
+
storeRef.current ??= chunkMH4VFSDL_js.createViewerZoomStore();
|
|
749
749
|
const store = storeRef.current;
|
|
750
750
|
const scale = useViewerStore(store, selectZoom);
|
|
751
751
|
const setScale = react.useCallback(
|
|
@@ -806,7 +806,7 @@ function useZoomViewport({
|
|
|
806
806
|
if (!wrapper || !canvasViewport) {
|
|
807
807
|
return;
|
|
808
808
|
}
|
|
809
|
-
const boundedScale =
|
|
809
|
+
const boundedScale = chunkMH4VFSDL_js.clampZoomScale(nextScale);
|
|
810
810
|
const nextEditorScale = fitScale * boundedScale;
|
|
811
811
|
const centerX = (bounds.minX + bounds.maxX) / 2;
|
|
812
812
|
const centerY = (bounds.minY + bounds.maxY) / 2;
|
|
@@ -843,29 +843,29 @@ function useZoomViewport({
|
|
|
843
843
|
selectedElements.forEach((element) => {
|
|
844
844
|
minX = Math.min(minX, element.x);
|
|
845
845
|
minY = Math.min(minY, element.y);
|
|
846
|
-
maxX = Math.max(maxX, element.x + Math.max(element.width,
|
|
847
|
-
maxY = Math.max(maxY, element.y + Math.max(element.height,
|
|
846
|
+
maxX = Math.max(maxX, element.x + Math.max(element.width, chunkH4LMXJ2Z_js.MIN_ELEMENT_SIZE));
|
|
847
|
+
maxY = Math.max(maxY, element.y + Math.max(element.height, chunkH4LMXJ2Z_js.MIN_ELEMENT_SIZE));
|
|
848
848
|
});
|
|
849
849
|
if (!Number.isFinite(minX) || !Number.isFinite(minY) || !Number.isFinite(maxX) || !Number.isFinite(maxY)) {
|
|
850
850
|
return;
|
|
851
851
|
}
|
|
852
852
|
const selectionBounds = { minX, minY, maxX, maxY };
|
|
853
|
-
const boundsWidth = Math.max(selectionBounds.maxX - selectionBounds.minX,
|
|
854
|
-
const boundsHeight = Math.max(selectionBounds.maxY - selectionBounds.minY,
|
|
853
|
+
const boundsWidth = Math.max(selectionBounds.maxX - selectionBounds.minX, chunkH4LMXJ2Z_js.MIN_ELEMENT_SIZE);
|
|
854
|
+
const boundsHeight = Math.max(selectionBounds.maxY - selectionBounds.minY, chunkH4LMXJ2Z_js.MIN_ELEMENT_SIZE);
|
|
855
855
|
const availableWidth = Math.max(
|
|
856
|
-
effectiveEditorDimensions.width -
|
|
857
|
-
|
|
856
|
+
effectiveEditorDimensions.width - chunkH4LMXJ2Z_js.ZOOM_TO_SELECTION_PADDING,
|
|
857
|
+
chunkH4LMXJ2Z_js.MIN_ELEMENT_SIZE
|
|
858
858
|
);
|
|
859
859
|
const availableHeight = Math.max(
|
|
860
|
-
effectiveEditorDimensions.height -
|
|
861
|
-
|
|
860
|
+
effectiveEditorDimensions.height - chunkH4LMXJ2Z_js.ZOOM_TO_SELECTION_PADDING,
|
|
861
|
+
chunkH4LMXJ2Z_js.MIN_ELEMENT_SIZE
|
|
862
862
|
);
|
|
863
863
|
const targetEditorScale = Math.min(
|
|
864
864
|
availableWidth / boundsWidth,
|
|
865
865
|
availableHeight / boundsHeight
|
|
866
866
|
);
|
|
867
867
|
const safeFitScale = fitScale > Number.EPSILON ? fitScale : Number.EPSILON;
|
|
868
|
-
const nextScale =
|
|
868
|
+
const nextScale = chunkMH4VFSDL_js.clampZoomScale(targetEditorScale / safeFitScale);
|
|
869
869
|
setScale(nextScale);
|
|
870
870
|
window.requestAnimationFrame(() => {
|
|
871
871
|
window.requestAnimationFrame(() => {
|
|
@@ -882,14 +882,14 @@ function useZoomViewport({
|
|
|
882
882
|
]);
|
|
883
883
|
const handleWheel = react.useCallback(
|
|
884
884
|
(event) => {
|
|
885
|
-
const mapped =
|
|
885
|
+
const mapped = chunkMH4VFSDL_js.mapEditingWheel(event, wheelBufferRef.current, true);
|
|
886
886
|
if (mapped.intent !== "zoom") {
|
|
887
887
|
return;
|
|
888
888
|
}
|
|
889
889
|
event.preventDefault();
|
|
890
890
|
store.dispatch({
|
|
891
891
|
type: "set-zoom",
|
|
892
|
-
zoom:
|
|
892
|
+
zoom: chunkMH4VFSDL_js.clampZoomScale(store.getState().zoom + mapped.deltaScale)
|
|
893
893
|
});
|
|
894
894
|
},
|
|
895
895
|
[store]
|
|
@@ -984,8 +984,8 @@ function scheduleOpeningAutoPlayGroup(controller, ctx) {
|
|
|
984
984
|
if (!group) {
|
|
985
985
|
return;
|
|
986
986
|
}
|
|
987
|
-
|
|
988
|
-
|
|
987
|
+
chunkMH4VFSDL_js.playGroup(controller, group, ctx);
|
|
988
|
+
chunkMH4VFSDL_js.scheduleAutoAdvanceChain(controller, ctx);
|
|
989
989
|
}, firstGroup.autoAdvanceDelayMs ?? 0);
|
|
990
990
|
ctx.timers.push(timer);
|
|
991
991
|
}
|
|
@@ -1004,7 +1004,7 @@ function scheduleEntranceAnimationTimers(slide, setPresentationAnimations, prese
|
|
|
1004
1004
|
}))
|
|
1005
1005
|
);
|
|
1006
1006
|
entranceAnimations.forEach((animation, animationIndex) => {
|
|
1007
|
-
const delay =
|
|
1007
|
+
const delay = chunkMH4VFSDL_js.computeEntranceAnimationDelay(animation.delayMs, animationIndex);
|
|
1008
1008
|
const timer = window.setTimeout(() => {
|
|
1009
1009
|
setPresentationAnimations(
|
|
1010
1010
|
(previousAnimations) => previousAnimations.map(
|
|
@@ -1037,7 +1037,7 @@ function useAnimationPlayback(input) {
|
|
|
1037
1037
|
const presentationTimersRef = react.useRef([]);
|
|
1038
1038
|
const controllerRef = react.useRef(null);
|
|
1039
1039
|
const buildRafRef = react.useRef(null);
|
|
1040
|
-
const activeAnimationGroupRef = react.useRef(
|
|
1040
|
+
const activeAnimationGroupRef = react.useRef(chunkMH4VFSDL_js.createActiveAnimationGroup());
|
|
1041
1041
|
const seededCompletedRef = react.useRef(false);
|
|
1042
1042
|
const mediaTimeNodeElementIdsRef = react.useRef(/* @__PURE__ */ new Map());
|
|
1043
1043
|
const lastSeedCompletedRef = react.useRef(false);
|
|
@@ -1054,15 +1054,15 @@ function useAnimationPlayback(input) {
|
|
|
1054
1054
|
}, [onPlayActionSound]);
|
|
1055
1055
|
react.useEffect(() => {
|
|
1056
1056
|
return () => {
|
|
1057
|
-
|
|
1057
|
+
chunkMH4VFSDL_js.cancelBuildReveal(buildRafRef);
|
|
1058
1058
|
};
|
|
1059
1059
|
}, []);
|
|
1060
1060
|
const clearPresentationTimers = react.useCallback(() => {
|
|
1061
|
-
|
|
1061
|
+
chunkMH4VFSDL_js.clearPlaybackTimers(buildPlaybackContext(), activeAnimationGroupRef.current);
|
|
1062
1062
|
}, [buildPlaybackContext]);
|
|
1063
1063
|
const resetSlideTimeline = react.useCallback(
|
|
1064
1064
|
(slideIndex) => {
|
|
1065
|
-
|
|
1065
|
+
chunkMH4VFSDL_js.cancelBuildReveal(buildRafRef);
|
|
1066
1066
|
const slide = slides[slideIndex];
|
|
1067
1067
|
if (!slide) {
|
|
1068
1068
|
controllerRef.current = null;
|
|
@@ -1073,14 +1073,14 @@ function useAnimationPlayback(input) {
|
|
|
1073
1073
|
setHoverTriggerShapeIds(/* @__PURE__ */ new Set());
|
|
1074
1074
|
return;
|
|
1075
1075
|
}
|
|
1076
|
-
const controller =
|
|
1076
|
+
const controller = chunkMH4VFSDL_js.PresentationAnimationController.fromSlide(slide, {
|
|
1077
1077
|
slideHeightPx: canvasSize?.height,
|
|
1078
1078
|
slideWidthPx: canvasSize?.width,
|
|
1079
1079
|
themeColorMap,
|
|
1080
1080
|
pixelateMosaic: pixelateMosaicAnimation
|
|
1081
1081
|
});
|
|
1082
1082
|
controllerRef.current = controller;
|
|
1083
|
-
mediaTimeNodeElementIdsRef.current =
|
|
1083
|
+
mediaTimeNodeElementIdsRef.current = chunkMH4VFSDL_js.resolveMediaTimeNodeElementIds(
|
|
1084
1084
|
slide.nativeAnimations ?? []
|
|
1085
1085
|
);
|
|
1086
1086
|
setPresentationKeyframesCss(controller.keyframesCss);
|
|
@@ -1094,7 +1094,7 @@ function useAnimationPlayback(input) {
|
|
|
1094
1094
|
if (!animationsEnabled) {
|
|
1095
1095
|
return false;
|
|
1096
1096
|
}
|
|
1097
|
-
return
|
|
1097
|
+
return chunkMH4VFSDL_js.advanceMainSequence(
|
|
1098
1098
|
controllerRef.current,
|
|
1099
1099
|
buildPlaybackContext(),
|
|
1100
1100
|
activeAnimationGroupRef.current
|
|
@@ -1110,7 +1110,7 @@ function useAnimationPlayback(input) {
|
|
|
1110
1110
|
if (!group) {
|
|
1111
1111
|
return false;
|
|
1112
1112
|
}
|
|
1113
|
-
|
|
1113
|
+
chunkMH4VFSDL_js.playGroup(controller, group, buildPlaybackContext());
|
|
1114
1114
|
return true;
|
|
1115
1115
|
},
|
|
1116
1116
|
[buildPlaybackContext]
|
|
@@ -1129,7 +1129,7 @@ function useAnimationPlayback(input) {
|
|
|
1129
1129
|
if (!group) {
|
|
1130
1130
|
return false;
|
|
1131
1131
|
}
|
|
1132
|
-
|
|
1132
|
+
chunkMH4VFSDL_js.playGroup(controller, group, buildPlaybackContext());
|
|
1133
1133
|
return true;
|
|
1134
1134
|
},
|
|
1135
1135
|
[animationsEnabled, buildPlaybackContext]
|
|
@@ -1210,12 +1210,12 @@ function useAnimationPlayback(input) {
|
|
|
1210
1210
|
presentationTimersRef
|
|
1211
1211
|
};
|
|
1212
1212
|
}
|
|
1213
|
-
var PRESENTER_CHANNEL_NAME =
|
|
1214
|
-
var AUDIENCE_HASH =
|
|
1215
|
-
var PRESENTER_MSG_ORIGIN =
|
|
1216
|
-
var AUDIENCE_NONCE_KEY =
|
|
1213
|
+
var PRESENTER_CHANNEL_NAME = chunkMH4VFSDL_js.PRESENTATION_CHANNEL_NAME;
|
|
1214
|
+
var AUDIENCE_HASH = chunkMH4VFSDL_js.PRESENTATION_HASH;
|
|
1215
|
+
var PRESENTER_MSG_ORIGIN = chunkMH4VFSDL_js.PRESENTATION_MESSAGE_ORIGIN;
|
|
1216
|
+
var AUDIENCE_NONCE_KEY = chunkMH4VFSDL_js.PRESENTATION_NONCE_KEY;
|
|
1217
1217
|
function generateSessionId() {
|
|
1218
|
-
return
|
|
1218
|
+
return chunkMH4VFSDL_js.createPresentationSessionId();
|
|
1219
1219
|
}
|
|
1220
1220
|
function parseAudienceNonce() {
|
|
1221
1221
|
const hash = window.location.hash;
|
|
@@ -1251,7 +1251,7 @@ function usePresenterWindow(input) {
|
|
|
1251
1251
|
}, []);
|
|
1252
1252
|
const swapDisplays = react.useCallback(async () => {
|
|
1253
1253
|
const audience = audienceWindowRef.current;
|
|
1254
|
-
return audience && !audience.closed ?
|
|
1254
|
+
return audience && !audience.closed ? chunkMH4VFSDL_js.swapPresentationWindows(window, audience) : false;
|
|
1255
1255
|
}, []);
|
|
1256
1256
|
const syncSlideToAudience = react.useCallback(
|
|
1257
1257
|
(slideIndex) => {
|
|
@@ -1315,7 +1315,7 @@ function usePresenterWindow(input) {
|
|
|
1315
1315
|
pollTimerRef.current = null;
|
|
1316
1316
|
}
|
|
1317
1317
|
if (closingSessionId) {
|
|
1318
|
-
void
|
|
1318
|
+
void chunkMH4VFSDL_js.clearAudienceContent(closingSessionId);
|
|
1319
1319
|
}
|
|
1320
1320
|
}, [getChannel]);
|
|
1321
1321
|
const openAudienceWindow = react.useCallback(() => {
|
|
@@ -1333,10 +1333,10 @@ function usePresenterWindow(input) {
|
|
|
1333
1333
|
audienceWindowRef.current = blankWin;
|
|
1334
1334
|
const sessionId = generateSessionId();
|
|
1335
1335
|
sessionIdRef.current = sessionId;
|
|
1336
|
-
const audienceUrl =
|
|
1337
|
-
void
|
|
1336
|
+
const audienceUrl = chunkMH4VFSDL_js.buildPresentationAudienceUrl(window.location.href, sessionId);
|
|
1337
|
+
void chunkMH4VFSDL_js.resolveAudienceScreenPlacement(window).then((placement) => {
|
|
1338
1338
|
if (placement && audienceWindowRef.current === blankWin && !blankWin.closed) {
|
|
1339
|
-
|
|
1339
|
+
chunkMH4VFSDL_js.placeAudienceWindow(blankWin, placement);
|
|
1340
1340
|
}
|
|
1341
1341
|
return void 0;
|
|
1342
1342
|
});
|
|
@@ -1366,7 +1366,7 @@ function usePresenterWindow(input) {
|
|
|
1366
1366
|
}
|
|
1367
1367
|
};
|
|
1368
1368
|
if (content) {
|
|
1369
|
-
void
|
|
1369
|
+
void chunkMH4VFSDL_js.storeAudienceContent(content, sessionId).then(() => navigateOrClose(true)).catch(() => navigateOrClose(false));
|
|
1370
1370
|
} else {
|
|
1371
1371
|
navigateOrClose(true);
|
|
1372
1372
|
}
|
|
@@ -1392,7 +1392,7 @@ function usePresenterWindow(input) {
|
|
|
1392
1392
|
}
|
|
1393
1393
|
const handleMessage = (event) => {
|
|
1394
1394
|
const message = event.data;
|
|
1395
|
-
if (
|
|
1395
|
+
if (chunkMH4VFSDL_js.isPresentationSessionMessage(message) && message.type === "audience-ready" && message.sessionId === sessionIdRef.current) {
|
|
1396
1396
|
syncStateToAudience(snapshotRef.current);
|
|
1397
1397
|
}
|
|
1398
1398
|
};
|
|
@@ -1421,7 +1421,7 @@ function usePresenterWindow(input) {
|
|
|
1421
1421
|
react.useEffect(() => {
|
|
1422
1422
|
const handleBeforeUnload = () => {
|
|
1423
1423
|
if (sessionIdRef.current) {
|
|
1424
|
-
void
|
|
1424
|
+
void chunkMH4VFSDL_js.clearAudienceContent(sessionIdRef.current);
|
|
1425
1425
|
}
|
|
1426
1426
|
};
|
|
1427
1427
|
window.addEventListener("beforeunload", handleBeforeUnload);
|
|
@@ -1483,7 +1483,7 @@ function useAudienceMode(input) {
|
|
|
1483
1483
|
}
|
|
1484
1484
|
channel.onmessage = (event) => {
|
|
1485
1485
|
const data = event.data;
|
|
1486
|
-
if (!
|
|
1486
|
+
if (!chunkMH4VFSDL_js.isPresentationSessionMessage(data) || data.origin !== PRESENTER_MSG_ORIGIN) {
|
|
1487
1487
|
return;
|
|
1488
1488
|
}
|
|
1489
1489
|
if (expectedSessionId && data.sessionId !== expectedSessionId) {
|
|
@@ -1499,16 +1499,16 @@ function useAudienceMode(input) {
|
|
|
1499
1499
|
}
|
|
1500
1500
|
if (data.type === "presenter-exit") {
|
|
1501
1501
|
if (expectedSessionId) {
|
|
1502
|
-
void
|
|
1502
|
+
void chunkMH4VFSDL_js.clearAudienceContent(expectedSessionId);
|
|
1503
1503
|
}
|
|
1504
|
-
if (
|
|
1504
|
+
if (chunkMH4VFSDL_js.endAudienceDisplay(window)) {
|
|
1505
1505
|
handlers.onPresenterEnded?.();
|
|
1506
1506
|
}
|
|
1507
1507
|
}
|
|
1508
1508
|
};
|
|
1509
1509
|
if (expectedSessionId) {
|
|
1510
1510
|
channel.postMessage({
|
|
1511
|
-
origin:
|
|
1511
|
+
origin: chunkMH4VFSDL_js.PRESENTATION_MESSAGE_ORIGIN,
|
|
1512
1512
|
type: "audience-ready",
|
|
1513
1513
|
sessionId: expectedSessionId
|
|
1514
1514
|
});
|
|
@@ -1522,7 +1522,7 @@ function useAudienceMode(input) {
|
|
|
1522
1522
|
}, []);
|
|
1523
1523
|
}
|
|
1524
1524
|
function usePresentationKeyboard(input) {
|
|
1525
|
-
const wheelBufferRef = react.useRef(
|
|
1525
|
+
const wheelBufferRef = react.useRef(chunkMH4VFSDL_js.createWheelStepBuffer());
|
|
1526
1526
|
const {
|
|
1527
1527
|
mode,
|
|
1528
1528
|
movePresentationSlide,
|
|
@@ -1543,14 +1543,14 @@ function usePresentationKeyboard(input) {
|
|
|
1543
1543
|
presentationSlideIndex,
|
|
1544
1544
|
setShowRehearsalSummary
|
|
1545
1545
|
} = input;
|
|
1546
|
-
const keyBufferRef = react.useRef(
|
|
1546
|
+
const keyBufferRef = react.useRef(chunkMH4VFSDL_js.createPresentationKeyBuffer());
|
|
1547
1547
|
react.useEffect(() => {
|
|
1548
|
-
if (mode !== "present" || !
|
|
1549
|
-
keyBufferRef.current =
|
|
1548
|
+
if (mode !== "present" || !chunkMH4VFSDL_js.acceptsPresentationInput()) {
|
|
1549
|
+
keyBufferRef.current = chunkMH4VFSDL_js.createPresentationKeyBuffer();
|
|
1550
1550
|
return;
|
|
1551
1551
|
}
|
|
1552
1552
|
const handleKeyDown = (event) => {
|
|
1553
|
-
const mapped =
|
|
1553
|
+
const mapped = chunkMH4VFSDL_js.mapPresentationKey(event, keyBufferRef.current);
|
|
1554
1554
|
if (mapped.action === "none") {
|
|
1555
1555
|
return;
|
|
1556
1556
|
}
|
|
@@ -1570,12 +1570,12 @@ function usePresentationKeyboard(input) {
|
|
|
1570
1570
|
movePresentationSlide(-1);
|
|
1571
1571
|
return;
|
|
1572
1572
|
case "first": {
|
|
1573
|
-
const first =
|
|
1573
|
+
const first = chunkMH4VFSDL_js.firstShowSlideIndex(showSlideIndexes);
|
|
1574
1574
|
navigateToSlide(first ?? 0);
|
|
1575
1575
|
return;
|
|
1576
1576
|
}
|
|
1577
1577
|
case "last": {
|
|
1578
|
-
const last =
|
|
1578
|
+
const last = chunkMH4VFSDL_js.lastShowSlideIndex(showSlideIndexes);
|
|
1579
1579
|
navigateToSlide(last ?? Math.max(0, slideCount - 1));
|
|
1580
1580
|
return;
|
|
1581
1581
|
}
|
|
@@ -1613,10 +1613,10 @@ function usePresentationKeyboard(input) {
|
|
|
1613
1613
|
}
|
|
1614
1614
|
};
|
|
1615
1615
|
const handleWheel = (event) => {
|
|
1616
|
-
if (mode !== "present" || !
|
|
1616
|
+
if (mode !== "present" || !chunkMH4VFSDL_js.acceptsPresentationInput()) {
|
|
1617
1617
|
return;
|
|
1618
1618
|
}
|
|
1619
|
-
const mapped =
|
|
1619
|
+
const mapped = chunkMH4VFSDL_js.mapPresentationWheel(event, wheelBufferRef.current);
|
|
1620
1620
|
if (mapped.intent === "next-slide") {
|
|
1621
1621
|
event.preventDefault();
|
|
1622
1622
|
movePresentationSlide(1);
|
|
@@ -1749,7 +1749,7 @@ function useRehearsalTimings(input) {
|
|
|
1749
1749
|
|
|
1750
1750
|
// src/viewer/hooks/presentation-mode/presentation-actions.ts
|
|
1751
1751
|
function handlePresentationActionImpl(action, deps) {
|
|
1752
|
-
|
|
1752
|
+
chunkMH4VFSDL_js.runPresentationAction(
|
|
1753
1753
|
action,
|
|
1754
1754
|
{ slideCount: deps.slidesLength, ...deps.elementId ? { elementId: deps.elementId } : {} },
|
|
1755
1755
|
{
|
|
@@ -1778,13 +1778,13 @@ function handlePresentationActionImpl(action, deps) {
|
|
|
1778
1778
|
function executeSlideTransition(nextSlideIndex, deps) {
|
|
1779
1779
|
const incomingSlide = deps.slides[nextSlideIndex];
|
|
1780
1780
|
const transition = deps.reverse ? deps.slides[deps.currentSlideIndex]?.transition : incomingSlide?.transition;
|
|
1781
|
-
const durationMs = deps.playTransition ?
|
|
1781
|
+
const durationMs = deps.playTransition ? chunkMH4VFSDL_js.resolveTransitionDurationMs(transition) : 0;
|
|
1782
1782
|
deps.clearPresentationTimers();
|
|
1783
1783
|
deps.setPresentationSlideIndex(nextSlideIndex);
|
|
1784
1784
|
deps.onSetActiveSlideIndex(nextSlideIndex);
|
|
1785
1785
|
deps.setPresentationSlideVisible(true);
|
|
1786
1786
|
deps.seedSlideAnimations(nextSlideIndex, { completed: deps.seedCompleted });
|
|
1787
|
-
const soundAction =
|
|
1787
|
+
const soundAction = chunkMH4VFSDL_js.resolveTransitionSoundAction(transition);
|
|
1788
1788
|
if (soundAction.kind === "play" && deps.onPlayActionSound) {
|
|
1789
1789
|
deps.onPlayActionSound(soundAction.soundPath, { loop: soundAction.loop });
|
|
1790
1790
|
} else if (soundAction.kind === "stop" && deps.onStopActionSound) {
|
|
@@ -1848,7 +1848,7 @@ function useSlideNavigation(input) {
|
|
|
1848
1848
|
});
|
|
1849
1849
|
const scheduleAutoAdvanceForSlide = react.useCallback(
|
|
1850
1850
|
(slideIndex) => {
|
|
1851
|
-
const delayMs =
|
|
1851
|
+
const delayMs = chunkMH4VFSDL_js.resolveAutoAdvanceDelayMs(slides[slideIndex], { useTimings });
|
|
1852
1852
|
if (delayMs === void 0) {
|
|
1853
1853
|
return;
|
|
1854
1854
|
}
|
|
@@ -1871,7 +1871,7 @@ function useSlideNavigation(input) {
|
|
|
1871
1871
|
if (availableSlideIndexes.length === 0) {
|
|
1872
1872
|
return;
|
|
1873
1873
|
}
|
|
1874
|
-
const pastLastSlide = direction === 1 && !
|
|
1874
|
+
const pastLastSlide = direction === 1 && !chunkMH4VFSDL_js.hasShowSlideAfter(presentationSlideIndex, availableSlideIndexes);
|
|
1875
1875
|
if (rehearsing && pastLastSlide) {
|
|
1876
1876
|
recordCurrentSlideTime(presentationSlideIndex);
|
|
1877
1877
|
try {
|
|
@@ -1889,9 +1889,9 @@ function useSlideNavigation(input) {
|
|
|
1889
1889
|
onAdvancePastLastSlide();
|
|
1890
1890
|
return;
|
|
1891
1891
|
}
|
|
1892
|
-
const nextSlideIndex = direction === 1 ?
|
|
1892
|
+
const nextSlideIndex = direction === 1 ? chunkMH4VFSDL_js.nextShowSlideIndex(presentationSlideIndex, availableSlideIndexes, {
|
|
1893
1893
|
loop: Boolean(loopContinuously) && !rehearsing
|
|
1894
|
-
}) :
|
|
1894
|
+
}) : chunkMH4VFSDL_js.previousShowSlideIndex(presentationSlideIndex, availableSlideIndexes);
|
|
1895
1895
|
if (nextSlideIndex === void 0 || nextSlideIndex === presentationSlideIndex) {
|
|
1896
1896
|
return;
|
|
1897
1897
|
}
|
|
@@ -2072,7 +2072,7 @@ function createCustomShowRunner(deps) {
|
|
|
2072
2072
|
return;
|
|
2073
2073
|
}
|
|
2074
2074
|
origin = returnAfter ? { showId: deps.getActiveCustomShowId(), slideIndex: deps.getPresentationSlideIndex() } : null;
|
|
2075
|
-
const first =
|
|
2075
|
+
const first = chunkMH4VFSDL_js.firstShowSlideIndex(chunkMH4VFSDL_js.resolveShowSlideIndexes(deps.getSlides(), target));
|
|
2076
2076
|
deps.setActiveCustomShowId(customShowId);
|
|
2077
2077
|
if (first !== void 0) {
|
|
2078
2078
|
deps.navigateToSlide(first);
|
|
@@ -2150,33 +2150,33 @@ function usePresentationActionExtensions(input) {
|
|
|
2150
2150
|
}
|
|
2151
2151
|
}, [navigateToSlideViaRef]);
|
|
2152
2152
|
const onOpenFile = react.useCallback((target) => {
|
|
2153
|
-
|
|
2153
|
+
chunkMH4VFSDL_js.safeOpenUrl(target);
|
|
2154
2154
|
}, []);
|
|
2155
2155
|
const onOpenPresentation = react.useCallback((target) => {
|
|
2156
|
-
|
|
2156
|
+
chunkMH4VFSDL_js.safeOpenUrl(target);
|
|
2157
2157
|
}, []);
|
|
2158
2158
|
const onRunProgram = react.useCallback(
|
|
2159
2159
|
(target) => {
|
|
2160
|
-
onAddRunProgramNotice?.(
|
|
2160
|
+
onAddRunProgramNotice?.(chunkMH4VFSDL_js.buildRunProgramNotice(target));
|
|
2161
2161
|
},
|
|
2162
2162
|
[onAddRunProgramNotice]
|
|
2163
2163
|
);
|
|
2164
2164
|
const onPlayMedia = react.useCallback(
|
|
2165
2165
|
(elementId) => {
|
|
2166
|
-
|
|
2166
|
+
chunkMH4VFSDL_js.toggleStageElementMedia(containerRef.current, elementId);
|
|
2167
2167
|
},
|
|
2168
2168
|
[containerRef]
|
|
2169
2169
|
);
|
|
2170
2170
|
const onOleVerb = react.useCallback(
|
|
2171
2171
|
(verb, elementId) => {
|
|
2172
|
-
const target =
|
|
2172
|
+
const target = chunkMH4VFSDL_js.resolveOleVerbTarget(slides[presentationSlideIndex], elementId, verb);
|
|
2173
2173
|
if (!target) {
|
|
2174
2174
|
return;
|
|
2175
2175
|
}
|
|
2176
2176
|
if (target.action === "download") {
|
|
2177
|
-
|
|
2177
|
+
chunkMH4VFSDL_js.downloadDataUrl(target.url, target.fileName ?? "download");
|
|
2178
2178
|
} else {
|
|
2179
|
-
|
|
2179
|
+
chunkMH4VFSDL_js.openUrlInNewTab(target.url);
|
|
2180
2180
|
}
|
|
2181
2181
|
},
|
|
2182
2182
|
[slides, presentationSlideIndex]
|
|
@@ -2207,22 +2207,22 @@ function usePresentationActionExtensions(input) {
|
|
|
2207
2207
|
};
|
|
2208
2208
|
}
|
|
2209
2209
|
function usePresenterConsole(slideIndex, active) {
|
|
2210
|
-
const timerRef = react.useRef(
|
|
2211
|
-
const [snapshot, setSnapshot] = react.useState(() =>
|
|
2210
|
+
const timerRef = react.useRef(chunkMH4VFSDL_js.createPresenterTimer());
|
|
2211
|
+
const [snapshot, setSnapshot] = react.useState(() => chunkMH4VFSDL_js.createInitialPresentationSnapshot(slideIndex));
|
|
2212
2212
|
const patch = react.useCallback((value) => {
|
|
2213
|
-
setSnapshot((current) =>
|
|
2213
|
+
setSnapshot((current) => chunkMH4VFSDL_js.mergePresentationSnapshot(current, value));
|
|
2214
2214
|
}, []);
|
|
2215
2215
|
react.useEffect(() => patch({ slideIndex }), [patch, slideIndex]);
|
|
2216
2216
|
react.useEffect(() => {
|
|
2217
2217
|
if (!active) {
|
|
2218
2218
|
return;
|
|
2219
2219
|
}
|
|
2220
|
-
timerRef.current =
|
|
2220
|
+
timerRef.current = chunkMH4VFSDL_js.resetPresenterTimer();
|
|
2221
2221
|
patch({ paused: false, elapsedMs: 0 });
|
|
2222
2222
|
const timer = window.setInterval(() => {
|
|
2223
2223
|
patch({
|
|
2224
2224
|
paused: timerRef.current.paused,
|
|
2225
|
-
elapsedMs:
|
|
2225
|
+
elapsedMs: chunkMH4VFSDL_js.presenterElapsed(timerRef.current)
|
|
2226
2226
|
});
|
|
2227
2227
|
}, 1e3);
|
|
2228
2228
|
return () => window.clearInterval(timer);
|
|
@@ -2232,19 +2232,19 @@ function usePresenterConsole(slideIndex, active) {
|
|
|
2232
2232
|
applyAudienceSnapshot: setSnapshot,
|
|
2233
2233
|
setBlackout: (blackout) => patch({ blackout }),
|
|
2234
2234
|
toggleTimer: () => {
|
|
2235
|
-
timerRef.current =
|
|
2235
|
+
timerRef.current = chunkMH4VFSDL_js.togglePresenterTimer(timerRef.current);
|
|
2236
2236
|
patch({
|
|
2237
2237
|
paused: timerRef.current.paused,
|
|
2238
|
-
elapsedMs:
|
|
2238
|
+
elapsedMs: chunkMH4VFSDL_js.presenterElapsed(timerRef.current)
|
|
2239
2239
|
});
|
|
2240
2240
|
},
|
|
2241
2241
|
resetTimer: () => {
|
|
2242
|
-
timerRef.current =
|
|
2242
|
+
timerRef.current = chunkMH4VFSDL_js.resetPresenterTimer();
|
|
2243
2243
|
patch({ paused: false, elapsedMs: 0 });
|
|
2244
2244
|
},
|
|
2245
2245
|
stepZoom: (direction) => setSnapshot(
|
|
2246
|
-
(current) =>
|
|
2247
|
-
zoom:
|
|
2246
|
+
(current) => chunkMH4VFSDL_js.mergePresentationSnapshot(current, {
|
|
2247
|
+
zoom: chunkMH4VFSDL_js.stepPresenterZoom(
|
|
2248
2248
|
current.zoom ?? { scale: 1, originX: 0.5, originY: 0.5 },
|
|
2249
2249
|
direction
|
|
2250
2250
|
)
|
|
@@ -2299,7 +2299,7 @@ function usePresentationMode(input) {
|
|
|
2299
2299
|
const [allSlidesOpen, setAllSlidesOpen] = react.useState(false);
|
|
2300
2300
|
const [endOfShowVisible, setEndOfShowVisible] = react.useState(false);
|
|
2301
2301
|
const [presentationStartTime, setPresentationStartTime] = react.useState(null);
|
|
2302
|
-
const showGuard = react.useMemo(() =>
|
|
2302
|
+
const showGuard = react.useMemo(() => chunkMH4VFSDL_js.createPresenterShowGuard(), []);
|
|
2303
2303
|
const {
|
|
2304
2304
|
presentationAnimations,
|
|
2305
2305
|
presentationElementStates,
|
|
@@ -2399,7 +2399,7 @@ function usePresentationMode(input) {
|
|
|
2399
2399
|
actionExtensions.bindNavigateToSlide(navigateToSlide);
|
|
2400
2400
|
const movePresentationSlide = react.useCallback(
|
|
2401
2401
|
(direction, trigger = "explicit") => {
|
|
2402
|
-
if (!
|
|
2402
|
+
if (!chunkMH4VFSDL_js.acceptsPresentationInput()) {
|
|
2403
2403
|
return;
|
|
2404
2404
|
}
|
|
2405
2405
|
if (endOfShowVisible) {
|
|
@@ -2468,7 +2468,7 @@ function usePresentationMode(input) {
|
|
|
2468
2468
|
onSetMode("present");
|
|
2469
2469
|
}, [containerRef, onSetMode, setRehearsing]);
|
|
2470
2470
|
const enterPresentModeFromBeginning = react.useCallback(() => {
|
|
2471
|
-
const first =
|
|
2471
|
+
const first = chunkMH4VFSDL_js.firstShowSlideIndex(visibleSlideIndexes);
|
|
2472
2472
|
if (first !== void 0) {
|
|
2473
2473
|
onSetActiveSlideIndex(first);
|
|
2474
2474
|
}
|
|
@@ -2548,7 +2548,7 @@ function usePresentationMode(input) {
|
|
|
2548
2548
|
if (mode !== "present") {
|
|
2549
2549
|
return;
|
|
2550
2550
|
}
|
|
2551
|
-
return
|
|
2551
|
+
return chunkMH4VFSDL_js.attachPresentationVisibilityPause({
|
|
2552
2552
|
root: containerRef.current ?? void 0,
|
|
2553
2553
|
onHidden: () => clearPresentationTimersRef.current(),
|
|
2554
2554
|
onVisible: () => scheduleAutoAdvanceRef.current(presentationSlideIndexRef.current)
|
|
@@ -2556,7 +2556,7 @@ function usePresentationMode(input) {
|
|
|
2556
2556
|
}, [mode, containerRef]);
|
|
2557
2557
|
react.useLayoutEffect(() => {
|
|
2558
2558
|
if (mode === "present") {
|
|
2559
|
-
const idx =
|
|
2559
|
+
const idx = chunkMH4VFSDL_js.presentationEntrySlideIndex(
|
|
2560
2560
|
activeSlideIndexRef.current,
|
|
2561
2561
|
visibleSlideIndexesRef.current
|
|
2562
2562
|
);
|
|
@@ -2635,11 +2635,11 @@ function usePresentationMode(input) {
|
|
|
2635
2635
|
return void 0;
|
|
2636
2636
|
}
|
|
2637
2637
|
const incoming = slides[transitionOverlay.incomingSlideIndex];
|
|
2638
|
-
return
|
|
2638
|
+
return chunkMH4VFSDL_js.buildMorphTransitionPlan(
|
|
2639
2639
|
slides[transitionOverlay.outgoingSlideIndex],
|
|
2640
2640
|
incoming,
|
|
2641
2641
|
transitionOverlay.durationMs,
|
|
2642
|
-
|
|
2642
|
+
chunkMH4VFSDL_js.morphOptionToMode(transitionOverlay.transition.morphOption),
|
|
2643
2643
|
// `PresentationStage` stacks the incoming slide's elements above its
|
|
2644
2644
|
// template shapes (`zIndex = templateElements.length + index`), so a
|
|
2645
2645
|
// z-index journey has to start counting where the stage does.
|
|
@@ -2664,7 +2664,7 @@ function usePresentationMode(input) {
|
|
|
2664
2664
|
if (!morphPlan) {
|
|
2665
2665
|
return presentationKeyframesCss;
|
|
2666
2666
|
}
|
|
2667
|
-
const imageRules =
|
|
2667
|
+
const imageRules = chunkMH4VFSDL_js.buildMorphAnimationRules(morphPlan, "", "incoming", "image");
|
|
2668
2668
|
return `${presentationKeyframesCss ?? ""}
|
|
2669
2669
|
${morphPlan.keyframesCss}
|
|
2670
2670
|
${imageRules}`;
|
|
@@ -2961,7 +2961,7 @@ function useFindReplace({
|
|
|
2961
2961
|
const [findResults, setFindResults] = react.useState([]);
|
|
2962
2962
|
const [findResultIndex, setFindResultIndex] = react.useState(-1);
|
|
2963
2963
|
const performFind = react.useCallback(() => {
|
|
2964
|
-
const results =
|
|
2964
|
+
const results = chunkMH4VFSDL_js.findInSlides(slides, findQuery, { matchCase: findMatchCase });
|
|
2965
2965
|
if (!findQuery) {
|
|
2966
2966
|
setFindResults([]);
|
|
2967
2967
|
setFindResultIndex(-1);
|
|
@@ -2995,7 +2995,7 @@ function useFindReplace({
|
|
|
2995
2995
|
return;
|
|
2996
2996
|
}
|
|
2997
2997
|
onUpdateSlides(
|
|
2998
|
-
(prevSlides) =>
|
|
2998
|
+
(prevSlides) => chunkMH4VFSDL_js.applyFindReplacements(prevSlides, toReplace, replaceQuery).slides
|
|
2999
2999
|
);
|
|
3000
3000
|
onMarkDirty();
|
|
3001
3001
|
},
|
|
@@ -3017,9 +3017,9 @@ function useFindReplace({
|
|
|
3017
3017
|
}, [findResults, applyReplacements, performFind]);
|
|
3018
3018
|
react.useEffect(() => {
|
|
3019
3019
|
const handler = (event) => {
|
|
3020
|
-
const { action } =
|
|
3020
|
+
const { action } = chunkMH4VFSDL_js.mapEditorKey(event, {
|
|
3021
3021
|
canEdit: mode === "edit",
|
|
3022
|
-
isTextInputTarget:
|
|
3022
|
+
isTextInputTarget: chunkMH4VFSDL_js.isEditorTextInputTarget(event.target)
|
|
3023
3023
|
});
|
|
3024
3024
|
if (action !== "find") {
|
|
3025
3025
|
return;
|
|
@@ -3130,7 +3130,7 @@ function addCommentToSlide(slides, slideIndex, text, authorName, elementId, ment
|
|
|
3130
3130
|
if (!slide) {
|
|
3131
3131
|
return { slides, didAdd: false };
|
|
3132
3132
|
}
|
|
3133
|
-
const next =
|
|
3133
|
+
const next = chunkMH4VFSDL_js.addCommentToList(
|
|
3134
3134
|
slide.comments || [],
|
|
3135
3135
|
text,
|
|
3136
3136
|
authorName,
|
|
@@ -3151,7 +3151,7 @@ function removeCommentFromSlide(slides, slideIndex, commentId) {
|
|
|
3151
3151
|
if (!slide) {
|
|
3152
3152
|
return { slides, didDelete: false };
|
|
3153
3153
|
}
|
|
3154
|
-
const next =
|
|
3154
|
+
const next = chunkMH4VFSDL_js.removeCommentFromList(slide.comments || [], commentId);
|
|
3155
3155
|
if (!next) {
|
|
3156
3156
|
return { slides, didDelete: false };
|
|
3157
3157
|
}
|
|
@@ -3162,7 +3162,7 @@ function editCommentInSlide(slides, slideIndex, commentId, newText) {
|
|
|
3162
3162
|
if (!slide) {
|
|
3163
3163
|
return { slides, didUpdate: false };
|
|
3164
3164
|
}
|
|
3165
|
-
const next =
|
|
3165
|
+
const next = chunkMH4VFSDL_js.editCommentInList(slide.comments || [], commentId, newText);
|
|
3166
3166
|
if (!next) {
|
|
3167
3167
|
return { slides, didUpdate: false };
|
|
3168
3168
|
}
|
|
@@ -3173,7 +3173,7 @@ function toggleResolvedInSlide(slides, slideIndex, commentId) {
|
|
|
3173
3173
|
if (!slide) {
|
|
3174
3174
|
return { slides, didUpdate: false };
|
|
3175
3175
|
}
|
|
3176
|
-
const next =
|
|
3176
|
+
const next = chunkMH4VFSDL_js.toggleCommentResolvedInList(slide.comments || [], commentId);
|
|
3177
3177
|
if (!next) {
|
|
3178
3178
|
return { slides, didUpdate: false };
|
|
3179
3179
|
}
|
|
@@ -3184,7 +3184,7 @@ function addReplyToSlide(slides, slideIndex, parentId, text, authorName, mention
|
|
|
3184
3184
|
if (!slide) {
|
|
3185
3185
|
return { slides, didAdd: false };
|
|
3186
3186
|
}
|
|
3187
|
-
const next =
|
|
3187
|
+
const next = chunkMH4VFSDL_js.replyToCommentInList(slide.comments || [], parentId, text, authorName);
|
|
3188
3188
|
if (!next) {
|
|
3189
3189
|
return { slides, didAdd: false };
|
|
3190
3190
|
}
|
|
@@ -3571,7 +3571,7 @@ function useDerivedElementState(input) {
|
|
|
3571
3571
|
return [];
|
|
3572
3572
|
}
|
|
3573
3573
|
return [
|
|
3574
|
-
...
|
|
3574
|
+
...chunkMH4VFSDL_js.visibleTemplateElements(activeSlide, templateElementsBySlideId[activeSlide.id] ?? [])
|
|
3575
3575
|
];
|
|
3576
3576
|
}, [activeSlide, templateElementsBySlideId]);
|
|
3577
3577
|
const activeMaster = slideMasters[activeMasterIndex];
|
|
@@ -3638,7 +3638,7 @@ function useViewerCoreState(_input) {
|
|
|
3638
3638
|
const marqueeStateRef = react.useRef(null);
|
|
3639
3639
|
const isDrawingRef = react.useRef(false);
|
|
3640
3640
|
const justInteractedRef = react.useRef(false);
|
|
3641
|
-
const livePatcher = react.useMemo(() =>
|
|
3641
|
+
const livePatcher = react.useMemo(() => chunkMH4VFSDL_js.createCollaborationLivePatcher(), []);
|
|
3642
3642
|
react.useEffect(() => () => livePatcher.dispose(), [livePatcher]);
|
|
3643
3643
|
const slidesRef = react.useRef([]);
|
|
3644
3644
|
const [mode, setMode] = react.useState("edit");
|
|
@@ -3647,8 +3647,8 @@ function useViewerCoreState(_input) {
|
|
|
3647
3647
|
const [slides, setSlides] = react.useState([]);
|
|
3648
3648
|
const [templateElementsBySlideId, setTemplateElementsBySlideId] = react.useState({});
|
|
3649
3649
|
const [canvasSize, setCanvasSize] = react.useState({
|
|
3650
|
-
width:
|
|
3651
|
-
height:
|
|
3650
|
+
width: chunkH4LMXJ2Z_js.DEFAULT_CANVAS_WIDTH,
|
|
3651
|
+
height: chunkH4LMXJ2Z_js.DEFAULT_CANVAS_HEIGHT
|
|
3652
3652
|
});
|
|
3653
3653
|
const [slideSizeEmu, setSlideSizeEmu] = react.useState();
|
|
3654
3654
|
const [activeSlideIndex, setActiveSlideIndex] = react.useState(0);
|
|
@@ -3669,7 +3669,7 @@ function useViewerCoreState(_input) {
|
|
|
3669
3669
|
const resolved = typeof value === "function" ? value(inlineEditingTextRef.current) : value;
|
|
3670
3670
|
inlineEditingTextRef.current = resolved;
|
|
3671
3671
|
setInlineEditingTextBase(value);
|
|
3672
|
-
|
|
3672
|
+
chunkMH4VFSDL_js.publishLiveInlineText(
|
|
3673
3673
|
livePatcher,
|
|
3674
3674
|
slidesRef.current[activeSlideIndexRef.current],
|
|
3675
3675
|
inlineEditingElementIdRef.current,
|
|
@@ -3962,6 +3962,12 @@ function useViewerState(input) {
|
|
|
3962
3962
|
const ui = useViewerUIState();
|
|
3963
3963
|
return { ...core, ...ui };
|
|
3964
3964
|
}
|
|
3965
|
+
|
|
3966
|
+
// src/viewer/utils/glyph-outline-cache.ts
|
|
3967
|
+
var glyphOutlineFontCache = new chunkMH4VFSDL_js.GlyphOutlineFontCache();
|
|
3968
|
+
var getGlyphOutline = chunkMH4VFSDL_js.createGlyphOutlineLookup(glyphOutlineFontCache);
|
|
3969
|
+
|
|
3970
|
+
// src/viewer/hooks/useLoadContent.ts
|
|
3965
3971
|
function useLoadContent({
|
|
3966
3972
|
content,
|
|
3967
3973
|
clearSelection,
|
|
@@ -4032,7 +4038,7 @@ function useLoadContent({
|
|
|
4032
4038
|
);
|
|
4033
4039
|
}
|
|
4034
4040
|
const previousHandler = handlerRef.current;
|
|
4035
|
-
const handler = new
|
|
4041
|
+
const handler = new chunkMH4VFSDL_js.PptxHandler();
|
|
4036
4042
|
const parsed = await handler.load(buffer, { allowExternalImages });
|
|
4037
4043
|
if (cancelled || token !== renderTokenRef.current) {
|
|
4038
4044
|
handler.dispose();
|
|
@@ -4044,7 +4050,7 @@ function useLoadContent({
|
|
|
4044
4050
|
handlerRef.current = null;
|
|
4045
4051
|
const mediaElements = [];
|
|
4046
4052
|
for (const slide of parsed.slides) {
|
|
4047
|
-
|
|
4053
|
+
chunkMH4VFSDL_js.collectMediaElements(slide.elements, mediaElements);
|
|
4048
4054
|
}
|
|
4049
4055
|
for (const url of mediaDataUrls.values()) {
|
|
4050
4056
|
if (url.startsWith("blob:")) {
|
|
@@ -4054,7 +4060,7 @@ function useLoadContent({
|
|
|
4054
4060
|
mediaDataUrls.clear();
|
|
4055
4061
|
await Promise.all(
|
|
4056
4062
|
mediaElements.map(async (mediaElement) => {
|
|
4057
|
-
const resolved = await
|
|
4063
|
+
const resolved = await chunkMH4VFSDL_js.resolveMediaElementSource(mediaElement, handler);
|
|
4058
4064
|
if (resolved.missing || !resolved.mediaPath || !resolved.url) {
|
|
4059
4065
|
mediaElement.mediaMissing = true;
|
|
4060
4066
|
return;
|
|
@@ -4065,7 +4071,7 @@ function useLoadContent({
|
|
|
4065
4071
|
}
|
|
4066
4072
|
})
|
|
4067
4073
|
);
|
|
4068
|
-
const { paths: imagePaths, refs: imageRefs } =
|
|
4074
|
+
const { paths: imagePaths, refs: imageRefs } = chunkMH4VFSDL_js.collectImagePaths(parsed.slides);
|
|
4069
4075
|
let nextSlides = parsed.slides;
|
|
4070
4076
|
if (imagePaths.size > 0) {
|
|
4071
4077
|
const resolvedMap = /* @__PURE__ */ new Map();
|
|
@@ -4081,25 +4087,25 @@ function useLoadContent({
|
|
|
4081
4087
|
})
|
|
4082
4088
|
);
|
|
4083
4089
|
nextSlides = parsed.slides.map((s) => {
|
|
4084
|
-
const newElements =
|
|
4090
|
+
const newElements = chunkMH4VFSDL_js.applyImagePathPatches(s.elements, resolvedMap, imageRefs);
|
|
4085
4091
|
return newElements === s.elements ? s : { ...s, elements: newElements };
|
|
4086
4092
|
});
|
|
4087
4093
|
}
|
|
4088
|
-
nextSlides = await
|
|
4094
|
+
nextSlides = await chunkMH4VFSDL_js.resolveTableCellImageUrls(
|
|
4089
4095
|
nextSlides,
|
|
4090
4096
|
(path) => handler.getImageData(path)
|
|
4091
4097
|
);
|
|
4092
|
-
const nextTableStyleMap = await
|
|
4098
|
+
const nextTableStyleMap = await chunkMH4VFSDL_js.resolveTableStyleImageUrls(
|
|
4093
4099
|
parsed.tableStyleMap,
|
|
4094
4100
|
(path) => handler.getImageData(path)
|
|
4095
4101
|
);
|
|
4096
4102
|
handlerRef.current = handler;
|
|
4097
|
-
const partition =
|
|
4103
|
+
const partition = chunkMH4VFSDL_js.partitionTemplateElements(nextSlides);
|
|
4098
4104
|
setSlides(partition.slides);
|
|
4099
4105
|
setTemplateElementsBySlideId(partition.templateElementsBySlideId);
|
|
4100
4106
|
setCanvasSize({
|
|
4101
|
-
width: parsed.width ??
|
|
4102
|
-
height: parsed.height ??
|
|
4107
|
+
width: parsed.width ?? chunkH4LMXJ2Z_js.DEFAULT_CANVAS_WIDTH,
|
|
4108
|
+
height: parsed.height ?? chunkH4LMXJ2Z_js.DEFAULT_CANVAS_HEIGHT
|
|
4103
4109
|
});
|
|
4104
4110
|
setSlideSizeEmu(
|
|
4105
4111
|
typeof parsed.widthEmu === "number" && typeof parsed.heightEmu === "number" && parsed.widthEmu > 0 && parsed.heightEmu > 0 ? {
|
|
@@ -4112,7 +4118,7 @@ function useLoadContent({
|
|
|
4112
4118
|
setLayoutOptions(parsed.layoutOptions ?? []);
|
|
4113
4119
|
setSlideMasters(parsed.slideMasters ?? []);
|
|
4114
4120
|
setModernCommentAuthors(parsed.modernCommentAuthors ?? []);
|
|
4115
|
-
setRecentColors(
|
|
4121
|
+
setRecentColors(chunkMH4VFSDL_js.seedRecentColors({ mruColors: parsed.mruColors }));
|
|
4116
4122
|
setTheme(parsed.theme);
|
|
4117
4123
|
setTableStyleMap(nextTableStyleMap);
|
|
4118
4124
|
setTableStylesDefaultId(parsed.tableStylesDefaultId);
|
|
@@ -4120,7 +4126,7 @@ function useLoadContent({
|
|
|
4120
4126
|
setThemeOptions(parsed.themeOptions ?? []);
|
|
4121
4127
|
setCustomShows(parsed.customShows ?? []);
|
|
4122
4128
|
setActiveCustomShowId(
|
|
4123
|
-
|
|
4129
|
+
chunkMH4VFSDL_js.resolveAuthoredCustomShowId(parsed.presentationProperties, parsed.customShows) ?? null
|
|
4124
4130
|
);
|
|
4125
4131
|
setSections(parsed.sections ?? []);
|
|
4126
4132
|
setPresentationProperties(parsed.presentationProperties ?? {});
|
|
@@ -4140,14 +4146,15 @@ function useLoadContent({
|
|
|
4140
4146
|
setCoreProperties(parsed.coreProperties);
|
|
4141
4147
|
setAppProperties(parsed.appProperties);
|
|
4142
4148
|
setEmbeddedFonts(parsed.embeddedFonts ?? []);
|
|
4149
|
+
glyphOutlineFontCache.registerEmbeddedFonts(parsed.embeddedFonts ?? []);
|
|
4143
4150
|
setHasMacros(parsed.hasMacros === true);
|
|
4144
4151
|
setHasDigitalSignatures(parsed.hasDigitalSignatures === true);
|
|
4145
4152
|
setDigitalSignatureCount(parsed.digitalSignatureCount ?? 0);
|
|
4146
|
-
setGuides(
|
|
4147
|
-
setReadOnlyRecommendation(
|
|
4153
|
+
setGuides(chunkMH4VFSDL_js.buildInitialGuides(parsed.presentationGuides, parsed.slides[0]?.guides));
|
|
4154
|
+
setReadOnlyRecommendation(chunkMH4VFSDL_js.readOnlyRecommendation(parsed));
|
|
4148
4155
|
setModifyVerifier(parsed.modifyVerifier ?? void 0);
|
|
4149
4156
|
setCompatToasts(
|
|
4150
|
-
|
|
4157
|
+
chunkMH4VFSDL_js.compatibilityWarningToasts([
|
|
4151
4158
|
...parsed.warnings ?? [],
|
|
4152
4159
|
...parsed.slides.flatMap((slide) => slide.warnings ?? [])
|
|
4153
4160
|
])
|
|
@@ -4159,7 +4166,7 @@ function useLoadContent({
|
|
|
4159
4166
|
onContentApplied?.();
|
|
4160
4167
|
} catch (err) {
|
|
4161
4168
|
if (!cancelled && token === renderTokenRef.current) {
|
|
4162
|
-
if (err instanceof
|
|
4169
|
+
if (err instanceof chunkMH4VFSDL_js.EncryptedFileError) {
|
|
4163
4170
|
setIsEncrypted(true);
|
|
4164
4171
|
} else {
|
|
4165
4172
|
console.error("[pptx] Failed to load presentation content:", err);
|
|
@@ -4187,7 +4194,7 @@ function useLoadContent({
|
|
|
4187
4194
|
}
|
|
4188
4195
|
function useAutosave(input) {
|
|
4189
4196
|
const { isDirty, filePath, serializeSlides, enabled = true, getChangeSources } = input;
|
|
4190
|
-
const intervalMs =
|
|
4197
|
+
const intervalMs = chunkMH4VFSDL_js.resolveAutosaveIntervalMs({
|
|
4191
4198
|
hostIntervalMs: input.intervalMs,
|
|
4192
4199
|
optionsIntervalSeconds: input.intervalSeconds
|
|
4193
4200
|
});
|
|
@@ -4218,7 +4225,7 @@ function useAutosave(input) {
|
|
|
4218
4225
|
return;
|
|
4219
4226
|
}
|
|
4220
4227
|
const sources = changeSourcesRef.current?.() ?? [];
|
|
4221
|
-
if (!
|
|
4228
|
+
if (!chunkMH4VFSDL_js.shouldWriteAutosaveSnapshot({
|
|
4222
4229
|
filePath: path,
|
|
4223
4230
|
isDirty: isDirtyRef.current,
|
|
4224
4231
|
saving: isSavingRef.current,
|
|
@@ -4236,8 +4243,8 @@ function useAutosave(input) {
|
|
|
4236
4243
|
isSavingRef.current = false;
|
|
4237
4244
|
return;
|
|
4238
4245
|
}
|
|
4239
|
-
await
|
|
4240
|
-
lastSnapshotRef.current =
|
|
4246
|
+
await chunkMH4VFSDL_js.saveAutosaveSnapshot(path, data);
|
|
4247
|
+
lastSnapshotRef.current = chunkMH4VFSDL_js.autosaveSnapshotMark(path, sources);
|
|
4241
4248
|
setAutosaveStatus({ state: "saved", timestamp: Date.now() });
|
|
4242
4249
|
} catch (err) {
|
|
4243
4250
|
setAutosaveStatus({
|
|
@@ -4291,13 +4298,13 @@ function useElementOperations(input) {
|
|
|
4291
4298
|
inlineEditingText
|
|
4292
4299
|
} = input;
|
|
4293
4300
|
const liveTextSegments = react.useCallback(() => {
|
|
4294
|
-
if (!selectedElement || !
|
|
4301
|
+
if (!selectedElement || !chunkMH4VFSDL_js.hasTextProperties(selectedElement)) {
|
|
4295
4302
|
return void 0;
|
|
4296
4303
|
}
|
|
4297
4304
|
if (selectedElement.id !== inlineEditingElementId) {
|
|
4298
4305
|
return selectedElement.textSegments;
|
|
4299
4306
|
}
|
|
4300
|
-
return
|
|
4307
|
+
return chunkMH4VFSDL_js.remapTextToSegments(
|
|
4301
4308
|
inlineEditingText,
|
|
4302
4309
|
selectedElement.textSegments,
|
|
4303
4310
|
selectedElement.textStyle
|
|
@@ -4338,11 +4345,11 @@ function useElementOperations(input) {
|
|
|
4338
4345
|
(elementId, updates) => {
|
|
4339
4346
|
if (masterView?.target) {
|
|
4340
4347
|
applyMasterViewWrite(
|
|
4341
|
-
|
|
4348
|
+
chunkMH4VFSDL_js.updateMasterViewElement(masterView, masterView.target, elementId, updates)
|
|
4342
4349
|
);
|
|
4343
4350
|
return;
|
|
4344
4351
|
}
|
|
4345
|
-
if (
|
|
4352
|
+
if (chunkMH4VFSDL_js.isTemplateElementId(elementId)) {
|
|
4346
4353
|
const slideId = activeSlide?.id;
|
|
4347
4354
|
if (slideId) {
|
|
4348
4355
|
setTemplateElementsBySlideId((prev) => ({
|
|
@@ -4353,7 +4360,7 @@ function useElementOperations(input) {
|
|
|
4353
4360
|
}));
|
|
4354
4361
|
}
|
|
4355
4362
|
} else {
|
|
4356
|
-
setSlides((prev) =>
|
|
4363
|
+
setSlides((prev) => chunkMH4VFSDL_js.updateElement(prev, activeSlideIndex, elementId, updates));
|
|
4357
4364
|
}
|
|
4358
4365
|
history.markDirty();
|
|
4359
4366
|
},
|
|
@@ -4378,7 +4385,7 @@ function useElementOperations(input) {
|
|
|
4378
4385
|
);
|
|
4379
4386
|
const updateSelectedShapeStyle = react.useCallback(
|
|
4380
4387
|
(updates) => {
|
|
4381
|
-
if (!selectedElement || !
|
|
4388
|
+
if (!selectedElement || !chunkMH4VFSDL_js.hasShapeProperties(selectedElement)) {
|
|
4382
4389
|
return;
|
|
4383
4390
|
}
|
|
4384
4391
|
updateSelectedElement({
|
|
@@ -4389,19 +4396,19 @@ function useElementOperations(input) {
|
|
|
4389
4396
|
);
|
|
4390
4397
|
const updateSelectedTextStyle = react.useCallback(
|
|
4391
4398
|
(updates) => {
|
|
4392
|
-
if (!selectedElement || !
|
|
4399
|
+
if (!selectedElement || !chunkMH4VFSDL_js.hasTextProperties(selectedElement)) {
|
|
4393
4400
|
return;
|
|
4394
4401
|
}
|
|
4395
4402
|
const isLiveEditing = selectedElement.id === inlineEditingElementId;
|
|
4396
4403
|
const currentSegments = liveTextSegments();
|
|
4397
|
-
const inlineSel =
|
|
4404
|
+
const inlineSel = chunkMH4VFSDL_js.getInlineEditorSelection(currentSegments);
|
|
4398
4405
|
if (inlineSel && currentSegments) {
|
|
4399
|
-
const { newSegments: newSegments2, newSelection } =
|
|
4406
|
+
const { newSegments: newSegments2, newSelection } = chunkMH4VFSDL_js.applyStyleToSelectedSegments(
|
|
4400
4407
|
currentSegments,
|
|
4401
4408
|
inlineSel,
|
|
4402
4409
|
updates
|
|
4403
4410
|
);
|
|
4404
|
-
|
|
4411
|
+
chunkMH4VFSDL_js.setPendingSelectionRestore(newSelection);
|
|
4405
4412
|
updateSelectedElement({
|
|
4406
4413
|
textSegments: newSegments2,
|
|
4407
4414
|
...isLiveEditing ? { text: inlineEditingText } : {}
|
|
@@ -4429,14 +4436,14 @@ function useElementOperations(input) {
|
|
|
4429
4436
|
);
|
|
4430
4437
|
const updateSelectedTextCase = react.useCallback(
|
|
4431
4438
|
(mode) => {
|
|
4432
|
-
if (!selectedElement || !
|
|
4439
|
+
if (!selectedElement || !chunkMH4VFSDL_js.hasTextProperties(selectedElement)) {
|
|
4433
4440
|
return;
|
|
4434
4441
|
}
|
|
4435
4442
|
const isLiveEditing = selectedElement.id === inlineEditingElementId;
|
|
4436
4443
|
const currentSegments = liveTextSegments();
|
|
4437
|
-
const inlineSel =
|
|
4444
|
+
const inlineSel = chunkMH4VFSDL_js.getInlineEditorSelection(currentSegments);
|
|
4438
4445
|
if (inlineSel && currentSegments) {
|
|
4439
|
-
const newSegments =
|
|
4446
|
+
const newSegments = chunkMH4VFSDL_js.applyCaseTransformToSegments(currentSegments, inlineSel, mode);
|
|
4440
4447
|
updateSelectedElement({
|
|
4441
4448
|
textSegments: newSegments,
|
|
4442
4449
|
...isLiveEditing ? { text: inlineEditingText } : {}
|
|
@@ -4445,7 +4452,7 @@ function useElementOperations(input) {
|
|
|
4445
4452
|
}
|
|
4446
4453
|
const updates = {};
|
|
4447
4454
|
if (currentSegments && currentSegments.length > 0) {
|
|
4448
|
-
updates.textSegments =
|
|
4455
|
+
updates.textSegments = chunkMH4VFSDL_js.applyCaseTransformToSegments(
|
|
4449
4456
|
currentSegments,
|
|
4450
4457
|
null,
|
|
4451
4458
|
mode
|
|
@@ -4453,7 +4460,7 @@ function useElementOperations(input) {
|
|
|
4453
4460
|
}
|
|
4454
4461
|
const baseText = isLiveEditing ? inlineEditingText : selectedElement.text;
|
|
4455
4462
|
if (typeof baseText === "string") {
|
|
4456
|
-
updates.text =
|
|
4463
|
+
updates.text = chunkMH4VFSDL_js.transformTextCase(baseText, mode);
|
|
4457
4464
|
}
|
|
4458
4465
|
updateSelectedElement(updates);
|
|
4459
4466
|
},
|
|
@@ -4472,15 +4479,15 @@ function useElementOperations(input) {
|
|
|
4472
4479
|
[setSlides]
|
|
4473
4480
|
);
|
|
4474
4481
|
const masterViewTarget = masterView?.target ?? null;
|
|
4475
|
-
const activeElements = masterViewTarget ?
|
|
4482
|
+
const activeElements = masterViewTarget ? chunkMH4VFSDL_js.masterViewElements(masterView, masterViewTarget) : editTemplateMode ? templateElements : activeSlide?.elements ?? [];
|
|
4476
4483
|
const updateActiveElements = react.useCallback(
|
|
4477
4484
|
(updater) => {
|
|
4478
4485
|
if (masterView?.target) {
|
|
4479
4486
|
applyMasterViewWrite(
|
|
4480
|
-
|
|
4487
|
+
chunkMH4VFSDL_js.replaceMasterViewElements(
|
|
4481
4488
|
masterView,
|
|
4482
4489
|
masterView.target,
|
|
4483
|
-
updater(
|
|
4490
|
+
updater(chunkMH4VFSDL_js.masterViewElements(masterView, masterView.target))
|
|
4484
4491
|
)
|
|
4485
4492
|
);
|
|
4486
4493
|
return;
|
|
@@ -4533,7 +4540,7 @@ function useSectionOperations(input) {
|
|
|
4533
4540
|
const { sections, setSections, slides, setSlides, markDirty } = input;
|
|
4534
4541
|
const addSection2 = react.useCallback(
|
|
4535
4542
|
(name, afterSlideIndex) => {
|
|
4536
|
-
const result =
|
|
4543
|
+
const result = chunkMH4VFSDL_js.addSection(sections, slides, name, afterSlideIndex);
|
|
4537
4544
|
setSlides(result.slides);
|
|
4538
4545
|
setSections(result.sections);
|
|
4539
4546
|
markDirty();
|
|
@@ -4542,7 +4549,7 @@ function useSectionOperations(input) {
|
|
|
4542
4549
|
);
|
|
4543
4550
|
const renameSection2 = react.useCallback(
|
|
4544
4551
|
(sectionId, newName) => {
|
|
4545
|
-
const result =
|
|
4552
|
+
const result = chunkMH4VFSDL_js.renameSection(sections, slides, sectionId, newName);
|
|
4546
4553
|
setSections(result.sections);
|
|
4547
4554
|
setSlides(result.slides);
|
|
4548
4555
|
markDirty();
|
|
@@ -4551,7 +4558,7 @@ function useSectionOperations(input) {
|
|
|
4551
4558
|
);
|
|
4552
4559
|
const deleteSection2 = react.useCallback(
|
|
4553
4560
|
(sectionId) => {
|
|
4554
|
-
const result =
|
|
4561
|
+
const result = chunkMH4VFSDL_js.deleteSection(sections, slides, sectionId);
|
|
4555
4562
|
setSections(result.sections);
|
|
4556
4563
|
setSlides(result.slides);
|
|
4557
4564
|
markDirty();
|
|
@@ -4560,21 +4567,21 @@ function useSectionOperations(input) {
|
|
|
4560
4567
|
);
|
|
4561
4568
|
const moveSectionUp2 = react.useCallback(
|
|
4562
4569
|
(sectionId) => {
|
|
4563
|
-
setSections(
|
|
4570
|
+
setSections(chunkMH4VFSDL_js.moveSectionUp(sections, sectionId));
|
|
4564
4571
|
markDirty();
|
|
4565
4572
|
},
|
|
4566
4573
|
[sections, setSections, markDirty]
|
|
4567
4574
|
);
|
|
4568
4575
|
const moveSectionDown2 = react.useCallback(
|
|
4569
4576
|
(sectionId) => {
|
|
4570
|
-
setSections(
|
|
4577
|
+
setSections(chunkMH4VFSDL_js.moveSectionDown(sections, sectionId));
|
|
4571
4578
|
markDirty();
|
|
4572
4579
|
},
|
|
4573
4580
|
[sections, setSections, markDirty]
|
|
4574
4581
|
);
|
|
4575
4582
|
const moveSlidesToSection2 = react.useCallback(
|
|
4576
4583
|
(slideIndexes, targetSectionId) => {
|
|
4577
|
-
const result =
|
|
4584
|
+
const result = chunkMH4VFSDL_js.moveSlidesToSection(sections, slides, slideIndexes, targetSectionId);
|
|
4578
4585
|
setSlides(result.slides);
|
|
4579
4586
|
setSections(result.sections);
|
|
4580
4587
|
markDirty();
|
|
@@ -4640,15 +4647,15 @@ function syncSelectionHandleOverlay(elementNode, elementId, geometry) {
|
|
|
4640
4647
|
// src/viewer/hooks/pointer-move-handlers.ts
|
|
4641
4648
|
function computeResizeGeometry(handle, startX, startY, startWidth, startHeight, dx, dy, snapToGrid, gridSpacingPx, lockAspect = false) {
|
|
4642
4649
|
const startBox = { x: startX, y: startY, width: startWidth, height: startHeight };
|
|
4643
|
-
let resized =
|
|
4650
|
+
let resized = chunkMH4VFSDL_js.applyResize(startBox, handle, dx, dy, 1, { minSize: chunkH4LMXJ2Z_js.MIN_ELEMENT_SIZE });
|
|
4644
4651
|
if (lockAspect) {
|
|
4645
|
-
resized =
|
|
4652
|
+
resized = chunkMH4VFSDL_js.lockResizeAspect(resized, startBox, handle, chunkH4LMXJ2Z_js.MIN_ELEMENT_SIZE);
|
|
4646
4653
|
}
|
|
4647
4654
|
const box = { x: resized.x, y: resized.y, width: resized.width, height: resized.height };
|
|
4648
4655
|
if (!snapToGrid) {
|
|
4649
4656
|
return box;
|
|
4650
4657
|
}
|
|
4651
|
-
return
|
|
4658
|
+
return chunkMH4VFSDL_js.snapBoxToGrid(box, handle, gridSpacingPx, chunkH4LMXJ2Z_js.MIN_ELEMENT_SIZE);
|
|
4652
4659
|
}
|
|
4653
4660
|
function resolveLiveTarget(input) {
|
|
4654
4661
|
const { livePatcher, editTemplateMode, activeSlide } = input;
|
|
@@ -4761,7 +4768,7 @@ function processDragMove(e, drag, editorScale, snapToGrid, snapToShape, gridSpac
|
|
|
4761
4768
|
width: el.width,
|
|
4762
4769
|
height: el.height
|
|
4763
4770
|
}));
|
|
4764
|
-
const snapResult =
|
|
4771
|
+
const snapResult = chunkMH4VFSDL_js.computeSnapToShape(
|
|
4765
4772
|
targetX,
|
|
4766
4773
|
targetY,
|
|
4767
4774
|
primaryEl.width,
|
|
@@ -4803,7 +4810,7 @@ function processDragMove(e, drag, editorScale, snapToGrid, snapToShape, gridSpac
|
|
|
4803
4810
|
if (live) {
|
|
4804
4811
|
for (const id of Object.keys(drag.startPositionsById)) {
|
|
4805
4812
|
const start = drag.startPositionsById[id];
|
|
4806
|
-
|
|
4813
|
+
chunkMH4VFSDL_js.publishLiveGeometry(live.patcher, live.slideId, id, {
|
|
4807
4814
|
x: start.x + appliedDx,
|
|
4808
4815
|
y: start.y + appliedDy
|
|
4809
4816
|
});
|
|
@@ -4835,8 +4842,8 @@ function processResizeMove(e, rs, editorScale, snapToGrid, gridSpacingPx, live)
|
|
|
4835
4842
|
rs.lastY = geo.y;
|
|
4836
4843
|
rs.lastWidth = geo.width;
|
|
4837
4844
|
rs.lastHeight = geo.height;
|
|
4838
|
-
const width = Math.max(geo.width,
|
|
4839
|
-
const height = Math.max(geo.height,
|
|
4845
|
+
const width = Math.max(geo.width, chunkH4LMXJ2Z_js.MIN_ELEMENT_SIZE);
|
|
4846
|
+
const height = Math.max(geo.height, chunkH4LMXJ2Z_js.MIN_ELEMENT_SIZE);
|
|
4840
4847
|
if (rs.domEl) {
|
|
4841
4848
|
rs.domEl.style.left = `${geo.x}px`;
|
|
4842
4849
|
rs.domEl.style.top = `${geo.y}px`;
|
|
@@ -4845,7 +4852,7 @@ function processResizeMove(e, rs, editorScale, snapToGrid, gridSpacingPx, live)
|
|
|
4845
4852
|
syncSelectionHandleOverlay(rs.domEl, rs.elementId, { x: geo.x, y: geo.y, width, height });
|
|
4846
4853
|
}
|
|
4847
4854
|
if (live) {
|
|
4848
|
-
|
|
4855
|
+
chunkMH4VFSDL_js.publishLiveGeometry(live.patcher, live.slideId, rs.elementId, {
|
|
4849
4856
|
x: geo.x,
|
|
4850
4857
|
y: geo.y,
|
|
4851
4858
|
width,
|
|
@@ -4856,7 +4863,7 @@ function processResizeMove(e, rs, editorScale, snapToGrid, gridSpacingPx, live)
|
|
|
4856
4863
|
function processAdjustmentMove(e, adj, editorScale, updateElementById) {
|
|
4857
4864
|
const dx = (e.clientX - adj.startClientX) / editorScale;
|
|
4858
4865
|
const dy = (e.clientY - adj.startClientY) / editorScale;
|
|
4859
|
-
const adjustments =
|
|
4866
|
+
const adjustments = chunkMH4VFSDL_js.getDraggedShapeAdjustments(adj, dx, dy);
|
|
4860
4867
|
if (!adj.moved && Math.hypot(dx, dy) > 2) {
|
|
4861
4868
|
adj.moved = true;
|
|
4862
4869
|
}
|
|
@@ -4931,13 +4938,13 @@ function processPointerUp(input) {
|
|
|
4931
4938
|
if (i !== activeSlideIndex) {
|
|
4932
4939
|
return s;
|
|
4933
4940
|
}
|
|
4934
|
-
const rerouted =
|
|
4941
|
+
const rerouted = chunkMH4VFSDL_js.rerouteConnectorsForMovedElements(s.elements, movedIds);
|
|
4935
4942
|
if (rerouted.length === 0) {
|
|
4936
4943
|
return s;
|
|
4937
4944
|
}
|
|
4938
4945
|
return {
|
|
4939
4946
|
...s,
|
|
4940
|
-
elements:
|
|
4947
|
+
elements: chunkMH4VFSDL_js.applyReroutedConnectors(s.elements, rerouted)
|
|
4941
4948
|
};
|
|
4942
4949
|
})
|
|
4943
4950
|
);
|
|
@@ -4962,9 +4969,9 @@ function processPointerUp(input) {
|
|
|
4962
4969
|
}
|
|
4963
4970
|
function commitMarquee(marquee, editTemplateMode, templateElements, activeSlide, applySelection, clearSelection) {
|
|
4964
4971
|
const sourceElements = editTemplateMode ? templateElements : activeSlide?.elements ?? [];
|
|
4965
|
-
const hitIds =
|
|
4972
|
+
const hitIds = chunkMH4VFSDL_js.computeMarqueeHitIds(marquee, sourceElements);
|
|
4966
4973
|
if (marquee.additive) {
|
|
4967
|
-
const merged =
|
|
4974
|
+
const merged = chunkMH4VFSDL_js.mergeAdditiveSelection(marquee.baseSelectionIds, hitIds);
|
|
4968
4975
|
if (merged.length > 0) {
|
|
4969
4976
|
applySelection(merged[0], merged);
|
|
4970
4977
|
} else {
|
|
@@ -4987,8 +4994,8 @@ function commitDrag(drag, editTemplateMode, activeSlide, activeSlideIndex, setTe
|
|
|
4987
4994
|
}
|
|
4988
4995
|
return { ...el, x: start.x + dx, y: start.y + dy };
|
|
4989
4996
|
});
|
|
4990
|
-
const rerouted =
|
|
4991
|
-
return
|
|
4997
|
+
const rerouted = chunkMH4VFSDL_js.rerouteConnectorsForMovedElements(movedElements, movedIds);
|
|
4998
|
+
return chunkMH4VFSDL_js.applyReroutedConnectors(movedElements, rerouted);
|
|
4992
4999
|
};
|
|
4993
5000
|
if (editTemplateMode) {
|
|
4994
5001
|
const slideId = activeSlide?.id;
|
|
@@ -5144,17 +5151,17 @@ function useCanvasInteractions(input) {
|
|
|
5144
5151
|
return;
|
|
5145
5152
|
}
|
|
5146
5153
|
const el = elementLookup.get(editId);
|
|
5147
|
-
if (el &&
|
|
5154
|
+
if (el && chunkMH4VFSDL_js.hasTextProperties(el)) {
|
|
5148
5155
|
const committedText = transformCommittedText ? transformCommittedText(inlineEditingText) : inlineEditingText;
|
|
5149
|
-
const textPatch =
|
|
5156
|
+
const textPatch = chunkMH4VFSDL_js.buildInlineTextCommitPatch(el, committedText);
|
|
5150
5157
|
if (!textPatch) {
|
|
5151
5158
|
setInlineEditingElementId(null);
|
|
5152
5159
|
setInlineEditingText("");
|
|
5153
5160
|
return;
|
|
5154
5161
|
}
|
|
5155
5162
|
const editorEl = document.querySelector("[data-inline-editor]");
|
|
5156
|
-
const newHeight =
|
|
5157
|
-
const shrink =
|
|
5163
|
+
const newHeight = chunkMH4VFSDL_js.resolveInlineEditAutoFitHeight(el.textStyle, el.height, editorEl);
|
|
5164
|
+
const shrink = chunkMH4VFSDL_js.resolveInlineEditNormAutofitShrink(el.textStyle, el.height, editorEl);
|
|
5158
5165
|
ops.updateElementById(editId, {
|
|
5159
5166
|
...textPatch,
|
|
5160
5167
|
...newHeight !== void 0 ? { height: newHeight } : {},
|
|
@@ -5172,7 +5179,7 @@ function useCanvasInteractions(input) {
|
|
|
5172
5179
|
setInlineEditingText("");
|
|
5173
5180
|
};
|
|
5174
5181
|
const openEquationEditorForElement = (el) => {
|
|
5175
|
-
if (!
|
|
5182
|
+
if (!chunkMH4VFSDL_js.hasTextProperties(el)) {
|
|
5176
5183
|
return false;
|
|
5177
5184
|
}
|
|
5178
5185
|
const eqSeg = el.textSegments?.find((seg) => seg.equationXml);
|
|
@@ -5202,7 +5209,7 @@ function useCanvasInteractions(input) {
|
|
|
5202
5209
|
justInteractedRef.current = false;
|
|
5203
5210
|
} else {
|
|
5204
5211
|
const el = elementLookup.get(elementId);
|
|
5205
|
-
if (el &&
|
|
5212
|
+
if (el && chunkMH4VFSDL_js.hasTextProperties(el) && chunkMH4VFSDL_js.canInteractWithElement(el, "textEdit")) {
|
|
5206
5213
|
if (!openEquationEditorForElement(el)) {
|
|
5207
5214
|
setInlineEditingElementId(elementId);
|
|
5208
5215
|
setInlineEditingText(el.text ?? "");
|
|
@@ -5221,7 +5228,7 @@ function useCanvasInteractions(input) {
|
|
|
5221
5228
|
if (openEquationEditorForElement(el)) {
|
|
5222
5229
|
return;
|
|
5223
5230
|
}
|
|
5224
|
-
if (
|
|
5231
|
+
if (chunkMH4VFSDL_js.hasTextProperties(el) && chunkMH4VFSDL_js.canInteractWithElement(el, "textEdit")) {
|
|
5225
5232
|
setInlineEditingElementId(elementId);
|
|
5226
5233
|
setInlineEditingText(el.text ?? "");
|
|
5227
5234
|
}
|
|
@@ -5244,7 +5251,7 @@ function useCanvasInteractions(input) {
|
|
|
5244
5251
|
justSelectedRef.current = false;
|
|
5245
5252
|
}
|
|
5246
5253
|
const ids = !wasSelected ? [elementId] : effectiveSelectedIds.length ? effectiveSelectedIds : [elementId];
|
|
5247
|
-
const movableIds =
|
|
5254
|
+
const movableIds = chunkMH4VFSDL_js.filterInteractableIds(ids, (id) => elementLookup.get(id), "move");
|
|
5248
5255
|
if (movableIds.length === 0) {
|
|
5249
5256
|
return;
|
|
5250
5257
|
}
|
|
@@ -5314,7 +5321,7 @@ function useCanvasInteractions(input) {
|
|
|
5314
5321
|
const handleResizePointerDown = (elementId, e, handle) => {
|
|
5315
5322
|
e.stopPropagation();
|
|
5316
5323
|
const el = elementLookup.get(elementId);
|
|
5317
|
-
if (!el || !
|
|
5324
|
+
if (!el || !chunkMH4VFSDL_js.canInteractWithElement(el, "resize")) {
|
|
5318
5325
|
return;
|
|
5319
5326
|
}
|
|
5320
5327
|
resizeStateRef.current = {
|
|
@@ -5336,7 +5343,7 @@ function useCanvasInteractions(input) {
|
|
|
5336
5343
|
};
|
|
5337
5344
|
const handleRotate = (elementId, rotationDeg) => {
|
|
5338
5345
|
const el = elementLookup.get(elementId);
|
|
5339
|
-
if (!el || !
|
|
5346
|
+
if (!el || !chunkMH4VFSDL_js.canInteractWithElement(el, "rotate")) {
|
|
5340
5347
|
return;
|
|
5341
5348
|
}
|
|
5342
5349
|
ops.updateElementById(elementId, { rotation: rotationDeg });
|
|
@@ -5356,10 +5363,10 @@ function useCanvasInteractions(input) {
|
|
|
5356
5363
|
const handleAdjustmentPointerDown = (elementId, e, descriptor) => {
|
|
5357
5364
|
e.stopPropagation();
|
|
5358
5365
|
const el = elementLookup.get(elementId);
|
|
5359
|
-
if (!el || !
|
|
5366
|
+
if (!el || !chunkMH4VFSDL_js.canInteractWithElement(el, "adjustHandle")) {
|
|
5360
5367
|
return;
|
|
5361
5368
|
}
|
|
5362
|
-
shapeAdjustmentDragStateRef.current =
|
|
5369
|
+
shapeAdjustmentDragStateRef.current = chunkMH4VFSDL_js.beginShapeAdjustment(
|
|
5363
5370
|
el,
|
|
5364
5371
|
descriptor,
|
|
5365
5372
|
e.clientX,
|
|
@@ -5406,7 +5413,7 @@ function createFileHandlers(deps) {
|
|
|
5406
5413
|
h = Math.round(h * scale);
|
|
5407
5414
|
}
|
|
5408
5415
|
addElement({
|
|
5409
|
-
id:
|
|
5416
|
+
id: chunkMH4VFSDL_js.generateElementId(),
|
|
5410
5417
|
type: "image",
|
|
5411
5418
|
x: Math.round((canvasSize.width - w) / 2),
|
|
5412
5419
|
y: Math.round((canvasSize.height - h) / 2),
|
|
@@ -5417,7 +5424,7 @@ function createFileHandlers(deps) {
|
|
|
5417
5424
|
};
|
|
5418
5425
|
img.onerror = () => {
|
|
5419
5426
|
addElement({
|
|
5420
|
-
id:
|
|
5427
|
+
id: chunkMH4VFSDL_js.generateElementId(),
|
|
5421
5428
|
type: "image",
|
|
5422
5429
|
x: 100,
|
|
5423
5430
|
y: 100,
|
|
@@ -5436,14 +5443,14 @@ function createFileHandlers(deps) {
|
|
|
5436
5443
|
return;
|
|
5437
5444
|
}
|
|
5438
5445
|
e.target.value = "";
|
|
5439
|
-
const mediaType =
|
|
5446
|
+
const mediaType = chunkMH4VFSDL_js.classifyMediaType(file.type);
|
|
5440
5447
|
if (!mediaType) {
|
|
5441
5448
|
return;
|
|
5442
5449
|
}
|
|
5443
5450
|
const elFilePath = file.path;
|
|
5444
5451
|
const insertMediaElement = (mediaSourceUrl, width, height) => {
|
|
5445
5452
|
addElement({
|
|
5446
|
-
id:
|
|
5453
|
+
id: chunkMH4VFSDL_js.generateElementId(),
|
|
5447
5454
|
type: "media",
|
|
5448
5455
|
mediaType,
|
|
5449
5456
|
mediaMimeType: file.type || void 0,
|
|
@@ -5618,13 +5625,13 @@ function createStructuredElementHandlers(deps) {
|
|
|
5618
5625
|
return;
|
|
5619
5626
|
}
|
|
5620
5627
|
addElement({
|
|
5621
|
-
id:
|
|
5628
|
+
id: chunkMH4VFSDL_js.generateElementId(),
|
|
5622
5629
|
type: "smartArt",
|
|
5623
5630
|
x: 100,
|
|
5624
5631
|
y: 120,
|
|
5625
5632
|
width: 600,
|
|
5626
5633
|
height: 340,
|
|
5627
|
-
smartArtData:
|
|
5634
|
+
smartArtData: chunkMH4VFSDL_js.buildSmartArtPresetData(
|
|
5628
5635
|
layout,
|
|
5629
5636
|
defaultItems,
|
|
5630
5637
|
(i) => `node-${Date.now()}-${i}-${Math.random().toString(36).slice(2, 8)}`
|
|
@@ -5636,7 +5643,7 @@ function createStructuredElementHandlers(deps) {
|
|
|
5636
5643
|
return;
|
|
5637
5644
|
}
|
|
5638
5645
|
addElement({
|
|
5639
|
-
id:
|
|
5646
|
+
id: chunkMH4VFSDL_js.generateElementId(),
|
|
5640
5647
|
type: "shape",
|
|
5641
5648
|
x: 120,
|
|
5642
5649
|
y: 200,
|
|
@@ -5674,7 +5681,7 @@ function createStructuredElementHandlers(deps) {
|
|
|
5674
5681
|
return;
|
|
5675
5682
|
}
|
|
5676
5683
|
const resolved = resolveHyperlinkEditResult(data);
|
|
5677
|
-
if (resolved.url && !
|
|
5684
|
+
if (resolved.url && !chunkMH4VFSDL_js.isUrlSafe(resolved.url)) {
|
|
5678
5685
|
return;
|
|
5679
5686
|
}
|
|
5680
5687
|
const actionClick = {
|
|
@@ -5698,7 +5705,7 @@ function createStructuredElementHandlers(deps) {
|
|
|
5698
5705
|
const displayText = value || fieldTexts[fieldType] || fieldType;
|
|
5699
5706
|
const fieldGuid = `{${crypto.randomUUID().toUpperCase()}}`;
|
|
5700
5707
|
addElement({
|
|
5701
|
-
id:
|
|
5708
|
+
id: chunkMH4VFSDL_js.generateElementId(),
|
|
5702
5709
|
type: "shape",
|
|
5703
5710
|
x: 120,
|
|
5704
5711
|
y: 200,
|
|
@@ -5720,11 +5727,11 @@ function createStructuredElementHandlers(deps) {
|
|
|
5720
5727
|
if (!activeSlide) {
|
|
5721
5728
|
return;
|
|
5722
5729
|
}
|
|
5723
|
-
const preset =
|
|
5730
|
+
const preset = chunkMH4VFSDL_js.ACTION_BUTTON_PRESETS.find((p) => p.shapeType === shapeType);
|
|
5724
5731
|
if (!preset) {
|
|
5725
5732
|
return;
|
|
5726
5733
|
}
|
|
5727
|
-
const defaultPptxAction =
|
|
5734
|
+
const defaultPptxAction = chunkMH4VFSDL_js.elementActionToPptxAction({
|
|
5728
5735
|
trigger: "click",
|
|
5729
5736
|
type: preset.defaultAction
|
|
5730
5737
|
});
|
|
@@ -5733,7 +5740,7 @@ function createStructuredElementHandlers(deps) {
|
|
|
5733
5740
|
defaultPptxAction.highlightClick = true;
|
|
5734
5741
|
}
|
|
5735
5742
|
addElement({
|
|
5736
|
-
id:
|
|
5743
|
+
id: chunkMH4VFSDL_js.generateElementId(),
|
|
5737
5744
|
type: "shape",
|
|
5738
5745
|
x: 150,
|
|
5739
5746
|
y: 150,
|
|
@@ -5800,14 +5807,14 @@ function useInsertElements(input) {
|
|
|
5800
5807
|
return;
|
|
5801
5808
|
}
|
|
5802
5809
|
addElement({
|
|
5803
|
-
id:
|
|
5810
|
+
id: chunkMH4VFSDL_js.generateElementId(),
|
|
5804
5811
|
type: "text",
|
|
5805
5812
|
x: 100,
|
|
5806
5813
|
y: 100,
|
|
5807
5814
|
width: 300,
|
|
5808
5815
|
height: 60,
|
|
5809
5816
|
text: "",
|
|
5810
|
-
textStyle: { fontSize:
|
|
5817
|
+
textStyle: { fontSize: chunkH4LMXJ2Z_js.DEFAULT_TEXT_FONT_SIZE }
|
|
5811
5818
|
});
|
|
5812
5819
|
};
|
|
5813
5820
|
const handleAddShape = () => {
|
|
@@ -5815,7 +5822,7 @@ function useInsertElements(input) {
|
|
|
5815
5822
|
return;
|
|
5816
5823
|
}
|
|
5817
5824
|
addElement({
|
|
5818
|
-
id:
|
|
5825
|
+
id: chunkMH4VFSDL_js.generateElementId(),
|
|
5819
5826
|
type: "shape",
|
|
5820
5827
|
x: 150,
|
|
5821
5828
|
y: 150,
|
|
@@ -5834,15 +5841,15 @@ function useInsertElements(input) {
|
|
|
5834
5841
|
return;
|
|
5835
5842
|
}
|
|
5836
5843
|
addElement({
|
|
5837
|
-
...
|
|
5838
|
-
id:
|
|
5844
|
+
...chunkMH4VFSDL_js.newTableElement(chunkH4LMXJ2Z_js.DEFAULT_TABLE_ROWS, chunkH4LMXJ2Z_js.DEFAULT_TABLE_COLUMNS, 100, 200),
|
|
5845
|
+
id: chunkMH4VFSDL_js.generateElementId()
|
|
5839
5846
|
});
|
|
5840
5847
|
};
|
|
5841
5848
|
const handleAddChart = (chartKind) => {
|
|
5842
5849
|
if (!activeSlide) {
|
|
5843
5850
|
return;
|
|
5844
5851
|
}
|
|
5845
|
-
addElement(
|
|
5852
|
+
addElement(chunkMH4VFSDL_js.createDefaultChartElement(chartKind));
|
|
5846
5853
|
};
|
|
5847
5854
|
const structured = createStructuredElementHandlers({
|
|
5848
5855
|
activeSlide,
|
|
@@ -5912,7 +5919,7 @@ function useClipboardHandlers(input) {
|
|
|
5912
5919
|
if (!selectedElement) {
|
|
5913
5920
|
return;
|
|
5914
5921
|
}
|
|
5915
|
-
setClipboardPayload(
|
|
5922
|
+
setClipboardPayload(chunkMH4VFSDL_js.buildElementClipboardPayload(selectedElement, editTemplateMode));
|
|
5916
5923
|
};
|
|
5917
5924
|
const handleDelete = () => {
|
|
5918
5925
|
const idsToDelete = effectiveSelectedIds;
|
|
@@ -5929,7 +5936,7 @@ function useClipboardHandlers(input) {
|
|
|
5929
5936
|
handleDelete();
|
|
5930
5937
|
};
|
|
5931
5938
|
const insertClone = (source) => {
|
|
5932
|
-
const clone =
|
|
5939
|
+
const clone = chunkMH4VFSDL_js.cloneElementForPaste(source, { intoTemplate: editTemplateMode });
|
|
5933
5940
|
ops.updateActiveElements((els) => [...els, clone]);
|
|
5934
5941
|
ops.applySelection(clone.id);
|
|
5935
5942
|
history.markDirty();
|
|
@@ -5964,7 +5971,7 @@ function resolveShapePath(el) {
|
|
|
5964
5971
|
return el.pathData;
|
|
5965
5972
|
}
|
|
5966
5973
|
if ("shapeType" in el && typeof el.shapeType === "string") {
|
|
5967
|
-
const clipPath =
|
|
5974
|
+
const clipPath = chunkMH4VFSDL_js.getPresetShapeClipPath(el.shapeType);
|
|
5968
5975
|
if (clipPath) {
|
|
5969
5976
|
const svgPath = clipPathToSvgPath(clipPath, el.width, el.height);
|
|
5970
5977
|
if (svgPath) {
|
|
@@ -6015,7 +6022,7 @@ function clipPathToSvgPath(clipPath, width, height) {
|
|
|
6015
6022
|
return parts.join(" ");
|
|
6016
6023
|
}
|
|
6017
6024
|
function transformPathToGlobal(pathData, el) {
|
|
6018
|
-
const polys =
|
|
6025
|
+
const polys = chunkMH4VFSDL_js.svgPathToPolygons(pathData);
|
|
6019
6026
|
if (polys.length === 0) {
|
|
6020
6027
|
return pathData;
|
|
6021
6028
|
}
|
|
@@ -6035,10 +6042,10 @@ function transformPathToGlobal(pathData, el) {
|
|
|
6035
6042
|
y: pt.y * scaleY + el.y
|
|
6036
6043
|
}))
|
|
6037
6044
|
);
|
|
6038
|
-
return
|
|
6045
|
+
return chunkMH4VFSDL_js.polygonsToSvgPath(transformed);
|
|
6039
6046
|
}
|
|
6040
6047
|
function transformPathToLocal(pathData, x, y, _width, _height) {
|
|
6041
|
-
const polys =
|
|
6048
|
+
const polys = chunkMH4VFSDL_js.svgPathToPolygons(pathData);
|
|
6042
6049
|
if (polys.length === 0) {
|
|
6043
6050
|
return pathData;
|
|
6044
6051
|
}
|
|
@@ -6048,10 +6055,10 @@ function transformPathToLocal(pathData, x, y, _width, _height) {
|
|
|
6048
6055
|
y: pt.y - y
|
|
6049
6056
|
}))
|
|
6050
6057
|
);
|
|
6051
|
-
return
|
|
6058
|
+
return chunkMH4VFSDL_js.polygonsToSvgPath(transformed);
|
|
6052
6059
|
}
|
|
6053
6060
|
function pathBounds(pathData) {
|
|
6054
|
-
const polys =
|
|
6061
|
+
const polys = chunkMH4VFSDL_js.svgPathToPolygons(pathData);
|
|
6055
6062
|
let minX = Infinity;
|
|
6056
6063
|
let minY = Infinity;
|
|
6057
6064
|
let maxX = -Infinity;
|
|
@@ -6110,7 +6117,7 @@ function useMergeShapesHandler(input) {
|
|
|
6110
6117
|
let allFragments = [];
|
|
6111
6118
|
let remaining = globalPaths[0];
|
|
6112
6119
|
for (let i = 1; i < globalPaths.length; i++) {
|
|
6113
|
-
const frags =
|
|
6120
|
+
const frags = chunkMH4VFSDL_js.mergeShapes("fragment", remaining, globalPaths[i]);
|
|
6114
6121
|
if (Array.isArray(frags)) {
|
|
6115
6122
|
allFragments = frags;
|
|
6116
6123
|
}
|
|
@@ -6139,7 +6146,7 @@ function useMergeShapesHandler(input) {
|
|
|
6139
6146
|
bounds.height
|
|
6140
6147
|
);
|
|
6141
6148
|
const newEl = {
|
|
6142
|
-
id:
|
|
6149
|
+
id: chunkMH4VFSDL_js.generateElementId(),
|
|
6143
6150
|
type: "shape",
|
|
6144
6151
|
x: bounds.x,
|
|
6145
6152
|
y: bounds.y,
|
|
@@ -6177,7 +6184,7 @@ function useMergeShapesHandler(input) {
|
|
|
6177
6184
|
} else {
|
|
6178
6185
|
let resultPath = globalPaths[0];
|
|
6179
6186
|
for (let i = 1; i < globalPaths.length; i++) {
|
|
6180
|
-
const result =
|
|
6187
|
+
const result = chunkMH4VFSDL_js.mergeShapes(operation, resultPath, globalPaths[i]);
|
|
6181
6188
|
if (typeof result === "string") {
|
|
6182
6189
|
resultPath = result;
|
|
6183
6190
|
}
|
|
@@ -6198,7 +6205,7 @@ function useMergeShapesHandler(input) {
|
|
|
6198
6205
|
);
|
|
6199
6206
|
const primary = targets[0];
|
|
6200
6207
|
const newEl = {
|
|
6201
|
-
id:
|
|
6208
|
+
id: chunkMH4VFSDL_js.generateElementId(),
|
|
6202
6209
|
type: "shape",
|
|
6203
6210
|
x: bounds.x,
|
|
6204
6211
|
y: bounds.y,
|
|
@@ -6261,10 +6268,10 @@ function useGroupAlignLayerHandlers(input) {
|
|
|
6261
6268
|
if (ids.length < 2 || !activeSlide) {
|
|
6262
6269
|
return;
|
|
6263
6270
|
}
|
|
6264
|
-
if (!selectedElements.every((el) =>
|
|
6271
|
+
if (!selectedElements.every((el) => chunkMH4VFSDL_js.canInteractWithElement(el, "group"))) {
|
|
6265
6272
|
return;
|
|
6266
6273
|
}
|
|
6267
|
-
const { elements, groupId } =
|
|
6274
|
+
const { elements, groupId } = chunkMH4VFSDL_js.groupElements(ops.activeElements, ids, chunkMH4VFSDL_js.generateElementId());
|
|
6268
6275
|
if (groupId === null) {
|
|
6269
6276
|
return;
|
|
6270
6277
|
}
|
|
@@ -6276,15 +6283,15 @@ function useGroupAlignLayerHandlers(input) {
|
|
|
6276
6283
|
if (!selectedElement || selectedElement.type !== "group" || !activeSlide) {
|
|
6277
6284
|
return;
|
|
6278
6285
|
}
|
|
6279
|
-
if (!
|
|
6286
|
+
if (!chunkMH4VFSDL_js.canInteractWithElement(selectedElement, "group")) {
|
|
6280
6287
|
return;
|
|
6281
6288
|
}
|
|
6282
6289
|
const group = selectedElement;
|
|
6283
|
-
const intoTemplate =
|
|
6290
|
+
const intoTemplate = chunkMH4VFSDL_js.isTemplateElementId(group.id);
|
|
6284
6291
|
const childIds = group.children.map(
|
|
6285
|
-
(child) => intoTemplate ?
|
|
6292
|
+
(child) => intoTemplate ? chunkMH4VFSDL_js.makeCloneId(true, child.id || group.id) : child.id || chunkMH4VFSDL_js.generateElementId()
|
|
6286
6293
|
);
|
|
6287
|
-
const { elements, childIds: usedIds } =
|
|
6294
|
+
const { elements, childIds: usedIds } = chunkMH4VFSDL_js.ungroupElements(
|
|
6288
6295
|
ops.activeElements,
|
|
6289
6296
|
group.id,
|
|
6290
6297
|
childIds,
|
|
@@ -6313,7 +6320,7 @@ function useGroupAlignLayerHandlers(input) {
|
|
|
6313
6320
|
if (!edge) {
|
|
6314
6321
|
return;
|
|
6315
6322
|
}
|
|
6316
|
-
const positions =
|
|
6323
|
+
const positions = chunkMH4VFSDL_js.alignElements(selectedElements, edge);
|
|
6317
6324
|
for (const [id, pos] of positions) {
|
|
6318
6325
|
const el = elementLookup.get(id);
|
|
6319
6326
|
if (!el) {
|
|
@@ -6331,7 +6338,7 @@ function useGroupAlignLayerHandlers(input) {
|
|
|
6331
6338
|
if (!distAxis) {
|
|
6332
6339
|
return;
|
|
6333
6340
|
}
|
|
6334
|
-
const positions =
|
|
6341
|
+
const positions = chunkMH4VFSDL_js.distributeElements(selectedElements, distAxis);
|
|
6335
6342
|
for (const [id, pos] of positions) {
|
|
6336
6343
|
const el = elementLookup.get(id);
|
|
6337
6344
|
if (!el) {
|
|
@@ -6342,14 +6349,14 @@ function useGroupAlignLayerHandlers(input) {
|
|
|
6342
6349
|
history.markDirty();
|
|
6343
6350
|
};
|
|
6344
6351
|
const canDistribute = selectedElements.length >= 3;
|
|
6345
|
-
const selectionGroupable = selectedElements.every((el) =>
|
|
6352
|
+
const selectionGroupable = selectedElements.every((el) => chunkMH4VFSDL_js.canInteractWithElement(el, "group"));
|
|
6346
6353
|
const handleMoveLayer = (direction) => {
|
|
6347
6354
|
if (!selectedElement || !activeSlide) {
|
|
6348
6355
|
return;
|
|
6349
6356
|
}
|
|
6350
6357
|
const id = selectedElement.id;
|
|
6351
6358
|
ops.updateActiveElements(
|
|
6352
|
-
(els) => direction === "forward" ?
|
|
6359
|
+
(els) => direction === "forward" ? chunkMH4VFSDL_js.bringForward(els, id) : direction === "backward" ? chunkMH4VFSDL_js.sendBackward(els, id) : els
|
|
6353
6360
|
);
|
|
6354
6361
|
history.markDirty();
|
|
6355
6362
|
};
|
|
@@ -6359,7 +6366,7 @@ function useGroupAlignLayerHandlers(input) {
|
|
|
6359
6366
|
}
|
|
6360
6367
|
const id = selectedElement.id;
|
|
6361
6368
|
ops.updateActiveElements(
|
|
6362
|
-
(els) => direction === "front" ?
|
|
6369
|
+
(els) => direction === "front" ? chunkMH4VFSDL_js.bringToFront(els, id) : chunkMH4VFSDL_js.sendToBack(els, id)
|
|
6363
6370
|
);
|
|
6364
6371
|
history.markDirty();
|
|
6365
6372
|
};
|
|
@@ -6493,7 +6500,7 @@ function useSlideManagement(input) {
|
|
|
6493
6500
|
theme
|
|
6494
6501
|
} = input;
|
|
6495
6502
|
const handleAddSlide = () => {
|
|
6496
|
-
const newSlide =
|
|
6503
|
+
const newSlide = chunkMH4VFSDL_js.createBlankSlide(slides.length + 1);
|
|
6497
6504
|
ops.updateSlides((prev) => {
|
|
6498
6505
|
const next = [...prev];
|
|
6499
6506
|
next.splice(activeSlideIndex + 1, 0, newSlide);
|
|
@@ -6556,7 +6563,7 @@ function useSlideManagement(input) {
|
|
|
6556
6563
|
}
|
|
6557
6564
|
const clone = {
|
|
6558
6565
|
...src,
|
|
6559
|
-
id:
|
|
6566
|
+
id: chunkMH4VFSDL_js.makeSlideId(),
|
|
6560
6567
|
elements: src.elements.map((el) => ({
|
|
6561
6568
|
...el,
|
|
6562
6569
|
id: `${el.id}-dup-${Math.random().toString(36).slice(2, 6)}`
|
|
@@ -6588,7 +6595,7 @@ function useSlideManagement(input) {
|
|
|
6588
6595
|
const handleInsertSlideFromLayout = (layoutPath, layoutName) => {
|
|
6589
6596
|
const insertAt = activeSlideIndex + 1;
|
|
6590
6597
|
const draft = {
|
|
6591
|
-
...
|
|
6598
|
+
...chunkMH4VFSDL_js.createBlankSlide(slides.length + 1),
|
|
6592
6599
|
layoutPath,
|
|
6593
6600
|
...layoutName ? { layoutName } : {}
|
|
6594
6601
|
};
|
|
@@ -6621,9 +6628,9 @@ function useSlideManagement(input) {
|
|
|
6621
6628
|
};
|
|
6622
6629
|
const handleInsertSlideFromTemplate = (templateId) => {
|
|
6623
6630
|
const insertAt = activeSlideIndex + 1;
|
|
6624
|
-
const draft =
|
|
6631
|
+
const draft = chunkMH4VFSDL_js.buildSlideTemplateSlide(templateId, chunkMH4VFSDL_js.makeSlideId(), slides.length + 1, {
|
|
6625
6632
|
...canvasSize ? { slideWidth: canvasSize.width, slideHeight: canvasSize.height } : {},
|
|
6626
|
-
scheme:
|
|
6633
|
+
scheme: chunkMH4VFSDL_js.templateSchemeFromTheme(theme?.colorScheme)
|
|
6627
6634
|
});
|
|
6628
6635
|
ops.updateSlides((prev) => insertSlideFromLayoutUpdater(prev, activeSlideIndex, draft));
|
|
6629
6636
|
setActiveSlideIndex(insertAt);
|
|
@@ -6660,7 +6667,7 @@ function createTableMergeHandlers(input) {
|
|
|
6660
6667
|
if (!nextCell || nextCell.hMerge || nextCell.vMerge) {
|
|
6661
6668
|
return;
|
|
6662
6669
|
}
|
|
6663
|
-
const newTableData =
|
|
6670
|
+
const newTableData = chunkMH4VFSDL_js.mergeCells(
|
|
6664
6671
|
[
|
|
6665
6672
|
{ row: rowIndex, col: columnIndex },
|
|
6666
6673
|
{ row: rowIndex, col: nextColIdx }
|
|
@@ -6668,7 +6675,7 @@ function createTableMergeHandlers(input) {
|
|
|
6668
6675
|
td
|
|
6669
6676
|
);
|
|
6670
6677
|
const updates = { tableData: newTableData };
|
|
6671
|
-
const newRawXml =
|
|
6678
|
+
const newRawXml = chunkMH4VFSDL_js.updateMergeAttrsInRawXml(selectedElement, newTableData);
|
|
6672
6679
|
if (newRawXml) {
|
|
6673
6680
|
updates.rawXml = newRawXml;
|
|
6674
6681
|
}
|
|
@@ -6694,7 +6701,7 @@ function createTableMergeHandlers(input) {
|
|
|
6694
6701
|
if (!targetNextCell || targetNextCell.hMerge || targetNextCell.vMerge) {
|
|
6695
6702
|
return;
|
|
6696
6703
|
}
|
|
6697
|
-
const newTableData =
|
|
6704
|
+
const newTableData = chunkMH4VFSDL_js.mergeCells(
|
|
6698
6705
|
[
|
|
6699
6706
|
{ row: rowIndex, col: columnIndex },
|
|
6700
6707
|
{ row: targetNextRowIdx, col: columnIndex }
|
|
@@ -6702,7 +6709,7 @@ function createTableMergeHandlers(input) {
|
|
|
6702
6709
|
td
|
|
6703
6710
|
);
|
|
6704
6711
|
const updates = { tableData: newTableData };
|
|
6705
|
-
const newRawXml =
|
|
6712
|
+
const newRawXml = chunkMH4VFSDL_js.updateMergeAttrsInRawXml(selectedElement, newTableData);
|
|
6706
6713
|
if (newRawXml) {
|
|
6707
6714
|
updates.rawXml = newRawXml;
|
|
6708
6715
|
}
|
|
@@ -6717,9 +6724,9 @@ function createTableMergeHandlers(input) {
|
|
|
6717
6724
|
return;
|
|
6718
6725
|
}
|
|
6719
6726
|
const td = selectedElement.tableData;
|
|
6720
|
-
const newTableData =
|
|
6727
|
+
const newTableData = chunkMH4VFSDL_js.mergeCells(ts.selectedCells, td);
|
|
6721
6728
|
const updates = { tableData: newTableData };
|
|
6722
|
-
const newRawXml =
|
|
6729
|
+
const newRawXml = chunkMH4VFSDL_js.updateMergeAttrsInRawXml(selectedElement, newTableData);
|
|
6723
6730
|
if (newRawXml) {
|
|
6724
6731
|
updates.rawXml = newRawXml;
|
|
6725
6732
|
}
|
|
@@ -6736,9 +6743,9 @@ function createTableMergeHandlers(input) {
|
|
|
6736
6743
|
}
|
|
6737
6744
|
const { rowIndex, columnIndex } = ts;
|
|
6738
6745
|
const td = selectedElement.tableData;
|
|
6739
|
-
const newTableData =
|
|
6746
|
+
const newTableData = chunkMH4VFSDL_js.splitCell(rowIndex, columnIndex, td);
|
|
6740
6747
|
const updates = { tableData: newTableData };
|
|
6741
|
-
const newRawXml =
|
|
6748
|
+
const newRawXml = chunkMH4VFSDL_js.updateMergeAttrsInRawXml(selectedElement, newTableData);
|
|
6742
6749
|
if (newRawXml) {
|
|
6743
6750
|
updates.rawXml = newRawXml;
|
|
6744
6751
|
}
|
|
@@ -6772,10 +6779,10 @@ function createTableStructHandlers(input) {
|
|
|
6772
6779
|
const text = transformCommittedText ? transformCommittedText(rawText) : rawText;
|
|
6773
6780
|
const updates = {};
|
|
6774
6781
|
if (el.tableData) {
|
|
6775
|
-
updates.tableData =
|
|
6782
|
+
updates.tableData = chunkMH4VFSDL_js.setCellText(el, rowIndex, colIndex, text).tableData;
|
|
6776
6783
|
}
|
|
6777
6784
|
if (el.rawXml) {
|
|
6778
|
-
const newRawXml =
|
|
6785
|
+
const newRawXml = chunkMH4VFSDL_js.updateCellTextInRawXml(el, rowIndex, colIndex, text);
|
|
6779
6786
|
if (newRawXml) {
|
|
6780
6787
|
updates.rawXml = newRawXml;
|
|
6781
6788
|
}
|
|
@@ -6799,7 +6806,7 @@ function createTableStructHandlers(input) {
|
|
|
6799
6806
|
const { rowIndex, columnIndex: colIndex } = ts;
|
|
6800
6807
|
const updates = {};
|
|
6801
6808
|
if (selectedElement.rawXml) {
|
|
6802
|
-
const newRawXml =
|
|
6809
|
+
const newRawXml = chunkMH4VFSDL_js.updateCellTextStyleInRawXml(
|
|
6803
6810
|
selectedElement,
|
|
6804
6811
|
rowIndex,
|
|
6805
6812
|
colIndex,
|
|
@@ -6863,9 +6870,9 @@ function createTableStructHandlers(input) {
|
|
|
6863
6870
|
return;
|
|
6864
6871
|
}
|
|
6865
6872
|
const rowIdx = ts?.rowIndex ?? 0;
|
|
6866
|
-
const newTableData =
|
|
6873
|
+
const newTableData = chunkMH4VFSDL_js.insertTableRow(selectedElement.tableData, rowIdx, position);
|
|
6867
6874
|
const updates = { tableData: newTableData };
|
|
6868
|
-
const newRawXml =
|
|
6875
|
+
const newRawXml = chunkMH4VFSDL_js.rebuildTableStructureInRawXml(selectedElement, newTableData);
|
|
6869
6876
|
if (newRawXml) {
|
|
6870
6877
|
updates.rawXml = newRawXml;
|
|
6871
6878
|
}
|
|
@@ -6878,12 +6885,12 @@ function createTableStructHandlers(input) {
|
|
|
6878
6885
|
}
|
|
6879
6886
|
const td = selectedElement.tableData;
|
|
6880
6887
|
const rowIdx = ts?.rowIndex ?? 0;
|
|
6881
|
-
const newTableData =
|
|
6888
|
+
const newTableData = chunkMH4VFSDL_js.deleteTableRow(td, rowIdx);
|
|
6882
6889
|
if (newTableData === td) {
|
|
6883
6890
|
return;
|
|
6884
6891
|
}
|
|
6885
6892
|
const updates = { tableData: newTableData };
|
|
6886
|
-
const newRawXml =
|
|
6893
|
+
const newRawXml = chunkMH4VFSDL_js.rebuildTableStructureInRawXml(selectedElement, newTableData);
|
|
6887
6894
|
if (newRawXml) {
|
|
6888
6895
|
updates.rawXml = newRawXml;
|
|
6889
6896
|
}
|
|
@@ -6895,9 +6902,9 @@ function createTableStructHandlers(input) {
|
|
|
6895
6902
|
return;
|
|
6896
6903
|
}
|
|
6897
6904
|
const colIdx = ts?.columnIndex ?? 0;
|
|
6898
|
-
const newTableData =
|
|
6905
|
+
const newTableData = chunkMH4VFSDL_js.insertTableColumn(selectedElement.tableData, colIdx, position);
|
|
6899
6906
|
const updates = { tableData: newTableData };
|
|
6900
|
-
const newRawXml =
|
|
6907
|
+
const newRawXml = chunkMH4VFSDL_js.rebuildTableStructureInRawXml(selectedElement, newTableData);
|
|
6901
6908
|
if (newRawXml) {
|
|
6902
6909
|
updates.rawXml = newRawXml;
|
|
6903
6910
|
}
|
|
@@ -6910,12 +6917,12 @@ function createTableStructHandlers(input) {
|
|
|
6910
6917
|
}
|
|
6911
6918
|
const td = selectedElement.tableData;
|
|
6912
6919
|
const colIdx = ts?.columnIndex ?? 0;
|
|
6913
|
-
const newTableData =
|
|
6920
|
+
const newTableData = chunkMH4VFSDL_js.deleteTableColumn(td, colIdx);
|
|
6914
6921
|
if (newTableData === td) {
|
|
6915
6922
|
return;
|
|
6916
6923
|
}
|
|
6917
6924
|
const updates = { tableData: newTableData };
|
|
6918
|
-
const newRawXml =
|
|
6925
|
+
const newRawXml = chunkMH4VFSDL_js.rebuildTableStructureInRawXml(selectedElement, newTableData);
|
|
6919
6926
|
if (newRawXml) {
|
|
6920
6927
|
updates.rawXml = newRawXml;
|
|
6921
6928
|
}
|
|
@@ -6951,8 +6958,8 @@ async function renderToCanvas(element, options = {}) {
|
|
|
6951
6958
|
return html2canvasPro(element, {
|
|
6952
6959
|
...options,
|
|
6953
6960
|
onclone: async (doc, clonedEl) => {
|
|
6954
|
-
await
|
|
6955
|
-
|
|
6961
|
+
await chunkMH4VFSDL_js.normalizeColorsForCapture(doc, clonedEl);
|
|
6962
|
+
chunkMH4VFSDL_js.preprocessCssForCapture(clonedEl);
|
|
6956
6963
|
if (typeof userOnClone === "function") {
|
|
6957
6964
|
userOnClone(doc, clonedEl);
|
|
6958
6965
|
}
|
|
@@ -6982,7 +6989,7 @@ function useExportSaveAs(input) {
|
|
|
6982
6989
|
slideSizeEmu
|
|
6983
6990
|
} = input;
|
|
6984
6991
|
const handleSaveAsFormat = async (format) => {
|
|
6985
|
-
const downloadName =
|
|
6992
|
+
const downloadName = chunkMH4VFSDL_js.savedPresentationFileName(filePath, format);
|
|
6986
6993
|
try {
|
|
6987
6994
|
const data = await serializeSlides(format);
|
|
6988
6995
|
if (!data) {
|
|
@@ -6990,16 +6997,16 @@ function useExportSaveAs(input) {
|
|
|
6990
6997
|
}
|
|
6991
6998
|
const mimeType = format === "ppt" ? "application/vnd.ms-powerpoint" : "application/vnd.openxmlformats-officedocument.presentationml.presentation";
|
|
6992
6999
|
const blob = new Blob([data], { type: mimeType });
|
|
6993
|
-
|
|
7000
|
+
chunkMH4VFSDL_js.downloadBlob(blob, downloadName);
|
|
6994
7001
|
} catch (err) {
|
|
6995
7002
|
console.error(`[PowerPointViewer] Save as .${format} failed:`, err);
|
|
6996
7003
|
}
|
|
6997
7004
|
};
|
|
6998
7005
|
const handleExportJson = () => {
|
|
6999
7006
|
const sourceName = filePath ? filePath.replace(/\\/gu, "/").split("/").pop() : void 0;
|
|
7000
|
-
const slideSize =
|
|
7007
|
+
const slideSize = chunkMH4VFSDL_js.resolveSlideSizeSelection({ current: slideSizeEmu, canvas: canvasSize }).size;
|
|
7001
7008
|
const data = {
|
|
7002
|
-
slides:
|
|
7009
|
+
slides: chunkMH4VFSDL_js.buildSaveSlides(slides, templateElementsBySlideId),
|
|
7003
7010
|
width: canvasSize.width,
|
|
7004
7011
|
height: canvasSize.height,
|
|
7005
7012
|
widthEmu: slideSize.widthEmu,
|
|
@@ -7018,7 +7025,7 @@ function useExportSaveAs(input) {
|
|
|
7018
7025
|
handoutMaster
|
|
7019
7026
|
};
|
|
7020
7027
|
try {
|
|
7021
|
-
|
|
7028
|
+
chunkMH4VFSDL_js.exportDeckJson(data, sourceName);
|
|
7022
7029
|
} catch (err) {
|
|
7023
7030
|
console.error("[PowerPointViewer] JSON export failed:", err);
|
|
7024
7031
|
}
|
|
@@ -7045,43 +7052,71 @@ function useExportSaveAs(input) {
|
|
|
7045
7052
|
};
|
|
7046
7053
|
}
|
|
7047
7054
|
|
|
7048
|
-
// src/viewer/utils/
|
|
7049
|
-
function
|
|
7050
|
-
|
|
7051
|
-
|
|
7052
|
-
|
|
7053
|
-
return null;
|
|
7055
|
+
// src/viewer/utils/export-helpers.ts
|
|
7056
|
+
function ignoreExportOverlayElements(el) {
|
|
7057
|
+
const htmlEl = el;
|
|
7058
|
+
if (htmlEl.dataset?.exportIgnore === "true") {
|
|
7059
|
+
return true;
|
|
7054
7060
|
}
|
|
7061
|
+
return Boolean(
|
|
7062
|
+
htmlEl.classList?.contains("pointer-events-none") && (htmlEl.classList.contains("z-50") || htmlEl.classList.contains("z-[60]"))
|
|
7063
|
+
);
|
|
7055
7064
|
}
|
|
7056
|
-
function
|
|
7057
|
-
|
|
7058
|
-
|
|
7059
|
-
|
|
7060
|
-
|
|
7061
|
-
}
|
|
7065
|
+
function measureNaturalSize(element) {
|
|
7066
|
+
const rect = element.getBoundingClientRect();
|
|
7067
|
+
return {
|
|
7068
|
+
width: rect.width || element.offsetWidth,
|
|
7069
|
+
height: rect.height || element.offsetHeight
|
|
7070
|
+
};
|
|
7062
7071
|
}
|
|
7063
|
-
|
|
7064
|
-
|
|
7065
|
-
async function renderElementToCanvas(element, scale = 2, backgroundColor) {
|
|
7066
|
-
const canvas = await renderToCanvas(element, {
|
|
7072
|
+
function buildRasterOptions(element, scale, backgroundColor, mode) {
|
|
7073
|
+
return {
|
|
7067
7074
|
scale,
|
|
7068
|
-
|
|
7069
|
-
|
|
7070
|
-
|
|
7071
|
-
|
|
7072
|
-
|
|
7073
|
-
|
|
7074
|
-
|
|
7075
|
-
|
|
7076
|
-
|
|
7077
|
-
|
|
7078
|
-
|
|
7079
|
-
|
|
7080
|
-
|
|
7081
|
-
|
|
7082
|
-
|
|
7083
|
-
|
|
7084
|
-
|
|
7075
|
+
backgroundColor,
|
|
7076
|
+
mode,
|
|
7077
|
+
html2canvasFallback: (sourceRect, outputSize) => renderToCanvas(element, {
|
|
7078
|
+
scale: outputSize.width / (sourceRect.width || 1),
|
|
7079
|
+
x: sourceRect.x,
|
|
7080
|
+
y: sourceRect.y,
|
|
7081
|
+
width: sourceRect.width,
|
|
7082
|
+
height: sourceRect.height,
|
|
7083
|
+
useCORS: true,
|
|
7084
|
+
allowTaint: true,
|
|
7085
|
+
backgroundColor: backgroundColor ?? null,
|
|
7086
|
+
logging: false,
|
|
7087
|
+
ignoreElements: ignoreExportOverlayElements
|
|
7088
|
+
})
|
|
7089
|
+
};
|
|
7090
|
+
}
|
|
7091
|
+
async function renderElementToRaster(element, scale = 2, backgroundColor, mode = "auto") {
|
|
7092
|
+
const { width, height } = measureNaturalSize(element);
|
|
7093
|
+
return chunkMH4VFSDL_js.rasterizeElement(
|
|
7094
|
+
element,
|
|
7095
|
+
width,
|
|
7096
|
+
height,
|
|
7097
|
+
element.ownerDocument,
|
|
7098
|
+
buildRasterOptions(element, scale, backgroundColor, mode)
|
|
7099
|
+
);
|
|
7100
|
+
}
|
|
7101
|
+
async function renderElementToTiles(element, scale = 2, backgroundColor, mode = "auto") {
|
|
7102
|
+
const { width, height } = measureNaturalSize(element);
|
|
7103
|
+
return chunkMH4VFSDL_js.rasterizeElementTiles(
|
|
7104
|
+
element,
|
|
7105
|
+
width,
|
|
7106
|
+
height,
|
|
7107
|
+
element.ownerDocument,
|
|
7108
|
+
buildRasterOptions(element, scale, backgroundColor, mode)
|
|
7109
|
+
);
|
|
7110
|
+
}
|
|
7111
|
+
async function renderElementToTiledCanvas(element, scale = 2, backgroundColor, mode = "auto") {
|
|
7112
|
+
const { width, height } = measureNaturalSize(element);
|
|
7113
|
+
return chunkMH4VFSDL_js.rasterizeElementTiledToCanvas(
|
|
7114
|
+
element,
|
|
7115
|
+
width,
|
|
7116
|
+
height,
|
|
7117
|
+
element.ownerDocument,
|
|
7118
|
+
buildRasterOptions(element, scale, backgroundColor, mode)
|
|
7119
|
+
);
|
|
7085
7120
|
}
|
|
7086
7121
|
function waitForRender(ms = 100) {
|
|
7087
7122
|
return new Promise((resolve) => {
|
|
@@ -7096,32 +7131,21 @@ function waitForRender(ms = 100) {
|
|
|
7096
7131
|
// src/viewer/utils/export-slides.ts
|
|
7097
7132
|
async function exportSlideToPngBlob(slideElement, options = {}) {
|
|
7098
7133
|
const { scale = 2, backgroundColor } = options;
|
|
7099
|
-
const
|
|
7100
|
-
return
|
|
7101
|
-
canvas.toBlob((blob) => {
|
|
7102
|
-
if (blob) {
|
|
7103
|
-
resolve(blob);
|
|
7104
|
-
} else {
|
|
7105
|
-
reject(new Error("Canvas toBlob returned null"));
|
|
7106
|
-
}
|
|
7107
|
-
}, "image/png");
|
|
7108
|
-
});
|
|
7134
|
+
const result = await renderElementToRaster(slideElement, scale, backgroundColor);
|
|
7135
|
+
return chunkMH4VFSDL_js.rasterResultToPngBlob(result);
|
|
7109
7136
|
}
|
|
7110
7137
|
async function exportSlideAsPng(slideElement, slideIndex, options = {}) {
|
|
7111
7138
|
const blob = await exportSlideToPngBlob(slideElement, options);
|
|
7112
|
-
|
|
7139
|
+
chunkMH4VFSDL_js.downloadBlob(blob, `slide-${slideIndex + 1}.png`);
|
|
7113
7140
|
}
|
|
7114
7141
|
async function copySlideToClipboard(slideElement, options = {}) {
|
|
7115
7142
|
const blob = await exportSlideToPngBlob(slideElement, options);
|
|
7116
7143
|
await navigator.clipboard.write([new ClipboardItem({ "image/png": blob })]);
|
|
7117
7144
|
}
|
|
7118
|
-
async function
|
|
7119
|
-
const { scale = 2, onProgress
|
|
7120
|
-
const
|
|
7145
|
+
async function captureAllSlidesAsPngDataUrls(slideStageRef, totalSlides, setActiveSlide, currentSlideIndex, options = {}) {
|
|
7146
|
+
const { scale = 2, onProgress } = options;
|
|
7147
|
+
const dataUrls = [];
|
|
7121
7148
|
for (let i = 0; i < totalSlides; i++) {
|
|
7122
|
-
if (signal?.aborted) {
|
|
7123
|
-
throw new DOMException("Export cancelled", "AbortError");
|
|
7124
|
-
}
|
|
7125
7149
|
onProgress?.(i, totalSlides);
|
|
7126
7150
|
setActiveSlide(i);
|
|
7127
7151
|
await waitForRender(150);
|
|
@@ -7130,21 +7154,34 @@ async function exportAllSlidesAsPdf(slideStageRef, totalSlides, setActiveSlide,
|
|
|
7130
7154
|
console.warn(`[export] Could not find slide stage element for slide ${i}`);
|
|
7131
7155
|
continue;
|
|
7132
7156
|
}
|
|
7133
|
-
const canvas = await
|
|
7134
|
-
|
|
7157
|
+
const { canvas } = await renderElementToTiledCanvas(stageEl, scale);
|
|
7158
|
+
dataUrls.push(canvas.toDataURL("image/png"));
|
|
7135
7159
|
}
|
|
7136
7160
|
onProgress?.(totalSlides, totalSlides);
|
|
7137
7161
|
setActiveSlide(currentSlideIndex);
|
|
7138
|
-
|
|
7139
|
-
throw new Error(chunk3AJ54EAB_js.translationsEn["pptx.export.errorNoSlidesPdf"]);
|
|
7140
|
-
}
|
|
7141
|
-
const pdfBlobUrl = chunkO27KNZLJ_js.buildPdfFromImageData(images);
|
|
7142
|
-
chunk3WK4AE52_js.downloadDataUrl(pdfBlobUrl, filename);
|
|
7162
|
+
return dataUrls;
|
|
7143
7163
|
}
|
|
7144
|
-
|
|
7145
|
-
|
|
7146
|
-
|
|
7164
|
+
|
|
7165
|
+
// src/viewer/utils/export-pdf.ts
|
|
7166
|
+
function tilesToPdfPage(tilesResult) {
|
|
7167
|
+
return tilesResult.tiles.map((tile) => ({
|
|
7168
|
+
image: chunkMH4VFSDL_js.canvasToJpegData(tile.canvas),
|
|
7169
|
+
placement: chunkMH4VFSDL_js.placeTileOnPage(
|
|
7170
|
+
tile,
|
|
7171
|
+
tilesResult.fullWidth,
|
|
7172
|
+
tilesResult.fullHeight,
|
|
7173
|
+
chunkMH4VFSDL_js.PDF_SLIDES_PAGE_WIDTH_PT,
|
|
7174
|
+
chunkMH4VFSDL_js.PDF_SLIDES_PAGE_HEIGHT_PT
|
|
7175
|
+
)
|
|
7176
|
+
}));
|
|
7177
|
+
}
|
|
7178
|
+
async function exportAllSlidesAsPdf(slideStageRef, totalSlides, setActiveSlide, currentSlideIndex, filename = "presentation.pdf", options = {}) {
|
|
7179
|
+
const { scale = 2, onProgress, signal } = options;
|
|
7180
|
+
const pages = [];
|
|
7147
7181
|
for (let i = 0; i < totalSlides; i++) {
|
|
7182
|
+
if (signal?.aborted) {
|
|
7183
|
+
throw new DOMException("Export cancelled", "AbortError");
|
|
7184
|
+
}
|
|
7148
7185
|
onProgress?.(i, totalSlides);
|
|
7149
7186
|
setActiveSlide(i);
|
|
7150
7187
|
await waitForRender(150);
|
|
@@ -7153,12 +7190,16 @@ async function captureAllSlidesAsPngDataUrls(slideStageRef, totalSlides, setActi
|
|
|
7153
7190
|
console.warn(`[export] Could not find slide stage element for slide ${i}`);
|
|
7154
7191
|
continue;
|
|
7155
7192
|
}
|
|
7156
|
-
const
|
|
7157
|
-
|
|
7193
|
+
const tilesResult = await renderElementToTiles(stageEl, scale);
|
|
7194
|
+
pages.push(tilesToPdfPage(tilesResult));
|
|
7158
7195
|
}
|
|
7159
7196
|
onProgress?.(totalSlides, totalSlides);
|
|
7160
7197
|
setActiveSlide(currentSlideIndex);
|
|
7161
|
-
|
|
7198
|
+
if (pages.length === 0) {
|
|
7199
|
+
throw new Error(chunk3AJ54EAB_js.translationsEn["pptx.export.errorNoSlidesPdf"]);
|
|
7200
|
+
}
|
|
7201
|
+
const pdfBlobUrl = chunkH4LMXJ2Z_js.buildPdfFromTiledImageData(pages);
|
|
7202
|
+
chunkMH4VFSDL_js.downloadDataUrl(pdfBlobUrl, filename);
|
|
7162
7203
|
}
|
|
7163
7204
|
async function exportAllSlidesAsNotesPdf(slideStageRef, totalSlides, setActiveSlide, currentSlideIndex, slideNotes, filename = "presentation-notes.pdf", options = {}) {
|
|
7164
7205
|
const { scale = 2, onProgress, signal } = options;
|
|
@@ -7175,7 +7216,7 @@ async function exportAllSlidesAsNotesPdf(slideStageRef, totalSlides, setActiveSl
|
|
|
7175
7216
|
console.warn(`[export] Could not find slide stage element for slide ${i}`);
|
|
7176
7217
|
continue;
|
|
7177
7218
|
}
|
|
7178
|
-
const canvas = await
|
|
7219
|
+
const { canvas } = await renderElementToTiledCanvas(stageEl, scale);
|
|
7179
7220
|
pages.push({
|
|
7180
7221
|
canvas,
|
|
7181
7222
|
notes: slideNotes[i],
|
|
@@ -7187,8 +7228,8 @@ async function exportAllSlidesAsNotesPdf(slideStageRef, totalSlides, setActiveSl
|
|
|
7187
7228
|
if (pages.length === 0) {
|
|
7188
7229
|
throw new Error(chunk3AJ54EAB_js.translationsEn["pptx.export.errorNoSlidesNotesPdf"]);
|
|
7189
7230
|
}
|
|
7190
|
-
const pdfDataUrl =
|
|
7191
|
-
|
|
7231
|
+
const pdfDataUrl = chunkH4LMXJ2Z_js.buildNotesPdf(pages);
|
|
7232
|
+
chunkMH4VFSDL_js.downloadDataUrl(pdfDataUrl, filename);
|
|
7192
7233
|
}
|
|
7193
7234
|
|
|
7194
7235
|
// src/viewer/utils/export-video.ts
|
|
@@ -7214,7 +7255,7 @@ async function exportAllSlidesAsVideo(slideStageRef, totalSlides, setActiveSlide
|
|
|
7214
7255
|
console.warn(`[export] Could not find slide stage element for slide ${i}`);
|
|
7215
7256
|
continue;
|
|
7216
7257
|
}
|
|
7217
|
-
const canvas = await
|
|
7258
|
+
const { canvas } = await renderElementToTiledCanvas(stageEl, scale);
|
|
7218
7259
|
slideCanvases.push(canvas);
|
|
7219
7260
|
}
|
|
7220
7261
|
setActiveSlide(currentSlideIndex);
|
|
@@ -7232,7 +7273,7 @@ async function exportAllSlidesAsVideo(slideStageRef, totalSlides, setActiveSlide
|
|
|
7232
7273
|
const fps = 30;
|
|
7233
7274
|
const stream = recordingCanvas.captureStream(fps);
|
|
7234
7275
|
const recorder = new MediaRecorder(stream, {
|
|
7235
|
-
mimeType:
|
|
7276
|
+
mimeType: chunkMH4VFSDL_js.pickSupportedMimeType([...chunkMH4VFSDL_js.WEBM_MIME_CANDIDATES]),
|
|
7236
7277
|
videoBitsPerSecond: 5e6
|
|
7237
7278
|
});
|
|
7238
7279
|
const chunks = [];
|
|
@@ -7255,8 +7296,8 @@ async function exportAllSlidesAsVideo(slideStageRef, totalSlides, setActiveSlide
|
|
|
7255
7296
|
const duration = slideTimingsMs?.[i] ?? slideDurationMs;
|
|
7256
7297
|
ctx.clearRect(0, 0, recordingCanvas.width, recordingCanvas.height);
|
|
7257
7298
|
ctx.drawImage(slideCanvases[i], 0, 0);
|
|
7258
|
-
const frameInterval =
|
|
7259
|
-
const framesNeeded =
|
|
7299
|
+
const frameInterval = chunkMH4VFSDL_js.fpsToFrameIntervalMs(fps);
|
|
7300
|
+
const framesNeeded = chunkMH4VFSDL_js.segmentFrameCount(duration, fps);
|
|
7260
7301
|
for (let f = 0; f < framesNeeded; f++) {
|
|
7261
7302
|
if (signal?.aborted) {
|
|
7262
7303
|
recorder.stop();
|
|
@@ -7275,8 +7316,34 @@ async function exportAllSlidesAsVideo(slideStageRef, totalSlides, setActiveSlide
|
|
|
7275
7316
|
}
|
|
7276
7317
|
|
|
7277
7318
|
// src/viewer/utils/export-gif.ts
|
|
7319
|
+
function frameFromCanvas(canvas, maxSide) {
|
|
7320
|
+
const { width, height } = chunkMH4VFSDL_js.clampGifDimensions(canvas.width, canvas.height, maxSide);
|
|
7321
|
+
let source = canvas;
|
|
7322
|
+
if (width !== canvas.width || height !== canvas.height) {
|
|
7323
|
+
const scaled = canvas.ownerDocument.createElement("canvas");
|
|
7324
|
+
scaled.width = width;
|
|
7325
|
+
scaled.height = height;
|
|
7326
|
+
const scaledCtx = scaled.getContext("2d");
|
|
7327
|
+
if (!scaledCtx) {
|
|
7328
|
+
return void 0;
|
|
7329
|
+
}
|
|
7330
|
+
scaledCtx.drawImage(canvas, 0, 0, width, height);
|
|
7331
|
+
source = scaled;
|
|
7332
|
+
}
|
|
7333
|
+
const ctx = source.getContext("2d");
|
|
7334
|
+
if (!ctx) {
|
|
7335
|
+
return void 0;
|
|
7336
|
+
}
|
|
7337
|
+
return { imageData: ctx.getImageData(0, 0, width, height), width, height };
|
|
7338
|
+
}
|
|
7278
7339
|
async function exportAllSlidesAsGif(slideStageRef, totalSlides, setActiveSlide, currentSlideIndex, options = {}) {
|
|
7279
|
-
const {
|
|
7340
|
+
const {
|
|
7341
|
+
scale = 0.5,
|
|
7342
|
+
slideDurationMs = 2e3,
|
|
7343
|
+
maxSide = chunkMH4VFSDL_js.GIF_POST_CAPTURE_MAX_SIDE,
|
|
7344
|
+
onProgress,
|
|
7345
|
+
signal
|
|
7346
|
+
} = options;
|
|
7280
7347
|
const frames = [];
|
|
7281
7348
|
for (let i = 0; i < totalSlides; i++) {
|
|
7282
7349
|
if (signal?.aborted) {
|
|
@@ -7289,23 +7356,18 @@ async function exportAllSlidesAsGif(slideStageRef, totalSlides, setActiveSlide,
|
|
|
7289
7356
|
if (!stageEl) {
|
|
7290
7357
|
continue;
|
|
7291
7358
|
}
|
|
7292
|
-
const canvas = await
|
|
7293
|
-
const
|
|
7294
|
-
if (!
|
|
7359
|
+
const { canvas } = await renderElementToTiledCanvas(stageEl, scale);
|
|
7360
|
+
const frame = frameFromCanvas(canvas, maxSide);
|
|
7361
|
+
if (!frame) {
|
|
7295
7362
|
continue;
|
|
7296
7363
|
}
|
|
7297
|
-
|
|
7298
|
-
frames.push({
|
|
7299
|
-
imageData,
|
|
7300
|
-
width: canvas.width,
|
|
7301
|
-
height: canvas.height
|
|
7302
|
-
});
|
|
7364
|
+
frames.push(frame);
|
|
7303
7365
|
}
|
|
7304
7366
|
setActiveSlide(currentSlideIndex);
|
|
7305
7367
|
if (frames.length === 0) {
|
|
7306
7368
|
throw new Error(chunk3AJ54EAB_js.translationsEn["pptx.export.errorNoSlidesGif"]);
|
|
7307
7369
|
}
|
|
7308
|
-
const gifBytes =
|
|
7370
|
+
const gifBytes = chunkMH4VFSDL_js.encodeGif(frames, Math.round(slideDurationMs / 10));
|
|
7309
7371
|
onProgress?.(totalSlides, totalSlides);
|
|
7310
7372
|
const buf = new ArrayBuffer(gifBytes.length);
|
|
7311
7373
|
new Uint8Array(buf).set(gifBytes);
|
|
@@ -7359,7 +7421,7 @@ function exportAllSlidesToSvg(data, options = {}) {
|
|
|
7359
7421
|
continue;
|
|
7360
7422
|
}
|
|
7361
7423
|
onProgress?.(processedCount, data.slides.length);
|
|
7362
|
-
let svg =
|
|
7424
|
+
let svg = chunkMH4VFSDL_js.SvgExporter.exportSlide(slide, data.width, data.height, svgOptions);
|
|
7363
7425
|
if (embedFonts && fontFaces?.length) {
|
|
7364
7426
|
svg = injectFontFaces(svg, fontFaces);
|
|
7365
7427
|
}
|
|
@@ -7370,6 +7432,149 @@ function exportAllSlidesToSvg(data, options = {}) {
|
|
|
7370
7432
|
return results;
|
|
7371
7433
|
}
|
|
7372
7434
|
|
|
7435
|
+
// src/viewer/utils/dom-helpers.ts
|
|
7436
|
+
function safePrompt(message, defaultValue) {
|
|
7437
|
+
try {
|
|
7438
|
+
return window.prompt(message, defaultValue);
|
|
7439
|
+
} catch {
|
|
7440
|
+
return null;
|
|
7441
|
+
}
|
|
7442
|
+
}
|
|
7443
|
+
function safeConfirm(message) {
|
|
7444
|
+
try {
|
|
7445
|
+
return window.confirm(message);
|
|
7446
|
+
} catch {
|
|
7447
|
+
return false;
|
|
7448
|
+
}
|
|
7449
|
+
}
|
|
7450
|
+
|
|
7451
|
+
// src/viewer/hooks/useExportMediaHandlers.ts
|
|
7452
|
+
function useExportMediaHandlers(input) {
|
|
7453
|
+
const {
|
|
7454
|
+
slides,
|
|
7455
|
+
activeSlideIndex,
|
|
7456
|
+
canvasStageRef,
|
|
7457
|
+
setActiveSlideIndex,
|
|
7458
|
+
imageResolutionScale = 1,
|
|
7459
|
+
exportAbortRef,
|
|
7460
|
+
setExportModalOpen,
|
|
7461
|
+
setExportModalTitle,
|
|
7462
|
+
setExportProgress,
|
|
7463
|
+
setExportStatusMessage
|
|
7464
|
+
} = input;
|
|
7465
|
+
const handleExportVideo = react.useCallback(async () => {
|
|
7466
|
+
if (!canvasStageRef.current) {
|
|
7467
|
+
return;
|
|
7468
|
+
}
|
|
7469
|
+
const abortCtrl = new AbortController();
|
|
7470
|
+
exportAbortRef.current = abortCtrl;
|
|
7471
|
+
setExportModalTitle("Export as Video");
|
|
7472
|
+
setExportStatusMessage("Capturing slides...");
|
|
7473
|
+
setExportProgress(0);
|
|
7474
|
+
setExportModalOpen(true);
|
|
7475
|
+
try {
|
|
7476
|
+
const { scale } = chunkMH4VFSDL_js.resolveExportCaptureDecision(imageResolutionScale, "video");
|
|
7477
|
+
const blob = await exportAllSlidesAsVideo(
|
|
7478
|
+
canvasStageRef,
|
|
7479
|
+
slides.length,
|
|
7480
|
+
setActiveSlideIndex,
|
|
7481
|
+
activeSlideIndex,
|
|
7482
|
+
{
|
|
7483
|
+
scale,
|
|
7484
|
+
slideDurationMs: 3e3,
|
|
7485
|
+
onProgress: (current, total) => {
|
|
7486
|
+
setExportProgress(chunkMH4VFSDL_js.slideProgressPercent(current, total, 45));
|
|
7487
|
+
setExportStatusMessage(chunkMH4VFSDL_js.slideStatusLabel("Capturing", current, total));
|
|
7488
|
+
},
|
|
7489
|
+
onRecordProgress: (current, total) => {
|
|
7490
|
+
setExportProgress(chunkMH4VFSDL_js.recordProgressPercent(current, total));
|
|
7491
|
+
setExportStatusMessage(chunkMH4VFSDL_js.slideStatusLabel("Recording", current, total));
|
|
7492
|
+
},
|
|
7493
|
+
signal: abortCtrl.signal
|
|
7494
|
+
}
|
|
7495
|
+
);
|
|
7496
|
+
setExportProgress(chunkMH4VFSDL_js.EXPORT_ASSEMBLING_PERCENT);
|
|
7497
|
+
setExportStatusMessage("Saving file...");
|
|
7498
|
+
chunkMH4VFSDL_js.downloadBlob(blob, "presentation.webm");
|
|
7499
|
+
setExportProgress(chunkMH4VFSDL_js.EXPORT_DONE_PERCENT);
|
|
7500
|
+
} catch (err) {
|
|
7501
|
+
if (!chunkMH4VFSDL_js.isExportAbortError(err)) {
|
|
7502
|
+
console.error("[PowerPointViewer] Video export failed:", err);
|
|
7503
|
+
}
|
|
7504
|
+
} finally {
|
|
7505
|
+
exportAbortRef.current = null;
|
|
7506
|
+
setExportModalOpen(false);
|
|
7507
|
+
}
|
|
7508
|
+
}, [
|
|
7509
|
+
canvasStageRef,
|
|
7510
|
+
slides.length,
|
|
7511
|
+
setActiveSlideIndex,
|
|
7512
|
+
activeSlideIndex,
|
|
7513
|
+
imageResolutionScale,
|
|
7514
|
+
exportAbortRef,
|
|
7515
|
+
setExportModalOpen,
|
|
7516
|
+
setExportModalTitle,
|
|
7517
|
+
setExportProgress,
|
|
7518
|
+
setExportStatusMessage
|
|
7519
|
+
]);
|
|
7520
|
+
const handleExportGif = react.useCallback(async () => {
|
|
7521
|
+
if (!canvasStageRef.current) {
|
|
7522
|
+
return;
|
|
7523
|
+
}
|
|
7524
|
+
const abortCtrl = new AbortController();
|
|
7525
|
+
exportAbortRef.current = abortCtrl;
|
|
7526
|
+
setExportModalTitle("Export as GIF");
|
|
7527
|
+
setExportStatusMessage("Capturing slides...");
|
|
7528
|
+
setExportProgress(0);
|
|
7529
|
+
setExportModalOpen(true);
|
|
7530
|
+
try {
|
|
7531
|
+
const { scale, postCaptureMaxSide } = chunkMH4VFSDL_js.resolveExportCaptureDecision(
|
|
7532
|
+
imageResolutionScale,
|
|
7533
|
+
"gif"
|
|
7534
|
+
);
|
|
7535
|
+
const blob = await exportAllSlidesAsGif(
|
|
7536
|
+
canvasStageRef,
|
|
7537
|
+
slides.length,
|
|
7538
|
+
setActiveSlideIndex,
|
|
7539
|
+
activeSlideIndex,
|
|
7540
|
+
{
|
|
7541
|
+
scale,
|
|
7542
|
+
maxSide: postCaptureMaxSide,
|
|
7543
|
+
slideDurationMs: 2e3,
|
|
7544
|
+
onProgress: (current, total) => {
|
|
7545
|
+
setExportProgress(chunkMH4VFSDL_js.slideProgressPercent(current, total));
|
|
7546
|
+
setExportStatusMessage(chunkMH4VFSDL_js.slideStatusLabel("Encoding", current, total));
|
|
7547
|
+
},
|
|
7548
|
+
signal: abortCtrl.signal
|
|
7549
|
+
}
|
|
7550
|
+
);
|
|
7551
|
+
setExportProgress(chunkMH4VFSDL_js.EXPORT_ASSEMBLING_PERCENT);
|
|
7552
|
+
setExportStatusMessage("Saving file...");
|
|
7553
|
+
chunkMH4VFSDL_js.downloadBlob(blob, "presentation.gif");
|
|
7554
|
+
setExportProgress(chunkMH4VFSDL_js.EXPORT_DONE_PERCENT);
|
|
7555
|
+
} catch (err) {
|
|
7556
|
+
if (!chunkMH4VFSDL_js.isExportAbortError(err)) {
|
|
7557
|
+
console.error("[PowerPointViewer] GIF export failed:", err);
|
|
7558
|
+
}
|
|
7559
|
+
} finally {
|
|
7560
|
+
exportAbortRef.current = null;
|
|
7561
|
+
setExportModalOpen(false);
|
|
7562
|
+
}
|
|
7563
|
+
}, [
|
|
7564
|
+
canvasStageRef,
|
|
7565
|
+
slides.length,
|
|
7566
|
+
setActiveSlideIndex,
|
|
7567
|
+
activeSlideIndex,
|
|
7568
|
+
imageResolutionScale,
|
|
7569
|
+
exportAbortRef,
|
|
7570
|
+
setExportModalOpen,
|
|
7571
|
+
setExportModalTitle,
|
|
7572
|
+
setExportProgress,
|
|
7573
|
+
setExportStatusMessage
|
|
7574
|
+
]);
|
|
7575
|
+
return { handleExportVideo, handleExportGif };
|
|
7576
|
+
}
|
|
7577
|
+
|
|
7373
7578
|
// src/viewer/hooks/useExportHandlers.ts
|
|
7374
7579
|
function useExportHandlers(input) {
|
|
7375
7580
|
const {
|
|
@@ -7394,13 +7599,26 @@ function useExportHandlers(input) {
|
|
|
7394
7599
|
theme,
|
|
7395
7600
|
canvasSize,
|
|
7396
7601
|
slideSizeEmu,
|
|
7397
|
-
imageExportScale
|
|
7602
|
+
imageExportScale,
|
|
7603
|
+
imageResolutionScale
|
|
7398
7604
|
} = input;
|
|
7399
7605
|
const [exportModalOpen, setExportModalOpen] = react.useState(false);
|
|
7400
7606
|
const [exportModalTitle, setExportModalTitle] = react.useState("");
|
|
7401
7607
|
const [exportProgress, setExportProgress] = react.useState(0);
|
|
7402
7608
|
const [exportStatusMessage, setExportStatusMessage] = react.useState("");
|
|
7403
7609
|
const exportAbortRef = react.useRef(null);
|
|
7610
|
+
const { handleExportVideo, handleExportGif } = useExportMediaHandlers({
|
|
7611
|
+
slides,
|
|
7612
|
+
activeSlideIndex,
|
|
7613
|
+
canvasStageRef,
|
|
7614
|
+
setActiveSlideIndex,
|
|
7615
|
+
imageResolutionScale,
|
|
7616
|
+
exportAbortRef,
|
|
7617
|
+
setExportModalOpen,
|
|
7618
|
+
setExportModalTitle,
|
|
7619
|
+
setExportProgress,
|
|
7620
|
+
setExportStatusMessage
|
|
7621
|
+
});
|
|
7404
7622
|
const {
|
|
7405
7623
|
handleExportJson,
|
|
7406
7624
|
handleSaveAsFormat,
|
|
@@ -7461,21 +7679,21 @@ function useExportHandlers(input) {
|
|
|
7461
7679
|
{
|
|
7462
7680
|
scale: imageExportScale,
|
|
7463
7681
|
onProgress: (current, total) => {
|
|
7464
|
-
setExportProgress(
|
|
7465
|
-
setExportStatusMessage(
|
|
7682
|
+
setExportProgress(chunkMH4VFSDL_js.slideProgressPercent(current, total));
|
|
7683
|
+
setExportStatusMessage(chunkMH4VFSDL_js.slideStatusLabel("Rendering", current, total));
|
|
7466
7684
|
},
|
|
7467
7685
|
signal: abortCtrl.signal
|
|
7468
7686
|
}
|
|
7469
7687
|
);
|
|
7470
|
-
setExportProgress(
|
|
7688
|
+
setExportProgress(chunkMH4VFSDL_js.EXPORT_ASSEMBLING_PERCENT);
|
|
7471
7689
|
setExportStatusMessage("Building PDF...");
|
|
7472
7690
|
await new Promise((r) => {
|
|
7473
7691
|
setTimeout(r, 100);
|
|
7474
7692
|
});
|
|
7475
|
-
setExportProgress(
|
|
7693
|
+
setExportProgress(chunkMH4VFSDL_js.EXPORT_DONE_PERCENT);
|
|
7476
7694
|
setExportStatusMessage("Done!");
|
|
7477
7695
|
} catch (err) {
|
|
7478
|
-
if (!
|
|
7696
|
+
if (!chunkMH4VFSDL_js.isExportAbortError(err)) {
|
|
7479
7697
|
console.error("[PowerPointViewer] PDF export failed:", err);
|
|
7480
7698
|
}
|
|
7481
7699
|
} finally {
|
|
@@ -7505,21 +7723,21 @@ function useExportHandlers(input) {
|
|
|
7505
7723
|
{
|
|
7506
7724
|
scale: imageExportScale,
|
|
7507
7725
|
onProgress: (current, total) => {
|
|
7508
|
-
setExportProgress(
|
|
7509
|
-
setExportStatusMessage(
|
|
7726
|
+
setExportProgress(chunkMH4VFSDL_js.slideProgressPercent(current, total));
|
|
7727
|
+
setExportStatusMessage(chunkMH4VFSDL_js.slideStatusLabel("Rendering", current, total));
|
|
7510
7728
|
},
|
|
7511
7729
|
signal: abortCtrl.signal
|
|
7512
7730
|
}
|
|
7513
7731
|
);
|
|
7514
|
-
setExportProgress(
|
|
7732
|
+
setExportProgress(chunkMH4VFSDL_js.EXPORT_ASSEMBLING_PERCENT);
|
|
7515
7733
|
setExportStatusMessage("Building PDF...");
|
|
7516
7734
|
await new Promise((r) => {
|
|
7517
7735
|
setTimeout(r, 100);
|
|
7518
7736
|
});
|
|
7519
|
-
setExportProgress(
|
|
7737
|
+
setExportProgress(chunkMH4VFSDL_js.EXPORT_DONE_PERCENT);
|
|
7520
7738
|
setExportStatusMessage("Done!");
|
|
7521
7739
|
} catch (err) {
|
|
7522
|
-
if (!
|
|
7740
|
+
if (!chunkMH4VFSDL_js.isExportAbortError(err)) {
|
|
7523
7741
|
console.error("[PowerPointViewer] Notes PDF export failed:", err);
|
|
7524
7742
|
}
|
|
7525
7743
|
} finally {
|
|
@@ -7541,88 +7759,6 @@ function useExportHandlers(input) {
|
|
|
7541
7759
|
console.error("[PowerPointViewer] Copy slide as image failed:", err);
|
|
7542
7760
|
}
|
|
7543
7761
|
}, [canvasStageRef, activeSlide?.backgroundColor, imageExportScale]);
|
|
7544
|
-
const handleExportVideo = react.useCallback(async () => {
|
|
7545
|
-
if (!canvasStageRef.current) {
|
|
7546
|
-
return;
|
|
7547
|
-
}
|
|
7548
|
-
const abortCtrl = new AbortController();
|
|
7549
|
-
exportAbortRef.current = abortCtrl;
|
|
7550
|
-
setExportModalTitle("Export as Video");
|
|
7551
|
-
setExportStatusMessage("Capturing slides...");
|
|
7552
|
-
setExportProgress(0);
|
|
7553
|
-
setExportModalOpen(true);
|
|
7554
|
-
try {
|
|
7555
|
-
const blob = await exportAllSlidesAsVideo(
|
|
7556
|
-
canvasStageRef,
|
|
7557
|
-
slides.length,
|
|
7558
|
-
setActiveSlideIndex,
|
|
7559
|
-
activeSlideIndex,
|
|
7560
|
-
{
|
|
7561
|
-
scale: 1,
|
|
7562
|
-
slideDurationMs: 3e3,
|
|
7563
|
-
onProgress: (current, total) => {
|
|
7564
|
-
setExportProgress(chunk3WK4AE52_js.slideProgressPercent(current, total, 45));
|
|
7565
|
-
setExportStatusMessage(chunk3WK4AE52_js.slideStatusLabel("Capturing", current, total));
|
|
7566
|
-
},
|
|
7567
|
-
onRecordProgress: (current, total) => {
|
|
7568
|
-
setExportProgress(chunk3WK4AE52_js.recordProgressPercent(current, total));
|
|
7569
|
-
setExportStatusMessage(chunk3WK4AE52_js.slideStatusLabel("Recording", current, total));
|
|
7570
|
-
},
|
|
7571
|
-
signal: abortCtrl.signal
|
|
7572
|
-
}
|
|
7573
|
-
);
|
|
7574
|
-
setExportProgress(chunk3WK4AE52_js.EXPORT_ASSEMBLING_PERCENT);
|
|
7575
|
-
setExportStatusMessage("Saving file...");
|
|
7576
|
-
chunk3WK4AE52_js.downloadBlob(blob, "presentation.webm");
|
|
7577
|
-
setExportProgress(chunk3WK4AE52_js.EXPORT_DONE_PERCENT);
|
|
7578
|
-
} catch (err) {
|
|
7579
|
-
if (!chunk3WK4AE52_js.isExportAbortError(err)) {
|
|
7580
|
-
console.error("[PowerPointViewer] Video export failed:", err);
|
|
7581
|
-
}
|
|
7582
|
-
} finally {
|
|
7583
|
-
exportAbortRef.current = null;
|
|
7584
|
-
setExportModalOpen(false);
|
|
7585
|
-
}
|
|
7586
|
-
}, [canvasStageRef, slides.length, setActiveSlideIndex, activeSlideIndex]);
|
|
7587
|
-
const handleExportGif = react.useCallback(async () => {
|
|
7588
|
-
if (!canvasStageRef.current) {
|
|
7589
|
-
return;
|
|
7590
|
-
}
|
|
7591
|
-
const abortCtrl = new AbortController();
|
|
7592
|
-
exportAbortRef.current = abortCtrl;
|
|
7593
|
-
setExportModalTitle("Export as GIF");
|
|
7594
|
-
setExportStatusMessage("Capturing slides...");
|
|
7595
|
-
setExportProgress(0);
|
|
7596
|
-
setExportModalOpen(true);
|
|
7597
|
-
try {
|
|
7598
|
-
const blob = await exportAllSlidesAsGif(
|
|
7599
|
-
canvasStageRef,
|
|
7600
|
-
slides.length,
|
|
7601
|
-
setActiveSlideIndex,
|
|
7602
|
-
activeSlideIndex,
|
|
7603
|
-
{
|
|
7604
|
-
scale: 0.5,
|
|
7605
|
-
slideDurationMs: 2e3,
|
|
7606
|
-
onProgress: (current, total) => {
|
|
7607
|
-
setExportProgress(chunk3WK4AE52_js.slideProgressPercent(current, total));
|
|
7608
|
-
setExportStatusMessage(chunk3WK4AE52_js.slideStatusLabel("Encoding", current, total));
|
|
7609
|
-
},
|
|
7610
|
-
signal: abortCtrl.signal
|
|
7611
|
-
}
|
|
7612
|
-
);
|
|
7613
|
-
setExportProgress(chunk3WK4AE52_js.EXPORT_ASSEMBLING_PERCENT);
|
|
7614
|
-
setExportStatusMessage("Saving file...");
|
|
7615
|
-
chunk3WK4AE52_js.downloadBlob(blob, "presentation.gif");
|
|
7616
|
-
setExportProgress(chunk3WK4AE52_js.EXPORT_DONE_PERCENT);
|
|
7617
|
-
} catch (err) {
|
|
7618
|
-
if (!chunk3WK4AE52_js.isExportAbortError(err)) {
|
|
7619
|
-
console.error("[PowerPointViewer] GIF export failed:", err);
|
|
7620
|
-
}
|
|
7621
|
-
} finally {
|
|
7622
|
-
exportAbortRef.current = null;
|
|
7623
|
-
setExportModalOpen(false);
|
|
7624
|
-
}
|
|
7625
|
-
}, [canvasStageRef, slides.length, setActiveSlideIndex, activeSlideIndex]);
|
|
7626
7762
|
const handleCancelExport = react.useCallback(() => {
|
|
7627
7763
|
exportAbortRef.current?.abort();
|
|
7628
7764
|
exportAbortRef.current = null;
|
|
@@ -7649,7 +7785,7 @@ function useExportHandlers(input) {
|
|
|
7649
7785
|
exportStatusMessage
|
|
7650
7786
|
};
|
|
7651
7787
|
}
|
|
7652
|
-
var ViewerOptionsContext = react.createContext(
|
|
7788
|
+
var ViewerOptionsContext = react.createContext(chunkMH4VFSDL_js.DEFAULT_VIEWER_OPTIONS);
|
|
7653
7789
|
function useViewerOptionsContext() {
|
|
7654
7790
|
return react.useContext(ViewerOptionsContext);
|
|
7655
7791
|
}
|
|
@@ -7661,13 +7797,13 @@ function usePrintHandlers(input) {
|
|
|
7661
7797
|
const { t } = reactI18next.useTranslation();
|
|
7662
7798
|
const viewerOptions = useViewerOptionsContext();
|
|
7663
7799
|
const includeHiddenSlides = viewerOptions.advanced.printHiddenSlides;
|
|
7664
|
-
const printRasterScale = (viewerOptions.advanced.printHighQuality ? 4 : 3) *
|
|
7800
|
+
const printRasterScale = (viewerOptions.advanced.printHighQuality ? 4 : 3) * chunkMH4VFSDL_js.resolveImageResolutionScale(viewerOptions);
|
|
7665
7801
|
const handlePrint = () => {
|
|
7666
7802
|
setIsPrintDialogOpen(true);
|
|
7667
7803
|
};
|
|
7668
7804
|
const handlePrintSvg = async (settings) => {
|
|
7669
7805
|
setIsPrintDialogOpen(false);
|
|
7670
|
-
const printWindow =
|
|
7806
|
+
const printWindow = chunkMH4VFSDL_js.openPendingPrintWindow(t("pptx.print.preparingToPrint"));
|
|
7671
7807
|
if (!printWindow) {
|
|
7672
7808
|
console.warn(
|
|
7673
7809
|
"[PowerPointViewer] Print window was blocked by the browser. Allow popups for this site to print."
|
|
@@ -7677,9 +7813,9 @@ function usePrintHandlers(input) {
|
|
|
7677
7813
|
if (!pptxData || settings.printWhat !== "slides") {
|
|
7678
7814
|
return runRasterPrint(printWindow, settings);
|
|
7679
7815
|
}
|
|
7680
|
-
const colorFilter =
|
|
7681
|
-
const slideIndices =
|
|
7682
|
-
|
|
7816
|
+
const colorFilter = chunkMH4VFSDL_js.computeColorFilter(settings.colorMode);
|
|
7817
|
+
const slideIndices = chunkMH4VFSDL_js.filterHiddenSlideIndices(
|
|
7818
|
+
chunkMH4VFSDL_js.computeSlideIndices(
|
|
7683
7819
|
settings.slideRange,
|
|
7684
7820
|
activeSlideIndex,
|
|
7685
7821
|
slides.length,
|
|
@@ -7697,22 +7833,22 @@ function usePrintHandlers(input) {
|
|
|
7697
7833
|
printWindow.close();
|
|
7698
7834
|
return;
|
|
7699
7835
|
}
|
|
7700
|
-
const printDoc =
|
|
7836
|
+
const printDoc = chunkMH4VFSDL_js.buildPrintDocument(svgs, pptxData.width, pptxData.height, {
|
|
7701
7837
|
title: "Slides (Vector)",
|
|
7702
7838
|
orientation: settings.orientation,
|
|
7703
7839
|
colorFilter,
|
|
7704
7840
|
scaleToFit: settings.scaleToFit
|
|
7705
7841
|
});
|
|
7706
|
-
|
|
7842
|
+
chunkMH4VFSDL_js.finishPrintWindow(printWindow, printDoc);
|
|
7707
7843
|
} catch (err) {
|
|
7708
7844
|
console.warn("[PowerPointViewer] SVG print path failed, falling back to raster:", err);
|
|
7709
7845
|
return runRasterPrint(printWindow, settings);
|
|
7710
7846
|
}
|
|
7711
7847
|
};
|
|
7712
7848
|
const runRasterPrint = async (printWindow, settings) => {
|
|
7713
|
-
const colorFilter =
|
|
7714
|
-
const slideIndices =
|
|
7715
|
-
|
|
7849
|
+
const colorFilter = chunkMH4VFSDL_js.computeColorFilter(settings.colorMode);
|
|
7850
|
+
const slideIndices = chunkMH4VFSDL_js.filterHiddenSlideIndices(
|
|
7851
|
+
chunkMH4VFSDL_js.computeSlideIndices(
|
|
7716
7852
|
settings.slideRange,
|
|
7717
7853
|
activeSlideIndex,
|
|
7718
7854
|
slides.length,
|
|
@@ -7723,11 +7859,11 @@ function usePrintHandlers(input) {
|
|
|
7723
7859
|
includeHiddenSlides
|
|
7724
7860
|
);
|
|
7725
7861
|
if (settings.printWhat === "outline") {
|
|
7726
|
-
|
|
7862
|
+
chunkMH4VFSDL_js.finishPrintWindow(
|
|
7727
7863
|
printWindow,
|
|
7728
|
-
|
|
7864
|
+
chunkMH4VFSDL_js.buildPrintHtmlDocument({
|
|
7729
7865
|
title: "Outline",
|
|
7730
|
-
bodyHtml: `<div class="outline-page">${
|
|
7866
|
+
bodyHtml: `<div class="outline-page">${chunkMH4VFSDL_js.buildOutlineHtml(slideIndices, slides)}</div>`,
|
|
7731
7867
|
orientation: settings.orientation,
|
|
7732
7868
|
colorFilter,
|
|
7733
7869
|
frameSlides: settings.frameSlides,
|
|
@@ -7754,11 +7890,11 @@ function usePrintHandlers(input) {
|
|
|
7754
7890
|
}
|
|
7755
7891
|
const slideImages = slideIndices.map((idx) => allImages[idx]).filter(Boolean);
|
|
7756
7892
|
if (settings.printWhat === "slides") {
|
|
7757
|
-
|
|
7893
|
+
chunkMH4VFSDL_js.finishPrintWindow(
|
|
7758
7894
|
printWindow,
|
|
7759
|
-
|
|
7895
|
+
chunkMH4VFSDL_js.buildPrintHtmlDocument({
|
|
7760
7896
|
title: "Slides",
|
|
7761
|
-
bodyHtml:
|
|
7897
|
+
bodyHtml: chunkMH4VFSDL_js.buildSlidesHtml(slideImages, slideIndices),
|
|
7762
7898
|
orientation: settings.orientation,
|
|
7763
7899
|
colorFilter,
|
|
7764
7900
|
frameSlides: settings.frameSlides,
|
|
@@ -7768,11 +7904,11 @@ function usePrintHandlers(input) {
|
|
|
7768
7904
|
return;
|
|
7769
7905
|
}
|
|
7770
7906
|
if (settings.printWhat === "notes") {
|
|
7771
|
-
|
|
7907
|
+
chunkMH4VFSDL_js.finishPrintWindow(
|
|
7772
7908
|
printWindow,
|
|
7773
|
-
|
|
7909
|
+
chunkMH4VFSDL_js.buildPrintHtmlDocument({
|
|
7774
7910
|
title: "Notes Pages",
|
|
7775
|
-
bodyHtml:
|
|
7911
|
+
bodyHtml: chunkMH4VFSDL_js.buildNotesHtml(slideImages, slideIndices, slides),
|
|
7776
7912
|
orientation: "portrait",
|
|
7777
7913
|
colorFilter,
|
|
7778
7914
|
frameSlides: settings.frameSlides,
|
|
@@ -7783,11 +7919,11 @@ function usePrintHandlers(input) {
|
|
|
7783
7919
|
}
|
|
7784
7920
|
if (settings.printWhat === "handouts") {
|
|
7785
7921
|
const spp = settings.slidesPerPage;
|
|
7786
|
-
|
|
7922
|
+
chunkMH4VFSDL_js.finishPrintWindow(
|
|
7787
7923
|
printWindow,
|
|
7788
|
-
|
|
7924
|
+
chunkMH4VFSDL_js.buildPrintHtmlDocument({
|
|
7789
7925
|
title: `Handout ${spp} per page`,
|
|
7790
|
-
bodyHtml:
|
|
7926
|
+
bodyHtml: chunkMH4VFSDL_js.buildHandoutsHtml(slideImages, slideIndices, spp, pptxData?.handoutMaster),
|
|
7791
7927
|
orientation: "portrait",
|
|
7792
7928
|
colorFilter,
|
|
7793
7929
|
frameSlides: settings.frameSlides,
|
|
@@ -7801,7 +7937,7 @@ function usePrintHandlers(input) {
|
|
|
7801
7937
|
};
|
|
7802
7938
|
const handlePrintWithSettings = async (settings) => {
|
|
7803
7939
|
setIsPrintDialogOpen(false);
|
|
7804
|
-
const printWindow =
|
|
7940
|
+
const printWindow = chunkMH4VFSDL_js.openPendingPrintWindow(t("pptx.print.preparingToPrint"));
|
|
7805
7941
|
if (!printWindow) {
|
|
7806
7942
|
console.warn(
|
|
7807
7943
|
"[PowerPointViewer] Print window was blocked by the browser. Allow popups for this site to print."
|
|
@@ -7866,13 +8002,13 @@ function useThemeHandlers(input) {
|
|
|
7866
8002
|
return;
|
|
7867
8003
|
}
|
|
7868
8004
|
await handler.updateThemeColorScheme(colorScheme);
|
|
7869
|
-
const previousMap = theme?.colorScheme ?
|
|
7870
|
-
setSlides((prev) =>
|
|
8005
|
+
const previousMap = theme?.colorScheme ? chunkMH4VFSDL_js.buildThemeColorMap(theme.colorScheme) : {};
|
|
8006
|
+
setSlides((prev) => chunkMH4VFSDL_js.reResolveSlideColors(prev, previousMap, colorScheme));
|
|
7871
8007
|
if (Object.keys(templateElementsBySlideId).length > 0) {
|
|
7872
8008
|
setTemplateElementsBySlideId((prev) => {
|
|
7873
8009
|
const next = {};
|
|
7874
8010
|
for (const [slideId, elements] of Object.entries(prev)) {
|
|
7875
|
-
next[slideId] =
|
|
8011
|
+
next[slideId] = chunkMH4VFSDL_js.reResolveElementColors(elements, previousMap, colorScheme);
|
|
7876
8012
|
}
|
|
7877
8013
|
return next;
|
|
7878
8014
|
});
|
|
@@ -7981,7 +8117,7 @@ function useThemeSwitching(input) {
|
|
|
7981
8117
|
}
|
|
7982
8118
|
try {
|
|
7983
8119
|
await handler.applyTheme(preset.colorScheme, preset.fontScheme, preset.name);
|
|
7984
|
-
const newData =
|
|
8120
|
+
const newData = chunkMH4VFSDL_js.applyThemeToData(data, preset.colorScheme, preset.fontScheme, preset.name);
|
|
7985
8121
|
onDataChange(newData);
|
|
7986
8122
|
onThemeChanged?.(preset);
|
|
7987
8123
|
} catch (error) {
|
|
@@ -7998,7 +8134,7 @@ function useThemeSwitching(input) {
|
|
|
7998
8134
|
}
|
|
7999
8135
|
try {
|
|
8000
8136
|
await handler.applyTheme(colorScheme, fontScheme ?? {}, themeName);
|
|
8001
|
-
const newData =
|
|
8137
|
+
const newData = chunkMH4VFSDL_js.applyThemeToData(data, colorScheme, fontScheme, themeName);
|
|
8002
8138
|
onDataChange(newData);
|
|
8003
8139
|
} catch (error) {
|
|
8004
8140
|
console.error("Failed to switch to custom theme:", error);
|
|
@@ -8010,12 +8146,12 @@ function useThemeSwitching(input) {
|
|
|
8010
8146
|
if (!data?.theme?.colorScheme) {
|
|
8011
8147
|
return void 0;
|
|
8012
8148
|
}
|
|
8013
|
-
return
|
|
8014
|
-
(p) =>
|
|
8149
|
+
return chunkMH4VFSDL_js.THEME_PRESETS.find(
|
|
8150
|
+
(p) => chunkMH4VFSDL_js.themeColorSchemesEqual(data.theme?.colorScheme, p.colorScheme)
|
|
8015
8151
|
);
|
|
8016
8152
|
}, [data?.theme?.colorScheme]);
|
|
8017
8153
|
return {
|
|
8018
|
-
presets:
|
|
8154
|
+
presets: chunkMH4VFSDL_js.THEME_PRESETS,
|
|
8019
8155
|
switchToPreset,
|
|
8020
8156
|
switchToCustom,
|
|
8021
8157
|
currentPreset
|
|
@@ -8090,7 +8226,7 @@ function usePropertyHandlers(input) {
|
|
|
8090
8226
|
}
|
|
8091
8227
|
try {
|
|
8092
8228
|
const ab = await file.arrayBuffer();
|
|
8093
|
-
const h = new
|
|
8229
|
+
const h = new chunkMH4VFSDL_js.PptxHandler();
|
|
8094
8230
|
const other = await h.load(ab);
|
|
8095
8231
|
if (!other) {
|
|
8096
8232
|
return;
|
|
@@ -8100,7 +8236,7 @@ function usePropertyHandlers(input) {
|
|
|
8100
8236
|
width: canvasSize.width,
|
|
8101
8237
|
height: canvasSize.height
|
|
8102
8238
|
};
|
|
8103
|
-
setCompareResult(
|
|
8239
|
+
setCompareResult(chunkMH4VFSDL_js.comparePresentation(cur, other));
|
|
8104
8240
|
setIsComparePanelOpen(true);
|
|
8105
8241
|
} catch (err) {
|
|
8106
8242
|
console.warn("Compare failed:", err);
|
|
@@ -8117,7 +8253,7 @@ function usePropertyHandlers(input) {
|
|
|
8117
8253
|
if (!diff || diff.status === "unchanged") {
|
|
8118
8254
|
return;
|
|
8119
8255
|
}
|
|
8120
|
-
setSlides((prev) =>
|
|
8256
|
+
setSlides((prev) => chunkMH4VFSDL_js.applyAcceptSlide(prev, diff));
|
|
8121
8257
|
setIsDirty(true);
|
|
8122
8258
|
},
|
|
8123
8259
|
[compareResult, setSlides, setIsDirty]
|
|
@@ -8128,10 +8264,10 @@ function usePropertyHandlers(input) {
|
|
|
8128
8264
|
if (!compareResult) {
|
|
8129
8265
|
return;
|
|
8130
8266
|
}
|
|
8131
|
-
setSlides((prev) =>
|
|
8267
|
+
setSlides((prev) => chunkMH4VFSDL_js.applyAcceptAllSlides(prev, compareResult));
|
|
8132
8268
|
setIsDirty(true);
|
|
8133
8269
|
}, [compareResult, setSlides, setIsDirty]);
|
|
8134
|
-
const usedFontFamilies = react.useMemo(() =>
|
|
8270
|
+
const usedFontFamilies = react.useMemo(() => chunkMH4VFSDL_js.collectUsedFonts(slides), [slides]);
|
|
8135
8271
|
return {
|
|
8136
8272
|
handleUpdateNotes,
|
|
8137
8273
|
handleUpdateSlide,
|
|
@@ -8286,7 +8422,7 @@ function useViewerDialogs(input) {
|
|
|
8286
8422
|
);
|
|
8287
8423
|
const embeddedFontKey = (embeddedFontFamilies ?? []).join("\0");
|
|
8288
8424
|
const fontEmbedding = react.useMemo(
|
|
8289
|
-
() =>
|
|
8425
|
+
() => chunkMH4VFSDL_js.describeFontEmbedding(embeddedFontKey ? embeddedFontKey.split("\0") : []),
|
|
8290
8426
|
[embeddedFontKey]
|
|
8291
8427
|
);
|
|
8292
8428
|
const [embedFontsEnabled, setEmbedFontsEnabled] = react.useState(fontEmbedding.initialEnabled);
|
|
@@ -8296,11 +8432,11 @@ function useViewerDialogs(input) {
|
|
|
8296
8432
|
setEmbedFontsEnabled(fontEmbedding.initialEnabled);
|
|
8297
8433
|
}
|
|
8298
8434
|
const [isNarrowViewport, setIsNarrowViewport] = react.useState(
|
|
8299
|
-
() => typeof window !== "undefined" ?
|
|
8435
|
+
() => typeof window !== "undefined" ? chunkMH4VFSDL_js.isMobileViewport(window.innerWidth, window.innerHeight, viewportIsTouch()) : false
|
|
8300
8436
|
);
|
|
8301
8437
|
react.useEffect(() => {
|
|
8302
8438
|
const handleWindow = () => setIsNarrowViewport(
|
|
8303
|
-
|
|
8439
|
+
chunkMH4VFSDL_js.isMobileViewport(window.innerWidth, window.innerHeight, viewportIsTouch())
|
|
8304
8440
|
);
|
|
8305
8441
|
window.addEventListener("resize", handleWindow);
|
|
8306
8442
|
return () => window.removeEventListener("resize", handleWindow);
|
|
@@ -8453,16 +8589,16 @@ function useViewerDialogs(input) {
|
|
|
8453
8589
|
};
|
|
8454
8590
|
}
|
|
8455
8591
|
function computeGridSpacingPx2(documentGridSpacing) {
|
|
8456
|
-
return
|
|
8592
|
+
return chunkMH4VFSDL_js.computeGridSpacingPx(documentGridSpacing, chunkH4LMXJ2Z_js.GRID_SIZE);
|
|
8457
8593
|
}
|
|
8458
8594
|
function computeVisibleSlideIndexes(slides, activeCustomShowId, customShows, presentationProperties) {
|
|
8459
8595
|
const activeShow = activeCustomShowId ? customShows.find((show) => show.id === activeCustomShowId) : void 0;
|
|
8460
|
-
const authoredRange =
|
|
8461
|
-
return
|
|
8596
|
+
const authoredRange = chunkMH4VFSDL_js.resolveAuthoredSlideRange(presentationProperties, slides.length);
|
|
8597
|
+
return chunkMH4VFSDL_js.resolveShowSlideIndexes(slides, activeShow, authoredRange);
|
|
8462
8598
|
}
|
|
8463
8599
|
function computeSlideSectionGroups(slides, sections) {
|
|
8464
|
-
return
|
|
8465
|
-
id: group.section?.id ?? (sections.length > 0 ?
|
|
8600
|
+
return chunkMH4VFSDL_js.groupSlidesBySection(sections, slides).map((group) => ({
|
|
8601
|
+
id: group.section?.id ?? (sections.length > 0 ? chunkH4LMXJ2Z_js.UNGROUPED_SECTION_ID : chunkH4LMXJ2Z_js.DEFAULT_SECTION_GROUP_ID),
|
|
8466
8602
|
label: group.section?.name ?? (sections.length > 0 ? "Ungrouped Slides" : "Slides"),
|
|
8467
8603
|
slideIndexes: group.slideIndexes,
|
|
8468
8604
|
...group.section?.color !== void 0 ? { color: group.section.color } : {},
|
|
@@ -8474,7 +8610,7 @@ function computeMasterPseudoSlide(mode, activeLayout, activeMaster) {
|
|
|
8474
8610
|
return void 0;
|
|
8475
8611
|
}
|
|
8476
8612
|
const document2 = activeLayout ? { slideMasters: [{ ...activeMaster, layouts: [activeLayout] }] } : { slideMasters: [activeMaster] };
|
|
8477
|
-
return
|
|
8613
|
+
return chunkMH4VFSDL_js.masterViewPseudoSlide(document2, {
|
|
8478
8614
|
tab: "slides",
|
|
8479
8615
|
masterIndex: 0,
|
|
8480
8616
|
layoutIndex: activeLayout ? 0 : null
|
|
@@ -8502,15 +8638,15 @@ function useDerivedSlideState(input) {
|
|
|
8502
8638
|
[slides, activeCustomShowId, customShows, presentationProperties]
|
|
8503
8639
|
);
|
|
8504
8640
|
const authoredRange = react.useMemo(
|
|
8505
|
-
() =>
|
|
8641
|
+
() => chunkMH4VFSDL_js.resolveAuthoredSlideRange(presentationProperties, slides.length),
|
|
8506
8642
|
[presentationProperties, slides.length]
|
|
8507
8643
|
);
|
|
8508
8644
|
const slideSectionGroups = react.useMemo(
|
|
8509
8645
|
() => computeSlideSectionGroups(slides, sections).map((group) => {
|
|
8510
|
-
if (group.id ===
|
|
8646
|
+
if (group.id === chunkH4LMXJ2Z_js.UNGROUPED_SECTION_ID && group.label === "Ungrouped Slides") {
|
|
8511
8647
|
return { ...group, label: t("pptx.slides.ungroupedSlides") };
|
|
8512
8648
|
}
|
|
8513
|
-
if (group.id ===
|
|
8649
|
+
if (group.id === chunkH4LMXJ2Z_js.DEFAULT_SECTION_GROUP_ID && group.label === "Slides") {
|
|
8514
8650
|
return { ...group, label: t("pptx.sections.slides") };
|
|
8515
8651
|
}
|
|
8516
8652
|
return group;
|
|
@@ -8611,13 +8747,13 @@ function useAnnotationHandlers(input) {
|
|
|
8611
8747
|
}, [annotations, setMode, setSlides, history]);
|
|
8612
8748
|
const handleSetMode = react.useCallback(
|
|
8613
8749
|
(nextMode) => {
|
|
8614
|
-
if (mode === "present" && nextMode !== "present" && !
|
|
8750
|
+
if (mode === "present" && nextMode !== "present" && !chunkMH4VFSDL_js.mayLeaveSlideShow()) {
|
|
8615
8751
|
return;
|
|
8616
8752
|
}
|
|
8617
8753
|
if (nextMode === "present") {
|
|
8618
8754
|
presentation.enterPresentMode();
|
|
8619
8755
|
} else if (mode === "present" && annotations.hasAnyAnnotations) {
|
|
8620
|
-
|
|
8756
|
+
chunkMH4VFSDL_js.stopAllPersistentAudio();
|
|
8621
8757
|
if (promptKeepInkAnnotations) {
|
|
8622
8758
|
pendingModeAfterAnnotationsRef.current = nextMode;
|
|
8623
8759
|
setShowKeepAnnotationsDialog(true);
|
|
@@ -8627,7 +8763,7 @@ function useAnnotationHandlers(input) {
|
|
|
8627
8763
|
}
|
|
8628
8764
|
} else {
|
|
8629
8765
|
if (mode === "present") {
|
|
8630
|
-
|
|
8766
|
+
chunkMH4VFSDL_js.stopAllPersistentAudio();
|
|
8631
8767
|
}
|
|
8632
8768
|
setMode(nextMode);
|
|
8633
8769
|
}
|
|
@@ -8696,13 +8832,13 @@ function useSerialize(input) {
|
|
|
8696
8832
|
let processedSlide = slide;
|
|
8697
8833
|
if (pendingEditId) {
|
|
8698
8834
|
const updatedElements = slide.elements.map((el) => {
|
|
8699
|
-
if (el.id !== pendingEditId || !
|
|
8835
|
+
if (el.id !== pendingEditId || !chunkMH4VFSDL_js.hasTextProperties(el)) {
|
|
8700
8836
|
return el;
|
|
8701
8837
|
}
|
|
8702
8838
|
return {
|
|
8703
8839
|
...el,
|
|
8704
8840
|
text: pendingEditText,
|
|
8705
|
-
textSegments:
|
|
8841
|
+
textSegments: chunkMH4VFSDL_js.remapTextToSegments(pendingEditText, el.textSegments, el.textStyle)
|
|
8706
8842
|
};
|
|
8707
8843
|
});
|
|
8708
8844
|
if (updatedElements.some((el, i) => el !== slide.elements[i])) {
|
|
@@ -8715,19 +8851,19 @@ function useSerialize(input) {
|
|
|
8715
8851
|
const pptxGuides = guides.map((g) => ({
|
|
8716
8852
|
id: g.id,
|
|
8717
8853
|
orientation: g.axis === "h" ? "horz" : "vert",
|
|
8718
|
-
positionEmu:
|
|
8854
|
+
positionEmu: chunkMH4VFSDL_js.guidePxToEmu(g.position)
|
|
8719
8855
|
}));
|
|
8720
8856
|
return {
|
|
8721
8857
|
...processedSlide,
|
|
8722
8858
|
guides: pptxGuides.length > 0 ? pptxGuides : void 0
|
|
8723
8859
|
};
|
|
8724
8860
|
});
|
|
8725
|
-
const slidesToSave =
|
|
8726
|
-
const saveOptions =
|
|
8861
|
+
const slidesToSave = chunkMH4VFSDL_js.buildSaveSlides(slidesWithGuides, templateElementsBySlideId);
|
|
8862
|
+
const saveOptions = chunkMH4VFSDL_js.buildDeckSaveOptions({
|
|
8727
8863
|
// Without this the Slide Size card edited a viewer-only pixel value and
|
|
8728
8864
|
// the saved `p:sldSz` never moved: passing `slideSize` is the only way a
|
|
8729
8865
|
// slide-size edit reaches the file.
|
|
8730
|
-
slideSize:
|
|
8866
|
+
slideSize: chunkMH4VFSDL_js.resolveSlideSizeSelection({ current: slideSizeEmu, canvas: canvasSize }).size,
|
|
8731
8867
|
headerFooter,
|
|
8732
8868
|
presentationProperties,
|
|
8733
8869
|
viewProperties,
|
|
@@ -8746,7 +8882,7 @@ function useSerialize(input) {
|
|
|
8746
8882
|
embedFonts,
|
|
8747
8883
|
outputFormat: format
|
|
8748
8884
|
});
|
|
8749
|
-
return
|
|
8885
|
+
return chunkMH4VFSDL_js.saveDeckWithPassword(handler, slidesToSave, saveOptions, { password, purpose });
|
|
8750
8886
|
},
|
|
8751
8887
|
[
|
|
8752
8888
|
slides,
|
|
@@ -8787,7 +8923,7 @@ function useRecoveryDetection(input) {
|
|
|
8787
8923
|
const onRestore = input.onRestore;
|
|
8788
8924
|
const openVersionHistory = input.openVersionHistory;
|
|
8789
8925
|
react.useEffect(() => {
|
|
8790
|
-
if (!
|
|
8926
|
+
if (!chunkMH4VFSDL_js.shouldProbeAutosaveRecovery({
|
|
8791
8927
|
alreadyChecked: recoveryCheckedRef.current,
|
|
8792
8928
|
filePath,
|
|
8793
8929
|
loading,
|
|
@@ -8799,7 +8935,7 @@ function useRecoveryDetection(input) {
|
|
|
8799
8935
|
}
|
|
8800
8936
|
recoveryCheckedRef.current = true;
|
|
8801
8937
|
void (async () => {
|
|
8802
|
-
const offer = await
|
|
8938
|
+
const offer = await chunkMH4VFSDL_js.probeAutosaveRecovery(filePath);
|
|
8803
8939
|
if (!offer) {
|
|
8804
8940
|
return;
|
|
8805
8941
|
}
|
|
@@ -8812,7 +8948,7 @@ function useRecoveryDetection(input) {
|
|
|
8812
8948
|
const record = recordRef.current;
|
|
8813
8949
|
setPrompt(null);
|
|
8814
8950
|
if (record && onRestore) {
|
|
8815
|
-
onRestore(
|
|
8951
|
+
onRestore(chunkMH4VFSDL_js.acceptAutosaveRecovery(record));
|
|
8816
8952
|
}
|
|
8817
8953
|
recordRef.current = null;
|
|
8818
8954
|
}, [onRestore]);
|
|
@@ -8821,7 +8957,7 @@ function useRecoveryDetection(input) {
|
|
|
8821
8957
|
setPrompt(null);
|
|
8822
8958
|
recordRef.current = null;
|
|
8823
8959
|
if (record) {
|
|
8824
|
-
void
|
|
8960
|
+
void chunkMH4VFSDL_js.discardAutosaveRecovery(record);
|
|
8825
8961
|
}
|
|
8826
8962
|
}, []);
|
|
8827
8963
|
return { prompt, restore, discard };
|
|
@@ -8872,11 +9008,11 @@ function usePresentationSetup(input) {
|
|
|
8872
9008
|
containerRef,
|
|
8873
9009
|
content,
|
|
8874
9010
|
onSetMode: (nextMode) => {
|
|
8875
|
-
if (mode === "present" && nextMode !== "present" && !
|
|
9011
|
+
if (mode === "present" && nextMode !== "present" && !chunkMH4VFSDL_js.mayLeaveSlideShow()) {
|
|
8876
9012
|
return;
|
|
8877
9013
|
}
|
|
8878
9014
|
if (mode === "present" && nextMode !== "present") {
|
|
8879
|
-
|
|
9015
|
+
chunkMH4VFSDL_js.stopAllPersistentAudio();
|
|
8880
9016
|
stopAnimationSound();
|
|
8881
9017
|
const exitHandler = exitModeHandlerRef.current;
|
|
8882
9018
|
if (exitHandler) {
|
|
@@ -8944,10 +9080,10 @@ function usePresentationSetup(input) {
|
|
|
8944
9080
|
onToggleToolbar: () => annotations.setToolbarVisible(!annotations.toolbarVisible),
|
|
8945
9081
|
onToggleSubtitles,
|
|
8946
9082
|
onSaveRehearsalTimings: (timings) => {
|
|
8947
|
-
setSlides((prev) =>
|
|
9083
|
+
setSlides((prev) => chunkMH4VFSDL_js.applyRehearsalTimings(prev, timings));
|
|
8948
9084
|
history.markDirty();
|
|
8949
9085
|
},
|
|
8950
|
-
loopContinuously:
|
|
9086
|
+
loopContinuously: chunkMH4VFSDL_js.shouldLoopContinuously(presentationProperties),
|
|
8951
9087
|
showWithAnimation: presentationProperties.showWithAnimation,
|
|
8952
9088
|
useTimings: presentationProperties.advanceMode !== "manual",
|
|
8953
9089
|
endWithBlackSlide,
|
|
@@ -9154,7 +9290,7 @@ function useEditorOperations(input) {
|
|
|
9154
9290
|
const { formatPainterActive, setFormatPainterActive, elementLookup } = state;
|
|
9155
9291
|
react.useEffect(() => {
|
|
9156
9292
|
if (formatPainterActive && !prevFormatPainterRef.current && selectedElement) {
|
|
9157
|
-
copiedFormatRef.current =
|
|
9293
|
+
copiedFormatRef.current = chunkMH4VFSDL_js.copyFormatFromElement(selectedElement);
|
|
9158
9294
|
} else if (!formatPainterActive) {
|
|
9159
9295
|
copiedFormatRef.current = null;
|
|
9160
9296
|
}
|
|
@@ -9180,12 +9316,12 @@ function useEditorOperations(input) {
|
|
|
9180
9316
|
e.stopPropagation();
|
|
9181
9317
|
const element = elementLookup.get(elementId);
|
|
9182
9318
|
if (element) {
|
|
9183
|
-
const updated =
|
|
9319
|
+
const updated = chunkMH4VFSDL_js.applyFormatToElement(element, copiedFormatRef.current);
|
|
9184
9320
|
const updates = {};
|
|
9185
|
-
if (
|
|
9321
|
+
if (chunkMH4VFSDL_js.hasShapeProperties(updated)) {
|
|
9186
9322
|
updates.shapeStyle = updated.shapeStyle;
|
|
9187
9323
|
}
|
|
9188
|
-
if (
|
|
9324
|
+
if (chunkMH4VFSDL_js.hasTextProperties(updated)) {
|
|
9189
9325
|
updates.textStyle = updated.textStyle;
|
|
9190
9326
|
}
|
|
9191
9327
|
ops.updateElementById(elementId, updates);
|
|
@@ -9236,7 +9372,8 @@ function useIOHandlers(input) {
|
|
|
9236
9372
|
serializeForRecovery,
|
|
9237
9373
|
setContent,
|
|
9238
9374
|
onContentChange,
|
|
9239
|
-
imageExportScale
|
|
9375
|
+
imageExportScale,
|
|
9376
|
+
imageResolutionScale
|
|
9240
9377
|
} = input;
|
|
9241
9378
|
const exportHandlers = useExportHandlers({
|
|
9242
9379
|
slides,
|
|
@@ -9260,7 +9397,8 @@ function useIOHandlers(input) {
|
|
|
9260
9397
|
theme: state.theme,
|
|
9261
9398
|
canvasSize,
|
|
9262
9399
|
slideSizeEmu: state.slideSizeEmu,
|
|
9263
|
-
imageExportScale
|
|
9400
|
+
imageExportScale,
|
|
9401
|
+
imageResolutionScale
|
|
9264
9402
|
});
|
|
9265
9403
|
const printHandlers = usePrintHandlers({
|
|
9266
9404
|
slides,
|
|
@@ -9369,10 +9507,10 @@ function useFontInjection({ embeddedFonts, slides }) {
|
|
|
9369
9507
|
}
|
|
9370
9508
|
};
|
|
9371
9509
|
}, [embeddedFonts]);
|
|
9372
|
-
const referencedFamilies = react.useMemo(() =>
|
|
9510
|
+
const referencedFamilies = react.useMemo(() => chunkMH4VFSDL_js.collectReferencedFontFamilies(slides), [slides]);
|
|
9373
9511
|
react.useEffect(() => {
|
|
9374
9512
|
let cancelled = false;
|
|
9375
|
-
void
|
|
9513
|
+
void chunkMH4VFSDL_js.resolveGoogleWebfontHref(slides, embeddedFonts).then((href) => {
|
|
9376
9514
|
if (cancelled) {
|
|
9377
9515
|
return null;
|
|
9378
9516
|
}
|
|
@@ -9394,6 +9532,52 @@ function useFontInjection({ embeddedFonts, slides }) {
|
|
|
9394
9532
|
}
|
|
9395
9533
|
};
|
|
9396
9534
|
}, [embeddedFonts, slides]);
|
|
9535
|
+
const [, setOutlineFontsTick] = react.useState(0);
|
|
9536
|
+
react.useEffect(() => {
|
|
9537
|
+
let cancelled = false;
|
|
9538
|
+
const referenced = chunkMH4VFSDL_js.collectReferencedFontFamilies(slides);
|
|
9539
|
+
const candidates = chunkMH4VFSDL_js.selectGoogleWebfontFamilies(
|
|
9540
|
+
referenced,
|
|
9541
|
+
embeddedFonts.map((font) => font.name)
|
|
9542
|
+
);
|
|
9543
|
+
if (candidates.length === 0) {
|
|
9544
|
+
return;
|
|
9545
|
+
}
|
|
9546
|
+
void chunkMH4VFSDL_js.resolveGoogleWebfontHref(slides, embeddedFonts).then(async (href) => {
|
|
9547
|
+
if (cancelled || !href) {
|
|
9548
|
+
return;
|
|
9549
|
+
}
|
|
9550
|
+
const boldItalicVariants = [
|
|
9551
|
+
{ bold: false, italic: false },
|
|
9552
|
+
{ bold: true, italic: false }
|
|
9553
|
+
];
|
|
9554
|
+
let registeredAny = false;
|
|
9555
|
+
for (const family of candidates) {
|
|
9556
|
+
for (const variant of boldItalicVariants) {
|
|
9557
|
+
if (cancelled) {
|
|
9558
|
+
return;
|
|
9559
|
+
}
|
|
9560
|
+
const bytes = await chunkMH4VFSDL_js.fetchGoogleWebfontOutlineBytes(
|
|
9561
|
+
href,
|
|
9562
|
+
family,
|
|
9563
|
+
variant.bold,
|
|
9564
|
+
variant.italic,
|
|
9565
|
+
fetch
|
|
9566
|
+
);
|
|
9567
|
+
if (bytes && glyphOutlineFontCache.registerFontBytes(family, variant.bold, variant.italic, bytes)) {
|
|
9568
|
+
registeredAny = true;
|
|
9569
|
+
}
|
|
9570
|
+
}
|
|
9571
|
+
}
|
|
9572
|
+
if (registeredAny && !cancelled) {
|
|
9573
|
+
setOutlineFontsTick((tick) => tick + 1);
|
|
9574
|
+
}
|
|
9575
|
+
return void 0;
|
|
9576
|
+
});
|
|
9577
|
+
return () => {
|
|
9578
|
+
cancelled = true;
|
|
9579
|
+
};
|
|
9580
|
+
}, [embeddedFonts, slides]);
|
|
9397
9581
|
react.useEffect(() => {
|
|
9398
9582
|
const neededSymbolFonts = SYMBOL_FONT_FAMILIES.filter((f) => referencedFamilies.has(f));
|
|
9399
9583
|
if (neededSymbolFonts.length === 0) {
|
|
@@ -9562,7 +9746,7 @@ function useKeyboardShortcuts(input) {
|
|
|
9562
9746
|
inputRef.current = input;
|
|
9563
9747
|
const handleKeyDown = react.useCallback((e) => {
|
|
9564
9748
|
const current = inputRef.current;
|
|
9565
|
-
const startAction =
|
|
9749
|
+
const startAction = chunkMH4VFSDL_js.mapSlideShowStartKey(e, { isPresenting: current.mode === "present" });
|
|
9566
9750
|
if (startAction !== null) {
|
|
9567
9751
|
e.preventDefault();
|
|
9568
9752
|
if (startAction === "fromBeginning") {
|
|
@@ -9572,7 +9756,7 @@ function useKeyboardShortcuts(input) {
|
|
|
9572
9756
|
}
|
|
9573
9757
|
return;
|
|
9574
9758
|
}
|
|
9575
|
-
const { action, dx, dy } =
|
|
9759
|
+
const { action, dx, dy } = chunkMH4VFSDL_js.mapEditorKey(e, {
|
|
9576
9760
|
canEdit: current.canEdit,
|
|
9577
9761
|
// The Slide Master view is an editing surface, not a viewing one.
|
|
9578
9762
|
// Gating on `mode !== 'edit'` alone made `mapEditorKey` return
|
|
@@ -9585,7 +9769,7 @@ function useKeyboardShortcuts(input) {
|
|
|
9585
9769
|
hasSelection: current.hasSelection,
|
|
9586
9770
|
isEditingText: Boolean(current.inlineEditingElementId || current.tableEditorState?.isEditing),
|
|
9587
9771
|
isDrawing: current.activeTool !== "select",
|
|
9588
|
-
isTextInputTarget:
|
|
9772
|
+
isTextInputTarget: chunkMH4VFSDL_js.isEditorTextInputTarget(e.target)
|
|
9589
9773
|
});
|
|
9590
9774
|
if (action === null) {
|
|
9591
9775
|
return;
|
|
@@ -9761,6 +9945,7 @@ function useViewerIntegration(input) {
|
|
|
9761
9945
|
canEdit,
|
|
9762
9946
|
promptKeepInkAnnotations,
|
|
9763
9947
|
imageExportScale,
|
|
9948
|
+
imageResolutionScale,
|
|
9764
9949
|
mode,
|
|
9765
9950
|
slides,
|
|
9766
9951
|
activeSlide,
|
|
@@ -9846,7 +10031,8 @@ function useViewerIntegration(input) {
|
|
|
9846
10031
|
serializeForRecovery,
|
|
9847
10032
|
setContent,
|
|
9848
10033
|
onContentChange,
|
|
9849
|
-
imageExportScale
|
|
10034
|
+
imageExportScale,
|
|
10035
|
+
imageResolutionScale
|
|
9850
10036
|
});
|
|
9851
10037
|
const {
|
|
9852
10038
|
showKeepAnnotationsDialog,
|
|
@@ -9915,7 +10101,7 @@ function useViewerIntegration(input) {
|
|
|
9915
10101
|
return zoom.scale;
|
|
9916
10102
|
},
|
|
9917
10103
|
setZoom(level) {
|
|
9918
|
-
zoom.setScale(
|
|
10104
|
+
zoom.setScale(chunkMH4VFSDL_js.clampZoomScale(level));
|
|
9919
10105
|
},
|
|
9920
10106
|
zoomIn() {
|
|
9921
10107
|
zoom.handleZoomIn();
|
|
@@ -10133,7 +10319,7 @@ function useReducedMotion() {
|
|
|
10133
10319
|
}
|
|
10134
10320
|
function useViewerOptions() {
|
|
10135
10321
|
const storeRef = react.useRef(null);
|
|
10136
|
-
storeRef.current ??=
|
|
10322
|
+
storeRef.current ??= chunkMH4VFSDL_js.createViewerOptionsStore();
|
|
10137
10323
|
const store = storeRef.current;
|
|
10138
10324
|
const options = react.useSyncExternalStore(
|
|
10139
10325
|
(onStoreChange) => store.subscribe(onStoreChange),
|
|
@@ -10142,9 +10328,9 @@ function useViewerOptions() {
|
|
|
10142
10328
|
);
|
|
10143
10329
|
return { optionsStore: store, options };
|
|
10144
10330
|
}
|
|
10145
|
-
var KNOWN_TAB_IDS = new Set(
|
|
10331
|
+
var KNOWN_TAB_IDS = new Set(chunkMH4VFSDL_js.TOOLBAR_TABS.map((tab) => tab.id));
|
|
10146
10332
|
function computeToolbarVisibility(hiddenActions, hiddenTabIds = []) {
|
|
10147
|
-
const isHidden = (id) =>
|
|
10333
|
+
const isHidden = (id) => chunkMH4VFSDL_js.isActionHidden(id, hiddenActions);
|
|
10148
10334
|
const userHidden = new Set(hiddenTabIds);
|
|
10149
10335
|
userHidden.delete("file");
|
|
10150
10336
|
const isTabVisible = (id) => !KNOWN_TAB_IDS.has(id) || !isHidden(id) && !userHidden.has(id);
|
|
@@ -10237,12 +10423,12 @@ function useYjsDocumentSync({
|
|
|
10237
10423
|
return;
|
|
10238
10424
|
}
|
|
10239
10425
|
try {
|
|
10240
|
-
const handler = new
|
|
10426
|
+
const handler = new chunkMH4VFSDL_js.PptxHandler();
|
|
10241
10427
|
await handler.load(sourceBytes.buffer);
|
|
10242
|
-
const currentSlides =
|
|
10428
|
+
const currentSlides = chunkMH4VFSDL_js.readSlidesFromYDoc(
|
|
10243
10429
|
doc
|
|
10244
10430
|
);
|
|
10245
|
-
const slidesToSave =
|
|
10431
|
+
const slidesToSave = chunkMH4VFSDL_js.buildSaveSlides(currentSlides, templateElementsBySlideId);
|
|
10246
10432
|
const bytes = await handler.save(slidesToSave, getSaveOptions?.());
|
|
10247
10433
|
config.onWriteBack(bytes);
|
|
10248
10434
|
} catch {
|
|
@@ -10257,10 +10443,10 @@ function useYjsDocumentSync({
|
|
|
10257
10443
|
if (!doc || !isConnected) {
|
|
10258
10444
|
return;
|
|
10259
10445
|
}
|
|
10260
|
-
const docSlides =
|
|
10446
|
+
const docSlides = chunkMH4VFSDL_js.readSlidesFromYDoc(
|
|
10261
10447
|
doc
|
|
10262
10448
|
);
|
|
10263
|
-
if (!
|
|
10449
|
+
if (!chunkMH4VFSDL_js.shouldRoomSlidesReplaceLoad(loadOrigin, docSlides.length)) {
|
|
10264
10450
|
return;
|
|
10265
10451
|
}
|
|
10266
10452
|
lastSyncedRef.current = JSON.stringify(docSlides);
|
|
@@ -10279,11 +10465,11 @@ function useYjsDocumentSync({
|
|
|
10279
10465
|
lastSyncedRef.current = serialized;
|
|
10280
10466
|
void (async () => {
|
|
10281
10467
|
const factories = await getFactories();
|
|
10282
|
-
|
|
10468
|
+
chunkMH4VFSDL_js.reconcileSlidesInYDoc(
|
|
10283
10469
|
slides,
|
|
10284
10470
|
doc,
|
|
10285
10471
|
factories,
|
|
10286
|
-
|
|
10472
|
+
chunkMH4VFSDL_js.LOCAL_SYNC_ORIGIN
|
|
10287
10473
|
);
|
|
10288
10474
|
scheduleWriteBack();
|
|
10289
10475
|
})();
|
|
@@ -10297,10 +10483,10 @@ function useYjsDocumentSync({
|
|
|
10297
10483
|
return;
|
|
10298
10484
|
}
|
|
10299
10485
|
const handleChange = (_events, transaction) => {
|
|
10300
|
-
if (transaction?.origin ===
|
|
10486
|
+
if (transaction?.origin === chunkMH4VFSDL_js.LOCAL_SYNC_ORIGIN) {
|
|
10301
10487
|
return;
|
|
10302
10488
|
}
|
|
10303
|
-
const remoteSlides =
|
|
10489
|
+
const remoteSlides = chunkMH4VFSDL_js.readSlidesFromYDoc(
|
|
10304
10490
|
doc
|
|
10305
10491
|
);
|
|
10306
10492
|
if (remoteSlides.length === 0) {
|
|
@@ -10316,7 +10502,7 @@ function useYjsDocumentSync({
|
|
|
10316
10502
|
isApplyingRemoteRef.current = false;
|
|
10317
10503
|
scheduleWriteBack();
|
|
10318
10504
|
};
|
|
10319
|
-
const unobserve =
|
|
10505
|
+
const unobserve = chunkMH4VFSDL_js.observeYDocSlides(
|
|
10320
10506
|
doc,
|
|
10321
10507
|
handleChange
|
|
10322
10508
|
);
|
|
@@ -10354,7 +10540,7 @@ function useBroadcastFollower({
|
|
|
10354
10540
|
if (!broadcaster) {
|
|
10355
10541
|
return;
|
|
10356
10542
|
}
|
|
10357
|
-
if (!
|
|
10543
|
+
if (!chunkMH4VFSDL_js.shouldAutoFollowBroadcaster({
|
|
10358
10544
|
localRole: collab.config.role,
|
|
10359
10545
|
broadcasterRole: broadcaster.role
|
|
10360
10546
|
})) {
|
|
@@ -10512,7 +10698,7 @@ function useLayoutSwitching(input) {
|
|
|
10512
10698
|
currentLayoutPath
|
|
10513
10699
|
};
|
|
10514
10700
|
}
|
|
10515
|
-
var MIN_TOUCH_TARGET =
|
|
10701
|
+
var MIN_TOUCH_TARGET = chunkMH4VFSDL_js.MIN_TOUCH_TARGET_PX;
|
|
10516
10702
|
function subscribeTouchCapability(callback) {
|
|
10517
10703
|
if (typeof window === "undefined") {
|
|
10518
10704
|
return () => {
|
|
@@ -10525,7 +10711,7 @@ function subscribeTouchCapability(callback) {
|
|
|
10525
10711
|
function useIsMobile() {
|
|
10526
10712
|
const isTouchDevice = react.useSyncExternalStore(
|
|
10527
10713
|
subscribeTouchCapability,
|
|
10528
|
-
|
|
10714
|
+
chunkMH4VFSDL_js.detectTouchDevice,
|
|
10529
10715
|
() => false
|
|
10530
10716
|
// server snapshot
|
|
10531
10717
|
);
|
|
@@ -10535,7 +10721,7 @@ function useIsMobile() {
|
|
|
10535
10721
|
const [viewportHeight, setViewportHeight] = react.useState(
|
|
10536
10722
|
() => typeof window === "undefined" ? 768 : window.innerHeight
|
|
10537
10723
|
);
|
|
10538
|
-
const [orientation, setOrientation] = react.useState(
|
|
10724
|
+
const [orientation, setOrientation] = react.useState(chunkMH4VFSDL_js.detectOrientation);
|
|
10539
10725
|
const [isVirtualKeyboardOpen, setIsVirtualKeyboardOpen] = react.useState(false);
|
|
10540
10726
|
const [initialViewportHeight] = react.useState(
|
|
10541
10727
|
() => typeof window !== "undefined" ? window.innerHeight : 800
|
|
@@ -10556,7 +10742,7 @@ function useIsMobile() {
|
|
|
10556
10742
|
return;
|
|
10557
10743
|
}
|
|
10558
10744
|
const handleOrientationChange = () => {
|
|
10559
|
-
setOrientation(
|
|
10745
|
+
setOrientation(chunkMH4VFSDL_js.detectOrientation());
|
|
10560
10746
|
};
|
|
10561
10747
|
if (screen.orientation) {
|
|
10562
10748
|
screen.orientation.addEventListener("change", handleOrientationChange);
|
|
@@ -10586,7 +10772,7 @@ function useIsMobile() {
|
|
|
10586
10772
|
window.addEventListener("resize", handleResize);
|
|
10587
10773
|
return () => window.removeEventListener("resize", handleResize);
|
|
10588
10774
|
}, [isTouchDevice, initialViewportHeight]);
|
|
10589
|
-
const { isMobile, isTablet, isDesktop } =
|
|
10775
|
+
const { isMobile, isTablet, isDesktop } = chunkMH4VFSDL_js.deriveViewportBreakpoints(
|
|
10590
10776
|
viewportWidth,
|
|
10591
10777
|
viewportHeight,
|
|
10592
10778
|
isTouchDevice
|
|
@@ -10597,7 +10783,9 @@ function useIsMobile() {
|
|
|
10597
10783
|
isDesktop,
|
|
10598
10784
|
isTouchDevice,
|
|
10599
10785
|
orientation,
|
|
10600
|
-
isVirtualKeyboardOpen
|
|
10786
|
+
isVirtualKeyboardOpen,
|
|
10787
|
+
viewportWidth,
|
|
10788
|
+
viewportHeight
|
|
10601
10789
|
};
|
|
10602
10790
|
}
|
|
10603
10791
|
function useTouchGestures(input) {
|
|
@@ -10617,10 +10805,10 @@ function useTouchGestures(input) {
|
|
|
10617
10805
|
if (!el || !enabled) {
|
|
10618
10806
|
return;
|
|
10619
10807
|
}
|
|
10620
|
-
const recognizer =
|
|
10808
|
+
const recognizer = chunkMH4VFSDL_js.createTouchGestureRecognizer({
|
|
10621
10809
|
getScale: () => scaleRef.current,
|
|
10622
|
-
minScale:
|
|
10623
|
-
maxScale:
|
|
10810
|
+
minScale: chunkMH4VFSDL_js.MIN_ZOOM_SCALE,
|
|
10811
|
+
maxScale: chunkMH4VFSDL_js.MAX_ZOOM_SCALE,
|
|
10624
10812
|
callbacks: {
|
|
10625
10813
|
onPinchZoom: (newScale) => callbacksRef.current.onPinchZoom?.(newScale),
|
|
10626
10814
|
onSwipe: (direction) => callbacksRef.current.onSwipe?.(direction),
|
|
@@ -10660,7 +10848,7 @@ function scrollFocusedIntoView(keyboardInset) {
|
|
|
10660
10848
|
return;
|
|
10661
10849
|
}
|
|
10662
10850
|
const rect = active.getBoundingClientRect();
|
|
10663
|
-
const delta =
|
|
10851
|
+
const delta = chunkMH4VFSDL_js.computeScrollDelta(
|
|
10664
10852
|
{ top: rect.top, bottom: rect.bottom },
|
|
10665
10853
|
window.innerHeight,
|
|
10666
10854
|
keyboardInset
|
|
@@ -10680,8 +10868,8 @@ function useKeyboardInsets(enabled = true) {
|
|
|
10680
10868
|
return;
|
|
10681
10869
|
}
|
|
10682
10870
|
const update = () => {
|
|
10683
|
-
const metrics =
|
|
10684
|
-
const inset = metrics ?
|
|
10871
|
+
const metrics = chunkMH4VFSDL_js.readViewportMetrics(window);
|
|
10872
|
+
const inset = metrics ? chunkMH4VFSDL_js.computeKeyboardInset(metrics) : 0;
|
|
10685
10873
|
setKeyboardInset(inset);
|
|
10686
10874
|
if (inset > 0) {
|
|
10687
10875
|
window.requestAnimationFrame(() => scrollFocusedIntoView(inset));
|
|
@@ -10692,8 +10880,8 @@ function useKeyboardInsets(enabled = true) {
|
|
|
10692
10880
|
vv.addEventListener("scroll", update);
|
|
10693
10881
|
const onFocusIn = () => {
|
|
10694
10882
|
window.requestAnimationFrame(() => {
|
|
10695
|
-
const metrics =
|
|
10696
|
-
const inset = metrics ?
|
|
10883
|
+
const metrics = chunkMH4VFSDL_js.readViewportMetrics(window);
|
|
10884
|
+
const inset = metrics ? chunkMH4VFSDL_js.computeKeyboardInset(metrics) : 0;
|
|
10697
10885
|
if (inset > 0) {
|
|
10698
10886
|
scrollFocusedIntoView(inset);
|
|
10699
10887
|
}
|
|
@@ -10706,7 +10894,7 @@ function useKeyboardInsets(enabled = true) {
|
|
|
10706
10894
|
document.removeEventListener("focusin", onFocusIn);
|
|
10707
10895
|
};
|
|
10708
10896
|
}, [enabled]);
|
|
10709
|
-
return { keyboardInset, isKeyboardOpen:
|
|
10897
|
+
return { keyboardInset, isKeyboardOpen: chunkMH4VFSDL_js.isKeyboardOpen(keyboardInset) };
|
|
10710
10898
|
}
|
|
10711
10899
|
|
|
10712
10900
|
// src/viewer/hooks/useViewerBuildingBlocks-canvas-props.ts
|
|
@@ -10735,21 +10923,21 @@ function buildCanvasProps(input) {
|
|
|
10735
10923
|
} = input;
|
|
10736
10924
|
const effectiveSlide = mode === "master" ? masterPseudoSlide : activeSlide;
|
|
10737
10925
|
const effectiveTemplateElements = mode === "master" ? s.activeLayout ? s.activeMaster?.elements ?? [] : [] : templateElements;
|
|
10738
|
-
const fieldContext =
|
|
10926
|
+
const fieldContext = chunkMH4VFSDL_js.buildFieldSubstitutionContext({
|
|
10739
10927
|
headerFooter: s.headerFooter,
|
|
10740
10928
|
customProperties: s.customProperties,
|
|
10741
10929
|
slide: activeSlide
|
|
10742
10930
|
});
|
|
10743
10931
|
const tableStyleContext = s.theme || s.tableStyleMap ? { theme: s.theme, tableStyleMap: s.tableStyleMap } : void 0;
|
|
10744
10932
|
const openExternalUrl = (url, target) => {
|
|
10745
|
-
if (
|
|
10933
|
+
if (chunkMH4VFSDL_js.shouldConfirmExternalHyperlink(viewerOptions, url) && !window.confirm(buildHyperlinkConfirmMessage(url))) {
|
|
10746
10934
|
return;
|
|
10747
10935
|
}
|
|
10748
|
-
|
|
10936
|
+
chunkMH4VFSDL_js.safeOpenUrl(url, target);
|
|
10749
10937
|
};
|
|
10750
10938
|
const handleActionClick = (elementId, action) => {
|
|
10751
10939
|
if (mode === "present") {
|
|
10752
|
-
const resolved =
|
|
10940
|
+
const resolved = chunkMH4VFSDL_js.resolvePresentationAction(action, { slideCount: slides.length });
|
|
10753
10941
|
if (resolved.intent.kind === "openUrl") {
|
|
10754
10942
|
openExternalUrl(resolved.intent.url);
|
|
10755
10943
|
return;
|
|
@@ -10760,9 +10948,9 @@ function buildCanvasProps(input) {
|
|
|
10760
10948
|
}
|
|
10761
10949
|
};
|
|
10762
10950
|
const handleHyperlinkClick = (url, target) => {
|
|
10763
|
-
if (
|
|
10951
|
+
if (chunkMH4VFSDL_js.isPpactionUrl(url)) {
|
|
10764
10952
|
if (mode === "present") {
|
|
10765
|
-
const parsed =
|
|
10953
|
+
const parsed = chunkMH4VFSDL_js.parsePpactionUrl(url);
|
|
10766
10954
|
if (parsed) {
|
|
10767
10955
|
presentation.handlePresentationAction({
|
|
10768
10956
|
action: parsed.action,
|
|
@@ -10868,7 +11056,7 @@ function buildCanvasProps(input) {
|
|
|
10868
11056
|
|
|
10869
11057
|
// src/viewer/hooks/useScopedLayoutOptions.ts
|
|
10870
11058
|
function scopeLayoutOptionsToActiveSlide(options, activeSlide) {
|
|
10871
|
-
return
|
|
11059
|
+
return chunkMH4VFSDL_js.scopeLayoutOptionsToSlide(options, activeSlide?.layoutPath);
|
|
10872
11060
|
}
|
|
10873
11061
|
|
|
10874
11062
|
// src/viewer/hooks/useViewerBuildingBlocks-toolbar-handlers.ts
|
|
@@ -10881,7 +11069,7 @@ function buildToolbarAnimationHandlers(input) {
|
|
|
10881
11069
|
const current = activeSlide.animations ?? [];
|
|
10882
11070
|
if (group === "motionPath") {
|
|
10883
11071
|
propertyHandlers.handleUpdateSlide({
|
|
10884
|
-
animations:
|
|
11072
|
+
animations: chunkMH4VFSDL_js.applyMotionPathPreset(current, selectedElement.id, preset)
|
|
10885
11073
|
});
|
|
10886
11074
|
return;
|
|
10887
11075
|
}
|
|
@@ -11077,7 +11265,7 @@ function buildToolbarProps(input) {
|
|
|
11077
11265
|
onOpenFile,
|
|
11078
11266
|
onOpenRecentFile,
|
|
11079
11267
|
onCreatePresentation: (templateId) => {
|
|
11080
|
-
s.setSlides(
|
|
11268
|
+
s.setSlides(chunkMH4VFSDL_js.createBackstagePresentation(templateId));
|
|
11081
11269
|
s.setActiveSlideIndex(0);
|
|
11082
11270
|
s.setSelectedElementId(null);
|
|
11083
11271
|
s.setSelectedElementIds([]);
|
|
@@ -11107,7 +11295,7 @@ function buildToolbarProps(input) {
|
|
|
11107
11295
|
loadLayoutPreviews: input.loadLayoutPreviews,
|
|
11108
11296
|
onInsertSlideFromLayout: slideOps.handleInsertSlideFromLayout,
|
|
11109
11297
|
onInsertSlideFromTemplate: slideOps.handleInsertSlideFromTemplate,
|
|
11110
|
-
templateScheme:
|
|
11298
|
+
templateScheme: chunkMH4VFSDL_js.templateSchemeFromTheme(s.theme?.colorScheme),
|
|
11111
11299
|
customShows: s.customShows,
|
|
11112
11300
|
activeCustomShowId: s.activeCustomShowId,
|
|
11113
11301
|
onSetActiveCustomShowId: s.setActiveCustomShowId,
|
|
@@ -11148,7 +11336,7 @@ function buildToolbarProps(input) {
|
|
|
11148
11336
|
isCommentsPanelOpen: s.isInspectorPaneOpen,
|
|
11149
11337
|
slideCommentCount: activeSlide?.comments?.length ?? 0,
|
|
11150
11338
|
formatPainterActive: s.formatPainterActive,
|
|
11151
|
-
canActivateFormatPainter:
|
|
11339
|
+
canActivateFormatPainter: chunkMH4VFSDL_js.hasCopyableFormat(selectedElement),
|
|
11152
11340
|
onToggleFormatPainter: () => s.setFormatPainterActive((p) => !p),
|
|
11153
11341
|
isSelectionPaneOpen: s.isSelectionPaneOpen,
|
|
11154
11342
|
onToggleSelectionPane: () => s.setIsSelectionPaneOpen((p) => !p),
|
|
@@ -11226,7 +11414,7 @@ function useViewerBuildingBlocksCore(input) {
|
|
|
11226
11414
|
headerFooter: state.headerFooter,
|
|
11227
11415
|
loading,
|
|
11228
11416
|
error,
|
|
11229
|
-
maxHistoryEntries:
|
|
11417
|
+
maxHistoryEntries: chunkMH4VFSDL_js.resolveHistoryDepth(viewerOptions),
|
|
11230
11418
|
hasActivePointerInteraction,
|
|
11231
11419
|
pointerCommitNonce: state.pointerCommitNonce,
|
|
11232
11420
|
onDirty: markDocumentDirty,
|
|
@@ -11251,7 +11439,7 @@ function useViewerBuildingBlocksCore(input) {
|
|
|
11251
11439
|
documentGridSpacing: state.viewProperties?.gridSpacing
|
|
11252
11440
|
});
|
|
11253
11441
|
const themeColorMap = react.useMemo(
|
|
11254
|
-
() => state.theme?.colorScheme ?
|
|
11442
|
+
() => state.theme?.colorScheme ? chunkMH4VFSDL_js.buildThemeColorMap(state.theme.colorScheme) : void 0,
|
|
11255
11443
|
[state.theme?.colorScheme]
|
|
11256
11444
|
);
|
|
11257
11445
|
const { presentation, annotations, actionSoundHandlerRef, setExitModeHandler } = usePresentationSetup({
|
|
@@ -11300,7 +11488,8 @@ function useViewerBuildingBlocksCore(input) {
|
|
|
11300
11488
|
gridSpacingPx,
|
|
11301
11489
|
// Multiplied against the pre-existing 2x baseline; see the matching
|
|
11302
11490
|
// comment in `PowerPointViewer.tsx`.
|
|
11303
|
-
imageExportScale: 2 *
|
|
11491
|
+
imageExportScale: 2 * chunkMH4VFSDL_js.resolveImageResolutionScale(viewerOptions),
|
|
11492
|
+
imageResolutionScale: chunkMH4VFSDL_js.resolveImageResolutionScale(viewerOptions),
|
|
11304
11493
|
viewerOptions
|
|
11305
11494
|
};
|
|
11306
11495
|
}
|
|
@@ -11316,7 +11505,7 @@ function useCompatibilityToastsState() {
|
|
|
11316
11505
|
}
|
|
11317
11506
|
function useReadOnlyRecommendationState(content) {
|
|
11318
11507
|
const [recommendation, setRecommendation] = react.useState(
|
|
11319
|
-
() =>
|
|
11508
|
+
() => chunkMH4VFSDL_js.readOnlyRecommendation(void 0)
|
|
11320
11509
|
);
|
|
11321
11510
|
const [modifyVerifier, setModifyVerifier] = react.useState(void 0);
|
|
11322
11511
|
const [bannerHidden, setBannerHidden] = react.useState(false);
|
|
@@ -11356,7 +11545,7 @@ function useReadOnlyRecommendationState(content) {
|
|
|
11356
11545
|
async (password) => {
|
|
11357
11546
|
setCheckingPassword(true);
|
|
11358
11547
|
try {
|
|
11359
|
-
const result = await
|
|
11548
|
+
const result = await chunkMH4VFSDL_js.checkModifyPassword(modifyVerifier, password);
|
|
11360
11549
|
if (result.ok) {
|
|
11361
11550
|
unlock();
|
|
11362
11551
|
} else {
|
|
@@ -11401,9 +11590,9 @@ function useViewPreferencesSync(input) {
|
|
|
11401
11590
|
setShowGuides
|
|
11402
11591
|
} = input;
|
|
11403
11592
|
react.useEffect(() => {
|
|
11404
|
-
const seeded =
|
|
11593
|
+
const seeded = chunkMH4VFSDL_js.viewerPreferencesFromViewProperties(
|
|
11405
11594
|
{ viewProperties },
|
|
11406
|
-
{ ...
|
|
11595
|
+
{ ...chunkMH4VFSDL_js.DEFAULT_VIEWER_PREFERENCES, snapToGrid, snapToObjects: snapToShape, showGuides }
|
|
11407
11596
|
);
|
|
11408
11597
|
setSnapToGrid(seeded.snapToGrid);
|
|
11409
11598
|
setSnapToShape(seeded.snapToObjects ?? snapToShape);
|
|
@@ -11413,7 +11602,7 @@ function useViewPreferencesSync(input) {
|
|
|
11413
11602
|
(prefsOverride) => {
|
|
11414
11603
|
setViewProperties((prev) => {
|
|
11415
11604
|
const merged = {
|
|
11416
|
-
...
|
|
11605
|
+
...chunkMH4VFSDL_js.DEFAULT_VIEWER_PREFERENCES,
|
|
11417
11606
|
snapToGrid,
|
|
11418
11607
|
snapToObjects: snapToShape,
|
|
11419
11608
|
showGuides,
|
|
@@ -11421,7 +11610,7 @@ function useViewPreferencesSync(input) {
|
|
|
11421
11610
|
gridSpacingCy: prev?.gridSpacing?.cy,
|
|
11422
11611
|
...prefsOverride
|
|
11423
11612
|
};
|
|
11424
|
-
const patch =
|
|
11613
|
+
const patch = chunkMH4VFSDL_js.viewPropertiesPatchFromPreferences(merged);
|
|
11425
11614
|
return {
|
|
11426
11615
|
...prev,
|
|
11427
11616
|
slideViewPr: { ...prev?.slideViewPr, ...patch.slideViewPr },
|
|
@@ -11483,6 +11672,7 @@ function useViewerBuildingBlocksState(input) {
|
|
|
11483
11672
|
actionSoundHandlerRef,
|
|
11484
11673
|
gridSpacingPx,
|
|
11485
11674
|
imageExportScale,
|
|
11675
|
+
imageResolutionScale,
|
|
11486
11676
|
setExitModeHandler,
|
|
11487
11677
|
viewerOptions
|
|
11488
11678
|
} = core;
|
|
@@ -11568,6 +11758,7 @@ function useViewerBuildingBlocksState(input) {
|
|
|
11568
11758
|
canEdit,
|
|
11569
11759
|
promptKeepInkAnnotations: viewerOptions.advanced.slideShowPromptKeepInkAnnotations,
|
|
11570
11760
|
imageExportScale,
|
|
11761
|
+
imageResolutionScale,
|
|
11571
11762
|
mode,
|
|
11572
11763
|
slides,
|
|
11573
11764
|
activeSlide,
|
|
@@ -11640,7 +11831,7 @@ function useViewerBuildingBlocks(input) {
|
|
|
11640
11831
|
}, [incomingContent]);
|
|
11641
11832
|
const onOpenFile = react.useCallback(() => {
|
|
11642
11833
|
void (async () => {
|
|
11643
|
-
const picked = await
|
|
11834
|
+
const picked = await chunkMH4VFSDL_js.openPptxFile();
|
|
11644
11835
|
if (picked) {
|
|
11645
11836
|
setContent(picked.buffer);
|
|
11646
11837
|
}
|
|
@@ -11648,7 +11839,7 @@ function useViewerBuildingBlocks(input) {
|
|
|
11648
11839
|
}, []);
|
|
11649
11840
|
const onOpenRecentFile = react.useCallback((key) => {
|
|
11650
11841
|
void (async () => {
|
|
11651
|
-
const bytes = await
|
|
11842
|
+
const bytes = await chunkMH4VFSDL_js.readBackstageRecentFile(key);
|
|
11652
11843
|
if (bytes) {
|
|
11653
11844
|
setContent(bytes);
|
|
11654
11845
|
}
|
|
@@ -11830,6 +12021,7 @@ exports.MIN_TOUCH_TARGET = MIN_TOUCH_TARGET;
|
|
|
11830
12021
|
exports.ViewerOptionsContext = ViewerOptionsContext;
|
|
11831
12022
|
exports.computeToolbarVisibility = computeToolbarVisibility;
|
|
11832
12023
|
exports.detectTargetType = detectTargetType;
|
|
12024
|
+
exports.getGlyphOutline = getGlyphOutline;
|
|
11833
12025
|
exports.isAudienceTab = isAudienceTab;
|
|
11834
12026
|
exports.parseAudienceNonce = parseAudienceNonce;
|
|
11835
12027
|
exports.parseEmailUrl = parseEmailUrl;
|