pptx-react-viewer 4.51.1 → 4.52.1
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 +74 -0
- package/dist/{AiChatPanel-EV22O7UO.js → AiChatPanel-7GJQ66GR.js} +19 -19
- package/dist/AiChatPanel-7GJQ66GR.js.br +0 -0
- package/dist/AiChatPanel-7GJQ66GR.js.gz +0 -0
- package/dist/{AiChatPanel-R323KNGN.mjs → AiChatPanel-AI75AT6C.mjs} +1 -1
- package/dist/AiChatPanel-AI75AT6C.mjs.br +0 -0
- package/dist/AiChatPanel-AI75AT6C.mjs.gz +0 -0
- package/dist/{chunk-YJ4DAS4V.js → chunk-2AM5YYWI.js} +586 -615
- package/dist/chunk-2AM5YYWI.js.br +0 -0
- package/dist/chunk-2AM5YYWI.js.gz +0 -0
- package/dist/{chunk-Z22RD3E2.js → chunk-3TN5SUQR.js} +4 -1
- package/dist/chunk-3TN5SUQR.js.br +0 -0
- package/dist/chunk-3TN5SUQR.js.gz +0 -0
- package/dist/{chunk-V4DY4IWP.mjs → chunk-6436YER5.mjs} +390 -420
- package/dist/chunk-6436YER5.mjs.br +0 -0
- package/dist/chunk-6436YER5.mjs.gz +0 -0
- package/dist/{chunk-ZCGYPCZM.mjs → chunk-ID37Y3HG.mjs} +4 -1
- package/dist/chunk-ID37Y3HG.mjs.br +0 -0
- package/dist/chunk-ID37Y3HG.mjs.gz +0 -0
- package/dist/{chunk-VRX5NJY2.js → chunk-JUH4YPMU.js} +1702 -1616
- package/dist/chunk-JUH4YPMU.js.br +0 -0
- package/dist/chunk-JUH4YPMU.js.gz +0 -0
- package/dist/{chunk-KCUXY7DE.mjs → chunk-L77POU5D.mjs} +216 -130
- package/dist/chunk-L77POU5D.mjs.br +0 -0
- package/dist/chunk-L77POU5D.mjs.gz +0 -0
- package/dist/i18n/de.cjs +1 -24
- package/dist/i18n/de.cjs.br +0 -0
- package/dist/i18n/de.cjs.gz +0 -0
- package/dist/i18n/de.mjs +1 -24
- package/dist/i18n/de.mjs.br +0 -0
- package/dist/i18n/de.mjs.gz +0 -0
- package/dist/i18n/es.cjs +1 -24
- package/dist/i18n/es.cjs.br +0 -0
- package/dist/i18n/es.cjs.gz +0 -0
- package/dist/i18n/es.mjs +1 -24
- package/dist/i18n/es.mjs.br +0 -0
- package/dist/i18n/es.mjs.gz +0 -0
- package/dist/i18n/fr.cjs +1 -24
- package/dist/i18n/fr.cjs.br +0 -0
- package/dist/i18n/fr.cjs.gz +0 -0
- package/dist/i18n/fr.mjs +1 -24
- package/dist/i18n/fr.mjs.br +0 -0
- package/dist/i18n/fr.mjs.gz +0 -0
- package/dist/i18n/zh-CN.cjs +0 -23
- package/dist/i18n/zh-CN.cjs.br +0 -0
- package/dist/i18n/zh-CN.cjs.gz +0 -0
- package/dist/i18n/zh-CN.mjs +0 -23
- package/dist/i18n/zh-CN.mjs.br +0 -0
- package/dist/i18n/zh-CN.mjs.gz +0 -0
- package/dist/index.d.ts +14 -2
- package/dist/index.js +25 -25
- package/dist/index.js.br +0 -0
- package/dist/index.js.gz +0 -0
- package/dist/index.mjs +3 -3
- package/dist/index.mjs.br +0 -0
- package/dist/index.mjs.gz +0 -0
- package/dist/internals.d.ts +85 -23
- package/dist/internals.js +81 -81
- package/dist/internals.js.br +0 -0
- package/dist/internals.js.gz +0 -0
- package/dist/internals.mjs +2 -2
- package/dist/internals.mjs.br +0 -0
- package/dist/internals.mjs.gz +0 -0
- package/dist/viewer/index.d.ts +13 -1
- package/dist/viewer/index.js +20 -20
- package/dist/viewer/index.js.br +0 -0
- package/dist/viewer/index.js.gz +0 -0
- package/dist/viewer/index.mjs +3 -3
- package/dist/viewer/index.mjs.br +0 -0
- package/dist/viewer/index.mjs.gz +0 -0
- package/package.json +3 -3
- package/dist/AiChatPanel-EV22O7UO.js.br +0 -0
- package/dist/AiChatPanel-EV22O7UO.js.gz +0 -0
- package/dist/AiChatPanel-R323KNGN.mjs.br +0 -0
- package/dist/AiChatPanel-R323KNGN.mjs.gz +0 -0
- package/dist/chunk-KCUXY7DE.mjs.br +0 -0
- package/dist/chunk-KCUXY7DE.mjs.gz +0 -0
- package/dist/chunk-V4DY4IWP.mjs.br +0 -0
- package/dist/chunk-V4DY4IWP.mjs.gz +0 -0
- package/dist/chunk-VRX5NJY2.js.br +0 -0
- package/dist/chunk-VRX5NJY2.js.gz +0 -0
- package/dist/chunk-YJ4DAS4V.js.br +0 -0
- package/dist/chunk-YJ4DAS4V.js.gz +0 -0
- package/dist/chunk-Z22RD3E2.js.br +0 -0
- package/dist/chunk-Z22RD3E2.js.gz +0 -0
- package/dist/chunk-ZCGYPCZM.mjs.br +0 -0
- package/dist/chunk-ZCGYPCZM.mjs.gz +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { cloneTemplateElementsBySlideId, cloneSlide, cloneHistorySnapshot, MIN_ELEMENT_SIZE, ZOOM_TO_SELECTION_PADDING, DEFAULT_CANVAS_HEIGHT, DEFAULT_CANVAS_WIDTH, partitionTemplateElements, isTemplateElementId, DEFAULT_TABLE_ROWS, DEFAULT_TABLE_COLUMNS, useTranslation, comparePresentation, UNGROUPED_SECTION_ID, DEFAULT_SECTION_GROUP_ID, stopAllPersistentAudio, buildSaveSlides, MAX_ZOOM_SCALE, MIN_ZOOM_SCALE, getImageEffectsOpacity, getImageEffectsFilter, getImageRenderStyle, cn, isEditableTextElement, getShapeVisualStyle, getTextStyleForElement, DEFAULT_TEXT_COLOR, renderVectorShape, isConnectorOrLineElement, build3DExtrusionData, getImageSurfaceStyle, getTextLayoutStyle, renderTableElement, renderMediaElement, shouldRenderFallbackLabel, getElementLabel, normalizeHexColor, makeCloneId, DEFAULT_TEXT_FONT_SIZE, buildPdfFromTiledImageData, GRID_SIZE, copyFormatFromElement, hasCopyableFormat, isImageTiled, getDuotoneColors, DEFAULT_STROKE_COLOR, DEFAULT_FILL_COLOR, buildCssGradientFromShapeStyle, getCropShapeClipPath, getElementTransform, hasDagDuotoneEffect, renderDagDuotoneSvgFilter, getImageSurfaceMaskStyle, getTextWarpStyle, getTextCompensationTransform, renderTextSegments, buildReactChartViewModel, renderChartElement, buildInkGroupStrokes, getInkReplayStyles, INK_REPLAY_KEYFRAMES, buildContentPartStrokes, getContentPartReplayStyles, buildTextBody3DSceneStyle, rerouteConnectorsForMovedElements, applyReroutedConnectors, updateCellTextStyleInRawXml, updateCellTextInRawXml, splitCell, updateMergeAttrsInRawXml, mergeCells, buildNotesPdf, canvasToJpegData, applyFormatToElement, isPpactionUrl, parsePpactionUrl, getImageTilingStyle, buildCacheKey, DEFAULT_COLOR_CHANGE_TOLERANCE, getCachedResult, applyColorChange, setCachedResult, colorWithOpacity, normalizeStrokeDashType, getSvgStrokeDasharray, getCompoundLineOffsets, getCompoundLineWidths, getConnectorPathGeometry, buildLineShadowCss, buildLineGlowFilter, renderConnectorMarker, getAriaRoleDescription as getAriaRoleDescription$1, getAriaLabel as getAriaLabel$1, getAriaRole, DEFAULT_FONT_FAMILY, ACTION_BUTTON_PRESETS, isUrlSafe, safeOpenUrl as safeOpenUrl$1, substituteFieldText, HYPERLINK_COLOR } from './chunk-
|
|
2
|
-
import { defineThreeViewElement, MIN_TOUCH_TARGET_PX, computeVirtualRange, DEFAULT_VIRTUAL_OVERSCAN, createCollaborationSessionController, registerCollaborationTeardown, createPresenceProjector, BROADCAST_THROTTLE_MS, sanitizeColor, createEditorHistoryController, createWheelStepBuffer, createViewerZoomStore, clampZoomScale, mapEditingWheel, createActiveAnimationGroup, cancelBuildReveal, clearPlaybackTimers, PresentationAnimationController, resolveMediaTimeNodeElementIds, resolveMediaBookmarkTimesMs, advanceMainSequence, playGroup, PRESENTATION_HASH, PRESENTATION_NONCE_KEY, PRESENTATION_CHANNEL_NAME, swapPresentationWindows, PRESENTATION_MESSAGE_ORIGIN, clearAudienceContent, buildPresentationAudienceUrl, resolveAudienceScreenPlacement, placeAudienceWindow, storeAudienceContent, isPresentationSessionMessage, endAudienceDisplay, createPresentationKeyBuffer, acceptsPresentationInput, resolveAutoAdvanceDelayMs, resolveShowBackward, resolveShowForward, beginZoomExcursion, buildZoomTransitionOverride, createPresenterShowGuard, firstShowSlideIndex, attachPresentationVisibilityPause, presentationEntrySlideIndex, buildMorphTransitionPlan, morphOptionToMode, buildMorphAnimationRules, findInSlides, applyFindReplacements, visibleTemplateElements, createCollaborationLivePatcher, reportInlineTextDraft, initialInspectorOpen, createPresentationLoadResources, collectMediaElements, resolveMediaElementSource, collectImagePaths, applyImagePathPatches, resolveTableCellImageUrls, resolveTableStyleImageUrls, resolveTextFillBlipUrls, seedRecentColors, resolveAuthoredCustomShowId, GlyphOutlineFontCache, buildInitialGuides, readOnlyRecommendation, compatibilityWarningToasts, resolveInitialSlideIndex, resolveAutosaveIntervalMs, createAutosaveController, saveAutosaveSnapshot, updateMasterViewElement, updateElement, masterViewElements, replaceMasterViewElements, addSection, renameSection, deleteSection, moveSectionUp, moveSectionDown, moveSlidesToSection, canMergeShapes, canInteractWithElement, prepareHtml2CanvasClone, html2canvasCaptureScope, slideProgressPercent, slideStatusLabel, EXPORT_ASSEMBLING_PERCENT, EXPORT_DONE_PERCENT, isExportAbortError, DEFAULT_VIEWER_OPTIONS, resolveImageResolutionScale, applyAcceptSlide, applyAcceptAllSlides, collectUsedFonts, describeFontEmbedding, isMobileViewport, resolveAuthoredSlideRange, mayLeaveSlideShow, buildDeckSaveOptions, resolveSlideSizeSelection, saveDeckWithPassword, createAutosaveRecoveryController, discardAutosaveRecovery, probeAutosaveRecovery, shouldLoopContinuously, applyRehearsalTimings, rasterResultToPngBlob, downloadBlob, elementPictureFilename, canEditElementPoints, selectTrustedEmbeddedFonts, resolveFontWeight, resolveFontItalic, collectReferencedFontFamilies, resolveGoogleWebfontHref, syncGoogleWebfontStylesheet, selectGoogleWebfontFamilies, fetchGoogleWebfontOutlineBytes, dispatchEditorKey, isFeatureEnabled, parentSelection, textFontSizePtToPx, stepFontSizePt, textFontSizePxToPt, cycleSelectableElement, createCustomizationController, prepareElementForInsertion, slideSpaceElement, autosaveStatusKind, createViewerOptionsStore, observeYDocSlides, LOCAL_SYNC_ORIGIN, readSlidesFromYDoc, shouldRoomSlidesReplaceLoad, reconcileSlidesInYDoc, shouldAutoFollowBroadcaster, detectTouchDevice, detectOrientation, deriveViewportBreakpoints, createTouchGestureRecognizer, isKeyboardOpen, scopeLayoutOptionsToSlide, INITIAL_READ_ONLY_SESSION, readOnlySessionActions, applyReadOnlySessionEvent, readOnlyBannerVisible, readOnlyLocked, viewerPreferencesFromViewProperties, DEFAULT_VIEWER_PREFERENCES, viewPropertiesPatchFromPreferences, resolveCollaborationConfig, openPptxFile, readBackstageRecentFile, resolveCollaborationShellEditability, resolveCollaborationShellState, getResizeHandleHitAreaStyle, resolveElementInteractivity, getBackgroundAnimationState, getShapeEffectLayerPlacement, buildTextStyleOverrideCss, isElementRendered, resolveElementAriaAttributes, isMediaFullscreenActive, shouldRenderHitTarget, elementHitTargetStyle, getShapeEffectAnimationLayerStyle, inlineElementPointerEvents, isHollowShapeElement, LINK_TOOLTIP_HOST_CLASS, resolvePalette as resolvePalette$1, mediaTransportVisible, oleActionsVisible, getGroupChildParentFill, deviceStrokeStageStyle, MORPH_CROSSFADE_GROUP_STYLE, MORPH_CROSSFADE_HALF_STYLE, getSlideTransitionAnimations, getFragmentedTransitionDescriptor, SLIDE_TRANSITION_KEYFRAMES, isActionHidden, buildInlineTextCommitPatch, resolveInlineEditAutoFitHeight, resolveInlineEditNormAutofitShrink, setPendingCaretPoint, resolveGroupDoubleClickTarget, filterInteractableIds, beginShapeAdjustment, buildElementClipboardPayload, contextMenuInspectorAnchor, savedPresentationFileName, deliverSavedPresentation, exportDeckJson, mapCustomizedEditorKey, isEditorTextInputTarget, groupElements, generateElementId, ungroupElements, alignElements, distributeElements, newTableElement, createDefaultChartElement, readViewportMetrics, computeKeyboardInset, planMergeShapes, applyMergeShapesPlan, mapPresentationKey, lastShowSlideIndex, mapPresentationWheel, openPendingPrintWindow, computeColorFilter, filterHiddenSlideIndices, computeSlideIndices, buildPrintDocument, finishPrintWindow, buildPrintHtmlDocument, buildOutlineHtml, buildSlidesHtml, buildNotesHtml, buildHandoutsHtml, createBlankSlide, insertSlidePaste, applySlidePasteTemplates, makeSlideId, buildSlideTemplateSlide, templateSchemeFromTheme, needsOwnedSession, openOwnedCollaboration, resolveViewportFitOptions, editorViewportFitFor, calculateViewportFit, observeViewportClientSize, scheduleAutoAdvanceChain, computeEntranceAnimationDelay, createPresentationSessionId, resolveTransitionDurationMs, resolveTransitionSoundAction, runPresentationAction, safeOpenUrl, buildRunProgramNotice, toggleStageElementMedia, resolveOleVerbTarget, downloadDataUrl, openUrlInNewTab, createPresenterTimer, createInitialPresentationSnapshot, mergePresentationSnapshot, resetPresenterTimer, presenterElapsed, stepPresenterZoom, togglePresenterTimer, addCommentToList, removeCommentFromList, editCommentInList, toggleCommentResolvedInList, slideSpaceMembers, remapTextToSegments, getInlineEditorSelectionResult, buildInlineListStylePatch, applyActiveInlineListFormatting, applyListStyleUpdate, setPendingSelectionRestore, applyTextStyleUpdate, toggleSelectionBullets, transformInlineListCase, applyCaseTransformToSegments, transformTextCase, createGestureController, resolveExportCaptureDecision, recordProgressPercent, computeGridSpacingPx as computeGridSpacingPx$1, resolveShowSlideIndexes, groupSlidesBySection, masterViewPseudoSlide, overlayMasterViewInlineSnapshot, overlayInlineTextSnapshot, rasterizeElement, cloneElementForPaste, applyPasteSpecialFormat, buildRasterPictureElement, cloneElementUpdates, assertElementUpdateTarget, prepareElementUpdateBatch, createWriteBackScheduler, writeBackReport, createSyncGate, observeExternalCollaborationReadiness, resolveHistoryDepth, createBackstagePresentation, buildFieldSubstitutionContext, getImageColorWashStyle, attachRotateHandlePlacement, getSelectionControlArtworkStyle, getSelectionOutlineColor, paintedStrokeWidth, ensureActionAffordanceStyles, resolveElementActionAffordance, actionAffordanceLabels, paintedElementSize, MEDIA_FULLSCREEN_OVERLAY_STYLE, elementContainerHeightStyle, getAnimationOpacity, resolveElementHighlightClick, applyHighlightClickStyle, getComputedEffectStyle, getSoftEdgeSvgFilter, getEffectStyleSource, getBevelLightingSvgFilter, buildStrokeOutline, buildHollowHitOutline, buildSubpathFillOverlay, strokeOutlineViewBox, buildSummaryZoomView, readEditableText, placeCaretAt, takePendingCaretPoint, getPendingSelectionRestore, restoreSegmentSelection, mapInlineTextFormatKey, mapInlineEditorChord, subscribeBarFacePicturePixelSamples, getBarFacePicturePixelSampleVersion, ensureChartInteractionStyles, applyChartPartHighlight, resolveRevealedChartData, formatAxisValue, chartFormatTargetFromEvent, resolveOleType, getOleAriaLabel, getOleTypeColor, getOleTypeLabel, filterRenderedElements, resolveGroupChildFill, isLinkedTextBox, getOverflowSegments, shouldUseSvgWarp, getTextBodyRotationTransform, placeholderPromptDescriptor, getAriaRoleDescription, getAriaLabel, elementIdSelector, TOOLBAR_TABS, resolveGroupPressTarget, scrollInspectorSectionIntoView, computeScrollDelta, replyToCommentInList, removeTableElementColumn, insertTableElementColumn, removeTableElementRow, insertTableElementRow, withCellStyle, setCellText, pickSupportedMimeType, WEBM_MIME_CANDIDATES, fpsToFrameIntervalMs, segmentFrameCount, stopCaptureStream, GIF_POST_CAPTURE_MAX_SIDE, encodeGif, rasterizeElementTiles, placeTileOnPage, PDF_SLIDES_PAGE_WIDTH_PT, PDF_SLIDES_PAGE_HEIGHT_PT, createSnapshotTextPositions, resolvePresentationAction, getImageSvgFilters, getCachedNativeImageSize, probeNativeImageSize, buildDuotoneCacheKey, getDuotoneCachedResult, applyDuotone, setDuotoneCachedResult, svgLineCap, screenStrokeWidth, connectorWrapperTransform, ACTION_INDICATOR_CLASS, ACTION_INDICATOR_ICON_PATH, LINK_TOOLTIP_CLASS, LINK_TOOLTIP_PANEL_CLASS, LINK_TOOLTIP_LABEL_CLASS, LINK_TOOLTIP_HINT_CLASS, modelDataToBlobUrl, resolveZoomNavigationTarget, inlineListBodyText, createInlineListSeed, readListActivationSelection, createInlineListModelObserver, attachCollaborationInlineEditor, bindInlineListParagraph, bindInlineListRun, attachInlineListController, restoreInlineListBodySelection, isBulletMarkerSegment, resolveChartThreeViewSpec, applyChart3DDrag, applyChart3DSelect, canDrillDown, findChartPartTarget, withChartTitle, resolveSmartArtThreeViewSpec, measureSvgViewportRect, isBrowserOpenableMime, formatBytes, getOleDisplayName, getOleBadgeLabel, hasGlyphEnvelope, buildGlyphEnvelopeBlock, getWarpPath, isWedgeCalloutPresetShape, getAriaRole as getAriaRole$1, isElementActionable, buildSmartArtPresetData, classifyMediaType, getDraggedShapeAdjustments, computeMarqueeHitIds, mergeAdditiveSelection, rasterizeElementTiledToCanvas, borrowExternalCollaborationAwareness, observeExternalCollaborationSession, publishLiveGeometry, clampGifDimensions, rasterResultToPngDataUrl, shouldConfirmExternalHyperlink, advanceChartMarkDrag, advanceChartValueDrag, resolveChartKind, buildChartMarkDragGeometry, beginChartMarkDrag, beginChartValueDrag, findSmartArtNodeText, commitSmartArtNodeFill, commitSmartArtNodeText, groupIntoParagraphs as groupIntoParagraphs$1, createGlyphOutlineLookup, applyMotionPathPreset, resolveRevealedSmartArtNodes, resolveRevealedDrawingShapes, buildSmartArtA11y, computeSmartArtElementLayout, flattenNodes, computeInlineEditorRect, smartArtNodeAtPoint, SMARTART_DEFAULT_PALETTE, computeDrawingViewBox, projectDrawingShapes, resolveRevealedDrawingShapeNodeIds, styleShadowFilter, buildChromeStyle, centeredSvgTextLines, rebuildDrawingShapesIfCleared, shouldCommitSmartArtNodeText, bringForward, sendBackward, bringToFront, sendToBack } from 'ooxml-ui/pptx';
|
|
1
|
+
import { cloneTemplateElementsBySlideId, cloneSlide, cloneHistorySnapshot, MIN_ELEMENT_SIZE, ZOOM_TO_SELECTION_PADDING, DEFAULT_CANVAS_HEIGHT, DEFAULT_CANVAS_WIDTH, partitionTemplateElements, isTemplateElementId, DEFAULT_TABLE_ROWS, DEFAULT_TABLE_COLUMNS, useTranslation, comparePresentation, UNGROUPED_SECTION_ID, DEFAULT_SECTION_GROUP_ID, stopAllPersistentAudio, buildSaveSlides, MAX_ZOOM_SCALE, MIN_ZOOM_SCALE, getImageEffectsOpacity, getImageEffectsFilter, getImageRenderStyle, cn, isEditableTextElement, getShapeVisualStyle, getTextStyleForElement, DEFAULT_TEXT_COLOR, renderVectorShape, isConnectorOrLineElement, build3DExtrusionData, getImageSurfaceStyle, getTextLayoutStyle, renderTableElement, renderMediaElement, shouldRenderFallbackLabel, getElementLabel, normalizeHexColor, makeCloneId, DEFAULT_TEXT_FONT_SIZE, buildPdfFromTiledImageData, GRID_SIZE, copyFormatFromElement, hasCopyableFormat, isImageTiled, getDuotoneColors, DEFAULT_STROKE_COLOR, DEFAULT_FILL_COLOR, buildCssGradientFromShapeStyle, getCropShapeClipPath, getElementTransform, hasDagDuotoneEffect, renderDagDuotoneSvgFilter, getImageSurfaceMaskStyle, getTextWarpStyle, getTextCompensationTransform, renderTextSegments, buildReactChartViewModel, renderChartElement, buildInkGroupStrokes, getInkReplayStyles, INK_REPLAY_KEYFRAMES, buildContentPartStrokes, getContentPartReplayStyles, buildTextBody3DSceneStyle, rerouteConnectorsForMovedElements, applyReroutedConnectors, updateCellTextStyleInRawXml, updateCellTextInRawXml, splitCell, updateMergeAttrsInRawXml, mergeCells, buildNotesPdf, canvasToJpegData, applyFormatToElement, isPpactionUrl, parsePpactionUrl, getImageTilingStyle, buildCacheKey, DEFAULT_COLOR_CHANGE_TOLERANCE, getCachedResult, applyColorChange, setCachedResult, colorWithOpacity, normalizeStrokeDashType, getSvgStrokeDasharray, getCompoundLineOffsets, getCompoundLineWidths, getConnectorPathGeometry, buildLineShadowCss, buildLineGlowFilter, renderConnectorMarker, getAriaRoleDescription as getAriaRoleDescription$1, getAriaLabel as getAriaLabel$1, getAriaRole, DEFAULT_FONT_FAMILY, ACTION_BUTTON_PRESETS, isUrlSafe, safeOpenUrl as safeOpenUrl$1, substituteFieldText, HYPERLINK_COLOR } from './chunk-ID37Y3HG.mjs';
|
|
2
|
+
import { defineThreeViewElement, MIN_TOUCH_TARGET_PX, computeVirtualRange, DEFAULT_VIRTUAL_OVERSCAN, createCollaborationSessionController, registerCollaborationTeardown, createPresenceProjector, BROADCAST_THROTTLE_MS, sanitizeColor, createEditorHistoryController, historyTheme, crossedHistoryTheme, createWheelStepBuffer, createViewerZoomStore, clampZoomScale, mapEditingWheel, createActiveAnimationGroup, cancelBuildReveal, clearPlaybackTimers, PresentationAnimationController, resolveMediaTimeNodeElementIds, resolveMediaBookmarkTimesMs, advanceMainSequence, playGroup, PRESENTATION_HASH, PRESENTATION_NONCE_KEY, PRESENTATION_CHANNEL_NAME, swapPresentationWindows, PRESENTATION_MESSAGE_ORIGIN, clearAudienceContent, buildPresentationAudienceUrl, resolveAudienceScreenPlacement, placeAudienceWindow, storeAudienceContent, isPresentationSessionMessage, endAudienceDisplay, createPresentationKeyBuffer, acceptsPresentationInput, resolveAutoAdvanceDelayMs, resolveShowBackward, resolveShowForward, beginZoomExcursion, buildZoomTransitionOverride, createPresenterShowGuard, firstShowSlideIndex, attachPresentationVisibilityPause, presentationEntrySlideIndex, buildMorphTransitionPlan, morphOptionToMode, buildMorphAnimationRules, INITIAL_FIND_REPLACE_SESSION, findReplaceSessionActions, visibleTemplateElements, createCollaborationLivePatcher, reportInlineTextDraft, initialInspectorOpen, createPresentationLoadResources, collectMediaElements, resolveMediaElementSource, collectImagePaths, applyImagePathPatches, resolveTableCellImageUrls, resolveTableStyleImageUrls, resolveTextFillBlipUrls, seedRecentColors, resolveAuthoredCustomShowId, GlyphOutlineFontCache, buildInitialGuides, readOnlyRecommendation, compatibilityWarningToasts, resolveInitialSlideIndex, resolveAutosaveIntervalMs, createAutosaveController, saveAutosaveSnapshot, updateMasterViewElement, updateElement, masterViewElements, replaceMasterViewElements, addSection, renameSection, deleteSection, moveSectionUp, moveSectionDown, moveSlidesToSection, canMergeShapes, canInteractWithElement, prepareHtml2CanvasClone, html2canvasCaptureScope, slideProgressPercent, slideStatusLabel, EXPORT_ASSEMBLING_PERCENT, EXPORT_DONE_PERCENT, isExportAbortError, DEFAULT_VIEWER_OPTIONS, resolveImageResolutionScale, applyAcceptSlide, applyAcceptAllSlides, collectUsedFonts, describeFontEmbedding, isMobileViewport, resolveAuthoredSlideRange, mayLeaveSlideShow, buildDeckSaveOptions, resolveSlideSizeSelection, saveDeckWithPassword, createAutosaveRecoveryController, discardAutosaveRecovery, probeAutosaveRecovery, shouldLoopContinuously, applyRehearsalTimings, rasterResultToPngBlob, downloadBlob, elementPictureFilename, canEditElementPoints, resolveGoogleFontsCss2Base, selectTrustedEmbeddedFonts, resolveFontWeight, resolveFontItalic, collectReferencedFontFamilies, resolveGoogleWebfontHref, syncGoogleWebfontStylesheet, selectGoogleWebfontFamilies, fetchGoogleWebfontOutlineBytes, dispatchEditorKey, isFeatureEnabled, parentSelection, textFontSizePtToPx, stepFontSizePt, textFontSizePxToPt, cycleSelectableElement, createCustomizationController, prepareElementForInsertion, slideSpaceElement, autosaveStatusKind, createViewerOptionsStore, observeYDocSlides, LOCAL_SYNC_ORIGIN, readSlidesFromYDoc, shouldRoomSlidesReplaceLoad, reconcileSlidesInYDoc, shouldAutoFollowBroadcaster, detectTouchDevice, detectOrientation, deriveViewportBreakpoints, createTouchGestureRecognizer, isKeyboardOpen, scopeLayoutOptionsToSlide, INITIAL_READ_ONLY_SESSION, readOnlySessionActions, applyReadOnlySessionEvent, readOnlyBannerVisible, readOnlyLocked, viewerPreferencesFromViewProperties, DEFAULT_VIEWER_PREFERENCES, viewPropertiesPatchFromPreferences, resolveCollaborationConfig, openPptxFile, readBackstageRecentFile, resolveCollaborationShellEditability, resolveCollaborationShellState, getResizeHandleHitAreaStyle, resolveElementInteractivity, getBackgroundAnimationState, getShapeEffectLayerPlacement, buildTextStyleOverrideCss, isElementRendered, resolveElementAriaAttributes, isMediaFullscreenActive, shouldRenderHitTarget, elementHitTargetStyle, getShapeEffectAnimationLayerStyle, inlineElementPointerEvents, isHollowShapeElement, LINK_TOOLTIP_HOST_CLASS, resolvePalette as resolvePalette$1, mediaTransportVisible, oleActionsVisible, getGroupChildParentFill, deviceStrokeStageStyle, MORPH_CROSSFADE_GROUP_STYLE, MORPH_CROSSFADE_HALF_STYLE, getSlideTransitionAnimations, getFragmentedTransitionDescriptor, SLIDE_TRANSITION_KEYFRAMES, isActionHidden, buildInlineTextCommitPatch, resolveInlineEditAutoFitHeight, resolveInlineEditNormAutofitShrink, setPendingCaretPoint, resolveGroupDoubleClickTarget, filterInteractableIds, beginShapeAdjustment, buildElementClipboardPayload, contextMenuInspectorAnchor, savedPresentationFileName, deliverSavedPresentation, exportDeckJson, mapCustomizedEditorKey, isEditorTextInputTarget, groupElements, generateElementId, ungroupElements, alignElements, distributeElements, newTableElement, createDefaultChartElement, readViewportMetrics, computeKeyboardInset, planMergeShapes, applyMergeShapesPlan, mapPresentationKey, lastShowSlideIndex, mapPresentationWheel, createBlankSlide, insertSlidePaste, applySlidePasteTemplates, makeSlideId, insertedLayoutCompletion, buildSlideTemplateSlide, templateSchemeFromTheme, queueThemeWrite, needsOwnedSession, openOwnedCollaboration, resolveViewportFitOptions, editorViewportFitFor, calculateViewportFit, observeViewportClientSize, scheduleAutoAdvanceChain, computeEntranceAnimationDelay, createPresentationSessionId, resolveTransitionDurationMs, resolveTransitionSoundAction, runPresentationAction, safeOpenUrl, buildRunProgramNotice, toggleStageElementMedia, resolveOleVerbTarget, downloadDataUrl, openUrlInNewTab, createPresenterTimer, createInitialPresentationSnapshot, mergePresentationSnapshot, resetPresenterTimer, presenterElapsed, stepPresenterZoom, togglePresenterTimer, addCommentToList, removeCommentFromList, editCommentInList, toggleCommentResolvedInList, slideSpaceMembers, remapTextToSegments, getInlineEditorSelectionResult, buildInlineListStylePatch, applyActiveInlineListFormatting, applyListStyleUpdate, setPendingSelectionRestore, applyTextStyleUpdate, toggleSelectionBullets, transformInlineListCase, applyCaseTransformToSegments, transformTextCase, createGestureController, resolveExportCaptureDecision, recordProgressPercent, computeGridSpacingPx as computeGridSpacingPx$1, resolveShowSlideIndexes, groupSlidesBySection, masterViewPseudoSlide, overlayMasterViewInlineSnapshot, overlayInlineTextSnapshot, rasterizeElement, cloneElementForPaste, applyPasteSpecialFormat, buildRasterPictureElement, cloneElementUpdates, assertElementUpdateTarget, prepareElementUpdateBatch, createWriteBackScheduler, writeBackReport, createSyncGate, observeExternalCollaborationReadiness, resolveHistoryDepth, createBackstagePresentation, buildFieldSubstitutionContext, getImageColorWashStyle, attachRotateHandlePlacement, getSelectionControlArtworkStyle, getSelectionOutlineColor, paintedStrokeWidth, ensureActionAffordanceStyles, resolveElementActionAffordance, actionAffordanceLabels, paintedElementSize, MEDIA_FULLSCREEN_OVERLAY_STYLE, elementContainerHeightStyle, getAnimationOpacity, resolveElementHighlightClick, applyHighlightClickStyle, getComputedEffectStyle, getSoftEdgeSvgFilter, getEffectStyleSource, getBevelLightingSvgFilter, buildStrokeOutline, buildHollowHitOutline, buildSubpathFillOverlay, strokeOutlineViewBox, buildSummaryZoomView, readEditableText, placeCaretAt, takePendingCaretPoint, getPendingSelectionRestore, restoreSegmentSelection, mapInlineTextFormatKey, mapInlineEditorChord, subscribeBarFacePicturePixelSamples, getBarFacePicturePixelSampleVersion, ensureChartInteractionStyles, applyChartPartHighlight, resolveRevealedChartData, formatAxisValue, chartFormatTargetFromEvent, resolveOleType, getOleAriaLabel, getOleTypeColor, getOleTypeLabel, filterRenderedElements, resolveGroupChildFill, isLinkedTextBox, getOverflowSegments, shouldUseSvgWarp, getTextBodyRotationTransform, placeholderPromptDescriptor, getAriaRoleDescription, getAriaLabel, elementIdSelector, TOOLBAR_TABS, resolveGroupPressTarget, scrollInspectorSectionIntoView, computeScrollDelta, buildOutlinePrintJobDocument, printJobRasterFallback, applyThemeByPath, withHistoryTheme, withHistoryMasterThemes, writeThemeParts, loadedThemeName, replyToCommentInList, removeTableElementColumn, insertTableElementColumn, removeTableElementRow, insertTableElementRow, withCellStyle, setCellText, pickSupportedMimeType, WEBM_MIME_CANDIDATES, fpsToFrameIntervalMs, segmentFrameCount, stopCaptureStream, GIF_POST_CAPTURE_MAX_SIDE, encodeGif, rasterizeElementTiles, placeTileOnPage, PDF_SLIDES_PAGE_WIDTH_PT, PDF_SLIDES_PAGE_HEIGHT_PT, createSnapshotTextPositions, resolvePresentationAction, getImageSvgFilters, getCachedNativeImageSize, probeNativeImageSize, buildDuotoneCacheKey, getDuotoneCachedResult, applyDuotone, setDuotoneCachedResult, svgLineCap, screenStrokeWidth, connectorWrapperTransform, ACTION_INDICATOR_CLASS, ACTION_INDICATOR_ICON_PATH, LINK_TOOLTIP_CLASS, LINK_TOOLTIP_PANEL_CLASS, LINK_TOOLTIP_LABEL_CLASS, LINK_TOOLTIP_HINT_CLASS, modelDataToBlobUrl, resolveZoomNavigationTarget, inlineListBodyText, createInlineListSeed, readListActivationSelection, createInlineListModelObserver, attachCollaborationInlineEditor, bindInlineListParagraph, bindInlineListRun, attachInlineListController, restoreInlineListBodySelection, isBulletMarkerSegment, resolveChartThreeViewSpec, applyChart3DDrag, applyChart3DSelect, canDrillDown, findChartPartTarget, withChartTitle, resolveSmartArtThreeViewSpec, measureSvgViewportRect, isBrowserOpenableMime, formatBytes, getOleDisplayName, getOleBadgeLabel, hasGlyphEnvelope, buildGlyphEnvelopeBlock, getWarpPath, isWedgeCalloutPresetShape, getAriaRole as getAriaRole$1, isElementActionable, buildSmartArtPresetData, classifyMediaType, getDraggedShapeAdjustments, computeMarqueeHitIds, mergeAdditiveSelection, planPrintJob, openPrintWindow, buildVectorPrintJobDocument, openPendingPrintWindow, borrowExternalCollaborationAwareness, observeExternalCollaborationSession, publishLiveGeometry, rasterizeElementTiledToCanvas, clampGifDimensions, rasterResultToPngDataUrl, shouldConfirmExternalHyperlink, advanceChartMarkDrag, advanceChartValueDrag, resolveChartKind, buildChartMarkDragGeometry, beginChartMarkDrag, beginChartValueDrag, findSmartArtNodeText, commitSmartArtNodeFill, commitSmartArtNodeText, groupIntoParagraphs as groupIntoParagraphs$1, createGlyphOutlineLookup, finishPrintWindow, buildRasterPrintJobDocument, applyMotionPathPreset, resolveRevealedSmartArtNodes, resolveRevealedDrawingShapes, buildSmartArtA11y, computeSmartArtElementLayout, flattenNodes, computeInlineEditorRect, smartArtNodeAtPoint, SMARTART_DEFAULT_PALETTE, computeDrawingViewBox, projectDrawingShapes, resolveRevealedDrawingShapeNodeIds, styleShadowFilter, buildChromeStyle, centeredSvgTextLines, rebuildDrawingShapesIfCleared, shouldCommitSmartArtNodeText, bringForward, sendBackward, bringToFront, sendToBack } from 'ooxml-ui/pptx';
|
|
3
3
|
export { DUOTONE_PRESETS, MOBILE_BREAKPOINT, SLIDE_TRANSITION_KEYFRAMES, TABLET_BREAKPOINT, clearAudienceContent, computeVirtualRange, downloadBlob, getSlideTransitionAnimations, loadAudienceContent, storeAudienceContent } from 'ooxml-ui/pptx';
|
|
4
4
|
import React17, { useRef, useState, useCallback, useEffect, useSyncExternalStore, useMemo, useContext, useLayoutEffect, createContext, useImperativeHandle, Suspense } from 'react';
|
|
5
5
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
6
|
-
import { PptxHandler, EncryptedFileError, hasShapeProperties, applyThemeToData, THEME_PRESETS, themeColorSchemesEqual, guidePxToEmu, hasTextProperties, isInkElement, duplicateSlide, buildThemeColorMap, reResolveSlideColors, reResolveElementColors, reResolveSlideFonts, reResolveElementFonts, isImageLikeElement,
|
|
6
|
+
import { PptxHandler, EncryptedFileError, hasShapeProperties, applyThemeToData, THEME_PRESETS, themeColorSchemesEqual, guidePxToEmu, hasTextProperties, isInkElement, duplicateSlide, buildThemeColorMap, reResolveSlideColors, reResolveElementColors, reResolveSlideFonts, reResolveElementFonts, isImageLikeElement, getSubstituteFontFamily, elementActionToPptxAction, SvgExporter, setSmartArtNodeStyle, updateSmartArtNodeText } from 'ooxml-core/pptx';
|
|
7
7
|
import { translationsEn } from 'ooxml-ui/pptx/i18n';
|
|
8
8
|
import { flushSync } from 'react-dom';
|
|
9
9
|
import { LuRotateCw } from 'react-icons/lu';
|
|
@@ -572,9 +572,30 @@ function serializeHistoryDocument(snapshot) {
|
|
|
572
572
|
slideId,
|
|
573
573
|
elements.map(historyElementContent)
|
|
574
574
|
])
|
|
575
|
-
)
|
|
575
|
+
),
|
|
576
|
+
// A theme pick that changes nothing on the slides is still an edit, and an undo step.
|
|
577
|
+
theme: snapshot.theme
|
|
576
578
|
});
|
|
577
579
|
}
|
|
580
|
+
function withMasterPathsIn(snapshot, paths) {
|
|
581
|
+
const { theme, ...rest } = snapshot;
|
|
582
|
+
if (!theme?.masterThemePaths) {
|
|
583
|
+
return snapshot;
|
|
584
|
+
}
|
|
585
|
+
const { masterThemePaths, ...parts } = theme;
|
|
586
|
+
const kept = Object.entries(masterThemePaths).filter(([path]) => paths.has(path));
|
|
587
|
+
const next = kept.length > 0 ? { ...parts, masterThemePaths: Object.fromEntries(kept) } : parts;
|
|
588
|
+
return Object.keys(next).length > 0 ? { ...rest, theme: next } : rest;
|
|
589
|
+
}
|
|
590
|
+
function differsOnlyInMasterSet(previous, next) {
|
|
591
|
+
const before = Object.keys(previous.theme?.masterThemePaths ?? {});
|
|
592
|
+
const after = new Set(Object.keys(next.theme?.masterThemePaths ?? {}));
|
|
593
|
+
if (before.length === after.size && before.every((path) => after.has(path))) {
|
|
594
|
+
return false;
|
|
595
|
+
}
|
|
596
|
+
const shared = new Set(before.filter((path) => after.has(path)));
|
|
597
|
+
return serializeHistoryDocument(withMasterPathsIn(previous, shared)) === serializeHistoryDocument(withMasterPathsIn(next, shared));
|
|
598
|
+
}
|
|
578
599
|
function recordExplicitSlideUpdate(history, previous, before, label) {
|
|
579
600
|
if (previous && serializeHistoryDocument(previous) !== serializeHistoryDocument(before)) {
|
|
580
601
|
history.record(cloneHistorySnapshot(previous), previous.actionLabel);
|
|
@@ -627,6 +648,9 @@ function useEditorHistory(input) {
|
|
|
627
648
|
hasActivePointerInteraction,
|
|
628
649
|
pointerCommitNonce,
|
|
629
650
|
onDirty,
|
|
651
|
+
theme,
|
|
652
|
+
slideMasters,
|
|
653
|
+
onRestoreTheme,
|
|
630
654
|
setSlides,
|
|
631
655
|
setCanvasSize,
|
|
632
656
|
setActiveSlideIndex,
|
|
@@ -653,16 +677,18 @@ function useEditorHistory(input) {
|
|
|
653
677
|
}, [history, maxHistoryEntries]);
|
|
654
678
|
const buildHistorySnapshot = useCallback(
|
|
655
679
|
(actionLabel) => {
|
|
680
|
+
const recordedTheme = historyTheme(theme, slideMasters);
|
|
656
681
|
return {
|
|
657
682
|
width: canvasSize.width,
|
|
658
683
|
height: canvasSize.height,
|
|
659
684
|
activeSlideIndex,
|
|
660
685
|
slides: slides.map(cloneSlide),
|
|
661
686
|
templateElementsBySlideId: cloneTemplateElementsBySlideId(templateElementsBySlideId),
|
|
687
|
+
...recordedTheme ? { theme: recordedTheme } : {},
|
|
662
688
|
...actionLabel ? { actionLabel } : {}
|
|
663
689
|
};
|
|
664
690
|
},
|
|
665
|
-
[activeSlideIndex, canvasSize, slides, templateElementsBySlideId]
|
|
691
|
+
[activeSlideIndex, canvasSize, slideMasters, slides, templateElementsBySlideId, theme]
|
|
666
692
|
);
|
|
667
693
|
const applyHistorySnapshot = useCallback(
|
|
668
694
|
(snapshot) => {
|
|
@@ -700,15 +726,41 @@ function useEditorHistory(input) {
|
|
|
700
726
|
useEffect(() => {
|
|
701
727
|
onDirtyRef.current = onDirty;
|
|
702
728
|
}, [onDirty]);
|
|
729
|
+
const untrackedDepthRef = useRef(0);
|
|
703
730
|
const markDirty = useCallback(() => {
|
|
731
|
+
if (untrackedDepthRef.current > 0) {
|
|
732
|
+
return;
|
|
733
|
+
}
|
|
704
734
|
setEditCommitNonce((previous) => previous + 1);
|
|
705
735
|
onDirtyRef.current?.();
|
|
706
736
|
}, []);
|
|
737
|
+
const onRestoreThemeRef = useRef(onRestoreTheme);
|
|
738
|
+
useEffect(() => {
|
|
739
|
+
onRestoreThemeRef.current = onRestoreTheme;
|
|
740
|
+
}, [onRestoreTheme]);
|
|
741
|
+
const restoreTheme = useCallback(
|
|
742
|
+
(current, target) => {
|
|
743
|
+
const crossed = crossedHistoryTheme(current.theme, target.theme);
|
|
744
|
+
if (crossed) {
|
|
745
|
+
onRestoreThemeRef.current?.(crossed);
|
|
746
|
+
}
|
|
747
|
+
},
|
|
748
|
+
[]
|
|
749
|
+
);
|
|
750
|
+
const withoutUndoStep = useCallback((apply) => {
|
|
751
|
+
untrackedDepthRef.current += 1;
|
|
752
|
+
try {
|
|
753
|
+
apply();
|
|
754
|
+
} finally {
|
|
755
|
+
untrackedDepthRef.current -= 1;
|
|
756
|
+
}
|
|
757
|
+
}, []);
|
|
707
758
|
const handleUndo = useCallback(() => {
|
|
708
759
|
if (!history.getSnapshot().canUndo) {
|
|
709
760
|
return;
|
|
710
761
|
}
|
|
711
|
-
const
|
|
762
|
+
const currentSnapshot = buildHistorySnapshot();
|
|
763
|
+
const result = history.undo(currentSnapshot);
|
|
712
764
|
if (!result) {
|
|
713
765
|
return;
|
|
714
766
|
}
|
|
@@ -717,14 +769,23 @@ function useEditorHistory(input) {
|
|
|
717
769
|
lastHistorySnapshotRef.current = cloneHistorySnapshot(nextSnapshot);
|
|
718
770
|
lastHistorySerializedRef.current = serializeHistoryDocument(nextSnapshot);
|
|
719
771
|
applyHistorySnapshot(nextSnapshot);
|
|
772
|
+
restoreTheme(currentSnapshot, nextSnapshot);
|
|
720
773
|
unlockHistoryTracking();
|
|
721
774
|
markDirty();
|
|
722
|
-
}, [
|
|
775
|
+
}, [
|
|
776
|
+
applyHistorySnapshot,
|
|
777
|
+
buildHistorySnapshot,
|
|
778
|
+
history,
|
|
779
|
+
markDirty,
|
|
780
|
+
restoreTheme,
|
|
781
|
+
unlockHistoryTracking
|
|
782
|
+
]);
|
|
723
783
|
const handleRedo = useCallback(() => {
|
|
724
784
|
if (!history.getSnapshot().canRedo) {
|
|
725
785
|
return;
|
|
726
786
|
}
|
|
727
|
-
const
|
|
787
|
+
const currentSnapshot = buildHistorySnapshot();
|
|
788
|
+
const result = history.redo(currentSnapshot);
|
|
728
789
|
if (!result) {
|
|
729
790
|
return;
|
|
730
791
|
}
|
|
@@ -733,9 +794,17 @@ function useEditorHistory(input) {
|
|
|
733
794
|
lastHistorySnapshotRef.current = cloneHistorySnapshot(targetSnapshot);
|
|
734
795
|
lastHistorySerializedRef.current = serializeHistoryDocument(targetSnapshot);
|
|
735
796
|
applyHistorySnapshot(targetSnapshot);
|
|
797
|
+
restoreTheme(currentSnapshot, targetSnapshot);
|
|
736
798
|
unlockHistoryTracking();
|
|
737
799
|
markDirty();
|
|
738
|
-
}, [
|
|
800
|
+
}, [
|
|
801
|
+
applyHistorySnapshot,
|
|
802
|
+
buildHistorySnapshot,
|
|
803
|
+
history,
|
|
804
|
+
markDirty,
|
|
805
|
+
restoreTheme,
|
|
806
|
+
unlockHistoryTracking
|
|
807
|
+
]);
|
|
739
808
|
const resetHistory = useCallback(
|
|
740
809
|
(initialSnapshot) => {
|
|
741
810
|
history.clear();
|
|
@@ -787,7 +856,7 @@ function useEditorHistory(input) {
|
|
|
787
856
|
return;
|
|
788
857
|
}
|
|
789
858
|
const previousSnapshot = lastHistorySnapshotRef.current;
|
|
790
|
-
if (!previousSnapshot) {
|
|
859
|
+
if (!previousSnapshot || differsOnlyInMasterSet(previousSnapshot, snapshot)) {
|
|
791
860
|
lastHistorySnapshotRef.current = snapshot;
|
|
792
861
|
lastHistorySerializedRef.current = serialized;
|
|
793
862
|
lastCheapHashRef.current = cheapHash;
|
|
@@ -813,9 +882,15 @@ function useEditorHistory(input) {
|
|
|
813
882
|
pointerReleaseNonce,
|
|
814
883
|
slides
|
|
815
884
|
]);
|
|
816
|
-
const commitSlides = (nextSlides, label, beforeSlides = slides) => {
|
|
885
|
+
const commitSlides = (nextSlides, label, beforeSlides = slides, nextSlideMasters) => {
|
|
817
886
|
const before = { ...buildHistorySnapshot(), slides: beforeSlides.map(cloneSlide) };
|
|
818
|
-
const
|
|
887
|
+
const { theme: beforeTheme, ...unthemed } = before;
|
|
888
|
+
const afterTheme = nextSlideMasters ? historyTheme(theme, nextSlideMasters) : beforeTheme;
|
|
889
|
+
const after = {
|
|
890
|
+
...unthemed,
|
|
891
|
+
slides: nextSlides.map(cloneSlide),
|
|
892
|
+
...afterTheme ? { theme: afterTheme } : {}
|
|
893
|
+
};
|
|
819
894
|
recordExplicitSlideUpdate(history, lastHistorySnapshotRef.current, before, label);
|
|
820
895
|
lastHistorySnapshotRef.current = cloneHistorySnapshot(after);
|
|
821
896
|
lastHistorySerializedRef.current = serializeHistoryDocument(after);
|
|
@@ -836,7 +911,9 @@ function useEditorHistory(input) {
|
|
|
836
911
|
handleUndo,
|
|
837
912
|
handleRedo,
|
|
838
913
|
resetHistory,
|
|
914
|
+
forgetHistory: history.forget,
|
|
839
915
|
markDirty,
|
|
916
|
+
withoutUndoStep,
|
|
840
917
|
buildHistorySnapshot
|
|
841
918
|
};
|
|
842
919
|
}
|
|
@@ -3135,109 +3212,62 @@ function usePresentationAnnotations(input) {
|
|
|
3135
3212
|
function useFindReplace({
|
|
3136
3213
|
slides,
|
|
3137
3214
|
mode,
|
|
3138
|
-
|
|
3139
|
-
onSetSelectedElementId,
|
|
3215
|
+
onShowMatch,
|
|
3140
3216
|
onUpdateSlides,
|
|
3141
3217
|
onMarkDirty,
|
|
3142
3218
|
keyboard
|
|
3143
3219
|
}) {
|
|
3144
3220
|
const [findReplaceOpen, setFindReplaceOpen] = useState(false);
|
|
3145
|
-
const [
|
|
3146
|
-
const
|
|
3147
|
-
|
|
3148
|
-
const
|
|
3149
|
-
const [
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
includeNotes: findIncludeNotes,
|
|
3166
|
-
includeChartTitles: findIncludeChartTitles,
|
|
3167
|
-
includeChartData: findIncludeChartData
|
|
3168
|
-
});
|
|
3169
|
-
if (!findQuery) {
|
|
3170
|
-
setFindResults([]);
|
|
3171
|
-
setFindResultIndex(-1);
|
|
3172
|
-
return;
|
|
3173
|
-
}
|
|
3174
|
-
setFindResults(results);
|
|
3175
|
-
setFindResultIndex(results.length > 0 ? 0 : -1);
|
|
3176
|
-
if (results.length > 0) {
|
|
3177
|
-
onSetActiveSlideIndex(results[0].slideIndex);
|
|
3178
|
-
onSetSelectedElementId(results[0].elementId);
|
|
3179
|
-
}
|
|
3180
|
-
}, [
|
|
3181
|
-
slides,
|
|
3182
|
-
findQuery,
|
|
3183
|
-
findMatchCase,
|
|
3184
|
-
findIncludeNotes,
|
|
3185
|
-
findIncludeChartTitles,
|
|
3186
|
-
findIncludeChartData,
|
|
3187
|
-
onSetActiveSlideIndex,
|
|
3188
|
-
onSetSelectedElementId
|
|
3189
|
-
]);
|
|
3190
|
-
const navigateFindResult = useCallback(
|
|
3191
|
-
(direction) => {
|
|
3192
|
-
if (findResults.length === 0) {
|
|
3193
|
-
return;
|
|
3194
|
-
}
|
|
3195
|
-
const nextIdx = (findResultIndex + direction + findResults.length) % findResults.length;
|
|
3196
|
-
setFindResultIndex(nextIdx);
|
|
3197
|
-
const match = findResults[nextIdx];
|
|
3198
|
-
if (match) {
|
|
3199
|
-
onSetActiveSlideIndex(match.slideIndex);
|
|
3200
|
-
onSetSelectedElementId(match.elementId);
|
|
3201
|
-
}
|
|
3202
|
-
},
|
|
3203
|
-
[findResults, findResultIndex, onSetActiveSlideIndex, onSetSelectedElementId]
|
|
3204
|
-
);
|
|
3205
|
-
const applyReplacements = useCallback(
|
|
3206
|
-
(toReplace) => {
|
|
3207
|
-
if (toReplace.length === 0) {
|
|
3208
|
-
return;
|
|
3209
|
-
}
|
|
3210
|
-
if (toReplace.some((match) => match.readOnly)) {
|
|
3211
|
-
return;
|
|
3221
|
+
const [session, setSession] = useState(INITIAL_FIND_REPLACE_SESSION);
|
|
3222
|
+
const latest = useRef({ slides, onShowMatch, onUpdateSlides, onMarkDirty });
|
|
3223
|
+
latest.current = { slides, onShowMatch, onUpdateSlides, onMarkDirty };
|
|
3224
|
+
const latestSession = useRef(session);
|
|
3225
|
+
const [actions] = useState(
|
|
3226
|
+
() => findReplaceSessionActions(
|
|
3227
|
+
{
|
|
3228
|
+
get: () => latestSession.current,
|
|
3229
|
+
set: (next) => {
|
|
3230
|
+
latestSession.current = next;
|
|
3231
|
+
setSession(next);
|
|
3232
|
+
}
|
|
3233
|
+
},
|
|
3234
|
+
{
|
|
3235
|
+
slides: () => latest.current.slides,
|
|
3236
|
+
commit: (next) => {
|
|
3237
|
+
latest.current.onUpdateSlides(() => next);
|
|
3238
|
+
latest.current.onMarkDirty();
|
|
3239
|
+
},
|
|
3240
|
+
navigate: ({ slideIndex, elementId }) => latest.current.onShowMatch(slideIndex, elementId)
|
|
3212
3241
|
}
|
|
3213
|
-
|
|
3214
|
-
(prevSlides) => applyFindReplacements(prevSlides, toReplace, replaceQuery).slides
|
|
3215
|
-
);
|
|
3216
|
-
onMarkDirty();
|
|
3217
|
-
},
|
|
3218
|
-
[replaceQuery, onUpdateSlides, onMarkDirty]
|
|
3242
|
+
)
|
|
3219
3243
|
);
|
|
3220
|
-
const handleReplace = useCallback(() => {
|
|
3221
|
-
if (findResults.length === 0 || findResultIndex < 0) {
|
|
3222
|
-
return;
|
|
3223
|
-
}
|
|
3224
|
-
applyReplacements([findResults[findResultIndex]]);
|
|
3225
|
-
pendingRefindRef.current = true;
|
|
3226
|
-
}, [findResults, findResultIndex, applyReplacements]);
|
|
3227
|
-
const handleReplaceAll = useCallback(() => {
|
|
3228
|
-
if (findResults.length === 0) {
|
|
3229
|
-
return;
|
|
3230
|
-
}
|
|
3231
|
-
applyReplacements(findResults);
|
|
3232
|
-
pendingRefindRef.current = true;
|
|
3233
|
-
}, [findResults, applyReplacements]);
|
|
3234
3244
|
useEffect(() => {
|
|
3235
|
-
if (!
|
|
3236
|
-
|
|
3245
|
+
if (!findReplaceOpen) {
|
|
3246
|
+
actions.close();
|
|
3237
3247
|
}
|
|
3238
|
-
|
|
3239
|
-
|
|
3240
|
-
|
|
3248
|
+
}, [findReplaceOpen, actions]);
|
|
3249
|
+
useEffect(() => {
|
|
3250
|
+
actions.slidesChanged();
|
|
3251
|
+
}, [slides, actions]);
|
|
3252
|
+
const handlers = useMemo(
|
|
3253
|
+
() => ({
|
|
3254
|
+
setFindQuery: (query) => actions.search({ query }),
|
|
3255
|
+
setReplaceQuery: actions.setReplacement,
|
|
3256
|
+
setFindMatchCase: (matchCase) => actions.search({ options: { matchCase } }),
|
|
3257
|
+
setFindIncludeNotes: (includeNotes) => actions.search({ options: { includeNotes } }),
|
|
3258
|
+
setFindIncludeChartTitles: (includeChartTitles) => actions.search({ options: { includeChartTitles } }),
|
|
3259
|
+
setFindIncludeChartData: (includeChartData) => actions.search({ options: { includeChartData } }),
|
|
3260
|
+
performFind: () => actions.search(),
|
|
3261
|
+
navigateFindResult: (direction) => direction > 0 ? actions.next() : actions.previous(),
|
|
3262
|
+
handleReplace: () => {
|
|
3263
|
+
actions.replaceCurrent();
|
|
3264
|
+
},
|
|
3265
|
+
handleReplaceAll: () => {
|
|
3266
|
+
actions.replaceAll();
|
|
3267
|
+
}
|
|
3268
|
+
}),
|
|
3269
|
+
[actions]
|
|
3270
|
+
);
|
|
3241
3271
|
useEffect(() => {
|
|
3242
3272
|
const handler = (event) => {
|
|
3243
3273
|
const { action } = mapCustomizedEditorKey(
|
|
@@ -3260,24 +3290,15 @@ function useFindReplace({
|
|
|
3260
3290
|
return {
|
|
3261
3291
|
findReplaceOpen,
|
|
3262
3292
|
setFindReplaceOpen,
|
|
3263
|
-
findQuery,
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
findIncludeChartData,
|
|
3273
|
-
setFindIncludeChartTitles,
|
|
3274
|
-
setFindIncludeChartData,
|
|
3275
|
-
findResults,
|
|
3276
|
-
findResultIndex,
|
|
3277
|
-
performFind,
|
|
3278
|
-
navigateFindResult,
|
|
3279
|
-
handleReplace,
|
|
3280
|
-
handleReplaceAll
|
|
3293
|
+
findQuery: session.query,
|
|
3294
|
+
replaceQuery: session.replacement,
|
|
3295
|
+
findMatchCase: session.options.matchCase,
|
|
3296
|
+
findIncludeNotes: session.options.includeNotes,
|
|
3297
|
+
findIncludeChartTitles: session.options.includeChartTitles,
|
|
3298
|
+
findIncludeChartData: session.options.includeChartData,
|
|
3299
|
+
findResults: session.matches,
|
|
3300
|
+
findResultIndex: session.current,
|
|
3301
|
+
...handlers
|
|
3281
3302
|
};
|
|
3282
3303
|
}
|
|
3283
3304
|
function useModalDismissDrag(onClose, threshold = 120) {
|
|
@@ -3937,6 +3958,35 @@ function useInlineEditingState(onTextChange) {
|
|
|
3937
3958
|
registerInlineEditReader
|
|
3938
3959
|
};
|
|
3939
3960
|
}
|
|
3961
|
+
function useSlideChangeSelection({
|
|
3962
|
+
setActiveSlideIndex,
|
|
3963
|
+
setSelectedElementId,
|
|
3964
|
+
setSelectedElementIds
|
|
3965
|
+
}) {
|
|
3966
|
+
const slideSelectionRef = useRef(null);
|
|
3967
|
+
const showSlideSelection = useCallback(
|
|
3968
|
+
(slideIndex, elementId) => {
|
|
3969
|
+
slideSelectionRef.current = slideIndex;
|
|
3970
|
+
setActiveSlideIndex(slideIndex);
|
|
3971
|
+
setSelectedElementId(elementId);
|
|
3972
|
+
setSelectedElementIds([]);
|
|
3973
|
+
},
|
|
3974
|
+
[setActiveSlideIndex, setSelectedElementId, setSelectedElementIds]
|
|
3975
|
+
);
|
|
3976
|
+
return { slideSelectionRef, showSlideSelection };
|
|
3977
|
+
}
|
|
3978
|
+
function useClearSelectionOnSlideChange(state, activeSlideIndex) {
|
|
3979
|
+
useEffect(() => {
|
|
3980
|
+
const kept = state.slideSelectionRef.current === activeSlideIndex;
|
|
3981
|
+
state.slideSelectionRef.current = null;
|
|
3982
|
+
state.setInlineEditingElementId(null);
|
|
3983
|
+
if (kept) {
|
|
3984
|
+
return;
|
|
3985
|
+
}
|
|
3986
|
+
state.setSelectedElementId(null);
|
|
3987
|
+
state.setSelectedElementIds([]);
|
|
3988
|
+
}, [activeSlideIndex]);
|
|
3989
|
+
}
|
|
3940
3990
|
function useSlideState() {
|
|
3941
3991
|
const [renderedSlides, setRenderedSlides] = useState([]);
|
|
3942
3992
|
const slidesRef = useRef(renderedSlides);
|
|
@@ -3976,6 +4026,11 @@ function useViewerCoreState(_input) {
|
|
|
3976
4026
|
const [activeSlideIndex, setActiveSlideIndex] = useState(0);
|
|
3977
4027
|
const [selectedElementId, setSelectedElementId] = useState(null);
|
|
3978
4028
|
const [selectedElementIds, setSelectedElementIds] = useState([]);
|
|
4029
|
+
const slideChangeSelection = useSlideChangeSelection({
|
|
4030
|
+
setActiveSlideIndex,
|
|
4031
|
+
setSelectedElementId,
|
|
4032
|
+
setSelectedElementIds
|
|
4033
|
+
});
|
|
3979
4034
|
const [isDirty, setIsDirty] = useState(false);
|
|
3980
4035
|
const autosaveDraftSinkRef = useRef(null);
|
|
3981
4036
|
const publishInlineText = useCallback(
|
|
@@ -4079,6 +4134,7 @@ function useViewerCoreState(_input) {
|
|
|
4079
4134
|
setSelectedElementId,
|
|
4080
4135
|
selectedElementIds,
|
|
4081
4136
|
setSelectedElementIds,
|
|
4137
|
+
...slideChangeSelection,
|
|
4082
4138
|
isDirty,
|
|
4083
4139
|
setIsDirty,
|
|
4084
4140
|
editTemplateMode,
|
|
@@ -6886,7 +6942,7 @@ function useSlideManagement(input) {
|
|
|
6886
6942
|
async (updated) => {
|
|
6887
6943
|
const templateElements = await handler.getTemplateElementsForSlide(updated.id).catch(() => []);
|
|
6888
6944
|
ops.updateSlides((prev) => {
|
|
6889
|
-
if (prev[insertAt]
|
|
6945
|
+
if (insertedLayoutCompletion(prev[insertAt], draft) !== "replace") {
|
|
6890
6946
|
return prev;
|
|
6891
6947
|
}
|
|
6892
6948
|
const next = [...prev];
|
|
@@ -7406,24 +7462,25 @@ async function copySlideToClipboard(slideElement, options = {}) {
|
|
|
7406
7462
|
const blob = await exportSlideToPngBlob(slideElement, options);
|
|
7407
7463
|
await navigator.clipboard.write([new ClipboardItem({ "image/png": blob })]);
|
|
7408
7464
|
}
|
|
7409
|
-
async function
|
|
7465
|
+
async function captureSlidesAsPngDataUrls(slideStageRef, slideIndices, setActiveSlide, currentSlideIndex, options = {}) {
|
|
7410
7466
|
const { scale = 2, onProgress } = options;
|
|
7411
|
-
const
|
|
7412
|
-
|
|
7413
|
-
|
|
7414
|
-
|
|
7467
|
+
const total = slideIndices.length;
|
|
7468
|
+
const captures = [];
|
|
7469
|
+
for (const [position, slideIndex] of slideIndices.entries()) {
|
|
7470
|
+
onProgress?.(position, total);
|
|
7471
|
+
setActiveSlide(slideIndex);
|
|
7415
7472
|
await waitForRender(150);
|
|
7416
7473
|
const stageEl = slideStageRef.current;
|
|
7417
7474
|
if (!stageEl) {
|
|
7418
|
-
console.warn(`[export] Could not find slide stage element for slide ${
|
|
7475
|
+
console.warn(`[export] Could not find slide stage element for slide ${slideIndex}`);
|
|
7419
7476
|
continue;
|
|
7420
7477
|
}
|
|
7421
7478
|
const { canvas } = await renderElementToTiledCanvas(stageEl, scale);
|
|
7422
|
-
|
|
7479
|
+
captures.push({ slideIndex, dataUrl: canvas.toDataURL("image/png") });
|
|
7423
7480
|
}
|
|
7424
|
-
onProgress?.(
|
|
7481
|
+
onProgress?.(total, total);
|
|
7425
7482
|
setActiveSlide(currentSlideIndex);
|
|
7426
|
-
return
|
|
7483
|
+
return captures;
|
|
7427
7484
|
}
|
|
7428
7485
|
function tilesToPdfPage(tilesResult) {
|
|
7429
7486
|
return tilesResult.tiles.map((tile) => ({
|
|
@@ -7663,35 +7720,12 @@ function injectFontFaces(svg, fontFaces) {
|
|
|
7663
7720
|
}
|
|
7664
7721
|
return `${svg.slice(0, closingBracket + 1)}<defs>${styleBlock}</defs>${svg.slice(closingBracket + 1)}`;
|
|
7665
7722
|
}
|
|
7666
|
-
function
|
|
7667
|
-
|
|
7668
|
-
|
|
7669
|
-
|
|
7670
|
-
slideIndices: options.slideIndices,
|
|
7671
|
-
defaultFontFamily: options.defaultFontFamily,
|
|
7672
|
-
defaultFontSize: options.defaultFontSize
|
|
7673
|
-
};
|
|
7674
|
-
const results = [];
|
|
7675
|
-
const includeHidden = svgOptions.includeHidden ?? false;
|
|
7676
|
-
let processedCount = 0;
|
|
7677
|
-
for (let i = 0; i < data.slides.length; i++) {
|
|
7678
|
-
if (svgOptions.slideIndices && !svgOptions.slideIndices.includes(i)) {
|
|
7679
|
-
continue;
|
|
7680
|
-
}
|
|
7681
|
-
const slide = data.slides[i];
|
|
7682
|
-
if (slide.hidden && !includeHidden) {
|
|
7683
|
-
continue;
|
|
7684
|
-
}
|
|
7685
|
-
onProgress?.(processedCount, data.slides.length);
|
|
7686
|
-
let svg = SvgExporter.exportSlide(slide, data.width, data.height, svgOptions);
|
|
7687
|
-
if (embedFonts && fontFaces?.length) {
|
|
7688
|
-
svg = injectFontFaces(svg, fontFaces);
|
|
7689
|
-
}
|
|
7690
|
-
results.push(svg);
|
|
7691
|
-
processedCount++;
|
|
7723
|
+
function exportSlideToSvg(slide, width, height, options = {}) {
|
|
7724
|
+
let svg = SvgExporter.exportSlide(slide, width, height, options);
|
|
7725
|
+
if (options.embedFonts && options.fontFaces?.length) {
|
|
7726
|
+
svg = injectFontFaces(svg, options.fontFaces);
|
|
7692
7727
|
}
|
|
7693
|
-
|
|
7694
|
-
return results;
|
|
7728
|
+
return svg;
|
|
7695
7729
|
}
|
|
7696
7730
|
function safePrompt(message, defaultValue) {
|
|
7697
7731
|
try {
|
|
@@ -8100,161 +8134,95 @@ function useViewerOptionsContext() {
|
|
|
8100
8134
|
}
|
|
8101
8135
|
|
|
8102
8136
|
// src/viewer/hooks/usePrintHandlers.ts
|
|
8137
|
+
var BLOCKED_WARNING = "[PowerPointViewer] Print window was blocked by the browser. Allow popups for this site to print.";
|
|
8103
8138
|
function usePrintHandlers(input) {
|
|
8104
|
-
const { slides, activeSlideIndex, canvasStageRef, setActiveSlideIndex,
|
|
8139
|
+
const { slides, activeSlideIndex, canvasStageRef, setActiveSlideIndex, canvasSize } = input;
|
|
8140
|
+
const handoutMaster = input.handoutMaster ?? input.pptxData?.handoutMaster;
|
|
8105
8141
|
const [isPrintDialogOpen, setIsPrintDialogOpen] = useState(false);
|
|
8106
8142
|
const { t } = useTranslation();
|
|
8107
8143
|
const viewerOptions = useViewerOptionsContext();
|
|
8108
|
-
const includeHiddenSlides = viewerOptions.advanced.printHiddenSlides;
|
|
8109
8144
|
const printRasterScale = (viewerOptions.advanced.printHighQuality ? 4 : 3) * resolveImageResolutionScale(viewerOptions);
|
|
8110
8145
|
const handlePrint = () => {
|
|
8111
8146
|
setIsPrintDialogOpen(true);
|
|
8112
8147
|
};
|
|
8113
|
-
const
|
|
8114
|
-
|
|
8115
|
-
|
|
8116
|
-
|
|
8117
|
-
|
|
8118
|
-
|
|
8119
|
-
|
|
8120
|
-
|
|
8121
|
-
|
|
8122
|
-
if (!pptxData || settings.printWhat !== "slides") {
|
|
8123
|
-
return runRasterPrint(printWindow, settings);
|
|
8124
|
-
}
|
|
8125
|
-
const colorFilter = computeColorFilter(settings.colorMode);
|
|
8126
|
-
const slideIndices = filterHiddenSlideIndices(
|
|
8127
|
-
computeSlideIndices(
|
|
8128
|
-
settings.slideRange,
|
|
8129
|
-
activeSlideIndex,
|
|
8130
|
-
slides.length,
|
|
8131
|
-
settings.customRangeFrom,
|
|
8132
|
-
settings.customRangeTo
|
|
8133
|
-
),
|
|
8134
|
-
slides,
|
|
8135
|
-
includeHiddenSlides
|
|
8136
|
-
);
|
|
8137
|
-
try {
|
|
8138
|
-
const svgs = exportAllSlidesToSvg(pptxData, {
|
|
8139
|
-
slideIndices
|
|
8140
|
-
});
|
|
8141
|
-
if (svgs.length === 0) {
|
|
8142
|
-
printWindow.close();
|
|
8143
|
-
return;
|
|
8144
|
-
}
|
|
8145
|
-
const printDoc = buildPrintDocument(svgs, pptxData.width, pptxData.height, {
|
|
8146
|
-
title: "Slides (Vector)",
|
|
8147
|
-
orientation: settings.orientation,
|
|
8148
|
-
colorFilter,
|
|
8149
|
-
scaleToFit: settings.scaleToFit
|
|
8150
|
-
});
|
|
8151
|
-
finishPrintWindow(printWindow, printDoc);
|
|
8152
|
-
} catch (err) {
|
|
8153
|
-
console.warn("[PowerPointViewer] SVG print path failed, falling back to raster:", err);
|
|
8154
|
-
return runRasterPrint(printWindow, settings);
|
|
8155
|
-
}
|
|
8156
|
-
};
|
|
8157
|
-
const runRasterPrint = async (printWindow, settings) => {
|
|
8158
|
-
const colorFilter = computeColorFilter(settings.colorMode);
|
|
8159
|
-
const slideIndices = filterHiddenSlideIndices(
|
|
8160
|
-
computeSlideIndices(
|
|
8161
|
-
settings.slideRange,
|
|
8162
|
-
activeSlideIndex,
|
|
8163
|
-
slides.length,
|
|
8164
|
-
settings.customRangeFrom,
|
|
8165
|
-
settings.customRangeTo
|
|
8166
|
-
),
|
|
8167
|
-
slides,
|
|
8168
|
-
includeHiddenSlides
|
|
8169
|
-
);
|
|
8170
|
-
if (settings.printWhat === "outline") {
|
|
8171
|
-
finishPrintWindow(
|
|
8172
|
-
printWindow,
|
|
8173
|
-
buildPrintHtmlDocument({
|
|
8174
|
-
title: "Outline",
|
|
8175
|
-
bodyHtml: `<div class="outline-page">${buildOutlineHtml(slideIndices, slides)}</div>`,
|
|
8176
|
-
orientation: settings.orientation,
|
|
8177
|
-
colorFilter,
|
|
8178
|
-
frameSlides: settings.frameSlides,
|
|
8179
|
-
scaleToFit: settings.scaleToFit
|
|
8180
|
-
})
|
|
8181
|
-
);
|
|
8182
|
-
return;
|
|
8183
|
-
}
|
|
8148
|
+
const deckSlides = () => input.templateElementsBySlideId ? buildSaveSlides(slides, input.templateElementsBySlideId) : slides;
|
|
8149
|
+
const plan = (settings, deck) => planPrintJob(settings, {
|
|
8150
|
+
slides: deck,
|
|
8151
|
+
activeSlideIndex,
|
|
8152
|
+
// Options > Advanced > "Print hidden slides".
|
|
8153
|
+
includeHiddenSlides: viewerOptions.advanced.printHiddenSlides
|
|
8154
|
+
});
|
|
8155
|
+
const title = (job) => t(job.title.key, job.title.params);
|
|
8156
|
+
const runRasterPrint = async (printWindow, job, deck) => {
|
|
8184
8157
|
try {
|
|
8185
8158
|
if (!canvasStageRef.current) {
|
|
8186
8159
|
printWindow.close();
|
|
8187
8160
|
return;
|
|
8188
8161
|
}
|
|
8189
|
-
const
|
|
8162
|
+
const captures = await captureSlidesAsPngDataUrls(
|
|
8190
8163
|
canvasStageRef,
|
|
8191
|
-
|
|
8164
|
+
job.slideIndices,
|
|
8192
8165
|
setActiveSlideIndex,
|
|
8193
8166
|
activeSlideIndex,
|
|
8194
8167
|
{ scale: printRasterScale }
|
|
8195
8168
|
);
|
|
8196
|
-
if (
|
|
8169
|
+
if (captures.length === 0) {
|
|
8197
8170
|
printWindow.close();
|
|
8198
8171
|
return;
|
|
8199
8172
|
}
|
|
8200
|
-
|
|
8201
|
-
|
|
8202
|
-
|
|
8203
|
-
|
|
8204
|
-
buildPrintHtmlDocument({
|
|
8205
|
-
title: "Slides",
|
|
8206
|
-
bodyHtml: buildSlidesHtml(slideImages, slideIndices),
|
|
8207
|
-
orientation: settings.orientation,
|
|
8208
|
-
colorFilter,
|
|
8209
|
-
frameSlides: settings.frameSlides,
|
|
8210
|
-
scaleToFit: settings.scaleToFit
|
|
8211
|
-
})
|
|
8212
|
-
);
|
|
8213
|
-
return;
|
|
8214
|
-
}
|
|
8215
|
-
if (settings.printWhat === "notes") {
|
|
8216
|
-
finishPrintWindow(
|
|
8217
|
-
printWindow,
|
|
8218
|
-
buildPrintHtmlDocument({
|
|
8219
|
-
title: "Notes Pages",
|
|
8220
|
-
bodyHtml: buildNotesHtml(slideImages, slideIndices, slides),
|
|
8221
|
-
orientation: "portrait",
|
|
8222
|
-
colorFilter,
|
|
8223
|
-
frameSlides: settings.frameSlides,
|
|
8224
|
-
scaleToFit: settings.scaleToFit
|
|
8225
|
-
})
|
|
8226
|
-
);
|
|
8227
|
-
return;
|
|
8228
|
-
}
|
|
8229
|
-
if (settings.printWhat === "handouts") {
|
|
8230
|
-
const spp = settings.slidesPerPage;
|
|
8231
|
-
finishPrintWindow(
|
|
8232
|
-
printWindow,
|
|
8233
|
-
buildPrintHtmlDocument({
|
|
8234
|
-
title: `Handout ${spp} per page`,
|
|
8235
|
-
bodyHtml: buildHandoutsHtml(slideImages, slideIndices, spp, pptxData?.handoutMaster),
|
|
8236
|
-
orientation: "portrait",
|
|
8237
|
-
colorFilter,
|
|
8238
|
-
frameSlides: settings.frameSlides,
|
|
8239
|
-
scaleToFit: settings.scaleToFit
|
|
8240
|
-
})
|
|
8241
|
-
);
|
|
8242
|
-
}
|
|
8173
|
+
finishPrintWindow(
|
|
8174
|
+
printWindow,
|
|
8175
|
+
buildRasterPrintJobDocument(job, title(job), captures, deck, handoutMaster)
|
|
8176
|
+
);
|
|
8243
8177
|
} catch (err) {
|
|
8244
8178
|
console.error("[PowerPointViewer] Print layout failed:", err);
|
|
8179
|
+
printWindow.close();
|
|
8245
8180
|
}
|
|
8246
8181
|
};
|
|
8247
|
-
const
|
|
8248
|
-
|
|
8182
|
+
const openNow = (html) => {
|
|
8183
|
+
if (!openPrintWindow(html)) {
|
|
8184
|
+
console.warn(BLOCKED_WARNING);
|
|
8185
|
+
}
|
|
8186
|
+
};
|
|
8187
|
+
const startRasterPrint = async (job, deck) => {
|
|
8249
8188
|
const printWindow = openPendingPrintWindow(t("pptx.print.preparingToPrint"));
|
|
8250
8189
|
if (!printWindow) {
|
|
8251
|
-
console.warn(
|
|
8252
|
-
|
|
8190
|
+
console.warn(BLOCKED_WARNING);
|
|
8191
|
+
return;
|
|
8192
|
+
}
|
|
8193
|
+
await runRasterPrint(printWindow, job, deck);
|
|
8194
|
+
};
|
|
8195
|
+
const vectorDocument = (job, deck) => {
|
|
8196
|
+
try {
|
|
8197
|
+
const svgs = job.slideIndices.map(
|
|
8198
|
+
(index) => exportSlideToSvg(deck[index], canvasSize.width, canvasSize.height)
|
|
8253
8199
|
);
|
|
8200
|
+
return buildVectorPrintJobDocument(job, title(job), svgs, canvasSize);
|
|
8201
|
+
} catch (err) {
|
|
8202
|
+
console.warn("[PowerPointViewer] SVG print path failed, falling back to raster:", err);
|
|
8203
|
+
return void 0;
|
|
8204
|
+
}
|
|
8205
|
+
};
|
|
8206
|
+
const runPrintJob = async (settings, vector) => {
|
|
8207
|
+
setIsPrintDialogOpen(false);
|
|
8208
|
+
const deck = deckSlides();
|
|
8209
|
+
const job = plan(settings, deck);
|
|
8210
|
+
if (!job.ok) {
|
|
8211
|
+
return;
|
|
8212
|
+
}
|
|
8213
|
+
if (job.output === "outline") {
|
|
8214
|
+
openNow(buildOutlinePrintJobDocument(job, title(job), deck));
|
|
8215
|
+
return;
|
|
8216
|
+
}
|
|
8217
|
+
const html = vector && job.output === "vector" ? vectorDocument(job, deck) : void 0;
|
|
8218
|
+
if (html !== void 0) {
|
|
8219
|
+
openNow(html);
|
|
8254
8220
|
return;
|
|
8255
8221
|
}
|
|
8256
|
-
|
|
8222
|
+
await startRasterPrint(printJobRasterFallback(job), deck);
|
|
8257
8223
|
};
|
|
8224
|
+
const handlePrintSvg = (settings) => runPrintJob(settings, true);
|
|
8225
|
+
const handlePrintWithSettings = (settings) => runPrintJob(settings, false);
|
|
8258
8226
|
return {
|
|
8259
8227
|
handlePrint,
|
|
8260
8228
|
handlePrintWithSettings,
|
|
@@ -8263,6 +8231,27 @@ function usePrintHandlers(input) {
|
|
|
8263
8231
|
setIsPrintDialogOpen
|
|
8264
8232
|
};
|
|
8265
8233
|
}
|
|
8234
|
+
async function applyThemePartInPlace(input, themePath, applyToAllMasters) {
|
|
8235
|
+
const change = await applyThemeByPath(input.handlerRef.current, {
|
|
8236
|
+
themePath,
|
|
8237
|
+
applyToAllMasters,
|
|
8238
|
+
slides: input.slides,
|
|
8239
|
+
slideMasters: input.slideMasters,
|
|
8240
|
+
theme: input.theme,
|
|
8241
|
+
templateElementsBySlideId: input.templateElementsBySlideId
|
|
8242
|
+
});
|
|
8243
|
+
if (!change) {
|
|
8244
|
+
return;
|
|
8245
|
+
}
|
|
8246
|
+
input.bumpHistory();
|
|
8247
|
+
input.setSlides(change.slides);
|
|
8248
|
+
input.setTemplateElementsBySlideId(change.templateElementsBySlideId);
|
|
8249
|
+
input.setSlideMasters(change.slideMasters);
|
|
8250
|
+
if (change.deckTheme) {
|
|
8251
|
+
input.setTheme(change.deckTheme.theme);
|
|
8252
|
+
}
|
|
8253
|
+
input.history.markDirty();
|
|
8254
|
+
}
|
|
8266
8255
|
async function applyThemeEditorEdit(input, { colorScheme, fontScheme, name }) {
|
|
8267
8256
|
const {
|
|
8268
8257
|
handlerRef,
|
|
@@ -8277,7 +8266,7 @@ async function applyThemeEditorEdit(input, { colorScheme, fontScheme, name }) {
|
|
|
8277
8266
|
if (!handler) {
|
|
8278
8267
|
return;
|
|
8279
8268
|
}
|
|
8280
|
-
await handler.applyTheme(colorScheme, fontScheme, name);
|
|
8269
|
+
await queueThemeWrite(handler, () => handler.applyTheme(colorScheme, fontScheme, name));
|
|
8281
8270
|
const previousMap = theme?.colorScheme ? buildThemeColorMap(theme.colorScheme) : {};
|
|
8282
8271
|
bumpHistory();
|
|
8283
8272
|
setSlides(
|
|
@@ -8303,14 +8292,27 @@ async function applyThemeEditorEdit(input, { colorScheme, fontScheme, name }) {
|
|
|
8303
8292
|
setTheme((prev) => ({ ...prev, colorScheme, fontScheme, name }));
|
|
8304
8293
|
history.markDirty();
|
|
8305
8294
|
}
|
|
8295
|
+
function restoreHistoryTheme(input, target) {
|
|
8296
|
+
const masters = input.slideMasters;
|
|
8297
|
+
const current = historyTheme(input.theme, masters);
|
|
8298
|
+
input.setTheme((prev) => withHistoryTheme(prev, target));
|
|
8299
|
+
if (target.masterThemePaths) {
|
|
8300
|
+
input.setSlideMasters(
|
|
8301
|
+
(prev) => withHistoryMasterThemes(prev, target)
|
|
8302
|
+
);
|
|
8303
|
+
}
|
|
8304
|
+
return writeThemeParts(
|
|
8305
|
+
input.handlerRef.current,
|
|
8306
|
+
current,
|
|
8307
|
+
target,
|
|
8308
|
+
loadedThemeName(input.themeOptions, input.slideMasters)
|
|
8309
|
+
);
|
|
8310
|
+
}
|
|
8306
8311
|
|
|
8307
8312
|
// src/viewer/hooks/useThemeHandlers.ts
|
|
8308
8313
|
function useThemeHandlers(input) {
|
|
8309
8314
|
const {
|
|
8310
8315
|
handlerRef,
|
|
8311
|
-
serializeSlides,
|
|
8312
|
-
setContent,
|
|
8313
|
-
onContentChange,
|
|
8314
8316
|
setTheme,
|
|
8315
8317
|
setSlideMasters,
|
|
8316
8318
|
slideMasters,
|
|
@@ -8321,36 +8323,13 @@ function useThemeHandlers(input) {
|
|
|
8321
8323
|
theme,
|
|
8322
8324
|
bumpHistory
|
|
8323
8325
|
} = input;
|
|
8324
|
-
const
|
|
8325
|
-
const updated = await serializeSlides();
|
|
8326
|
-
if (!updated) {
|
|
8327
|
-
return;
|
|
8328
|
-
}
|
|
8329
|
-
setContent(updated);
|
|
8330
|
-
if (onContentChange) {
|
|
8331
|
-
onContentChange(updated);
|
|
8332
|
-
}
|
|
8333
|
-
history.markDirty();
|
|
8334
|
-
};
|
|
8335
|
-
const handleApplyTheme = async (themePath, applyToAllMasters) => {
|
|
8336
|
-
const handler = handlerRef.current;
|
|
8337
|
-
if (!handler) {
|
|
8338
|
-
return;
|
|
8339
|
-
}
|
|
8340
|
-
await handler.setPresentationTheme(themePath, applyToAllMasters);
|
|
8341
|
-
setSlideMasters(
|
|
8342
|
-
(prev) => prev.map(
|
|
8343
|
-
(master, index) => applyToAllMasters || index === 0 ? { ...master, themePath } : master
|
|
8344
|
-
)
|
|
8345
|
-
);
|
|
8346
|
-
await refreshContentAfterThemeChange();
|
|
8347
|
-
};
|
|
8326
|
+
const handleApplyTheme = (themePath, applyToAllMasters) => applyThemePartInPlace(input, themePath, applyToAllMasters);
|
|
8348
8327
|
const handleUpdateThemeColorScheme = async (colorScheme) => {
|
|
8349
8328
|
const handler = handlerRef.current;
|
|
8350
8329
|
if (!handler) {
|
|
8351
8330
|
return;
|
|
8352
8331
|
}
|
|
8353
|
-
await handler.updateThemeColorScheme(colorScheme);
|
|
8332
|
+
await queueThemeWrite(handler, () => handler.updateThemeColorScheme(colorScheme));
|
|
8354
8333
|
const previousMap = theme?.colorScheme ? buildThemeColorMap(theme.colorScheme) : {};
|
|
8355
8334
|
setSlides((prev) => reResolveSlideColors(prev, previousMap, colorScheme));
|
|
8356
8335
|
if (Object.keys(templateElementsBySlideId).length > 0) {
|
|
@@ -8371,7 +8350,7 @@ function useThemeHandlers(input) {
|
|
|
8371
8350
|
if (!handler) {
|
|
8372
8351
|
return;
|
|
8373
8352
|
}
|
|
8374
|
-
await handler.updateThemeFontScheme(fontScheme);
|
|
8353
|
+
await queueThemeWrite(handler, () => handler.updateThemeFontScheme(fontScheme));
|
|
8375
8354
|
const previousFonts = theme?.fontScheme;
|
|
8376
8355
|
bumpHistory();
|
|
8377
8356
|
setSlides((prev) => reResolveSlideFonts(prev, previousFonts, fontScheme));
|
|
@@ -8391,20 +8370,15 @@ function useThemeHandlers(input) {
|
|
|
8391
8370
|
if (!handler) {
|
|
8392
8371
|
return;
|
|
8393
8372
|
}
|
|
8394
|
-
await handler.updateThemeName(name);
|
|
8373
|
+
await queueThemeWrite(handler, () => handler.updateThemeName(name));
|
|
8395
8374
|
setTheme((prev) => prev ? { ...prev, name } : { name });
|
|
8396
8375
|
history.markDirty();
|
|
8397
8376
|
};
|
|
8398
8377
|
const handleApplyThemeToPresentation = async () => {
|
|
8399
|
-
const handler = handlerRef.current;
|
|
8400
|
-
if (!handler) {
|
|
8401
|
-
return;
|
|
8402
|
-
}
|
|
8403
8378
|
const primaryThemePath = slideMasters[0]?.themePath;
|
|
8404
8379
|
if (primaryThemePath) {
|
|
8405
|
-
await
|
|
8380
|
+
await applyThemePartInPlace(input, primaryThemePath, true);
|
|
8406
8381
|
}
|
|
8407
|
-
await refreshContentAfterThemeChange();
|
|
8408
8382
|
};
|
|
8409
8383
|
const handleApplyThemeData = (colorScheme, fontScheme, themeName) => applyThemeEditorEdit(input, { colorScheme, fontScheme, name: themeName ?? theme?.name ?? "" });
|
|
8410
8384
|
const handleSetTemplateBackground = (path, backgroundColor) => {
|
|
@@ -8432,16 +8406,9 @@ function useThemeHandlers(input) {
|
|
|
8432
8406
|
}
|
|
8433
8407
|
return handler.getAvailableThemes();
|
|
8434
8408
|
};
|
|
8435
|
-
const handleSwitchTheme =
|
|
8436
|
-
const handler = handlerRef.current;
|
|
8437
|
-
if (!handler) {
|
|
8438
|
-
return;
|
|
8439
|
-
}
|
|
8440
|
-
await handler.setPresentationTheme(themePath, true);
|
|
8441
|
-
setSlideMasters((prev) => prev.map((master) => ({ ...master, themePath })));
|
|
8442
|
-
await refreshContentAfterThemeChange();
|
|
8443
|
-
};
|
|
8409
|
+
const handleSwitchTheme = (themePath) => applyThemePartInPlace(input, themePath, true);
|
|
8444
8410
|
const handleApplyThemeEdit = (edit) => applyThemeEditorEdit(input, edit);
|
|
8411
|
+
const handleRestoreHistoryTheme = (target) => restoreHistoryTheme(input, target);
|
|
8445
8412
|
return {
|
|
8446
8413
|
handleApplyThemeEdit,
|
|
8447
8414
|
handleApplyTheme,
|
|
@@ -8450,6 +8417,7 @@ function useThemeHandlers(input) {
|
|
|
8450
8417
|
handleUpdateThemeName,
|
|
8451
8418
|
handleApplyThemeToPresentation,
|
|
8452
8419
|
handleApplyThemeData,
|
|
8420
|
+
handleRestoreHistoryTheme,
|
|
8453
8421
|
handleSetTemplateBackground,
|
|
8454
8422
|
handleGetTemplateBackgroundColor,
|
|
8455
8423
|
handleGetAvailableThemes,
|
|
@@ -9820,8 +9788,7 @@ function useEditorOperations(input) {
|
|
|
9820
9788
|
const findReplace = useFindReplace({
|
|
9821
9789
|
slides,
|
|
9822
9790
|
mode,
|
|
9823
|
-
|
|
9824
|
-
onSetSelectedElementId: state.setSelectedElementId,
|
|
9791
|
+
onShowMatch: state.showSlideSelection,
|
|
9825
9792
|
onUpdateSlides: ops.updateSlides,
|
|
9826
9793
|
onMarkDirty: history.markDirty,
|
|
9827
9794
|
keyboard
|
|
@@ -10026,9 +9993,7 @@ function useIOHandlers(input) {
|
|
|
10026
9993
|
zoom,
|
|
10027
9994
|
handlerRef,
|
|
10028
9995
|
serializeSlides,
|
|
10029
|
-
serializeForRecovery,
|
|
10030
9996
|
setContent,
|
|
10031
|
-
onContentChange,
|
|
10032
9997
|
onPropertiesChange,
|
|
10033
9998
|
onNotesUpdate,
|
|
10034
9999
|
imageExportScale,
|
|
@@ -10065,19 +10030,19 @@ function useIOHandlers(input) {
|
|
|
10065
10030
|
slides,
|
|
10066
10031
|
activeSlideIndex,
|
|
10067
10032
|
canvasStageRef: zoom.canvasStageRef,
|
|
10068
|
-
setActiveSlideIndex: state.setActiveSlideIndex
|
|
10033
|
+
setActiveSlideIndex: state.setActiveSlideIndex,
|
|
10034
|
+
canvasSize,
|
|
10035
|
+
templateElementsBySlideId: state.templateElementsBySlideId,
|
|
10036
|
+
handoutMaster: state.handoutMaster
|
|
10069
10037
|
});
|
|
10070
10038
|
const themeHandlers = useThemeHandlers({
|
|
10071
10039
|
handlerRef,
|
|
10072
|
-
// Theme apply re-serialises and re-parses through `setContent`, so these
|
|
10073
|
-
// bytes go back into our own loader: plaintext, never the protected save.
|
|
10074
|
-
serializeSlides: serializeForRecovery,
|
|
10075
|
-
setContent,
|
|
10076
|
-
onContentChange,
|
|
10077
10040
|
setTheme: state.setTheme,
|
|
10078
10041
|
setSlideMasters: state.setSlideMasters,
|
|
10079
10042
|
slideMasters: state.slideMasters,
|
|
10043
|
+
themeOptions: state.themeOptions,
|
|
10080
10044
|
history,
|
|
10045
|
+
slides,
|
|
10081
10046
|
setSlides: state.setSlides,
|
|
10082
10047
|
templateElementsBySlideId: state.templateElementsBySlideId,
|
|
10083
10048
|
setTemplateElementsBySlideId: state.setTemplateElementsBySlideId,
|
|
@@ -10131,7 +10096,12 @@ function isFontDataUrlSafe(url) {
|
|
|
10131
10096
|
}
|
|
10132
10097
|
return FONT_DATA_URL_PATTERN.test(url);
|
|
10133
10098
|
}
|
|
10134
|
-
function useFontInjection({
|
|
10099
|
+
function useFontInjection({
|
|
10100
|
+
embeddedFonts,
|
|
10101
|
+
slides,
|
|
10102
|
+
googleFonts
|
|
10103
|
+
}) {
|
|
10104
|
+
const googleFontsBase = resolveGoogleFontsCss2Base(googleFonts);
|
|
10135
10105
|
useEffect(() => {
|
|
10136
10106
|
if (!embeddedFonts.length) {
|
|
10137
10107
|
return;
|
|
@@ -10173,17 +10143,19 @@ function useFontInjection({ embeddedFonts, slides }) {
|
|
|
10173
10143
|
const referencedFamilies = useMemo(() => collectReferencedFontFamilies(slides), [slides]);
|
|
10174
10144
|
useEffect(() => {
|
|
10175
10145
|
let cancelled = false;
|
|
10176
|
-
void resolveGoogleWebfontHref(slides, embeddedFonts).then(
|
|
10177
|
-
|
|
10178
|
-
|
|
10146
|
+
void resolveGoogleWebfontHref(slides, embeddedFonts, void 0, googleFontsBase).then(
|
|
10147
|
+
(href) => {
|
|
10148
|
+
if (cancelled) {
|
|
10149
|
+
return null;
|
|
10150
|
+
}
|
|
10151
|
+
syncGoogleWebfontStylesheet(document, GOOGLE_FONTS_LINK_ID, href);
|
|
10152
|
+
return href;
|
|
10179
10153
|
}
|
|
10180
|
-
|
|
10181
|
-
return href;
|
|
10182
|
-
});
|
|
10154
|
+
);
|
|
10183
10155
|
return () => {
|
|
10184
10156
|
cancelled = true;
|
|
10185
10157
|
};
|
|
10186
|
-
}, [embeddedFonts, slides]);
|
|
10158
|
+
}, [embeddedFonts, slides, googleFontsBase]);
|
|
10187
10159
|
useEffect(() => () => document.getElementById(GOOGLE_FONTS_LINK_ID)?.remove(), []);
|
|
10188
10160
|
const [, setOutlineFontsTick] = useState(0);
|
|
10189
10161
|
useEffect(() => {
|
|
@@ -10196,41 +10168,43 @@ function useFontInjection({ embeddedFonts, slides }) {
|
|
|
10196
10168
|
if (candidates.length === 0) {
|
|
10197
10169
|
return;
|
|
10198
10170
|
}
|
|
10199
|
-
void resolveGoogleWebfontHref(slides, embeddedFonts).then(
|
|
10200
|
-
|
|
10201
|
-
|
|
10202
|
-
|
|
10203
|
-
|
|
10204
|
-
|
|
10205
|
-
|
|
10206
|
-
|
|
10207
|
-
|
|
10208
|
-
|
|
10209
|
-
for (const
|
|
10210
|
-
|
|
10211
|
-
|
|
10212
|
-
|
|
10213
|
-
|
|
10214
|
-
|
|
10215
|
-
|
|
10216
|
-
|
|
10217
|
-
|
|
10218
|
-
|
|
10219
|
-
|
|
10220
|
-
|
|
10221
|
-
|
|
10171
|
+
void resolveGoogleWebfontHref(slides, embeddedFonts, void 0, googleFontsBase).then(
|
|
10172
|
+
async (href) => {
|
|
10173
|
+
if (cancelled || !href) {
|
|
10174
|
+
return;
|
|
10175
|
+
}
|
|
10176
|
+
const boldItalicVariants = [
|
|
10177
|
+
{ bold: false, italic: false },
|
|
10178
|
+
{ bold: true, italic: false }
|
|
10179
|
+
];
|
|
10180
|
+
let registeredAny = false;
|
|
10181
|
+
for (const family of candidates) {
|
|
10182
|
+
for (const variant of boldItalicVariants) {
|
|
10183
|
+
if (cancelled) {
|
|
10184
|
+
return;
|
|
10185
|
+
}
|
|
10186
|
+
const bytes = await fetchGoogleWebfontOutlineBytes(
|
|
10187
|
+
href,
|
|
10188
|
+
family,
|
|
10189
|
+
variant.bold,
|
|
10190
|
+
variant.italic,
|
|
10191
|
+
fetch
|
|
10192
|
+
);
|
|
10193
|
+
if (bytes && glyphOutlineFontCache.registerFontBytes(family, variant.bold, variant.italic, bytes)) {
|
|
10194
|
+
registeredAny = true;
|
|
10195
|
+
}
|
|
10222
10196
|
}
|
|
10223
10197
|
}
|
|
10198
|
+
if (registeredAny && !cancelled) {
|
|
10199
|
+
setOutlineFontsTick((tick) => tick + 1);
|
|
10200
|
+
}
|
|
10201
|
+
return void 0;
|
|
10224
10202
|
}
|
|
10225
|
-
|
|
10226
|
-
setOutlineFontsTick((tick) => tick + 1);
|
|
10227
|
-
}
|
|
10228
|
-
return void 0;
|
|
10229
|
-
});
|
|
10203
|
+
);
|
|
10230
10204
|
return () => {
|
|
10231
10205
|
cancelled = true;
|
|
10232
10206
|
};
|
|
10233
|
-
}, [embeddedFonts, slides]);
|
|
10207
|
+
}, [embeddedFonts, slides, googleFontsBase]);
|
|
10234
10208
|
useEffect(() => {
|
|
10235
10209
|
const neededSymbolFonts = SYMBOL_FONT_FAMILIES.filter((f) => referencedFamilies.has(f));
|
|
10236
10210
|
if (neededSymbolFonts.length === 0) {
|
|
@@ -10278,6 +10252,7 @@ function useContentLifecycle(input) {
|
|
|
10278
10252
|
onContentApplied,
|
|
10279
10253
|
allowExternalImages,
|
|
10280
10254
|
initialSlide,
|
|
10255
|
+
googleFonts,
|
|
10281
10256
|
setReadOnlyRecommendation,
|
|
10282
10257
|
setModifyVerifier,
|
|
10283
10258
|
setCompatToasts
|
|
@@ -10334,7 +10309,7 @@ function useContentLifecycle(input) {
|
|
|
10334
10309
|
useEffect(() => {
|
|
10335
10310
|
actionSoundHandlerRef.current = handlerRef.current;
|
|
10336
10311
|
}, [handlerRef, actionSoundHandlerRef, state.loading]);
|
|
10337
|
-
useFontInjection({ embeddedFonts: state.embeddedFonts, slides });
|
|
10312
|
+
useFontInjection({ embeddedFonts: state.embeddedFonts, slides, googleFonts });
|
|
10338
10313
|
const serializeInput = {
|
|
10339
10314
|
slides,
|
|
10340
10315
|
templateElementsBySlideId: state.templateElementsBySlideId,
|
|
@@ -10690,6 +10665,7 @@ function useViewerIntegration(input) {
|
|
|
10690
10665
|
autosaveIntervalMs,
|
|
10691
10666
|
allowExternalImages,
|
|
10692
10667
|
initialSlide,
|
|
10668
|
+
googleFonts,
|
|
10693
10669
|
setReadOnlyRecommendation,
|
|
10694
10670
|
setModifyVerifier,
|
|
10695
10671
|
setCompatToasts,
|
|
@@ -10754,32 +10730,31 @@ function useViewerIntegration(input) {
|
|
|
10754
10730
|
});
|
|
10755
10731
|
const [isEncryptedDialogOpen, setIsEncryptedDialogOpen] = useState(false);
|
|
10756
10732
|
const [loadVersion, setLoadVersion] = useState(0);
|
|
10757
|
-
const { handlerRef, serializeSlides,
|
|
10758
|
-
|
|
10759
|
-
|
|
10760
|
-
|
|
10761
|
-
|
|
10762
|
-
|
|
10763
|
-
|
|
10764
|
-
|
|
10765
|
-
|
|
10766
|
-
|
|
10767
|
-
|
|
10768
|
-
|
|
10769
|
-
|
|
10770
|
-
|
|
10771
|
-
|
|
10772
|
-
|
|
10773
|
-
|
|
10774
|
-
|
|
10775
|
-
|
|
10776
|
-
|
|
10777
|
-
|
|
10778
|
-
|
|
10779
|
-
|
|
10780
|
-
|
|
10781
|
-
|
|
10782
|
-
);
|
|
10733
|
+
const { handlerRef, serializeSlides, autosaveStatus } = useContentLifecycle({
|
|
10734
|
+
content,
|
|
10735
|
+
filePath,
|
|
10736
|
+
storage,
|
|
10737
|
+
autosaveEnabled,
|
|
10738
|
+
autosaveIntervalMs,
|
|
10739
|
+
onAutosave,
|
|
10740
|
+
// The File > Fonts toggle, finally reaching a save call.
|
|
10741
|
+
embedFonts: dialogs.embedFontsEnabled,
|
|
10742
|
+
slides,
|
|
10743
|
+
state,
|
|
10744
|
+
history,
|
|
10745
|
+
ops: editorOps.ops,
|
|
10746
|
+
transformCommittedText: input.transformCommittedText,
|
|
10747
|
+
actionSoundHandlerRef,
|
|
10748
|
+
setIsEncryptedDialogOpen,
|
|
10749
|
+
password: dialogs.presentationPassword ?? void 0,
|
|
10750
|
+
onContentApplied: () => setLoadVersion((v) => v + 1),
|
|
10751
|
+
allowExternalImages,
|
|
10752
|
+
initialSlide,
|
|
10753
|
+
googleFonts,
|
|
10754
|
+
setReadOnlyRecommendation,
|
|
10755
|
+
setModifyVerifier,
|
|
10756
|
+
setCompatToasts
|
|
10757
|
+
});
|
|
10783
10758
|
const { exportHandlers, printHandlers, themeHandlers, propertyHandlers } = useIOHandlers({
|
|
10784
10759
|
state,
|
|
10785
10760
|
slides,
|
|
@@ -10793,9 +10768,7 @@ function useViewerIntegration(input) {
|
|
|
10793
10768
|
zoom,
|
|
10794
10769
|
handlerRef,
|
|
10795
10770
|
serializeSlides,
|
|
10796
|
-
serializeForRecovery,
|
|
10797
10771
|
setContent,
|
|
10798
|
-
onContentChange,
|
|
10799
10772
|
onPropertiesChange,
|
|
10800
10773
|
onNotesUpdate,
|
|
10801
10774
|
imageExportScale,
|
|
@@ -11608,11 +11581,9 @@ function useLayoutSwitching(input) {
|
|
|
11608
11581
|
}
|
|
11609
11582
|
setIsLoading(true);
|
|
11610
11583
|
try {
|
|
11611
|
-
const updated = await handler.applyLayoutToSlide(
|
|
11612
|
-
|
|
11613
|
-
|
|
11614
|
-
slidesRef.current
|
|
11615
|
-
);
|
|
11584
|
+
const updated = await handler.applyLayoutToSlide(activeSlideIndex, layoutPath, [
|
|
11585
|
+
...slidesRef.current
|
|
11586
|
+
]);
|
|
11616
11587
|
ops.updateSlides((prev) => {
|
|
11617
11588
|
const next = [...prev];
|
|
11618
11589
|
next[activeSlideIndex] = updated;
|
|
@@ -12833,7 +12804,7 @@ function useViewPreferencesSync(input) {
|
|
|
12833
12804
|
// src/viewer/hooks/useViewerBuildingBlocksState.ts
|
|
12834
12805
|
function useViewerBuildingBlocksState(input) {
|
|
12835
12806
|
const { core, content, canEdit, filePath, autosaveEnabled, userName, handle, setContent } = input;
|
|
12836
|
-
const { initialSlide } = input;
|
|
12807
|
+
const { initialSlide, googleFonts } = input;
|
|
12837
12808
|
const {
|
|
12838
12809
|
onContentChange,
|
|
12839
12810
|
onDirtyChange,
|
|
@@ -12891,11 +12862,7 @@ function useViewerBuildingBlocksState(input) {
|
|
|
12891
12862
|
});
|
|
12892
12863
|
const readOnlyRec = useReadOnlyRecommendationState(content);
|
|
12893
12864
|
const compatToastsState = useCompatibilityToastsState();
|
|
12894
|
-
|
|
12895
|
-
state.setSelectedElementId(null);
|
|
12896
|
-
state.setSelectedElementIds([]);
|
|
12897
|
-
state.setInlineEditingElementId(null);
|
|
12898
|
-
}, [activeSlideIndex]);
|
|
12865
|
+
useClearSelectionOnSlideChange(state, activeSlideIndex);
|
|
12899
12866
|
const editorOps = useEditorOperations({
|
|
12900
12867
|
state,
|
|
12901
12868
|
history,
|
|
@@ -12937,6 +12904,7 @@ function useViewerBuildingBlocksState(input) {
|
|
|
12937
12904
|
filePath,
|
|
12938
12905
|
autosaveEnabled,
|
|
12939
12906
|
initialSlide,
|
|
12907
|
+
googleFonts,
|
|
12940
12908
|
// Trust Center > "Allow external content": same gate `PowerPointViewer`
|
|
12941
12909
|
// applies, so the headless building-blocks API loads http(s) images
|
|
12942
12910
|
// under the same default-off, core-side SSRF/privacy guard.
|
|
@@ -13001,6 +12969,7 @@ function useViewerBuildingBlocks(input) {
|
|
|
13001
12969
|
filePath,
|
|
13002
12970
|
fileName,
|
|
13003
12971
|
initialSlide,
|
|
12972
|
+
googleFonts,
|
|
13004
12973
|
autosaveEnabled = true,
|
|
13005
12974
|
userName,
|
|
13006
12975
|
hiddenActions,
|
|
@@ -13089,6 +13058,7 @@ function useViewerBuildingBlocks(input) {
|
|
|
13089
13058
|
canEdit,
|
|
13090
13059
|
filePath,
|
|
13091
13060
|
initialSlide,
|
|
13061
|
+
googleFonts,
|
|
13092
13062
|
autosaveEnabled,
|
|
13093
13063
|
userName,
|
|
13094
13064
|
handle,
|
|
@@ -18693,4 +18663,4 @@ function useResizablePanels() {
|
|
|
18693
18663
|
};
|
|
18694
18664
|
}
|
|
18695
18665
|
|
|
18696
|
-
export { ACTION_VERB_MAP, ChartFormatContext, ChartPartSelectionProvider, CollaborationCursorOverlay, CollaborationProvider, ElementRenderer, FragmentedTransitionLayer, InlineCollaborationContext, MIN_TOUCH_TARGET, MorphTransitionOverlay, PresentationTransitionOverlay, RemoteSelectionOverlay, RemoteUserCursors, Rendering3DFlagsContext, ResizeHandles, SlideBackgroundImageLayer, SlideLayer, StaticElementRenderer, ViewerOptionsContext, ViewerOptionsStoreContext, computeToolbarVisibility, createReviewCommentsHost, detectTargetType, imgSrc, isAudienceTab, parseAudienceNonce, parseEmailUrl, parseSlideFromUrl, playAnimationSound, renderStrokeView, renderToCanvas, resolveSmartArtDataPalette, safePrompt, scopeLayoutOptionsToActiveSlide, useAnimationPlayback, useAnnotationHandlers, useAudienceMode, useAutosave, useBroadcastFollower, useCanvasInteractions, useChartFormatContext, useChartPartSelection, useClipboardHandlers, useCollaboration, useCollaborationDocumentSync, useCollaborativeHistory, useCollaborativeState, useComments, useCompatibilityToastsState, useContentLifecycle, useController, 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, useReportOnChange, 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, withDisplayName };
|
|
18666
|
+
export { ACTION_VERB_MAP, ChartFormatContext, ChartPartSelectionProvider, CollaborationCursorOverlay, CollaborationProvider, ElementRenderer, FragmentedTransitionLayer, InlineCollaborationContext, MIN_TOUCH_TARGET, MorphTransitionOverlay, PresentationTransitionOverlay, RemoteSelectionOverlay, RemoteUserCursors, Rendering3DFlagsContext, ResizeHandles, SlideBackgroundImageLayer, SlideLayer, StaticElementRenderer, ViewerOptionsContext, ViewerOptionsStoreContext, computeToolbarVisibility, createReviewCommentsHost, detectTargetType, imgSrc, isAudienceTab, parseAudienceNonce, parseEmailUrl, parseSlideFromUrl, playAnimationSound, renderStrokeView, renderToCanvas, resolveSmartArtDataPalette, safePrompt, scopeLayoutOptionsToActiveSlide, useAnimationPlayback, useAnnotationHandlers, useAudienceMode, useAutosave, useBroadcastFollower, useCanvasInteractions, useChartFormatContext, useChartPartSelection, useClearSelectionOnSlideChange, useClipboardHandlers, useCollaboration, useCollaborationDocumentSync, useCollaborativeHistory, useCollaborativeState, useComments, useCompatibilityToastsState, useContentLifecycle, useController, 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, useReportOnChange, 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, withDisplayName };
|