pptx-react-viewer 3.12.0 → 3.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +48 -0
- package/dist/{AiChatPanel-TXCDQDHD.js → AiChatPanel-42X7I5I2.js} +32 -32
- package/dist/AiChatPanel-42X7I5I2.js.br +0 -0
- package/dist/AiChatPanel-42X7I5I2.js.gz +0 -0
- package/dist/{AiChatPanel-SCA4RLFI.mjs → AiChatPanel-NJBUCO4X.mjs} +11 -11
- package/dist/AiChatPanel-NJBUCO4X.mjs.br +0 -0
- package/dist/AiChatPanel-NJBUCO4X.mjs.gz +0 -0
- package/dist/{Area3DChartScene-YAK6W2J5.js → Area3DChartScene-IDS5APPJ.js} +2 -2
- package/dist/Area3DChartScene-IDS5APPJ.js.br +0 -0
- package/dist/Area3DChartScene-IDS5APPJ.js.gz +0 -0
- package/dist/{Area3DChartScene-NSV5AIMM.mjs → Area3DChartScene-TFZPHEZ6.mjs} +1 -1
- package/dist/Area3DChartScene-TFZPHEZ6.mjs.br +0 -0
- package/dist/Area3DChartScene-TFZPHEZ6.mjs.gz +0 -0
- package/dist/{Bar3DChartScene-WNBEX3TN.js → Bar3DChartScene-C3CQCKB6.js} +2 -2
- package/dist/Bar3DChartScene-C3CQCKB6.js.br +0 -0
- package/dist/Bar3DChartScene-C3CQCKB6.js.gz +0 -0
- package/dist/{Bar3DChartScene-DFJ7XK3Q.mjs → Bar3DChartScene-L3VXO7BS.mjs} +1 -1
- package/dist/{Bar3DChartScene-DFJ7XK3Q.mjs.br → Bar3DChartScene-L3VXO7BS.mjs.br} +0 -0
- package/dist/Bar3DChartScene-L3VXO7BS.mjs.gz +0 -0
- package/dist/{Line3DChartScene-TK6RPGET.mjs → Line3DChartScene-UM4ZJJSY.mjs} +1 -1
- package/dist/{Line3DChartScene-TK6RPGET.mjs.br → Line3DChartScene-UM4ZJJSY.mjs.br} +0 -0
- package/dist/Line3DChartScene-UM4ZJJSY.mjs.gz +0 -0
- package/dist/{Line3DChartScene-PXA6WAQG.js → Line3DChartScene-YU4M3VMW.js} +2 -2
- package/dist/Line3DChartScene-YU4M3VMW.js.br +0 -0
- package/dist/Line3DChartScene-YU4M3VMW.js.gz +0 -0
- package/dist/{Model3DScene-7FZSQ3SP.mjs → Model3DScene-YEWZQAN5.mjs} +1 -1
- package/dist/Model3DScene-YEWZQAN5.mjs.br +0 -0
- package/dist/Model3DScene-YEWZQAN5.mjs.gz +0 -0
- package/dist/{Model3DScene-FJQOUWCV.js → Model3DScene-YRRNSOYK.js} +2 -2
- package/dist/Model3DScene-YRRNSOYK.js.br +0 -0
- package/dist/Model3DScene-YRRNSOYK.js.gz +0 -0
- package/dist/{PieChart3DScene-KKZTAIFB.mjs → PieChart3DScene-2OBYYK55.mjs} +1 -1
- package/dist/{PieChart3DScene-KKZTAIFB.mjs.br → PieChart3DScene-2OBYYK55.mjs.br} +0 -0
- package/dist/PieChart3DScene-2OBYYK55.mjs.gz +0 -0
- package/dist/{PieChart3DScene-P25IGVT6.js → PieChart3DScene-GH4X3W3E.js} +2 -2
- package/dist/PieChart3DScene-GH4X3W3E.js.br +0 -0
- package/dist/PieChart3DScene-GH4X3W3E.js.gz +0 -0
- package/dist/{SurfaceChart3DScene-LWJCERTR.mjs → SurfaceChart3DScene-DYG5I5UP.mjs} +1 -1
- package/dist/{SurfaceChart3DScene-LWJCERTR.mjs.br → SurfaceChart3DScene-DYG5I5UP.mjs.br} +0 -0
- package/dist/SurfaceChart3DScene-DYG5I5UP.mjs.gz +0 -0
- package/dist/{SurfaceChart3DScene-36MT6QAK.js → SurfaceChart3DScene-J5CAPHVA.js} +2 -2
- package/dist/SurfaceChart3DScene-J5CAPHVA.js.br +0 -0
- package/dist/SurfaceChart3DScene-J5CAPHVA.js.gz +0 -0
- package/dist/{chunk-T7MY5L3O.js → chunk-7OMXJNYI.js} +1568 -1416
- package/dist/chunk-7OMXJNYI.js.br +0 -0
- package/dist/chunk-7OMXJNYI.js.gz +0 -0
- package/dist/{chunk-AARQTIMN.js → chunk-7Z7AY4MH.js} +772 -580
- package/dist/chunk-7Z7AY4MH.js.br +0 -0
- package/dist/chunk-7Z7AY4MH.js.gz +0 -0
- package/dist/{chunk-ZOEKVSSU.mjs → chunk-EZ3EI2VM.mjs} +323 -171
- package/dist/chunk-EZ3EI2VM.mjs.br +0 -0
- package/dist/chunk-EZ3EI2VM.mjs.gz +0 -0
- package/dist/{chunk-WRHPPTYF.mjs → chunk-GQMVEUHM.mjs} +356 -165
- package/dist/chunk-GQMVEUHM.mjs.br +0 -0
- package/dist/chunk-GQMVEUHM.mjs.gz +0 -0
- package/dist/{chunk-O27KNZLJ.js → chunk-H4LMXJ2Z.js} +169 -169
- package/dist/chunk-H4LMXJ2Z.js.br +0 -0
- package/dist/chunk-H4LMXJ2Z.js.gz +0 -0
- package/dist/{chunk-C2BDHCL2.mjs → chunk-HADPGII2.mjs} +47276 -43466
- package/dist/chunk-HADPGII2.mjs.br +0 -0
- package/dist/chunk-HADPGII2.mjs.gz +0 -0
- package/dist/{chunk-45AVHO7M.js → chunk-INKQT4SQ.js} +5 -5
- package/dist/chunk-INKQT4SQ.js.br +0 -0
- package/dist/chunk-INKQT4SQ.js.gz +0 -0
- package/dist/{chunk-3WK4AE52.js → chunk-MH4VFSDL.js} +47294 -43466
- package/dist/chunk-MH4VFSDL.js.br +0 -0
- package/dist/chunk-MH4VFSDL.js.gz +0 -0
- package/dist/{chunk-HXDNYDRJ.mjs → chunk-OVOXRK7D.mjs} +4 -4
- package/dist/chunk-OVOXRK7D.mjs.br +0 -0
- package/dist/chunk-OVOXRK7D.mjs.gz +0 -0
- package/dist/{chunk-2FSNTJVI.mjs → chunk-YFYSY7ZL.mjs} +1 -1
- package/dist/chunk-YFYSY7ZL.mjs.br +0 -0
- package/dist/chunk-YFYSY7ZL.mjs.gz +0 -0
- package/dist/index.js +45 -45
- package/dist/index.js.br +0 -0
- package/dist/index.js.gz +0 -0
- package/dist/index.mjs +5 -5
- package/dist/index.mjs.br +0 -0
- package/dist/index.mjs.gz +0 -0
- package/dist/internals.d.ts +33 -1
- package/dist/internals.d.ts.map +1 -1
- package/dist/internals.js +78 -78
- package/dist/internals.js.br +0 -0
- package/dist/internals.js.gz +0 -0
- package/dist/internals.mjs +3 -3
- package/dist/internals.mjs.br +0 -0
- package/dist/internals.mjs.gz +0 -0
- package/dist/pptx-viewer.css +1 -1
- package/dist/pptx-viewer.css.br +0 -0
- package/dist/pptx-viewer.css.gz +0 -0
- package/dist/viewer/index.js +26 -26
- package/dist/viewer/index.js.br +0 -0
- package/dist/viewer/index.js.gz +0 -0
- package/dist/viewer/index.mjs +5 -5
- package/dist/viewer/index.mjs.br +0 -0
- package/dist/viewer/index.mjs.gz +0 -0
- package/package.json +3 -1
- package/dist/AiChatPanel-SCA4RLFI.mjs.br +0 -0
- package/dist/AiChatPanel-SCA4RLFI.mjs.gz +0 -0
- package/dist/AiChatPanel-TXCDQDHD.js.br +0 -0
- package/dist/AiChatPanel-TXCDQDHD.js.gz +0 -0
- package/dist/Area3DChartScene-NSV5AIMM.mjs.br +0 -0
- package/dist/Area3DChartScene-NSV5AIMM.mjs.gz +0 -0
- package/dist/Area3DChartScene-YAK6W2J5.js.br +0 -0
- package/dist/Area3DChartScene-YAK6W2J5.js.gz +0 -0
- package/dist/Bar3DChartScene-DFJ7XK3Q.mjs.gz +0 -0
- package/dist/Bar3DChartScene-WNBEX3TN.js.br +0 -0
- package/dist/Bar3DChartScene-WNBEX3TN.js.gz +0 -0
- package/dist/Line3DChartScene-PXA6WAQG.js.br +0 -0
- package/dist/Line3DChartScene-PXA6WAQG.js.gz +0 -0
- package/dist/Line3DChartScene-TK6RPGET.mjs.gz +0 -0
- package/dist/Model3DScene-7FZSQ3SP.mjs.br +0 -0
- package/dist/Model3DScene-7FZSQ3SP.mjs.gz +0 -0
- package/dist/Model3DScene-FJQOUWCV.js.br +0 -0
- package/dist/Model3DScene-FJQOUWCV.js.gz +0 -0
- package/dist/PieChart3DScene-KKZTAIFB.mjs.gz +0 -0
- package/dist/PieChart3DScene-P25IGVT6.js.br +0 -0
- package/dist/PieChart3DScene-P25IGVT6.js.gz +0 -0
- package/dist/SurfaceChart3DScene-36MT6QAK.js.br +0 -0
- package/dist/SurfaceChart3DScene-36MT6QAK.js.gz +0 -0
- package/dist/SurfaceChart3DScene-LWJCERTR.mjs.gz +0 -0
- package/dist/chunk-2FSNTJVI.mjs.br +0 -0
- package/dist/chunk-2FSNTJVI.mjs.gz +0 -0
- package/dist/chunk-3WK4AE52.js.br +0 -0
- package/dist/chunk-3WK4AE52.js.gz +0 -0
- package/dist/chunk-45AVHO7M.js.br +0 -0
- package/dist/chunk-45AVHO7M.js.gz +0 -0
- package/dist/chunk-AARQTIMN.js.br +0 -0
- package/dist/chunk-AARQTIMN.js.gz +0 -0
- package/dist/chunk-C2BDHCL2.mjs.br +0 -0
- package/dist/chunk-C2BDHCL2.mjs.gz +0 -0
- package/dist/chunk-HXDNYDRJ.mjs.br +0 -0
- package/dist/chunk-HXDNYDRJ.mjs.gz +0 -0
- package/dist/chunk-O27KNZLJ.js.br +0 -0
- package/dist/chunk-O27KNZLJ.js.gz +0 -0
- package/dist/chunk-T7MY5L3O.js.br +0 -0
- package/dist/chunk-T7MY5L3O.js.gz +0 -0
- package/dist/chunk-WRHPPTYF.mjs.br +0 -0
- package/dist/chunk-WRHPPTYF.mjs.gz +0 -0
- package/dist/chunk-ZOEKVSSU.mjs.br +0 -0
- package/dist/chunk-ZOEKVSSU.mjs.gz +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
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,
|
|
2
|
-
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, createActiveAnimationGroup, cancelBuildReveal, clearPlaybackTimers, PresentationAnimationController, resolveMediaTimeNodeElementIds, advanceMainSequence, playGroup, 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, firstShowSlideIndex, attachPresentationVisibilityPause, presentationEntrySlideIndex, buildMorphTransitionPlan, morphOptionToMode, buildMorphAnimationRules, findInSlides, applyFindReplacements, visibleTemplateElements, createCollaborationLivePatcher, publishLiveInlineText, PptxHandler, collectMediaElements, resolveMediaElementSource, collectImagePaths, applyImagePathPatches, resolveTableCellImageUrls, resolveTableStyleImageUrls, partitionTemplateElements, seedRecentColors, resolveAuthoredCustomShowId, buildInitialGuides, readOnlyRecommendation, compatibilityWarningToasts, EncryptedFileError, resolveAutosaveIntervalMs, shouldWriteAutosaveSnapshot, saveAutosaveSnapshot, autosaveSnapshotMark, hasTextProperties, remapTextToSegments, updateMasterViewElement, isTemplateElementId, updateElement, hasShapeProperties, getInlineEditorSelection, applyStyleToSelectedSegments, setPendingSelectionRestore, applyCaseTransformToSegments, transformTextCase, masterViewElements, replaceMasterViewElements, addSection, renameSection, deleteSection, moveSectionUp, moveSectionDown, moveSlidesToSection, canInteractWithElement, normalizeColorsForCapture, preprocessCssForCapture, slideProgressPercent, slideStatusLabel, EXPORT_ASSEMBLING_PERCENT, EXPORT_DONE_PERCENT, isExportAbortError,
|
|
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, buildPdfFromTiledImageData, buildNotesPdf, GRID_SIZE, DEFAULT_TEXT_FONT_SIZE } from './chunk-OVOXRK7D.mjs';
|
|
2
|
+
import { GlyphOutlineFontCache, createGlyphOutlineLookup, DEFAULT_VIEWER_OPTIONS, TOOLBAR_TABS, MIN_TOUCH_TARGET_PX, 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, createActiveAnimationGroup, cancelBuildReveal, clearPlaybackTimers, PresentationAnimationController, resolveMediaTimeNodeElementIds, advanceMainSequence, playGroup, 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, firstShowSlideIndex, attachPresentationVisibilityPause, presentationEntrySlideIndex, buildMorphTransitionPlan, morphOptionToMode, buildMorphAnimationRules, findInSlides, applyFindReplacements, visibleTemplateElements, createCollaborationLivePatcher, publishLiveInlineText, PptxHandler, collectMediaElements, resolveMediaElementSource, collectImagePaths, applyImagePathPatches, resolveTableCellImageUrls, resolveTableStyleImageUrls, partitionTemplateElements, seedRecentColors, resolveAuthoredCustomShowId, buildInitialGuides, readOnlyRecommendation, compatibilityWarningToasts, EncryptedFileError, resolveAutosaveIntervalMs, shouldWriteAutosaveSnapshot, saveAutosaveSnapshot, autosaveSnapshotMark, hasTextProperties, remapTextToSegments, updateMasterViewElement, isTemplateElementId, updateElement, hasShapeProperties, getInlineEditorSelection, applyStyleToSelectedSegments, setPendingSelectionRestore, applyCaseTransformToSegments, transformTextCase, masterViewElements, replaceMasterViewElements, addSection, renameSection, deleteSection, moveSectionUp, moveSectionDown, moveSlidesToSection, canInteractWithElement, normalizeColorsForCapture, preprocessCssForCapture, slideProgressPercent, slideStatusLabel, EXPORT_ASSEMBLING_PERCENT, EXPORT_DONE_PERCENT, isExportAbortError, resolveImageResolutionScale, applyThemeToData, THEME_PRESETS, themeColorSchemesEqual, comparePresentation, applyAcceptSlide, applyAcceptAllSlides, collectUsedFonts, describeFontEmbedding, isMobileViewport, resolveAuthoredSlideRange, mayLeaveSlideShow, stopAllPersistentAudio, guidePxToEmu, buildSaveSlides, buildDeckSaveOptions, resolveSlideSizeSelection, saveDeckWithPassword, shouldProbeAutosaveRecovery, probeAutosaveRecovery, acceptAutosaveRecovery, discardAutosaveRecovery, shouldLoopContinuously, applyRehearsalTimings, copyFormatFromElement, applyFormatToElement, collectReferencedFontFamilies, resolveGoogleWebfontHref, selectGoogleWebfontFamilies, fetchGoogleWebfontOutlineBytes, mapSlideShowStartKey, mapEditorKey, isEditorTextInputTarget, createViewerOptionsStore, readSlidesFromYDoc, shouldRoomSlidesReplaceLoad, reconcileSlidesInYDoc, LOCAL_SYNC_ORIGIN, observeYDocSlides, shouldAutoFollowBroadcaster, detectTouchDevice, detectOrientation, deriveViewportBreakpoints, createTouchGestureRecognizer, MAX_ZOOM_SCALE, MIN_ZOOM_SCALE, isKeyboardOpen, scopeLayoutOptionsToSlide, checkModifyPassword, viewerPreferencesFromViewProperties, DEFAULT_VIEWER_PREFERENCES, viewPropertiesPatchFromPreferences, openPptxFile, readBackstageRecentFile, isActionHidden, buildInlineTextCommitPatch, resolveInlineEditAutoFitHeight, resolveInlineEditNormAutofitShrink, filterInteractableIds, beginShapeAdjustment, buildElementClipboardPayload, savedPresentationFileName, downloadBlob, exportDeckJson, groupElements, generateElementId, makeCloneId, ungroupElements, alignElements, distributeElements, bringForward, sendBackward, bringToFront, sendToBack, newTableElement, createDefaultChartElement, readViewportMetrics, computeKeyboardInset, mergeShapes, mapPresentationKey, lastShowSlideIndex, mapPresentationWheel, openPendingPrintWindow, computeColorFilter, filterHiddenSlideIndices, computeSlideIndices, buildPrintDocument, finishPrintWindow, buildPrintHtmlDocument, buildOutlineHtml, buildSlidesHtml, buildNotesHtml, buildHandoutsHtml, createBlankSlide, makeSlideId, buildSlideTemplateSlide, templateSchemeFromTheme, buildThemeColorMap, reResolveSlideColors, reResolveElementColors, scheduleAutoAdvanceChain, computeEntranceAnimationDelay, createPresentationSessionId, resolveTransitionDurationMs, resolveTransitionSoundAction, runPresentationAction, safeOpenUrl, buildRunProgramNotice, toggleStageElementMedia, resolveOleVerbTarget, downloadDataUrl, openUrlInNewTab, createPresenterTimer, createInitialPresentationSnapshot, mergePresentationSnapshot, resetPresenterTimer, presenterElapsed, stepPresenterZoom, togglePresenterTimer, addCommentToList, removeCommentFromList, editCommentInList, toggleCommentResolvedInList, resolveExportCaptureDecision, recordProgressPercent, computeGridSpacingPx, resolveShowSlideIndexes, groupSlidesBySection, masterViewPseudoSlide, resolveHistoryDepth, hasCopyableFormat, createBackstagePresentation, buildFieldSubstitutionContext, cloneElementForPaste, computeScrollDelta, getPresetShapeClipPath, svgPathToPolygons, polygonsToSvgPath, rerouteConnectorsForMovedElements, applyReroutedConnectors, SvgExporter, replyToCommentInList, deleteTableColumn, rebuildTableStructureInRawXml, insertTableColumn, deleteTableRow, insertTableRow, updateCellTextStyleInRawXml, setCellText, updateCellTextInRawXml, splitCell, updateMergeAttrsInRawXml, mergeCells, pickSupportedMimeType, WEBM_MIME_CANDIDATES, fpsToFrameIntervalMs, segmentFrameCount, GIF_POST_CAPTURE_MAX_SIDE, encodeGif, rasterResultToPngBlob, rasterizeElementTiles, placeTileOnPage, PDF_SLIDES_PAGE_WIDTH_PT, PDF_SLIDES_PAGE_HEIGHT_PT, canvasToJpegData, rasterizeElementTiledToCanvas, isPpactionUrl, parsePpactionUrl, resolvePresentationAction, ACTION_BUTTON_PRESETS, elementActionToPptxAction, isUrlSafe, buildSmartArtPresetData, classifyMediaType, computeSnapToShape, publishLiveGeometry, getDraggedShapeAdjustments, computeMarqueeHitIds, mergeAdditiveSelection, clampGifDimensions, rasterizeElement, shouldConfirmExternalHyperlink, applyResize, lockResizeAspect, snapBoxToGrid, applyMotionPathPreset } from './chunk-HADPGII2.mjs';
|
|
3
3
|
import { translationsEn } from './chunk-HMX3MQR7.mjs';
|
|
4
4
|
import { createContext, useRef, useState, useEffect, useCallback, useMemo, useLayoutEffect, useContext, useImperativeHandle, useSyncExternalStore } from 'react';
|
|
5
5
|
import { useTranslation } from 'react-i18next';
|
|
@@ -3960,6 +3960,12 @@ function useViewerState(input) {
|
|
|
3960
3960
|
const ui = useViewerUIState();
|
|
3961
3961
|
return { ...core, ...ui };
|
|
3962
3962
|
}
|
|
3963
|
+
|
|
3964
|
+
// src/viewer/utils/glyph-outline-cache.ts
|
|
3965
|
+
var glyphOutlineFontCache = new GlyphOutlineFontCache();
|
|
3966
|
+
var getGlyphOutline = createGlyphOutlineLookup(glyphOutlineFontCache);
|
|
3967
|
+
|
|
3968
|
+
// src/viewer/hooks/useLoadContent.ts
|
|
3963
3969
|
function useLoadContent({
|
|
3964
3970
|
content,
|
|
3965
3971
|
clearSelection,
|
|
@@ -4138,6 +4144,7 @@ function useLoadContent({
|
|
|
4138
4144
|
setCoreProperties(parsed.coreProperties);
|
|
4139
4145
|
setAppProperties(parsed.appProperties);
|
|
4140
4146
|
setEmbeddedFonts(parsed.embeddedFonts ?? []);
|
|
4147
|
+
glyphOutlineFontCache.registerEmbeddedFonts(parsed.embeddedFonts ?? []);
|
|
4141
4148
|
setHasMacros(parsed.hasMacros === true);
|
|
4142
4149
|
setHasDigitalSignatures(parsed.hasDigitalSignatures === true);
|
|
4143
4150
|
setDigitalSignatureCount(parsed.digitalSignatureCount ?? 0);
|
|
@@ -7043,43 +7050,71 @@ function useExportSaveAs(input) {
|
|
|
7043
7050
|
};
|
|
7044
7051
|
}
|
|
7045
7052
|
|
|
7046
|
-
// src/viewer/utils/
|
|
7047
|
-
function
|
|
7048
|
-
|
|
7049
|
-
|
|
7050
|
-
|
|
7051
|
-
return null;
|
|
7053
|
+
// src/viewer/utils/export-helpers.ts
|
|
7054
|
+
function ignoreExportOverlayElements(el) {
|
|
7055
|
+
const htmlEl = el;
|
|
7056
|
+
if (htmlEl.dataset?.exportIgnore === "true") {
|
|
7057
|
+
return true;
|
|
7052
7058
|
}
|
|
7059
|
+
return Boolean(
|
|
7060
|
+
htmlEl.classList?.contains("pointer-events-none") && (htmlEl.classList.contains("z-50") || htmlEl.classList.contains("z-[60]"))
|
|
7061
|
+
);
|
|
7053
7062
|
}
|
|
7054
|
-
function
|
|
7055
|
-
|
|
7056
|
-
|
|
7057
|
-
|
|
7058
|
-
|
|
7059
|
-
}
|
|
7063
|
+
function measureNaturalSize(element) {
|
|
7064
|
+
const rect = element.getBoundingClientRect();
|
|
7065
|
+
return {
|
|
7066
|
+
width: rect.width || element.offsetWidth,
|
|
7067
|
+
height: rect.height || element.offsetHeight
|
|
7068
|
+
};
|
|
7060
7069
|
}
|
|
7061
|
-
|
|
7062
|
-
|
|
7063
|
-
async function renderElementToCanvas(element, scale = 2, backgroundColor) {
|
|
7064
|
-
const canvas = await renderToCanvas(element, {
|
|
7070
|
+
function buildRasterOptions(element, scale, backgroundColor, mode) {
|
|
7071
|
+
return {
|
|
7065
7072
|
scale,
|
|
7066
|
-
|
|
7067
|
-
|
|
7068
|
-
|
|
7069
|
-
|
|
7070
|
-
|
|
7071
|
-
|
|
7072
|
-
|
|
7073
|
-
|
|
7074
|
-
|
|
7075
|
-
|
|
7076
|
-
|
|
7077
|
-
|
|
7078
|
-
|
|
7079
|
-
|
|
7080
|
-
|
|
7081
|
-
|
|
7082
|
-
|
|
7073
|
+
backgroundColor,
|
|
7074
|
+
mode,
|
|
7075
|
+
html2canvasFallback: (sourceRect, outputSize) => renderToCanvas(element, {
|
|
7076
|
+
scale: outputSize.width / (sourceRect.width || 1),
|
|
7077
|
+
x: sourceRect.x,
|
|
7078
|
+
y: sourceRect.y,
|
|
7079
|
+
width: sourceRect.width,
|
|
7080
|
+
height: sourceRect.height,
|
|
7081
|
+
useCORS: true,
|
|
7082
|
+
allowTaint: true,
|
|
7083
|
+
backgroundColor: backgroundColor ?? null,
|
|
7084
|
+
logging: false,
|
|
7085
|
+
ignoreElements: ignoreExportOverlayElements
|
|
7086
|
+
})
|
|
7087
|
+
};
|
|
7088
|
+
}
|
|
7089
|
+
async function renderElementToRaster(element, scale = 2, backgroundColor, mode = "auto") {
|
|
7090
|
+
const { width, height } = measureNaturalSize(element);
|
|
7091
|
+
return rasterizeElement(
|
|
7092
|
+
element,
|
|
7093
|
+
width,
|
|
7094
|
+
height,
|
|
7095
|
+
element.ownerDocument,
|
|
7096
|
+
buildRasterOptions(element, scale, backgroundColor, mode)
|
|
7097
|
+
);
|
|
7098
|
+
}
|
|
7099
|
+
async function renderElementToTiles(element, scale = 2, backgroundColor, mode = "auto") {
|
|
7100
|
+
const { width, height } = measureNaturalSize(element);
|
|
7101
|
+
return rasterizeElementTiles(
|
|
7102
|
+
element,
|
|
7103
|
+
width,
|
|
7104
|
+
height,
|
|
7105
|
+
element.ownerDocument,
|
|
7106
|
+
buildRasterOptions(element, scale, backgroundColor, mode)
|
|
7107
|
+
);
|
|
7108
|
+
}
|
|
7109
|
+
async function renderElementToTiledCanvas(element, scale = 2, backgroundColor, mode = "auto") {
|
|
7110
|
+
const { width, height } = measureNaturalSize(element);
|
|
7111
|
+
return rasterizeElementTiledToCanvas(
|
|
7112
|
+
element,
|
|
7113
|
+
width,
|
|
7114
|
+
height,
|
|
7115
|
+
element.ownerDocument,
|
|
7116
|
+
buildRasterOptions(element, scale, backgroundColor, mode)
|
|
7117
|
+
);
|
|
7083
7118
|
}
|
|
7084
7119
|
function waitForRender(ms = 100) {
|
|
7085
7120
|
return new Promise((resolve) => {
|
|
@@ -7094,16 +7129,8 @@ function waitForRender(ms = 100) {
|
|
|
7094
7129
|
// src/viewer/utils/export-slides.ts
|
|
7095
7130
|
async function exportSlideToPngBlob(slideElement, options = {}) {
|
|
7096
7131
|
const { scale = 2, backgroundColor } = options;
|
|
7097
|
-
const
|
|
7098
|
-
return
|
|
7099
|
-
canvas.toBlob((blob) => {
|
|
7100
|
-
if (blob) {
|
|
7101
|
-
resolve(blob);
|
|
7102
|
-
} else {
|
|
7103
|
-
reject(new Error("Canvas toBlob returned null"));
|
|
7104
|
-
}
|
|
7105
|
-
}, "image/png");
|
|
7106
|
-
});
|
|
7132
|
+
const result = await renderElementToRaster(slideElement, scale, backgroundColor);
|
|
7133
|
+
return rasterResultToPngBlob(result);
|
|
7107
7134
|
}
|
|
7108
7135
|
async function exportSlideAsPng(slideElement, slideIndex, options = {}) {
|
|
7109
7136
|
const blob = await exportSlideToPngBlob(slideElement, options);
|
|
@@ -7113,13 +7140,10 @@ async function copySlideToClipboard(slideElement, options = {}) {
|
|
|
7113
7140
|
const blob = await exportSlideToPngBlob(slideElement, options);
|
|
7114
7141
|
await navigator.clipboard.write([new ClipboardItem({ "image/png": blob })]);
|
|
7115
7142
|
}
|
|
7116
|
-
async function
|
|
7117
|
-
const { scale = 2, onProgress
|
|
7118
|
-
const
|
|
7143
|
+
async function captureAllSlidesAsPngDataUrls(slideStageRef, totalSlides, setActiveSlide, currentSlideIndex, options = {}) {
|
|
7144
|
+
const { scale = 2, onProgress } = options;
|
|
7145
|
+
const dataUrls = [];
|
|
7119
7146
|
for (let i = 0; i < totalSlides; i++) {
|
|
7120
|
-
if (signal?.aborted) {
|
|
7121
|
-
throw new DOMException("Export cancelled", "AbortError");
|
|
7122
|
-
}
|
|
7123
7147
|
onProgress?.(i, totalSlides);
|
|
7124
7148
|
setActiveSlide(i);
|
|
7125
7149
|
await waitForRender(150);
|
|
@@ -7128,21 +7152,34 @@ async function exportAllSlidesAsPdf(slideStageRef, totalSlides, setActiveSlide,
|
|
|
7128
7152
|
console.warn(`[export] Could not find slide stage element for slide ${i}`);
|
|
7129
7153
|
continue;
|
|
7130
7154
|
}
|
|
7131
|
-
const canvas = await
|
|
7132
|
-
|
|
7155
|
+
const { canvas } = await renderElementToTiledCanvas(stageEl, scale);
|
|
7156
|
+
dataUrls.push(canvas.toDataURL("image/png"));
|
|
7133
7157
|
}
|
|
7134
7158
|
onProgress?.(totalSlides, totalSlides);
|
|
7135
7159
|
setActiveSlide(currentSlideIndex);
|
|
7136
|
-
|
|
7137
|
-
throw new Error(translationsEn["pptx.export.errorNoSlidesPdf"]);
|
|
7138
|
-
}
|
|
7139
|
-
const pdfBlobUrl = buildPdfFromImageData(images);
|
|
7140
|
-
downloadDataUrl(pdfBlobUrl, filename);
|
|
7160
|
+
return dataUrls;
|
|
7141
7161
|
}
|
|
7142
|
-
|
|
7143
|
-
|
|
7144
|
-
|
|
7162
|
+
|
|
7163
|
+
// src/viewer/utils/export-pdf.ts
|
|
7164
|
+
function tilesToPdfPage(tilesResult) {
|
|
7165
|
+
return tilesResult.tiles.map((tile) => ({
|
|
7166
|
+
image: canvasToJpegData(tile.canvas),
|
|
7167
|
+
placement: placeTileOnPage(
|
|
7168
|
+
tile,
|
|
7169
|
+
tilesResult.fullWidth,
|
|
7170
|
+
tilesResult.fullHeight,
|
|
7171
|
+
PDF_SLIDES_PAGE_WIDTH_PT,
|
|
7172
|
+
PDF_SLIDES_PAGE_HEIGHT_PT
|
|
7173
|
+
)
|
|
7174
|
+
}));
|
|
7175
|
+
}
|
|
7176
|
+
async function exportAllSlidesAsPdf(slideStageRef, totalSlides, setActiveSlide, currentSlideIndex, filename = "presentation.pdf", options = {}) {
|
|
7177
|
+
const { scale = 2, onProgress, signal } = options;
|
|
7178
|
+
const pages = [];
|
|
7145
7179
|
for (let i = 0; i < totalSlides; i++) {
|
|
7180
|
+
if (signal?.aborted) {
|
|
7181
|
+
throw new DOMException("Export cancelled", "AbortError");
|
|
7182
|
+
}
|
|
7146
7183
|
onProgress?.(i, totalSlides);
|
|
7147
7184
|
setActiveSlide(i);
|
|
7148
7185
|
await waitForRender(150);
|
|
@@ -7151,12 +7188,16 @@ async function captureAllSlidesAsPngDataUrls(slideStageRef, totalSlides, setActi
|
|
|
7151
7188
|
console.warn(`[export] Could not find slide stage element for slide ${i}`);
|
|
7152
7189
|
continue;
|
|
7153
7190
|
}
|
|
7154
|
-
const
|
|
7155
|
-
|
|
7191
|
+
const tilesResult = await renderElementToTiles(stageEl, scale);
|
|
7192
|
+
pages.push(tilesToPdfPage(tilesResult));
|
|
7156
7193
|
}
|
|
7157
7194
|
onProgress?.(totalSlides, totalSlides);
|
|
7158
7195
|
setActiveSlide(currentSlideIndex);
|
|
7159
|
-
|
|
7196
|
+
if (pages.length === 0) {
|
|
7197
|
+
throw new Error(translationsEn["pptx.export.errorNoSlidesPdf"]);
|
|
7198
|
+
}
|
|
7199
|
+
const pdfBlobUrl = buildPdfFromTiledImageData(pages);
|
|
7200
|
+
downloadDataUrl(pdfBlobUrl, filename);
|
|
7160
7201
|
}
|
|
7161
7202
|
async function exportAllSlidesAsNotesPdf(slideStageRef, totalSlides, setActiveSlide, currentSlideIndex, slideNotes, filename = "presentation-notes.pdf", options = {}) {
|
|
7162
7203
|
const { scale = 2, onProgress, signal } = options;
|
|
@@ -7173,7 +7214,7 @@ async function exportAllSlidesAsNotesPdf(slideStageRef, totalSlides, setActiveSl
|
|
|
7173
7214
|
console.warn(`[export] Could not find slide stage element for slide ${i}`);
|
|
7174
7215
|
continue;
|
|
7175
7216
|
}
|
|
7176
|
-
const canvas = await
|
|
7217
|
+
const { canvas } = await renderElementToTiledCanvas(stageEl, scale);
|
|
7177
7218
|
pages.push({
|
|
7178
7219
|
canvas,
|
|
7179
7220
|
notes: slideNotes[i],
|
|
@@ -7212,7 +7253,7 @@ async function exportAllSlidesAsVideo(slideStageRef, totalSlides, setActiveSlide
|
|
|
7212
7253
|
console.warn(`[export] Could not find slide stage element for slide ${i}`);
|
|
7213
7254
|
continue;
|
|
7214
7255
|
}
|
|
7215
|
-
const canvas = await
|
|
7256
|
+
const { canvas } = await renderElementToTiledCanvas(stageEl, scale);
|
|
7216
7257
|
slideCanvases.push(canvas);
|
|
7217
7258
|
}
|
|
7218
7259
|
setActiveSlide(currentSlideIndex);
|
|
@@ -7273,8 +7314,34 @@ async function exportAllSlidesAsVideo(slideStageRef, totalSlides, setActiveSlide
|
|
|
7273
7314
|
}
|
|
7274
7315
|
|
|
7275
7316
|
// src/viewer/utils/export-gif.ts
|
|
7317
|
+
function frameFromCanvas(canvas, maxSide) {
|
|
7318
|
+
const { width, height } = clampGifDimensions(canvas.width, canvas.height, maxSide);
|
|
7319
|
+
let source = canvas;
|
|
7320
|
+
if (width !== canvas.width || height !== canvas.height) {
|
|
7321
|
+
const scaled = canvas.ownerDocument.createElement("canvas");
|
|
7322
|
+
scaled.width = width;
|
|
7323
|
+
scaled.height = height;
|
|
7324
|
+
const scaledCtx = scaled.getContext("2d");
|
|
7325
|
+
if (!scaledCtx) {
|
|
7326
|
+
return void 0;
|
|
7327
|
+
}
|
|
7328
|
+
scaledCtx.drawImage(canvas, 0, 0, width, height);
|
|
7329
|
+
source = scaled;
|
|
7330
|
+
}
|
|
7331
|
+
const ctx = source.getContext("2d");
|
|
7332
|
+
if (!ctx) {
|
|
7333
|
+
return void 0;
|
|
7334
|
+
}
|
|
7335
|
+
return { imageData: ctx.getImageData(0, 0, width, height), width, height };
|
|
7336
|
+
}
|
|
7276
7337
|
async function exportAllSlidesAsGif(slideStageRef, totalSlides, setActiveSlide, currentSlideIndex, options = {}) {
|
|
7277
|
-
const {
|
|
7338
|
+
const {
|
|
7339
|
+
scale = 0.5,
|
|
7340
|
+
slideDurationMs = 2e3,
|
|
7341
|
+
maxSide = GIF_POST_CAPTURE_MAX_SIDE,
|
|
7342
|
+
onProgress,
|
|
7343
|
+
signal
|
|
7344
|
+
} = options;
|
|
7278
7345
|
const frames = [];
|
|
7279
7346
|
for (let i = 0; i < totalSlides; i++) {
|
|
7280
7347
|
if (signal?.aborted) {
|
|
@@ -7287,17 +7354,12 @@ async function exportAllSlidesAsGif(slideStageRef, totalSlides, setActiveSlide,
|
|
|
7287
7354
|
if (!stageEl) {
|
|
7288
7355
|
continue;
|
|
7289
7356
|
}
|
|
7290
|
-
const canvas = await
|
|
7291
|
-
const
|
|
7292
|
-
if (!
|
|
7357
|
+
const { canvas } = await renderElementToTiledCanvas(stageEl, scale);
|
|
7358
|
+
const frame = frameFromCanvas(canvas, maxSide);
|
|
7359
|
+
if (!frame) {
|
|
7293
7360
|
continue;
|
|
7294
7361
|
}
|
|
7295
|
-
|
|
7296
|
-
frames.push({
|
|
7297
|
-
imageData,
|
|
7298
|
-
width: canvas.width,
|
|
7299
|
-
height: canvas.height
|
|
7300
|
-
});
|
|
7362
|
+
frames.push(frame);
|
|
7301
7363
|
}
|
|
7302
7364
|
setActiveSlide(currentSlideIndex);
|
|
7303
7365
|
if (frames.length === 0) {
|
|
@@ -7368,6 +7430,149 @@ function exportAllSlidesToSvg(data, options = {}) {
|
|
|
7368
7430
|
return results;
|
|
7369
7431
|
}
|
|
7370
7432
|
|
|
7433
|
+
// src/viewer/utils/dom-helpers.ts
|
|
7434
|
+
function safePrompt(message, defaultValue) {
|
|
7435
|
+
try {
|
|
7436
|
+
return window.prompt(message, defaultValue);
|
|
7437
|
+
} catch {
|
|
7438
|
+
return null;
|
|
7439
|
+
}
|
|
7440
|
+
}
|
|
7441
|
+
function safeConfirm(message) {
|
|
7442
|
+
try {
|
|
7443
|
+
return window.confirm(message);
|
|
7444
|
+
} catch {
|
|
7445
|
+
return false;
|
|
7446
|
+
}
|
|
7447
|
+
}
|
|
7448
|
+
|
|
7449
|
+
// src/viewer/hooks/useExportMediaHandlers.ts
|
|
7450
|
+
function useExportMediaHandlers(input) {
|
|
7451
|
+
const {
|
|
7452
|
+
slides,
|
|
7453
|
+
activeSlideIndex,
|
|
7454
|
+
canvasStageRef,
|
|
7455
|
+
setActiveSlideIndex,
|
|
7456
|
+
imageResolutionScale = 1,
|
|
7457
|
+
exportAbortRef,
|
|
7458
|
+
setExportModalOpen,
|
|
7459
|
+
setExportModalTitle,
|
|
7460
|
+
setExportProgress,
|
|
7461
|
+
setExportStatusMessage
|
|
7462
|
+
} = input;
|
|
7463
|
+
const handleExportVideo = useCallback(async () => {
|
|
7464
|
+
if (!canvasStageRef.current) {
|
|
7465
|
+
return;
|
|
7466
|
+
}
|
|
7467
|
+
const abortCtrl = new AbortController();
|
|
7468
|
+
exportAbortRef.current = abortCtrl;
|
|
7469
|
+
setExportModalTitle("Export as Video");
|
|
7470
|
+
setExportStatusMessage("Capturing slides...");
|
|
7471
|
+
setExportProgress(0);
|
|
7472
|
+
setExportModalOpen(true);
|
|
7473
|
+
try {
|
|
7474
|
+
const { scale } = resolveExportCaptureDecision(imageResolutionScale, "video");
|
|
7475
|
+
const blob = await exportAllSlidesAsVideo(
|
|
7476
|
+
canvasStageRef,
|
|
7477
|
+
slides.length,
|
|
7478
|
+
setActiveSlideIndex,
|
|
7479
|
+
activeSlideIndex,
|
|
7480
|
+
{
|
|
7481
|
+
scale,
|
|
7482
|
+
slideDurationMs: 3e3,
|
|
7483
|
+
onProgress: (current, total) => {
|
|
7484
|
+
setExportProgress(slideProgressPercent(current, total, 45));
|
|
7485
|
+
setExportStatusMessage(slideStatusLabel("Capturing", current, total));
|
|
7486
|
+
},
|
|
7487
|
+
onRecordProgress: (current, total) => {
|
|
7488
|
+
setExportProgress(recordProgressPercent(current, total));
|
|
7489
|
+
setExportStatusMessage(slideStatusLabel("Recording", current, total));
|
|
7490
|
+
},
|
|
7491
|
+
signal: abortCtrl.signal
|
|
7492
|
+
}
|
|
7493
|
+
);
|
|
7494
|
+
setExportProgress(EXPORT_ASSEMBLING_PERCENT);
|
|
7495
|
+
setExportStatusMessage("Saving file...");
|
|
7496
|
+
downloadBlob(blob, "presentation.webm");
|
|
7497
|
+
setExportProgress(EXPORT_DONE_PERCENT);
|
|
7498
|
+
} catch (err) {
|
|
7499
|
+
if (!isExportAbortError(err)) {
|
|
7500
|
+
console.error("[PowerPointViewer] Video export failed:", err);
|
|
7501
|
+
}
|
|
7502
|
+
} finally {
|
|
7503
|
+
exportAbortRef.current = null;
|
|
7504
|
+
setExportModalOpen(false);
|
|
7505
|
+
}
|
|
7506
|
+
}, [
|
|
7507
|
+
canvasStageRef,
|
|
7508
|
+
slides.length,
|
|
7509
|
+
setActiveSlideIndex,
|
|
7510
|
+
activeSlideIndex,
|
|
7511
|
+
imageResolutionScale,
|
|
7512
|
+
exportAbortRef,
|
|
7513
|
+
setExportModalOpen,
|
|
7514
|
+
setExportModalTitle,
|
|
7515
|
+
setExportProgress,
|
|
7516
|
+
setExportStatusMessage
|
|
7517
|
+
]);
|
|
7518
|
+
const handleExportGif = useCallback(async () => {
|
|
7519
|
+
if (!canvasStageRef.current) {
|
|
7520
|
+
return;
|
|
7521
|
+
}
|
|
7522
|
+
const abortCtrl = new AbortController();
|
|
7523
|
+
exportAbortRef.current = abortCtrl;
|
|
7524
|
+
setExportModalTitle("Export as GIF");
|
|
7525
|
+
setExportStatusMessage("Capturing slides...");
|
|
7526
|
+
setExportProgress(0);
|
|
7527
|
+
setExportModalOpen(true);
|
|
7528
|
+
try {
|
|
7529
|
+
const { scale, postCaptureMaxSide } = resolveExportCaptureDecision(
|
|
7530
|
+
imageResolutionScale,
|
|
7531
|
+
"gif"
|
|
7532
|
+
);
|
|
7533
|
+
const blob = await exportAllSlidesAsGif(
|
|
7534
|
+
canvasStageRef,
|
|
7535
|
+
slides.length,
|
|
7536
|
+
setActiveSlideIndex,
|
|
7537
|
+
activeSlideIndex,
|
|
7538
|
+
{
|
|
7539
|
+
scale,
|
|
7540
|
+
maxSide: postCaptureMaxSide,
|
|
7541
|
+
slideDurationMs: 2e3,
|
|
7542
|
+
onProgress: (current, total) => {
|
|
7543
|
+
setExportProgress(slideProgressPercent(current, total));
|
|
7544
|
+
setExportStatusMessage(slideStatusLabel("Encoding", current, total));
|
|
7545
|
+
},
|
|
7546
|
+
signal: abortCtrl.signal
|
|
7547
|
+
}
|
|
7548
|
+
);
|
|
7549
|
+
setExportProgress(EXPORT_ASSEMBLING_PERCENT);
|
|
7550
|
+
setExportStatusMessage("Saving file...");
|
|
7551
|
+
downloadBlob(blob, "presentation.gif");
|
|
7552
|
+
setExportProgress(EXPORT_DONE_PERCENT);
|
|
7553
|
+
} catch (err) {
|
|
7554
|
+
if (!isExportAbortError(err)) {
|
|
7555
|
+
console.error("[PowerPointViewer] GIF export failed:", err);
|
|
7556
|
+
}
|
|
7557
|
+
} finally {
|
|
7558
|
+
exportAbortRef.current = null;
|
|
7559
|
+
setExportModalOpen(false);
|
|
7560
|
+
}
|
|
7561
|
+
}, [
|
|
7562
|
+
canvasStageRef,
|
|
7563
|
+
slides.length,
|
|
7564
|
+
setActiveSlideIndex,
|
|
7565
|
+
activeSlideIndex,
|
|
7566
|
+
imageResolutionScale,
|
|
7567
|
+
exportAbortRef,
|
|
7568
|
+
setExportModalOpen,
|
|
7569
|
+
setExportModalTitle,
|
|
7570
|
+
setExportProgress,
|
|
7571
|
+
setExportStatusMessage
|
|
7572
|
+
]);
|
|
7573
|
+
return { handleExportVideo, handleExportGif };
|
|
7574
|
+
}
|
|
7575
|
+
|
|
7371
7576
|
// src/viewer/hooks/useExportHandlers.ts
|
|
7372
7577
|
function useExportHandlers(input) {
|
|
7373
7578
|
const {
|
|
@@ -7392,13 +7597,26 @@ function useExportHandlers(input) {
|
|
|
7392
7597
|
theme,
|
|
7393
7598
|
canvasSize,
|
|
7394
7599
|
slideSizeEmu,
|
|
7395
|
-
imageExportScale
|
|
7600
|
+
imageExportScale,
|
|
7601
|
+
imageResolutionScale
|
|
7396
7602
|
} = input;
|
|
7397
7603
|
const [exportModalOpen, setExportModalOpen] = useState(false);
|
|
7398
7604
|
const [exportModalTitle, setExportModalTitle] = useState("");
|
|
7399
7605
|
const [exportProgress, setExportProgress] = useState(0);
|
|
7400
7606
|
const [exportStatusMessage, setExportStatusMessage] = useState("");
|
|
7401
7607
|
const exportAbortRef = useRef(null);
|
|
7608
|
+
const { handleExportVideo, handleExportGif } = useExportMediaHandlers({
|
|
7609
|
+
slides,
|
|
7610
|
+
activeSlideIndex,
|
|
7611
|
+
canvasStageRef,
|
|
7612
|
+
setActiveSlideIndex,
|
|
7613
|
+
imageResolutionScale,
|
|
7614
|
+
exportAbortRef,
|
|
7615
|
+
setExportModalOpen,
|
|
7616
|
+
setExportModalTitle,
|
|
7617
|
+
setExportProgress,
|
|
7618
|
+
setExportStatusMessage
|
|
7619
|
+
});
|
|
7402
7620
|
const {
|
|
7403
7621
|
handleExportJson,
|
|
7404
7622
|
handleSaveAsFormat,
|
|
@@ -7539,88 +7757,6 @@ function useExportHandlers(input) {
|
|
|
7539
7757
|
console.error("[PowerPointViewer] Copy slide as image failed:", err);
|
|
7540
7758
|
}
|
|
7541
7759
|
}, [canvasStageRef, activeSlide?.backgroundColor, imageExportScale]);
|
|
7542
|
-
const handleExportVideo = useCallback(async () => {
|
|
7543
|
-
if (!canvasStageRef.current) {
|
|
7544
|
-
return;
|
|
7545
|
-
}
|
|
7546
|
-
const abortCtrl = new AbortController();
|
|
7547
|
-
exportAbortRef.current = abortCtrl;
|
|
7548
|
-
setExportModalTitle("Export as Video");
|
|
7549
|
-
setExportStatusMessage("Capturing slides...");
|
|
7550
|
-
setExportProgress(0);
|
|
7551
|
-
setExportModalOpen(true);
|
|
7552
|
-
try {
|
|
7553
|
-
const blob = await exportAllSlidesAsVideo(
|
|
7554
|
-
canvasStageRef,
|
|
7555
|
-
slides.length,
|
|
7556
|
-
setActiveSlideIndex,
|
|
7557
|
-
activeSlideIndex,
|
|
7558
|
-
{
|
|
7559
|
-
scale: 1,
|
|
7560
|
-
slideDurationMs: 3e3,
|
|
7561
|
-
onProgress: (current, total) => {
|
|
7562
|
-
setExportProgress(slideProgressPercent(current, total, 45));
|
|
7563
|
-
setExportStatusMessage(slideStatusLabel("Capturing", current, total));
|
|
7564
|
-
},
|
|
7565
|
-
onRecordProgress: (current, total) => {
|
|
7566
|
-
setExportProgress(recordProgressPercent(current, total));
|
|
7567
|
-
setExportStatusMessage(slideStatusLabel("Recording", current, total));
|
|
7568
|
-
},
|
|
7569
|
-
signal: abortCtrl.signal
|
|
7570
|
-
}
|
|
7571
|
-
);
|
|
7572
|
-
setExportProgress(EXPORT_ASSEMBLING_PERCENT);
|
|
7573
|
-
setExportStatusMessage("Saving file...");
|
|
7574
|
-
downloadBlob(blob, "presentation.webm");
|
|
7575
|
-
setExportProgress(EXPORT_DONE_PERCENT);
|
|
7576
|
-
} catch (err) {
|
|
7577
|
-
if (!isExportAbortError(err)) {
|
|
7578
|
-
console.error("[PowerPointViewer] Video export failed:", err);
|
|
7579
|
-
}
|
|
7580
|
-
} finally {
|
|
7581
|
-
exportAbortRef.current = null;
|
|
7582
|
-
setExportModalOpen(false);
|
|
7583
|
-
}
|
|
7584
|
-
}, [canvasStageRef, slides.length, setActiveSlideIndex, activeSlideIndex]);
|
|
7585
|
-
const handleExportGif = useCallback(async () => {
|
|
7586
|
-
if (!canvasStageRef.current) {
|
|
7587
|
-
return;
|
|
7588
|
-
}
|
|
7589
|
-
const abortCtrl = new AbortController();
|
|
7590
|
-
exportAbortRef.current = abortCtrl;
|
|
7591
|
-
setExportModalTitle("Export as GIF");
|
|
7592
|
-
setExportStatusMessage("Capturing slides...");
|
|
7593
|
-
setExportProgress(0);
|
|
7594
|
-
setExportModalOpen(true);
|
|
7595
|
-
try {
|
|
7596
|
-
const blob = await exportAllSlidesAsGif(
|
|
7597
|
-
canvasStageRef,
|
|
7598
|
-
slides.length,
|
|
7599
|
-
setActiveSlideIndex,
|
|
7600
|
-
activeSlideIndex,
|
|
7601
|
-
{
|
|
7602
|
-
scale: 0.5,
|
|
7603
|
-
slideDurationMs: 2e3,
|
|
7604
|
-
onProgress: (current, total) => {
|
|
7605
|
-
setExportProgress(slideProgressPercent(current, total));
|
|
7606
|
-
setExportStatusMessage(slideStatusLabel("Encoding", current, total));
|
|
7607
|
-
},
|
|
7608
|
-
signal: abortCtrl.signal
|
|
7609
|
-
}
|
|
7610
|
-
);
|
|
7611
|
-
setExportProgress(EXPORT_ASSEMBLING_PERCENT);
|
|
7612
|
-
setExportStatusMessage("Saving file...");
|
|
7613
|
-
downloadBlob(blob, "presentation.gif");
|
|
7614
|
-
setExportProgress(EXPORT_DONE_PERCENT);
|
|
7615
|
-
} catch (err) {
|
|
7616
|
-
if (!isExportAbortError(err)) {
|
|
7617
|
-
console.error("[PowerPointViewer] GIF export failed:", err);
|
|
7618
|
-
}
|
|
7619
|
-
} finally {
|
|
7620
|
-
exportAbortRef.current = null;
|
|
7621
|
-
setExportModalOpen(false);
|
|
7622
|
-
}
|
|
7623
|
-
}, [canvasStageRef, slides.length, setActiveSlideIndex, activeSlideIndex]);
|
|
7624
7760
|
const handleCancelExport = useCallback(() => {
|
|
7625
7761
|
exportAbortRef.current?.abort();
|
|
7626
7762
|
exportAbortRef.current = null;
|
|
@@ -9234,7 +9370,8 @@ function useIOHandlers(input) {
|
|
|
9234
9370
|
serializeForRecovery,
|
|
9235
9371
|
setContent,
|
|
9236
9372
|
onContentChange,
|
|
9237
|
-
imageExportScale
|
|
9373
|
+
imageExportScale,
|
|
9374
|
+
imageResolutionScale
|
|
9238
9375
|
} = input;
|
|
9239
9376
|
const exportHandlers = useExportHandlers({
|
|
9240
9377
|
slides,
|
|
@@ -9258,7 +9395,8 @@ function useIOHandlers(input) {
|
|
|
9258
9395
|
theme: state.theme,
|
|
9259
9396
|
canvasSize,
|
|
9260
9397
|
slideSizeEmu: state.slideSizeEmu,
|
|
9261
|
-
imageExportScale
|
|
9398
|
+
imageExportScale,
|
|
9399
|
+
imageResolutionScale
|
|
9262
9400
|
});
|
|
9263
9401
|
const printHandlers = usePrintHandlers({
|
|
9264
9402
|
slides,
|
|
@@ -9392,6 +9530,52 @@ function useFontInjection({ embeddedFonts, slides }) {
|
|
|
9392
9530
|
}
|
|
9393
9531
|
};
|
|
9394
9532
|
}, [embeddedFonts, slides]);
|
|
9533
|
+
const [, setOutlineFontsTick] = useState(0);
|
|
9534
|
+
useEffect(() => {
|
|
9535
|
+
let cancelled = false;
|
|
9536
|
+
const referenced = collectReferencedFontFamilies(slides);
|
|
9537
|
+
const candidates = selectGoogleWebfontFamilies(
|
|
9538
|
+
referenced,
|
|
9539
|
+
embeddedFonts.map((font) => font.name)
|
|
9540
|
+
);
|
|
9541
|
+
if (candidates.length === 0) {
|
|
9542
|
+
return;
|
|
9543
|
+
}
|
|
9544
|
+
void resolveGoogleWebfontHref(slides, embeddedFonts).then(async (href) => {
|
|
9545
|
+
if (cancelled || !href) {
|
|
9546
|
+
return;
|
|
9547
|
+
}
|
|
9548
|
+
const boldItalicVariants = [
|
|
9549
|
+
{ bold: false, italic: false },
|
|
9550
|
+
{ bold: true, italic: false }
|
|
9551
|
+
];
|
|
9552
|
+
let registeredAny = false;
|
|
9553
|
+
for (const family of candidates) {
|
|
9554
|
+
for (const variant of boldItalicVariants) {
|
|
9555
|
+
if (cancelled) {
|
|
9556
|
+
return;
|
|
9557
|
+
}
|
|
9558
|
+
const bytes = await fetchGoogleWebfontOutlineBytes(
|
|
9559
|
+
href,
|
|
9560
|
+
family,
|
|
9561
|
+
variant.bold,
|
|
9562
|
+
variant.italic,
|
|
9563
|
+
fetch
|
|
9564
|
+
);
|
|
9565
|
+
if (bytes && glyphOutlineFontCache.registerFontBytes(family, variant.bold, variant.italic, bytes)) {
|
|
9566
|
+
registeredAny = true;
|
|
9567
|
+
}
|
|
9568
|
+
}
|
|
9569
|
+
}
|
|
9570
|
+
if (registeredAny && !cancelled) {
|
|
9571
|
+
setOutlineFontsTick((tick) => tick + 1);
|
|
9572
|
+
}
|
|
9573
|
+
return void 0;
|
|
9574
|
+
});
|
|
9575
|
+
return () => {
|
|
9576
|
+
cancelled = true;
|
|
9577
|
+
};
|
|
9578
|
+
}, [embeddedFonts, slides]);
|
|
9395
9579
|
useEffect(() => {
|
|
9396
9580
|
const neededSymbolFonts = SYMBOL_FONT_FAMILIES.filter((f) => referencedFamilies.has(f));
|
|
9397
9581
|
if (neededSymbolFonts.length === 0) {
|
|
@@ -9759,6 +9943,7 @@ function useViewerIntegration(input) {
|
|
|
9759
9943
|
canEdit,
|
|
9760
9944
|
promptKeepInkAnnotations,
|
|
9761
9945
|
imageExportScale,
|
|
9946
|
+
imageResolutionScale,
|
|
9762
9947
|
mode,
|
|
9763
9948
|
slides,
|
|
9764
9949
|
activeSlide,
|
|
@@ -9844,7 +10029,8 @@ function useViewerIntegration(input) {
|
|
|
9844
10029
|
serializeForRecovery,
|
|
9845
10030
|
setContent,
|
|
9846
10031
|
onContentChange,
|
|
9847
|
-
imageExportScale
|
|
10032
|
+
imageExportScale,
|
|
10033
|
+
imageResolutionScale
|
|
9848
10034
|
});
|
|
9849
10035
|
const {
|
|
9850
10036
|
showKeepAnnotationsDialog,
|
|
@@ -10510,7 +10696,7 @@ function useLayoutSwitching(input) {
|
|
|
10510
10696
|
currentLayoutPath
|
|
10511
10697
|
};
|
|
10512
10698
|
}
|
|
10513
|
-
var MIN_TOUCH_TARGET =
|
|
10699
|
+
var MIN_TOUCH_TARGET = MIN_TOUCH_TARGET_PX;
|
|
10514
10700
|
function subscribeTouchCapability(callback) {
|
|
10515
10701
|
if (typeof window === "undefined") {
|
|
10516
10702
|
return () => {
|
|
@@ -10595,7 +10781,9 @@ function useIsMobile() {
|
|
|
10595
10781
|
isDesktop,
|
|
10596
10782
|
isTouchDevice,
|
|
10597
10783
|
orientation,
|
|
10598
|
-
isVirtualKeyboardOpen
|
|
10784
|
+
isVirtualKeyboardOpen,
|
|
10785
|
+
viewportWidth,
|
|
10786
|
+
viewportHeight
|
|
10599
10787
|
};
|
|
10600
10788
|
}
|
|
10601
10789
|
function useTouchGestures(input) {
|
|
@@ -11299,6 +11487,7 @@ function useViewerBuildingBlocksCore(input) {
|
|
|
11299
11487
|
// Multiplied against the pre-existing 2x baseline; see the matching
|
|
11300
11488
|
// comment in `PowerPointViewer.tsx`.
|
|
11301
11489
|
imageExportScale: 2 * resolveImageResolutionScale(viewerOptions),
|
|
11490
|
+
imageResolutionScale: resolveImageResolutionScale(viewerOptions),
|
|
11302
11491
|
viewerOptions
|
|
11303
11492
|
};
|
|
11304
11493
|
}
|
|
@@ -11481,6 +11670,7 @@ function useViewerBuildingBlocksState(input) {
|
|
|
11481
11670
|
actionSoundHandlerRef,
|
|
11482
11671
|
gridSpacingPx,
|
|
11483
11672
|
imageExportScale,
|
|
11673
|
+
imageResolutionScale,
|
|
11484
11674
|
setExitModeHandler,
|
|
11485
11675
|
viewerOptions
|
|
11486
11676
|
} = core;
|
|
@@ -11566,6 +11756,7 @@ function useViewerBuildingBlocksState(input) {
|
|
|
11566
11756
|
canEdit,
|
|
11567
11757
|
promptKeepInkAnnotations: viewerOptions.advanced.slideShowPromptKeepInkAnnotations,
|
|
11568
11758
|
imageExportScale,
|
|
11759
|
+
imageResolutionScale,
|
|
11569
11760
|
mode,
|
|
11570
11761
|
slides,
|
|
11571
11762
|
activeSlide,
|
|
@@ -11823,4 +12014,4 @@ function useResizablePanels() {
|
|
|
11823
12014
|
};
|
|
11824
12015
|
}
|
|
11825
12016
|
|
|
11826
|
-
export { ACTION_VERB_MAP, MIN_TOUCH_TARGET, ViewerOptionsContext, computeToolbarVisibility, detectTargetType, isAudienceTab, parseAudienceNonce, parseEmailUrl, parseSlideFromUrl, playAnimationSound, renderToCanvas, safePrompt, scopeLayoutOptionsToActiveSlide, syncSelectionHandleOverlay, useAnimationPlayback, useAnnotationHandlers, useAudienceMode, useAutosave, useBroadcastFollower, useCanvasInteractions, useClipboardHandlers, useCollaborationLivePatch, useCollaborativeHistory, useCollaborativeState, useComments, useCompatibilityToastsState, 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, useReadOnlyRecommendationState, useRecoveryDetection, useReducedMotion, useRehearsalTimings, useResizablePanels, useSectionOperations, useSerialize, useSheetDismissDrag, useSlideManagement, useSlideNavigation, useSwipeNavigation, useTableOperations, useThemeHandlers, useThemeSwitching, useToolbarVisibility, useTouchGestures, useViewPreferencesSync, useViewerBuildingBlocks, useViewerCoreState, useViewerDialogs, useViewerIntegration, useViewerOptions, useViewerOptionsContext, useViewerState, useViewerUIState, useVirtualizedSlides, useYjsDocumentSync, useYjsProvider, useZoomNavigation, useZoomViewport };
|
|
12017
|
+
export { ACTION_VERB_MAP, MIN_TOUCH_TARGET, ViewerOptionsContext, computeToolbarVisibility, detectTargetType, getGlyphOutline, isAudienceTab, parseAudienceNonce, parseEmailUrl, parseSlideFromUrl, playAnimationSound, renderToCanvas, safePrompt, scopeLayoutOptionsToActiveSlide, syncSelectionHandleOverlay, useAnimationPlayback, useAnnotationHandlers, useAudienceMode, useAutosave, useBroadcastFollower, useCanvasInteractions, useClipboardHandlers, useCollaborationLivePatch, useCollaborativeHistory, useCollaborativeState, useComments, useCompatibilityToastsState, 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, useReadOnlyRecommendationState, useRecoveryDetection, useReducedMotion, useRehearsalTimings, useResizablePanels, useSectionOperations, useSerialize, useSheetDismissDrag, useSlideManagement, useSlideNavigation, useSwipeNavigation, useTableOperations, useThemeHandlers, useThemeSwitching, useToolbarVisibility, useTouchGestures, useViewPreferencesSync, useViewerBuildingBlocks, useViewerCoreState, useViewerDialogs, useViewerIntegration, useViewerOptions, useViewerOptionsContext, useViewerState, useViewerUIState, useVirtualizedSlides, useYjsDocumentSync, useYjsProvider, useZoomNavigation, useZoomViewport };
|