pptx-react-viewer 3.1.0 → 3.1.2
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 +58 -0
- package/dist/{AiChatPanel-WVORGKRT.js → AiChatPanel-4EYZDQXM.js} +24 -24
- package/dist/AiChatPanel-4EYZDQXM.js.br +0 -0
- package/dist/AiChatPanel-4EYZDQXM.js.gz +0 -0
- package/dist/{AiChatPanel-5LCCN7FG.mjs → AiChatPanel-UCFQIWOQ.mjs} +4 -4
- package/dist/AiChatPanel-UCFQIWOQ.mjs.br +0 -0
- package/dist/AiChatPanel-UCFQIWOQ.mjs.gz +0 -0
- package/dist/{Area3DChartScene-W6UZTRDP.mjs → Area3DChartScene-PMYXO4MR.mjs} +1 -1
- package/dist/Area3DChartScene-PMYXO4MR.mjs.br +0 -0
- package/dist/Area3DChartScene-PMYXO4MR.mjs.gz +0 -0
- package/dist/{Area3DChartScene-DY5CSLE2.js → Area3DChartScene-YBMC6NKY.js} +2 -2
- package/dist/Area3DChartScene-YBMC6NKY.js.br +0 -0
- package/dist/Area3DChartScene-YBMC6NKY.js.gz +0 -0
- package/dist/{Bar3DChartScene-7HZSPYG4.js → Bar3DChartScene-75DCA2ZA.js} +2 -2
- package/dist/Bar3DChartScene-75DCA2ZA.js.br +0 -0
- package/dist/Bar3DChartScene-75DCA2ZA.js.gz +0 -0
- package/dist/{Bar3DChartScene-FCWQEQLH.mjs → Bar3DChartScene-CEOI6SU6.mjs} +1 -1
- package/dist/Bar3DChartScene-CEOI6SU6.mjs.br +0 -0
- package/dist/Bar3DChartScene-CEOI6SU6.mjs.gz +0 -0
- package/dist/{Line3DChartScene-EPPWQOHS.mjs → Line3DChartScene-EZZKWUZR.mjs} +1 -1
- package/dist/Line3DChartScene-EZZKWUZR.mjs.br +0 -0
- package/dist/Line3DChartScene-EZZKWUZR.mjs.gz +0 -0
- package/dist/{Line3DChartScene-BKO24WYO.js → Line3DChartScene-STGX6N6V.js} +2 -2
- package/dist/Line3DChartScene-STGX6N6V.js.br +0 -0
- package/dist/Line3DChartScene-STGX6N6V.js.gz +0 -0
- package/dist/{Model3DScene-JFVRE5VL.js → Model3DScene-DWRD63FH.js} +2 -2
- package/dist/Model3DScene-DWRD63FH.js.br +0 -0
- package/dist/Model3DScene-DWRD63FH.js.gz +0 -0
- package/dist/{Model3DScene-IAY33GO2.mjs → Model3DScene-FGQJKWL6.mjs} +1 -1
- package/dist/Model3DScene-FGQJKWL6.mjs.br +0 -0
- package/dist/Model3DScene-FGQJKWL6.mjs.gz +0 -0
- package/dist/{PieChart3DScene-ZP5TSL62.mjs → PieChart3DScene-DH6RSJO6.mjs} +1 -1
- package/dist/PieChart3DScene-DH6RSJO6.mjs.br +0 -0
- package/dist/PieChart3DScene-DH6RSJO6.mjs.gz +0 -0
- package/dist/{PieChart3DScene-IPH7GLKU.js → PieChart3DScene-R3Y7OVVO.js} +2 -2
- package/dist/PieChart3DScene-R3Y7OVVO.js.br +0 -0
- package/dist/PieChart3DScene-R3Y7OVVO.js.gz +0 -0
- package/dist/PowerPointViewer-Cl6jBPNw.d.ts.map +1 -1
- package/dist/{SurfaceChart3DScene-DOMJGPAD.mjs → SurfaceChart3DScene-BMBU5RKI.mjs} +1 -1
- package/dist/SurfaceChart3DScene-BMBU5RKI.mjs.br +0 -0
- package/dist/SurfaceChart3DScene-BMBU5RKI.mjs.gz +0 -0
- package/dist/{SurfaceChart3DScene-TGDBVJSW.js → SurfaceChart3DScene-UM5HA3VO.js} +2 -2
- package/dist/SurfaceChart3DScene-UM5HA3VO.js.br +0 -0
- package/dist/SurfaceChart3DScene-UM5HA3VO.js.gz +0 -0
- package/dist/{chunk-7JZLE56X.js → chunk-2HLDBQH7.js} +157 -157
- package/dist/chunk-2HLDBQH7.js.br +0 -0
- package/dist/chunk-2HLDBQH7.js.gz +0 -0
- package/dist/{chunk-VMLKJDA5.mjs → chunk-4VVOTEQ4.mjs} +359 -336
- package/dist/chunk-4VVOTEQ4.mjs.br +0 -0
- package/dist/chunk-4VVOTEQ4.mjs.gz +0 -0
- package/dist/{chunk-T7BAPZBY.js → chunk-7ZQ2FZXE.js} +305 -45
- package/dist/chunk-7ZQ2FZXE.js.br +0 -0
- package/dist/chunk-7ZQ2FZXE.js.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-A5EUD6UU.js → chunk-MQEG5GOV.js} +1343 -1250
- package/dist/chunk-MQEG5GOV.js.br +0 -0
- package/dist/chunk-MQEG5GOV.js.gz +0 -0
- package/dist/{chunk-PQNZCSB7.mjs → chunk-O5DKWJDK.mjs} +1 -1
- package/dist/chunk-O5DKWJDK.mjs.br +0 -0
- package/dist/{chunk-PQNZCSB7.mjs.gz → chunk-O5DKWJDK.mjs.gz} +0 -0
- package/dist/{chunk-BP2L2KOZ.mjs → chunk-S546O4W2.mjs} +291 -45
- package/dist/chunk-S546O4W2.mjs.br +0 -0
- package/dist/chunk-S546O4W2.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-TIEUZCYQ.mjs → chunk-VLLZ3QL2.mjs} +265 -172
- package/dist/chunk-VLLZ3QL2.mjs.br +0 -0
- package/dist/chunk-VLLZ3QL2.mjs.gz +0 -0
- package/dist/{chunk-SNWAM2XJ.mjs → chunk-W3J6SNVE.mjs} +2 -2
- package/dist/chunk-W3J6SNVE.mjs.br +0 -0
- package/dist/chunk-W3J6SNVE.mjs.gz +0 -0
- package/dist/{chunk-POAZ53L5.js → chunk-WVIKFMNS.js} +725 -704
- package/dist/chunk-WVIKFMNS.js.br +0 -0
- package/dist/chunk-WVIKFMNS.js.gz +0 -0
- package/dist/{chunk-VQVC27WL.js → chunk-YNUYFR2T.js} +3 -3
- package/dist/chunk-YNUYFR2T.js.br +0 -0
- package/dist/chunk-YNUYFR2T.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 +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-5LCCN7FG.mjs.br +0 -0
- package/dist/AiChatPanel-5LCCN7FG.mjs.gz +0 -0
- package/dist/AiChatPanel-WVORGKRT.js.br +0 -0
- package/dist/AiChatPanel-WVORGKRT.js.gz +0 -0
- package/dist/Area3DChartScene-DY5CSLE2.js.br +0 -0
- package/dist/Area3DChartScene-DY5CSLE2.js.gz +0 -0
- package/dist/Area3DChartScene-W6UZTRDP.mjs.br +0 -0
- package/dist/Area3DChartScene-W6UZTRDP.mjs.gz +0 -0
- package/dist/Bar3DChartScene-7HZSPYG4.js.br +0 -0
- package/dist/Bar3DChartScene-7HZSPYG4.js.gz +0 -0
- package/dist/Bar3DChartScene-FCWQEQLH.mjs.br +0 -0
- package/dist/Bar3DChartScene-FCWQEQLH.mjs.gz +0 -0
- package/dist/Line3DChartScene-BKO24WYO.js.br +0 -0
- package/dist/Line3DChartScene-BKO24WYO.js.gz +0 -0
- package/dist/Line3DChartScene-EPPWQOHS.mjs.br +0 -0
- package/dist/Line3DChartScene-EPPWQOHS.mjs.gz +0 -0
- package/dist/Model3DScene-IAY33GO2.mjs.br +0 -0
- package/dist/Model3DScene-IAY33GO2.mjs.gz +0 -0
- package/dist/Model3DScene-JFVRE5VL.js.br +0 -0
- package/dist/Model3DScene-JFVRE5VL.js.gz +0 -0
- package/dist/PieChart3DScene-IPH7GLKU.js.br +0 -0
- package/dist/PieChart3DScene-IPH7GLKU.js.gz +0 -0
- package/dist/PieChart3DScene-ZP5TSL62.mjs.br +0 -0
- package/dist/PieChart3DScene-ZP5TSL62.mjs.gz +0 -0
- package/dist/SurfaceChart3DScene-DOMJGPAD.mjs.br +0 -0
- package/dist/SurfaceChart3DScene-DOMJGPAD.mjs.gz +0 -0
- package/dist/SurfaceChart3DScene-TGDBVJSW.js.br +0 -0
- package/dist/SurfaceChart3DScene-TGDBVJSW.js.gz +0 -0
- package/dist/chunk-7JZLE56X.js.br +0 -0
- package/dist/chunk-7JZLE56X.js.gz +0 -0
- package/dist/chunk-A5EUD6UU.js.br +0 -0
- package/dist/chunk-A5EUD6UU.js.gz +0 -0
- package/dist/chunk-BP2L2KOZ.mjs.br +0 -0
- package/dist/chunk-BP2L2KOZ.mjs.gz +0 -0
- package/dist/chunk-MKPSUHUH.mjs.br +0 -0
- package/dist/chunk-MKPSUHUH.mjs.gz +0 -0
- package/dist/chunk-PIUB7R2K.js.br +0 -0
- package/dist/chunk-PIUB7R2K.js.gz +0 -0
- package/dist/chunk-POAZ53L5.js.br +0 -0
- package/dist/chunk-POAZ53L5.js.gz +0 -0
- package/dist/chunk-PQNZCSB7.mjs.br +0 -0
- package/dist/chunk-SNWAM2XJ.mjs.br +0 -0
- package/dist/chunk-SNWAM2XJ.mjs.gz +0 -0
- package/dist/chunk-T7BAPZBY.js.br +0 -0
- package/dist/chunk-T7BAPZBY.js.gz +0 -0
- package/dist/chunk-TIEUZCYQ.mjs.br +0 -0
- package/dist/chunk-TIEUZCYQ.mjs.gz +0 -0
- package/dist/chunk-VMLKJDA5.mjs.br +0 -0
- package/dist/chunk-VMLKJDA5.mjs.gz +0 -0
- package/dist/chunk-VQVC27WL.js.br +0 -0
- package/dist/chunk-VQVC27WL.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-W3J6SNVE.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-S546O4W2.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;
|
|
@@ -6546,13 +6546,15 @@ function createTableStructHandlers(input) {
|
|
|
6546
6546
|
elementLookup,
|
|
6547
6547
|
setTableEditorState,
|
|
6548
6548
|
ops,
|
|
6549
|
-
history
|
|
6549
|
+
history,
|
|
6550
|
+
transformCommittedText
|
|
6550
6551
|
} = input;
|
|
6551
|
-
const handleCommitCellEdit = (elementId, rowIndex, colIndex,
|
|
6552
|
+
const handleCommitCellEdit = (elementId, rowIndex, colIndex, rawText) => {
|
|
6552
6553
|
const el = elementLookup.get(elementId);
|
|
6553
6554
|
if (!el || el.type !== "table") {
|
|
6554
6555
|
return;
|
|
6555
6556
|
}
|
|
6557
|
+
const text = transformCommittedText ? transformCommittedText(rawText) : rawText;
|
|
6556
6558
|
const updates = {};
|
|
6557
6559
|
if (el.tableData) {
|
|
6558
6560
|
updates.tableData = setCellText(el, rowIndex, colIndex, text).tableData;
|
|
@@ -6743,6 +6745,144 @@ async function renderToCanvas(element, options = {}) {
|
|
|
6743
6745
|
});
|
|
6744
6746
|
}
|
|
6745
6747
|
|
|
6748
|
+
// src/viewer/hooks/useExportSaveAs.ts
|
|
6749
|
+
function useExportSaveAs(input) {
|
|
6750
|
+
const {
|
|
6751
|
+
slides,
|
|
6752
|
+
templateElementsBySlideId,
|
|
6753
|
+
filePath,
|
|
6754
|
+
handlerRef,
|
|
6755
|
+
headerFooter,
|
|
6756
|
+
presentationProperties,
|
|
6757
|
+
customShows,
|
|
6758
|
+
sections,
|
|
6759
|
+
coreProperties,
|
|
6760
|
+
appProperties,
|
|
6761
|
+
customProperties,
|
|
6762
|
+
tagCollections,
|
|
6763
|
+
slideMasters,
|
|
6764
|
+
notesMaster,
|
|
6765
|
+
handoutMaster,
|
|
6766
|
+
guides,
|
|
6767
|
+
activeSlideIndexForGuides,
|
|
6768
|
+
theme,
|
|
6769
|
+
canvasSize,
|
|
6770
|
+
slideSizeEmu,
|
|
6771
|
+
password
|
|
6772
|
+
} = input;
|
|
6773
|
+
const handleSaveAsFormat = async (format) => {
|
|
6774
|
+
const handler = handlerRef.current;
|
|
6775
|
+
if (!handler) {
|
|
6776
|
+
return;
|
|
6777
|
+
}
|
|
6778
|
+
const downloadName = savedPresentationFileName(filePath, format);
|
|
6779
|
+
try {
|
|
6780
|
+
const data = await buildSaveAsData(handler, format);
|
|
6781
|
+
const blob = new Blob([data], {
|
|
6782
|
+
type: "application/vnd.openxmlformats-officedocument.presentationml.presentation"
|
|
6783
|
+
});
|
|
6784
|
+
downloadBlob(blob, downloadName);
|
|
6785
|
+
} catch (err) {
|
|
6786
|
+
console.error(`[PowerPointViewer] Save as .${format} failed:`, err);
|
|
6787
|
+
}
|
|
6788
|
+
};
|
|
6789
|
+
const buildSaveAsData = async (handler, format) => {
|
|
6790
|
+
const slidesWithGuides = slides.map((slide, idx) => {
|
|
6791
|
+
if (idx !== activeSlideIndexForGuides) {
|
|
6792
|
+
return slide;
|
|
6793
|
+
}
|
|
6794
|
+
const pptxGuides = guides.map((g) => ({
|
|
6795
|
+
id: g.id,
|
|
6796
|
+
orientation: g.axis === "h" ? "horz" : "vert",
|
|
6797
|
+
positionEmu: guidePxToEmu(g.position)
|
|
6798
|
+
}));
|
|
6799
|
+
return {
|
|
6800
|
+
...slide,
|
|
6801
|
+
guides: pptxGuides.length > 0 ? pptxGuides : void 0
|
|
6802
|
+
};
|
|
6803
|
+
});
|
|
6804
|
+
const slidesToSave = buildSaveSlides(slidesWithGuides, templateElementsBySlideId);
|
|
6805
|
+
const saveOptions = {
|
|
6806
|
+
// Save As shares Save's slide-size decision; leaving it out here is how
|
|
6807
|
+
// a preset picked in the inspector reached one save path and not the other.
|
|
6808
|
+
slideSize: resolveSlideSizeSelection({ current: slideSizeEmu, canvas: canvasSize }).size,
|
|
6809
|
+
headerFooter,
|
|
6810
|
+
presentationProperties,
|
|
6811
|
+
customShows: customShows.length > 0 ? customShows : void 0,
|
|
6812
|
+
sections: sections.length > 0 ? sections : void 0,
|
|
6813
|
+
coreProperties: coreProperties ?? void 0,
|
|
6814
|
+
appProperties: appProperties ?? void 0,
|
|
6815
|
+
customProperties: customProperties.length > 0 ? customProperties : void 0,
|
|
6816
|
+
tags: tagCollections.length > 0 ? tagCollections : void 0,
|
|
6817
|
+
slideMasters,
|
|
6818
|
+
notesMaster,
|
|
6819
|
+
handoutMaster,
|
|
6820
|
+
outputFormat: format
|
|
6821
|
+
};
|
|
6822
|
+
return saveDeckWithPassword(handler, slidesToSave, saveOptions, password);
|
|
6823
|
+
};
|
|
6824
|
+
const handleExportJson = () => {
|
|
6825
|
+
const sourceName = filePath ? filePath.replace(/\\/gu, "/").split("/").pop() : void 0;
|
|
6826
|
+
const slideSize = resolveSlideSizeSelection({ current: slideSizeEmu, canvas: canvasSize }).size;
|
|
6827
|
+
const data = {
|
|
6828
|
+
slides: buildSaveSlides(slides, templateElementsBySlideId),
|
|
6829
|
+
width: canvasSize.width,
|
|
6830
|
+
height: canvasSize.height,
|
|
6831
|
+
widthEmu: slideSize.widthEmu,
|
|
6832
|
+
heightEmu: slideSize.heightEmu,
|
|
6833
|
+
slideSizeType: slideSize.type === "" ? void 0 : slideSize.type,
|
|
6834
|
+
theme,
|
|
6835
|
+
headerFooter,
|
|
6836
|
+
presentationProperties,
|
|
6837
|
+
customShows: customShows.length > 0 ? customShows : void 0,
|
|
6838
|
+
sections: sections.length > 0 ? sections : void 0,
|
|
6839
|
+
coreProperties: coreProperties ?? void 0,
|
|
6840
|
+
appProperties: appProperties ?? void 0,
|
|
6841
|
+
customProperties: customProperties.length > 0 ? customProperties : void 0,
|
|
6842
|
+
tags: tagCollections.length > 0 ? tagCollections : void 0,
|
|
6843
|
+
notesMaster,
|
|
6844
|
+
handoutMaster
|
|
6845
|
+
};
|
|
6846
|
+
try {
|
|
6847
|
+
exportDeckJson(data, sourceName);
|
|
6848
|
+
} catch (err) {
|
|
6849
|
+
console.error("[PowerPointViewer] JSON export failed:", err);
|
|
6850
|
+
}
|
|
6851
|
+
};
|
|
6852
|
+
const handleSaveAsPptx = () => {
|
|
6853
|
+
void handleSaveAsFormat("pptx");
|
|
6854
|
+
};
|
|
6855
|
+
const handleSaveAsPpsx = () => {
|
|
6856
|
+
void handleSaveAsFormat("ppsx");
|
|
6857
|
+
};
|
|
6858
|
+
const handleSaveAsPptm = () => {
|
|
6859
|
+
void handleSaveAsFormat("pptm");
|
|
6860
|
+
};
|
|
6861
|
+
return {
|
|
6862
|
+
handleExportJson,
|
|
6863
|
+
handleSaveAsFormat,
|
|
6864
|
+
handleSaveAsPptx,
|
|
6865
|
+
handleSaveAsPpsx,
|
|
6866
|
+
handleSaveAsPptm
|
|
6867
|
+
};
|
|
6868
|
+
}
|
|
6869
|
+
|
|
6870
|
+
// src/viewer/utils/dom-helpers.ts
|
|
6871
|
+
function safePrompt(message, defaultValue) {
|
|
6872
|
+
try {
|
|
6873
|
+
return window.prompt(message, defaultValue);
|
|
6874
|
+
} catch {
|
|
6875
|
+
return null;
|
|
6876
|
+
}
|
|
6877
|
+
}
|
|
6878
|
+
function safeConfirm(message) {
|
|
6879
|
+
try {
|
|
6880
|
+
return window.confirm(message);
|
|
6881
|
+
} catch {
|
|
6882
|
+
return false;
|
|
6883
|
+
}
|
|
6884
|
+
}
|
|
6885
|
+
|
|
6746
6886
|
// src/viewer/utils/export-helpers.ts
|
|
6747
6887
|
async function renderElementToCanvas(element, scale = 2, backgroundColor) {
|
|
6748
6888
|
const canvas = await renderToCanvas(element, {
|
|
@@ -7052,194 +7192,6 @@ function exportAllSlidesToSvg(data, options = {}) {
|
|
|
7052
7192
|
return results;
|
|
7053
7193
|
}
|
|
7054
7194
|
|
|
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
7195
|
// src/viewer/hooks/useExportHandlers.ts
|
|
7244
7196
|
function useExportHandlers(input) {
|
|
7245
7197
|
const {
|
|
@@ -7251,7 +7203,6 @@ function useExportHandlers(input) {
|
|
|
7251
7203
|
canvasStageRef,
|
|
7252
7204
|
setActiveSlideIndex,
|
|
7253
7205
|
handlerRef,
|
|
7254
|
-
serializeSlides,
|
|
7255
7206
|
headerFooter,
|
|
7256
7207
|
presentationProperties,
|
|
7257
7208
|
customShows,
|
|
@@ -7268,23 +7219,16 @@ function useExportHandlers(input) {
|
|
|
7268
7219
|
theme,
|
|
7269
7220
|
canvasSize,
|
|
7270
7221
|
slideSizeEmu,
|
|
7271
|
-
password
|
|
7222
|
+
password,
|
|
7223
|
+
imageExportScale
|
|
7272
7224
|
} = input;
|
|
7273
7225
|
const [exportModalOpen, setExportModalOpen] = useState(false);
|
|
7274
7226
|
const [exportModalTitle, setExportModalTitle] = useState("");
|
|
7275
7227
|
const [exportProgress, setExportProgress] = useState(0);
|
|
7276
7228
|
const [exportStatusMessage, setExportStatusMessage] = useState("");
|
|
7277
7229
|
const exportAbortRef = useRef(null);
|
|
7278
|
-
const modalControls = {
|
|
7279
|
-
setExportModalOpen,
|
|
7280
|
-
setExportModalTitle,
|
|
7281
|
-
setExportProgress,
|
|
7282
|
-
setExportStatusMessage,
|
|
7283
|
-
exportAbortRef
|
|
7284
|
-
};
|
|
7285
7230
|
const {
|
|
7286
7231
|
handleExportJson,
|
|
7287
|
-
handlePackageForSharing,
|
|
7288
7232
|
handleSaveAsFormat,
|
|
7289
7233
|
handleSaveAsPptx,
|
|
7290
7234
|
handleSaveAsPpsx,
|
|
@@ -7294,7 +7238,6 @@ function useExportHandlers(input) {
|
|
|
7294
7238
|
templateElementsBySlideId,
|
|
7295
7239
|
filePath,
|
|
7296
7240
|
handlerRef,
|
|
7297
|
-
serializeSlides,
|
|
7298
7241
|
headerFooter,
|
|
7299
7242
|
presentationProperties,
|
|
7300
7243
|
customShows,
|
|
@@ -7311,7 +7254,6 @@ function useExportHandlers(input) {
|
|
|
7311
7254
|
theme,
|
|
7312
7255
|
canvasSize,
|
|
7313
7256
|
slideSizeEmu,
|
|
7314
|
-
modalControls,
|
|
7315
7257
|
password
|
|
7316
7258
|
});
|
|
7317
7259
|
const handleExportPng = useCallback(async () => {
|
|
@@ -7321,12 +7263,13 @@ function useExportHandlers(input) {
|
|
|
7321
7263
|
}
|
|
7322
7264
|
try {
|
|
7323
7265
|
await exportSlideAsPng(stageEl, activeSlideIndex, {
|
|
7324
|
-
backgroundColor: activeSlide?.backgroundColor
|
|
7266
|
+
backgroundColor: activeSlide?.backgroundColor,
|
|
7267
|
+
scale: imageExportScale
|
|
7325
7268
|
});
|
|
7326
7269
|
} catch (err) {
|
|
7327
7270
|
console.error("[PowerPointViewer] PNG export failed:", err);
|
|
7328
7271
|
}
|
|
7329
|
-
}, [canvasStageRef, activeSlideIndex, activeSlide?.backgroundColor]);
|
|
7272
|
+
}, [canvasStageRef, activeSlideIndex, activeSlide?.backgroundColor, imageExportScale]);
|
|
7330
7273
|
const handleExportPdf = useCallback(async () => {
|
|
7331
7274
|
if (!canvasStageRef.current) {
|
|
7332
7275
|
return;
|
|
@@ -7345,7 +7288,7 @@ function useExportHandlers(input) {
|
|
|
7345
7288
|
activeSlideIndex,
|
|
7346
7289
|
"presentation.pdf",
|
|
7347
7290
|
{
|
|
7348
|
-
scale:
|
|
7291
|
+
scale: imageExportScale,
|
|
7349
7292
|
onProgress: (current, total) => {
|
|
7350
7293
|
setExportProgress(slideProgressPercent(current, total));
|
|
7351
7294
|
setExportStatusMessage(slideStatusLabel("Rendering", current, total));
|
|
@@ -7368,7 +7311,7 @@ function useExportHandlers(input) {
|
|
|
7368
7311
|
exportAbortRef.current = null;
|
|
7369
7312
|
setExportModalOpen(false);
|
|
7370
7313
|
}
|
|
7371
|
-
}, [canvasStageRef, slides.length, setActiveSlideIndex, activeSlideIndex]);
|
|
7314
|
+
}, [canvasStageRef, slides.length, setActiveSlideIndex, activeSlideIndex, imageExportScale]);
|
|
7372
7315
|
const handleExportNotesPdf = useCallback(async () => {
|
|
7373
7316
|
if (!canvasStageRef.current) {
|
|
7374
7317
|
return;
|
|
@@ -7389,7 +7332,7 @@ function useExportHandlers(input) {
|
|
|
7389
7332
|
slideNotes,
|
|
7390
7333
|
"presentation-notes.pdf",
|
|
7391
7334
|
{
|
|
7392
|
-
scale:
|
|
7335
|
+
scale: imageExportScale,
|
|
7393
7336
|
onProgress: (current, total) => {
|
|
7394
7337
|
setExportProgress(slideProgressPercent(current, total));
|
|
7395
7338
|
setExportStatusMessage(slideStatusLabel("Rendering", current, total));
|
|
@@ -7412,7 +7355,7 @@ function useExportHandlers(input) {
|
|
|
7412
7355
|
exportAbortRef.current = null;
|
|
7413
7356
|
setExportModalOpen(false);
|
|
7414
7357
|
}
|
|
7415
|
-
}, [canvasStageRef, slides, setActiveSlideIndex, activeSlideIndex]);
|
|
7358
|
+
}, [canvasStageRef, slides, setActiveSlideIndex, activeSlideIndex, imageExportScale]);
|
|
7416
7359
|
const handleCopySlideAsImage = useCallback(async () => {
|
|
7417
7360
|
const stageEl = canvasStageRef.current;
|
|
7418
7361
|
if (!stageEl) {
|
|
@@ -7420,12 +7363,13 @@ function useExportHandlers(input) {
|
|
|
7420
7363
|
}
|
|
7421
7364
|
try {
|
|
7422
7365
|
await copySlideToClipboard(stageEl, {
|
|
7423
|
-
backgroundColor: activeSlide?.backgroundColor
|
|
7366
|
+
backgroundColor: activeSlide?.backgroundColor,
|
|
7367
|
+
scale: imageExportScale
|
|
7424
7368
|
});
|
|
7425
7369
|
} catch (err) {
|
|
7426
7370
|
console.error("[PowerPointViewer] Copy slide as image failed:", err);
|
|
7427
7371
|
}
|
|
7428
|
-
}, [canvasStageRef, activeSlide?.backgroundColor]);
|
|
7372
|
+
}, [canvasStageRef, activeSlide?.backgroundColor, imageExportScale]);
|
|
7429
7373
|
const handleExportVideo = useCallback(async () => {
|
|
7430
7374
|
if (!canvasStageRef.current) {
|
|
7431
7375
|
return;
|
|
@@ -7522,7 +7466,6 @@ function useExportHandlers(input) {
|
|
|
7522
7466
|
handleExportVideo,
|
|
7523
7467
|
handleExportGif,
|
|
7524
7468
|
handleExportJson,
|
|
7525
|
-
handlePackageForSharing,
|
|
7526
7469
|
handleSaveAsFormat,
|
|
7527
7470
|
handleSaveAsPptx,
|
|
7528
7471
|
handleSaveAsPpsx,
|
|
@@ -7534,95 +7477,96 @@ function useExportHandlers(input) {
|
|
|
7534
7477
|
exportStatusMessage
|
|
7535
7478
|
};
|
|
7536
7479
|
}
|
|
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;
|
|
7480
|
+
var ViewerOptionsContext = createContext(DEFAULT_VIEWER_OPTIONS);
|
|
7481
|
+
function useViewerOptionsContext() {
|
|
7482
|
+
return useContext(ViewerOptionsContext);
|
|
7566
7483
|
}
|
|
7484
|
+
|
|
7485
|
+
// src/viewer/hooks/usePrintHandlers.ts
|
|
7567
7486
|
function usePrintHandlers(input) {
|
|
7568
7487
|
const { slides, activeSlideIndex, canvasStageRef, setActiveSlideIndex, pptxData } = input;
|
|
7569
7488
|
const [isPrintDialogOpen, setIsPrintDialogOpen] = useState(false);
|
|
7489
|
+
const { t } = useTranslation();
|
|
7490
|
+
const viewerOptions = useViewerOptionsContext();
|
|
7491
|
+
const includeHiddenSlides = viewerOptions.advanced.printHiddenSlides;
|
|
7492
|
+
const printRasterScale = (viewerOptions.advanced.printHighQuality ? 4 : 3) * resolveImageResolutionScale(viewerOptions);
|
|
7570
7493
|
const handlePrint = () => {
|
|
7571
7494
|
setIsPrintDialogOpen(true);
|
|
7572
7495
|
};
|
|
7573
7496
|
const handlePrintSvg = async (settings) => {
|
|
7574
7497
|
setIsPrintDialogOpen(false);
|
|
7498
|
+
const printWindow = openPendingPrintWindow(t("pptx.print.preparingToPrint"));
|
|
7499
|
+
if (!printWindow) {
|
|
7500
|
+
console.warn(
|
|
7501
|
+
"[PowerPointViewer] Print window was blocked by the browser. Allow popups for this site to print."
|
|
7502
|
+
);
|
|
7503
|
+
return;
|
|
7504
|
+
}
|
|
7575
7505
|
if (!pptxData || settings.printWhat !== "slides") {
|
|
7576
|
-
return
|
|
7506
|
+
return runRasterPrint(printWindow, settings);
|
|
7577
7507
|
}
|
|
7578
7508
|
const colorFilter = computeColorFilter(settings.colorMode);
|
|
7579
|
-
const slideIndices =
|
|
7580
|
-
|
|
7581
|
-
|
|
7582
|
-
|
|
7583
|
-
|
|
7584
|
-
|
|
7509
|
+
const slideIndices = filterHiddenSlideIndices(
|
|
7510
|
+
computeSlideIndices(
|
|
7511
|
+
settings.slideRange,
|
|
7512
|
+
activeSlideIndex,
|
|
7513
|
+
slides.length,
|
|
7514
|
+
settings.customRangeFrom,
|
|
7515
|
+
settings.customRangeTo
|
|
7516
|
+
),
|
|
7517
|
+
slides,
|
|
7518
|
+
includeHiddenSlides
|
|
7585
7519
|
);
|
|
7586
7520
|
try {
|
|
7587
7521
|
const svgs = exportAllSlidesToSvg(pptxData, {
|
|
7588
7522
|
slideIndices
|
|
7589
7523
|
});
|
|
7590
7524
|
if (svgs.length === 0) {
|
|
7525
|
+
printWindow.close();
|
|
7591
7526
|
return;
|
|
7592
7527
|
}
|
|
7593
7528
|
const printDoc = buildPrintDocument(svgs, pptxData.width, pptxData.height, {
|
|
7594
7529
|
title: "Slides (Vector)",
|
|
7595
7530
|
orientation: settings.orientation,
|
|
7596
|
-
colorFilter
|
|
7531
|
+
colorFilter,
|
|
7532
|
+
scaleToFit: settings.scaleToFit
|
|
7597
7533
|
});
|
|
7598
|
-
|
|
7534
|
+
finishPrintWindow(printWindow, printDoc);
|
|
7599
7535
|
} catch (err) {
|
|
7600
7536
|
console.warn("[PowerPointViewer] SVG print path failed, falling back to raster:", err);
|
|
7601
|
-
return
|
|
7537
|
+
return runRasterPrint(printWindow, settings);
|
|
7602
7538
|
}
|
|
7603
7539
|
};
|
|
7604
|
-
const
|
|
7605
|
-
setIsPrintDialogOpen(false);
|
|
7540
|
+
const runRasterPrint = async (printWindow, settings) => {
|
|
7606
7541
|
const colorFilter = computeColorFilter(settings.colorMode);
|
|
7607
|
-
const slideIndices =
|
|
7608
|
-
|
|
7609
|
-
|
|
7610
|
-
|
|
7611
|
-
|
|
7612
|
-
|
|
7542
|
+
const slideIndices = filterHiddenSlideIndices(
|
|
7543
|
+
computeSlideIndices(
|
|
7544
|
+
settings.slideRange,
|
|
7545
|
+
activeSlideIndex,
|
|
7546
|
+
slides.length,
|
|
7547
|
+
settings.customRangeFrom,
|
|
7548
|
+
settings.customRangeTo
|
|
7549
|
+
),
|
|
7550
|
+
slides,
|
|
7551
|
+
includeHiddenSlides
|
|
7613
7552
|
);
|
|
7614
7553
|
if (settings.printWhat === "outline") {
|
|
7615
|
-
|
|
7616
|
-
|
|
7617
|
-
|
|
7618
|
-
|
|
7619
|
-
|
|
7620
|
-
|
|
7554
|
+
finishPrintWindow(
|
|
7555
|
+
printWindow,
|
|
7556
|
+
buildPrintHtmlDocument({
|
|
7557
|
+
title: "Outline",
|
|
7558
|
+
bodyHtml: `<div class="outline-page">${buildOutlineHtml(slideIndices, slides)}</div>`,
|
|
7559
|
+
orientation: settings.orientation,
|
|
7560
|
+
colorFilter,
|
|
7561
|
+
frameSlides: settings.frameSlides,
|
|
7562
|
+
scaleToFit: settings.scaleToFit
|
|
7563
|
+
})
|
|
7621
7564
|
);
|
|
7622
7565
|
return;
|
|
7623
7566
|
}
|
|
7624
7567
|
try {
|
|
7625
7568
|
if (!canvasStageRef.current) {
|
|
7569
|
+
printWindow.close();
|
|
7626
7570
|
return;
|
|
7627
7571
|
}
|
|
7628
7572
|
const allImages = await captureAllSlidesAsPngDataUrls(
|
|
@@ -7630,46 +7574,70 @@ function usePrintHandlers(input) {
|
|
|
7630
7574
|
slides.length,
|
|
7631
7575
|
setActiveSlideIndex,
|
|
7632
7576
|
activeSlideIndex,
|
|
7633
|
-
{ scale:
|
|
7577
|
+
{ scale: printRasterScale }
|
|
7634
7578
|
);
|
|
7635
7579
|
if (allImages.length === 0) {
|
|
7580
|
+
printWindow.close();
|
|
7636
7581
|
return;
|
|
7637
7582
|
}
|
|
7638
7583
|
const slideImages = slideIndices.map((idx) => allImages[idx]).filter(Boolean);
|
|
7639
7584
|
if (settings.printWhat === "slides") {
|
|
7640
|
-
|
|
7641
|
-
|
|
7642
|
-
|
|
7643
|
-
|
|
7644
|
-
|
|
7645
|
-
|
|
7585
|
+
finishPrintWindow(
|
|
7586
|
+
printWindow,
|
|
7587
|
+
buildPrintHtmlDocument({
|
|
7588
|
+
title: "Slides",
|
|
7589
|
+
bodyHtml: buildSlidesHtml(slideImages, slideIndices),
|
|
7590
|
+
orientation: settings.orientation,
|
|
7591
|
+
colorFilter,
|
|
7592
|
+
frameSlides: settings.frameSlides,
|
|
7593
|
+
scaleToFit: settings.scaleToFit
|
|
7594
|
+
})
|
|
7646
7595
|
);
|
|
7647
7596
|
return;
|
|
7648
7597
|
}
|
|
7649
7598
|
if (settings.printWhat === "notes") {
|
|
7650
|
-
|
|
7651
|
-
|
|
7652
|
-
|
|
7653
|
-
|
|
7654
|
-
|
|
7655
|
-
|
|
7599
|
+
finishPrintWindow(
|
|
7600
|
+
printWindow,
|
|
7601
|
+
buildPrintHtmlDocument({
|
|
7602
|
+
title: "Notes Pages",
|
|
7603
|
+
bodyHtml: buildNotesHtml(slideImages, slideIndices, slides),
|
|
7604
|
+
orientation: "portrait",
|
|
7605
|
+
colorFilter,
|
|
7606
|
+
frameSlides: settings.frameSlides,
|
|
7607
|
+
scaleToFit: settings.scaleToFit
|
|
7608
|
+
})
|
|
7656
7609
|
);
|
|
7657
7610
|
return;
|
|
7658
7611
|
}
|
|
7659
7612
|
if (settings.printWhat === "handouts") {
|
|
7660
7613
|
const spp = settings.slidesPerPage;
|
|
7661
|
-
|
|
7662
|
-
|
|
7663
|
-
|
|
7664
|
-
|
|
7665
|
-
|
|
7666
|
-
|
|
7614
|
+
finishPrintWindow(
|
|
7615
|
+
printWindow,
|
|
7616
|
+
buildPrintHtmlDocument({
|
|
7617
|
+
title: `Handout ${spp} per page`,
|
|
7618
|
+
bodyHtml: buildHandoutsHtml(slideImages, slideIndices, spp),
|
|
7619
|
+
orientation: "portrait",
|
|
7620
|
+
colorFilter,
|
|
7621
|
+
frameSlides: settings.frameSlides,
|
|
7622
|
+
scaleToFit: settings.scaleToFit
|
|
7623
|
+
})
|
|
7667
7624
|
);
|
|
7668
7625
|
}
|
|
7669
7626
|
} catch (err) {
|
|
7670
7627
|
console.error("[PowerPointViewer] Print layout failed:", err);
|
|
7671
7628
|
}
|
|
7672
7629
|
};
|
|
7630
|
+
const handlePrintWithSettings = async (settings) => {
|
|
7631
|
+
setIsPrintDialogOpen(false);
|
|
7632
|
+
const printWindow = openPendingPrintWindow(t("pptx.print.preparingToPrint"));
|
|
7633
|
+
if (!printWindow) {
|
|
7634
|
+
console.warn(
|
|
7635
|
+
"[PowerPointViewer] Print window was blocked by the browser. Allow popups for this site to print."
|
|
7636
|
+
);
|
|
7637
|
+
return;
|
|
7638
|
+
}
|
|
7639
|
+
return runRasterPrint(printWindow, settings);
|
|
7640
|
+
};
|
|
7673
7641
|
return {
|
|
7674
7642
|
handlePrint,
|
|
7675
7643
|
handlePrintWithSettings,
|
|
@@ -8460,11 +8428,12 @@ function useAnnotationHandlers(input) {
|
|
|
8460
8428
|
presentation.enterPresentMode();
|
|
8461
8429
|
} else if (mode === "present" && annotations.hasAnyAnnotations) {
|
|
8462
8430
|
stopAllPersistentAudio();
|
|
8463
|
-
pendingModeAfterAnnotationsRef.current = nextMode;
|
|
8464
8431
|
if (promptKeepInkAnnotations) {
|
|
8432
|
+
pendingModeAfterAnnotationsRef.current = nextMode;
|
|
8465
8433
|
setShowKeepAnnotationsDialog(true);
|
|
8466
8434
|
} else {
|
|
8467
|
-
|
|
8435
|
+
annotations.clearAllAnnotations();
|
|
8436
|
+
setMode(nextMode);
|
|
8468
8437
|
}
|
|
8469
8438
|
} else {
|
|
8470
8439
|
if (mode === "present") {
|
|
@@ -8473,14 +8442,7 @@ function useAnnotationHandlers(input) {
|
|
|
8473
8442
|
setMode(nextMode);
|
|
8474
8443
|
}
|
|
8475
8444
|
},
|
|
8476
|
-
[
|
|
8477
|
-
presentation,
|
|
8478
|
-
mode,
|
|
8479
|
-
annotations.hasAnyAnnotations,
|
|
8480
|
-
promptKeepInkAnnotations,
|
|
8481
|
-
handleKeepAnnotations,
|
|
8482
|
-
setMode
|
|
8483
|
-
]
|
|
8445
|
+
[presentation, mode, annotations, promptKeepInkAnnotations, setMode]
|
|
8484
8446
|
);
|
|
8485
8447
|
const handleDiscardAnnotations = useCallback(() => {
|
|
8486
8448
|
annotations.clearAllAnnotations();
|
|
@@ -8678,8 +8640,7 @@ function usePresentationSetup(input) {
|
|
|
8678
8640
|
onToggleSubtitles
|
|
8679
8641
|
} = input;
|
|
8680
8642
|
const actionSoundHandlerRef = useRef(null);
|
|
8681
|
-
const
|
|
8682
|
-
const pendingModeRef = useRef("edit");
|
|
8643
|
+
const exitModeHandlerRef = useRef(null);
|
|
8683
8644
|
const annotations = usePresentationAnnotations({
|
|
8684
8645
|
isActive: mode === "present",
|
|
8685
8646
|
activeSlideIndex,
|
|
@@ -8696,16 +8657,19 @@ function usePresentationSetup(input) {
|
|
|
8696
8657
|
if (mode === "present" && nextMode !== "present" && !mayLeaveSlideShow()) {
|
|
8697
8658
|
return;
|
|
8698
8659
|
}
|
|
8699
|
-
if (mode === "present" && nextMode !== "present"
|
|
8700
|
-
|
|
8701
|
-
|
|
8702
|
-
|
|
8703
|
-
if (
|
|
8704
|
-
|
|
8705
|
-
|
|
8660
|
+
if (mode === "present" && nextMode !== "present") {
|
|
8661
|
+
stopAllPersistentAudio();
|
|
8662
|
+
stopAnimationSound();
|
|
8663
|
+
const exitHandler = exitModeHandlerRef.current;
|
|
8664
|
+
if (exitHandler) {
|
|
8665
|
+
exitHandler(nextMode);
|
|
8666
|
+
return;
|
|
8667
|
+
}
|
|
8668
|
+
if (annotations.hasAnyAnnotations && !promptKeepInkAnnotations) {
|
|
8669
|
+
annotations.clearAllAnnotations();
|
|
8706
8670
|
}
|
|
8707
|
-
setMode(nextMode);
|
|
8708
8671
|
}
|
|
8672
|
+
setMode(nextMode);
|
|
8709
8673
|
},
|
|
8710
8674
|
onSetActiveSlideIndex: setActiveSlideIndex,
|
|
8711
8675
|
onPlayActionSound: (soundPath, options) => {
|
|
@@ -8764,7 +8728,14 @@ function usePresentationSetup(input) {
|
|
|
8764
8728
|
useTimings: presentationProperties.advanceMode !== "manual",
|
|
8765
8729
|
endWithBlackSlide
|
|
8766
8730
|
});
|
|
8767
|
-
return {
|
|
8731
|
+
return {
|
|
8732
|
+
presentation,
|
|
8733
|
+
annotations,
|
|
8734
|
+
actionSoundHandlerRef,
|
|
8735
|
+
setExitModeHandler: (handler) => {
|
|
8736
|
+
exitModeHandlerRef.current = handler;
|
|
8737
|
+
}
|
|
8738
|
+
};
|
|
8768
8739
|
}
|
|
8769
8740
|
function useEditorOperations(input) {
|
|
8770
8741
|
const {
|
|
@@ -8928,7 +8899,8 @@ function useEditorOperations(input) {
|
|
|
8928
8899
|
tableEditorState: state.tableEditorState,
|
|
8929
8900
|
setTableEditorState: state.setTableEditorState,
|
|
8930
8901
|
ops,
|
|
8931
|
-
history
|
|
8902
|
+
history,
|
|
8903
|
+
transformCommittedText
|
|
8932
8904
|
});
|
|
8933
8905
|
const combinedUpdateTextStyle = useCallback(
|
|
8934
8906
|
(updates) => {
|
|
@@ -9030,11 +9002,11 @@ function useIOHandlers(input) {
|
|
|
9030
9002
|
ops,
|
|
9031
9003
|
zoom,
|
|
9032
9004
|
handlerRef,
|
|
9033
|
-
serializeSlides,
|
|
9034
9005
|
serializeForRecovery,
|
|
9035
9006
|
setContent,
|
|
9036
9007
|
onContentChange,
|
|
9037
|
-
password
|
|
9008
|
+
password,
|
|
9009
|
+
imageExportScale
|
|
9038
9010
|
} = input;
|
|
9039
9011
|
const exportHandlers = useExportHandlers({
|
|
9040
9012
|
slides,
|
|
@@ -9045,7 +9017,6 @@ function useIOHandlers(input) {
|
|
|
9045
9017
|
canvasStageRef: zoom.canvasStageRef,
|
|
9046
9018
|
setActiveSlideIndex: state.setActiveSlideIndex,
|
|
9047
9019
|
handlerRef,
|
|
9048
|
-
serializeSlides,
|
|
9049
9020
|
headerFooter: state.headerFooter,
|
|
9050
9021
|
presentationProperties: state.presentationProperties,
|
|
9051
9022
|
customShows: state.customShows,
|
|
@@ -9062,7 +9033,8 @@ function useIOHandlers(input) {
|
|
|
9062
9033
|
theme: state.theme,
|
|
9063
9034
|
canvasSize,
|
|
9064
9035
|
slideSizeEmu: state.slideSizeEmu,
|
|
9065
|
-
password
|
|
9036
|
+
password,
|
|
9037
|
+
imageExportScale
|
|
9066
9038
|
});
|
|
9067
9039
|
const printHandlers = usePrintHandlers({
|
|
9068
9040
|
slides,
|
|
@@ -9276,7 +9248,8 @@ function useContentLifecycle(input) {
|
|
|
9276
9248
|
actionSoundHandlerRef,
|
|
9277
9249
|
setIsEncryptedDialogOpen,
|
|
9278
9250
|
password,
|
|
9279
|
-
onContentApplied
|
|
9251
|
+
onContentApplied,
|
|
9252
|
+
allowExternalImages
|
|
9280
9253
|
} = input;
|
|
9281
9254
|
const { handlerRef } = useLoadContent({
|
|
9282
9255
|
content,
|
|
@@ -9315,7 +9288,8 @@ function useContentLifecycle(input) {
|
|
|
9315
9288
|
setError: state.setError,
|
|
9316
9289
|
setIsDirty: state.setIsDirty,
|
|
9317
9290
|
setIsEncrypted: setIsEncryptedDialogOpen,
|
|
9318
|
-
onContentApplied
|
|
9291
|
+
onContentApplied,
|
|
9292
|
+
allowExternalImages
|
|
9319
9293
|
});
|
|
9320
9294
|
useEffect(() => {
|
|
9321
9295
|
actionSoundHandlerRef.current = handlerRef.current;
|
|
@@ -9554,7 +9528,10 @@ function useViewerIntegration(input) {
|
|
|
9554
9528
|
autosaveEnabled,
|
|
9555
9529
|
autosaveAllowed = true,
|
|
9556
9530
|
autosaveIntervalMs,
|
|
9531
|
+
allowExternalImages,
|
|
9557
9532
|
canEdit,
|
|
9533
|
+
promptKeepInkAnnotations,
|
|
9534
|
+
imageExportScale,
|
|
9558
9535
|
mode,
|
|
9559
9536
|
slides,
|
|
9560
9537
|
activeSlide,
|
|
@@ -9619,7 +9596,8 @@ function useViewerIntegration(input) {
|
|
|
9619
9596
|
actionSoundHandlerRef,
|
|
9620
9597
|
setIsEncryptedDialogOpen,
|
|
9621
9598
|
password: dialogs.presentationPassword ?? void 0,
|
|
9622
|
-
onContentApplied: () => setLoadVersion((v) => v + 1)
|
|
9599
|
+
onContentApplied: () => setLoadVersion((v) => v + 1),
|
|
9600
|
+
allowExternalImages
|
|
9623
9601
|
}
|
|
9624
9602
|
);
|
|
9625
9603
|
const { exportHandlers, printHandlers, themeHandlers, propertyHandlers } = useIOHandlers({
|
|
@@ -9632,11 +9610,11 @@ function useViewerIntegration(input) {
|
|
|
9632
9610
|
ops: editorOps.ops,
|
|
9633
9611
|
zoom,
|
|
9634
9612
|
handlerRef,
|
|
9635
|
-
serializeSlides,
|
|
9636
9613
|
serializeForRecovery,
|
|
9637
9614
|
setContent,
|
|
9638
9615
|
onContentChange,
|
|
9639
|
-
password: dialogs.presentationPassword ?? void 0
|
|
9616
|
+
password: dialogs.presentationPassword ?? void 0,
|
|
9617
|
+
imageExportScale
|
|
9640
9618
|
});
|
|
9641
9619
|
const {
|
|
9642
9620
|
showKeepAnnotationsDialog,
|
|
@@ -9651,7 +9629,8 @@ function useViewerIntegration(input) {
|
|
|
9651
9629
|
annotations,
|
|
9652
9630
|
history,
|
|
9653
9631
|
setMode: state.setMode,
|
|
9654
|
-
setSlides: state.setSlides
|
|
9632
|
+
setSlides: state.setSlides,
|
|
9633
|
+
promptKeepInkAnnotations
|
|
9655
9634
|
});
|
|
9656
9635
|
const recovery = useRecoveryDetection({
|
|
9657
9636
|
filePath,
|
|
@@ -9930,13 +9909,19 @@ function useViewerOptions() {
|
|
|
9930
9909
|
return { optionsStore: store, options };
|
|
9931
9910
|
}
|
|
9932
9911
|
var KNOWN_TAB_IDS = new Set(TOOLBAR_TABS.map((tab) => tab.id));
|
|
9933
|
-
function computeToolbarVisibility(hiddenActions) {
|
|
9912
|
+
function computeToolbarVisibility(hiddenActions, hiddenTabIds = []) {
|
|
9934
9913
|
const isHidden = (id) => isActionHidden(id, hiddenActions);
|
|
9935
|
-
const
|
|
9914
|
+
const userHidden = new Set(hiddenTabIds);
|
|
9915
|
+
userHidden.delete("file");
|
|
9916
|
+
const isTabVisible = (id) => !KNOWN_TAB_IDS.has(id) || !isHidden(id) && !userHidden.has(id);
|
|
9936
9917
|
return { isHidden, isTabVisible };
|
|
9937
9918
|
}
|
|
9938
9919
|
function useToolbarVisibility(hiddenActions) {
|
|
9939
|
-
|
|
9920
|
+
const hiddenTabIds = useViewerOptionsContext().ribbon.hiddenTabIds;
|
|
9921
|
+
return useMemo(
|
|
9922
|
+
() => computeToolbarVisibility(hiddenActions, hiddenTabIds),
|
|
9923
|
+
[hiddenActions, hiddenTabIds]
|
|
9924
|
+
);
|
|
9940
9925
|
}
|
|
9941
9926
|
function useCollaborativeHistory({
|
|
9942
9927
|
localClientId: _localClientId,
|
|
@@ -10509,7 +10494,9 @@ function buildCanvasProps(input) {
|
|
|
10509
10494
|
tableOps,
|
|
10510
10495
|
presentation,
|
|
10511
10496
|
findResults,
|
|
10512
|
-
findResultIndex
|
|
10497
|
+
findResultIndex,
|
|
10498
|
+
viewerOptions,
|
|
10499
|
+
buildHyperlinkConfirmMessage
|
|
10513
10500
|
} = input;
|
|
10514
10501
|
const effectiveSlide = mode === "master" ? masterPseudoSlide : activeSlide;
|
|
10515
10502
|
const effectiveTemplateElements = mode === "master" ? s.activeLayout ? s.activeMaster?.elements ?? [] : [] : templateElements;
|
|
@@ -10519,11 +10506,22 @@ function buildCanvasProps(input) {
|
|
|
10519
10506
|
slide: activeSlide
|
|
10520
10507
|
});
|
|
10521
10508
|
const tableStyleContext = s.theme || s.tableStyleMap ? { theme: s.theme, tableStyleMap: s.tableStyleMap } : void 0;
|
|
10509
|
+
const openExternalUrl = (url) => {
|
|
10510
|
+
if (shouldConfirmExternalHyperlink(viewerOptions, url) && !window.confirm(buildHyperlinkConfirmMessage(url))) {
|
|
10511
|
+
return;
|
|
10512
|
+
}
|
|
10513
|
+
safeOpenUrl(url);
|
|
10514
|
+
};
|
|
10522
10515
|
const handleActionClick = (_elementId, action) => {
|
|
10523
10516
|
if (mode === "present") {
|
|
10517
|
+
const resolved = resolvePresentationAction(action, { slideCount: slides.length });
|
|
10518
|
+
if (resolved.intent.kind === "openUrl") {
|
|
10519
|
+
openExternalUrl(resolved.intent.url);
|
|
10520
|
+
return;
|
|
10521
|
+
}
|
|
10524
10522
|
presentation.handlePresentationAction(action);
|
|
10525
10523
|
} else if (action.url) {
|
|
10526
|
-
|
|
10524
|
+
openExternalUrl(action.url);
|
|
10527
10525
|
}
|
|
10528
10526
|
};
|
|
10529
10527
|
const handleHyperlinkClick = (url) => {
|
|
@@ -10539,7 +10537,7 @@ function buildCanvasProps(input) {
|
|
|
10539
10537
|
}
|
|
10540
10538
|
return;
|
|
10541
10539
|
}
|
|
10542
|
-
|
|
10540
|
+
openExternalUrl(url);
|
|
10543
10541
|
};
|
|
10544
10542
|
return {
|
|
10545
10543
|
activeSlide: effectiveSlide,
|
|
@@ -10839,7 +10837,6 @@ function buildToolbarProps(input) {
|
|
|
10839
10837
|
onExportVideo: exportHandlers.handleExportVideo,
|
|
10840
10838
|
onExportGif: exportHandlers.handleExportGif,
|
|
10841
10839
|
onExportJson: exportHandlers.handleExportJson,
|
|
10842
|
-
onPackageForSharing: exportHandlers.handlePackageForSharing,
|
|
10843
10840
|
onOpenFile,
|
|
10844
10841
|
onOpenRecentFile,
|
|
10845
10842
|
onCreatePresentation: (templateId) => {
|
|
@@ -10977,6 +10974,7 @@ function useViewerBuildingBlocksCore(input) {
|
|
|
10977
10974
|
]
|
|
10978
10975
|
);
|
|
10979
10976
|
const zoom = useZoomViewport({ canvasSize, selectedElements: state.selectedElements });
|
|
10977
|
+
const { options: viewerOptions } = useViewerOptions();
|
|
10980
10978
|
const history = useEditorHistory({
|
|
10981
10979
|
slides,
|
|
10982
10980
|
canvasSize,
|
|
@@ -10986,6 +10984,7 @@ function useViewerBuildingBlocksCore(input) {
|
|
|
10986
10984
|
headerFooter: state.headerFooter,
|
|
10987
10985
|
loading,
|
|
10988
10986
|
error,
|
|
10987
|
+
maxHistoryEntries: resolveHistoryDepth(viewerOptions),
|
|
10989
10988
|
hasActivePointerInteraction,
|
|
10990
10989
|
pointerCommitNonce: state.pointerCommitNonce,
|
|
10991
10990
|
setSlides: state.setSlides,
|
|
@@ -11007,12 +11006,15 @@ function useViewerBuildingBlocksCore(input) {
|
|
|
11007
11006
|
activeMaster: state.activeMaster,
|
|
11008
11007
|
documentGridSpacing: state.viewProperties?.gridSpacing
|
|
11009
11008
|
});
|
|
11010
|
-
const {
|
|
11011
|
-
const { presentation, annotations, actionSoundHandlerRef } = usePresentationSetup({
|
|
11009
|
+
const { presentation, annotations, actionSoundHandlerRef, setExitModeHandler } = usePresentationSetup({
|
|
11012
11010
|
mode,
|
|
11013
11011
|
slides,
|
|
11014
11012
|
visibleSlideIndexes,
|
|
11015
11013
|
endWithBlackSlide: viewerOptions.advanced.slideShowEndWithBlackSlide,
|
|
11014
|
+
// File > Options > Advanced > "Prompt to keep ink annotations when
|
|
11015
|
+
// exiting" / "Show popup toolbar" while presenting.
|
|
11016
|
+
promptKeepInkAnnotations: viewerOptions.advanced.slideShowPromptKeepInkAnnotations,
|
|
11017
|
+
popupToolbarEnabled: viewerOptions.advanced.slideShowShowPopupToolbar,
|
|
11016
11018
|
activeSlideIndex,
|
|
11017
11019
|
containerRef,
|
|
11018
11020
|
content,
|
|
@@ -11042,8 +11044,13 @@ function useViewerBuildingBlocksCore(input) {
|
|
|
11042
11044
|
presentation,
|
|
11043
11045
|
annotations,
|
|
11044
11046
|
actionSoundHandlerRef,
|
|
11047
|
+
setExitModeHandler,
|
|
11045
11048
|
masterPseudoSlide,
|
|
11046
|
-
gridSpacingPx
|
|
11049
|
+
gridSpacingPx,
|
|
11050
|
+
// Multiplied against the pre-existing 2x baseline; see the matching
|
|
11051
|
+
// comment in `PowerPointViewer.tsx`.
|
|
11052
|
+
imageExportScale: 2 * resolveImageResolutionScale(viewerOptions),
|
|
11053
|
+
viewerOptions
|
|
11047
11054
|
};
|
|
11048
11055
|
}
|
|
11049
11056
|
function useViewerBuildingBlocksState(input) {
|
|
@@ -11071,7 +11078,10 @@ function useViewerBuildingBlocksState(input) {
|
|
|
11071
11078
|
presentation,
|
|
11072
11079
|
annotations,
|
|
11073
11080
|
actionSoundHandlerRef,
|
|
11074
|
-
gridSpacingPx
|
|
11081
|
+
gridSpacingPx,
|
|
11082
|
+
imageExportScale,
|
|
11083
|
+
setExitModeHandler,
|
|
11084
|
+
viewerOptions
|
|
11075
11085
|
} = core;
|
|
11076
11086
|
const dialogs = useViewerDialogs({
|
|
11077
11087
|
mode,
|
|
@@ -11142,7 +11152,13 @@ function useViewerBuildingBlocksState(input) {
|
|
|
11142
11152
|
content,
|
|
11143
11153
|
filePath,
|
|
11144
11154
|
autosaveEnabled,
|
|
11155
|
+
// Trust Center > "Allow external content": same gate `PowerPointViewer`
|
|
11156
|
+
// applies, so the headless building-blocks API loads http(s) images
|
|
11157
|
+
// under the same default-off, core-side SSRF/privacy guard.
|
|
11158
|
+
allowExternalImages: viewerOptions.trust.allowExternalContent,
|
|
11145
11159
|
canEdit,
|
|
11160
|
+
promptKeepInkAnnotations: viewerOptions.advanced.slideShowPromptKeepInkAnnotations,
|
|
11161
|
+
imageExportScale,
|
|
11146
11162
|
mode,
|
|
11147
11163
|
slides,
|
|
11148
11164
|
activeSlide,
|
|
@@ -11160,6 +11176,7 @@ function useViewerBuildingBlocksState(input) {
|
|
|
11160
11176
|
onSelectionChange,
|
|
11161
11177
|
onSlideCountChange
|
|
11162
11178
|
});
|
|
11179
|
+
setExitModeHandler(handleSetMode);
|
|
11163
11180
|
return {
|
|
11164
11181
|
dialogs,
|
|
11165
11182
|
editorOps,
|
|
@@ -11195,6 +11212,7 @@ function useViewerBuildingBlocks(input) {
|
|
|
11195
11212
|
onOpenHeaderFooter,
|
|
11196
11213
|
onOpenShareDialog
|
|
11197
11214
|
} = input;
|
|
11215
|
+
const { t } = useTranslation();
|
|
11198
11216
|
const [content, setContent] = useState(incomingContent ?? null);
|
|
11199
11217
|
useEffect(() => {
|
|
11200
11218
|
setContent(incomingContent ?? null);
|
|
@@ -11229,7 +11247,8 @@ function useViewerBuildingBlocks(input) {
|
|
|
11229
11247
|
history,
|
|
11230
11248
|
presentation,
|
|
11231
11249
|
masterPseudoSlide,
|
|
11232
|
-
gridSpacingPx
|
|
11250
|
+
gridSpacingPx,
|
|
11251
|
+
viewerOptions
|
|
11233
11252
|
} = core;
|
|
11234
11253
|
const {
|
|
11235
11254
|
dialogs,
|
|
@@ -11305,7 +11324,11 @@ function useViewerBuildingBlocks(input) {
|
|
|
11305
11324
|
tableOps: editorOps.tableOps,
|
|
11306
11325
|
presentation,
|
|
11307
11326
|
findResults: editorOps.findReplace.findResults,
|
|
11308
|
-
findResultIndex: editorOps.findReplace.findResultIndex
|
|
11327
|
+
findResultIndex: editorOps.findReplace.findResultIndex,
|
|
11328
|
+
viewerOptions,
|
|
11329
|
+
buildHyperlinkConfirmMessage: (url) => `${t("pptx.options.trust.confirmHyperlinks")}
|
|
11330
|
+
|
|
11331
|
+
${url}`
|
|
11309
11332
|
});
|
|
11310
11333
|
return { toolbarProps, canvasProps, mode, loading, error, autosaveStatus };
|
|
11311
11334
|
}
|
|
@@ -11379,4 +11402,4 @@ function useResizablePanels() {
|
|
|
11379
11402
|
};
|
|
11380
11403
|
}
|
|
11381
11404
|
|
|
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 };
|
|
11405
|
+
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 };
|