pptx-react-viewer 3.1.1 → 3.1.3
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 +22 -0
- package/dist/{AiChatPanel-EIENGCKW.mjs → AiChatPanel-5JAQBLTU.mjs} +4 -4
- package/dist/AiChatPanel-5JAQBLTU.mjs.br +0 -0
- package/dist/AiChatPanel-5JAQBLTU.mjs.gz +0 -0
- package/dist/{AiChatPanel-6PERJN7M.js → AiChatPanel-C3E7UV7T.js} +24 -24
- package/dist/AiChatPanel-C3E7UV7T.js.br +0 -0
- package/dist/AiChatPanel-C3E7UV7T.js.gz +0 -0
- package/dist/{Area3DChartScene-W6SVC235.mjs → Area3DChartScene-KE434ERF.mjs} +1 -1
- package/dist/{Area3DChartScene-W6SVC235.mjs.br → Area3DChartScene-KE434ERF.mjs.br} +0 -0
- package/dist/Area3DChartScene-KE434ERF.mjs.gz +0 -0
- package/dist/{Area3DChartScene-TXCLQLBQ.js → Area3DChartScene-XY2PKRMA.js} +2 -2
- package/dist/Area3DChartScene-XY2PKRMA.js.br +0 -0
- package/dist/Area3DChartScene-XY2PKRMA.js.gz +0 -0
- package/dist/{Bar3DChartScene-FCVUZIJ3.mjs → Bar3DChartScene-2KQABQZM.mjs} +1 -1
- package/dist/{Bar3DChartScene-FCVUZIJ3.mjs.br → Bar3DChartScene-2KQABQZM.mjs.br} +0 -0
- package/dist/Bar3DChartScene-2KQABQZM.mjs.gz +0 -0
- package/dist/{Bar3DChartScene-6RHPFLZT.js → Bar3DChartScene-YMADUUZN.js} +2 -2
- package/dist/Bar3DChartScene-YMADUUZN.js.br +0 -0
- package/dist/Bar3DChartScene-YMADUUZN.js.gz +0 -0
- package/dist/{Line3DChartScene-2ZFE53KO.js → Line3DChartScene-AB7N6ORX.js} +2 -2
- package/dist/Line3DChartScene-AB7N6ORX.js.br +0 -0
- package/dist/Line3DChartScene-AB7N6ORX.js.gz +0 -0
- package/dist/{Line3DChartScene-MJXFXSPW.mjs → Line3DChartScene-K3BSK6BB.mjs} +1 -1
- package/dist/{Line3DChartScene-MJXFXSPW.mjs.br → Line3DChartScene-K3BSK6BB.mjs.br} +0 -0
- package/dist/Line3DChartScene-K3BSK6BB.mjs.gz +0 -0
- package/dist/{Model3DScene-A5RV3KNJ.mjs → Model3DScene-NT5RRIB5.mjs} +1 -1
- package/dist/{Model3DScene-A5RV3KNJ.mjs.br → Model3DScene-NT5RRIB5.mjs.br} +0 -0
- package/dist/Model3DScene-NT5RRIB5.mjs.gz +0 -0
- package/dist/{Model3DScene-7VQNRY5B.js → Model3DScene-VSLGUWC7.js} +2 -2
- package/dist/{Model3DScene-7VQNRY5B.js.br → Model3DScene-VSLGUWC7.js.br} +0 -0
- package/dist/Model3DScene-VSLGUWC7.js.gz +0 -0
- package/dist/{PieChart3DScene-JTHZESS3.js → PieChart3DScene-6MUFRFYJ.js} +2 -2
- package/dist/PieChart3DScene-6MUFRFYJ.js.br +0 -0
- package/dist/PieChart3DScene-6MUFRFYJ.js.gz +0 -0
- package/dist/{PieChart3DScene-UEVFZZVW.mjs → PieChart3DScene-NFRBKII7.mjs} +1 -1
- package/dist/PieChart3DScene-NFRBKII7.mjs.br +0 -0
- package/dist/PieChart3DScene-NFRBKII7.mjs.gz +0 -0
- package/dist/PowerPointViewer-Cl6jBPNw.d.ts.map +1 -1
- package/dist/{SurfaceChart3DScene-FXUNT5OK.js → SurfaceChart3DScene-2UQOKVFB.js} +2 -2
- package/dist/SurfaceChart3DScene-2UQOKVFB.js.br +0 -0
- package/dist/SurfaceChart3DScene-2UQOKVFB.js.gz +0 -0
- package/dist/{SurfaceChart3DScene-WD65PAG4.mjs → SurfaceChart3DScene-UKIOTKJC.mjs} +1 -1
- package/dist/{SurfaceChart3DScene-WD65PAG4.mjs.br → SurfaceChart3DScene-UKIOTKJC.mjs.br} +0 -0
- package/dist/SurfaceChart3DScene-UKIOTKJC.mjs.gz +0 -0
- package/dist/{chunk-ICAYXQVJ.mjs → chunk-5WH6UVWC.mjs} +289 -135
- package/dist/chunk-5WH6UVWC.mjs.br +0 -0
- package/dist/chunk-5WH6UVWC.mjs.gz +0 -0
- package/dist/{chunk-OUX4O5XK.mjs → chunk-ACVLIDUS.mjs} +2 -2
- package/dist/chunk-ACVLIDUS.mjs.br +0 -0
- package/dist/chunk-ACVLIDUS.mjs.gz +0 -0
- package/dist/{chunk-MKPSUHUH.mjs → chunk-ARJE3V6V.mjs} +5 -6
- package/dist/chunk-ARJE3V6V.mjs.br +0 -0
- package/dist/chunk-ARJE3V6V.mjs.gz +0 -0
- package/dist/{chunk-MAOUVROK.mjs → chunk-BZ6OM3H5.mjs} +360 -338
- package/dist/chunk-BZ6OM3H5.mjs.br +0 -0
- package/dist/chunk-BZ6OM3H5.mjs.gz +0 -0
- package/dist/{chunk-GIFQWIW5.js → chunk-GCOGKBK3.js} +1368 -1214
- package/dist/chunk-GCOGKBK3.js.br +0 -0
- package/dist/chunk-GCOGKBK3.js.gz +0 -0
- package/dist/{chunk-IDTNKL4S.js → chunk-HMZA25W2.js} +300 -45
- package/dist/chunk-HMZA25W2.js.br +0 -0
- package/dist/chunk-HMZA25W2.js.gz +0 -0
- package/dist/{chunk-OZGFMZEX.js → chunk-K4DUVYZ7.js} +3 -3
- package/dist/chunk-K4DUVYZ7.js.br +0 -0
- package/dist/chunk-K4DUVYZ7.js.gz +0 -0
- package/dist/{chunk-GCE2TYHF.js → chunk-OABOL32L.js} +157 -157
- package/dist/chunk-OABOL32L.js.br +0 -0
- package/dist/chunk-OABOL32L.js.gz +0 -0
- package/dist/{chunk-ISDTM2V3.mjs → chunk-SRAXNEJX.mjs} +286 -45
- package/dist/chunk-SRAXNEJX.mjs.br +0 -0
- package/dist/chunk-SRAXNEJX.mjs.gz +0 -0
- package/dist/{chunk-PIUB7R2K.js → chunk-SWRY3SI5.js} +5 -6
- package/dist/chunk-SWRY3SI5.js.br +0 -0
- package/dist/chunk-SWRY3SI5.js.gz +0 -0
- package/dist/{chunk-OTBQBTTQ.js → chunk-XBR7W47W.js} +726 -706
- package/dist/chunk-XBR7W47W.js.br +0 -0
- package/dist/chunk-XBR7W47W.js.gz +0 -0
- package/dist/{chunk-5ERW2B25.mjs → chunk-Z3DEULRJ.mjs} +1 -1
- package/dist/chunk-Z3DEULRJ.mjs.br +0 -0
- package/dist/chunk-Z3DEULRJ.mjs.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 +27 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +47 -47
- 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 +99 -22
- 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/{useViewerBuildingBlocks-DC1O_op4.d.ts → useViewerBuildingBlocks-X1L8BjsQ.d.ts} +19 -2
- package/dist/useViewerBuildingBlocks-X1L8BjsQ.d.ts.map +1 -0
- 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 +1 -1
- package/dist/AiChatPanel-6PERJN7M.js.br +0 -0
- package/dist/AiChatPanel-6PERJN7M.js.gz +0 -0
- package/dist/AiChatPanel-EIENGCKW.mjs.br +0 -0
- package/dist/AiChatPanel-EIENGCKW.mjs.gz +0 -0
- package/dist/Area3DChartScene-TXCLQLBQ.js.br +0 -0
- package/dist/Area3DChartScene-TXCLQLBQ.js.gz +0 -0
- package/dist/Area3DChartScene-W6SVC235.mjs.gz +0 -0
- package/dist/Bar3DChartScene-6RHPFLZT.js.br +0 -0
- package/dist/Bar3DChartScene-6RHPFLZT.js.gz +0 -0
- package/dist/Bar3DChartScene-FCVUZIJ3.mjs.gz +0 -0
- package/dist/Line3DChartScene-2ZFE53KO.js.br +0 -0
- package/dist/Line3DChartScene-2ZFE53KO.js.gz +0 -0
- package/dist/Line3DChartScene-MJXFXSPW.mjs.gz +0 -0
- package/dist/Model3DScene-7VQNRY5B.js.gz +0 -0
- package/dist/Model3DScene-A5RV3KNJ.mjs.gz +0 -0
- package/dist/PieChart3DScene-JTHZESS3.js.br +0 -0
- package/dist/PieChart3DScene-JTHZESS3.js.gz +0 -0
- package/dist/PieChart3DScene-UEVFZZVW.mjs.br +0 -0
- package/dist/PieChart3DScene-UEVFZZVW.mjs.gz +0 -0
- package/dist/SurfaceChart3DScene-FXUNT5OK.js.br +0 -0
- package/dist/SurfaceChart3DScene-FXUNT5OK.js.gz +0 -0
- package/dist/SurfaceChart3DScene-WD65PAG4.mjs.gz +0 -0
- package/dist/chunk-5ERW2B25.mjs.br +0 -0
- package/dist/chunk-5ERW2B25.mjs.gz +0 -0
- package/dist/chunk-GCE2TYHF.js.br +0 -0
- package/dist/chunk-GCE2TYHF.js.gz +0 -0
- package/dist/chunk-GIFQWIW5.js.br +0 -0
- package/dist/chunk-GIFQWIW5.js.gz +0 -0
- package/dist/chunk-ICAYXQVJ.mjs.br +0 -0
- package/dist/chunk-ICAYXQVJ.mjs.gz +0 -0
- package/dist/chunk-IDTNKL4S.js.br +0 -0
- package/dist/chunk-IDTNKL4S.js.gz +0 -0
- package/dist/chunk-ISDTM2V3.mjs.br +0 -0
- package/dist/chunk-ISDTM2V3.mjs.gz +0 -0
- package/dist/chunk-MAOUVROK.mjs.br +0 -0
- package/dist/chunk-MAOUVROK.mjs.gz +0 -0
- package/dist/chunk-MKPSUHUH.mjs.br +0 -0
- package/dist/chunk-MKPSUHUH.mjs.gz +0 -0
- package/dist/chunk-OTBQBTTQ.js.br +0 -0
- package/dist/chunk-OTBQBTTQ.js.gz +0 -0
- package/dist/chunk-OUX4O5XK.mjs.br +0 -0
- package/dist/chunk-OUX4O5XK.mjs.gz +0 -0
- package/dist/chunk-OZGFMZEX.js.br +0 -0
- package/dist/chunk-OZGFMZEX.js.gz +0 -0
- package/dist/chunk-PIUB7R2K.js.br +0 -0
- package/dist/chunk-PIUB7R2K.js.gz +0 -0
- package/dist/useViewerBuildingBlocks-DC1O_op4.d.ts.map +0 -1
|
@@ -1,8 +1,7 @@
|
|
|
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, 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, collectTableCellImagePaths, applyTableCellImagePatches, collectTableStyleImagePaths, applyTableStyleImagePatches, partitionTemplateElements, resolveAuthoredCustomShowId, buildInitialGuides, EncryptedFileError, resolveAutosaveIntervalMs, shouldWriteAutosaveSnapshot, saveAutosaveSnapshot, autosaveSnapshotMark, updateMasterViewElement, isTemplateElementId, hasShapeProperties, hasTextProperties, getInlineEditorSelection, applyStyleToSelectedSegments, setPendingSelectionRestore, applyCaseTransformToSegments, transformTextCase, masterViewElements, replaceMasterViewElements, addSection, renameSection, deleteSection, moveSectionUp, moveSectionDown, moveSlidesToSection, normalizeColorsForCapture, preprocessCssForCapture, slideProgressPercent, slideStatusLabel, EXPORT_ASSEMBLING_PERCENT, EXPORT_DONE_PERCENT, isExportAbortError, recordProgressPercent, downloadBlob, applyThemeToData, THEME_PRESETS, themeColorSchemesEqual, comparePresentation, applyAcceptSlide, applyAcceptAllSlides, collectUsedFonts, describeFontEmbedding, isMobileViewport, mayLeaveSlideShow, stopAllPersistentAudio, remapTextToSegments, guidePxToEmu, buildSaveSlides, embeddedFontSaveOptions, resolveSlideSizeSelection, saveDeckWithPassword, shouldProbeAutosaveRecovery, probeAutosaveRecovery, acceptAutosaveRecovery, discardAutosaveRecovery, shouldLoopContinuously, applyRehearsalTimings, copyFormatFromElement, applyFormatToElement, mapEditorKey, isEditorTextInputTarget, createViewerOptionsStore, readSlidesFromYDoc, shouldRoomSlidesReplaceLoad, reconcileSlidesInYDoc, LOCAL_SYNC_ORIGIN, observeYDocSlides, shouldAutoFollowBroadcaster, detectTouchDevice, detectOrientation, deriveViewportBreakpoints, createTouchGestureRecognizer, MAX_ZOOM_SCALE, MIN_ZOOM_SCALE, isKeyboardOpen, scopeLayoutOptionsToSlide, openPptxFile, readBackstageRecentFile, isActionHidden, resolveInlineEditAutoFitHeight, canInteractWithElement, filterInteractableIds, beginShapeAdjustment, buildElementClipboardPayload, savedPresentationFileName,
|
|
4
|
-
import { useRef, useState, useEffect, useCallback, useMemo, useLayoutEffect, useImperativeHandle, useSyncExternalStore } from 'react';
|
|
5
|
-
import JSZip from 'jszip';
|
|
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, GRID_SIZE, DEFAULT_TEXT_FONT_SIZE } from './chunk-ACVLIDUS.mjs';
|
|
2
|
+
import { translationsEn } from './chunk-ARJE3V6V.mjs';
|
|
3
|
+
import { DEFAULT_VIEWER_OPTIONS, 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, collectTableCellImagePaths, applyTableCellImagePatches, collectTableStyleImagePaths, applyTableStyleImagePatches, partitionTemplateElements, resolveAuthoredCustomShowId, buildInitialGuides, EncryptedFileError, resolveAutosaveIntervalMs, shouldWriteAutosaveSnapshot, saveAutosaveSnapshot, autosaveSnapshotMark, updateMasterViewElement, isTemplateElementId, hasShapeProperties, hasTextProperties, getInlineEditorSelection, applyStyleToSelectedSegments, setPendingSelectionRestore, applyCaseTransformToSegments, transformTextCase, masterViewElements, replaceMasterViewElements, addSection, renameSection, deleteSection, moveSectionUp, moveSectionDown, moveSlidesToSection, normalizeColorsForCapture, preprocessCssForCapture, slideProgressPercent, slideStatusLabel, EXPORT_ASSEMBLING_PERCENT, EXPORT_DONE_PERCENT, isExportAbortError, recordProgressPercent, downloadBlob, resolveImageResolutionScale, applyThemeToData, THEME_PRESETS, themeColorSchemesEqual, comparePresentation, applyAcceptSlide, applyAcceptAllSlides, collectUsedFonts, describeFontEmbedding, isMobileViewport, mayLeaveSlideShow, stopAllPersistentAudio, remapTextToSegments, guidePxToEmu, buildSaveSlides, embeddedFontSaveOptions, resolveSlideSizeSelection, saveDeckWithPassword, shouldProbeAutosaveRecovery, probeAutosaveRecovery, acceptAutosaveRecovery, discardAutosaveRecovery, shouldLoopContinuously, applyRehearsalTimings, copyFormatFromElement, applyFormatToElement, mapEditorKey, isEditorTextInputTarget, createViewerOptionsStore, readSlidesFromYDoc, shouldRoomSlidesReplaceLoad, reconcileSlidesInYDoc, LOCAL_SYNC_ORIGIN, observeYDocSlides, shouldAutoFollowBroadcaster, detectTouchDevice, detectOrientation, deriveViewportBreakpoints, createTouchGestureRecognizer, MAX_ZOOM_SCALE, MIN_ZOOM_SCALE, isKeyboardOpen, scopeLayoutOptionsToSlide, openPptxFile, readBackstageRecentFile, isActionHidden, resolveInlineEditAutoFitHeight, canInteractWithElement, filterInteractableIds, beginShapeAdjustment, buildElementClipboardPayload, savedPresentationFileName, exportDeckJson, groupElements, generateElementId, makeCloneId, ungroupElements, alignElements, distributeElements, bringForward, sendBackward, bringToFront, sendToBack, newTableElement, createDefaultChartElement, readViewportMetrics, computeKeyboardInset, mergeShapes, mapPresentationKey, lastShowSlideIndex, firstShowSlideIndex, mapPresentationWheel, openPendingPrintWindow, computeColorFilter, filterHiddenSlideIndices, computeSlideIndices, buildPrintDocument, finishPrintWindow, buildPrintHtmlDocument, buildOutlineHtml, buildSlidesHtml, buildNotesHtml, buildHandoutsHtml, createBlankSlide, makeSlideId, buildSlideTemplateSlide, templateSchemeFromTheme, buildThemeColorMap, reResolveSlideColors, computeEntranceAnimationDelay, createPresentationSessionId, resolveTransitionDurationMs, runPresentationAction, createPresenterTimer, createInitialPresentationSnapshot, mergePresentationSnapshot, resetPresenterTimer, presenterElapsed, stepPresenterZoom, togglePresenterTimer, addCommentToList, removeCommentFromList, editCommentInList, toggleCommentResolvedInList, replyToCommentInList, canvasToJpegData, downloadDataUrl, pickSupportedMimeType, WEBM_MIME_CANDIDATES, fpsToFrameIntervalMs, segmentFrameCount, encodeGif, computeGridSpacingPx, resolveShowSlideIndexes, groupSlidesBySection, masterViewPseudoSlide, resolveHistoryDepth, hasCopyableFormat, createBackstagePresentation, buildFieldSubstitutionContext, cloneElementForPaste, computeScrollDelta, getPresetShapeClipPath, svgPathToPolygons, polygonsToSvgPath, rerouteConnectorsForMovedElements, applyReroutedConnectors, SvgExporter, deleteTableColumn, rebuildTableStructureInRawXml, insertTableColumn, deleteTableRow, insertTableRow, updateCellTextStyleInRawXml, setCellText, updateCellTextInRawXml, splitCell, updateMergeAttrsInRawXml, mergeCells, isPpactionUrl, parsePpactionUrl, resolvePresentationAction, ACTION_BUTTON_PRESETS, elementActionToPptxAction, isUrlSafe, buildSmartArtPresetData, classifyMediaType, computeSnapToShape, publishLiveGeometry, getDraggedShapeAdjustments, computeMarqueeHitIds, mergeAdditiveSelection, shouldConfirmExternalHyperlink, safeOpenUrl, applyResize, snapBoxToGrid, applyMotionPathPreset } from './chunk-SRAXNEJX.mjs';
|
|
4
|
+
import { createContext, useRef, useState, useEffect, useCallback, useMemo, useLayoutEffect, useContext, useImperativeHandle, useSyncExternalStore } from 'react';
|
|
6
5
|
import { useTranslation } from 'react-i18next';
|
|
7
6
|
|
|
8
7
|
function useVirtualizedSlides({
|
|
@@ -3792,7 +3791,8 @@ function useLoadContent({
|
|
|
3792
3791
|
setError,
|
|
3793
3792
|
setIsDirty,
|
|
3794
3793
|
setIsEncrypted,
|
|
3795
|
-
onContentApplied
|
|
3794
|
+
onContentApplied,
|
|
3795
|
+
allowExternalImages
|
|
3796
3796
|
}) {
|
|
3797
3797
|
const handlerRef = useRef(null);
|
|
3798
3798
|
const originalBufferRef = useRef(null);
|
|
@@ -3818,7 +3818,7 @@ function useLoadContent({
|
|
|
3818
3818
|
}
|
|
3819
3819
|
const previousHandler = handlerRef.current;
|
|
3820
3820
|
const handler = new PptxHandler();
|
|
3821
|
-
const parsed = await handler.load(buffer);
|
|
3821
|
+
const parsed = await handler.load(buffer, { allowExternalImages });
|
|
3822
3822
|
if (cancelled || token !== renderTokenRef.current) {
|
|
3823
3823
|
handler.dispose();
|
|
3824
3824
|
return;
|
|
@@ -4904,8 +4904,7 @@ function usePointerHandlers(input) {
|
|
|
4904
4904
|
updateSlides,
|
|
4905
4905
|
updateElementById,
|
|
4906
4906
|
markDirty,
|
|
4907
|
-
livePatcher
|
|
4908
|
-
input
|
|
4907
|
+
livePatcher
|
|
4909
4908
|
]);
|
|
4910
4909
|
}
|
|
4911
4910
|
function mouseDownStartsSelectionDrag(event) {
|
|
@@ -6546,13 +6545,15 @@ function createTableStructHandlers(input) {
|
|
|
6546
6545
|
elementLookup,
|
|
6547
6546
|
setTableEditorState,
|
|
6548
6547
|
ops,
|
|
6549
|
-
history
|
|
6548
|
+
history,
|
|
6549
|
+
transformCommittedText
|
|
6550
6550
|
} = input;
|
|
6551
|
-
const handleCommitCellEdit = (elementId, rowIndex, colIndex,
|
|
6551
|
+
const handleCommitCellEdit = (elementId, rowIndex, colIndex, rawText) => {
|
|
6552
6552
|
const el = elementLookup.get(elementId);
|
|
6553
6553
|
if (!el || el.type !== "table") {
|
|
6554
6554
|
return;
|
|
6555
6555
|
}
|
|
6556
|
+
const text = transformCommittedText ? transformCommittedText(rawText) : rawText;
|
|
6556
6557
|
const updates = {};
|
|
6557
6558
|
if (el.tableData) {
|
|
6558
6559
|
updates.tableData = setCellText(el, rowIndex, colIndex, text).tableData;
|
|
@@ -6743,6 +6744,144 @@ async function renderToCanvas(element, options = {}) {
|
|
|
6743
6744
|
});
|
|
6744
6745
|
}
|
|
6745
6746
|
|
|
6747
|
+
// src/viewer/hooks/useExportSaveAs.ts
|
|
6748
|
+
function useExportSaveAs(input) {
|
|
6749
|
+
const {
|
|
6750
|
+
slides,
|
|
6751
|
+
templateElementsBySlideId,
|
|
6752
|
+
filePath,
|
|
6753
|
+
handlerRef,
|
|
6754
|
+
headerFooter,
|
|
6755
|
+
presentationProperties,
|
|
6756
|
+
customShows,
|
|
6757
|
+
sections,
|
|
6758
|
+
coreProperties,
|
|
6759
|
+
appProperties,
|
|
6760
|
+
customProperties,
|
|
6761
|
+
tagCollections,
|
|
6762
|
+
slideMasters,
|
|
6763
|
+
notesMaster,
|
|
6764
|
+
handoutMaster,
|
|
6765
|
+
guides,
|
|
6766
|
+
activeSlideIndexForGuides,
|
|
6767
|
+
theme,
|
|
6768
|
+
canvasSize,
|
|
6769
|
+
slideSizeEmu,
|
|
6770
|
+
password
|
|
6771
|
+
} = input;
|
|
6772
|
+
const handleSaveAsFormat = async (format) => {
|
|
6773
|
+
const handler = handlerRef.current;
|
|
6774
|
+
if (!handler) {
|
|
6775
|
+
return;
|
|
6776
|
+
}
|
|
6777
|
+
const downloadName = savedPresentationFileName(filePath, format);
|
|
6778
|
+
try {
|
|
6779
|
+
const data = await buildSaveAsData(handler, format);
|
|
6780
|
+
const blob = new Blob([data], {
|
|
6781
|
+
type: "application/vnd.openxmlformats-officedocument.presentationml.presentation"
|
|
6782
|
+
});
|
|
6783
|
+
downloadBlob(blob, downloadName);
|
|
6784
|
+
} catch (err) {
|
|
6785
|
+
console.error(`[PowerPointViewer] Save as .${format} failed:`, err);
|
|
6786
|
+
}
|
|
6787
|
+
};
|
|
6788
|
+
const buildSaveAsData = async (handler, format) => {
|
|
6789
|
+
const slidesWithGuides = slides.map((slide, idx) => {
|
|
6790
|
+
if (idx !== activeSlideIndexForGuides) {
|
|
6791
|
+
return slide;
|
|
6792
|
+
}
|
|
6793
|
+
const pptxGuides = guides.map((g) => ({
|
|
6794
|
+
id: g.id,
|
|
6795
|
+
orientation: g.axis === "h" ? "horz" : "vert",
|
|
6796
|
+
positionEmu: guidePxToEmu(g.position)
|
|
6797
|
+
}));
|
|
6798
|
+
return {
|
|
6799
|
+
...slide,
|
|
6800
|
+
guides: pptxGuides.length > 0 ? pptxGuides : void 0
|
|
6801
|
+
};
|
|
6802
|
+
});
|
|
6803
|
+
const slidesToSave = buildSaveSlides(slidesWithGuides, templateElementsBySlideId);
|
|
6804
|
+
const saveOptions = {
|
|
6805
|
+
// Save As shares Save's slide-size decision; leaving it out here is how
|
|
6806
|
+
// a preset picked in the inspector reached one save path and not the other.
|
|
6807
|
+
slideSize: resolveSlideSizeSelection({ current: slideSizeEmu, canvas: canvasSize }).size,
|
|
6808
|
+
headerFooter,
|
|
6809
|
+
presentationProperties,
|
|
6810
|
+
customShows: customShows.length > 0 ? customShows : void 0,
|
|
6811
|
+
sections: sections.length > 0 ? sections : void 0,
|
|
6812
|
+
coreProperties: coreProperties ?? void 0,
|
|
6813
|
+
appProperties: appProperties ?? void 0,
|
|
6814
|
+
customProperties: customProperties.length > 0 ? customProperties : void 0,
|
|
6815
|
+
tags: tagCollections.length > 0 ? tagCollections : void 0,
|
|
6816
|
+
slideMasters,
|
|
6817
|
+
notesMaster,
|
|
6818
|
+
handoutMaster,
|
|
6819
|
+
outputFormat: format
|
|
6820
|
+
};
|
|
6821
|
+
return saveDeckWithPassword(handler, slidesToSave, saveOptions, password);
|
|
6822
|
+
};
|
|
6823
|
+
const handleExportJson = () => {
|
|
6824
|
+
const sourceName = filePath ? filePath.replace(/\\/gu, "/").split("/").pop() : void 0;
|
|
6825
|
+
const slideSize = resolveSlideSizeSelection({ current: slideSizeEmu, canvas: canvasSize }).size;
|
|
6826
|
+
const data = {
|
|
6827
|
+
slides: buildSaveSlides(slides, templateElementsBySlideId),
|
|
6828
|
+
width: canvasSize.width,
|
|
6829
|
+
height: canvasSize.height,
|
|
6830
|
+
widthEmu: slideSize.widthEmu,
|
|
6831
|
+
heightEmu: slideSize.heightEmu,
|
|
6832
|
+
slideSizeType: slideSize.type === "" ? void 0 : slideSize.type,
|
|
6833
|
+
theme,
|
|
6834
|
+
headerFooter,
|
|
6835
|
+
presentationProperties,
|
|
6836
|
+
customShows: customShows.length > 0 ? customShows : void 0,
|
|
6837
|
+
sections: sections.length > 0 ? sections : void 0,
|
|
6838
|
+
coreProperties: coreProperties ?? void 0,
|
|
6839
|
+
appProperties: appProperties ?? void 0,
|
|
6840
|
+
customProperties: customProperties.length > 0 ? customProperties : void 0,
|
|
6841
|
+
tags: tagCollections.length > 0 ? tagCollections : void 0,
|
|
6842
|
+
notesMaster,
|
|
6843
|
+
handoutMaster
|
|
6844
|
+
};
|
|
6845
|
+
try {
|
|
6846
|
+
exportDeckJson(data, sourceName);
|
|
6847
|
+
} catch (err) {
|
|
6848
|
+
console.error("[PowerPointViewer] JSON export failed:", err);
|
|
6849
|
+
}
|
|
6850
|
+
};
|
|
6851
|
+
const handleSaveAsPptx = () => {
|
|
6852
|
+
void handleSaveAsFormat("pptx");
|
|
6853
|
+
};
|
|
6854
|
+
const handleSaveAsPpsx = () => {
|
|
6855
|
+
void handleSaveAsFormat("ppsx");
|
|
6856
|
+
};
|
|
6857
|
+
const handleSaveAsPptm = () => {
|
|
6858
|
+
void handleSaveAsFormat("pptm");
|
|
6859
|
+
};
|
|
6860
|
+
return {
|
|
6861
|
+
handleExportJson,
|
|
6862
|
+
handleSaveAsFormat,
|
|
6863
|
+
handleSaveAsPptx,
|
|
6864
|
+
handleSaveAsPpsx,
|
|
6865
|
+
handleSaveAsPptm
|
|
6866
|
+
};
|
|
6867
|
+
}
|
|
6868
|
+
|
|
6869
|
+
// src/viewer/utils/dom-helpers.ts
|
|
6870
|
+
function safePrompt(message, defaultValue) {
|
|
6871
|
+
try {
|
|
6872
|
+
return window.prompt(message, defaultValue);
|
|
6873
|
+
} catch {
|
|
6874
|
+
return null;
|
|
6875
|
+
}
|
|
6876
|
+
}
|
|
6877
|
+
function safeConfirm(message) {
|
|
6878
|
+
try {
|
|
6879
|
+
return window.confirm(message);
|
|
6880
|
+
} catch {
|
|
6881
|
+
return false;
|
|
6882
|
+
}
|
|
6883
|
+
}
|
|
6884
|
+
|
|
6746
6885
|
// src/viewer/utils/export-helpers.ts
|
|
6747
6886
|
async function renderElementToCanvas(element, scale = 2, backgroundColor) {
|
|
6748
6887
|
const canvas = await renderToCanvas(element, {
|
|
@@ -7052,194 +7191,6 @@ function exportAllSlidesToSvg(data, options = {}) {
|
|
|
7052
7191
|
return results;
|
|
7053
7192
|
}
|
|
7054
7193
|
|
|
7055
|
-
// src/viewer/hooks/useExportSaveAs.ts
|
|
7056
|
-
function useExportSaveAs(input) {
|
|
7057
|
-
const {
|
|
7058
|
-
slides,
|
|
7059
|
-
templateElementsBySlideId,
|
|
7060
|
-
filePath,
|
|
7061
|
-
handlerRef,
|
|
7062
|
-
serializeSlides,
|
|
7063
|
-
headerFooter,
|
|
7064
|
-
presentationProperties,
|
|
7065
|
-
customShows,
|
|
7066
|
-
sections,
|
|
7067
|
-
coreProperties,
|
|
7068
|
-
appProperties,
|
|
7069
|
-
customProperties,
|
|
7070
|
-
tagCollections,
|
|
7071
|
-
slideMasters,
|
|
7072
|
-
notesMaster,
|
|
7073
|
-
handoutMaster,
|
|
7074
|
-
guides,
|
|
7075
|
-
activeSlideIndexForGuides,
|
|
7076
|
-
theme,
|
|
7077
|
-
canvasSize,
|
|
7078
|
-
slideSizeEmu,
|
|
7079
|
-
modalControls,
|
|
7080
|
-
password
|
|
7081
|
-
} = input;
|
|
7082
|
-
const {
|
|
7083
|
-
setExportModalOpen,
|
|
7084
|
-
setExportModalTitle,
|
|
7085
|
-
setExportProgress,
|
|
7086
|
-
setExportStatusMessage,
|
|
7087
|
-
exportAbortRef
|
|
7088
|
-
} = modalControls;
|
|
7089
|
-
const handlePackageForSharing = async () => {
|
|
7090
|
-
const abortCtrl = new AbortController();
|
|
7091
|
-
exportAbortRef.current = abortCtrl;
|
|
7092
|
-
setExportModalTitle("Package for Sharing");
|
|
7093
|
-
setExportStatusMessage("Preparing package...");
|
|
7094
|
-
setExportProgress(0);
|
|
7095
|
-
setExportModalOpen(true);
|
|
7096
|
-
try {
|
|
7097
|
-
const zip = new JSZip();
|
|
7098
|
-
const pkgFolder = zip.folder("presentation-package");
|
|
7099
|
-
setExportProgress(10);
|
|
7100
|
-
setExportStatusMessage("Adding presentation...");
|
|
7101
|
-
const pptxData = await serializeSlides();
|
|
7102
|
-
const pptxFilename = savedPresentationFileName(filePath);
|
|
7103
|
-
if (pptxData) {
|
|
7104
|
-
pkgFolder.file(pptxFilename, pptxData);
|
|
7105
|
-
}
|
|
7106
|
-
setExportProgress(70);
|
|
7107
|
-
setExportStatusMessage("Writing README...");
|
|
7108
|
-
const readme = generatePackageReadme(pptxFilename);
|
|
7109
|
-
pkgFolder.file("README.txt", readme);
|
|
7110
|
-
if (abortCtrl.signal.aborted) {
|
|
7111
|
-
throw new DOMException("Export cancelled", "AbortError");
|
|
7112
|
-
}
|
|
7113
|
-
setExportProgress(85);
|
|
7114
|
-
setExportStatusMessage("Generating ZIP...");
|
|
7115
|
-
const zipBlob = await zip.generateAsync({ type: "blob" });
|
|
7116
|
-
setExportProgress(95);
|
|
7117
|
-
setExportStatusMessage("Downloading...");
|
|
7118
|
-
downloadBlob(zipBlob, `${presentationBaseName(pptxFilename)}-package.zip`);
|
|
7119
|
-
setExportProgress(100);
|
|
7120
|
-
} catch (err) {
|
|
7121
|
-
if (err.name !== "AbortError") {
|
|
7122
|
-
console.error("[PowerPointViewer] Package export failed:", err);
|
|
7123
|
-
}
|
|
7124
|
-
} finally {
|
|
7125
|
-
exportAbortRef.current = null;
|
|
7126
|
-
setExportModalOpen(false);
|
|
7127
|
-
}
|
|
7128
|
-
};
|
|
7129
|
-
const handleSaveAsFormat = async (format) => {
|
|
7130
|
-
const handler = handlerRef.current;
|
|
7131
|
-
if (!handler) {
|
|
7132
|
-
return;
|
|
7133
|
-
}
|
|
7134
|
-
const downloadName = savedPresentationFileName(filePath, format);
|
|
7135
|
-
try {
|
|
7136
|
-
const data = await buildSaveAsData(handler, format);
|
|
7137
|
-
const blob = new Blob([data], {
|
|
7138
|
-
type: "application/vnd.openxmlformats-officedocument.presentationml.presentation"
|
|
7139
|
-
});
|
|
7140
|
-
downloadBlob(blob, downloadName);
|
|
7141
|
-
} catch (err) {
|
|
7142
|
-
console.error(`[PowerPointViewer] Save as .${format} failed:`, err);
|
|
7143
|
-
}
|
|
7144
|
-
};
|
|
7145
|
-
const buildSaveAsData = async (handler, format) => {
|
|
7146
|
-
const slidesWithGuides = slides.map((slide, idx) => {
|
|
7147
|
-
if (idx !== activeSlideIndexForGuides) {
|
|
7148
|
-
return slide;
|
|
7149
|
-
}
|
|
7150
|
-
const pptxGuides = guides.map((g) => ({
|
|
7151
|
-
id: g.id,
|
|
7152
|
-
orientation: g.axis === "h" ? "horz" : "vert",
|
|
7153
|
-
positionEmu: guidePxToEmu(g.position)
|
|
7154
|
-
}));
|
|
7155
|
-
return {
|
|
7156
|
-
...slide,
|
|
7157
|
-
guides: pptxGuides.length > 0 ? pptxGuides : void 0
|
|
7158
|
-
};
|
|
7159
|
-
});
|
|
7160
|
-
const slidesToSave = buildSaveSlides(slidesWithGuides, templateElementsBySlideId);
|
|
7161
|
-
const saveOptions = {
|
|
7162
|
-
// Save As shares Save's slide-size decision; leaving it out here is how
|
|
7163
|
-
// a preset picked in the inspector reached one save path and not the other.
|
|
7164
|
-
slideSize: resolveSlideSizeSelection({ current: slideSizeEmu, canvas: canvasSize }).size,
|
|
7165
|
-
headerFooter,
|
|
7166
|
-
presentationProperties,
|
|
7167
|
-
customShows: customShows.length > 0 ? customShows : void 0,
|
|
7168
|
-
sections: sections.length > 0 ? sections : void 0,
|
|
7169
|
-
coreProperties: coreProperties ?? void 0,
|
|
7170
|
-
appProperties: appProperties ?? void 0,
|
|
7171
|
-
customProperties: customProperties.length > 0 ? customProperties : void 0,
|
|
7172
|
-
tags: tagCollections.length > 0 ? tagCollections : void 0,
|
|
7173
|
-
slideMasters,
|
|
7174
|
-
notesMaster,
|
|
7175
|
-
handoutMaster,
|
|
7176
|
-
outputFormat: format
|
|
7177
|
-
};
|
|
7178
|
-
return saveDeckWithPassword(handler, slidesToSave, saveOptions, password);
|
|
7179
|
-
};
|
|
7180
|
-
const handleExportJson = () => {
|
|
7181
|
-
const sourceName = filePath ? filePath.replace(/\\/gu, "/").split("/").pop() : void 0;
|
|
7182
|
-
const slideSize = resolveSlideSizeSelection({ current: slideSizeEmu, canvas: canvasSize }).size;
|
|
7183
|
-
const data = {
|
|
7184
|
-
slides: buildSaveSlides(slides, templateElementsBySlideId),
|
|
7185
|
-
width: canvasSize.width,
|
|
7186
|
-
height: canvasSize.height,
|
|
7187
|
-
widthEmu: slideSize.widthEmu,
|
|
7188
|
-
heightEmu: slideSize.heightEmu,
|
|
7189
|
-
slideSizeType: slideSize.type === "" ? void 0 : slideSize.type,
|
|
7190
|
-
theme,
|
|
7191
|
-
headerFooter,
|
|
7192
|
-
presentationProperties,
|
|
7193
|
-
customShows: customShows.length > 0 ? customShows : void 0,
|
|
7194
|
-
sections: sections.length > 0 ? sections : void 0,
|
|
7195
|
-
coreProperties: coreProperties ?? void 0,
|
|
7196
|
-
appProperties: appProperties ?? void 0,
|
|
7197
|
-
customProperties: customProperties.length > 0 ? customProperties : void 0,
|
|
7198
|
-
tags: tagCollections.length > 0 ? tagCollections : void 0,
|
|
7199
|
-
notesMaster,
|
|
7200
|
-
handoutMaster
|
|
7201
|
-
};
|
|
7202
|
-
try {
|
|
7203
|
-
exportDeckJson(data, sourceName);
|
|
7204
|
-
} catch (err) {
|
|
7205
|
-
console.error("[PowerPointViewer] JSON export failed:", err);
|
|
7206
|
-
}
|
|
7207
|
-
};
|
|
7208
|
-
const handleSaveAsPptx = () => {
|
|
7209
|
-
void handleSaveAsFormat("pptx");
|
|
7210
|
-
};
|
|
7211
|
-
const handleSaveAsPpsx = () => {
|
|
7212
|
-
void handleSaveAsFormat("ppsx");
|
|
7213
|
-
};
|
|
7214
|
-
const handleSaveAsPptm = () => {
|
|
7215
|
-
void handleSaveAsFormat("pptm");
|
|
7216
|
-
};
|
|
7217
|
-
return {
|
|
7218
|
-
handleExportJson,
|
|
7219
|
-
handlePackageForSharing,
|
|
7220
|
-
handleSaveAsFormat,
|
|
7221
|
-
handleSaveAsPptx,
|
|
7222
|
-
handleSaveAsPpsx,
|
|
7223
|
-
handleSaveAsPptm
|
|
7224
|
-
};
|
|
7225
|
-
}
|
|
7226
|
-
|
|
7227
|
-
// src/viewer/utils/dom-helpers.ts
|
|
7228
|
-
function safePrompt(message, defaultValue) {
|
|
7229
|
-
try {
|
|
7230
|
-
return window.prompt(message, defaultValue);
|
|
7231
|
-
} catch {
|
|
7232
|
-
return null;
|
|
7233
|
-
}
|
|
7234
|
-
}
|
|
7235
|
-
function safeConfirm(message) {
|
|
7236
|
-
try {
|
|
7237
|
-
return window.confirm(message);
|
|
7238
|
-
} catch {
|
|
7239
|
-
return false;
|
|
7240
|
-
}
|
|
7241
|
-
}
|
|
7242
|
-
|
|
7243
7194
|
// src/viewer/hooks/useExportHandlers.ts
|
|
7244
7195
|
function useExportHandlers(input) {
|
|
7245
7196
|
const {
|
|
@@ -7251,7 +7202,6 @@ function useExportHandlers(input) {
|
|
|
7251
7202
|
canvasStageRef,
|
|
7252
7203
|
setActiveSlideIndex,
|
|
7253
7204
|
handlerRef,
|
|
7254
|
-
serializeSlides,
|
|
7255
7205
|
headerFooter,
|
|
7256
7206
|
presentationProperties,
|
|
7257
7207
|
customShows,
|
|
@@ -7268,23 +7218,16 @@ function useExportHandlers(input) {
|
|
|
7268
7218
|
theme,
|
|
7269
7219
|
canvasSize,
|
|
7270
7220
|
slideSizeEmu,
|
|
7271
|
-
password
|
|
7221
|
+
password,
|
|
7222
|
+
imageExportScale
|
|
7272
7223
|
} = input;
|
|
7273
7224
|
const [exportModalOpen, setExportModalOpen] = useState(false);
|
|
7274
7225
|
const [exportModalTitle, setExportModalTitle] = useState("");
|
|
7275
7226
|
const [exportProgress, setExportProgress] = useState(0);
|
|
7276
7227
|
const [exportStatusMessage, setExportStatusMessage] = useState("");
|
|
7277
7228
|
const exportAbortRef = useRef(null);
|
|
7278
|
-
const modalControls = {
|
|
7279
|
-
setExportModalOpen,
|
|
7280
|
-
setExportModalTitle,
|
|
7281
|
-
setExportProgress,
|
|
7282
|
-
setExportStatusMessage,
|
|
7283
|
-
exportAbortRef
|
|
7284
|
-
};
|
|
7285
7229
|
const {
|
|
7286
7230
|
handleExportJson,
|
|
7287
|
-
handlePackageForSharing,
|
|
7288
7231
|
handleSaveAsFormat,
|
|
7289
7232
|
handleSaveAsPptx,
|
|
7290
7233
|
handleSaveAsPpsx,
|
|
@@ -7294,7 +7237,6 @@ function useExportHandlers(input) {
|
|
|
7294
7237
|
templateElementsBySlideId,
|
|
7295
7238
|
filePath,
|
|
7296
7239
|
handlerRef,
|
|
7297
|
-
serializeSlides,
|
|
7298
7240
|
headerFooter,
|
|
7299
7241
|
presentationProperties,
|
|
7300
7242
|
customShows,
|
|
@@ -7311,7 +7253,6 @@ function useExportHandlers(input) {
|
|
|
7311
7253
|
theme,
|
|
7312
7254
|
canvasSize,
|
|
7313
7255
|
slideSizeEmu,
|
|
7314
|
-
modalControls,
|
|
7315
7256
|
password
|
|
7316
7257
|
});
|
|
7317
7258
|
const handleExportPng = useCallback(async () => {
|
|
@@ -7321,12 +7262,13 @@ function useExportHandlers(input) {
|
|
|
7321
7262
|
}
|
|
7322
7263
|
try {
|
|
7323
7264
|
await exportSlideAsPng(stageEl, activeSlideIndex, {
|
|
7324
|
-
backgroundColor: activeSlide?.backgroundColor
|
|
7265
|
+
backgroundColor: activeSlide?.backgroundColor,
|
|
7266
|
+
scale: imageExportScale
|
|
7325
7267
|
});
|
|
7326
7268
|
} catch (err) {
|
|
7327
7269
|
console.error("[PowerPointViewer] PNG export failed:", err);
|
|
7328
7270
|
}
|
|
7329
|
-
}, [canvasStageRef, activeSlideIndex, activeSlide?.backgroundColor]);
|
|
7271
|
+
}, [canvasStageRef, activeSlideIndex, activeSlide?.backgroundColor, imageExportScale]);
|
|
7330
7272
|
const handleExportPdf = useCallback(async () => {
|
|
7331
7273
|
if (!canvasStageRef.current) {
|
|
7332
7274
|
return;
|
|
@@ -7345,7 +7287,7 @@ function useExportHandlers(input) {
|
|
|
7345
7287
|
activeSlideIndex,
|
|
7346
7288
|
"presentation.pdf",
|
|
7347
7289
|
{
|
|
7348
|
-
scale:
|
|
7290
|
+
scale: imageExportScale,
|
|
7349
7291
|
onProgress: (current, total) => {
|
|
7350
7292
|
setExportProgress(slideProgressPercent(current, total));
|
|
7351
7293
|
setExportStatusMessage(slideStatusLabel("Rendering", current, total));
|
|
@@ -7368,7 +7310,7 @@ function useExportHandlers(input) {
|
|
|
7368
7310
|
exportAbortRef.current = null;
|
|
7369
7311
|
setExportModalOpen(false);
|
|
7370
7312
|
}
|
|
7371
|
-
}, [canvasStageRef, slides.length, setActiveSlideIndex, activeSlideIndex]);
|
|
7313
|
+
}, [canvasStageRef, slides.length, setActiveSlideIndex, activeSlideIndex, imageExportScale]);
|
|
7372
7314
|
const handleExportNotesPdf = useCallback(async () => {
|
|
7373
7315
|
if (!canvasStageRef.current) {
|
|
7374
7316
|
return;
|
|
@@ -7389,7 +7331,7 @@ function useExportHandlers(input) {
|
|
|
7389
7331
|
slideNotes,
|
|
7390
7332
|
"presentation-notes.pdf",
|
|
7391
7333
|
{
|
|
7392
|
-
scale:
|
|
7334
|
+
scale: imageExportScale,
|
|
7393
7335
|
onProgress: (current, total) => {
|
|
7394
7336
|
setExportProgress(slideProgressPercent(current, total));
|
|
7395
7337
|
setExportStatusMessage(slideStatusLabel("Rendering", current, total));
|
|
@@ -7412,7 +7354,7 @@ function useExportHandlers(input) {
|
|
|
7412
7354
|
exportAbortRef.current = null;
|
|
7413
7355
|
setExportModalOpen(false);
|
|
7414
7356
|
}
|
|
7415
|
-
}, [canvasStageRef, slides, setActiveSlideIndex, activeSlideIndex]);
|
|
7357
|
+
}, [canvasStageRef, slides, setActiveSlideIndex, activeSlideIndex, imageExportScale]);
|
|
7416
7358
|
const handleCopySlideAsImage = useCallback(async () => {
|
|
7417
7359
|
const stageEl = canvasStageRef.current;
|
|
7418
7360
|
if (!stageEl) {
|
|
@@ -7420,12 +7362,13 @@ function useExportHandlers(input) {
|
|
|
7420
7362
|
}
|
|
7421
7363
|
try {
|
|
7422
7364
|
await copySlideToClipboard(stageEl, {
|
|
7423
|
-
backgroundColor: activeSlide?.backgroundColor
|
|
7365
|
+
backgroundColor: activeSlide?.backgroundColor,
|
|
7366
|
+
scale: imageExportScale
|
|
7424
7367
|
});
|
|
7425
7368
|
} catch (err) {
|
|
7426
7369
|
console.error("[PowerPointViewer] Copy slide as image failed:", err);
|
|
7427
7370
|
}
|
|
7428
|
-
}, [canvasStageRef, activeSlide?.backgroundColor]);
|
|
7371
|
+
}, [canvasStageRef, activeSlide?.backgroundColor, imageExportScale]);
|
|
7429
7372
|
const handleExportVideo = useCallback(async () => {
|
|
7430
7373
|
if (!canvasStageRef.current) {
|
|
7431
7374
|
return;
|
|
@@ -7522,7 +7465,6 @@ function useExportHandlers(input) {
|
|
|
7522
7465
|
handleExportVideo,
|
|
7523
7466
|
handleExportGif,
|
|
7524
7467
|
handleExportJson,
|
|
7525
|
-
handlePackageForSharing,
|
|
7526
7468
|
handleSaveAsFormat,
|
|
7527
7469
|
handleSaveAsPptx,
|
|
7528
7470
|
handleSaveAsPpsx,
|
|
@@ -7534,95 +7476,96 @@ function useExportHandlers(input) {
|
|
|
7534
7476
|
exportStatusMessage
|
|
7535
7477
|
};
|
|
7536
7478
|
}
|
|
7537
|
-
|
|
7538
|
-
|
|
7539
|
-
|
|
7540
|
-
return false;
|
|
7541
|
-
}
|
|
7542
|
-
printWindow.document.open();
|
|
7543
|
-
printWindow.document.write(
|
|
7544
|
-
buildPrintHtmlDocument({ title, bodyHtml, orientation, colorFilter, frameSlides })
|
|
7545
|
-
);
|
|
7546
|
-
printWindow.document.close();
|
|
7547
|
-
printWindow.focus();
|
|
7548
|
-
setTimeout(() => {
|
|
7549
|
-
printWindow.print();
|
|
7550
|
-
}, 300);
|
|
7551
|
-
return true;
|
|
7552
|
-
}
|
|
7553
|
-
function openPrintWindowWithDocument(htmlDocument) {
|
|
7554
|
-
const printWindow = window.open("", "_blank", "noopener,noreferrer");
|
|
7555
|
-
if (!printWindow) {
|
|
7556
|
-
return false;
|
|
7557
|
-
}
|
|
7558
|
-
printWindow.document.open();
|
|
7559
|
-
printWindow.document.write(htmlDocument);
|
|
7560
|
-
printWindow.document.close();
|
|
7561
|
-
printWindow.focus();
|
|
7562
|
-
setTimeout(() => {
|
|
7563
|
-
printWindow.print();
|
|
7564
|
-
}, 300);
|
|
7565
|
-
return true;
|
|
7479
|
+
var ViewerOptionsContext = createContext(DEFAULT_VIEWER_OPTIONS);
|
|
7480
|
+
function useViewerOptionsContext() {
|
|
7481
|
+
return useContext(ViewerOptionsContext);
|
|
7566
7482
|
}
|
|
7483
|
+
|
|
7484
|
+
// src/viewer/hooks/usePrintHandlers.ts
|
|
7567
7485
|
function usePrintHandlers(input) {
|
|
7568
7486
|
const { slides, activeSlideIndex, canvasStageRef, setActiveSlideIndex, pptxData } = input;
|
|
7569
7487
|
const [isPrintDialogOpen, setIsPrintDialogOpen] = useState(false);
|
|
7488
|
+
const { t } = useTranslation();
|
|
7489
|
+
const viewerOptions = useViewerOptionsContext();
|
|
7490
|
+
const includeHiddenSlides = viewerOptions.advanced.printHiddenSlides;
|
|
7491
|
+
const printRasterScale = (viewerOptions.advanced.printHighQuality ? 4 : 3) * resolveImageResolutionScale(viewerOptions);
|
|
7570
7492
|
const handlePrint = () => {
|
|
7571
7493
|
setIsPrintDialogOpen(true);
|
|
7572
7494
|
};
|
|
7573
7495
|
const handlePrintSvg = async (settings) => {
|
|
7574
7496
|
setIsPrintDialogOpen(false);
|
|
7497
|
+
const printWindow = openPendingPrintWindow(t("pptx.print.preparingToPrint"));
|
|
7498
|
+
if (!printWindow) {
|
|
7499
|
+
console.warn(
|
|
7500
|
+
"[PowerPointViewer] Print window was blocked by the browser. Allow popups for this site to print."
|
|
7501
|
+
);
|
|
7502
|
+
return;
|
|
7503
|
+
}
|
|
7575
7504
|
if (!pptxData || settings.printWhat !== "slides") {
|
|
7576
|
-
return
|
|
7505
|
+
return runRasterPrint(printWindow, settings);
|
|
7577
7506
|
}
|
|
7578
7507
|
const colorFilter = computeColorFilter(settings.colorMode);
|
|
7579
|
-
const slideIndices =
|
|
7580
|
-
|
|
7581
|
-
|
|
7582
|
-
|
|
7583
|
-
|
|
7584
|
-
|
|
7508
|
+
const slideIndices = filterHiddenSlideIndices(
|
|
7509
|
+
computeSlideIndices(
|
|
7510
|
+
settings.slideRange,
|
|
7511
|
+
activeSlideIndex,
|
|
7512
|
+
slides.length,
|
|
7513
|
+
settings.customRangeFrom,
|
|
7514
|
+
settings.customRangeTo
|
|
7515
|
+
),
|
|
7516
|
+
slides,
|
|
7517
|
+
includeHiddenSlides
|
|
7585
7518
|
);
|
|
7586
7519
|
try {
|
|
7587
7520
|
const svgs = exportAllSlidesToSvg(pptxData, {
|
|
7588
7521
|
slideIndices
|
|
7589
7522
|
});
|
|
7590
7523
|
if (svgs.length === 0) {
|
|
7524
|
+
printWindow.close();
|
|
7591
7525
|
return;
|
|
7592
7526
|
}
|
|
7593
7527
|
const printDoc = buildPrintDocument(svgs, pptxData.width, pptxData.height, {
|
|
7594
7528
|
title: "Slides (Vector)",
|
|
7595
7529
|
orientation: settings.orientation,
|
|
7596
|
-
colorFilter
|
|
7530
|
+
colorFilter,
|
|
7531
|
+
scaleToFit: settings.scaleToFit
|
|
7597
7532
|
});
|
|
7598
|
-
|
|
7533
|
+
finishPrintWindow(printWindow, printDoc);
|
|
7599
7534
|
} catch (err) {
|
|
7600
7535
|
console.warn("[PowerPointViewer] SVG print path failed, falling back to raster:", err);
|
|
7601
|
-
return
|
|
7536
|
+
return runRasterPrint(printWindow, settings);
|
|
7602
7537
|
}
|
|
7603
7538
|
};
|
|
7604
|
-
const
|
|
7605
|
-
setIsPrintDialogOpen(false);
|
|
7539
|
+
const runRasterPrint = async (printWindow, settings) => {
|
|
7606
7540
|
const colorFilter = computeColorFilter(settings.colorMode);
|
|
7607
|
-
const slideIndices =
|
|
7608
|
-
|
|
7609
|
-
|
|
7610
|
-
|
|
7611
|
-
|
|
7612
|
-
|
|
7541
|
+
const slideIndices = filterHiddenSlideIndices(
|
|
7542
|
+
computeSlideIndices(
|
|
7543
|
+
settings.slideRange,
|
|
7544
|
+
activeSlideIndex,
|
|
7545
|
+
slides.length,
|
|
7546
|
+
settings.customRangeFrom,
|
|
7547
|
+
settings.customRangeTo
|
|
7548
|
+
),
|
|
7549
|
+
slides,
|
|
7550
|
+
includeHiddenSlides
|
|
7613
7551
|
);
|
|
7614
7552
|
if (settings.printWhat === "outline") {
|
|
7615
|
-
|
|
7616
|
-
|
|
7617
|
-
|
|
7618
|
-
|
|
7619
|
-
|
|
7620
|
-
|
|
7553
|
+
finishPrintWindow(
|
|
7554
|
+
printWindow,
|
|
7555
|
+
buildPrintHtmlDocument({
|
|
7556
|
+
title: "Outline",
|
|
7557
|
+
bodyHtml: `<div class="outline-page">${buildOutlineHtml(slideIndices, slides)}</div>`,
|
|
7558
|
+
orientation: settings.orientation,
|
|
7559
|
+
colorFilter,
|
|
7560
|
+
frameSlides: settings.frameSlides,
|
|
7561
|
+
scaleToFit: settings.scaleToFit
|
|
7562
|
+
})
|
|
7621
7563
|
);
|
|
7622
7564
|
return;
|
|
7623
7565
|
}
|
|
7624
7566
|
try {
|
|
7625
7567
|
if (!canvasStageRef.current) {
|
|
7568
|
+
printWindow.close();
|
|
7626
7569
|
return;
|
|
7627
7570
|
}
|
|
7628
7571
|
const allImages = await captureAllSlidesAsPngDataUrls(
|
|
@@ -7630,46 +7573,70 @@ function usePrintHandlers(input) {
|
|
|
7630
7573
|
slides.length,
|
|
7631
7574
|
setActiveSlideIndex,
|
|
7632
7575
|
activeSlideIndex,
|
|
7633
|
-
{ scale:
|
|
7576
|
+
{ scale: printRasterScale }
|
|
7634
7577
|
);
|
|
7635
7578
|
if (allImages.length === 0) {
|
|
7579
|
+
printWindow.close();
|
|
7636
7580
|
return;
|
|
7637
7581
|
}
|
|
7638
7582
|
const slideImages = slideIndices.map((idx) => allImages[idx]).filter(Boolean);
|
|
7639
7583
|
if (settings.printWhat === "slides") {
|
|
7640
|
-
|
|
7641
|
-
|
|
7642
|
-
|
|
7643
|
-
|
|
7644
|
-
|
|
7645
|
-
|
|
7584
|
+
finishPrintWindow(
|
|
7585
|
+
printWindow,
|
|
7586
|
+
buildPrintHtmlDocument({
|
|
7587
|
+
title: "Slides",
|
|
7588
|
+
bodyHtml: buildSlidesHtml(slideImages, slideIndices),
|
|
7589
|
+
orientation: settings.orientation,
|
|
7590
|
+
colorFilter,
|
|
7591
|
+
frameSlides: settings.frameSlides,
|
|
7592
|
+
scaleToFit: settings.scaleToFit
|
|
7593
|
+
})
|
|
7646
7594
|
);
|
|
7647
7595
|
return;
|
|
7648
7596
|
}
|
|
7649
7597
|
if (settings.printWhat === "notes") {
|
|
7650
|
-
|
|
7651
|
-
|
|
7652
|
-
|
|
7653
|
-
|
|
7654
|
-
|
|
7655
|
-
|
|
7598
|
+
finishPrintWindow(
|
|
7599
|
+
printWindow,
|
|
7600
|
+
buildPrintHtmlDocument({
|
|
7601
|
+
title: "Notes Pages",
|
|
7602
|
+
bodyHtml: buildNotesHtml(slideImages, slideIndices, slides),
|
|
7603
|
+
orientation: "portrait",
|
|
7604
|
+
colorFilter,
|
|
7605
|
+
frameSlides: settings.frameSlides,
|
|
7606
|
+
scaleToFit: settings.scaleToFit
|
|
7607
|
+
})
|
|
7656
7608
|
);
|
|
7657
7609
|
return;
|
|
7658
7610
|
}
|
|
7659
7611
|
if (settings.printWhat === "handouts") {
|
|
7660
7612
|
const spp = settings.slidesPerPage;
|
|
7661
|
-
|
|
7662
|
-
|
|
7663
|
-
|
|
7664
|
-
|
|
7665
|
-
|
|
7666
|
-
|
|
7613
|
+
finishPrintWindow(
|
|
7614
|
+
printWindow,
|
|
7615
|
+
buildPrintHtmlDocument({
|
|
7616
|
+
title: `Handout ${spp} per page`,
|
|
7617
|
+
bodyHtml: buildHandoutsHtml(slideImages, slideIndices, spp),
|
|
7618
|
+
orientation: "portrait",
|
|
7619
|
+
colorFilter,
|
|
7620
|
+
frameSlides: settings.frameSlides,
|
|
7621
|
+
scaleToFit: settings.scaleToFit
|
|
7622
|
+
})
|
|
7667
7623
|
);
|
|
7668
7624
|
}
|
|
7669
7625
|
} catch (err) {
|
|
7670
7626
|
console.error("[PowerPointViewer] Print layout failed:", err);
|
|
7671
7627
|
}
|
|
7672
7628
|
};
|
|
7629
|
+
const handlePrintWithSettings = async (settings) => {
|
|
7630
|
+
setIsPrintDialogOpen(false);
|
|
7631
|
+
const printWindow = openPendingPrintWindow(t("pptx.print.preparingToPrint"));
|
|
7632
|
+
if (!printWindow) {
|
|
7633
|
+
console.warn(
|
|
7634
|
+
"[PowerPointViewer] Print window was blocked by the browser. Allow popups for this site to print."
|
|
7635
|
+
);
|
|
7636
|
+
return;
|
|
7637
|
+
}
|
|
7638
|
+
return runRasterPrint(printWindow, settings);
|
|
7639
|
+
};
|
|
7673
7640
|
return {
|
|
7674
7641
|
handlePrint,
|
|
7675
7642
|
handlePrintWithSettings,
|
|
@@ -8460,11 +8427,12 @@ function useAnnotationHandlers(input) {
|
|
|
8460
8427
|
presentation.enterPresentMode();
|
|
8461
8428
|
} else if (mode === "present" && annotations.hasAnyAnnotations) {
|
|
8462
8429
|
stopAllPersistentAudio();
|
|
8463
|
-
pendingModeAfterAnnotationsRef.current = nextMode;
|
|
8464
8430
|
if (promptKeepInkAnnotations) {
|
|
8431
|
+
pendingModeAfterAnnotationsRef.current = nextMode;
|
|
8465
8432
|
setShowKeepAnnotationsDialog(true);
|
|
8466
8433
|
} else {
|
|
8467
|
-
|
|
8434
|
+
annotations.clearAllAnnotations();
|
|
8435
|
+
setMode(nextMode);
|
|
8468
8436
|
}
|
|
8469
8437
|
} else {
|
|
8470
8438
|
if (mode === "present") {
|
|
@@ -8473,14 +8441,7 @@ function useAnnotationHandlers(input) {
|
|
|
8473
8441
|
setMode(nextMode);
|
|
8474
8442
|
}
|
|
8475
8443
|
},
|
|
8476
|
-
[
|
|
8477
|
-
presentation,
|
|
8478
|
-
mode,
|
|
8479
|
-
annotations.hasAnyAnnotations,
|
|
8480
|
-
promptKeepInkAnnotations,
|
|
8481
|
-
handleKeepAnnotations,
|
|
8482
|
-
setMode
|
|
8483
|
-
]
|
|
8444
|
+
[presentation, mode, annotations, promptKeepInkAnnotations, setMode]
|
|
8484
8445
|
);
|
|
8485
8446
|
const handleDiscardAnnotations = useCallback(() => {
|
|
8486
8447
|
annotations.clearAllAnnotations();
|
|
@@ -8678,8 +8639,7 @@ function usePresentationSetup(input) {
|
|
|
8678
8639
|
onToggleSubtitles
|
|
8679
8640
|
} = input;
|
|
8680
8641
|
const actionSoundHandlerRef = useRef(null);
|
|
8681
|
-
const
|
|
8682
|
-
const pendingModeRef = useRef("edit");
|
|
8642
|
+
const exitModeHandlerRef = useRef(null);
|
|
8683
8643
|
const annotations = usePresentationAnnotations({
|
|
8684
8644
|
isActive: mode === "present",
|
|
8685
8645
|
activeSlideIndex,
|
|
@@ -8696,16 +8656,19 @@ function usePresentationSetup(input) {
|
|
|
8696
8656
|
if (mode === "present" && nextMode !== "present" && !mayLeaveSlideShow()) {
|
|
8697
8657
|
return;
|
|
8698
8658
|
}
|
|
8699
|
-
if (mode === "present" && nextMode !== "present"
|
|
8700
|
-
|
|
8701
|
-
|
|
8702
|
-
|
|
8703
|
-
if (
|
|
8704
|
-
|
|
8705
|
-
|
|
8659
|
+
if (mode === "present" && nextMode !== "present") {
|
|
8660
|
+
stopAllPersistentAudio();
|
|
8661
|
+
stopAnimationSound();
|
|
8662
|
+
const exitHandler = exitModeHandlerRef.current;
|
|
8663
|
+
if (exitHandler) {
|
|
8664
|
+
exitHandler(nextMode);
|
|
8665
|
+
return;
|
|
8666
|
+
}
|
|
8667
|
+
if (annotations.hasAnyAnnotations && !promptKeepInkAnnotations) {
|
|
8668
|
+
annotations.clearAllAnnotations();
|
|
8706
8669
|
}
|
|
8707
|
-
setMode(nextMode);
|
|
8708
8670
|
}
|
|
8671
|
+
setMode(nextMode);
|
|
8709
8672
|
},
|
|
8710
8673
|
onSetActiveSlideIndex: setActiveSlideIndex,
|
|
8711
8674
|
onPlayActionSound: (soundPath, options) => {
|
|
@@ -8764,7 +8727,14 @@ function usePresentationSetup(input) {
|
|
|
8764
8727
|
useTimings: presentationProperties.advanceMode !== "manual",
|
|
8765
8728
|
endWithBlackSlide
|
|
8766
8729
|
});
|
|
8767
|
-
return {
|
|
8730
|
+
return {
|
|
8731
|
+
presentation,
|
|
8732
|
+
annotations,
|
|
8733
|
+
actionSoundHandlerRef,
|
|
8734
|
+
setExitModeHandler: (handler) => {
|
|
8735
|
+
exitModeHandlerRef.current = handler;
|
|
8736
|
+
}
|
|
8737
|
+
};
|
|
8768
8738
|
}
|
|
8769
8739
|
function useEditorOperations(input) {
|
|
8770
8740
|
const {
|
|
@@ -8928,7 +8898,8 @@ function useEditorOperations(input) {
|
|
|
8928
8898
|
tableEditorState: state.tableEditorState,
|
|
8929
8899
|
setTableEditorState: state.setTableEditorState,
|
|
8930
8900
|
ops,
|
|
8931
|
-
history
|
|
8901
|
+
history,
|
|
8902
|
+
transformCommittedText
|
|
8932
8903
|
});
|
|
8933
8904
|
const combinedUpdateTextStyle = useCallback(
|
|
8934
8905
|
(updates) => {
|
|
@@ -9030,11 +9001,11 @@ function useIOHandlers(input) {
|
|
|
9030
9001
|
ops,
|
|
9031
9002
|
zoom,
|
|
9032
9003
|
handlerRef,
|
|
9033
|
-
serializeSlides,
|
|
9034
9004
|
serializeForRecovery,
|
|
9035
9005
|
setContent,
|
|
9036
9006
|
onContentChange,
|
|
9037
|
-
password
|
|
9007
|
+
password,
|
|
9008
|
+
imageExportScale
|
|
9038
9009
|
} = input;
|
|
9039
9010
|
const exportHandlers = useExportHandlers({
|
|
9040
9011
|
slides,
|
|
@@ -9045,7 +9016,6 @@ function useIOHandlers(input) {
|
|
|
9045
9016
|
canvasStageRef: zoom.canvasStageRef,
|
|
9046
9017
|
setActiveSlideIndex: state.setActiveSlideIndex,
|
|
9047
9018
|
handlerRef,
|
|
9048
|
-
serializeSlides,
|
|
9049
9019
|
headerFooter: state.headerFooter,
|
|
9050
9020
|
presentationProperties: state.presentationProperties,
|
|
9051
9021
|
customShows: state.customShows,
|
|
@@ -9062,7 +9032,8 @@ function useIOHandlers(input) {
|
|
|
9062
9032
|
theme: state.theme,
|
|
9063
9033
|
canvasSize,
|
|
9064
9034
|
slideSizeEmu: state.slideSizeEmu,
|
|
9065
|
-
password
|
|
9035
|
+
password,
|
|
9036
|
+
imageExportScale
|
|
9066
9037
|
});
|
|
9067
9038
|
const printHandlers = usePrintHandlers({
|
|
9068
9039
|
slides,
|
|
@@ -9276,7 +9247,8 @@ function useContentLifecycle(input) {
|
|
|
9276
9247
|
actionSoundHandlerRef,
|
|
9277
9248
|
setIsEncryptedDialogOpen,
|
|
9278
9249
|
password,
|
|
9279
|
-
onContentApplied
|
|
9250
|
+
onContentApplied,
|
|
9251
|
+
allowExternalImages
|
|
9280
9252
|
} = input;
|
|
9281
9253
|
const { handlerRef } = useLoadContent({
|
|
9282
9254
|
content,
|
|
@@ -9315,7 +9287,8 @@ function useContentLifecycle(input) {
|
|
|
9315
9287
|
setError: state.setError,
|
|
9316
9288
|
setIsDirty: state.setIsDirty,
|
|
9317
9289
|
setIsEncrypted: setIsEncryptedDialogOpen,
|
|
9318
|
-
onContentApplied
|
|
9290
|
+
onContentApplied,
|
|
9291
|
+
allowExternalImages
|
|
9319
9292
|
});
|
|
9320
9293
|
useEffect(() => {
|
|
9321
9294
|
actionSoundHandlerRef.current = handlerRef.current;
|
|
@@ -9554,7 +9527,10 @@ function useViewerIntegration(input) {
|
|
|
9554
9527
|
autosaveEnabled,
|
|
9555
9528
|
autosaveAllowed = true,
|
|
9556
9529
|
autosaveIntervalMs,
|
|
9530
|
+
allowExternalImages,
|
|
9557
9531
|
canEdit,
|
|
9532
|
+
promptKeepInkAnnotations,
|
|
9533
|
+
imageExportScale,
|
|
9558
9534
|
mode,
|
|
9559
9535
|
slides,
|
|
9560
9536
|
activeSlide,
|
|
@@ -9619,7 +9595,8 @@ function useViewerIntegration(input) {
|
|
|
9619
9595
|
actionSoundHandlerRef,
|
|
9620
9596
|
setIsEncryptedDialogOpen,
|
|
9621
9597
|
password: dialogs.presentationPassword ?? void 0,
|
|
9622
|
-
onContentApplied: () => setLoadVersion((v) => v + 1)
|
|
9598
|
+
onContentApplied: () => setLoadVersion((v) => v + 1),
|
|
9599
|
+
allowExternalImages
|
|
9623
9600
|
}
|
|
9624
9601
|
);
|
|
9625
9602
|
const { exportHandlers, printHandlers, themeHandlers, propertyHandlers } = useIOHandlers({
|
|
@@ -9632,11 +9609,11 @@ function useViewerIntegration(input) {
|
|
|
9632
9609
|
ops: editorOps.ops,
|
|
9633
9610
|
zoom,
|
|
9634
9611
|
handlerRef,
|
|
9635
|
-
serializeSlides,
|
|
9636
9612
|
serializeForRecovery,
|
|
9637
9613
|
setContent,
|
|
9638
9614
|
onContentChange,
|
|
9639
|
-
password: dialogs.presentationPassword ?? void 0
|
|
9615
|
+
password: dialogs.presentationPassword ?? void 0,
|
|
9616
|
+
imageExportScale
|
|
9640
9617
|
});
|
|
9641
9618
|
const {
|
|
9642
9619
|
showKeepAnnotationsDialog,
|
|
@@ -9651,7 +9628,8 @@ function useViewerIntegration(input) {
|
|
|
9651
9628
|
annotations,
|
|
9652
9629
|
history,
|
|
9653
9630
|
setMode: state.setMode,
|
|
9654
|
-
setSlides: state.setSlides
|
|
9631
|
+
setSlides: state.setSlides,
|
|
9632
|
+
promptKeepInkAnnotations
|
|
9655
9633
|
});
|
|
9656
9634
|
const recovery = useRecoveryDetection({
|
|
9657
9635
|
filePath,
|
|
@@ -9930,13 +9908,19 @@ function useViewerOptions() {
|
|
|
9930
9908
|
return { optionsStore: store, options };
|
|
9931
9909
|
}
|
|
9932
9910
|
var KNOWN_TAB_IDS = new Set(TOOLBAR_TABS.map((tab) => tab.id));
|
|
9933
|
-
function computeToolbarVisibility(hiddenActions) {
|
|
9911
|
+
function computeToolbarVisibility(hiddenActions, hiddenTabIds = []) {
|
|
9934
9912
|
const isHidden = (id) => isActionHidden(id, hiddenActions);
|
|
9935
|
-
const
|
|
9913
|
+
const userHidden = new Set(hiddenTabIds);
|
|
9914
|
+
userHidden.delete("file");
|
|
9915
|
+
const isTabVisible = (id) => !KNOWN_TAB_IDS.has(id) || !isHidden(id) && !userHidden.has(id);
|
|
9936
9916
|
return { isHidden, isTabVisible };
|
|
9937
9917
|
}
|
|
9938
9918
|
function useToolbarVisibility(hiddenActions) {
|
|
9939
|
-
|
|
9919
|
+
const hiddenTabIds = useViewerOptionsContext().ribbon.hiddenTabIds;
|
|
9920
|
+
return useMemo(
|
|
9921
|
+
() => computeToolbarVisibility(hiddenActions, hiddenTabIds),
|
|
9922
|
+
[hiddenActions, hiddenTabIds]
|
|
9923
|
+
);
|
|
9940
9924
|
}
|
|
9941
9925
|
function useCollaborativeHistory({
|
|
9942
9926
|
localClientId: _localClientId,
|
|
@@ -10509,7 +10493,9 @@ function buildCanvasProps(input) {
|
|
|
10509
10493
|
tableOps,
|
|
10510
10494
|
presentation,
|
|
10511
10495
|
findResults,
|
|
10512
|
-
findResultIndex
|
|
10496
|
+
findResultIndex,
|
|
10497
|
+
viewerOptions,
|
|
10498
|
+
buildHyperlinkConfirmMessage
|
|
10513
10499
|
} = input;
|
|
10514
10500
|
const effectiveSlide = mode === "master" ? masterPseudoSlide : activeSlide;
|
|
10515
10501
|
const effectiveTemplateElements = mode === "master" ? s.activeLayout ? s.activeMaster?.elements ?? [] : [] : templateElements;
|
|
@@ -10519,11 +10505,22 @@ function buildCanvasProps(input) {
|
|
|
10519
10505
|
slide: activeSlide
|
|
10520
10506
|
});
|
|
10521
10507
|
const tableStyleContext = s.theme || s.tableStyleMap ? { theme: s.theme, tableStyleMap: s.tableStyleMap } : void 0;
|
|
10508
|
+
const openExternalUrl = (url) => {
|
|
10509
|
+
if (shouldConfirmExternalHyperlink(viewerOptions, url) && !window.confirm(buildHyperlinkConfirmMessage(url))) {
|
|
10510
|
+
return;
|
|
10511
|
+
}
|
|
10512
|
+
safeOpenUrl(url);
|
|
10513
|
+
};
|
|
10522
10514
|
const handleActionClick = (_elementId, action) => {
|
|
10523
10515
|
if (mode === "present") {
|
|
10516
|
+
const resolved = resolvePresentationAction(action, { slideCount: slides.length });
|
|
10517
|
+
if (resolved.intent.kind === "openUrl") {
|
|
10518
|
+
openExternalUrl(resolved.intent.url);
|
|
10519
|
+
return;
|
|
10520
|
+
}
|
|
10524
10521
|
presentation.handlePresentationAction(action);
|
|
10525
10522
|
} else if (action.url) {
|
|
10526
|
-
|
|
10523
|
+
openExternalUrl(action.url);
|
|
10527
10524
|
}
|
|
10528
10525
|
};
|
|
10529
10526
|
const handleHyperlinkClick = (url) => {
|
|
@@ -10539,7 +10536,7 @@ function buildCanvasProps(input) {
|
|
|
10539
10536
|
}
|
|
10540
10537
|
return;
|
|
10541
10538
|
}
|
|
10542
|
-
|
|
10539
|
+
openExternalUrl(url);
|
|
10543
10540
|
};
|
|
10544
10541
|
return {
|
|
10545
10542
|
activeSlide: effectiveSlide,
|
|
@@ -10839,7 +10836,6 @@ function buildToolbarProps(input) {
|
|
|
10839
10836
|
onExportVideo: exportHandlers.handleExportVideo,
|
|
10840
10837
|
onExportGif: exportHandlers.handleExportGif,
|
|
10841
10838
|
onExportJson: exportHandlers.handleExportJson,
|
|
10842
|
-
onPackageForSharing: exportHandlers.handlePackageForSharing,
|
|
10843
10839
|
onOpenFile,
|
|
10844
10840
|
onOpenRecentFile,
|
|
10845
10841
|
onCreatePresentation: (templateId) => {
|
|
@@ -10977,6 +10973,7 @@ function useViewerBuildingBlocksCore(input) {
|
|
|
10977
10973
|
]
|
|
10978
10974
|
);
|
|
10979
10975
|
const zoom = useZoomViewport({ canvasSize, selectedElements: state.selectedElements });
|
|
10976
|
+
const { options: viewerOptions } = useViewerOptions();
|
|
10980
10977
|
const history = useEditorHistory({
|
|
10981
10978
|
slides,
|
|
10982
10979
|
canvasSize,
|
|
@@ -10986,6 +10983,7 @@ function useViewerBuildingBlocksCore(input) {
|
|
|
10986
10983
|
headerFooter: state.headerFooter,
|
|
10987
10984
|
loading,
|
|
10988
10985
|
error,
|
|
10986
|
+
maxHistoryEntries: resolveHistoryDepth(viewerOptions),
|
|
10989
10987
|
hasActivePointerInteraction,
|
|
10990
10988
|
pointerCommitNonce: state.pointerCommitNonce,
|
|
10991
10989
|
setSlides: state.setSlides,
|
|
@@ -11007,12 +11005,15 @@ function useViewerBuildingBlocksCore(input) {
|
|
|
11007
11005
|
activeMaster: state.activeMaster,
|
|
11008
11006
|
documentGridSpacing: state.viewProperties?.gridSpacing
|
|
11009
11007
|
});
|
|
11010
|
-
const {
|
|
11011
|
-
const { presentation, annotations, actionSoundHandlerRef } = usePresentationSetup({
|
|
11008
|
+
const { presentation, annotations, actionSoundHandlerRef, setExitModeHandler } = usePresentationSetup({
|
|
11012
11009
|
mode,
|
|
11013
11010
|
slides,
|
|
11014
11011
|
visibleSlideIndexes,
|
|
11015
11012
|
endWithBlackSlide: viewerOptions.advanced.slideShowEndWithBlackSlide,
|
|
11013
|
+
// File > Options > Advanced > "Prompt to keep ink annotations when
|
|
11014
|
+
// exiting" / "Show popup toolbar" while presenting.
|
|
11015
|
+
promptKeepInkAnnotations: viewerOptions.advanced.slideShowPromptKeepInkAnnotations,
|
|
11016
|
+
popupToolbarEnabled: viewerOptions.advanced.slideShowShowPopupToolbar,
|
|
11016
11017
|
activeSlideIndex,
|
|
11017
11018
|
containerRef,
|
|
11018
11019
|
content,
|
|
@@ -11042,8 +11043,13 @@ function useViewerBuildingBlocksCore(input) {
|
|
|
11042
11043
|
presentation,
|
|
11043
11044
|
annotations,
|
|
11044
11045
|
actionSoundHandlerRef,
|
|
11046
|
+
setExitModeHandler,
|
|
11045
11047
|
masterPseudoSlide,
|
|
11046
|
-
gridSpacingPx
|
|
11048
|
+
gridSpacingPx,
|
|
11049
|
+
// Multiplied against the pre-existing 2x baseline; see the matching
|
|
11050
|
+
// comment in `PowerPointViewer.tsx`.
|
|
11051
|
+
imageExportScale: 2 * resolveImageResolutionScale(viewerOptions),
|
|
11052
|
+
viewerOptions
|
|
11047
11053
|
};
|
|
11048
11054
|
}
|
|
11049
11055
|
function useViewerBuildingBlocksState(input) {
|
|
@@ -11071,7 +11077,10 @@ function useViewerBuildingBlocksState(input) {
|
|
|
11071
11077
|
presentation,
|
|
11072
11078
|
annotations,
|
|
11073
11079
|
actionSoundHandlerRef,
|
|
11074
|
-
gridSpacingPx
|
|
11080
|
+
gridSpacingPx,
|
|
11081
|
+
imageExportScale,
|
|
11082
|
+
setExitModeHandler,
|
|
11083
|
+
viewerOptions
|
|
11075
11084
|
} = core;
|
|
11076
11085
|
const dialogs = useViewerDialogs({
|
|
11077
11086
|
mode,
|
|
@@ -11142,7 +11151,13 @@ function useViewerBuildingBlocksState(input) {
|
|
|
11142
11151
|
content,
|
|
11143
11152
|
filePath,
|
|
11144
11153
|
autosaveEnabled,
|
|
11154
|
+
// Trust Center > "Allow external content": same gate `PowerPointViewer`
|
|
11155
|
+
// applies, so the headless building-blocks API loads http(s) images
|
|
11156
|
+
// under the same default-off, core-side SSRF/privacy guard.
|
|
11157
|
+
allowExternalImages: viewerOptions.trust.allowExternalContent,
|
|
11145
11158
|
canEdit,
|
|
11159
|
+
promptKeepInkAnnotations: viewerOptions.advanced.slideShowPromptKeepInkAnnotations,
|
|
11160
|
+
imageExportScale,
|
|
11146
11161
|
mode,
|
|
11147
11162
|
slides,
|
|
11148
11163
|
activeSlide,
|
|
@@ -11160,6 +11175,7 @@ function useViewerBuildingBlocksState(input) {
|
|
|
11160
11175
|
onSelectionChange,
|
|
11161
11176
|
onSlideCountChange
|
|
11162
11177
|
});
|
|
11178
|
+
setExitModeHandler(handleSetMode);
|
|
11163
11179
|
return {
|
|
11164
11180
|
dialogs,
|
|
11165
11181
|
editorOps,
|
|
@@ -11195,6 +11211,7 @@ function useViewerBuildingBlocks(input) {
|
|
|
11195
11211
|
onOpenHeaderFooter,
|
|
11196
11212
|
onOpenShareDialog
|
|
11197
11213
|
} = input;
|
|
11214
|
+
const { t } = useTranslation();
|
|
11198
11215
|
const [content, setContent] = useState(incomingContent ?? null);
|
|
11199
11216
|
useEffect(() => {
|
|
11200
11217
|
setContent(incomingContent ?? null);
|
|
@@ -11229,7 +11246,8 @@ function useViewerBuildingBlocks(input) {
|
|
|
11229
11246
|
history,
|
|
11230
11247
|
presentation,
|
|
11231
11248
|
masterPseudoSlide,
|
|
11232
|
-
gridSpacingPx
|
|
11249
|
+
gridSpacingPx,
|
|
11250
|
+
viewerOptions
|
|
11233
11251
|
} = core;
|
|
11234
11252
|
const {
|
|
11235
11253
|
dialogs,
|
|
@@ -11305,7 +11323,11 @@ function useViewerBuildingBlocks(input) {
|
|
|
11305
11323
|
tableOps: editorOps.tableOps,
|
|
11306
11324
|
presentation,
|
|
11307
11325
|
findResults: editorOps.findReplace.findResults,
|
|
11308
|
-
findResultIndex: editorOps.findReplace.findResultIndex
|
|
11326
|
+
findResultIndex: editorOps.findReplace.findResultIndex,
|
|
11327
|
+
viewerOptions,
|
|
11328
|
+
buildHyperlinkConfirmMessage: (url) => `${t("pptx.options.trust.confirmHyperlinks")}
|
|
11329
|
+
|
|
11330
|
+
${url}`
|
|
11309
11331
|
});
|
|
11310
11332
|
return { toolbarProps, canvasProps, mode, loading, error, autosaveStatus };
|
|
11311
11333
|
}
|
|
@@ -11379,4 +11401,4 @@ function useResizablePanels() {
|
|
|
11379
11401
|
};
|
|
11380
11402
|
}
|
|
11381
11403
|
|
|
11382
|
-
export { ACTION_VERB_MAP, MIN_TOUCH_TARGET, computeToolbarVisibility, detectTargetType, isAudienceTab, parseAudienceNonce, parseEmailUrl, parseSlideFromUrl, renderToCanvas, scopeLayoutOptionsToActiveSlide, useAnimationPlayback, useAnnotationHandlers, useAudienceMode, useAutosave, useBroadcastFollower, useCanvasInteractions, useClipboardHandlers, useCollaborationLivePatch, useCollaborativeHistory, useCollaborativeState, useComments, useContentLifecycle, useDerivedElementState, useDerivedSlideState, useDialogCustomShows, useEditorHistory, useEditorOperations, useElementManipulation, useElementOperations, useExportHandlers, useExportSaveAs, useFindReplace, useFollowMode, useFontInjection, useGroupAlignLayerHandlers, useIOHandlers, useInsertElements, useIsMobile, useKeyboardInsets, useKeyboardShortcutWiring, useKeyboardShortcuts, useLayoutSwitching, useLoadContent, useMergeShapesHandler, useModalDismissDrag, usePointerHandlers, usePresenceTracking, usePresentationAnnotations, usePresentationKeyboard, usePresentationMode, usePresentationSetup, usePresenterWindow, usePrintHandlers, usePropertyHandlers, useRecoveryDetection, useReducedMotion, useRehearsalTimings, useResizablePanels, useSectionOperations, useSerialize, useSheetDismissDrag, useSlideManagement, useSlideNavigation, useSwipeNavigation, useTableOperations, useThemeHandlers, useThemeSwitching, useToolbarVisibility, useTouchGestures, useViewerBuildingBlocks, useViewerCoreState, useViewerDialogs, useViewerIntegration, useViewerOptions, useViewerState, useViewerUIState, useVirtualizedSlides, useYjsDocumentSync, useYjsProvider, useZoomNavigation, useZoomViewport };
|
|
11404
|
+
export { ACTION_VERB_MAP, MIN_TOUCH_TARGET, ViewerOptionsContext, computeToolbarVisibility, detectTargetType, isAudienceTab, parseAudienceNonce, parseEmailUrl, parseSlideFromUrl, renderToCanvas, scopeLayoutOptionsToActiveSlide, useAnimationPlayback, useAnnotationHandlers, useAudienceMode, useAutosave, useBroadcastFollower, useCanvasInteractions, useClipboardHandlers, useCollaborationLivePatch, useCollaborativeHistory, useCollaborativeState, useComments, useContentLifecycle, useDerivedElementState, useDerivedSlideState, useDialogCustomShows, useEditorHistory, useEditorOperations, useElementManipulation, useElementOperations, useExportHandlers, useExportSaveAs, useFindReplace, useFollowMode, useFontInjection, useGroupAlignLayerHandlers, useIOHandlers, useInsertElements, useIsMobile, useKeyboardInsets, useKeyboardShortcutWiring, useKeyboardShortcuts, useLayoutSwitching, useLoadContent, useMergeShapesHandler, useModalDismissDrag, usePointerHandlers, usePresenceTracking, usePresentationAnnotations, usePresentationKeyboard, usePresentationMode, usePresentationSetup, usePresenterWindow, usePrintHandlers, usePropertyHandlers, useRecoveryDetection, useReducedMotion, useRehearsalTimings, useResizablePanels, useSectionOperations, useSerialize, useSheetDismissDrag, useSlideManagement, useSlideNavigation, useSwipeNavigation, useTableOperations, useThemeHandlers, useThemeSwitching, useToolbarVisibility, useTouchGestures, useViewerBuildingBlocks, useViewerCoreState, useViewerDialogs, useViewerIntegration, useViewerOptions, useViewerOptionsContext, useViewerState, useViewerUIState, useVirtualizedSlides, useYjsDocumentSync, useYjsProvider, useZoomNavigation, useZoomViewport };
|