pptx-react-viewer 2.17.0 → 2.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2 -0
- package/README.md +14 -14
- package/dist/{AiChatPanel-RZ4A7P4H.mjs → AiChatPanel-SSSBERWJ.mjs} +4 -4
- package/dist/AiChatPanel-SSSBERWJ.mjs.br +0 -0
- package/dist/AiChatPanel-SSSBERWJ.mjs.gz +0 -0
- package/dist/{AiChatPanel-HCHCVQN2.js → AiChatPanel-UN5DHPZY.js} +24 -24
- package/dist/AiChatPanel-UN5DHPZY.js.br +0 -0
- package/dist/AiChatPanel-UN5DHPZY.js.gz +0 -0
- package/dist/{Model3DScene-LK7LSQNH.js → Model3DScene-4RPYKC2I.js} +2 -2
- package/dist/Model3DScene-4RPYKC2I.js.br +0 -0
- package/dist/Model3DScene-4RPYKC2I.js.gz +0 -0
- package/dist/{Model3DScene-I7FR74AD.mjs → Model3DScene-LYEESYAI.mjs} +1 -1
- package/dist/Model3DScene-LYEESYAI.mjs.br +0 -0
- package/dist/Model3DScene-LYEESYAI.mjs.gz +0 -0
- package/dist/{PowerPointViewer-Du7u4INi.d.ts → PowerPointViewer-Cf4YHjdF.d.ts} +2 -2
- package/dist/{PowerPointViewer-Du7u4INi.d.ts.map → PowerPointViewer-Cf4YHjdF.d.ts.map} +1 -1
- package/dist/{SurfaceChart3DScene-ODQY77SZ.js → SurfaceChart3DScene-ACPKCWLJ.js} +2 -2
- package/dist/SurfaceChart3DScene-ACPKCWLJ.js.br +0 -0
- package/dist/SurfaceChart3DScene-ACPKCWLJ.js.gz +0 -0
- package/dist/{SurfaceChart3DScene-DEQP5O3U.mjs → SurfaceChart3DScene-JR62SOYO.mjs} +1 -1
- package/dist/{SurfaceChart3DScene-DEQP5O3U.mjs.br → SurfaceChart3DScene-JR62SOYO.mjs.br} +0 -0
- package/dist/SurfaceChart3DScene-JR62SOYO.mjs.gz +0 -0
- package/dist/{audience-content-store-BvqKy7Hf.d.ts → audience-content-store-CyS0oP6t.d.ts} +2 -2
- package/dist/{audience-content-store-BvqKy7Hf.d.ts.map → audience-content-store-CyS0oP6t.d.ts.map} +1 -1
- package/dist/{chunk-5BXATG54.js → chunk-4LWGAVAP.js} +239 -293
- package/dist/chunk-4LWGAVAP.js.br +0 -0
- package/dist/chunk-4LWGAVAP.js.gz +0 -0
- package/dist/{chunk-FXJOTEPO.mjs → chunk-7XF6S4AM.mjs} +1 -1
- package/dist/chunk-7XF6S4AM.mjs.br +0 -0
- package/dist/chunk-7XF6S4AM.mjs.gz +0 -0
- package/dist/{chunk-TCGXGD6E.js → chunk-ASKYZ5ZY.js} +544 -426
- package/dist/chunk-ASKYZ5ZY.js.br +0 -0
- package/dist/chunk-ASKYZ5ZY.js.gz +0 -0
- package/dist/{chunk-MQHC5TXI.mjs → chunk-BZOL6FXF.mjs} +25 -80
- package/dist/chunk-BZOL6FXF.mjs.br +0 -0
- package/dist/chunk-BZOL6FXF.mjs.gz +0 -0
- package/dist/{chunk-K2QU73KB.mjs → chunk-GODW6RNR.mjs} +9801 -6455
- package/dist/chunk-GODW6RNR.mjs.br +0 -0
- package/dist/chunk-GODW6RNR.mjs.gz +0 -0
- package/dist/{chunk-NQJPPIVH.js → chunk-ICZDMFF2.js} +1444 -1131
- package/dist/chunk-ICZDMFF2.js.br +0 -0
- package/dist/chunk-ICZDMFF2.js.gz +0 -0
- package/dist/{chunk-ATOUVRRQ.js → chunk-MAVLV56S.js} +3 -3
- package/dist/chunk-MAVLV56S.js.br +0 -0
- package/dist/chunk-MAVLV56S.js.gz +0 -0
- package/dist/{chunk-422DF424.mjs → chunk-O7FTUUXP.mjs} +464 -151
- package/dist/chunk-O7FTUUXP.mjs.br +0 -0
- package/dist/chunk-O7FTUUXP.mjs.gz +0 -0
- package/dist/{chunk-ZA5JONCW.mjs → chunk-QUB5OSKY.mjs} +193 -75
- package/dist/chunk-QUB5OSKY.mjs.br +0 -0
- package/dist/chunk-QUB5OSKY.mjs.gz +0 -0
- package/dist/{chunk-AONFHTTJ.js → chunk-RTUGI4HQ.js} +27 -4
- package/dist/chunk-RTUGI4HQ.js.br +0 -0
- package/dist/chunk-RTUGI4HQ.js.gz +0 -0
- package/dist/{chunk-S64T7C4V.mjs → chunk-SNL6LBRX.mjs} +27 -4
- package/dist/chunk-SNL6LBRX.mjs.br +0 -0
- package/dist/{chunk-S64T7C4V.mjs.gz → chunk-SNL6LBRX.mjs.gz} +0 -0
- package/dist/{chunk-7JPLVECA.js → chunk-WVDM36ZM.js} +9838 -6458
- package/dist/chunk-WVDM36ZM.js.br +0 -0
- package/dist/chunk-WVDM36ZM.js.gz +0 -0
- package/dist/i18n.js +4 -4
- package/dist/i18n.js.br +0 -0
- package/dist/i18n.js.gz +0 -0
- package/dist/i18n.mjs +1 -1
- package/dist/i18n.mjs.br +0 -0
- package/dist/i18n.mjs.gz +0 -0
- package/dist/index.d.ts +497 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +65 -41
- package/dist/index.js.br +0 -0
- package/dist/index.js.gz +0 -0
- package/dist/index.mjs +6 -6
- package/dist/index.mjs.br +0 -0
- package/dist/index.mjs.gz +0 -0
- package/dist/internals.d.ts +543 -32
- package/dist/internals.d.ts.map +1 -1
- package/dist/internals.js +79 -79
- package/dist/internals.js.br +0 -0
- package/dist/internals.js.gz +0 -0
- package/dist/internals.mjs +4 -4
- 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/{types-DU35aAJK.d.ts → types-C_CTI-QE.d.ts} +3 -31
- package/dist/types-C_CTI-QE.d.ts.map +1 -0
- package/dist/{useViewerBuildingBlocks-C9-prKYB.d.ts → useViewerBuildingBlocks-DItilDbP.d.ts} +16 -3
- package/dist/useViewerBuildingBlocks-DItilDbP.d.ts.map +1 -0
- package/dist/viewer/index.d.ts +427 -39
- package/dist/viewer/index.js +27 -27
- package/dist/viewer/index.js.br +0 -0
- package/dist/viewer/index.js.gz +0 -0
- package/dist/viewer/index.mjs +6 -6
- package/dist/viewer/index.mjs.br +0 -0
- package/dist/viewer/index.mjs.gz +0 -0
- package/package.json +2 -2
- package/dist/AiChatPanel-HCHCVQN2.js.br +0 -0
- package/dist/AiChatPanel-HCHCVQN2.js.gz +0 -0
- package/dist/AiChatPanel-RZ4A7P4H.mjs.br +0 -0
- package/dist/AiChatPanel-RZ4A7P4H.mjs.gz +0 -0
- package/dist/Model3DScene-I7FR74AD.mjs.br +0 -0
- package/dist/Model3DScene-I7FR74AD.mjs.gz +0 -0
- package/dist/Model3DScene-LK7LSQNH.js.br +0 -0
- package/dist/Model3DScene-LK7LSQNH.js.gz +0 -0
- package/dist/SurfaceChart3DScene-DEQP5O3U.mjs.gz +0 -0
- package/dist/SurfaceChart3DScene-ODQY77SZ.js.br +0 -0
- package/dist/SurfaceChart3DScene-ODQY77SZ.js.gz +0 -0
- package/dist/chunk-422DF424.mjs.br +0 -0
- package/dist/chunk-422DF424.mjs.gz +0 -0
- package/dist/chunk-5BXATG54.js.br +0 -0
- package/dist/chunk-5BXATG54.js.gz +0 -0
- package/dist/chunk-7JPLVECA.js.br +0 -0
- package/dist/chunk-7JPLVECA.js.gz +0 -0
- package/dist/chunk-AONFHTTJ.js.br +0 -0
- package/dist/chunk-AONFHTTJ.js.gz +0 -0
- package/dist/chunk-ATOUVRRQ.js.br +0 -0
- package/dist/chunk-ATOUVRRQ.js.gz +0 -0
- package/dist/chunk-FXJOTEPO.mjs.br +0 -0
- package/dist/chunk-FXJOTEPO.mjs.gz +0 -0
- package/dist/chunk-K2QU73KB.mjs.br +0 -0
- package/dist/chunk-K2QU73KB.mjs.gz +0 -0
- package/dist/chunk-MQHC5TXI.mjs.br +0 -0
- package/dist/chunk-MQHC5TXI.mjs.gz +0 -0
- package/dist/chunk-NQJPPIVH.js.br +0 -0
- package/dist/chunk-NQJPPIVH.js.gz +0 -0
- package/dist/chunk-S64T7C4V.mjs.br +0 -0
- package/dist/chunk-TCGXGD6E.js.br +0 -0
- package/dist/chunk-TCGXGD6E.js.gz +0 -0
- package/dist/chunk-ZA5JONCW.mjs.br +0 -0
- package/dist/chunk-ZA5JONCW.mjs.gz +0 -0
- package/dist/types-DU35aAJK.d.ts.map +0 -1
- package/dist/useViewerBuildingBlocks-C9-prKYB.d.ts.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { cloneHistorySnapshot, MIN_ELEMENT_SIZE, ZOOM_TO_SELECTION_PADDING, DEFAULT_CANVAS_HEIGHT, DEFAULT_CANVAS_WIDTH, UNGROUPED_SECTION_ID, DEFAULT_TABLE_ROWS, DEFAULT_TABLE_COLUMNS, executeMediaCommand, buildPdfFromImageData, buildNotesPdf, EMU_PER_PX, GRID_SIZE, DEFAULT_TEXT_FONT_SIZE } from './chunk-
|
|
2
|
-
import { translationsEn } from './chunk-
|
|
3
|
-
import { TOOLBAR_TABS, computeVirtualRange, DEFAULT_VIRTUAL_OVERSCAN, createPresenceProjector, BROADCAST_THROTTLE_MS, createSyncGate, clearLocalAwareness, validateRoomId, createDepartureChannel, resolveTransportForServerUrl, isMixedContentBlocked, CONNECTION_TIMEOUT_MS, registerCollaborationTeardown, sanitizeColor, cloneTemplateElementsBySlideId, cloneSlide, createWheelStepBuffer, createViewerZoomStore, clampZoomScale, mapEditingWheel, PresentationAnimationController, PRESENTATION_HASH, PRESENTATION_NONCE_KEY, PRESENTATION_CHANNEL_NAME, swapPresentationWindows, PRESENTATION_MESSAGE_ORIGIN, clearAudienceContent, buildPresentationAudienceUrl, resolveAudienceScreenPlacement, placeAudienceWindow, storeAudienceContent, isPresentationSessionMessage, endAudienceDisplay, createPresentationKeyBuffer, acceptsPresentationInput, resolveAutoAdvanceDelayMs, hasShowSlideAfter, nextShowSlideIndex, previousShowSlideIndex, createPresenterShowGuard, attachPresentationVisibilityPause, buildMorphTransitionPlan, morphOptionToMode, buildMorphAnimationRules, findInSlides, applyFindReplacements, createCollaborationLivePatcher, publishLiveInlineText, PptxHandler, collectMediaElements, collectImagePaths, partitionTemplateElements, buildInitialGuides, EncryptedFileError, saveAutosaveSnapshot, updateMasterViewElement, isTemplateElementId, hasShapeProperties, hasTextProperties, getInlineEditorSelection, applyStyleToSelectedSegments, setPendingSelectionRestore, applyCaseTransformToSegments, transformTextCase, masterViewElements, replaceMasterViewElements, addSection, renameSection, deleteSection, moveSectionUp, moveSectionDown, moveSlidesToSection, normalizeColorsForCapture, preprocessCssForCapture, downloadBlob, sanitizeDownloadFilename, slideProgressPercent, slideStatusLabel, EXPORT_ASSEMBLING_PERCENT, EXPORT_DONE_PERCENT, isExportAbortError, recordProgressPercent, applyThemeToData, THEME_PRESETS, themeColorSchemesEqual, comparePresentation, applyAcceptSlide, applyAcceptAllSlides, collectUsedFonts, detectTouchDevice, detectOrientation, isMobileViewport, MOBILE_BREAKPOINT, TABLET_BREAKPOINT, describeFontEmbedding, mayLeaveSlideShow, stopAllPersistentAudio, remapTextToSegments, guidePxToEmu, buildSaveSlides, embeddedFontSaveOptions, saveDeckWithPassword, shouldLoopContinuously, applyRehearsalTimings, copyFormatFromElement, applyFormatToElement, mapEditorKey, isEditorTextInputTarget, createViewerOptionsStore, readSlidesFromYDoc, reconcileSlidesInYDoc, LOCAL_SYNC_ORIGIN, observeYDocSlides, shouldAutoFollowBroadcaster, createTouchGestureRecognizer, MAX_ZOOM_SCALE, MIN_ZOOM_SCALE, isKeyboardOpen, scopeLayoutOptionsToSlide, openPptxFile, readBackstageRecentFile, isActionHidden, canInteractWithElement, filterInteractableIds, buildElementClipboardPayload, generatePackageReadme, exportDeckJson, groupElements, generateElementId, makeCloneId, ungroupElements, alignElements, distributeElements, bringForward, sendBackward, bringToFront, sendToBack, newTableElement, createDefaultChartElement, readViewportMetrics, computeKeyboardInset, mergeShapes, mapPresentationKey, lastShowSlideIndex, firstShowSlideIndex, mapPresentationWheel, buildPrintDocument, buildOutlineHtml, buildSlidesHtml, buildNotesHtml, buildHandoutsHtml, createBlankSlide, makeSlideId, buildSlideTemplateSlide, templateSchemeFromTheme, buildThemeColorMap, reResolveSlideColors, computeEntranceAnimationDelay, createPresentationSessionId, resolveTransitionDurationMs, runPresentationAction, createPresenterTimer, createInitialPresentationSnapshot, mergePresentationSnapshot, resetPresenterTimer, presenterElapsed, stepPresenterZoom, togglePresenterTimer, canvasToJpegData, downloadDataUrl, pickSupportedMimeType, WEBM_MIME_CANDIDATES, fpsToFrameIntervalMs, segmentFrameCount, encodeGif, resolveShowSlideIndexes, groupSlidesBySection, masterViewPseudoSlide, hasCopyableFormat, createBackstagePresentation, buildFieldSubstitutionContext, cloneElementForPaste, computeScrollDelta, getPresetShapeClipPath, svgPathToPolygons, polygonsToSvgPath, rerouteConnectorsForMovedElements, applyReroutedConnectors, SvgExporter, buildPrintHtmlDocument, deleteTableColumn, rebuildTableStructureInRawXml, insertTableColumn, deleteTableRow, insertTableRow, updateCellTextStyleInRawXml, updateCellTextInRawXml, splitCell, updateMergeAttrsInRawXml, mergeCells, isPpactionUrl, parsePpactionUrl, safeOpenUrl, ACTION_BUTTON_PRESETS, elementActionToPptxAction, buildSmartArtPresetData, computeSnapToShape, publishLiveGeometry,
|
|
1
|
+
import { cloneHistorySnapshot, MIN_ELEMENT_SIZE, ZOOM_TO_SELECTION_PADDING, DEFAULT_CANVAS_HEIGHT, DEFAULT_CANVAS_WIDTH, UNGROUPED_SECTION_ID, DEFAULT_SECTION_GROUP_ID, DEFAULT_TABLE_ROWS, DEFAULT_TABLE_COLUMNS, executeMediaCommand, buildPdfFromImageData, buildNotesPdf, EMU_PER_PX, GRID_SIZE, DEFAULT_TEXT_FONT_SIZE } from './chunk-BZOL6FXF.mjs';
|
|
2
|
+
import { translationsEn } from './chunk-SNL6LBRX.mjs';
|
|
3
|
+
import { TOOLBAR_TABS, computeVirtualRange, DEFAULT_VIRTUAL_OVERSCAN, createPresenceProjector, BROADCAST_THROTTLE_MS, createSyncGate, clearLocalAwareness, validateRoomId, createDepartureChannel, resolveTransportForServerUrl, isMixedContentBlocked, CONNECTION_TIMEOUT_MS, registerCollaborationTeardown, sanitizeColor, cloneTemplateElementsBySlideId, cloneSlide, createWheelStepBuffer, createViewerZoomStore, clampZoomScale, mapEditingWheel, PresentationAnimationController, PRESENTATION_HASH, PRESENTATION_NONCE_KEY, PRESENTATION_CHANNEL_NAME, swapPresentationWindows, PRESENTATION_MESSAGE_ORIGIN, clearAudienceContent, buildPresentationAudienceUrl, resolveAudienceScreenPlacement, placeAudienceWindow, storeAudienceContent, isPresentationSessionMessage, endAudienceDisplay, createPresentationKeyBuffer, acceptsPresentationInput, resolveAutoAdvanceDelayMs, hasShowSlideAfter, nextShowSlideIndex, previousShowSlideIndex, createPresenterShowGuard, attachPresentationVisibilityPause, buildMorphTransitionPlan, morphOptionToMode, buildMorphAnimationRules, findInSlides, applyFindReplacements, createCollaborationLivePatcher, publishLiveInlineText, PptxHandler, collectMediaElements, collectImagePaths, partitionTemplateElements, resolveAuthoredCustomShowId, buildInitialGuides, EncryptedFileError, shouldWriteAutosaveSnapshot, saveAutosaveSnapshot, autosaveSnapshotMark, updateMasterViewElement, isTemplateElementId, hasShapeProperties, hasTextProperties, getInlineEditorSelection, applyStyleToSelectedSegments, setPendingSelectionRestore, applyCaseTransformToSegments, transformTextCase, masterViewElements, replaceMasterViewElements, addSection, renameSection, deleteSection, moveSectionUp, moveSectionDown, moveSlidesToSection, normalizeColorsForCapture, preprocessCssForCapture, downloadBlob, sanitizeDownloadFilename, slideProgressPercent, slideStatusLabel, EXPORT_ASSEMBLING_PERCENT, EXPORT_DONE_PERCENT, isExportAbortError, recordProgressPercent, applyThemeToData, THEME_PRESETS, themeColorSchemesEqual, comparePresentation, applyAcceptSlide, applyAcceptAllSlides, collectUsedFonts, detectTouchDevice, detectOrientation, isMobileViewport, MOBILE_BREAKPOINT, TABLET_BREAKPOINT, describeFontEmbedding, mayLeaveSlideShow, stopAllPersistentAudio, remapTextToSegments, guidePxToEmu, buildSaveSlides, embeddedFontSaveOptions, resolveSlideSizeSelection, saveDeckWithPassword, shouldLoopContinuously, applyRehearsalTimings, copyFormatFromElement, applyFormatToElement, mapEditorKey, isEditorTextInputTarget, createViewerOptionsStore, readSlidesFromYDoc, reconcileSlidesInYDoc, LOCAL_SYNC_ORIGIN, observeYDocSlides, shouldAutoFollowBroadcaster, createTouchGestureRecognizer, MAX_ZOOM_SCALE, MIN_ZOOM_SCALE, isKeyboardOpen, scopeLayoutOptionsToSlide, openPptxFile, readBackstageRecentFile, isActionHidden, canInteractWithElement, filterInteractableIds, beginShapeAdjustment, buildElementClipboardPayload, savedPresentationFileName, generatePackageReadme, presentationBaseName, exportDeckJson, groupElements, generateElementId, makeCloneId, ungroupElements, alignElements, distributeElements, bringForward, sendBackward, bringToFront, sendToBack, newTableElement, createDefaultChartElement, readViewportMetrics, computeKeyboardInset, mergeShapes, mapPresentationKey, lastShowSlideIndex, firstShowSlideIndex, mapPresentationWheel, buildPrintDocument, buildOutlineHtml, buildSlidesHtml, buildNotesHtml, buildHandoutsHtml, createBlankSlide, makeSlideId, buildSlideTemplateSlide, templateSchemeFromTheme, buildThemeColorMap, reResolveSlideColors, computeEntranceAnimationDelay, createPresentationSessionId, resolveTransitionDurationMs, runPresentationAction, createPresenterTimer, createInitialPresentationSnapshot, mergePresentationSnapshot, resetPresenterTimer, presenterElapsed, stepPresenterZoom, togglePresenterTimer, canvasToJpegData, downloadDataUrl, pickSupportedMimeType, WEBM_MIME_CANDIDATES, fpsToFrameIntervalMs, segmentFrameCount, encodeGif, resolveShowSlideIndexes, groupSlidesBySection, masterViewPseudoSlide, hasCopyableFormat, createBackstagePresentation, buildFieldSubstitutionContext, cloneElementForPaste, computeScrollDelta, getPresetShapeClipPath, svgPathToPolygons, polygonsToSvgPath, rerouteConnectorsForMovedElements, applyReroutedConnectors, SvgExporter, buildPrintHtmlDocument, deleteTableColumn, rebuildTableStructureInRawXml, insertTableColumn, deleteTableRow, insertTableRow, updateCellTextStyleInRawXml, updateCellTextInRawXml, splitCell, updateMergeAttrsInRawXml, mergeCells, isPpactionUrl, parsePpactionUrl, safeOpenUrl, ACTION_BUTTON_PRESETS, elementActionToPptxAction, buildSmartArtPresetData, computeSnapToShape, publishLiveGeometry, getDraggedShapeAdjustments, computeMarqueeHitIds, mergeAdditiveSelection, applyResize, snapBoxToGrid, applyMotionPathPreset } from './chunk-GODW6RNR.mjs';
|
|
4
4
|
import { useRef, useState, useEffect, useCallback, useMemo, useLayoutEffect, useSyncExternalStore, useImperativeHandle } from 'react';
|
|
5
5
|
import JSZip from 'jszip';
|
|
6
6
|
import { useTranslation } from 'react-i18next';
|
|
@@ -1676,6 +1676,7 @@ function usePresentationKeyboard(input) {
|
|
|
1676
1676
|
onToggleInkMarkup,
|
|
1677
1677
|
onToggleToolbar,
|
|
1678
1678
|
onShowAllSlides,
|
|
1679
|
+
onToggleSubtitles,
|
|
1679
1680
|
onToggleBlackScreen,
|
|
1680
1681
|
onToggleWhiteScreen,
|
|
1681
1682
|
rehearsing,
|
|
@@ -1741,6 +1742,9 @@ function usePresentationKeyboard(input) {
|
|
|
1741
1742
|
case "showAllSlides":
|
|
1742
1743
|
onShowAllSlides?.();
|
|
1743
1744
|
return;
|
|
1745
|
+
case "toggleSubtitles":
|
|
1746
|
+
onToggleSubtitles?.();
|
|
1747
|
+
return;
|
|
1744
1748
|
case "toggleBlackScreen":
|
|
1745
1749
|
onToggleBlackScreen?.();
|
|
1746
1750
|
return;
|
|
@@ -1780,6 +1784,7 @@ function usePresentationKeyboard(input) {
|
|
|
1780
1784
|
onToggleInkMarkup,
|
|
1781
1785
|
onToggleToolbar,
|
|
1782
1786
|
onShowAllSlides,
|
|
1787
|
+
onToggleSubtitles,
|
|
1783
1788
|
onToggleBlackScreen,
|
|
1784
1789
|
onToggleWhiteScreen,
|
|
1785
1790
|
rehearsing,
|
|
@@ -2220,6 +2225,7 @@ function usePresentationMode(input) {
|
|
|
2220
2225
|
onEraseAnnotations,
|
|
2221
2226
|
onToggleInkMarkup,
|
|
2222
2227
|
onToggleToolbar,
|
|
2228
|
+
onToggleSubtitles,
|
|
2223
2229
|
onSaveRehearsalTimings,
|
|
2224
2230
|
loopContinuously,
|
|
2225
2231
|
showWithAnimation,
|
|
@@ -2427,6 +2433,7 @@ function usePresentationMode(input) {
|
|
|
2427
2433
|
onToggleInkMarkup,
|
|
2428
2434
|
onToggleToolbar,
|
|
2429
2435
|
onShowAllSlides: openAllSlides,
|
|
2436
|
+
onToggleSubtitles,
|
|
2430
2437
|
onToggleBlackScreen: () => presenterConsole.setBlackout(
|
|
2431
2438
|
presenterConsole.snapshot.blackout === "black" ? "none" : "black"
|
|
2432
2439
|
),
|
|
@@ -2909,13 +2916,15 @@ function useFindReplace({
|
|
|
2909
2916
|
}, [findResults, applyReplacements, performFind]);
|
|
2910
2917
|
useEffect(() => {
|
|
2911
2918
|
const handler = (event) => {
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2919
|
+
const { action } = mapEditorKey(event, {
|
|
2920
|
+
canEdit: mode === "edit",
|
|
2921
|
+
isTextInputTarget: isEditorTextInputTarget(event.target)
|
|
2922
|
+
});
|
|
2923
|
+
if (action !== "find") {
|
|
2924
|
+
return;
|
|
2918
2925
|
}
|
|
2926
|
+
event.preventDefault();
|
|
2927
|
+
setFindReplaceOpen((prev) => !prev);
|
|
2919
2928
|
};
|
|
2920
2929
|
window.addEventListener("keydown", handler);
|
|
2921
2930
|
return () => window.removeEventListener("keydown", handler);
|
|
@@ -3355,9 +3364,28 @@ function useDerivedElementState(input) {
|
|
|
3355
3364
|
}
|
|
3356
3365
|
return templateElementsBySlideId[activeSlide.id] ?? [];
|
|
3357
3366
|
}, [activeSlide, templateElementsBySlideId]);
|
|
3367
|
+
const activeMaster = slideMasters[activeMasterIndex];
|
|
3368
|
+
const activeLayout = useMemo(
|
|
3369
|
+
() => resolveActiveLayout(activeMaster, activeLayoutIndex),
|
|
3370
|
+
[activeMaster, activeLayoutIndex]
|
|
3371
|
+
);
|
|
3372
|
+
const masterViewElements2 = useMemo(
|
|
3373
|
+
() => computeMasterViewElements(activeMaster, activeLayout),
|
|
3374
|
+
[activeMaster, activeLayout]
|
|
3375
|
+
);
|
|
3376
|
+
const notesMasterElements = useMemo(() => notesMaster?.elements ?? [], [notesMaster]);
|
|
3377
|
+
const handoutMasterElements = useMemo(() => handoutMaster?.elements ?? [], [handoutMaster]);
|
|
3358
3378
|
const elementLookup = useMemo(
|
|
3359
|
-
() => buildElementLookup(
|
|
3360
|
-
|
|
3379
|
+
() => buildElementLookup(
|
|
3380
|
+
[
|
|
3381
|
+
...templateElements,
|
|
3382
|
+
...masterViewElements2,
|
|
3383
|
+
...notesMasterElements,
|
|
3384
|
+
...handoutMasterElements
|
|
3385
|
+
],
|
|
3386
|
+
activeSlide?.elements ?? []
|
|
3387
|
+
),
|
|
3388
|
+
[activeSlide, templateElements, masterViewElements2, notesMasterElements, handoutMasterElements]
|
|
3361
3389
|
);
|
|
3362
3390
|
const selectedElement = useMemo(() => {
|
|
3363
3391
|
if (!selectedElementId) {
|
|
@@ -3374,17 +3402,6 @@ function useDerivedElementState(input) {
|
|
|
3374
3402
|
() => effectiveSelectedIds.map((id) => elementLookup.get(id)).filter(Boolean),
|
|
3375
3403
|
[effectiveSelectedIds, elementLookup]
|
|
3376
3404
|
);
|
|
3377
|
-
const activeMaster = slideMasters[activeMasterIndex];
|
|
3378
|
-
const activeLayout = useMemo(
|
|
3379
|
-
() => resolveActiveLayout(activeMaster, activeLayoutIndex),
|
|
3380
|
-
[activeMaster, activeLayoutIndex]
|
|
3381
|
-
);
|
|
3382
|
-
const masterViewElements2 = useMemo(
|
|
3383
|
-
() => computeMasterViewElements(activeMaster, activeLayout),
|
|
3384
|
-
[activeMaster, activeLayout]
|
|
3385
|
-
);
|
|
3386
|
-
const notesMasterElements = useMemo(() => notesMaster?.elements ?? [], [notesMaster]);
|
|
3387
|
-
const handoutMasterElements = useMemo(() => handoutMaster?.elements ?? [], [handoutMaster]);
|
|
3388
3405
|
return {
|
|
3389
3406
|
activeSlide,
|
|
3390
3407
|
templateElements,
|
|
@@ -3423,6 +3440,7 @@ function useViewerCoreState(_input) {
|
|
|
3423
3440
|
width: DEFAULT_CANVAS_WIDTH,
|
|
3424
3441
|
height: DEFAULT_CANVAS_HEIGHT
|
|
3425
3442
|
});
|
|
3443
|
+
const [slideSizeEmu, setSlideSizeEmu] = useState();
|
|
3426
3444
|
const [activeSlideIndex, setActiveSlideIndex] = useState(0);
|
|
3427
3445
|
const [selectedElementId, setSelectedElementId] = useState(null);
|
|
3428
3446
|
const [selectedElementIds, setSelectedElementIds] = useState([]);
|
|
@@ -3521,6 +3539,8 @@ function useViewerCoreState(_input) {
|
|
|
3521
3539
|
setTemplateElementsBySlideId,
|
|
3522
3540
|
canvasSize,
|
|
3523
3541
|
setCanvasSize,
|
|
3542
|
+
slideSizeEmu,
|
|
3543
|
+
setSlideSizeEmu,
|
|
3524
3544
|
activeSlideIndex,
|
|
3525
3545
|
setActiveSlideIndex,
|
|
3526
3546
|
selectedElementId,
|
|
@@ -3725,6 +3745,7 @@ function useLoadContent({
|
|
|
3725
3745
|
setTemplateElementsBySlideId,
|
|
3726
3746
|
mediaDataUrls,
|
|
3727
3747
|
setCanvasSize,
|
|
3748
|
+
setSlideSizeEmu,
|
|
3728
3749
|
setHeaderFooter,
|
|
3729
3750
|
setLayoutOptions,
|
|
3730
3751
|
setSlideMasters,
|
|
@@ -3732,6 +3753,7 @@ function useLoadContent({
|
|
|
3732
3753
|
setTableStyleMap,
|
|
3733
3754
|
setThemeOptions,
|
|
3734
3755
|
setCustomShows,
|
|
3756
|
+
setActiveCustomShowId,
|
|
3735
3757
|
setSections,
|
|
3736
3758
|
setPresentationProperties,
|
|
3737
3759
|
setNotesMaster,
|
|
@@ -3891,6 +3913,13 @@ function useLoadContent({
|
|
|
3891
3913
|
width: parsed.width ?? DEFAULT_CANVAS_WIDTH,
|
|
3892
3914
|
height: parsed.height ?? DEFAULT_CANVAS_HEIGHT
|
|
3893
3915
|
});
|
|
3916
|
+
setSlideSizeEmu(
|
|
3917
|
+
typeof parsed.widthEmu === "number" && typeof parsed.heightEmu === "number" && parsed.widthEmu > 0 && parsed.heightEmu > 0 ? {
|
|
3918
|
+
widthEmu: parsed.widthEmu,
|
|
3919
|
+
heightEmu: parsed.heightEmu,
|
|
3920
|
+
type: parsed.slideSizeType ?? ""
|
|
3921
|
+
} : void 0
|
|
3922
|
+
);
|
|
3894
3923
|
setHeaderFooter(parsed.headerFooter ?? {});
|
|
3895
3924
|
setLayoutOptions(parsed.layoutOptions ?? []);
|
|
3896
3925
|
setSlideMasters(parsed.slideMasters ?? []);
|
|
@@ -3898,6 +3927,9 @@ function useLoadContent({
|
|
|
3898
3927
|
setTableStyleMap(parsed.tableStyleMap);
|
|
3899
3928
|
setThemeOptions(parsed.themeOptions ?? []);
|
|
3900
3929
|
setCustomShows(parsed.customShows ?? []);
|
|
3930
|
+
setActiveCustomShowId(
|
|
3931
|
+
resolveAuthoredCustomShowId(parsed.presentationProperties, parsed.customShows) ?? null
|
|
3932
|
+
);
|
|
3901
3933
|
setSections(parsed.sections ?? []);
|
|
3902
3934
|
setPresentationProperties(parsed.presentationProperties ?? {});
|
|
3903
3935
|
setNotesMaster(parsed.notesMaster);
|
|
@@ -3966,7 +3998,8 @@ function useAutosave(input) {
|
|
|
3966
3998
|
filePath,
|
|
3967
3999
|
serializeSlides,
|
|
3968
4000
|
intervalSeconds = DEFAULT_AUTOSAVE_INTERVAL_SECONDS,
|
|
3969
|
-
enabled = true
|
|
4001
|
+
enabled = true,
|
|
4002
|
+
getChangeSources
|
|
3970
4003
|
} = input;
|
|
3971
4004
|
const [autosaveStatus, setAutosaveStatus] = useState({
|
|
3972
4005
|
state: "idle"
|
|
@@ -3975,6 +4008,8 @@ function useAutosave(input) {
|
|
|
3975
4008
|
const filePathRef = useRef(filePath);
|
|
3976
4009
|
const serializeRef = useRef(serializeSlides);
|
|
3977
4010
|
const isSavingRef = useRef(false);
|
|
4011
|
+
const changeSourcesRef = useRef(getChangeSources);
|
|
4012
|
+
const lastSnapshotRef = useRef(void 0);
|
|
3978
4013
|
useEffect(() => {
|
|
3979
4014
|
isDirtyRef.current = isDirty;
|
|
3980
4015
|
}, [isDirty]);
|
|
@@ -3984,14 +4019,22 @@ function useAutosave(input) {
|
|
|
3984
4019
|
useEffect(() => {
|
|
3985
4020
|
serializeRef.current = serializeSlides;
|
|
3986
4021
|
}, [serializeSlides]);
|
|
3987
|
-
|
|
3988
|
-
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
|
|
4022
|
+
useEffect(() => {
|
|
4023
|
+
changeSourcesRef.current = getChangeSources;
|
|
4024
|
+
}, [getChangeSources]);
|
|
4025
|
+
const doAutosave = useCallback(async (options) => {
|
|
4026
|
+
const path = filePathRef.current;
|
|
4027
|
+
if (!path) {
|
|
4028
|
+
return;
|
|
4029
|
+
}
|
|
4030
|
+
const sources = changeSourcesRef.current?.() ?? [];
|
|
4031
|
+
if (!shouldWriteAutosaveSnapshot({
|
|
4032
|
+
filePath: path,
|
|
4033
|
+
isDirty: isDirtyRef.current,
|
|
4034
|
+
saving: isSavingRef.current,
|
|
4035
|
+
sources: options?.polled === true ? sources : [],
|
|
4036
|
+
lastSnapshot: lastSnapshotRef.current
|
|
4037
|
+
})) {
|
|
3995
4038
|
return;
|
|
3996
4039
|
}
|
|
3997
4040
|
isSavingRef.current = true;
|
|
@@ -4003,7 +4046,8 @@ function useAutosave(input) {
|
|
|
4003
4046
|
isSavingRef.current = false;
|
|
4004
4047
|
return;
|
|
4005
4048
|
}
|
|
4006
|
-
await saveAutosaveSnapshot(
|
|
4049
|
+
await saveAutosaveSnapshot(path, data);
|
|
4050
|
+
lastSnapshotRef.current = autosaveSnapshotMark(path, sources);
|
|
4007
4051
|
setAutosaveStatus({ state: "saved", timestamp: Date.now() });
|
|
4008
4052
|
} catch (err) {
|
|
4009
4053
|
setAutosaveStatus({
|
|
@@ -4029,13 +4073,13 @@ function useAutosave(input) {
|
|
|
4029
4073
|
setAutosaveStatus((prev) => prev.state === "disabled" ? { state: "idle" } : prev);
|
|
4030
4074
|
const ms = computeAutosaveIntervalMs(intervalSeconds);
|
|
4031
4075
|
const id = setInterval(() => {
|
|
4032
|
-
void doAutosave();
|
|
4076
|
+
void doAutosave({ polled: true });
|
|
4033
4077
|
}, ms);
|
|
4034
4078
|
return () => clearInterval(id);
|
|
4035
4079
|
}, [enabled, filePath, intervalSeconds, doAutosave]);
|
|
4036
4080
|
return {
|
|
4037
4081
|
autosaveStatus,
|
|
4038
|
-
triggerAutosave: doAutosave
|
|
4082
|
+
triggerAutosave: () => doAutosave()
|
|
4039
4083
|
};
|
|
4040
4084
|
}
|
|
4041
4085
|
function useElementOperations(input) {
|
|
@@ -4327,13 +4371,23 @@ function useSectionOperations(input) {
|
|
|
4327
4371
|
},
|
|
4328
4372
|
[sections, slides, setSlides, setSections, markDirty]
|
|
4329
4373
|
);
|
|
4374
|
+
const toggleSectionCollapse = useCallback(
|
|
4375
|
+
(sectionId) => {
|
|
4376
|
+
setSections(
|
|
4377
|
+
(prev) => prev.map((sec) => sec.id === sectionId ? { ...sec, collapsed: !sec.collapsed } : sec)
|
|
4378
|
+
);
|
|
4379
|
+
markDirty();
|
|
4380
|
+
},
|
|
4381
|
+
[setSections, markDirty]
|
|
4382
|
+
);
|
|
4330
4383
|
return {
|
|
4331
4384
|
addSection: addSection2,
|
|
4332
4385
|
renameSection: renameSection2,
|
|
4333
4386
|
deleteSection: deleteSection2,
|
|
4334
4387
|
moveSectionUp: moveSectionUp2,
|
|
4335
4388
|
moveSectionDown: moveSectionDown2,
|
|
4336
|
-
moveSlidesToSection: moveSlidesToSection2
|
|
4389
|
+
moveSlidesToSection: moveSlidesToSection2,
|
|
4390
|
+
toggleSectionCollapse
|
|
4337
4391
|
};
|
|
4338
4392
|
}
|
|
4339
4393
|
|
|
@@ -4551,13 +4605,14 @@ function processResizeMove(e, rs, editorScale, snapToGrid, gridSpacingPx, live)
|
|
|
4551
4605
|
}
|
|
4552
4606
|
function processAdjustmentMove(e, adj, editorScale, updateElementById) {
|
|
4553
4607
|
const dx = (e.clientX - adj.startClientX) / editorScale;
|
|
4554
|
-
const
|
|
4555
|
-
|
|
4608
|
+
const dy = (e.clientY - adj.startClientY) / editorScale;
|
|
4609
|
+
const adjustments = getDraggedShapeAdjustments(adj, dx, dy);
|
|
4610
|
+
if (!adj.moved && Math.hypot(dx, dy) > 2) {
|
|
4556
4611
|
adj.moved = true;
|
|
4557
4612
|
}
|
|
4558
4613
|
if (adj.moved) {
|
|
4559
4614
|
updateElementById(adj.elementId, {
|
|
4560
|
-
shapeAdjustments:
|
|
4615
|
+
shapeAdjustments: adjustments
|
|
4561
4616
|
});
|
|
4562
4617
|
}
|
|
4563
4618
|
}
|
|
@@ -5034,33 +5089,18 @@ function useCanvasInteractions(input) {
|
|
|
5034
5089
|
const handleFormatText = (updates) => {
|
|
5035
5090
|
ops.updateSelectedTextStyle(updates);
|
|
5036
5091
|
};
|
|
5037
|
-
const handleAdjustmentPointerDown = (elementId, e) => {
|
|
5092
|
+
const handleAdjustmentPointerDown = (elementId, e, descriptor) => {
|
|
5038
5093
|
e.stopPropagation();
|
|
5039
5094
|
const el = elementLookup.get(elementId);
|
|
5040
|
-
if (!el || !(
|
|
5041
|
-
return;
|
|
5042
|
-
}
|
|
5043
|
-
if (!canInteractWithElement(el, "adjustHandle")) {
|
|
5095
|
+
if (!el || !canInteractWithElement(el, "adjustHandle")) {
|
|
5044
5096
|
return;
|
|
5045
5097
|
}
|
|
5046
|
-
|
|
5047
|
-
el
|
|
5098
|
+
shapeAdjustmentDragStateRef.current = beginShapeAdjustment(
|
|
5099
|
+
el,
|
|
5100
|
+
descriptor,
|
|
5101
|
+
e.clientX,
|
|
5102
|
+
e.clientY
|
|
5048
5103
|
);
|
|
5049
|
-
if (!adjEntries.length) {
|
|
5050
|
-
return;
|
|
5051
|
-
}
|
|
5052
|
-
const [key, value] = adjEntries[0];
|
|
5053
|
-
shapeAdjustmentDragStateRef.current = {
|
|
5054
|
-
elementId,
|
|
5055
|
-
key,
|
|
5056
|
-
shapeType: el.shapeType ?? "rect",
|
|
5057
|
-
startClientX: e.clientX,
|
|
5058
|
-
startClientY: e.clientY,
|
|
5059
|
-
startAdjustment: value,
|
|
5060
|
-
startWidth: el.width,
|
|
5061
|
-
startHeight: el.height,
|
|
5062
|
-
moved: false
|
|
5063
|
-
};
|
|
5064
5104
|
};
|
|
5065
5105
|
return {
|
|
5066
5106
|
handleElementClick,
|
|
@@ -6975,12 +7015,14 @@ function useExportSaveAs(input) {
|
|
|
6975
7015
|
appProperties,
|
|
6976
7016
|
customProperties,
|
|
6977
7017
|
tagCollections,
|
|
7018
|
+
slideMasters,
|
|
6978
7019
|
notesMaster,
|
|
6979
7020
|
handoutMaster,
|
|
6980
7021
|
guides,
|
|
6981
7022
|
activeSlideIndexForGuides,
|
|
6982
7023
|
theme,
|
|
6983
7024
|
canvasSize,
|
|
7025
|
+
slideSizeEmu,
|
|
6984
7026
|
modalControls,
|
|
6985
7027
|
password
|
|
6986
7028
|
} = input;
|
|
@@ -7004,7 +7046,7 @@ function useExportSaveAs(input) {
|
|
|
7004
7046
|
setExportProgress(10);
|
|
7005
7047
|
setExportStatusMessage("Adding presentation...");
|
|
7006
7048
|
const pptxData = await serializeSlides();
|
|
7007
|
-
const pptxFilename = filePath
|
|
7049
|
+
const pptxFilename = savedPresentationFileName(filePath);
|
|
7008
7050
|
if (pptxData) {
|
|
7009
7051
|
pkgFolder.file(pptxFilename, pptxData);
|
|
7010
7052
|
}
|
|
@@ -7020,8 +7062,7 @@ function useExportSaveAs(input) {
|
|
|
7020
7062
|
const zipBlob = await zip.generateAsync({ type: "blob" });
|
|
7021
7063
|
setExportProgress(95);
|
|
7022
7064
|
setExportStatusMessage("Downloading...");
|
|
7023
|
-
|
|
7024
|
-
downloadBlob(zipBlob, `${baseName}-package.zip`);
|
|
7065
|
+
downloadBlob(zipBlob, `${presentationBaseName(pptxFilename)}-package.zip`);
|
|
7025
7066
|
setExportProgress(100);
|
|
7026
7067
|
} catch (err) {
|
|
7027
7068
|
if (err.name !== "AbortError") {
|
|
@@ -7037,16 +7078,15 @@ function useExportSaveAs(input) {
|
|
|
7037
7078
|
if (!handler) {
|
|
7038
7079
|
return;
|
|
7039
7080
|
}
|
|
7040
|
-
const
|
|
7041
|
-
const baseName = filePath ? filePath.replace(/\\/gu, "/").split("/").pop()?.replace(/\.[^.]+$/u, "") ?? "presentation" : "presentation";
|
|
7081
|
+
const downloadName = savedPresentationFileName(filePath, format);
|
|
7042
7082
|
try {
|
|
7043
7083
|
const data = await buildSaveAsData(handler, format);
|
|
7044
7084
|
const blob = new Blob([data], {
|
|
7045
7085
|
type: "application/vnd.openxmlformats-officedocument.presentationml.presentation"
|
|
7046
7086
|
});
|
|
7047
|
-
downloadBlob(blob,
|
|
7087
|
+
downloadBlob(blob, downloadName);
|
|
7048
7088
|
} catch (err) {
|
|
7049
|
-
console.error(`[PowerPointViewer] Save as .${
|
|
7089
|
+
console.error(`[PowerPointViewer] Save as .${format} failed:`, err);
|
|
7050
7090
|
}
|
|
7051
7091
|
};
|
|
7052
7092
|
const buildSaveAsData = async (handler, format) => {
|
|
@@ -7066,6 +7106,9 @@ function useExportSaveAs(input) {
|
|
|
7066
7106
|
});
|
|
7067
7107
|
const slidesToSave = buildSaveSlides(slidesWithGuides, templateElementsBySlideId);
|
|
7068
7108
|
const saveOptions = {
|
|
7109
|
+
// Save As shares Save's slide-size decision; leaving it out here is how
|
|
7110
|
+
// a preset picked in the inspector reached one save path and not the other.
|
|
7111
|
+
slideSize: resolveSlideSizeSelection({ current: slideSizeEmu, canvas: canvasSize }).size,
|
|
7069
7112
|
headerFooter,
|
|
7070
7113
|
presentationProperties,
|
|
7071
7114
|
customShows: customShows.length > 0 ? customShows : void 0,
|
|
@@ -7074,6 +7117,7 @@ function useExportSaveAs(input) {
|
|
|
7074
7117
|
appProperties: appProperties ?? void 0,
|
|
7075
7118
|
customProperties: customProperties.length > 0 ? customProperties : void 0,
|
|
7076
7119
|
tags: tagCollections.length > 0 ? tagCollections : void 0,
|
|
7120
|
+
slideMasters,
|
|
7077
7121
|
notesMaster,
|
|
7078
7122
|
handoutMaster,
|
|
7079
7123
|
outputFormat: format
|
|
@@ -7082,12 +7126,14 @@ function useExportSaveAs(input) {
|
|
|
7082
7126
|
};
|
|
7083
7127
|
const handleExportJson = () => {
|
|
7084
7128
|
const sourceName = filePath ? filePath.replace(/\\/gu, "/").split("/").pop() : void 0;
|
|
7129
|
+
const slideSize = resolveSlideSizeSelection({ current: slideSizeEmu, canvas: canvasSize }).size;
|
|
7085
7130
|
const data = {
|
|
7086
7131
|
slides: buildSaveSlides(slides, templateElementsBySlideId),
|
|
7087
7132
|
width: canvasSize.width,
|
|
7088
7133
|
height: canvasSize.height,
|
|
7089
|
-
widthEmu:
|
|
7090
|
-
heightEmu:
|
|
7134
|
+
widthEmu: slideSize.widthEmu,
|
|
7135
|
+
heightEmu: slideSize.heightEmu,
|
|
7136
|
+
slideSizeType: slideSize.type === "" ? void 0 : slideSize.type,
|
|
7091
7137
|
theme,
|
|
7092
7138
|
headerFooter,
|
|
7093
7139
|
presentationProperties,
|
|
@@ -7164,12 +7210,14 @@ function useExportHandlers(input) {
|
|
|
7164
7210
|
appProperties,
|
|
7165
7211
|
customProperties,
|
|
7166
7212
|
tagCollections,
|
|
7213
|
+
slideMasters,
|
|
7167
7214
|
notesMaster,
|
|
7168
7215
|
handoutMaster,
|
|
7169
7216
|
guides,
|
|
7170
7217
|
activeSlideIndexForGuides,
|
|
7171
7218
|
theme,
|
|
7172
7219
|
canvasSize,
|
|
7220
|
+
slideSizeEmu,
|
|
7173
7221
|
password
|
|
7174
7222
|
} = input;
|
|
7175
7223
|
const [exportModalOpen, setExportModalOpen] = useState(false);
|
|
@@ -7205,12 +7253,14 @@ function useExportHandlers(input) {
|
|
|
7205
7253
|
appProperties,
|
|
7206
7254
|
customProperties,
|
|
7207
7255
|
tagCollections,
|
|
7256
|
+
slideMasters,
|
|
7208
7257
|
notesMaster,
|
|
7209
7258
|
handoutMaster,
|
|
7210
7259
|
guides,
|
|
7211
7260
|
activeSlideIndexForGuides,
|
|
7212
7261
|
theme,
|
|
7213
7262
|
canvasSize,
|
|
7263
|
+
slideSizeEmu,
|
|
7214
7264
|
modalControls,
|
|
7215
7265
|
password
|
|
7216
7266
|
});
|
|
@@ -8380,7 +8430,7 @@ function computeVisibleSlideIndexes(slides, activeCustomShowId, customShows) {
|
|
|
8380
8430
|
}
|
|
8381
8431
|
function computeSlideSectionGroups(slides, sections) {
|
|
8382
8432
|
return groupSlidesBySection(sections, slides).map((group) => ({
|
|
8383
|
-
id: group.section?.id ?? (sections.length > 0 ? UNGROUPED_SECTION_ID :
|
|
8433
|
+
id: group.section?.id ?? (sections.length > 0 ? UNGROUPED_SECTION_ID : DEFAULT_SECTION_GROUP_ID),
|
|
8384
8434
|
label: group.section?.name ?? (sections.length > 0 ? "Ungrouped Slides" : "Slides"),
|
|
8385
8435
|
slideIndexes: group.slideIndexes,
|
|
8386
8436
|
...group.section?.color !== void 0 ? { color: group.section.color } : {},
|
|
@@ -8423,7 +8473,7 @@ function useDerivedSlideState(input) {
|
|
|
8423
8473
|
if (group.id === UNGROUPED_SECTION_ID && group.label === "Ungrouped Slides") {
|
|
8424
8474
|
return { ...group, label: t("pptx.slides.ungroupedSlides") };
|
|
8425
8475
|
}
|
|
8426
|
-
if (group.id ===
|
|
8476
|
+
if (group.id === DEFAULT_SECTION_GROUP_ID && group.label === "Slides") {
|
|
8427
8477
|
return { ...group, label: t("pptx.sections.slides") };
|
|
8428
8478
|
}
|
|
8429
8479
|
return group;
|
|
@@ -8577,6 +8627,8 @@ function useSerialize(input) {
|
|
|
8577
8627
|
slides,
|
|
8578
8628
|
templateElementsBySlideId,
|
|
8579
8629
|
activeSlideIndex,
|
|
8630
|
+
canvasSize,
|
|
8631
|
+
slideSizeEmu,
|
|
8580
8632
|
guides,
|
|
8581
8633
|
headerFooter,
|
|
8582
8634
|
presentationProperties,
|
|
@@ -8586,6 +8638,7 @@ function useSerialize(input) {
|
|
|
8586
8638
|
appProperties,
|
|
8587
8639
|
customProperties,
|
|
8588
8640
|
tagCollections,
|
|
8641
|
+
slideMasters,
|
|
8589
8642
|
notesMaster,
|
|
8590
8643
|
handoutMaster,
|
|
8591
8644
|
handlerRef,
|
|
@@ -8634,6 +8687,10 @@ function useSerialize(input) {
|
|
|
8634
8687
|
});
|
|
8635
8688
|
const slidesToSave = buildSaveSlides(slidesWithGuides, templateElementsBySlideId);
|
|
8636
8689
|
const saveOptions = {
|
|
8690
|
+
// Without this the Slide Size card edited a viewer-only pixel value and
|
|
8691
|
+
// the saved `p:sldSz` never moved: passing `slideSize` is the only way a
|
|
8692
|
+
// slide-size edit reaches the file.
|
|
8693
|
+
slideSize: resolveSlideSizeSelection({ current: slideSizeEmu, canvas: canvasSize }).size,
|
|
8637
8694
|
headerFooter,
|
|
8638
8695
|
presentationProperties,
|
|
8639
8696
|
customShows: customShows.length > 0 ? customShows : void 0,
|
|
@@ -8642,6 +8699,7 @@ function useSerialize(input) {
|
|
|
8642
8699
|
appProperties,
|
|
8643
8700
|
customProperties: customProperties.length > 0 ? customProperties : void 0,
|
|
8644
8701
|
tags: tagCollections.length > 0 ? tagCollections : void 0,
|
|
8702
|
+
slideMasters,
|
|
8645
8703
|
notesMaster,
|
|
8646
8704
|
handoutMaster,
|
|
8647
8705
|
...embeddedFontSaveOptions(embedFonts)
|
|
@@ -8650,6 +8708,8 @@ function useSerialize(input) {
|
|
|
8650
8708
|
}, [
|
|
8651
8709
|
slides,
|
|
8652
8710
|
templateElementsBySlideId,
|
|
8711
|
+
canvasSize,
|
|
8712
|
+
slideSizeEmu,
|
|
8653
8713
|
headerFooter,
|
|
8654
8714
|
presentationProperties,
|
|
8655
8715
|
customShows,
|
|
@@ -8658,6 +8718,7 @@ function useSerialize(input) {
|
|
|
8658
8718
|
appProperties,
|
|
8659
8719
|
customProperties,
|
|
8660
8720
|
tagCollections,
|
|
8721
|
+
slideMasters,
|
|
8661
8722
|
notesMaster,
|
|
8662
8723
|
handoutMaster,
|
|
8663
8724
|
guides,
|
|
@@ -8783,7 +8844,8 @@ function usePresentationSetup(input) {
|
|
|
8783
8844
|
history,
|
|
8784
8845
|
endWithBlackSlide = true,
|
|
8785
8846
|
promptKeepInkAnnotations = true,
|
|
8786
|
-
popupToolbarEnabled = true
|
|
8847
|
+
popupToolbarEnabled = true,
|
|
8848
|
+
onToggleSubtitles
|
|
8787
8849
|
} = input;
|
|
8788
8850
|
const actionSoundHandlerRef = useRef(null);
|
|
8789
8851
|
const [, setShowKeepAnnotationsDialog] = useState(false);
|
|
@@ -8862,6 +8924,7 @@ function usePresentationSetup(input) {
|
|
|
8862
8924
|
onEraseAnnotations: () => annotations.clearAnnotations(),
|
|
8863
8925
|
onToggleInkMarkup: () => annotations.setInkMarkupVisible(!annotations.inkMarkupVisible),
|
|
8864
8926
|
onToggleToolbar: () => annotations.setToolbarVisible(!annotations.toolbarVisible),
|
|
8927
|
+
onToggleSubtitles,
|
|
8865
8928
|
onSaveRehearsalTimings: (timings) => {
|
|
8866
8929
|
setSlides((prev) => applyRehearsalTimings(prev, timings));
|
|
8867
8930
|
history.markDirty();
|
|
@@ -9161,12 +9224,14 @@ function useIOHandlers(input) {
|
|
|
9161
9224
|
appProperties: state.appProperties ?? null,
|
|
9162
9225
|
customProperties: state.customProperties,
|
|
9163
9226
|
tagCollections: state.tagCollections,
|
|
9227
|
+
slideMasters: state.slideMasters,
|
|
9164
9228
|
notesMaster: state.notesMaster,
|
|
9165
9229
|
handoutMaster: state.handoutMaster,
|
|
9166
9230
|
guides: state.guides,
|
|
9167
9231
|
activeSlideIndexForGuides: state.activeSlideIndex,
|
|
9168
9232
|
theme: state.theme,
|
|
9169
9233
|
canvasSize,
|
|
9234
|
+
slideSizeEmu: state.slideSizeEmu,
|
|
9170
9235
|
password
|
|
9171
9236
|
});
|
|
9172
9237
|
const printHandlers = usePrintHandlers({
|
|
@@ -9391,6 +9456,7 @@ function useContentLifecycle(input) {
|
|
|
9391
9456
|
setTemplateElementsBySlideId: state.setTemplateElementsBySlideId,
|
|
9392
9457
|
mediaDataUrls: state.mediaDataUrls,
|
|
9393
9458
|
setCanvasSize: state.setCanvasSize,
|
|
9459
|
+
setSlideSizeEmu: state.setSlideSizeEmu,
|
|
9394
9460
|
setHeaderFooter: state.setHeaderFooter,
|
|
9395
9461
|
setLayoutOptions: state.setLayoutOptions,
|
|
9396
9462
|
setSlideMasters: state.setSlideMasters,
|
|
@@ -9398,6 +9464,7 @@ function useContentLifecycle(input) {
|
|
|
9398
9464
|
setTableStyleMap: state.setTableStyleMap,
|
|
9399
9465
|
setThemeOptions: state.setThemeOptions,
|
|
9400
9466
|
setCustomShows: state.setCustomShows,
|
|
9467
|
+
setActiveCustomShowId: state.setActiveCustomShowId,
|
|
9401
9468
|
setSections: state.setSections,
|
|
9402
9469
|
setPresentationProperties: state.setPresentationProperties,
|
|
9403
9470
|
setNotesMaster: state.setNotesMaster,
|
|
@@ -9427,6 +9494,8 @@ function useContentLifecycle(input) {
|
|
|
9427
9494
|
slides,
|
|
9428
9495
|
templateElementsBySlideId: state.templateElementsBySlideId,
|
|
9429
9496
|
activeSlideIndex: state.activeSlideIndex,
|
|
9497
|
+
canvasSize: state.canvasSize,
|
|
9498
|
+
slideSizeEmu: state.slideSizeEmu,
|
|
9430
9499
|
guides: state.guides,
|
|
9431
9500
|
headerFooter: state.headerFooter,
|
|
9432
9501
|
presentationProperties: state.presentationProperties,
|
|
@@ -9436,6 +9505,7 @@ function useContentLifecycle(input) {
|
|
|
9436
9505
|
appProperties: state.appProperties,
|
|
9437
9506
|
customProperties: state.customProperties,
|
|
9438
9507
|
tagCollections: state.tagCollections,
|
|
9508
|
+
slideMasters: state.slideMasters,
|
|
9439
9509
|
notesMaster: state.notesMaster,
|
|
9440
9510
|
handoutMaster: state.handoutMaster,
|
|
9441
9511
|
handlerRef,
|
|
@@ -9451,7 +9521,31 @@ function useContentLifecycle(input) {
|
|
|
9451
9521
|
filePath,
|
|
9452
9522
|
serializeSlides: serializeForRecovery,
|
|
9453
9523
|
enabled: autosaveEnabled,
|
|
9454
|
-
...autosaveIntervalSeconds === void 0 ? {} : { intervalSeconds: autosaveIntervalSeconds }
|
|
9524
|
+
...autosaveIntervalSeconds === void 0 ? {} : { intervalSeconds: autosaveIntervalSeconds },
|
|
9525
|
+
// Everything `serializeForRecovery` reads that changes by REASSIGNMENT,
|
|
9526
|
+
// so a poll that finds all of them unchanged can skip re-serializing a
|
|
9527
|
+
// deck it has already snapshotted. The two refs are read by `.current`
|
|
9528
|
+
// because an inline edit in progress lives there and nowhere else yet.
|
|
9529
|
+
getChangeSources: () => [
|
|
9530
|
+
slides,
|
|
9531
|
+
state.templateElementsBySlideId,
|
|
9532
|
+
state.guides,
|
|
9533
|
+
state.headerFooter,
|
|
9534
|
+
state.presentationProperties,
|
|
9535
|
+
state.customShows,
|
|
9536
|
+
state.sections,
|
|
9537
|
+
state.coreProperties,
|
|
9538
|
+
state.appProperties,
|
|
9539
|
+
state.customProperties,
|
|
9540
|
+
state.tagCollections,
|
|
9541
|
+
state.notesMaster,
|
|
9542
|
+
state.handoutMaster,
|
|
9543
|
+
state.embeddedFonts,
|
|
9544
|
+
embedFonts,
|
|
9545
|
+
password,
|
|
9546
|
+
state.inlineEditingElementIdRef.current,
|
|
9547
|
+
state.inlineEditingTextRef.current
|
|
9548
|
+
]
|
|
9455
9549
|
});
|
|
9456
9550
|
return { handlerRef, serializeSlides, serializeForRecovery, autosaveStatus };
|
|
9457
9551
|
}
|
|
@@ -9462,7 +9556,14 @@ function useKeyboardShortcuts(input) {
|
|
|
9462
9556
|
const current = inputRef.current;
|
|
9463
9557
|
const { action, dx, dy } = mapEditorKey(e, {
|
|
9464
9558
|
canEdit: current.canEdit,
|
|
9465
|
-
|
|
9559
|
+
// The Slide Master view is an editing surface, not a viewing one.
|
|
9560
|
+
// Gating on `mode !== 'edit'` alone made `mapEditorKey` return
|
|
9561
|
+
// NO_ACTION there, so Delete, the arrow-key nudges and the clipboard
|
|
9562
|
+
// keys were all inert over a master shape even though the write path
|
|
9563
|
+
// behind them routes to the owning part correctly. Svelte and
|
|
9564
|
+
// vanilla, which render the master into their ordinary editable
|
|
9565
|
+
// stage, never had the gap.
|
|
9566
|
+
isPresenting: current.mode !== "edit" && current.mode !== "master",
|
|
9466
9567
|
hasSelection: current.hasSelection,
|
|
9467
9568
|
isEditingText: Boolean(current.inlineEditingElementId || current.tableEditorState?.isEditing),
|
|
9468
9569
|
isDrawing: current.activeTool !== "select",
|
|
@@ -9509,6 +9610,9 @@ function useKeyboardShortcuts(input) {
|
|
|
9509
9610
|
case "toggleShortcuts":
|
|
9510
9611
|
current.onToggleShortcuts?.();
|
|
9511
9612
|
break;
|
|
9613
|
+
case "find":
|
|
9614
|
+
current.onFind?.();
|
|
9615
|
+
break;
|
|
9512
9616
|
case "nudge":
|
|
9513
9617
|
current.onNudge(dx ?? 0, dy ?? 0);
|
|
9514
9618
|
break;
|
|
@@ -10855,6 +10959,15 @@ function buildToolbarProps(input) {
|
|
|
10855
10959
|
onToggleVersionHistory: () => propertyHandlers.setIsVersionHistoryOpen((p) => !p),
|
|
10856
10960
|
onOpenPasswordProtection: () => dialogs.setIsPasswordDialogOpen(true),
|
|
10857
10961
|
onOpenDocumentProperties: () => dialogs.setIsDocPropsDialogOpen(true),
|
|
10962
|
+
// Design > Slide Size: the size control is the inspector's SLIDE SIZE
|
|
10963
|
+
// card, which the deck (no-selection) panel renders. Drop the selection so
|
|
10964
|
+
// that panel is what the pane shows, then open it.
|
|
10965
|
+
onOpenSlideSize: () => {
|
|
10966
|
+
s.setSelectedElementId(null);
|
|
10967
|
+
s.setSelectedElementIds([]);
|
|
10968
|
+
s.setSidebarPanelMode("properties");
|
|
10969
|
+
s.setIsInspectorPaneOpen(true);
|
|
10970
|
+
},
|
|
10858
10971
|
onOpenFontEmbedding: () => dialogs.setIsFontEmbeddingOpen(true),
|
|
10859
10972
|
onOpenDigitalSignatures: () => dialogs.setIsDigitalSigDialogOpen(true),
|
|
10860
10973
|
onEnterPresenterView,
|
|
@@ -10981,7 +11094,12 @@ function useViewerBuildingBlocksCore(input) {
|
|
|
10981
11094
|
setMode: state.setMode,
|
|
10982
11095
|
setActiveSlideIndex: state.setActiveSlideIndex,
|
|
10983
11096
|
setSlides: state.setSlides,
|
|
10984
|
-
history
|
|
11097
|
+
history,
|
|
11098
|
+
// PowerPoint's bare `J` during a show toggles live captions.
|
|
11099
|
+
onToggleSubtitles: () => state.setPresentationProperties((prev) => ({
|
|
11100
|
+
...prev,
|
|
11101
|
+
showSubtitles: !prev.showSubtitles
|
|
11102
|
+
}))
|
|
10985
11103
|
});
|
|
10986
11104
|
return {
|
|
10987
11105
|
state,
|
|
Binary file
|