pptx-react-viewer 4.49.0 → 4.50.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 +106 -0
- package/dist/{AiChatPanel-NKTBHT5B.mjs → AiChatPanel-VJV5OEG2.mjs} +1 -1
- package/dist/AiChatPanel-VJV5OEG2.mjs.br +0 -0
- package/dist/AiChatPanel-VJV5OEG2.mjs.gz +0 -0
- package/dist/{AiChatPanel-S4WNQCY4.js → AiChatPanel-WYAL24DX.js} +9 -9
- package/dist/AiChatPanel-WYAL24DX.js.br +0 -0
- package/dist/AiChatPanel-WYAL24DX.js.gz +0 -0
- package/dist/{chunk-2ZXXHNNR.js → chunk-4OF7X5EE.js} +1669 -3046
- package/dist/chunk-4OF7X5EE.js.br +0 -0
- package/dist/chunk-4OF7X5EE.js.gz +0 -0
- package/dist/{chunk-YKLL2Z33.mjs → chunk-5JJQLK7N.mjs} +452 -1829
- package/dist/chunk-5JJQLK7N.mjs.br +0 -0
- package/dist/chunk-5JJQLK7N.mjs.gz +0 -0
- package/dist/{chunk-PFV626ED.mjs → chunk-77IXTLKU.mjs} +3 -4
- package/dist/chunk-77IXTLKU.mjs.br +0 -0
- package/dist/chunk-77IXTLKU.mjs.gz +0 -0
- package/dist/{chunk-ME5QRTVS.js → chunk-D5NXYXPP.js} +740 -1188
- package/dist/chunk-D5NXYXPP.js.br +0 -0
- package/dist/chunk-D5NXYXPP.js.gz +0 -0
- package/dist/chunk-DDJ634MV.js.br +0 -0
- package/dist/chunk-DDJ634MV.js.gz +0 -0
- package/dist/{chunk-JAI42EXQ.js → chunk-JWNBTFZZ.js} +0 -6
- package/dist/chunk-JWNBTFZZ.js.br +0 -0
- package/dist/chunk-JWNBTFZZ.js.gz +0 -0
- package/dist/{chunk-Z62JFXMZ.mjs → chunk-QHGEPW5G.mjs} +563 -1011
- package/dist/chunk-QHGEPW5G.mjs.br +0 -0
- package/dist/chunk-QHGEPW5G.mjs.gz +0 -0
- package/dist/chunk-QIUK53JR.mjs.br +0 -0
- package/dist/chunk-QIUK53JR.mjs.gz +0 -0
- package/dist/i18n/de.cjs +1138 -221
- package/dist/i18n/de.cjs.br +0 -0
- package/dist/i18n/de.cjs.gz +0 -0
- package/dist/i18n/de.mjs +1138 -221
- package/dist/i18n/de.mjs.br +0 -0
- package/dist/i18n/de.mjs.gz +0 -0
- package/dist/i18n/es.cjs +1138 -221
- package/dist/i18n/es.cjs.br +0 -0
- package/dist/i18n/es.cjs.gz +0 -0
- package/dist/i18n/es.mjs +1138 -221
- package/dist/i18n/es.mjs.br +0 -0
- package/dist/i18n/es.mjs.gz +0 -0
- package/dist/i18n/fr.cjs +1138 -221
- package/dist/i18n/fr.cjs.br +0 -0
- package/dist/i18n/fr.cjs.gz +0 -0
- package/dist/i18n/fr.mjs +1138 -221
- package/dist/i18n/fr.mjs.br +0 -0
- package/dist/i18n/fr.mjs.gz +0 -0
- package/dist/i18n/zh-CN.cjs +1138 -221
- package/dist/i18n/zh-CN.cjs.br +0 -0
- package/dist/i18n/zh-CN.cjs.gz +0 -0
- package/dist/i18n/zh-CN.mjs +1138 -221
- package/dist/i18n/zh-CN.mjs.br +0 -0
- package/dist/i18n/zh-CN.mjs.gz +0 -0
- package/dist/index.d.ts +5 -15
- package/dist/index.js +24 -24
- 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 +105 -94
- 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/pptx-viewer-canvas.css +1 -1
- package/dist/pptx-viewer-canvas.css.br +0 -0
- package/dist/pptx-viewer-canvas.css.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.d.ts +7 -12
- package/dist/viewer/index.js +19 -19
- 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/dist/{y-webrtc-2H7UYAQD.mjs → y-webrtc-HRGGVQZH.mjs} +1 -1
- package/dist/y-webrtc-HRGGVQZH.mjs.br +0 -0
- package/dist/y-webrtc-HRGGVQZH.mjs.gz +0 -0
- package/dist/{y-webrtc-DVPQNFLL.js → y-webrtc-QVVT5PCK.js} +124 -124
- package/dist/y-webrtc-QVVT5PCK.js.br +0 -0
- package/dist/y-webrtc-QVVT5PCK.js.gz +0 -0
- package/dist/{y-websocket-WORVRRQS.mjs → y-websocket-46M6UFI7.mjs} +1 -1
- package/dist/y-websocket-46M6UFI7.mjs.br +0 -0
- package/dist/y-websocket-46M6UFI7.mjs.gz +0 -0
- package/dist/{y-websocket-TN4OKPXQ.js → y-websocket-EDOMWMAD.js} +78 -78
- package/dist/y-websocket-EDOMWMAD.js.br +0 -0
- package/dist/y-websocket-EDOMWMAD.js.gz +0 -0
- package/package.json +3 -3
- package/dist/AiChatPanel-NKTBHT5B.mjs.br +0 -0
- package/dist/AiChatPanel-NKTBHT5B.mjs.gz +0 -0
- package/dist/AiChatPanel-S4WNQCY4.js.br +0 -0
- package/dist/AiChatPanel-S4WNQCY4.js.gz +0 -0
- package/dist/chunk-2ZXXHNNR.js.br +0 -0
- package/dist/chunk-2ZXXHNNR.js.gz +0 -0
- package/dist/chunk-3VVZGHHY.mjs.br +0 -0
- package/dist/chunk-3VVZGHHY.mjs.gz +0 -0
- package/dist/chunk-JAI42EXQ.js.br +0 -0
- package/dist/chunk-JAI42EXQ.js.gz +0 -0
- package/dist/chunk-ME5QRTVS.js.br +0 -0
- package/dist/chunk-ME5QRTVS.js.gz +0 -0
- package/dist/chunk-NUNDT6EL.js.br +0 -0
- package/dist/chunk-NUNDT6EL.js.gz +0 -0
- package/dist/chunk-PFV626ED.mjs.br +0 -0
- package/dist/chunk-PFV626ED.mjs.gz +0 -0
- package/dist/chunk-YKLL2Z33.mjs.br +0 -0
- package/dist/chunk-YKLL2Z33.mjs.gz +0 -0
- package/dist/chunk-Z62JFXMZ.mjs.br +0 -0
- package/dist/chunk-Z62JFXMZ.mjs.gz +0 -0
- package/dist/y-webrtc-2H7UYAQD.mjs.br +0 -0
- package/dist/y-webrtc-2H7UYAQD.mjs.gz +0 -0
- package/dist/y-webrtc-DVPQNFLL.js.br +0 -0
- package/dist/y-webrtc-DVPQNFLL.js.gz +0 -0
- package/dist/y-websocket-TN4OKPXQ.js.br +0 -0
- package/dist/y-websocket-TN4OKPXQ.js.gz +0 -0
- package/dist/y-websocket-WORVRRQS.mjs.br +0 -0
- package/dist/y-websocket-WORVRRQS.mjs.gz +0 -0
- package/dist/{chunk-NUNDT6EL.js → chunk-DDJ634MV.js} +436 -436
- package/dist/{chunk-3VVZGHHY.mjs → chunk-QIUK53JR.mjs} +436 -436
|
@@ -1,7 +1,7 @@
|
|
|
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, 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,
|
|
2
|
-
import { defineThreeViewElement, MIN_TOUCH_TARGET_PX, computeVirtualRange, DEFAULT_VIRTUAL_OVERSCAN, createSyncGate, clearLocalAwareness, validateRoomId, createDepartureChannel, resolveTransportForServerUrl, isMixedContentBlocked, CONNECTION_TIMEOUT_MS, registerCollaborationTeardown, createPresenceProjector, BROADCAST_THROTTLE_MS, sanitizeColor, 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, resolveForwardSlideWithZoomReturn, buildZoomTransitionOverride, hasShowSlideAfter, nextShowSlideIndex, previousShowSlideIndex, beginZoomExcursion, createPresenterShowGuard, firstShowSlideIndex, attachPresentationVisibilityPause, presentationEntrySlideIndex, buildMorphTransitionPlan, morphOptionToMode, buildMorphAnimationRules, findInSlides, applyFindReplacements, visibleTemplateElements, createCollaborationLivePatcher, publishLiveInlineText, initialInspectorOpen, createPresentationLoadResources, collectMediaElements, resolveMediaElementSource, collectImagePaths, applyImagePathPatches, resolveTableCellImageUrls, resolveTableStyleImageUrls, resolveTextFillBlipUrls, seedRecentColors, resolveAuthoredCustomShowId, GlyphOutlineFontCache, buildInitialGuides, readOnlyRecommendation, compatibilityWarningToasts, resolveInitialSlideIndex, resolveAutosaveIntervalMs, shouldWriteAutosaveSnapshot, saveAutosaveSnapshot, autosaveSnapshotMark, 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, shouldProbeAutosaveRecovery, probeAutosaveRecovery, acceptAutosaveRecovery, acknowledgeAutosaveRecovery, discardAutosaveRecovery, shouldLoopContinuously, applyRehearsalTimings, rasterResultToPngBlob, downloadBlob, elementPictureFilename, canEditElementPoints, selectTrustedEmbeddedFonts, resolveFontWeight, resolveFontItalic, collectReferencedFontFamilies, resolveGoogleWebfontHref, syncGoogleWebfontStylesheet, selectGoogleWebfontFamilies, fetchGoogleWebfontOutlineBytes, isFeatureEnabled, mapSlideShowStartKey, mapCustomizedEditorKey, isEditorControlTarget, isEditorTextInputTarget, 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, elementIdSelector, createRotationDrag, isActionHidden, buildInlineTextCommitPatch, resolveInlineEditAutoFitHeight, resolveInlineEditNormAutofitShrink, setPendingCaretPoint, drillSelectionForDoubleClick, filterInteractableIds, beginShapeAdjustment, buildElementClipboardPayload, contextMenuInspectorAnchor, savedPresentationFileName, deliverSavedPresentation, exportDeckJson, 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, resolveExportCaptureDecision, recordProgressPercent, computeGridSpacingPx as computeGridSpacingPx$1, resolveShowSlideIndexes, groupSlidesBySection, masterViewPseudoSlide, overlayMasterViewInlineSnapshot, overlayInlineTextSnapshot, rasterizeElement, cloneElementForPaste, applyPasteSpecialFormat, buildRasterPictureElement, cloneElementUpdates, assertElementUpdateTarget, prepareElementUpdateBatch, createWriteBackScheduler, writeBackReport, 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, resolveRevealedSmartArtNodes, resolveRevealedDrawingShapes, buildSmartArtA11y, canDrillDown, computeSmartArtElementLayout, flattenNodes, 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, TOOLBAR_TABS, isEnterableGroup, memberChainAtPoint, findElementPath, drillSelectionForClick, 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, SMARTART_DEFAULT_PALETTE, computeDrawingViewBox, projectDrawingShapes, resolveRevealedDrawingShapeNodeIds, styleShadowFilter, buildChromeStyle, measureSvgViewportRect, modelDataToBlobUrl, resolveZoomNavigationTarget, inlineListBodyText, createInlineListSeed, readListActivationSelection, createInlineListModelObserver, attachCollaborationInlineEditor, bindInlineListParagraph, bindInlineListRun, attachInlineListController, restoreInlineListBodySelection, isBulletMarkerSegment, resolveChartThreeViewSpec, applyChart3DDrag, applyChart3DSelect, findChartPartTarget, withChartTitle, resolveSmartArtThreeViewSpec, isBrowserOpenableMime, formatBytes, getOleDisplayName, getOleBadgeLabel, hasGlyphEnvelope, buildGlyphEnvelopeBlock, getWarpPath, isWedgeCalloutPresetShape, getAriaRole as getAriaRole$1, isElementActionable, buildSmartArtPresetData, classifyMediaType, publishLiveGeometry, getDraggedShapeAdjustments, computeMarqueeHitIds, mergeAdditiveSelection, rasterizeElementTiledToCanvas, borrowExternalCollaborationAwareness, observeExternalCollaborationSession, clampGifDimensions, rasterResultToPngDataUrl, shouldConfirmExternalHyperlink, centeredSvgTextLines, findSmartArtNodeText, rebuildDrawingShapesIfCleared, shouldCommitSmartArtNodeText, advanceChartMarkDrag, advanceChartValueDrag, resolveChartKind, buildChartMarkDragGeometry, beginChartMarkDrag, beginChartValueDrag, commitSmartArtNodeFill, commitSmartArtNodeText, groupIntoParagraphs as groupIntoParagraphs$1, createGlyphOutlineLookup, applyResize, lockResizeAspect, snapBoxToGrid, applyMotionPathPreset, computeInlineEditorRect, smartArtNodeAtPoint, 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, 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-77IXTLKU.mjs';
|
|
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';
|
|
3
3
|
export { DUOTONE_PRESETS, MOBILE_BREAKPOINT, SLIDE_TRANSITION_KEYFRAMES, TABLET_BREAKPOINT, clearAudienceContent, computeVirtualRange, downloadBlob, getSlideTransitionAnimations, loadAudienceContent, storeAudienceContent } from 'ooxml-ui/pptx';
|
|
4
|
-
import React17, { useRef, useState, useCallback, useEffect, useMemo, useContext, useLayoutEffect, createContext, useImperativeHandle,
|
|
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
6
|
import { PptxHandler, EncryptedFileError, hasShapeProperties, applyThemeToData, THEME_PRESETS, themeColorSchemesEqual, guidePxToEmu, hasTextProperties, isInkElement, duplicateSlide, buildThemeColorMap, reResolveSlideColors, reResolveElementColors, isImageLikeElement, SvgExporter, reResolveElementFonts, getSubstituteFontFamily, elementActionToPptxAction, setSmartArtNodeStyle, updateSmartArtNodeText } from 'ooxml-core/pptx';
|
|
7
7
|
import { translationsEn } from 'ooxml-ui/pptx/i18n';
|
|
@@ -75,240 +75,59 @@ function useVirtualizedSlides({
|
|
|
75
75
|
scrollToIndex
|
|
76
76
|
};
|
|
77
77
|
}
|
|
78
|
+
function useController(controller) {
|
|
79
|
+
return useSyncExternalStore(controller.subscribe, controller.getSnapshot, controller.getSnapshot);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// src/viewer/hooks/collaboration/collaboration-modules.ts
|
|
83
|
+
var collabModules = {
|
|
84
|
+
loadYjs: () => import('yjs'),
|
|
85
|
+
loadWebsocket: () => import('./y-websocket-46M6UFI7.mjs'),
|
|
86
|
+
loadWebrtc: () => import('./y-webrtc-HRGGVQZH.mjs')
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
// src/viewer/hooks/collaboration/useYjsProvider.ts
|
|
78
90
|
function useYjsProvider({ config: inputConfig }) {
|
|
79
91
|
const config = inputConfig?.externalSession ? void 0 : inputConfig;
|
|
80
|
-
const [
|
|
81
|
-
|
|
82
|
-
const [doc, setDoc] = useState(null);
|
|
83
|
-
const [clientId, setClientId] = useState(null);
|
|
84
|
-
const [synced, setSynced] = useState(false);
|
|
85
|
-
const cleanupRef = useRef(null);
|
|
86
|
-
const generationRef = useRef(0);
|
|
87
|
-
const timeoutRef = useRef(null);
|
|
88
|
-
const departureRef = useRef(null);
|
|
89
|
-
const gateRef = useRef(null);
|
|
90
|
-
if (!gateRef.current) {
|
|
91
|
-
gateRef.current = createSyncGate(() => setSynced(true));
|
|
92
|
-
}
|
|
93
|
-
const teardown = useCallback(() => {
|
|
94
|
-
generationRef.current += 1;
|
|
95
|
-
if (timeoutRef.current) {
|
|
96
|
-
clearTimeout(timeoutRef.current);
|
|
97
|
-
timeoutRef.current = null;
|
|
98
|
-
}
|
|
99
|
-
gateRef.current?.reset();
|
|
100
|
-
setSynced(false);
|
|
101
|
-
cleanupRef.current?.();
|
|
102
|
-
cleanupRef.current = null;
|
|
103
|
-
}, []);
|
|
104
|
-
const announceDeparture = useCallback(() => {
|
|
105
|
-
departureRef.current?.announce();
|
|
106
|
-
departureRef.current?.dispose();
|
|
107
|
-
departureRef.current = null;
|
|
108
|
-
}, []);
|
|
109
|
-
const buildCleanup = useCallback(
|
|
110
|
-
(provider, yDoc) => () => {
|
|
111
|
-
announceDeparture();
|
|
112
|
-
clearLocalAwareness(provider.awareness);
|
|
113
|
-
provider.destroy();
|
|
114
|
-
yDoc.destroy();
|
|
115
|
-
setDoc(null);
|
|
116
|
-
setAwareness(null);
|
|
117
|
-
setClientId(null);
|
|
118
|
-
setStatus("disconnected");
|
|
119
|
-
},
|
|
120
|
-
[announceDeparture]
|
|
92
|
+
const [controller] = useState(
|
|
93
|
+
() => createCollaborationSessionController({ modules: collabModules, registerTeardown: false })
|
|
121
94
|
);
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
setStatus("connecting");
|
|
128
|
-
try {
|
|
129
|
-
const [Y, { WebrtcProvider }] = await Promise.all([import('yjs'), import('./y-webrtc-2H7UYAQD.mjs')]);
|
|
130
|
-
if (generation !== generationRef.current) {
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
const yDoc = new Y.Doc();
|
|
134
|
-
const opts = {};
|
|
135
|
-
if (config.signaling && config.signaling.length > 0) {
|
|
136
|
-
opts.signaling = config.signaling;
|
|
137
|
-
}
|
|
138
|
-
if (config.authToken) {
|
|
139
|
-
opts.password = config.authToken;
|
|
140
|
-
}
|
|
141
|
-
const roomId = validateRoomId(config.roomId);
|
|
142
|
-
const provider = new WebrtcProvider(roomId, yDoc, opts);
|
|
143
|
-
departureRef.current = createDepartureChannel(roomId, provider.awareness);
|
|
144
|
-
setDoc(yDoc);
|
|
145
|
-
setAwareness(provider.awareness);
|
|
146
|
-
setClientId(provider.awareness.clientID);
|
|
147
|
-
setStatus("connected");
|
|
148
|
-
const handleSynced = (event) => {
|
|
149
|
-
if (event?.synced !== false) {
|
|
150
|
-
gateRef.current?.open();
|
|
151
|
-
}
|
|
152
|
-
};
|
|
153
|
-
provider.on("synced", handleSynced);
|
|
154
|
-
gateRef.current?.arm();
|
|
155
|
-
const handleStatus = (event) => {
|
|
156
|
-
if (event.connected === false) {
|
|
157
|
-
setStatus("disconnected");
|
|
158
|
-
gateRef.current?.reset();
|
|
159
|
-
setSynced(false);
|
|
160
|
-
gateRef.current?.arm();
|
|
161
|
-
} else if (event.connected) {
|
|
162
|
-
setStatus("connected");
|
|
163
|
-
}
|
|
164
|
-
};
|
|
165
|
-
provider.on("status", handleStatus);
|
|
166
|
-
const baseCleanup = buildCleanup(provider, yDoc);
|
|
167
|
-
cleanupRef.current = () => {
|
|
168
|
-
provider.off("synced", handleSynced);
|
|
169
|
-
provider.off("status", handleStatus);
|
|
170
|
-
baseCleanup();
|
|
171
|
-
};
|
|
172
|
-
} catch (err) {
|
|
173
|
-
if (generation !== generationRef.current) {
|
|
174
|
-
return;
|
|
175
|
-
}
|
|
176
|
-
console.warn(
|
|
177
|
-
"[pptx-viewer] WebRTC collaboration packages not available:",
|
|
178
|
-
err instanceof Error ? err.message : err
|
|
179
|
-
);
|
|
180
|
-
setStatus("error");
|
|
181
|
-
}
|
|
182
|
-
}, [config?.roomId, config?.authToken, config?.signaling, buildCleanup]);
|
|
183
|
-
const init = useCallback(async () => {
|
|
184
|
-
teardown();
|
|
185
|
-
const generation = generationRef.current;
|
|
95
|
+
const state = useController(controller);
|
|
96
|
+
const signalingKey = config?.signaling?.join("\n");
|
|
97
|
+
useEffect(() => {
|
|
186
98
|
if (!config) {
|
|
99
|
+
controller.stop();
|
|
187
100
|
return;
|
|
188
101
|
}
|
|
189
|
-
|
|
190
|
-
const
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
);
|
|
199
|
-
setStatus("error");
|
|
200
|
-
return;
|
|
201
|
-
}
|
|
202
|
-
setStatus("connecting");
|
|
203
|
-
try {
|
|
204
|
-
const [Y, { WebsocketProvider }] = await Promise.all([import('yjs'), import('./y-websocket-WORVRRQS.mjs')]);
|
|
205
|
-
if (generation !== generationRef.current) {
|
|
206
|
-
return;
|
|
207
|
-
}
|
|
208
|
-
const yDoc = new Y.Doc();
|
|
209
|
-
const provider = new WebsocketProvider(config.serverUrl, roomId, yDoc, {
|
|
210
|
-
params: config.authToken ? { token: config.authToken } : void 0
|
|
211
|
-
});
|
|
212
|
-
departureRef.current = createDepartureChannel(roomId, provider.awareness);
|
|
213
|
-
let connected = false;
|
|
214
|
-
const handleStatus = (event) => {
|
|
215
|
-
if (event.status === "connected") {
|
|
216
|
-
connected = true;
|
|
217
|
-
if (timeoutRef.current) {
|
|
218
|
-
clearTimeout(timeoutRef.current);
|
|
219
|
-
timeoutRef.current = null;
|
|
220
|
-
}
|
|
221
|
-
setStatus("connected");
|
|
222
|
-
gateRef.current?.arm();
|
|
223
|
-
} else if (event.status === "disconnected") {
|
|
224
|
-
setStatus("disconnected");
|
|
225
|
-
gateRef.current?.reset();
|
|
226
|
-
setSynced(false);
|
|
227
|
-
gateRef.current?.arm();
|
|
228
|
-
}
|
|
229
|
-
};
|
|
230
|
-
const handleSynced = (isSynced) => {
|
|
231
|
-
if (isSynced) {
|
|
232
|
-
gateRef.current?.open();
|
|
233
|
-
}
|
|
234
|
-
};
|
|
235
|
-
provider.on("status", handleStatus);
|
|
236
|
-
provider.on("sync", handleSynced);
|
|
237
|
-
if (provider.wsconnected) {
|
|
238
|
-
connected = true;
|
|
239
|
-
setStatus("connected");
|
|
240
|
-
gateRef.current?.arm();
|
|
241
|
-
}
|
|
242
|
-
if (provider.synced) {
|
|
243
|
-
gateRef.current?.open();
|
|
244
|
-
}
|
|
245
|
-
if (!connected) {
|
|
246
|
-
timeoutRef.current = setTimeout(() => {
|
|
247
|
-
timeoutRef.current = null;
|
|
248
|
-
if (!connected) {
|
|
249
|
-
provider.off("status", handleStatus);
|
|
250
|
-
provider.off("sync", handleSynced);
|
|
251
|
-
announceDeparture();
|
|
252
|
-
clearLocalAwareness(provider.awareness);
|
|
253
|
-
provider.destroy();
|
|
254
|
-
yDoc.destroy();
|
|
255
|
-
setDoc(null);
|
|
256
|
-
setAwareness(null);
|
|
257
|
-
setClientId(null);
|
|
258
|
-
cleanupRef.current = null;
|
|
259
|
-
setStatus("error");
|
|
260
|
-
}
|
|
261
|
-
}, CONNECTION_TIMEOUT_MS);
|
|
262
|
-
}
|
|
263
|
-
setDoc(yDoc);
|
|
264
|
-
setAwareness(provider.awareness);
|
|
265
|
-
setClientId(provider.awareness.clientID);
|
|
266
|
-
cleanupRef.current = () => {
|
|
267
|
-
provider.off("status", handleStatus);
|
|
268
|
-
provider.off("sync", handleSynced);
|
|
269
|
-
announceDeparture();
|
|
270
|
-
clearLocalAwareness(provider.awareness);
|
|
271
|
-
provider.destroy();
|
|
272
|
-
yDoc.destroy();
|
|
273
|
-
setDoc(null);
|
|
274
|
-
setAwareness(null);
|
|
275
|
-
setClientId(null);
|
|
276
|
-
setStatus("disconnected");
|
|
277
|
-
};
|
|
278
|
-
} catch (err) {
|
|
279
|
-
if (generation !== generationRef.current) {
|
|
280
|
-
return;
|
|
281
|
-
}
|
|
282
|
-
console.warn(
|
|
283
|
-
"[pptx-viewer] Collaboration packages not available:",
|
|
284
|
-
err instanceof Error ? err.message : err
|
|
285
|
-
);
|
|
286
|
-
setStatus("error");
|
|
287
|
-
}
|
|
102
|
+
void controller.start(config);
|
|
103
|
+
const disposeTeardown = registerCollaborationTeardown({
|
|
104
|
+
leave: () => controller.stop(),
|
|
105
|
+
rejoin: () => void controller.retry()
|
|
106
|
+
});
|
|
107
|
+
return () => {
|
|
108
|
+
disposeTeardown();
|
|
109
|
+
controller.stop();
|
|
110
|
+
};
|
|
288
111
|
}, [
|
|
112
|
+
controller,
|
|
289
113
|
config?.roomId,
|
|
290
114
|
config?.serverUrl,
|
|
291
115
|
config?.authToken,
|
|
292
116
|
config?.transport,
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
teardown
|
|
117
|
+
signalingKey,
|
|
118
|
+
Boolean(config)
|
|
296
119
|
]);
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
const retry = useCallback(() => {
|
|
309
|
-
init();
|
|
310
|
-
}, [init]);
|
|
311
|
-
return { status, awareness, doc, clientId, synced, retry };
|
|
120
|
+
const session = state.active ? controller.getSession() : null;
|
|
121
|
+
return {
|
|
122
|
+
status: state.status,
|
|
123
|
+
awareness: session?.awareness ?? null,
|
|
124
|
+
doc: session?.doc ?? null,
|
|
125
|
+
clientId: state.clientId,
|
|
126
|
+
synced: state.synced,
|
|
127
|
+
retry: () => {
|
|
128
|
+
void controller.retry();
|
|
129
|
+
}
|
|
130
|
+
};
|
|
312
131
|
}
|
|
313
132
|
function usePresenceTracking({
|
|
314
133
|
awareness,
|
|
@@ -757,15 +576,11 @@ function serializeHistoryDocument(snapshot) {
|
|
|
757
576
|
)
|
|
758
577
|
});
|
|
759
578
|
}
|
|
760
|
-
function recordExplicitSlideUpdate(
|
|
579
|
+
function recordExplicitSlideUpdate(history, previous, before, label) {
|
|
761
580
|
if (previous && serializeHistoryDocument(previous) !== serializeHistoryDocument(before)) {
|
|
762
|
-
|
|
763
|
-
}
|
|
764
|
-
past.push({ ...cloneHistorySnapshot(before), actionLabel: label });
|
|
765
|
-
while (past.length > Math.max(1, maxDepth)) {
|
|
766
|
-
past.shift();
|
|
581
|
+
history.record(cloneHistorySnapshot(previous), previous.actionLabel);
|
|
767
582
|
}
|
|
768
|
-
|
|
583
|
+
history.record({ ...cloneHistorySnapshot(before), actionLabel: label }, label);
|
|
769
584
|
}
|
|
770
585
|
var POLL_INTERVAL_MS = 16;
|
|
771
586
|
function usePointerReleaseWakeup(hasActivePointerInteraction) {
|
|
@@ -801,7 +616,6 @@ function usePointerReleaseWakeup(hasActivePointerInteraction) {
|
|
|
801
616
|
}
|
|
802
617
|
|
|
803
618
|
// src/viewer/hooks/useEditorHistory.ts
|
|
804
|
-
var DEFAULT_MAX_HISTORY_ENTRIES = 120;
|
|
805
619
|
function useEditorHistory(input) {
|
|
806
620
|
const {
|
|
807
621
|
slides,
|
|
@@ -810,7 +624,7 @@ function useEditorHistory(input) {
|
|
|
810
624
|
templateElementsBySlideId,
|
|
811
625
|
loading,
|
|
812
626
|
error,
|
|
813
|
-
maxHistoryEntries
|
|
627
|
+
maxHistoryEntries,
|
|
814
628
|
hasActivePointerInteraction,
|
|
815
629
|
pointerCommitNonce,
|
|
816
630
|
onDirty,
|
|
@@ -821,30 +635,23 @@ function useEditorHistory(input) {
|
|
|
821
635
|
setSelectedElementId,
|
|
822
636
|
setSelectedElementIds
|
|
823
637
|
} = input;
|
|
824
|
-
const
|
|
825
|
-
const
|
|
638
|
+
const [history] = useState(() => createEditorHistoryController());
|
|
639
|
+
const historyState = useController(history);
|
|
826
640
|
const lastHistorySnapshotRef = useRef(null);
|
|
827
641
|
const lastHistorySerializedRef = useRef("");
|
|
828
642
|
const lastCheapHashRef = useRef("");
|
|
829
643
|
const isApplyingHistoryRef = useRef(false);
|
|
830
644
|
const trackingHeldRef = useRef(false);
|
|
831
645
|
const unlockHistoryTimerRef = useRef(null);
|
|
832
|
-
const [canUndo, setCanUndo] = useState(false);
|
|
833
|
-
const [canRedo, setCanRedo] = useState(false);
|
|
834
|
-
const [undoLabel, setUndoLabel] = useState(void 0);
|
|
835
|
-
const [redoLabel, setRedoLabel] = useState(void 0);
|
|
836
646
|
const [editCommitNonce, setEditCommitNonce] = useState(0);
|
|
837
647
|
const { pointerReleaseNonce, deferUntilPointerReleased } = usePointerReleaseWakeup(
|
|
838
648
|
hasActivePointerInteraction
|
|
839
649
|
);
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
const futureTop = historyFutureRef.current[historyFutureRef.current.length - 1];
|
|
846
|
-
setRedoLabel(futureTop?.actionLabel);
|
|
847
|
-
}, []);
|
|
650
|
+
useEffect(() => {
|
|
651
|
+
if (maxHistoryEntries !== void 0) {
|
|
652
|
+
history.setMaxDepth(maxHistoryEntries);
|
|
653
|
+
}
|
|
654
|
+
}, [history, maxHistoryEntries]);
|
|
848
655
|
const buildHistorySnapshot = useCallback(
|
|
849
656
|
(actionLabel) => {
|
|
850
657
|
return {
|
|
@@ -899,53 +706,40 @@ function useEditorHistory(input) {
|
|
|
899
706
|
onDirtyRef.current?.();
|
|
900
707
|
}, []);
|
|
901
708
|
const handleUndo = useCallback(() => {
|
|
902
|
-
|
|
903
|
-
|
|
709
|
+
if (!history.getSnapshot().canUndo) {
|
|
710
|
+
return;
|
|
711
|
+
}
|
|
712
|
+
const result = history.undo(buildHistorySnapshot());
|
|
713
|
+
if (!result) {
|
|
904
714
|
return;
|
|
905
715
|
}
|
|
906
|
-
const currentSnapshot = buildHistorySnapshot(previousSnapshot.actionLabel);
|
|
907
|
-
historyFutureRef.current.push(currentSnapshot);
|
|
908
716
|
isApplyingHistoryRef.current = true;
|
|
909
|
-
const nextSnapshot = cloneHistorySnapshot(
|
|
717
|
+
const nextSnapshot = cloneHistorySnapshot(result.snapshot);
|
|
910
718
|
lastHistorySnapshotRef.current = cloneHistorySnapshot(nextSnapshot);
|
|
911
719
|
lastHistorySerializedRef.current = serializeHistoryDocument(nextSnapshot);
|
|
912
720
|
applyHistorySnapshot(nextSnapshot);
|
|
913
|
-
updateHistoryAvailability();
|
|
914
721
|
unlockHistoryTracking();
|
|
915
722
|
markDirty();
|
|
916
|
-
}, [
|
|
917
|
-
applyHistorySnapshot,
|
|
918
|
-
buildHistorySnapshot,
|
|
919
|
-
markDirty,
|
|
920
|
-
unlockHistoryTracking,
|
|
921
|
-
updateHistoryAvailability
|
|
922
|
-
]);
|
|
723
|
+
}, [applyHistorySnapshot, buildHistorySnapshot, history, markDirty, unlockHistoryTracking]);
|
|
923
724
|
const handleRedo = useCallback(() => {
|
|
924
|
-
|
|
925
|
-
|
|
725
|
+
if (!history.getSnapshot().canRedo) {
|
|
726
|
+
return;
|
|
727
|
+
}
|
|
728
|
+
const result = history.redo(buildHistorySnapshot());
|
|
729
|
+
if (!result) {
|
|
926
730
|
return;
|
|
927
731
|
}
|
|
928
|
-
const currentSnapshot = buildHistorySnapshot(nextSnapshot.actionLabel);
|
|
929
|
-
historyPastRef.current.push(currentSnapshot);
|
|
930
732
|
isApplyingHistoryRef.current = true;
|
|
931
|
-
const targetSnapshot = cloneHistorySnapshot(
|
|
733
|
+
const targetSnapshot = cloneHistorySnapshot(result.snapshot);
|
|
932
734
|
lastHistorySnapshotRef.current = cloneHistorySnapshot(targetSnapshot);
|
|
933
735
|
lastHistorySerializedRef.current = serializeHistoryDocument(targetSnapshot);
|
|
934
736
|
applyHistorySnapshot(targetSnapshot);
|
|
935
|
-
updateHistoryAvailability();
|
|
936
737
|
unlockHistoryTracking();
|
|
937
738
|
markDirty();
|
|
938
|
-
}, [
|
|
939
|
-
applyHistorySnapshot,
|
|
940
|
-
buildHistorySnapshot,
|
|
941
|
-
markDirty,
|
|
942
|
-
unlockHistoryTracking,
|
|
943
|
-
updateHistoryAvailability
|
|
944
|
-
]);
|
|
739
|
+
}, [applyHistorySnapshot, buildHistorySnapshot, history, markDirty, unlockHistoryTracking]);
|
|
945
740
|
const resetHistory = useCallback(
|
|
946
741
|
(initialSnapshot) => {
|
|
947
|
-
|
|
948
|
-
historyFutureRef.current = [];
|
|
742
|
+
history.clear();
|
|
949
743
|
if (initialSnapshot) {
|
|
950
744
|
const clonedInitial = cloneHistorySnapshot(initialSnapshot);
|
|
951
745
|
lastHistorySnapshotRef.current = clonedInitial;
|
|
@@ -954,9 +748,8 @@ function useEditorHistory(input) {
|
|
|
954
748
|
lastHistorySnapshotRef.current = null;
|
|
955
749
|
lastHistorySerializedRef.current = "";
|
|
956
750
|
}
|
|
957
|
-
updateHistoryAvailability();
|
|
958
751
|
},
|
|
959
|
-
[
|
|
752
|
+
[history]
|
|
960
753
|
);
|
|
961
754
|
useEffect(() => {
|
|
962
755
|
return () => {
|
|
@@ -999,19 +792,13 @@ function useEditorHistory(input) {
|
|
|
999
792
|
lastHistorySnapshotRef.current = snapshot;
|
|
1000
793
|
lastHistorySerializedRef.current = serialized;
|
|
1001
794
|
lastCheapHashRef.current = cheapHash;
|
|
1002
|
-
updateHistoryAvailability();
|
|
1003
795
|
return;
|
|
1004
796
|
}
|
|
1005
797
|
onDirtyRef.current?.();
|
|
1006
|
-
|
|
1007
|
-
while (historyPastRef.current.length > Math.max(1, maxHistoryEntries)) {
|
|
1008
|
-
historyPastRef.current.shift();
|
|
1009
|
-
}
|
|
1010
|
-
historyFutureRef.current = [];
|
|
798
|
+
history.record(previousSnapshot, previousSnapshot.actionLabel);
|
|
1011
799
|
lastHistorySnapshotRef.current = snapshot;
|
|
1012
800
|
lastHistorySerializedRef.current = serialized;
|
|
1013
801
|
lastCheapHashRef.current = cheapHash;
|
|
1014
|
-
updateHistoryAvailability();
|
|
1015
802
|
}, [
|
|
1016
803
|
activeSlideIndex,
|
|
1017
804
|
buildHistorySnapshot,
|
|
@@ -1021,30 +808,21 @@ function useEditorHistory(input) {
|
|
|
1021
808
|
editCommitNonce,
|
|
1022
809
|
error,
|
|
1023
810
|
hasActivePointerInteraction,
|
|
811
|
+
history,
|
|
1024
812
|
loading,
|
|
1025
|
-
maxHistoryEntries,
|
|
1026
813
|
pointerCommitNonce,
|
|
1027
814
|
pointerReleaseNonce,
|
|
1028
|
-
slides
|
|
1029
|
-
updateHistoryAvailability
|
|
815
|
+
slides
|
|
1030
816
|
]);
|
|
1031
817
|
const commitSlides = (nextSlides, label, beforeSlides = slides) => {
|
|
1032
818
|
const before = { ...buildHistorySnapshot(), slides: beforeSlides.map(cloneSlide) };
|
|
1033
819
|
const after = { ...before, slides: nextSlides.map(cloneSlide) };
|
|
1034
|
-
recordExplicitSlideUpdate(
|
|
1035
|
-
historyPastRef.current,
|
|
1036
|
-
historyFutureRef.current,
|
|
1037
|
-
lastHistorySnapshotRef.current,
|
|
1038
|
-
before,
|
|
1039
|
-
label,
|
|
1040
|
-
maxHistoryEntries
|
|
1041
|
-
);
|
|
820
|
+
recordExplicitSlideUpdate(history, lastHistorySnapshotRef.current, before, label);
|
|
1042
821
|
lastHistorySnapshotRef.current = cloneHistorySnapshot(after);
|
|
1043
822
|
lastHistorySerializedRef.current = serializeHistoryDocument(after);
|
|
1044
823
|
isApplyingHistoryRef.current = false;
|
|
1045
824
|
setSlides(nextSlides);
|
|
1046
825
|
onDirtyRef.current?.();
|
|
1047
|
-
updateHistoryAvailability();
|
|
1048
826
|
};
|
|
1049
827
|
const holdTracking = useCallback((held) => {
|
|
1050
828
|
trackingHeldRef.current = held;
|
|
@@ -1052,10 +830,10 @@ function useEditorHistory(input) {
|
|
|
1052
830
|
return {
|
|
1053
831
|
commitSlides,
|
|
1054
832
|
holdTracking,
|
|
1055
|
-
canUndo,
|
|
1056
|
-
canRedo,
|
|
1057
|
-
undoLabel,
|
|
1058
|
-
redoLabel,
|
|
833
|
+
canUndo: historyState.canUndo,
|
|
834
|
+
canRedo: historyState.canRedo,
|
|
835
|
+
undoLabel: historyState.undoLabel,
|
|
836
|
+
redoLabel: historyState.redoLabel,
|
|
1059
837
|
handleUndo,
|
|
1060
838
|
handleRedo,
|
|
1061
839
|
resetHistory,
|
|
@@ -2198,9 +1976,6 @@ function executeSlideTransition(nextSlideIndex, deps) {
|
|
|
2198
1976
|
}
|
|
2199
1977
|
|
|
2200
1978
|
// src/viewer/hooks/presentation-mode/useSlideNavigation.ts
|
|
2201
|
-
function isClickAdvanceBlocked(slide, direction, trigger) {
|
|
2202
|
-
return trigger === "click" && direction === 1 && slide?.transition?.advanceOnClick === false;
|
|
2203
|
-
}
|
|
2204
1979
|
function useSlideNavigation(input) {
|
|
2205
1980
|
const {
|
|
2206
1981
|
slides,
|
|
@@ -2250,50 +2025,71 @@ function useSlideNavigation(input) {
|
|
|
2250
2025
|
);
|
|
2251
2026
|
const movePresentationSlide = useCallback(
|
|
2252
2027
|
(direction, trigger = "explicit") => {
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
}
|
|
2256
|
-
|
|
2028
|
+
const showOrder = visibleSlideIndexes.length > 0 ? visibleSlideIndexes : slides.map((_slide, slideIndex) => slideIndex);
|
|
2029
|
+
const current = presentationSlideIndex;
|
|
2030
|
+
const transitionTo = (index, options = {}) => executeSlideTransition(index, {
|
|
2031
|
+
slides,
|
|
2032
|
+
currentSlideIndex: current,
|
|
2033
|
+
onPlayActionSound,
|
|
2034
|
+
onStopActionSound,
|
|
2035
|
+
setPresentationSlideVisible,
|
|
2036
|
+
clearPresentationTimers,
|
|
2037
|
+
setPresentationSlideIndex,
|
|
2038
|
+
onSetActiveSlideIndex,
|
|
2039
|
+
seedSlideAnimations,
|
|
2040
|
+
startSlideAnimations,
|
|
2041
|
+
scheduleAutoAdvanceForSlide: rehearsing ? void 0 : scheduleAutoAdvanceForSlide,
|
|
2042
|
+
presentationTimersRef,
|
|
2043
|
+
setTransitionOverlay,
|
|
2044
|
+
// PowerPoint plays a slide's transition only when advancing into it,
|
|
2045
|
+
// and replays the LEAVING slide's transition in reverse when stepping
|
|
2046
|
+
// back (a morph glides its shapes back to where they came from).
|
|
2047
|
+
playTransition: true,
|
|
2048
|
+
...options
|
|
2049
|
+
});
|
|
2050
|
+
if (direction === -1) {
|
|
2051
|
+
const step2 = resolveShowBackward({
|
|
2052
|
+
currentIndex: current,
|
|
2053
|
+
showOrder,
|
|
2054
|
+
endOfShow: false,
|
|
2055
|
+
seededCompleted: false
|
|
2056
|
+
});
|
|
2057
|
+
if (step2.kind === "go") {
|
|
2058
|
+
transitionTo(step2.index, { reverse: true, seedCompleted: true });
|
|
2059
|
+
}
|
|
2257
2060
|
return;
|
|
2258
2061
|
}
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
)
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
clearPresentationTimers,
|
|
2275
|
-
setPresentationSlideIndex,
|
|
2276
|
-
onSetActiveSlideIndex,
|
|
2277
|
-
seedSlideAnimations,
|
|
2278
|
-
startSlideAnimations,
|
|
2062
|
+
const step = resolveShowForward({
|
|
2063
|
+
currentIndex: current,
|
|
2064
|
+
currentSlide: slides[current],
|
|
2065
|
+
showOrder,
|
|
2066
|
+
endOfShow: false,
|
|
2067
|
+
fromClick: trigger === "click",
|
|
2068
|
+
loop: Boolean(loopContinuously) && !rehearsing,
|
|
2069
|
+
endWithBlackSlide: true,
|
|
2070
|
+
zoomExcursion: zoomExcursionRef.current,
|
|
2071
|
+
advanceBuild: playNextAnimationGroup
|
|
2072
|
+
});
|
|
2073
|
+
if (step.kind === "go") {
|
|
2074
|
+
if (step.zoomReturn) {
|
|
2075
|
+
zoomExcursionRef.current = step.zoomReturn.excursion;
|
|
2076
|
+
transitionTo(step.index, {
|
|
2279
2077
|
scheduleAutoAdvanceForSlide,
|
|
2280
|
-
|
|
2281
|
-
setTransitionOverlay,
|
|
2282
|
-
playTransition: true,
|
|
2283
|
-
transitionOverride: buildZoomTransitionOverride(
|
|
2284
|
-
consumedExcursion?.transitionDurationMs
|
|
2285
|
-
)
|
|
2078
|
+
transitionOverride: step.zoomReturn.transitionOverride
|
|
2286
2079
|
});
|
|
2287
2080
|
return;
|
|
2288
2081
|
}
|
|
2082
|
+
if (rehearsing) {
|
|
2083
|
+
recordCurrentSlideTime(current);
|
|
2084
|
+
}
|
|
2085
|
+
transitionTo(step.index);
|
|
2086
|
+
return;
|
|
2289
2087
|
}
|
|
2290
|
-
|
|
2291
|
-
if (availableSlideIndexes.length === 0) {
|
|
2088
|
+
if (step.kind !== "end-screen" && step.kind !== "exit") {
|
|
2292
2089
|
return;
|
|
2293
2090
|
}
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
recordCurrentSlideTime(presentationSlideIndex);
|
|
2091
|
+
if (rehearsing) {
|
|
2092
|
+
recordCurrentSlideTime(current);
|
|
2297
2093
|
try {
|
|
2298
2094
|
if (document.fullscreenElement) {
|
|
2299
2095
|
void document.exitFullscreen().catch(() => {
|
|
@@ -2305,41 +2101,7 @@ function useSlideNavigation(input) {
|
|
|
2305
2101
|
setShowRehearsalSummary(true);
|
|
2306
2102
|
return;
|
|
2307
2103
|
}
|
|
2308
|
-
|
|
2309
|
-
onAdvancePastLastSlide();
|
|
2310
|
-
return;
|
|
2311
|
-
}
|
|
2312
|
-
const nextSlideIndex = direction === 1 ? nextShowSlideIndex(presentationSlideIndex, availableSlideIndexes, {
|
|
2313
|
-
loop: Boolean(loopContinuously) && !rehearsing
|
|
2314
|
-
}) : previousShowSlideIndex(presentationSlideIndex, availableSlideIndexes);
|
|
2315
|
-
if (nextSlideIndex === void 0 || nextSlideIndex === presentationSlideIndex) {
|
|
2316
|
-
return;
|
|
2317
|
-
}
|
|
2318
|
-
if (rehearsing && direction === 1) {
|
|
2319
|
-
recordCurrentSlideTime(presentationSlideIndex);
|
|
2320
|
-
}
|
|
2321
|
-
executeSlideTransition(nextSlideIndex, {
|
|
2322
|
-
slides,
|
|
2323
|
-
currentSlideIndex: presentationSlideIndex,
|
|
2324
|
-
onPlayActionSound,
|
|
2325
|
-
onStopActionSound,
|
|
2326
|
-
setPresentationSlideVisible,
|
|
2327
|
-
clearPresentationTimers,
|
|
2328
|
-
setPresentationSlideIndex,
|
|
2329
|
-
onSetActiveSlideIndex,
|
|
2330
|
-
seedSlideAnimations,
|
|
2331
|
-
startSlideAnimations,
|
|
2332
|
-
scheduleAutoAdvanceForSlide: rehearsing ? void 0 : scheduleAutoAdvanceForSlide,
|
|
2333
|
-
presentationTimersRef,
|
|
2334
|
-
setTransitionOverlay,
|
|
2335
|
-
// PowerPoint plays a slide's transition only when advancing into it,
|
|
2336
|
-
// and replays the LEAVING slide's transition in reverse when stepping
|
|
2337
|
-
// back (a morph glides its shapes back to where they came from).
|
|
2338
|
-
playTransition: true,
|
|
2339
|
-
reverse: direction === -1,
|
|
2340
|
-
// Stepping back onto a slide shows it with its builds already played.
|
|
2341
|
-
seedCompleted: direction === -1
|
|
2342
|
-
});
|
|
2104
|
+
onAdvancePastLastSlide?.();
|
|
2343
2105
|
},
|
|
2344
2106
|
[
|
|
2345
2107
|
clearPresentationTimers,
|
|
@@ -4199,6 +3961,7 @@ function useViewerCoreState(_input) {
|
|
|
4199
3961
|
const marqueeStateRef = useRef(null);
|
|
4200
3962
|
const isDrawingRef = useRef(false);
|
|
4201
3963
|
const justInteractedRef = useRef(false);
|
|
3964
|
+
const gestureControllerRef = useRef(null);
|
|
4202
3965
|
const livePatcher = useMemo(() => createCollaborationLivePatcher(), []);
|
|
4203
3966
|
useEffect(() => () => livePatcher.dispose(), [livePatcher]);
|
|
4204
3967
|
const [mode, setMode] = useState("edit");
|
|
@@ -4215,10 +3978,11 @@ function useViewerCoreState(_input) {
|
|
|
4215
3978
|
const [selectedElementId, setSelectedElementId] = useState(null);
|
|
4216
3979
|
const [selectedElementIds, setSelectedElementIds] = useState([]);
|
|
4217
3980
|
const [isDirty, setIsDirty] = useState(false);
|
|
3981
|
+
const autosaveDraftSinkRef = useRef(null);
|
|
4218
3982
|
const publishInlineText = useCallback(
|
|
4219
3983
|
(elementId, text) => {
|
|
4220
|
-
|
|
4221
|
-
livePatcher,
|
|
3984
|
+
reportInlineTextDraft(
|
|
3985
|
+
{ livePatcher, autosave: autosaveDraftSinkRef.current },
|
|
4222
3986
|
slidesRef.current[activeSlideIndexRef.current],
|
|
4223
3987
|
elementId,
|
|
4224
3988
|
text
|
|
@@ -4284,6 +4048,7 @@ function useViewerCoreState(_input) {
|
|
|
4284
4048
|
imageInputRef,
|
|
4285
4049
|
mediaInputRef,
|
|
4286
4050
|
activeSlideIndexRef,
|
|
4051
|
+
autosaveDraftSinkRef,
|
|
4287
4052
|
...inlineEditing,
|
|
4288
4053
|
...editPointsMode,
|
|
4289
4054
|
dragStateRef,
|
|
@@ -4292,6 +4057,7 @@ function useViewerCoreState(_input) {
|
|
|
4292
4057
|
marqueeStateRef,
|
|
4293
4058
|
isDrawingRef,
|
|
4294
4059
|
justInteractedRef,
|
|
4060
|
+
gestureControllerRef,
|
|
4295
4061
|
livePatcher,
|
|
4296
4062
|
mode,
|
|
4297
4063
|
setMode,
|
|
@@ -4778,96 +4544,43 @@ function useLoadContent({
|
|
|
4778
4544
|
return { handlerRef };
|
|
4779
4545
|
}
|
|
4780
4546
|
function useAutosave(input) {
|
|
4781
|
-
const { isDirty, filePath,
|
|
4547
|
+
const { isDirty, filePath, enabled = true } = input;
|
|
4782
4548
|
const intervalMs = resolveAutosaveIntervalMs({
|
|
4783
4549
|
hostIntervalMs: input.intervalMs,
|
|
4784
4550
|
optionsIntervalSeconds: input.intervalSeconds
|
|
4785
4551
|
});
|
|
4786
|
-
const
|
|
4787
|
-
|
|
4788
|
-
|
|
4789
|
-
|
|
4790
|
-
|
|
4791
|
-
|
|
4792
|
-
|
|
4793
|
-
|
|
4794
|
-
|
|
4795
|
-
|
|
4796
|
-
|
|
4797
|
-
|
|
4798
|
-
|
|
4799
|
-
|
|
4800
|
-
|
|
4801
|
-
|
|
4802
|
-
|
|
4803
|
-
|
|
4804
|
-
|
|
4805
|
-
|
|
4806
|
-
}
|
|
4807
|
-
|
|
4808
|
-
serializeRef.current = serializeSlides;
|
|
4809
|
-
}, [serializeSlides]);
|
|
4552
|
+
const live = useRef(input);
|
|
4553
|
+
live.current = input;
|
|
4554
|
+
const [controller] = useState(
|
|
4555
|
+
() => createAutosaveController({
|
|
4556
|
+
getActivation: () => ({ active: live.current.enabled ?? true }),
|
|
4557
|
+
getFilePath: () => live.current.filePath,
|
|
4558
|
+
getIntervalMs: () => resolveAutosaveIntervalMs({
|
|
4559
|
+
hostIntervalMs: live.current.intervalMs,
|
|
4560
|
+
optionsIntervalSeconds: live.current.intervalSeconds
|
|
4561
|
+
}),
|
|
4562
|
+
serialize: () => live.current.serializeSlides(),
|
|
4563
|
+
getStorage: () => live.current.storage,
|
|
4564
|
+
onSaved: (data) => live.current.onSaved?.(data),
|
|
4565
|
+
writeSnapshot: saveAutosaveSnapshot,
|
|
4566
|
+
// serializeSlides already overlays the live inline draft from its refs.
|
|
4567
|
+
getInlineEditingId: () => live.current.getInlineEditingId?.()
|
|
4568
|
+
})
|
|
4569
|
+
);
|
|
4570
|
+
if (input.inlineDraftSinkRef) {
|
|
4571
|
+
input.inlineDraftSinkRef.current = controller;
|
|
4572
|
+
}
|
|
4573
|
+
const { status } = useController(controller);
|
|
4810
4574
|
useEffect(() => {
|
|
4811
|
-
|
|
4812
|
-
}, [
|
|
4813
|
-
const doAutosave = useCallback(async (options) => {
|
|
4814
|
-
const path = filePathRef.current;
|
|
4815
|
-
if (!path) {
|
|
4816
|
-
return;
|
|
4817
|
-
}
|
|
4818
|
-
const sources = changeSourcesRef.current?.() ?? [];
|
|
4819
|
-
if (!shouldWriteAutosaveSnapshot({
|
|
4820
|
-
filePath: path,
|
|
4821
|
-
isDirty: isDirtyRef.current,
|
|
4822
|
-
saving: isSavingRef.current,
|
|
4823
|
-
sources: options?.polled === true ? sources : [],
|
|
4824
|
-
lastSnapshot: lastSnapshotRef.current
|
|
4825
|
-
})) {
|
|
4826
|
-
return;
|
|
4827
|
-
}
|
|
4828
|
-
isSavingRef.current = true;
|
|
4829
|
-
setAutosaveStatus({ state: "saving" });
|
|
4830
|
-
try {
|
|
4831
|
-
const data = await serializeRef.current();
|
|
4832
|
-
if (!data) {
|
|
4833
|
-
setAutosaveStatus({ state: "idle" });
|
|
4834
|
-
isSavingRef.current = false;
|
|
4835
|
-
return;
|
|
4836
|
-
}
|
|
4837
|
-
await saveAutosaveSnapshot(path, data, storageRef.current);
|
|
4838
|
-
lastSnapshotRef.current = autosaveSnapshotMark(path, sources);
|
|
4839
|
-
setAutosaveStatus({ state: "saved", timestamp: Date.now() });
|
|
4840
|
-
onSavedRef.current?.(data);
|
|
4841
|
-
} catch (err) {
|
|
4842
|
-
setAutosaveStatus({
|
|
4843
|
-
state: "error",
|
|
4844
|
-
message: err instanceof Error ? err.message : "Autosave failed"
|
|
4845
|
-
});
|
|
4846
|
-
} finally {
|
|
4847
|
-
isSavingRef.current = false;
|
|
4848
|
-
}
|
|
4849
|
-
}, []);
|
|
4575
|
+
controller.refresh();
|
|
4576
|
+
}, [controller, enabled, filePath, intervalMs]);
|
|
4850
4577
|
useEffect(() => {
|
|
4851
|
-
|
|
4852
|
-
|
|
4853
|
-
|
|
4854
|
-
}
|
|
4855
|
-
if (!filePath) {
|
|
4856
|
-
setAutosaveStatus({
|
|
4857
|
-
state: "disabled",
|
|
4858
|
-
reason: "no_file_path"
|
|
4859
|
-
});
|
|
4860
|
-
return;
|
|
4861
|
-
}
|
|
4862
|
-
setAutosaveStatus((prev) => prev.state === "disabled" ? { state: "idle" } : prev);
|
|
4863
|
-
const id = setInterval(() => {
|
|
4864
|
-
void doAutosave({ polled: true });
|
|
4865
|
-
}, intervalMs);
|
|
4866
|
-
return () => clearInterval(id);
|
|
4867
|
-
}, [enabled, filePath, intervalMs, doAutosave]);
|
|
4578
|
+
controller.observe(isDirty, live.current.getChangeSources?.() ?? []);
|
|
4579
|
+
});
|
|
4580
|
+
useEffect(() => () => controller.markClean(), [controller]);
|
|
4868
4581
|
return {
|
|
4869
|
-
autosaveStatus,
|
|
4870
|
-
triggerAutosave: () =>
|
|
4582
|
+
autosaveStatus: status,
|
|
4583
|
+
triggerAutosave: () => controller.saveNow()
|
|
4871
4584
|
};
|
|
4872
4585
|
}
|
|
4873
4586
|
|
|
@@ -5382,45 +5095,238 @@ function syncSelectionHandleOverlay(elementNode, elementId, geometry) {
|
|
|
5382
5095
|
}
|
|
5383
5096
|
}
|
|
5384
5097
|
|
|
5385
|
-
// src/viewer/hooks/
|
|
5386
|
-
|
|
5387
|
-
|
|
5388
|
-
|
|
5389
|
-
|
|
5390
|
-
|
|
5098
|
+
// src/viewer/hooks/canvas-gestures.ts
|
|
5099
|
+
var animationFrames = {
|
|
5100
|
+
request: (callback) => requestAnimationFrame(callback),
|
|
5101
|
+
cancel: (handle) => cancelAnimationFrame(handle)
|
|
5102
|
+
};
|
|
5103
|
+
function createCanvasGestures(getInput, frames = animationFrames) {
|
|
5104
|
+
let armed = null;
|
|
5105
|
+
let pending = null;
|
|
5106
|
+
let frameHandle = 0;
|
|
5107
|
+
let lastSnapLinesKey = "";
|
|
5108
|
+
const liveTarget = () => {
|
|
5109
|
+
const { livePatcher, editTemplateMode, activeSlide } = getInput();
|
|
5110
|
+
return livePatcher && !editTemplateMode && livePatcher.isActive() ? { patcher: livePatcher, slideId: activeSlide?.id } : void 0;
|
|
5111
|
+
};
|
|
5112
|
+
function showSnapLines(lines) {
|
|
5113
|
+
const next = lines.map((line) => ({
|
|
5114
|
+
axis: line.axis === "v" ? "x" : "y",
|
|
5115
|
+
position: line.position
|
|
5116
|
+
}));
|
|
5117
|
+
const key = JSON.stringify(next);
|
|
5118
|
+
if (key !== lastSnapLinesKey) {
|
|
5119
|
+
lastSnapLinesKey = key;
|
|
5120
|
+
getInput().setSnapLines(next);
|
|
5121
|
+
}
|
|
5391
5122
|
}
|
|
5392
|
-
|
|
5393
|
-
|
|
5394
|
-
|
|
5123
|
+
function paintMove(drag, transform) {
|
|
5124
|
+
const start = drag.startPositionsById[transform.id];
|
|
5125
|
+
if (!start) {
|
|
5126
|
+
return;
|
|
5127
|
+
}
|
|
5128
|
+
drag.lastDx = transform.x - start.x;
|
|
5129
|
+
drag.lastDy = transform.y - start.y;
|
|
5130
|
+
const live = liveTarget();
|
|
5131
|
+
for (const [id, from] of Object.entries(drag.startPositionsById)) {
|
|
5132
|
+
const x = from.x + drag.lastDx;
|
|
5133
|
+
const y = from.y + drag.lastDy;
|
|
5134
|
+
const domEl = drag.domEls.get(id);
|
|
5135
|
+
if (domEl) {
|
|
5136
|
+
domEl.style.left = `${x}px`;
|
|
5137
|
+
domEl.style.top = `${y}px`;
|
|
5138
|
+
syncSelectionHandleOverlay(domEl, id, { x, y });
|
|
5139
|
+
}
|
|
5140
|
+
if (live) {
|
|
5141
|
+
publishLiveGeometry(live.patcher, live.slideId, id, { x, y });
|
|
5142
|
+
}
|
|
5143
|
+
}
|
|
5144
|
+
}
|
|
5145
|
+
function paintResize(resize, transform) {
|
|
5146
|
+
const { x, y } = transform;
|
|
5147
|
+
const width = Math.max(transform.width, MIN_ELEMENT_SIZE);
|
|
5148
|
+
const height = Math.max(transform.height, MIN_ELEMENT_SIZE);
|
|
5149
|
+
resize.lastX = x;
|
|
5150
|
+
resize.lastY = y;
|
|
5151
|
+
resize.lastWidth = transform.width;
|
|
5152
|
+
resize.lastHeight = transform.height;
|
|
5153
|
+
if (resize.domEl) {
|
|
5154
|
+
Object.assign(resize.domEl.style, {
|
|
5155
|
+
left: `${x}px`,
|
|
5156
|
+
top: `${y}px`,
|
|
5157
|
+
width: `${width}px`,
|
|
5158
|
+
height: `${height}px`
|
|
5159
|
+
});
|
|
5160
|
+
syncSelectionHandleOverlay(resize.domEl, resize.elementId, { x, y, width, height });
|
|
5161
|
+
}
|
|
5162
|
+
const live = liveTarget();
|
|
5163
|
+
if (live) {
|
|
5164
|
+
publishLiveGeometry(live.patcher, live.slideId, resize.elementId, { x, y, width, height });
|
|
5165
|
+
}
|
|
5395
5166
|
}
|
|
5396
|
-
|
|
5167
|
+
function paintPending() {
|
|
5168
|
+
const frame = pending;
|
|
5169
|
+
pending = null;
|
|
5170
|
+
frameHandle = 0;
|
|
5171
|
+
if (!frame || !armed) {
|
|
5172
|
+
return;
|
|
5173
|
+
}
|
|
5174
|
+
if (armed.kind === "move") {
|
|
5175
|
+
armed.drag.moved = true;
|
|
5176
|
+
showSnapLines(frame.lines);
|
|
5177
|
+
paintMove(armed.drag, frame.transform);
|
|
5178
|
+
} else {
|
|
5179
|
+
armed.resize.moved = true;
|
|
5180
|
+
paintResize(armed.resize, frame.transform);
|
|
5181
|
+
}
|
|
5182
|
+
}
|
|
5183
|
+
function flushFrame() {
|
|
5184
|
+
if (frameHandle !== 0) {
|
|
5185
|
+
frames.cancel(frameHandle);
|
|
5186
|
+
}
|
|
5187
|
+
paintPending();
|
|
5188
|
+
}
|
|
5189
|
+
const controller = createGestureController({
|
|
5190
|
+
getScale: () => getInput().editorScale,
|
|
5191
|
+
// Axis-aligned, as the canvas has always moved and resized (no rotation).
|
|
5192
|
+
getElementBox: (id) => {
|
|
5193
|
+
const el = getInput().elementLookup.get(id);
|
|
5194
|
+
return el ? { x: el.x, y: el.y, width: el.width, height: el.height } : void 0;
|
|
5195
|
+
},
|
|
5196
|
+
getSiblings: () => {
|
|
5197
|
+
const { editTemplateMode, templateElements, activeSlide } = getInput();
|
|
5198
|
+
const source = editTemplateMode ? templateElements : activeSlide?.elements ?? [];
|
|
5199
|
+
return source.map(({ id, x, y, width, height }) => ({ id, x, y, width, height }));
|
|
5200
|
+
},
|
|
5201
|
+
getSnapToGrid: () => getInput().snapToGrid,
|
|
5202
|
+
getGridSize: () => getInput().gridSpacingPx,
|
|
5203
|
+
getSnapToShape: () => getInput().snapToShape,
|
|
5204
|
+
getGuides: () => getInput().guides.map(({ axis, position }) => ({ axis, position })),
|
|
5205
|
+
getMinSize: () => MIN_ELEMENT_SIZE,
|
|
5206
|
+
getSnapExcludeIds: () => armed?.kind === "move" ? Object.keys(armed.drag.startPositionsById) : [],
|
|
5207
|
+
getStageOrigin: () => {
|
|
5208
|
+
const rect = getInput().canvasStageRef.current?.getBoundingClientRect();
|
|
5209
|
+
return { left: rect?.left ?? 0, top: rect?.top ?? 0 };
|
|
5210
|
+
},
|
|
5211
|
+
onStart: () => void 0,
|
|
5212
|
+
onPreview: (transform, lines) => {
|
|
5213
|
+
pending = { transform, lines };
|
|
5214
|
+
if (frameHandle === 0) {
|
|
5215
|
+
frameHandle = frames.request(paintPending);
|
|
5216
|
+
}
|
|
5217
|
+
},
|
|
5218
|
+
onEnd: (transform, moved) => {
|
|
5219
|
+
flushFrame();
|
|
5220
|
+
const ended = armed;
|
|
5221
|
+
armed = null;
|
|
5222
|
+
if (ended) {
|
|
5223
|
+
finishGesture(ended, moved ? transform : null);
|
|
5224
|
+
}
|
|
5225
|
+
}
|
|
5226
|
+
});
|
|
5227
|
+
function finishGesture(ended, transform) {
|
|
5228
|
+
const input = getInput();
|
|
5229
|
+
if (transform) {
|
|
5230
|
+
if (ended.kind === "move") {
|
|
5231
|
+
commitMove(input, ended.drag);
|
|
5232
|
+
} else {
|
|
5233
|
+
commitResize(input, ended.resize);
|
|
5234
|
+
}
|
|
5235
|
+
input.justInteractedRef.current = true;
|
|
5236
|
+
input.livePatcher?.flush();
|
|
5237
|
+
}
|
|
5238
|
+
input.dragStateRef.current = null;
|
|
5239
|
+
input.resizeStateRef.current = null;
|
|
5240
|
+
lastSnapLinesKey = "";
|
|
5241
|
+
input.setSnapLines([]);
|
|
5242
|
+
if (transform) {
|
|
5243
|
+
input.markDirty();
|
|
5244
|
+
}
|
|
5245
|
+
input.setPointerCommitNonce((n) => n + 1);
|
|
5246
|
+
}
|
|
5247
|
+
return {
|
|
5248
|
+
begin(kind, id, pointer) {
|
|
5249
|
+
if (controller.isActive()) {
|
|
5250
|
+
return;
|
|
5251
|
+
}
|
|
5252
|
+
const input = getInput();
|
|
5253
|
+
const drag = input.dragStateRef.current;
|
|
5254
|
+
const resize = input.resizeStateRef.current;
|
|
5255
|
+
armed = kind === "move" && drag ? { kind, drag } : kind === "resize" && resize ? { kind, resize } : null;
|
|
5256
|
+
if (!armed) {
|
|
5257
|
+
return;
|
|
5258
|
+
}
|
|
5259
|
+
lastSnapLinesKey = "";
|
|
5260
|
+
const handle = armed.kind === "resize" ? armed.resize.handle : void 0;
|
|
5261
|
+
controller.begin(kind, id, pointer, handle);
|
|
5262
|
+
if (!controller.isActive()) {
|
|
5263
|
+
armed = null;
|
|
5264
|
+
}
|
|
5265
|
+
},
|
|
5266
|
+
isActive: () => controller.isActive(),
|
|
5267
|
+
dispose: () => {
|
|
5268
|
+
if (frameHandle !== 0) {
|
|
5269
|
+
frames.cancel(frameHandle);
|
|
5270
|
+
frameHandle = 0;
|
|
5271
|
+
}
|
|
5272
|
+
pending = null;
|
|
5273
|
+
armed = null;
|
|
5274
|
+
controller.dispose();
|
|
5275
|
+
}
|
|
5276
|
+
};
|
|
5397
5277
|
}
|
|
5398
|
-
function
|
|
5399
|
-
const {
|
|
5400
|
-
|
|
5401
|
-
|
|
5278
|
+
function commitMove(input, drag) {
|
|
5279
|
+
const { lastDx: dx, lastDy: dy } = drag;
|
|
5280
|
+
const movedIds = new Set(Object.keys(drag.startPositionsById));
|
|
5281
|
+
const moveElements = (elements) => {
|
|
5282
|
+
const moved = elements.map((el) => {
|
|
5283
|
+
const start = drag.startPositionsById[el.id];
|
|
5284
|
+
return start ? { ...el, x: start.x + dx, y: start.y + dy } : el;
|
|
5285
|
+
});
|
|
5286
|
+
return applyReroutedConnectors(moved, rerouteConnectorsForMovedElements(moved, movedIds));
|
|
5287
|
+
};
|
|
5288
|
+
if (input.editTemplateMode) {
|
|
5289
|
+
const slideId = input.activeSlide?.id;
|
|
5290
|
+
if (slideId) {
|
|
5291
|
+
input.setTemplateElementsBySlideId((prev) => ({
|
|
5292
|
+
...prev,
|
|
5293
|
+
[slideId]: moveElements(prev[slideId] ?? [])
|
|
5294
|
+
}));
|
|
5295
|
+
}
|
|
5296
|
+
return;
|
|
5402
5297
|
}
|
|
5403
|
-
|
|
5298
|
+
input.updateSlides(
|
|
5299
|
+
(prev) => prev.map(
|
|
5300
|
+
(s, i) => i !== input.activeSlideIndex ? s : { ...s, elements: moveElements(s.elements) }
|
|
5301
|
+
)
|
|
5302
|
+
);
|
|
5404
5303
|
}
|
|
5405
|
-
function
|
|
5304
|
+
function commitResize(input, resize) {
|
|
5305
|
+
input.updateElementById(resize.elementId, {
|
|
5306
|
+
x: resize.lastX,
|
|
5307
|
+
y: resize.lastY,
|
|
5308
|
+
width: resize.lastWidth,
|
|
5309
|
+
height: resize.lastHeight
|
|
5310
|
+
});
|
|
5311
|
+
const movedIds = /* @__PURE__ */ new Set([resize.elementId]);
|
|
5312
|
+
input.updateSlides(
|
|
5313
|
+
(prev) => prev.map((s, i) => {
|
|
5314
|
+
if (i !== input.activeSlideIndex) {
|
|
5315
|
+
return s;
|
|
5316
|
+
}
|
|
5317
|
+
const rerouted = rerouteConnectorsForMovedElements(s.elements, movedIds);
|
|
5318
|
+
return rerouted.length === 0 ? s : { ...s, elements: applyReroutedConnectors(s.elements, rerouted) };
|
|
5319
|
+
})
|
|
5320
|
+
);
|
|
5321
|
+
}
|
|
5322
|
+
function processPointerMove(e, input) {
|
|
5406
5323
|
const {
|
|
5407
5324
|
editorScale,
|
|
5408
5325
|
canvasStageRef,
|
|
5409
5326
|
canvasSize,
|
|
5410
|
-
snapToGrid,
|
|
5411
|
-
snapToShape,
|
|
5412
|
-
gridSpacingPx,
|
|
5413
|
-
editTemplateMode,
|
|
5414
|
-
templateElements,
|
|
5415
|
-
activeSlide,
|
|
5416
|
-
guides,
|
|
5417
|
-
elementLookup,
|
|
5418
5327
|
marqueeStateRef,
|
|
5419
|
-
dragStateRef,
|
|
5420
|
-
resizeStateRef,
|
|
5421
5328
|
shapeAdjustmentDragStateRef,
|
|
5422
5329
|
setMarqueeSelectionState,
|
|
5423
|
-
setSnapLines,
|
|
5424
5330
|
updateElementById
|
|
5425
5331
|
} = input;
|
|
5426
5332
|
const marquee = marqueeStateRef.current;
|
|
@@ -5435,31 +5341,6 @@ function processPointerMove(e, input, tracker) {
|
|
|
5435
5341
|
);
|
|
5436
5342
|
return;
|
|
5437
5343
|
}
|
|
5438
|
-
const drag = dragStateRef.current;
|
|
5439
|
-
if (drag) {
|
|
5440
|
-
processDragMove(
|
|
5441
|
-
e,
|
|
5442
|
-
drag,
|
|
5443
|
-
editorScale,
|
|
5444
|
-
snapToGrid,
|
|
5445
|
-
snapToShape,
|
|
5446
|
-
gridSpacingPx,
|
|
5447
|
-
editTemplateMode,
|
|
5448
|
-
templateElements,
|
|
5449
|
-
activeSlide,
|
|
5450
|
-
guides,
|
|
5451
|
-
elementLookup,
|
|
5452
|
-
tracker,
|
|
5453
|
-
setSnapLines,
|
|
5454
|
-
resolveLiveTarget(input)
|
|
5455
|
-
);
|
|
5456
|
-
return;
|
|
5457
|
-
}
|
|
5458
|
-
const rs = resizeStateRef.current;
|
|
5459
|
-
if (rs) {
|
|
5460
|
-
processResizeMove(e, rs, editorScale, snapToGrid, gridSpacingPx, resolveLiveTarget(input));
|
|
5461
|
-
return;
|
|
5462
|
-
}
|
|
5463
5344
|
const adj = shapeAdjustmentDragStateRef.current;
|
|
5464
5345
|
if (adj) {
|
|
5465
5346
|
processAdjustmentMove(e, adj, editorScale, updateElementById);
|
|
@@ -5475,129 +5356,6 @@ function processMarqueeMove(e, marquee, canvasStageRef, canvasSize, editorScale,
|
|
|
5475
5356
|
marquee.currentY = Math.max(0, Math.min(canvasSize.height, (e.clientY - rect.top) / editorScale));
|
|
5476
5357
|
setMarqueeSelectionState({ ...marquee });
|
|
5477
5358
|
}
|
|
5478
|
-
function processDragMove(e, drag, editorScale, snapToGrid, snapToShape, gridSpacingPx, editTemplateMode, templateElements, activeSlide, guides, elementLookup, tracker, setSnapLines, live) {
|
|
5479
|
-
const dx = (e.clientX - drag.startClientX) / editorScale;
|
|
5480
|
-
const dy = (e.clientY - drag.startClientY) / editorScale;
|
|
5481
|
-
if (!drag.moved && (Math.abs(dx) > 2 || Math.abs(dy) > 2)) {
|
|
5482
|
-
drag.moved = true;
|
|
5483
|
-
}
|
|
5484
|
-
if (!drag.moved) {
|
|
5485
|
-
return;
|
|
5486
|
-
}
|
|
5487
|
-
let appliedDx = dx;
|
|
5488
|
-
let appliedDy = dy;
|
|
5489
|
-
const draggedIds = Object.keys(drag.startPositionsById);
|
|
5490
|
-
const primaryId = draggedIds[0];
|
|
5491
|
-
const primaryStart = primaryId ? drag.startPositionsById[primaryId] : void 0;
|
|
5492
|
-
const primaryEl = primaryId ? elementLookup.get(primaryId) : void 0;
|
|
5493
|
-
if (primaryStart && primaryEl) {
|
|
5494
|
-
let targetX = primaryStart.x + appliedDx;
|
|
5495
|
-
let targetY = primaryStart.y + appliedDy;
|
|
5496
|
-
if (snapToGrid) {
|
|
5497
|
-
targetX = Math.round(targetX / gridSpacingPx) * gridSpacingPx;
|
|
5498
|
-
targetY = Math.round(targetY / gridSpacingPx) * gridSpacingPx;
|
|
5499
|
-
}
|
|
5500
|
-
if (snapToShape) {
|
|
5501
|
-
const siblingSource = editTemplateMode ? templateElements : activeSlide?.elements ?? [];
|
|
5502
|
-
const siblings = siblingSource.map((el) => ({
|
|
5503
|
-
id: el.id,
|
|
5504
|
-
x: el.x,
|
|
5505
|
-
y: el.y,
|
|
5506
|
-
width: el.width,
|
|
5507
|
-
height: el.height
|
|
5508
|
-
}));
|
|
5509
|
-
const snapResult = computeSnapToShape(
|
|
5510
|
-
targetX,
|
|
5511
|
-
targetY,
|
|
5512
|
-
primaryEl.width,
|
|
5513
|
-
primaryEl.height,
|
|
5514
|
-
siblings,
|
|
5515
|
-
new Set(draggedIds),
|
|
5516
|
-
guides.map((g) => ({ axis: g.axis, position: g.position }))
|
|
5517
|
-
);
|
|
5518
|
-
targetX = snapResult.x;
|
|
5519
|
-
targetY = snapResult.y;
|
|
5520
|
-
const newSnapLines = snapResult.lines.map((line) => ({
|
|
5521
|
-
axis: line.axis === "v" ? "x" : "y",
|
|
5522
|
-
position: line.position
|
|
5523
|
-
}));
|
|
5524
|
-
const newKey = JSON.stringify(newSnapLines);
|
|
5525
|
-
if (newKey !== tracker.lastSnapLinesKey) {
|
|
5526
|
-
tracker.lastSnapLinesKey = newKey;
|
|
5527
|
-
setSnapLines(newSnapLines);
|
|
5528
|
-
}
|
|
5529
|
-
} else if (tracker.lastSnapLinesKey !== "[]") {
|
|
5530
|
-
tracker.lastSnapLinesKey = "[]";
|
|
5531
|
-
setSnapLines([]);
|
|
5532
|
-
}
|
|
5533
|
-
appliedDx = targetX - primaryStart.x;
|
|
5534
|
-
appliedDy = targetY - primaryStart.y;
|
|
5535
|
-
}
|
|
5536
|
-
drag.lastDx = appliedDx;
|
|
5537
|
-
drag.lastDy = appliedDy;
|
|
5538
|
-
for (const [id, domEl] of drag.domEls) {
|
|
5539
|
-
const start = drag.startPositionsById[id];
|
|
5540
|
-
if (start) {
|
|
5541
|
-
const x = start.x + appliedDx;
|
|
5542
|
-
const y = start.y + appliedDy;
|
|
5543
|
-
domEl.style.left = `${x}px`;
|
|
5544
|
-
domEl.style.top = `${y}px`;
|
|
5545
|
-
syncSelectionHandleOverlay(domEl, id, { x, y });
|
|
5546
|
-
}
|
|
5547
|
-
}
|
|
5548
|
-
if (live) {
|
|
5549
|
-
for (const id of Object.keys(drag.startPositionsById)) {
|
|
5550
|
-
const start = drag.startPositionsById[id];
|
|
5551
|
-
publishLiveGeometry(live.patcher, live.slideId, id, {
|
|
5552
|
-
x: start.x + appliedDx,
|
|
5553
|
-
y: start.y + appliedDy
|
|
5554
|
-
});
|
|
5555
|
-
}
|
|
5556
|
-
}
|
|
5557
|
-
}
|
|
5558
|
-
function processResizeMove(e, rs, editorScale, snapToGrid, gridSpacingPx, live) {
|
|
5559
|
-
const dx = (e.clientX - rs.startClientX) / editorScale;
|
|
5560
|
-
const dy = (e.clientY - rs.startClientY) / editorScale;
|
|
5561
|
-
if (!rs.moved && (Math.abs(dx) > 2 || Math.abs(dy) > 2)) {
|
|
5562
|
-
rs.moved = true;
|
|
5563
|
-
}
|
|
5564
|
-
if (!rs.moved) {
|
|
5565
|
-
return;
|
|
5566
|
-
}
|
|
5567
|
-
const geo = computeResizeGeometry(
|
|
5568
|
-
rs.handle,
|
|
5569
|
-
rs.startX,
|
|
5570
|
-
rs.startY,
|
|
5571
|
-
rs.startWidth,
|
|
5572
|
-
rs.startHeight,
|
|
5573
|
-
dx,
|
|
5574
|
-
dy,
|
|
5575
|
-
snapToGrid,
|
|
5576
|
-
gridSpacingPx,
|
|
5577
|
-
e.shiftKey
|
|
5578
|
-
);
|
|
5579
|
-
rs.lastX = geo.x;
|
|
5580
|
-
rs.lastY = geo.y;
|
|
5581
|
-
rs.lastWidth = geo.width;
|
|
5582
|
-
rs.lastHeight = geo.height;
|
|
5583
|
-
const width = Math.max(geo.width, MIN_ELEMENT_SIZE);
|
|
5584
|
-
const height = Math.max(geo.height, MIN_ELEMENT_SIZE);
|
|
5585
|
-
if (rs.domEl) {
|
|
5586
|
-
rs.domEl.style.left = `${geo.x}px`;
|
|
5587
|
-
rs.domEl.style.top = `${geo.y}px`;
|
|
5588
|
-
rs.domEl.style.width = `${width}px`;
|
|
5589
|
-
rs.domEl.style.height = `${height}px`;
|
|
5590
|
-
syncSelectionHandleOverlay(rs.domEl, rs.elementId, { x: geo.x, y: geo.y, width, height });
|
|
5591
|
-
}
|
|
5592
|
-
if (live) {
|
|
5593
|
-
publishLiveGeometry(live.patcher, live.slideId, rs.elementId, {
|
|
5594
|
-
x: geo.x,
|
|
5595
|
-
y: geo.y,
|
|
5596
|
-
width,
|
|
5597
|
-
height
|
|
5598
|
-
});
|
|
5599
|
-
}
|
|
5600
|
-
}
|
|
5601
5359
|
function processAdjustmentMove(e, adj, editorScale, updateElementById) {
|
|
5602
5360
|
const dx = (e.clientX - adj.startClientX) / editorScale;
|
|
5603
5361
|
const dy = (e.clientY - adj.startClientY) / editorScale;
|
|
@@ -5616,26 +5374,20 @@ function processPointerUp(input) {
|
|
|
5616
5374
|
editTemplateMode,
|
|
5617
5375
|
templateElements,
|
|
5618
5376
|
activeSlide,
|
|
5619
|
-
activeSlideIndex,
|
|
5620
5377
|
marqueeStateRef,
|
|
5621
5378
|
dragStateRef,
|
|
5622
5379
|
resizeStateRef,
|
|
5623
5380
|
shapeAdjustmentDragStateRef,
|
|
5624
5381
|
justInteractedRef,
|
|
5382
|
+
gestureRef,
|
|
5625
5383
|
setMarqueeSelectionState,
|
|
5626
|
-
setSnapLines,
|
|
5627
|
-
setTemplateElementsBySlideId,
|
|
5628
5384
|
setPointerCommitNonce,
|
|
5629
5385
|
applySelection,
|
|
5630
5386
|
clearSelection,
|
|
5631
|
-
updateSlides,
|
|
5632
|
-
updateElementById,
|
|
5633
5387
|
markDirty,
|
|
5634
5388
|
livePatcher
|
|
5635
5389
|
} = input;
|
|
5636
5390
|
const marquee = marqueeStateRef.current;
|
|
5637
|
-
const drag = dragStateRef.current;
|
|
5638
|
-
const rs = resizeStateRef.current;
|
|
5639
5391
|
const adj = shapeAdjustmentDragStateRef.current;
|
|
5640
5392
|
if (marquee) {
|
|
5641
5393
|
commitMarquee(
|
|
@@ -5646,62 +5398,22 @@ function processPointerUp(input) {
|
|
|
5646
5398
|
applySelection,
|
|
5647
5399
|
clearSelection
|
|
5648
5400
|
);
|
|
5649
|
-
marqueeStateRef.current = null;
|
|
5650
|
-
setMarqueeSelectionState(null);
|
|
5651
5401
|
}
|
|
5652
|
-
if (
|
|
5653
|
-
|
|
5654
|
-
|
|
5655
|
-
editTemplateMode,
|
|
5656
|
-
activeSlide,
|
|
5657
|
-
activeSlideIndex,
|
|
5658
|
-
setTemplateElementsBySlideId,
|
|
5659
|
-
updateSlides
|
|
5660
|
-
);
|
|
5402
|
+
if (!gestureRef?.current?.isActive()) {
|
|
5403
|
+
dragStateRef.current = null;
|
|
5404
|
+
resizeStateRef.current = null;
|
|
5661
5405
|
}
|
|
5662
|
-
if (
|
|
5663
|
-
const resizedId = rs.elementId;
|
|
5664
|
-
const resizeUpdates = {
|
|
5665
|
-
x: rs.lastX,
|
|
5666
|
-
y: rs.lastY,
|
|
5667
|
-
width: rs.lastWidth,
|
|
5668
|
-
height: rs.lastHeight
|
|
5669
|
-
};
|
|
5670
|
-
updateElementById(resizedId, resizeUpdates);
|
|
5671
|
-
const movedIds = /* @__PURE__ */ new Set([resizedId]);
|
|
5672
|
-
updateSlides(
|
|
5673
|
-
(prev) => prev.map((s, i) => {
|
|
5674
|
-
if (i !== activeSlideIndex) {
|
|
5675
|
-
return s;
|
|
5676
|
-
}
|
|
5677
|
-
const rerouted = rerouteConnectorsForMovedElements(s.elements, movedIds);
|
|
5678
|
-
if (rerouted.length === 0) {
|
|
5679
|
-
return s;
|
|
5680
|
-
}
|
|
5681
|
-
return {
|
|
5682
|
-
...s,
|
|
5683
|
-
elements: applyReroutedConnectors(s.elements, rerouted)
|
|
5684
|
-
};
|
|
5685
|
-
})
|
|
5686
|
-
);
|
|
5687
|
-
}
|
|
5688
|
-
const wasMoved = drag?.moved || rs?.moved || adj?.moved;
|
|
5689
|
-
if (wasMoved) {
|
|
5406
|
+
if (adj?.moved) {
|
|
5690
5407
|
justInteractedRef.current = true;
|
|
5691
|
-
}
|
|
5692
|
-
if (wasMoved) {
|
|
5693
5408
|
livePatcher?.flush();
|
|
5694
5409
|
}
|
|
5695
5410
|
marqueeStateRef.current = null;
|
|
5696
|
-
dragStateRef.current = null;
|
|
5697
|
-
resizeStateRef.current = null;
|
|
5698
5411
|
shapeAdjustmentDragStateRef.current = null;
|
|
5699
5412
|
setMarqueeSelectionState(null);
|
|
5700
|
-
|
|
5701
|
-
if (wasMoved) {
|
|
5413
|
+
if (adj?.moved) {
|
|
5702
5414
|
markDirty();
|
|
5703
5415
|
}
|
|
5704
|
-
if (
|
|
5416
|
+
if (adj || marquee) {
|
|
5705
5417
|
setPointerCommitNonce((n) => n + 1);
|
|
5706
5418
|
}
|
|
5707
5419
|
}
|
|
@@ -5721,35 +5433,6 @@ function commitMarquee(marquee, editTemplateMode, templateElements, activeSlide,
|
|
|
5721
5433
|
clearSelection();
|
|
5722
5434
|
}
|
|
5723
5435
|
}
|
|
5724
|
-
function commitDrag(drag, editTemplateMode, activeSlide, activeSlideIndex, setTemplateElementsBySlideId, updateSlides) {
|
|
5725
|
-
const dx = drag.lastDx, dy = drag.lastDy;
|
|
5726
|
-
const movedIds = new Set(Object.keys(drag.startPositionsById));
|
|
5727
|
-
const moveElements = (elements) => {
|
|
5728
|
-
const movedElements = elements.map((el) => {
|
|
5729
|
-
const start = drag.startPositionsById[el.id];
|
|
5730
|
-
if (!start) {
|
|
5731
|
-
return el;
|
|
5732
|
-
}
|
|
5733
|
-
return { ...el, x: start.x + dx, y: start.y + dy };
|
|
5734
|
-
});
|
|
5735
|
-
const rerouted = rerouteConnectorsForMovedElements(movedElements, movedIds);
|
|
5736
|
-
return applyReroutedConnectors(movedElements, rerouted);
|
|
5737
|
-
};
|
|
5738
|
-
if (editTemplateMode) {
|
|
5739
|
-
const slideId = activeSlide?.id;
|
|
5740
|
-
if (!slideId) {
|
|
5741
|
-
return;
|
|
5742
|
-
}
|
|
5743
|
-
setTemplateElementsBySlideId((prev) => ({
|
|
5744
|
-
...prev,
|
|
5745
|
-
[slideId]: moveElements(prev[slideId] ?? [])
|
|
5746
|
-
}));
|
|
5747
|
-
return;
|
|
5748
|
-
}
|
|
5749
|
-
updateSlides(
|
|
5750
|
-
(prev) => prev.map((s, i) => i !== activeSlideIndex ? s : { ...s, elements: moveElements(s.elements) })
|
|
5751
|
-
);
|
|
5752
|
-
}
|
|
5753
5436
|
|
|
5754
5437
|
// src/viewer/hooks/usePointerHandlers.ts
|
|
5755
5438
|
function usePointerHandlers(input) {
|
|
@@ -5759,41 +5442,42 @@ function usePointerHandlers(input) {
|
|
|
5759
5442
|
canvasSize,
|
|
5760
5443
|
activeSlide,
|
|
5761
5444
|
activeSlideIndex,
|
|
5762
|
-
gridSpacingPx,
|
|
5763
|
-
dragStateRef,
|
|
5764
|
-
resizeStateRef,
|
|
5765
5445
|
shapeAdjustmentDragStateRef,
|
|
5766
5446
|
marqueeStateRef,
|
|
5767
5447
|
editTemplateMode,
|
|
5768
|
-
snapToGrid,
|
|
5769
|
-
snapToShape,
|
|
5770
|
-
guides,
|
|
5771
5448
|
templateElements,
|
|
5772
|
-
elementLookup,
|
|
5773
5449
|
setMarqueeSelectionState,
|
|
5774
|
-
setSnapLines,
|
|
5775
|
-
setTemplateElementsBySlideId,
|
|
5776
5450
|
setPointerCommitNonce,
|
|
5777
5451
|
applySelection,
|
|
5778
5452
|
clearSelection,
|
|
5779
|
-
updateSlides,
|
|
5780
5453
|
updateElementById,
|
|
5781
5454
|
markDirty,
|
|
5782
|
-
livePatcher
|
|
5455
|
+
livePatcher,
|
|
5456
|
+
gestureRef
|
|
5783
5457
|
} = input;
|
|
5458
|
+
const inputRef = useRef(input);
|
|
5459
|
+
inputRef.current = input;
|
|
5460
|
+
const gestures = useMemo(() => createCanvasGestures(() => inputRef.current), []);
|
|
5784
5461
|
useEffect(() => {
|
|
5785
|
-
|
|
5786
|
-
|
|
5787
|
-
|
|
5788
|
-
|
|
5462
|
+
if (gestureRef) {
|
|
5463
|
+
gestureRef.current = gestures;
|
|
5464
|
+
}
|
|
5465
|
+
return () => {
|
|
5466
|
+
gestures.dispose();
|
|
5467
|
+
if (gestureRef?.current === gestures) {
|
|
5468
|
+
gestureRef.current = null;
|
|
5469
|
+
}
|
|
5789
5470
|
};
|
|
5471
|
+
}, [gestures, gestureRef]);
|
|
5472
|
+
useEffect(() => {
|
|
5473
|
+
const tracker = { rafId: 0, pendingMoveEvent: null };
|
|
5790
5474
|
const handlePointerMove = (e) => {
|
|
5791
5475
|
tracker.pendingMoveEvent = e;
|
|
5792
5476
|
if (tracker.rafId === 0) {
|
|
5793
5477
|
tracker.rafId = requestAnimationFrame(() => {
|
|
5794
5478
|
tracker.rafId = 0;
|
|
5795
5479
|
if (tracker.pendingMoveEvent) {
|
|
5796
|
-
processPointerMove(tracker.pendingMoveEvent, input
|
|
5480
|
+
processPointerMove(tracker.pendingMoveEvent, input);
|
|
5797
5481
|
tracker.pendingMoveEvent = null;
|
|
5798
5482
|
}
|
|
5799
5483
|
});
|
|
@@ -5821,31 +5505,22 @@ function usePointerHandlers(input) {
|
|
|
5821
5505
|
}, [
|
|
5822
5506
|
editorScale,
|
|
5823
5507
|
canvasStageRef,
|
|
5824
|
-
dragStateRef,
|
|
5825
|
-
resizeStateRef,
|
|
5826
5508
|
shapeAdjustmentDragStateRef,
|
|
5827
5509
|
marqueeStateRef,
|
|
5828
5510
|
editTemplateMode,
|
|
5829
|
-
snapToGrid,
|
|
5830
|
-
snapToShape,
|
|
5831
|
-
guides,
|
|
5832
5511
|
templateElements,
|
|
5833
5512
|
setMarqueeSelectionState,
|
|
5834
|
-
setSnapLines,
|
|
5835
|
-
elementLookup,
|
|
5836
|
-
setTemplateElementsBySlideId,
|
|
5837
5513
|
setPointerCommitNonce,
|
|
5838
5514
|
activeSlide,
|
|
5839
5515
|
activeSlideIndex,
|
|
5840
5516
|
canvasSize.width,
|
|
5841
5517
|
canvasSize.height,
|
|
5842
|
-
gridSpacingPx,
|
|
5843
5518
|
applySelection,
|
|
5844
5519
|
clearSelection,
|
|
5845
|
-
updateSlides,
|
|
5846
5520
|
updateElementById,
|
|
5847
5521
|
markDirty,
|
|
5848
|
-
livePatcher
|
|
5522
|
+
livePatcher,
|
|
5523
|
+
gestureRef
|
|
5849
5524
|
]);
|
|
5850
5525
|
}
|
|
5851
5526
|
function mouseDownStartsSelectionDrag(event) {
|
|
@@ -5871,6 +5546,7 @@ function useCanvasInteractions(input) {
|
|
|
5871
5546
|
shapeAdjustmentDragStateRef,
|
|
5872
5547
|
marqueeStateRef,
|
|
5873
5548
|
justInteractedRef,
|
|
5549
|
+
gestureRef,
|
|
5874
5550
|
setInlineEditingElementId,
|
|
5875
5551
|
setInlineEditingText,
|
|
5876
5552
|
setContextMenuState,
|
|
@@ -5896,25 +5572,7 @@ function useCanvasInteractions(input) {
|
|
|
5896
5572
|
const scale = editorScale || 1;
|
|
5897
5573
|
return rect ? { x: (e.clientX - rect.left) / scale, y: (e.clientY - rect.top) / scale } : null;
|
|
5898
5574
|
};
|
|
5899
|
-
const
|
|
5900
|
-
if (!slideElements) {
|
|
5901
|
-
return null;
|
|
5902
|
-
}
|
|
5903
|
-
const top = slideElements.find((el) => el.id === elementId);
|
|
5904
|
-
const point = slidePoint(e);
|
|
5905
|
-
if (!top || !point || !isEnterableGroup(top)) {
|
|
5906
|
-
return null;
|
|
5907
|
-
}
|
|
5908
|
-
return memberChainAtPoint(slideElements, elementId, point);
|
|
5909
|
-
};
|
|
5910
|
-
const resolvePressTarget = (elementId, e) => {
|
|
5911
|
-
const chain = drillChain(elementId, e);
|
|
5912
|
-
if (!chain || !slideElements) {
|
|
5913
|
-
return elementId;
|
|
5914
|
-
}
|
|
5915
|
-
const selectedPath = selectedElementId ? findElementPath(slideElements, selectedElementId) : null;
|
|
5916
|
-
return drillSelectionForClick(chain, selectedPath) ?? elementId;
|
|
5917
|
-
};
|
|
5575
|
+
const resolvePressTarget = (elementId, e) => slideElements ? resolveGroupPressTarget(slideElements, elementId, slidePoint(e), effectiveSelectedIds) : elementId;
|
|
5918
5576
|
const handleInlineEditCommit = () => {
|
|
5919
5577
|
const editId = inlineEditingElementId;
|
|
5920
5578
|
if (!editId) {
|
|
@@ -6014,9 +5672,7 @@ function useCanvasInteractions(input) {
|
|
|
6014
5672
|
}
|
|
6015
5673
|
};
|
|
6016
5674
|
const handleElementDoubleClick = (pressedId, e) => {
|
|
6017
|
-
const
|
|
6018
|
-
const innermost = chain ? drillSelectionForDoubleClick(chain) : null;
|
|
6019
|
-
const elementId = innermost && canInteractWithElement(elementLookup.get(innermost), "select") ? innermost : pressedId;
|
|
5675
|
+
const elementId = mode === "present" || !slideElements ? pressedId : resolveGroupDoubleClickTarget(slideElements, pressedId, slidePoint(e));
|
|
6020
5676
|
if (elementId !== pressedId) {
|
|
6021
5677
|
ops.applySelection(elementId);
|
|
6022
5678
|
}
|
|
@@ -6079,6 +5735,7 @@ function useCanvasInteractions(input) {
|
|
|
6079
5735
|
lastDy: 0
|
|
6080
5736
|
};
|
|
6081
5737
|
setSnapLines([]);
|
|
5738
|
+
gestureRef?.current?.begin("move", movableIds[0], e);
|
|
6082
5739
|
};
|
|
6083
5740
|
const handleElementContextMenu = (elementId, e) => {
|
|
6084
5741
|
if (mode === "present") {
|
|
@@ -6151,6 +5808,7 @@ function useCanvasInteractions(input) {
|
|
|
6151
5808
|
lastWidth: el.width,
|
|
6152
5809
|
lastHeight: el.height
|
|
6153
5810
|
};
|
|
5811
|
+
gestureRef?.current?.begin("resize", elementId, e);
|
|
6154
5812
|
};
|
|
6155
5813
|
const handleRotate = (elementId, rotationDeg) => {
|
|
6156
5814
|
const el = elementLookup.get(elementId);
|
|
@@ -6656,11 +6314,11 @@ function useInsertElements(input) {
|
|
|
6656
6314
|
id: generateElementId()
|
|
6657
6315
|
});
|
|
6658
6316
|
};
|
|
6659
|
-
const handleAddChart = (chartKind) => {
|
|
6317
|
+
const handleAddChart = (chartKind, options) => {
|
|
6660
6318
|
if (!activeSlide) {
|
|
6661
6319
|
return;
|
|
6662
6320
|
}
|
|
6663
|
-
addElement(createDefaultChartElement(chartKind));
|
|
6321
|
+
addElement(createDefaultChartElement(chartKind, void 0, options));
|
|
6664
6322
|
};
|
|
6665
6323
|
const structured = createStructuredElementHandlers({
|
|
6666
6324
|
activeSlide,
|
|
@@ -9105,6 +8763,7 @@ function useViewerDialogs(input) {
|
|
|
9105
8763
|
embeddedFontFamilies
|
|
9106
8764
|
} = input;
|
|
9107
8765
|
const [isSmartArtDialogOpen, setIsSmartArtDialogOpen] = useState(false);
|
|
8766
|
+
const [isChartDialogOpen, setIsChartDialogOpen] = useState(false);
|
|
9108
8767
|
const [isEquationDialogOpen, setIsEquationDialogOpen] = useState(false);
|
|
9109
8768
|
const [isHyperlinkDialogOpen, setIsHyperlinkDialogOpen] = useState(false);
|
|
9110
8769
|
const [isPasswordDialogOpen, setIsPasswordDialogOpen] = useState(false);
|
|
@@ -9249,6 +8908,8 @@ function useViewerDialogs(input) {
|
|
|
9249
8908
|
return {
|
|
9250
8909
|
isSmartArtDialogOpen,
|
|
9251
8910
|
setIsSmartArtDialogOpen,
|
|
8911
|
+
isChartDialogOpen,
|
|
8912
|
+
setIsChartDialogOpen,
|
|
9252
8913
|
isEquationDialogOpen,
|
|
9253
8914
|
setIsEquationDialogOpen,
|
|
9254
8915
|
isHyperlinkDialogOpen,
|
|
@@ -9694,84 +9355,35 @@ function useSerialize(input) {
|
|
|
9694
9355
|
}
|
|
9695
9356
|
function useRecoveryDetection(input) {
|
|
9696
9357
|
const { filePath, fileName, loading, error, slideCount, autosaveAllowed = true } = input;
|
|
9697
|
-
const
|
|
9698
|
-
|
|
9699
|
-
const
|
|
9700
|
-
|
|
9701
|
-
|
|
9702
|
-
|
|
9703
|
-
|
|
9704
|
-
|
|
9705
|
-
|
|
9706
|
-
|
|
9707
|
-
|
|
9708
|
-
|
|
9709
|
-
|
|
9358
|
+
const live = useRef(input);
|
|
9359
|
+
live.current = input;
|
|
9360
|
+
const [controller] = useState(
|
|
9361
|
+
() => createAutosaveRecoveryController({
|
|
9362
|
+
getStorage: () => live.current.storage,
|
|
9363
|
+
load: (bytes) => live.current.onRestore?.(bytes),
|
|
9364
|
+
onOffered: (record) => {
|
|
9365
|
+
live.current.onOffered?.(record);
|
|
9366
|
+
live.current.openVersionHistory?.();
|
|
9367
|
+
},
|
|
9368
|
+
probe: probeAutosaveRecovery,
|
|
9369
|
+
discardRecord: discardAutosaveRecovery
|
|
9370
|
+
})
|
|
9371
|
+
);
|
|
9372
|
+
const { prompt, discarding } = useController(controller);
|
|
9710
9373
|
useEffect(() => {
|
|
9711
|
-
|
|
9712
|
-
|
|
9713
|
-
|
|
9714
|
-
|
|
9715
|
-
|
|
9716
|
-
|
|
9717
|
-
|
|
9718
|
-
|
|
9719
|
-
|
|
9720
|
-
|
|
9721
|
-
|
|
9722
|
-
void (async () => {
|
|
9723
|
-
const offer = await probeAutosaveRecovery(
|
|
9724
|
-
filePath,
|
|
9725
|
-
Date.now(),
|
|
9726
|
-
fileName,
|
|
9727
|
-
storageRef.current
|
|
9728
|
-
);
|
|
9729
|
-
if (!offer) {
|
|
9730
|
-
return;
|
|
9731
|
-
}
|
|
9732
|
-
recordRef.current = offer.record;
|
|
9733
|
-
setPrompt(offer.prompt);
|
|
9734
|
-
onOfferedRef.current?.(offer.record);
|
|
9735
|
-
openVersionHistory?.();
|
|
9736
|
-
})();
|
|
9737
|
-
}, [filePath, fileName, loading, error, slideCount, autosaveAllowed, openVersionHistory]);
|
|
9738
|
-
const restore = useCallback(() => {
|
|
9739
|
-
if (actionPendingRef.current) {
|
|
9740
|
-
return;
|
|
9741
|
-
}
|
|
9742
|
-
actionPendingRef.current = true;
|
|
9743
|
-
const record = recordRef.current;
|
|
9744
|
-
setPrompt(null);
|
|
9745
|
-
if (record && onRestore) {
|
|
9746
|
-
onRestore(acceptAutosaveRecovery(record));
|
|
9747
|
-
acknowledgeAutosaveRecovery(record);
|
|
9748
|
-
}
|
|
9749
|
-
recordRef.current = null;
|
|
9750
|
-
}, [onRestore]);
|
|
9751
|
-
const discard = useCallback(() => {
|
|
9752
|
-
if (actionPendingRef.current) {
|
|
9753
|
-
return;
|
|
9754
|
-
}
|
|
9755
|
-
const record = recordRef.current;
|
|
9756
|
-
if (!record) {
|
|
9757
|
-
setPrompt(null);
|
|
9758
|
-
return;
|
|
9374
|
+
controller.check({ filePath, fileName, loading, error, slideCount, autosaveAllowed });
|
|
9375
|
+
}, [controller, filePath, fileName, loading, error, slideCount, autosaveAllowed]);
|
|
9376
|
+
return {
|
|
9377
|
+
prompt,
|
|
9378
|
+
discarding,
|
|
9379
|
+
restore: () => {
|
|
9380
|
+
void controller.restore().catch(() => {
|
|
9381
|
+
});
|
|
9382
|
+
},
|
|
9383
|
+
discard: () => {
|
|
9384
|
+
void controller.discard();
|
|
9759
9385
|
}
|
|
9760
|
-
|
|
9761
|
-
setDiscarding(true);
|
|
9762
|
-
void (async () => {
|
|
9763
|
-
try {
|
|
9764
|
-
await discardAutosaveRecovery(record, storageRef.current);
|
|
9765
|
-
recordRef.current = null;
|
|
9766
|
-
setPrompt(null);
|
|
9767
|
-
} catch {
|
|
9768
|
-
} finally {
|
|
9769
|
-
actionPendingRef.current = false;
|
|
9770
|
-
setDiscarding(false);
|
|
9771
|
-
}
|
|
9772
|
-
})();
|
|
9773
|
-
}, []);
|
|
9774
|
-
return { prompt, restore, discard, discarding };
|
|
9386
|
+
};
|
|
9775
9387
|
}
|
|
9776
9388
|
function usePresentationSetup(input) {
|
|
9777
9389
|
const {
|
|
@@ -10245,6 +9857,7 @@ function useEditorOperations(input) {
|
|
|
10245
9857
|
shapeAdjustmentDragStateRef: state.shapeAdjustmentDragStateRef,
|
|
10246
9858
|
marqueeStateRef: state.marqueeStateRef,
|
|
10247
9859
|
justInteractedRef: state.justInteractedRef,
|
|
9860
|
+
gestureRef: state.gestureControllerRef,
|
|
10248
9861
|
setInlineEditingElementId: state.setInlineEditingElementId,
|
|
10249
9862
|
setInlineEditingText: state.setInlineEditingText,
|
|
10250
9863
|
setContextMenuState: state.setContextMenuState,
|
|
@@ -10777,6 +10390,8 @@ function useContentLifecycle(input) {
|
|
|
10777
10390
|
// deck it has already snapshotted. The two refs are read by `.current`
|
|
10778
10391
|
// because an inline edit in progress lives there and nowhere else yet.
|
|
10779
10392
|
onSaved: input.onAutosave,
|
|
10393
|
+
inlineDraftSinkRef: state.autosaveDraftSinkRef,
|
|
10394
|
+
getInlineEditingId: () => state.inlineEditingElementIdRef.current,
|
|
10780
10395
|
getChangeSources: () => [
|
|
10781
10396
|
slides,
|
|
10782
10397
|
state.templateElementsBySlideId,
|
|
@@ -10806,138 +10421,27 @@ function useKeyboardShortcuts(input) {
|
|
|
10806
10421
|
inputRef.current = input;
|
|
10807
10422
|
const handleKeyDown = useCallback((e) => {
|
|
10808
10423
|
const current = inputRef.current;
|
|
10809
|
-
|
|
10810
|
-
if (startAction !== null) {
|
|
10811
|
-
e.preventDefault();
|
|
10812
|
-
if (startAction === "fromBeginning") {
|
|
10813
|
-
current.onStartShowFromBeginning();
|
|
10814
|
-
} else {
|
|
10815
|
-
current.onStartShowFromCurrent();
|
|
10816
|
-
}
|
|
10817
|
-
return;
|
|
10818
|
-
}
|
|
10819
|
-
const { action, dx, dy } = mapCustomizedEditorKey(
|
|
10424
|
+
dispatchEditorKey(
|
|
10820
10425
|
e,
|
|
10821
10426
|
{
|
|
10822
10427
|
canEdit: current.canEdit,
|
|
10823
|
-
canPaste: current.canPaste,
|
|
10824
|
-
// The Slide Master view is an editing surface, not a viewing one
|
|
10825
|
-
//
|
|
10826
|
-
// NO_ACTION there, so Delete, the arrow-key nudges and the clipboard
|
|
10827
|
-
// keys were all inert over a master shape even though the write path
|
|
10828
|
-
// behind them routes to the owning part correctly. Svelte and
|
|
10829
|
-
// vanilla, which render the master into their ordinary editable
|
|
10830
|
-
// stage, never had the gap.
|
|
10428
|
+
...current.canPaste === void 0 ? {} : { canPaste: current.canPaste },
|
|
10429
|
+
// The Slide Master view is an editing surface, not a viewing one, so
|
|
10430
|
+
// only the other modes count as "not editing" for the editor keymap.
|
|
10831
10431
|
isPresenting: current.mode !== "edit" && current.mode !== "master",
|
|
10432
|
+
// F5 is only inert while the show itself runs: a read-only viewer can
|
|
10433
|
+
// still start a show (it has a "From Beginning" button too).
|
|
10434
|
+
isShowRunning: current.mode === "present",
|
|
10435
|
+
canStartShow: !current.customization || isFeatureEnabled(current.customization, "presentMode"),
|
|
10832
10436
|
hasSelection: current.hasSelection,
|
|
10833
10437
|
isEditingText: Boolean(
|
|
10834
10438
|
current.inlineEditingElementId || current.tableEditorState?.isEditing
|
|
10835
10439
|
),
|
|
10836
10440
|
isDrawing: current.activeTool !== "select",
|
|
10837
|
-
|
|
10838
|
-
isControlTarget: isEditorControlTarget(e.target)
|
|
10441
|
+
keyboard: current.customization?.keyboard
|
|
10839
10442
|
},
|
|
10840
|
-
current
|
|
10443
|
+
toEditorKeyHandlers(current)
|
|
10841
10444
|
);
|
|
10842
|
-
if (action === null) {
|
|
10843
|
-
return;
|
|
10844
|
-
}
|
|
10845
|
-
e.preventDefault();
|
|
10846
|
-
switch (action) {
|
|
10847
|
-
case "escape":
|
|
10848
|
-
current.onEscape();
|
|
10849
|
-
break;
|
|
10850
|
-
case "delete":
|
|
10851
|
-
current.onDelete();
|
|
10852
|
-
break;
|
|
10853
|
-
case "undo":
|
|
10854
|
-
current.onUndo();
|
|
10855
|
-
break;
|
|
10856
|
-
case "redo":
|
|
10857
|
-
current.onRedo();
|
|
10858
|
-
break;
|
|
10859
|
-
case "copy":
|
|
10860
|
-
current.onCopy();
|
|
10861
|
-
break;
|
|
10862
|
-
case "cut":
|
|
10863
|
-
current.onCut();
|
|
10864
|
-
break;
|
|
10865
|
-
case "paste":
|
|
10866
|
-
current.onPaste();
|
|
10867
|
-
break;
|
|
10868
|
-
case "duplicate":
|
|
10869
|
-
current.onDuplicate();
|
|
10870
|
-
break;
|
|
10871
|
-
case "selectAll":
|
|
10872
|
-
current.onSelectAll();
|
|
10873
|
-
break;
|
|
10874
|
-
case "group":
|
|
10875
|
-
current.onGroup?.();
|
|
10876
|
-
break;
|
|
10877
|
-
case "ungroup":
|
|
10878
|
-
current.onUngroup?.();
|
|
10879
|
-
break;
|
|
10880
|
-
case "toggleShortcuts":
|
|
10881
|
-
current.onToggleShortcuts?.();
|
|
10882
|
-
break;
|
|
10883
|
-
case "find":
|
|
10884
|
-
current.onFind?.();
|
|
10885
|
-
break;
|
|
10886
|
-
case "nudge":
|
|
10887
|
-
current.onNudge(dx ?? 0, dy ?? 0);
|
|
10888
|
-
break;
|
|
10889
|
-
case "prevSlide":
|
|
10890
|
-
current.onPrevSlide?.();
|
|
10891
|
-
break;
|
|
10892
|
-
case "nextSlide":
|
|
10893
|
-
current.onNextSlide?.();
|
|
10894
|
-
break;
|
|
10895
|
-
case "alignLeft":
|
|
10896
|
-
current.onAlignLeft?.();
|
|
10897
|
-
break;
|
|
10898
|
-
case "alignCenter":
|
|
10899
|
-
current.onAlignCenter?.();
|
|
10900
|
-
break;
|
|
10901
|
-
case "alignRight":
|
|
10902
|
-
current.onAlignRight?.();
|
|
10903
|
-
break;
|
|
10904
|
-
case "alignJustify":
|
|
10905
|
-
current.onAlignJustify?.();
|
|
10906
|
-
break;
|
|
10907
|
-
case "increaseFontSize":
|
|
10908
|
-
current.onIncreaseFontSize?.();
|
|
10909
|
-
break;
|
|
10910
|
-
case "decreaseFontSize":
|
|
10911
|
-
current.onDecreaseFontSize?.();
|
|
10912
|
-
break;
|
|
10913
|
-
case "copyFormat":
|
|
10914
|
-
current.onCopyFormat?.();
|
|
10915
|
-
break;
|
|
10916
|
-
case "pasteFormat":
|
|
10917
|
-
current.onPasteFormat?.();
|
|
10918
|
-
break;
|
|
10919
|
-
case "newSlide":
|
|
10920
|
-
current.onNewSlide?.();
|
|
10921
|
-
break;
|
|
10922
|
-
case "hyperlink":
|
|
10923
|
-
current.onHyperlink?.();
|
|
10924
|
-
break;
|
|
10925
|
-
case "findReplace":
|
|
10926
|
-
current.onFindReplace?.();
|
|
10927
|
-
break;
|
|
10928
|
-
case "clearFormatting":
|
|
10929
|
-
current.onClearFormatting?.();
|
|
10930
|
-
break;
|
|
10931
|
-
case "cycleSelectionNext":
|
|
10932
|
-
current.onCycleSelectionNext?.();
|
|
10933
|
-
break;
|
|
10934
|
-
case "cycleSelectionPrev":
|
|
10935
|
-
current.onCycleSelectionPrev?.();
|
|
10936
|
-
break;
|
|
10937
|
-
case "pasteSpecial":
|
|
10938
|
-
current.onPasteSpecial?.();
|
|
10939
|
-
break;
|
|
10940
|
-
}
|
|
10941
10445
|
}, []);
|
|
10942
10446
|
useEffect(() => {
|
|
10943
10447
|
window.addEventListener("keydown", handleKeyDown);
|
|
@@ -10946,6 +10450,43 @@ function useKeyboardShortcuts(input) {
|
|
|
10946
10450
|
};
|
|
10947
10451
|
}, [handleKeyDown]);
|
|
10948
10452
|
}
|
|
10453
|
+
function toEditorKeyHandlers(current) {
|
|
10454
|
+
return {
|
|
10455
|
+
startShowFromBeginning: current.onStartShowFromBeginning,
|
|
10456
|
+
startShowFromCurrent: current.onStartShowFromCurrent,
|
|
10457
|
+
escape: current.onEscape,
|
|
10458
|
+
delete: current.onDelete,
|
|
10459
|
+
undo: current.onUndo,
|
|
10460
|
+
redo: current.onRedo,
|
|
10461
|
+
copy: current.onCopy,
|
|
10462
|
+
cut: current.onCut,
|
|
10463
|
+
paste: current.onPaste,
|
|
10464
|
+
duplicate: current.onDuplicate,
|
|
10465
|
+
selectAll: current.onSelectAll,
|
|
10466
|
+
group: current.onGroup,
|
|
10467
|
+
ungroup: current.onUngroup,
|
|
10468
|
+
toggleShortcuts: current.onToggleShortcuts,
|
|
10469
|
+
find: current.onFind,
|
|
10470
|
+
nudge: current.onNudge,
|
|
10471
|
+
prevSlide: current.onPrevSlide,
|
|
10472
|
+
nextSlide: current.onNextSlide,
|
|
10473
|
+
alignLeft: current.onAlignLeft,
|
|
10474
|
+
alignCenter: current.onAlignCenter,
|
|
10475
|
+
alignRight: current.onAlignRight,
|
|
10476
|
+
alignJustify: current.onAlignJustify,
|
|
10477
|
+
increaseFontSize: current.onIncreaseFontSize,
|
|
10478
|
+
decreaseFontSize: current.onDecreaseFontSize,
|
|
10479
|
+
copyFormat: current.onCopyFormat,
|
|
10480
|
+
pasteFormat: current.onPasteFormat,
|
|
10481
|
+
newSlide: current.onNewSlide,
|
|
10482
|
+
hyperlink: current.onHyperlink,
|
|
10483
|
+
findReplace: current.onFindReplace,
|
|
10484
|
+
clearFormatting: current.onClearFormatting,
|
|
10485
|
+
cycleSelectionNext: current.onCycleSelectionNext,
|
|
10486
|
+
cycleSelectionPrev: current.onCycleSelectionPrev,
|
|
10487
|
+
pasteSpecial: current.onPasteSpecial
|
|
10488
|
+
};
|
|
10489
|
+
}
|
|
10949
10490
|
var CLEAR_FORMATTING_PATCH = {
|
|
10950
10491
|
bold: false,
|
|
10951
10492
|
italic: false,
|
|
@@ -11211,7 +10752,8 @@ function useViewerIntegration(input) {
|
|
|
11211
10752
|
updateSlides: editorOps.ops.updateSlides,
|
|
11212
10753
|
updateElementById: editorOps.ops.updateElementById,
|
|
11213
10754
|
markDirty: history.markDirty,
|
|
11214
|
-
livePatcher: state.livePatcher
|
|
10755
|
+
livePatcher: state.livePatcher,
|
|
10756
|
+
gestureRef: state.gestureControllerRef
|
|
11215
10757
|
});
|
|
11216
10758
|
const [isEncryptedDialogOpen, setIsEncryptedDialogOpen] = useState(false);
|
|
11217
10759
|
const [loadVersion, setLoadVersion] = useState(0);
|
|
@@ -12648,6 +12190,7 @@ function buildToolbarProps(input) {
|
|
|
12648
12190
|
onAddShape: insertHandlers.handleAddShape,
|
|
12649
12191
|
onAddTable: insertHandlers.handleAddTable,
|
|
12650
12192
|
onAddChart: insertHandlers.handleAddChart,
|
|
12193
|
+
onOpenChartDialog: () => dialogs.setIsChartDialogOpen(true),
|
|
12651
12194
|
onAddSmartArt: () => dialogs.setIsSmartArtDialogOpen(true),
|
|
12652
12195
|
onAddEquation: () => {
|
|
12653
12196
|
dialogs.setEditingEquationOmml(null);
|
|
@@ -14507,6 +14050,50 @@ var EDGE_HANDLES = [
|
|
|
14507
14050
|
sizeClass: "w-2 h-5 max-md:w-3 max-md:h-8 rounded-sm"
|
|
14508
14051
|
}
|
|
14509
14052
|
];
|
|
14053
|
+
var wholeDegrees = (deg) => Math.round((deg % 360 + 360) % 360) % 360;
|
|
14054
|
+
function startRotateKnobGesture(options) {
|
|
14055
|
+
const { button, elementId, rotation, onRotate } = options;
|
|
14056
|
+
const scope = button.closest("[data-pptx-viewport]") ?? document;
|
|
14057
|
+
const wrapper = scope.querySelector(elementIdSelector(elementId));
|
|
14058
|
+
if (!wrapper) {
|
|
14059
|
+
return;
|
|
14060
|
+
}
|
|
14061
|
+
const rect = wrapper.getBoundingClientRect();
|
|
14062
|
+
const base = options.nonRotationTransform ? ` ${options.nonRotationTransform}` : "";
|
|
14063
|
+
const paint = (deg) => {
|
|
14064
|
+
const transform = `rotate(${deg}deg)${base}`;
|
|
14065
|
+
wrapper.style.transform = transform;
|
|
14066
|
+
syncSelectionHandleOverlay(wrapper, elementId, { transform });
|
|
14067
|
+
};
|
|
14068
|
+
if (options.pointerId !== void 0) {
|
|
14069
|
+
button.setPointerCapture?.(options.pointerId);
|
|
14070
|
+
}
|
|
14071
|
+
const gesture = createGestureController({
|
|
14072
|
+
getScale: () => 1,
|
|
14073
|
+
getElementBox: () => ({
|
|
14074
|
+
x: rect.left,
|
|
14075
|
+
y: rect.top,
|
|
14076
|
+
width: rect.width,
|
|
14077
|
+
height: rect.height,
|
|
14078
|
+
rotation
|
|
14079
|
+
}),
|
|
14080
|
+
getSiblings: () => [],
|
|
14081
|
+
getStageOrigin: () => ({ left: 0, top: 0 }),
|
|
14082
|
+
onStart: () => void 0,
|
|
14083
|
+
onPreview: (transform) => paint(wholeDegrees(transform.rotation)),
|
|
14084
|
+
onEnd: (transform) => {
|
|
14085
|
+
const deg = transform ? wholeDegrees(transform.rotation) : rotation;
|
|
14086
|
+
if (deg !== rotation) {
|
|
14087
|
+
onRotate?.(elementId, deg);
|
|
14088
|
+
}
|
|
14089
|
+
}
|
|
14090
|
+
});
|
|
14091
|
+
gesture.begin("rotate", elementId, {
|
|
14092
|
+
clientX: options.pointer.clientX,
|
|
14093
|
+
clientY: options.pointer.clientY,
|
|
14094
|
+
shiftKey: false
|
|
14095
|
+
});
|
|
14096
|
+
}
|
|
14510
14097
|
var appearance = { fill: "var(--color-primary)", borderColor: "#ffffff" };
|
|
14511
14098
|
var cornerSize = "var(--pptx-react-corner-default, 12px)";
|
|
14512
14099
|
var edgeLength = "var(--pptx-react-edge-length-default, 20px)";
|
|
@@ -14620,50 +14207,15 @@ function ResizeHandles({
|
|
|
14620
14207
|
e.currentTarget.setPointerCapture?.(e.pointerId);
|
|
14621
14208
|
onResizePointerDown(elementId, e, handle);
|
|
14622
14209
|
};
|
|
14623
|
-
const startRotate = (
|
|
14624
|
-
|
|
14625
|
-
|
|
14626
|
-
|
|
14627
|
-
|
|
14628
|
-
|
|
14629
|
-
|
|
14630
|
-
|
|
14631
|
-
|
|
14632
|
-
const base = nonRotationTransform ? ` ${nonRotationTransform}` : "";
|
|
14633
|
-
const startDeg = rotation ?? 0;
|
|
14634
|
-
const dragRotation = createRotationDrag(
|
|
14635
|
-
{ x: cx, y: cy },
|
|
14636
|
-
{ x: pointer.clientX, y: pointer.clientY },
|
|
14637
|
-
startDeg
|
|
14638
|
-
);
|
|
14639
|
-
let last = startDeg;
|
|
14640
|
-
if (pointerId !== void 0) {
|
|
14641
|
-
btn.setPointerCapture?.(pointerId);
|
|
14642
|
-
}
|
|
14643
|
-
const apply = (clientX, clientY, shift) => {
|
|
14644
|
-
let deg = dragRotation({ x: clientX, y: clientY });
|
|
14645
|
-
if (shift) {
|
|
14646
|
-
deg = Math.round(deg / 15) * 15;
|
|
14647
|
-
}
|
|
14648
|
-
deg = Math.round((deg % 360 + 360) % 360);
|
|
14649
|
-
last = deg;
|
|
14650
|
-
const transform = `rotate(${deg}deg)${base}`;
|
|
14651
|
-
wrapper.style.transform = transform;
|
|
14652
|
-
syncSelectionHandleOverlay(wrapper, elementId, { transform });
|
|
14653
|
-
};
|
|
14654
|
-
const onPointerMove = (ev) => apply(ev.clientX, ev.clientY, ev.shiftKey);
|
|
14655
|
-
const end = () => {
|
|
14656
|
-
window.removeEventListener("pointermove", onPointerMove);
|
|
14657
|
-
window.removeEventListener("pointerup", end);
|
|
14658
|
-
window.removeEventListener("pointercancel", end);
|
|
14659
|
-
if (last !== startDeg) {
|
|
14660
|
-
onRotate?.(elementId, last);
|
|
14661
|
-
}
|
|
14662
|
-
};
|
|
14663
|
-
window.addEventListener("pointermove", onPointerMove);
|
|
14664
|
-
window.addEventListener("pointerup", end);
|
|
14665
|
-
window.addEventListener("pointercancel", end);
|
|
14666
|
-
};
|
|
14210
|
+
const startRotate = (button, pointer) => startRotateKnobGesture({
|
|
14211
|
+
button,
|
|
14212
|
+
elementId,
|
|
14213
|
+
pointer,
|
|
14214
|
+
pointerId: pointer.pointerId,
|
|
14215
|
+
rotation: rotation ?? 0,
|
|
14216
|
+
...nonRotationTransform ? { nonRotationTransform } : {},
|
|
14217
|
+
...onRotate ? { onRotate } : {}
|
|
14218
|
+
});
|
|
14667
14219
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
14668
14220
|
[...CORNER_HANDLES, ...EDGE_HANDLES].map(({ handle, posClass, cursor }) => {
|
|
14669
14221
|
const corner = handle.length === 2;
|
|
@@ -14734,7 +14286,7 @@ function ResizeHandles({
|
|
|
14734
14286
|
},
|
|
14735
14287
|
onPointerDown: (e) => {
|
|
14736
14288
|
e.stopPropagation();
|
|
14737
|
-
startRotate(e.currentTarget, e
|
|
14289
|
+
startRotate(e.currentTarget, e);
|
|
14738
14290
|
},
|
|
14739
14291
|
onMouseDown: (e) => {
|
|
14740
14292
|
e.stopPropagation();
|
|
@@ -19144,4 +18696,4 @@ function useResizablePanels() {
|
|
|
19144
18696
|
};
|
|
19145
18697
|
}
|
|
19146
18698
|
|
|
19147
|
-
export { ACTION_VERB_MAP, ChartFormatContext, ChartPartSelectionProvider, CollaborationCursorOverlay, CollaborationProvider, ElementRenderer, FragmentedTransitionLayer, InlineCollaborationContext, MIN_TOUCH_TARGET, MorphTransitionOverlay, PresentationTransitionOverlay, RemoteSelectionOverlay, RemoteUserCursors, Rendering3DFlagsContext, ResizeHandles, SlideBackgroundImageLayer, SlideLayer,
|
|
18699
|
+
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 };
|