@editframe/elements 0.37.3-beta → 0.38.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/dist/EF_FRAMEGEN.js +17 -14
- package/dist/EF_FRAMEGEN.js.map +1 -1
- package/dist/EF_RENDERING.js.map +1 -1
- package/dist/canvas/EFCanvas.d.ts +9 -2
- package/dist/canvas/EFCanvas.js +14 -4
- package/dist/canvas/EFCanvas.js.map +1 -1
- package/dist/canvas/EFCanvasItem.d.ts +4 -4
- package/dist/canvas/overlays/SelectionOverlay.d.ts +10 -2
- package/dist/canvas/overlays/SelectionOverlay.js +5 -12
- package/dist/canvas/overlays/SelectionOverlay.js.map +1 -1
- package/dist/canvas/overlays/overlayState.js.map +1 -1
- package/dist/canvas/selection/SelectionController.js.map +1 -1
- package/dist/elements/EFAudio.d.ts +1 -11
- package/dist/elements/EFAudio.js +2 -10
- package/dist/elements/EFAudio.js.map +1 -1
- package/dist/elements/EFCaptions.d.ts +5 -9
- package/dist/elements/EFCaptions.js +34 -11
- package/dist/elements/EFCaptions.js.map +1 -1
- package/dist/elements/EFImage.d.ts +10 -8
- package/dist/elements/EFImage.js +117 -32
- package/dist/elements/EFImage.js.map +1 -1
- package/dist/elements/EFMedia/AssetMediaEngine.js +2 -2
- package/dist/elements/EFMedia/AssetMediaEngine.js.map +1 -1
- package/dist/elements/EFMedia/BaseMediaEngine.js +15 -92
- package/dist/elements/EFMedia/BaseMediaEngine.js.map +1 -1
- package/dist/elements/EFMedia/BufferedSeekingInput.js +10 -11
- package/dist/elements/EFMedia/BufferedSeekingInput.js.map +1 -1
- package/dist/elements/EFMedia/{AssetIdMediaEngine.js → FileMediaEngine.js} +44 -24
- package/dist/elements/EFMedia/FileMediaEngine.js.map +1 -0
- package/dist/elements/EFMedia/JitMediaEngine.js +14 -13
- package/dist/elements/EFMedia/JitMediaEngine.js.map +1 -1
- package/dist/elements/EFMedia/shared/AudioSpanUtils.js +3 -3
- package/dist/elements/EFMedia/shared/AudioSpanUtils.js.map +1 -1
- package/dist/elements/EFMedia/shared/ThumbnailExtractor.js +12 -7
- package/dist/elements/EFMedia/shared/ThumbnailExtractor.js.map +1 -1
- package/dist/elements/EFMedia/shared/timeoutUtils.js +44 -0
- package/dist/elements/EFMedia/shared/timeoutUtils.js.map +1 -0
- package/dist/elements/EFMedia/videoTasks/MainVideoInputCache.js +1 -1
- package/dist/elements/EFMedia/videoTasks/MainVideoInputCache.js.map +1 -1
- package/dist/elements/EFMedia/videoTasks/ScrubInputCache.js +4 -4
- package/dist/elements/EFMedia/videoTasks/ScrubInputCache.js.map +1 -1
- package/dist/elements/EFMedia.d.ts +14 -8
- package/dist/elements/EFMedia.js +52 -19
- package/dist/elements/EFMedia.js.map +1 -1
- package/dist/elements/EFPanZoom.d.ts +2 -2
- package/dist/elements/EFPanZoom.js +1 -1
- package/dist/elements/EFPanZoom.js.map +1 -1
- package/dist/elements/EFSourceMixin.js +16 -8
- package/dist/elements/EFSourceMixin.js.map +1 -1
- package/dist/elements/EFSurface.d.ts +7 -10
- package/dist/elements/EFSurface.js +4 -43
- package/dist/elements/EFSurface.js.map +1 -1
- package/dist/elements/EFTemporal.d.ts +33 -8
- package/dist/elements/EFTemporal.js +92 -40
- package/dist/elements/EFTemporal.js.map +1 -1
- package/dist/elements/EFText.d.ts +3 -0
- package/dist/elements/EFText.js +54 -21
- package/dist/elements/EFText.js.map +1 -1
- package/dist/elements/EFTextSegment.js +8 -4
- package/dist/elements/EFTextSegment.js.map +1 -1
- package/dist/elements/EFTimegroup.d.ts +26 -43
- package/dist/elements/EFTimegroup.js +295 -314
- package/dist/elements/EFTimegroup.js.map +1 -1
- package/dist/elements/EFVideo.d.ts +44 -42
- package/dist/elements/EFVideo.js +259 -172
- package/dist/elements/EFVideo.js.map +1 -1
- package/dist/elements/EFWaveform.d.ts +3 -8
- package/dist/elements/EFWaveform.js +18 -13
- package/dist/elements/EFWaveform.js.map +1 -1
- package/dist/elements/ElementPositionInfo.js.map +1 -1
- package/dist/elements/FetchMixin.js.map +1 -1
- package/dist/elements/TargetController.d.ts +0 -3
- package/dist/elements/TargetController.js +12 -35
- package/dist/elements/TargetController.js.map +1 -1
- package/dist/elements/TimegroupController.js.map +1 -1
- package/dist/elements/cloneFactoryRegistry.d.ts +14 -0
- package/dist/elements/cloneFactoryRegistry.js +15 -0
- package/dist/elements/cloneFactoryRegistry.js.map +1 -0
- package/dist/elements/renderTemporalAudio.js +8 -6
- package/dist/elements/renderTemporalAudio.js.map +1 -1
- package/dist/elements/setupTemporalHierarchy.js +62 -0
- package/dist/elements/setupTemporalHierarchy.js.map +1 -0
- package/dist/elements/updateAnimations.js +62 -87
- package/dist/elements/updateAnimations.js.map +1 -1
- package/dist/getRenderInfo.d.ts +3 -2
- package/dist/getRenderInfo.js +20 -4
- package/dist/getRenderInfo.js.map +1 -1
- package/dist/gui/ContextMixin.js +68 -12
- package/dist/gui/ContextMixin.js.map +1 -1
- package/dist/gui/Controllable.js +1 -1
- package/dist/gui/Controllable.js.map +1 -1
- package/dist/gui/EFActiveRootTemporal.d.ts +4 -4
- package/dist/gui/EFActiveRootTemporal.js.map +1 -1
- package/dist/gui/EFControls.d.ts +2 -2
- package/dist/gui/EFControls.js +2 -2
- package/dist/gui/EFControls.js.map +1 -1
- package/dist/gui/EFDial.d.ts +4 -4
- package/dist/gui/EFDial.js +12 -9
- package/dist/gui/EFDial.js.map +1 -1
- package/dist/gui/EFFilmstrip.d.ts +2 -0
- package/dist/gui/EFFilmstrip.js +18 -10
- package/dist/gui/EFFilmstrip.js.map +1 -1
- package/dist/gui/EFFitScale.d.ts +28 -4
- package/dist/gui/EFFitScale.js +88 -26
- package/dist/gui/EFFitScale.js.map +1 -1
- package/dist/gui/EFFocusOverlay.d.ts +4 -4
- package/dist/gui/EFFocusOverlay.js +3 -3
- package/dist/gui/EFFocusOverlay.js.map +1 -1
- package/dist/gui/EFOverlayItem.d.ts +4 -4
- package/dist/gui/EFOverlayLayer.d.ts +4 -4
- package/dist/gui/EFPause.d.ts +4 -4
- package/dist/gui/EFPause.js +1 -1
- package/dist/gui/EFPlay.d.ts +4 -4
- package/dist/gui/EFPlay.js +1 -1
- package/dist/gui/EFPreview.js +1 -1
- package/dist/gui/EFResizableBox.d.ts +4 -4
- package/dist/gui/EFResizableBox.js +5 -5
- package/dist/gui/EFResizableBox.js.map +1 -1
- package/dist/gui/EFScrubber.d.ts +4 -4
- package/dist/gui/EFScrubber.js +8 -13
- package/dist/gui/EFScrubber.js.map +1 -1
- package/dist/gui/EFTimeDisplay.d.ts +8 -4
- package/dist/gui/EFTimeDisplay.js +25 -7
- package/dist/gui/EFTimeDisplay.js.map +1 -1
- package/dist/gui/EFTimelineRuler.d.ts +4 -4
- package/dist/gui/EFTimelineRuler.js +3 -3
- package/dist/gui/EFTimelineRuler.js.map +1 -1
- package/dist/gui/EFToggleLoop.d.ts +4 -4
- package/dist/gui/EFToggleLoop.js +1 -1
- package/dist/gui/EFTogglePlay.d.ts +4 -4
- package/dist/gui/EFTogglePlay.js +1 -1
- package/dist/gui/EFTransformHandles.d.ts +4 -4
- package/dist/gui/EFTransformHandles.js +6 -6
- package/dist/gui/EFTransformHandles.js.map +1 -1
- package/dist/gui/EFWorkbench.d.ts +40 -36
- package/dist/gui/EFWorkbench.js +436 -822
- package/dist/gui/EFWorkbench.js.map +1 -1
- package/dist/gui/FitScaleHelpers.js.map +1 -1
- package/dist/gui/PlaybackController.d.ts +3 -8
- package/dist/gui/PlaybackController.js +59 -56
- package/dist/gui/PlaybackController.js.map +1 -1
- package/dist/gui/TWMixin.js +1 -1
- package/dist/gui/TWMixin.js.map +1 -1
- package/dist/gui/TargetOrContextMixin.js +43 -6
- package/dist/gui/TargetOrContextMixin.js.map +1 -1
- package/dist/gui/ef-theme.css +136 -0
- package/dist/gui/hierarchy/EFHierarchy.d.ts +2 -2
- package/dist/gui/hierarchy/EFHierarchy.js +14 -24
- package/dist/gui/hierarchy/EFHierarchy.js.map +1 -1
- package/dist/gui/hierarchy/EFHierarchyItem.d.ts +3 -3
- package/dist/gui/hierarchy/EFHierarchyItem.js +22 -10
- package/dist/gui/hierarchy/EFHierarchyItem.js.map +1 -1
- package/dist/gui/icons.js.map +1 -1
- package/dist/gui/previewSettingsContext.d.ts +18 -0
- package/dist/gui/previewSettingsContext.js.map +1 -1
- package/dist/gui/theme.js +34 -0
- package/dist/gui/theme.js.map +1 -0
- package/dist/gui/timeline/EFTimeline.d.ts +2 -2
- package/dist/gui/timeline/EFTimeline.js +70 -52
- package/dist/gui/timeline/EFTimeline.js.map +1 -1
- package/dist/gui/timeline/EFTimelineRow.d.ts +3 -1
- package/dist/gui/timeline/EFTimelineRow.js +55 -32
- package/dist/gui/timeline/EFTimelineRow.js.map +1 -1
- package/dist/gui/timeline/TrimHandles.d.ts +23 -9
- package/dist/gui/timeline/TrimHandles.js +224 -51
- package/dist/gui/timeline/TrimHandles.js.map +1 -1
- package/dist/gui/timeline/flattenHierarchy.js.map +1 -1
- package/dist/gui/timeline/timelineEditingContext.d.ts +34 -0
- package/dist/gui/timeline/timelineEditingContext.js +24 -0
- package/dist/gui/timeline/timelineEditingContext.js.map +1 -0
- package/dist/gui/timeline/timelineStateContext.js.map +1 -1
- package/dist/gui/timeline/tracks/AudioTrack.js +1 -1
- package/dist/gui/timeline/tracks/AudioTrack.js.map +1 -1
- package/dist/gui/timeline/tracks/CaptionsTrack.d.ts +2 -3
- package/dist/gui/timeline/tracks/CaptionsTrack.js +17 -75
- package/dist/gui/timeline/tracks/CaptionsTrack.js.map +1 -1
- package/dist/gui/timeline/tracks/EFThumbnailStrip.d.ts +52 -0
- package/dist/gui/timeline/tracks/EFThumbnailStrip.js +596 -0
- package/dist/gui/timeline/tracks/EFThumbnailStrip.js.map +1 -0
- package/dist/gui/timeline/tracks/HTMLTrack.js.map +1 -1
- package/dist/gui/timeline/tracks/ImageTrack.js.map +1 -1
- package/dist/gui/timeline/tracks/TextTrack.d.ts +3 -2
- package/dist/gui/timeline/tracks/TextTrack.js +17 -43
- package/dist/gui/timeline/tracks/TextTrack.js.map +1 -1
- package/dist/gui/timeline/tracks/TimegroupTrack.d.ts +3 -4
- package/dist/gui/timeline/tracks/TimegroupTrack.js +33 -23
- package/dist/gui/timeline/tracks/TimegroupTrack.js.map +1 -1
- package/dist/gui/timeline/tracks/TrackItem.d.ts +7 -9
- package/dist/gui/timeline/tracks/TrackItem.js +18 -17
- package/dist/gui/timeline/tracks/TrackItem.js.map +1 -1
- package/dist/gui/timeline/tracks/VideoTrack.d.ts +3 -3
- package/dist/gui/timeline/tracks/VideoTrack.js +11 -14
- package/dist/gui/timeline/tracks/VideoTrack.js.map +1 -1
- package/dist/gui/timeline/tracks/WaveformTrack.js.map +1 -1
- package/dist/gui/timeline/tracks/renderTrackChildren.js.map +1 -1
- package/dist/gui/timeline/tracks/waveformUtils.js +1 -1
- package/dist/gui/timeline/tracks/waveformUtils.js.map +1 -1
- package/dist/gui/tree/EFTree.d.ts +4 -4
- package/dist/gui/tree/EFTree.js +8 -14
- package/dist/gui/tree/EFTree.js.map +1 -1
- package/dist/gui/tree/EFTreeItem.d.ts +4 -4
- package/dist/gui/tree/EFTreeItem.js +3 -3
- package/dist/gui/tree/EFTreeItem.js.map +1 -1
- package/dist/gui/tree/treeContext.js.map +1 -1
- package/dist/index.d.ts +10 -8
- package/dist/index.js +6 -5
- package/dist/index.js.map +1 -1
- package/dist/node.d.ts +2 -2
- package/dist/node.js +2 -2
- package/dist/preview/AdaptiveResolutionTracker.js +3 -3
- package/dist/preview/AdaptiveResolutionTracker.js.map +1 -1
- package/dist/preview/FrameController.d.ts +2 -17
- package/dist/preview/FrameController.js +40 -63
- package/dist/preview/FrameController.js.map +1 -1
- package/dist/preview/QualityUpgradeScheduler.d.ts +76 -0
- package/dist/preview/QualityUpgradeScheduler.js +158 -0
- package/dist/preview/QualityUpgradeScheduler.js.map +1 -0
- package/dist/preview/RenderContext.d.ts +119 -1
- package/dist/preview/RenderContext.js +21 -3
- package/dist/preview/RenderContext.js.map +1 -1
- package/dist/preview/RenderProfiler.js.map +1 -1
- package/dist/preview/RenderStats.js +85 -0
- package/dist/preview/RenderStats.js.map +1 -0
- package/dist/preview/encoding/canvasEncoder.js +2 -52
- package/dist/preview/encoding/canvasEncoder.js.map +1 -1
- package/dist/preview/encoding/mainThreadEncoder.js.map +1 -1
- package/dist/preview/encoding/workerEncoder.js.map +1 -1
- package/dist/preview/logger.js.map +1 -1
- package/dist/preview/previewSettings.d.ts +34 -0
- package/dist/preview/previewSettings.js +29 -17
- package/dist/preview/previewSettings.js.map +1 -1
- package/dist/preview/previewTypes.js +4 -4
- package/dist/preview/previewTypes.js.map +1 -1
- package/dist/preview/renderElementToCanvas.d.ts +44 -0
- package/dist/preview/renderElementToCanvas.js +72 -0
- package/dist/preview/renderElementToCanvas.js.map +1 -0
- package/dist/preview/renderTimegroupToCanvas.js +267 -145
- package/dist/preview/renderTimegroupToCanvas.js.map +1 -1
- package/dist/preview/renderTimegroupToCanvas.types.d.ts +30 -0
- package/dist/preview/renderTimegroupToVideo.js +85 -105
- package/dist/preview/renderTimegroupToVideo.js.map +1 -1
- package/dist/preview/{renderTimegroupToVideo.d.ts → renderTimegroupToVideo.types.d.ts} +9 -9
- package/dist/preview/renderVideoToVideo.js +286 -0
- package/dist/preview/renderVideoToVideo.js.map +1 -0
- package/dist/preview/renderers.js.map +1 -1
- package/dist/preview/rendering/ScaleConfig.js +74 -0
- package/dist/preview/rendering/ScaleConfig.js.map +1 -0
- package/dist/preview/rendering/inlineImages.js +1 -44
- package/dist/preview/rendering/inlineImages.js.map +1 -1
- package/dist/preview/rendering/loadImage.js +22 -0
- package/dist/preview/rendering/loadImage.js.map +1 -0
- package/dist/preview/rendering/renderToImageNative.js +3 -3
- package/dist/preview/rendering/renderToImageNative.js.map +1 -1
- package/dist/preview/rendering/serializeTimelineDirect.js +224 -68
- package/dist/preview/rendering/serializeTimelineDirect.js.map +1 -1
- package/dist/preview/statsTrackingStrategy.js +1 -101
- package/dist/preview/statsTrackingStrategy.js.map +1 -1
- package/dist/preview/workers/WorkerPool.js +0 -1
- package/dist/preview/workers/WorkerPool.js.map +1 -1
- package/dist/preview/workers/encoderWorkerInline.js +21 -54
- package/dist/preview/workers/encoderWorkerInline.js.map +1 -1
- package/dist/render/EFRenderAPI.d.ts +2 -1
- package/dist/render/EFRenderAPI.js +12 -36
- package/dist/render/EFRenderAPI.js.map +1 -1
- package/dist/render/getRenderData.js +4 -4
- package/dist/render/getRenderData.js.map +1 -1
- package/dist/style.css +114 -163
- package/dist/transcoding/cache/RequestDeduplicator.js +1 -0
- package/dist/transcoding/cache/RequestDeduplicator.js.map +1 -1
- package/dist/transcoding/types/index.d.ts +1 -1
- package/dist/transcoding/utils/UrlGenerator.js +10 -3
- package/dist/transcoding/utils/UrlGenerator.js.map +1 -1
- package/dist/utils/LRUCache.js +1 -0
- package/dist/utils/LRUCache.js.map +1 -1
- package/dist/utils/frameTime.js +23 -1
- package/dist/utils/frameTime.js.map +1 -1
- package/package.json +21 -8
- package/scripts/build-css.js +8 -1
- package/test/setup.ts +0 -1
- package/test/useAssetMSW.ts +50 -0
- package/test/visualRegressionUtils.ts +23 -9
- package/dist/_virtual/rolldown_runtime.js +0 -27
- package/dist/elements/EFMedia/AssetIdMediaEngine.js.map +0 -1
- package/dist/elements/EFThumbnailStrip.d.ts +0 -167
- package/dist/elements/EFThumbnailStrip.js +0 -731
- package/dist/elements/EFThumbnailStrip.js.map +0 -1
- package/dist/elements/SessionThumbnailCache.js +0 -154
- package/dist/elements/SessionThumbnailCache.js.map +0 -1
- package/dist/node_modules/react/cjs/react-jsx-runtime.development.js +0 -688
- package/dist/node_modules/react/cjs/react-jsx-runtime.development.js.map +0 -1
- package/dist/node_modules/react/cjs/react.development.js +0 -1521
- package/dist/node_modules/react/cjs/react.development.js.map +0 -1
- package/dist/node_modules/react/index.js +0 -13
- package/dist/node_modules/react/index.js.map +0 -1
- package/dist/node_modules/react/jsx-runtime.js +0 -13
- package/dist/node_modules/react/jsx-runtime.js.map +0 -1
- package/dist/preview/encoding/types.d.ts +0 -1
- package/dist/preview/renderTimegroupPreview.js +0 -686
- package/dist/preview/renderTimegroupPreview.js.map +0 -1
- package/dist/preview/renderTimegroupToCanvas.d.ts +0 -42
- package/dist/preview/rendering/renderToImage.d.ts +0 -2
- package/dist/preview/rendering/renderToImage.js +0 -95
- package/dist/preview/rendering/renderToImage.js.map +0 -1
- package/dist/preview/rendering/renderToImageForeignObject.js +0 -163
- package/dist/preview/rendering/renderToImageForeignObject.js.map +0 -1
- package/dist/preview/rendering/renderToImageNative.d.ts +0 -1
- package/dist/preview/rendering/svgSerializer.js +0 -43
- package/dist/preview/rendering/svgSerializer.js.map +0 -1
- package/dist/preview/rendering/types.d.ts +0 -2
- package/dist/preview/thumbnailCacheSettings.js +0 -52
- package/dist/preview/thumbnailCacheSettings.js.map +0 -1
- package/dist/sandbox/PlaybackControls.d.ts +0 -1
- package/dist/sandbox/PlaybackControls.js +0 -10
- package/dist/sandbox/PlaybackControls.js.map +0 -1
- package/dist/sandbox/ScenarioRunner.d.ts +0 -1
- package/dist/sandbox/ScenarioRunner.js +0 -1
- package/dist/sandbox/defineSandbox.d.ts +0 -1
- package/dist/sandbox/index.d.ts +0 -3
- package/dist/sandbox/index.js +0 -2
- package/test/EFVideo.framegen.browsertest.ts +0 -80
- package/test/thumbnail-performance-test.html +0 -116
|
@@ -1,686 +0,0 @@
|
|
|
1
|
-
import { logger } from "./logger.js";
|
|
2
|
-
import { getTemporalBounds, isTemporal, isVisibleAtTime } from "./previewTypes.js";
|
|
3
|
-
|
|
4
|
-
//#region src/preview/renderTimegroupPreview.ts
|
|
5
|
-
/**
|
|
6
|
-
* Elements to skip entirely when building the preview.
|
|
7
|
-
*/
|
|
8
|
-
const SKIP_TAGS = new Set([
|
|
9
|
-
"EF-AUDIO",
|
|
10
|
-
"EF-THUMBNAIL-STRIP",
|
|
11
|
-
"EF-FILMSTRIP",
|
|
12
|
-
"EF-TIMELINE",
|
|
13
|
-
"EF-WORKBENCH",
|
|
14
|
-
"SCRIPT",
|
|
15
|
-
"STYLE"
|
|
16
|
-
]);
|
|
17
|
-
/**
|
|
18
|
-
* All CSS properties to sync (camelCase for style[] access).
|
|
19
|
-
*/
|
|
20
|
-
const SYNC_PROPERTIES = [
|
|
21
|
-
"display",
|
|
22
|
-
"visibility",
|
|
23
|
-
"opacity",
|
|
24
|
-
"position",
|
|
25
|
-
"top",
|
|
26
|
-
"right",
|
|
27
|
-
"bottom",
|
|
28
|
-
"left",
|
|
29
|
-
"zIndex",
|
|
30
|
-
"width",
|
|
31
|
-
"height",
|
|
32
|
-
"minWidth",
|
|
33
|
-
"minHeight",
|
|
34
|
-
"maxWidth",
|
|
35
|
-
"maxHeight",
|
|
36
|
-
"flexGrow",
|
|
37
|
-
"flexShrink",
|
|
38
|
-
"flexBasis",
|
|
39
|
-
"flexDirection",
|
|
40
|
-
"flexWrap",
|
|
41
|
-
"justifyContent",
|
|
42
|
-
"alignItems",
|
|
43
|
-
"alignContent",
|
|
44
|
-
"alignSelf",
|
|
45
|
-
"gap",
|
|
46
|
-
"gridTemplate",
|
|
47
|
-
"gridColumn",
|
|
48
|
-
"gridRow",
|
|
49
|
-
"gridArea",
|
|
50
|
-
"margin",
|
|
51
|
-
"padding",
|
|
52
|
-
"boxSizing",
|
|
53
|
-
"border",
|
|
54
|
-
"borderTop",
|
|
55
|
-
"borderRight",
|
|
56
|
-
"borderBottom",
|
|
57
|
-
"borderLeft",
|
|
58
|
-
"borderRadius",
|
|
59
|
-
"background",
|
|
60
|
-
"color",
|
|
61
|
-
"boxShadow",
|
|
62
|
-
"filter",
|
|
63
|
-
"backdropFilter",
|
|
64
|
-
"clipPath",
|
|
65
|
-
"fontFamily",
|
|
66
|
-
"fontSize",
|
|
67
|
-
"fontWeight",
|
|
68
|
-
"fontStyle",
|
|
69
|
-
"fontVariant",
|
|
70
|
-
"textAlign",
|
|
71
|
-
"textDecoration",
|
|
72
|
-
"textTransform",
|
|
73
|
-
"letterSpacing",
|
|
74
|
-
"wordSpacing",
|
|
75
|
-
"whiteSpace",
|
|
76
|
-
"textOverflow",
|
|
77
|
-
"lineHeight",
|
|
78
|
-
"verticalAlign",
|
|
79
|
-
"transform",
|
|
80
|
-
"transformOrigin",
|
|
81
|
-
"transformStyle",
|
|
82
|
-
"perspective",
|
|
83
|
-
"perspectiveOrigin",
|
|
84
|
-
"backfaceVisibility",
|
|
85
|
-
"cursor",
|
|
86
|
-
"pointerEvents",
|
|
87
|
-
"userSelect",
|
|
88
|
-
"overflow"
|
|
89
|
-
];
|
|
90
|
-
/**
|
|
91
|
-
* Kebab-case versions for computedStyleMap.get() - pre-computed for speed.
|
|
92
|
-
*/
|
|
93
|
-
const SYNC_PROPERTIES_KEBAB = SYNC_PROPERTIES.map((prop) => prop.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`));
|
|
94
|
-
/**
|
|
95
|
-
* Feature detection: computedStyleMap is ~15% faster for style syncing.
|
|
96
|
-
*/
|
|
97
|
-
const HAS_COMPUTED_STYLE_MAP = typeof Element !== "undefined" && typeof Element.prototype.computedStyleMap === "function";
|
|
98
|
-
/**
|
|
99
|
-
* CSS initial/default values for SAFE-TO-SKIP properties.
|
|
100
|
-
* Only includes NON-INHERITED properties where skipping the default
|
|
101
|
-
* won't affect visual output.
|
|
102
|
-
*
|
|
103
|
-
* EXCLUDED (must always serialize):
|
|
104
|
-
* - Inherited properties (color, font, text-*, visibility, cursor)
|
|
105
|
-
* - Display (affects layout significantly)
|
|
106
|
-
* - Properties where "auto" computes to a specific value
|
|
107
|
-
*
|
|
108
|
-
* INCLUDED (safe to skip):
|
|
109
|
-
* - Transform/filter effects (none = no effect)
|
|
110
|
-
* - Box shadows (none = no shadow)
|
|
111
|
-
* - Borders when none/0 (no visual impact)
|
|
112
|
-
* - backdrop-filter (none = no effect)
|
|
113
|
-
*/
|
|
114
|
-
const CSS_SAFE_DEFAULT_VALUES = {
|
|
115
|
-
transform: "none",
|
|
116
|
-
filter: "none",
|
|
117
|
-
backdropFilter: "none",
|
|
118
|
-
boxShadow: "none",
|
|
119
|
-
border: [
|
|
120
|
-
"none",
|
|
121
|
-
"0px none",
|
|
122
|
-
"0px",
|
|
123
|
-
"0px none rgb(0, 0, 0)"
|
|
124
|
-
],
|
|
125
|
-
borderTop: [
|
|
126
|
-
"none",
|
|
127
|
-
"0px none",
|
|
128
|
-
"0px",
|
|
129
|
-
"0px none rgb(0, 0, 0)"
|
|
130
|
-
],
|
|
131
|
-
borderRight: [
|
|
132
|
-
"none",
|
|
133
|
-
"0px none",
|
|
134
|
-
"0px",
|
|
135
|
-
"0px none rgb(0, 0, 0)"
|
|
136
|
-
],
|
|
137
|
-
borderBottom: [
|
|
138
|
-
"none",
|
|
139
|
-
"0px none",
|
|
140
|
-
"0px",
|
|
141
|
-
"0px none rgb(0, 0, 0)"
|
|
142
|
-
],
|
|
143
|
-
borderLeft: [
|
|
144
|
-
"none",
|
|
145
|
-
"0px none",
|
|
146
|
-
"0px",
|
|
147
|
-
"0px none rgb(0, 0, 0)"
|
|
148
|
-
],
|
|
149
|
-
borderRadius: ["0px", "0"],
|
|
150
|
-
position: "static",
|
|
151
|
-
zIndex: "auto",
|
|
152
|
-
transformStyle: "flat",
|
|
153
|
-
perspective: "none",
|
|
154
|
-
backfaceVisibility: "visible"
|
|
155
|
-
};
|
|
156
|
-
/**
|
|
157
|
-
* Check if a value matches a safe-to-skip default.
|
|
158
|
-
*/
|
|
159
|
-
function isDefaultValue(prop, value) {
|
|
160
|
-
const defaults = CSS_SAFE_DEFAULT_VALUES[prop];
|
|
161
|
-
if (!defaults) return false;
|
|
162
|
-
if (Array.isArray(defaults)) return defaults.includes(value);
|
|
163
|
-
return defaults === value;
|
|
164
|
-
}
|
|
165
|
-
/**
|
|
166
|
-
* Remove hidden nodes from the clone DOM for serialization.
|
|
167
|
-
* Returns info needed to restore them afterward.
|
|
168
|
-
*
|
|
169
|
-
* This physically removes non-visible nodes so they won't be serialized,
|
|
170
|
-
* avoiding the cost of serializing hidden elements and their resources.
|
|
171
|
-
*/
|
|
172
|
-
function removeHiddenNodesForSerialization(state) {
|
|
173
|
-
const removed = [];
|
|
174
|
-
const visibleSet = state.currentVisibleSet;
|
|
175
|
-
function visit(node) {
|
|
176
|
-
for (const child of node.children) visit(child);
|
|
177
|
-
if (!visibleSet.has(node)) {
|
|
178
|
-
const parent = node.clone.parentNode;
|
|
179
|
-
if (parent) {
|
|
180
|
-
const nextSibling = node.clone.nextSibling;
|
|
181
|
-
parent.removeChild(node.clone);
|
|
182
|
-
removed.push({
|
|
183
|
-
node,
|
|
184
|
-
parent,
|
|
185
|
-
nextSibling
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
if (state.tree.root) visit(state.tree.root);
|
|
191
|
-
return removed;
|
|
192
|
-
}
|
|
193
|
-
/**
|
|
194
|
-
* Restore previously removed hidden nodes to the clone DOM.
|
|
195
|
-
* Must be called after serialization to maintain tree integrity for next frame.
|
|
196
|
-
*/
|
|
197
|
-
function restoreHiddenNodes(removed) {
|
|
198
|
-
for (let i = removed.length - 1; i >= 0; i--) {
|
|
199
|
-
const { node, parent, nextSibling } = removed[i];
|
|
200
|
-
if (nextSibling) parent.insertBefore(node.clone, nextSibling);
|
|
201
|
-
else parent.appendChild(node.clone);
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
/**
|
|
205
|
-
* Unified CSS property sync for all elements (canvas clones and regular elements).
|
|
206
|
-
*
|
|
207
|
-
* Canvas clones use a limited property set matching the original implementation
|
|
208
|
-
* to avoid dimension/layout issues. Regular elements use the full SYNC_PROPERTIES array.
|
|
209
|
-
*
|
|
210
|
-
* @param source - Source element to read styles from
|
|
211
|
-
* @param clone - Clone element to write styles to
|
|
212
|
-
* @param contentSource - Optional content element for width/height (canvas clones only)
|
|
213
|
-
*/
|
|
214
|
-
function syncElementStyles(source, clone, contentSource) {
|
|
215
|
-
const cloneStyle = clone.style;
|
|
216
|
-
const tagName = source.tagName;
|
|
217
|
-
if (!!contentSource) {
|
|
218
|
-
let cs;
|
|
219
|
-
let contentCs;
|
|
220
|
-
try {
|
|
221
|
-
cs = getComputedStyle(source);
|
|
222
|
-
if (contentSource) contentCs = getComputedStyle(contentSource);
|
|
223
|
-
} catch {
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
226
|
-
cloneStyle.position = cs.position;
|
|
227
|
-
cloneStyle.top = cs.top;
|
|
228
|
-
cloneStyle.right = cs.right;
|
|
229
|
-
cloneStyle.bottom = cs.bottom;
|
|
230
|
-
cloneStyle.left = cs.left;
|
|
231
|
-
cloneStyle.margin = cs.margin;
|
|
232
|
-
cloneStyle.zIndex = cs.zIndex;
|
|
233
|
-
cloneStyle.transform = cs.transform;
|
|
234
|
-
cloneStyle.transformOrigin = cs.transformOrigin;
|
|
235
|
-
cloneStyle.opacity = cs.opacity;
|
|
236
|
-
cloneStyle.visibility = cs.visibility;
|
|
237
|
-
cloneStyle.backfaceVisibility = cs.backfaceVisibility;
|
|
238
|
-
cloneStyle.transformStyle = cs.transformStyle;
|
|
239
|
-
cloneStyle.background = cs.background;
|
|
240
|
-
cloneStyle.color = cs.color;
|
|
241
|
-
cloneStyle.boxShadow = cs.boxShadow;
|
|
242
|
-
cloneStyle.filter = cs.filter;
|
|
243
|
-
cloneStyle.backdropFilter = cs.backdropFilter;
|
|
244
|
-
if (contentCs) {
|
|
245
|
-
cloneStyle.width = contentCs.width;
|
|
246
|
-
cloneStyle.height = contentCs.height;
|
|
247
|
-
}
|
|
248
|
-
cloneStyle.display = "block";
|
|
249
|
-
cloneStyle.animation = "none";
|
|
250
|
-
cloneStyle.transition = "none";
|
|
251
|
-
return;
|
|
252
|
-
}
|
|
253
|
-
const propLen = SYNC_PROPERTIES.length;
|
|
254
|
-
if (HAS_COMPUTED_STYLE_MAP) {
|
|
255
|
-
let srcMap;
|
|
256
|
-
try {
|
|
257
|
-
srcMap = source.computedStyleMap();
|
|
258
|
-
} catch {
|
|
259
|
-
return;
|
|
260
|
-
}
|
|
261
|
-
for (let j = 0; j < propLen; j++) {
|
|
262
|
-
const kebab = SYNC_PROPERTIES_KEBAB[j];
|
|
263
|
-
const camel = SYNC_PROPERTIES[j];
|
|
264
|
-
const srcVal = srcMap.get(kebab);
|
|
265
|
-
if (!srcVal) continue;
|
|
266
|
-
const strVal = srcVal.toString();
|
|
267
|
-
if (camel === "display") {
|
|
268
|
-
cloneStyle.display = strVal === "none" && !(tagName && (tagName === "EF-CAPTIONS-ACTIVE-WORD" || tagName === "EF-CAPTIONS-BEFORE-ACTIVE-WORD" || tagName === "EF-CAPTIONS-AFTER-ACTIVE-WORD" || tagName === "EF-CAPTIONS-SEGMENT")) ? "block" : strVal;
|
|
269
|
-
continue;
|
|
270
|
-
}
|
|
271
|
-
if (camel === "clipPath") continue;
|
|
272
|
-
if (isDefaultValue(camel, strVal)) {
|
|
273
|
-
if (cloneStyle[camel]) cloneStyle[camel] = "";
|
|
274
|
-
continue;
|
|
275
|
-
}
|
|
276
|
-
cloneStyle[camel] = strVal;
|
|
277
|
-
}
|
|
278
|
-
} else {
|
|
279
|
-
let cs;
|
|
280
|
-
try {
|
|
281
|
-
cs = getComputedStyle(source);
|
|
282
|
-
} catch {
|
|
283
|
-
return;
|
|
284
|
-
}
|
|
285
|
-
const srcStyle = cs;
|
|
286
|
-
for (const prop of SYNC_PROPERTIES) {
|
|
287
|
-
const srcVal = srcStyle[prop];
|
|
288
|
-
if (!srcVal) continue;
|
|
289
|
-
if (prop === "display") {
|
|
290
|
-
cloneStyle.display = srcVal === "none" && !(tagName && (tagName === "EF-CAPTIONS-ACTIVE-WORD" || tagName === "EF-CAPTIONS-BEFORE-ACTIVE-WORD" || tagName === "EF-CAPTIONS-AFTER-ACTIVE-WORD" || tagName === "EF-CAPTIONS-SEGMENT")) ? "block" : srcVal;
|
|
291
|
-
continue;
|
|
292
|
-
}
|
|
293
|
-
if (prop === "clipPath") continue;
|
|
294
|
-
if (isDefaultValue(prop, srcVal)) {
|
|
295
|
-
if (cloneStyle[prop]) cloneStyle[prop] = "";
|
|
296
|
-
continue;
|
|
297
|
-
}
|
|
298
|
-
cloneStyle[prop] = srcVal;
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
cloneStyle.animation = "none";
|
|
302
|
-
cloneStyle.transition = "none";
|
|
303
|
-
}
|
|
304
|
-
/**
|
|
305
|
-
* Refresh canvas pixel content from shadow DOM source.
|
|
306
|
-
* Handles both shadow canvas and shadow img sources.
|
|
307
|
-
*/
|
|
308
|
-
function refreshCanvasPixels(node) {
|
|
309
|
-
const { source, clone } = node;
|
|
310
|
-
const canvas = clone;
|
|
311
|
-
const shadowCanvas = source.shadowRoot?.querySelector("canvas");
|
|
312
|
-
const shadowImg = source.shadowRoot?.querySelector("img");
|
|
313
|
-
if (shadowCanvas) {
|
|
314
|
-
if (canvas.width !== shadowCanvas.width) canvas.width = shadowCanvas.width;
|
|
315
|
-
if (canvas.height !== shadowCanvas.height) canvas.height = shadowCanvas.height;
|
|
316
|
-
const ctx = canvas.getContext("2d");
|
|
317
|
-
if (ctx && shadowCanvas.width > 0 && shadowCanvas.height > 0) try {
|
|
318
|
-
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
319
|
-
ctx.drawImage(shadowCanvas, 0, 0);
|
|
320
|
-
} catch (e) {
|
|
321
|
-
logger.warn("[refreshCanvasPixels] Canvas draw failed:", e);
|
|
322
|
-
}
|
|
323
|
-
} else if (shadowImg?.complete && shadowImg.naturalWidth > 0) {
|
|
324
|
-
if (canvas.width !== shadowImg.naturalWidth) canvas.width = shadowImg.naturalWidth;
|
|
325
|
-
if (canvas.height !== shadowImg.naturalHeight) canvas.height = shadowImg.naturalHeight;
|
|
326
|
-
const ctx = canvas.getContext("2d");
|
|
327
|
-
if (ctx) {
|
|
328
|
-
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
329
|
-
try {
|
|
330
|
-
ctx.drawImage(shadowImg, 0, 0);
|
|
331
|
-
} catch {}
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
/**
|
|
336
|
-
* Sync text content from light DOM to clone.
|
|
337
|
-
*/
|
|
338
|
-
function syncTextContent(source, clone) {
|
|
339
|
-
const srcTextNode = source.childNodes[0];
|
|
340
|
-
if (srcTextNode?.nodeType === Node.TEXT_NODE) {
|
|
341
|
-
const srcText = srcTextNode.textContent || "";
|
|
342
|
-
const cloneTextNode = clone.childNodes[0];
|
|
343
|
-
if (cloneTextNode?.nodeType === Node.TEXT_NODE) {
|
|
344
|
-
if (cloneTextNode.textContent !== srcText) cloneTextNode.textContent = srcText;
|
|
345
|
-
} else if (!clone.childNodes.length) clone.appendChild(document.createTextNode(srcText));
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
/**
|
|
349
|
-
* Sync input element value.
|
|
350
|
-
*/
|
|
351
|
-
function syncInputValue(source, clone) {
|
|
352
|
-
if (source instanceof HTMLInputElement) {
|
|
353
|
-
const srcVal = source.value;
|
|
354
|
-
const cloneInput = clone;
|
|
355
|
-
if (cloneInput.value !== srcVal) {
|
|
356
|
-
cloneInput.value = srcVal;
|
|
357
|
-
cloneInput.setAttribute("value", srcVal);
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
/**
|
|
362
|
-
* Build clone tree structure with minimal overhead.
|
|
363
|
-
* Caches temporal bounds on each node for visibility checks.
|
|
364
|
-
* Optionally syncs styles in the same pass if timeMs is provided.
|
|
365
|
-
*/
|
|
366
|
-
function buildCloneStructure(source, timeMs) {
|
|
367
|
-
const container = document.createElement("div");
|
|
368
|
-
container.style.cssText = "position:absolute;top:0;left:0;width:100%;height:100%";
|
|
369
|
-
let nodeCount = 0;
|
|
370
|
-
const canvasSourceMap = /* @__PURE__ */ new WeakMap();
|
|
371
|
-
function cloneElement(srcEl, parentNode) {
|
|
372
|
-
if (SKIP_TAGS.has(srcEl.tagName)) return null;
|
|
373
|
-
const bounds = getTemporalBounds(srcEl);
|
|
374
|
-
if (srcEl instanceof HTMLCanvasElement) {
|
|
375
|
-
const canvas = document.createElement("canvas");
|
|
376
|
-
canvas.width = srcEl.width;
|
|
377
|
-
canvas.height = srcEl.height;
|
|
378
|
-
const ctx = canvas.getContext("2d");
|
|
379
|
-
if (ctx) try {
|
|
380
|
-
ctx.drawImage(srcEl, 0, 0);
|
|
381
|
-
} catch {}
|
|
382
|
-
canvas.style.width = `${srcEl.width}px`;
|
|
383
|
-
canvas.style.height = `${srcEl.height}px`;
|
|
384
|
-
try {
|
|
385
|
-
const cs = getComputedStyle(srcEl);
|
|
386
|
-
canvas.style.position = cs.position;
|
|
387
|
-
canvas.style.top = cs.top;
|
|
388
|
-
canvas.style.right = cs.right;
|
|
389
|
-
canvas.style.bottom = cs.bottom;
|
|
390
|
-
canvas.style.left = cs.left;
|
|
391
|
-
canvas.style.margin = cs.margin;
|
|
392
|
-
canvas.style.zIndex = cs.zIndex;
|
|
393
|
-
canvas.style.transform = cs.transform;
|
|
394
|
-
canvas.style.transformOrigin = cs.transformOrigin;
|
|
395
|
-
canvas.style.opacity = cs.opacity;
|
|
396
|
-
canvas.style.visibility = cs.visibility;
|
|
397
|
-
canvas.style.display = "block";
|
|
398
|
-
} catch {}
|
|
399
|
-
canvasSourceMap.set(canvas, srcEl);
|
|
400
|
-
const node$1 = {
|
|
401
|
-
source: srcEl,
|
|
402
|
-
clone: canvas,
|
|
403
|
-
children: [],
|
|
404
|
-
isCanvasClone: true,
|
|
405
|
-
bounds,
|
|
406
|
-
parent: parentNode
|
|
407
|
-
};
|
|
408
|
-
nodeCount++;
|
|
409
|
-
return node$1;
|
|
410
|
-
}
|
|
411
|
-
const isCustom = srcEl.tagName.includes("-");
|
|
412
|
-
if (isCustom && srcEl.shadowRoot) {
|
|
413
|
-
const shadowCanvas = srcEl.shadowRoot.querySelector("canvas");
|
|
414
|
-
if (shadowCanvas) {
|
|
415
|
-
const clone$1 = document.createElement("canvas");
|
|
416
|
-
clone$1.width = shadowCanvas.width || srcEl.clientWidth;
|
|
417
|
-
clone$1.height = shadowCanvas.height || srcEl.clientHeight;
|
|
418
|
-
if (srcEl.tagName === "EF-WAVEFORM") clone$1.dataset.preserveAlpha = "true";
|
|
419
|
-
else if (srcEl.tagName === "EF-IMAGE") {
|
|
420
|
-
const hasAlpha = "hasAlpha" in srcEl && srcEl.hasAlpha;
|
|
421
|
-
if (hasAlpha) clone$1.dataset.preserveAlpha = "true";
|
|
422
|
-
console.log(`[buildCloneStructure] EF-IMAGE canvas: size=${clone$1.width}x${clone$1.height}, hasAlpha=${hasAlpha}, preserveAlpha=${hasAlpha ? "PNG" : "JPEG"}`);
|
|
423
|
-
}
|
|
424
|
-
const ctx = clone$1.getContext("2d");
|
|
425
|
-
if (ctx) try {
|
|
426
|
-
ctx.drawImage(shadowCanvas, 0, 0);
|
|
427
|
-
} catch {}
|
|
428
|
-
try {
|
|
429
|
-
syncElementStyles(srcEl, clone$1, shadowCanvas);
|
|
430
|
-
} catch {}
|
|
431
|
-
canvasSourceMap.set(clone$1, srcEl);
|
|
432
|
-
const node$1 = {
|
|
433
|
-
source: srcEl,
|
|
434
|
-
clone: clone$1,
|
|
435
|
-
children: [],
|
|
436
|
-
isCanvasClone: true,
|
|
437
|
-
bounds,
|
|
438
|
-
parent: parentNode
|
|
439
|
-
};
|
|
440
|
-
nodeCount++;
|
|
441
|
-
return node$1;
|
|
442
|
-
}
|
|
443
|
-
const shadowImg = srcEl.shadowRoot.querySelector("img");
|
|
444
|
-
if (shadowImg?.complete && shadowImg.naturalWidth > 0) {
|
|
445
|
-
const clone$1 = document.createElement("canvas");
|
|
446
|
-
clone$1.width = shadowImg.naturalWidth;
|
|
447
|
-
clone$1.height = shadowImg.naturalHeight;
|
|
448
|
-
if (srcEl.tagName === "EF-IMAGE") {
|
|
449
|
-
if ("hasAlpha" in srcEl && srcEl.hasAlpha) clone$1.dataset.preserveAlpha = "true";
|
|
450
|
-
}
|
|
451
|
-
const ctx = clone$1.getContext("2d");
|
|
452
|
-
if (ctx) try {
|
|
453
|
-
ctx.drawImage(shadowImg, 0, 0);
|
|
454
|
-
} catch {}
|
|
455
|
-
try {
|
|
456
|
-
syncElementStyles(srcEl, clone$1, shadowImg);
|
|
457
|
-
} catch {}
|
|
458
|
-
canvasSourceMap.set(clone$1, srcEl);
|
|
459
|
-
const node$1 = {
|
|
460
|
-
source: srcEl,
|
|
461
|
-
clone: clone$1,
|
|
462
|
-
children: [],
|
|
463
|
-
isCanvasClone: true,
|
|
464
|
-
bounds,
|
|
465
|
-
parent: parentNode
|
|
466
|
-
};
|
|
467
|
-
nodeCount++;
|
|
468
|
-
return node$1;
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
let clone;
|
|
472
|
-
if (srcEl instanceof SVGElement) clone = document.createElementNS("http://www.w3.org/2000/svg", srcEl.tagName);
|
|
473
|
-
else clone = document.createElement(isCustom ? "div" : srcEl.tagName.toLowerCase());
|
|
474
|
-
const attrs = srcEl.attributes;
|
|
475
|
-
const attrLen = attrs.length;
|
|
476
|
-
if (attrLen > 0) for (let i = 0; i < attrLen; i++) {
|
|
477
|
-
const attr = attrs[i];
|
|
478
|
-
const name = attr.name.toLowerCase();
|
|
479
|
-
if (name === "id" || name.startsWith("on")) continue;
|
|
480
|
-
if (isCustom && name !== "class" && !name.startsWith("data-")) continue;
|
|
481
|
-
try {
|
|
482
|
-
clone.setAttribute(attr.name, attr.value);
|
|
483
|
-
} catch {}
|
|
484
|
-
}
|
|
485
|
-
if (srcEl instanceof HTMLImageElement && srcEl.src) clone.src = srcEl.src;
|
|
486
|
-
if (srcEl instanceof HTMLInputElement) clone.value = srcEl.value;
|
|
487
|
-
const node = {
|
|
488
|
-
source: srcEl,
|
|
489
|
-
clone,
|
|
490
|
-
children: [],
|
|
491
|
-
isCanvasClone: false,
|
|
492
|
-
bounds,
|
|
493
|
-
parent: parentNode
|
|
494
|
-
};
|
|
495
|
-
nodeCount++;
|
|
496
|
-
if (srcEl.shadowRoot) {
|
|
497
|
-
const shadowChildren = srcEl.shadowRoot.childNodes;
|
|
498
|
-
const shadowLen = shadowChildren.length;
|
|
499
|
-
if (shadowLen > 0) {
|
|
500
|
-
const isTextSegment = srcEl.tagName === "EF-TEXT-SEGMENT";
|
|
501
|
-
let hasTextNode = false;
|
|
502
|
-
for (let i = 0; i < shadowLen; i++) {
|
|
503
|
-
const child = shadowChildren[i];
|
|
504
|
-
if (child.nodeType === Node.TEXT_NODE) {
|
|
505
|
-
if (child.textContent?.trim() || isTextSegment) {
|
|
506
|
-
clone.appendChild(document.createTextNode(child.textContent || ""));
|
|
507
|
-
hasTextNode = true;
|
|
508
|
-
}
|
|
509
|
-
} else if (child.nodeType === Node.ELEMENT_NODE) {
|
|
510
|
-
const el = child;
|
|
511
|
-
if (el.tagName === "STYLE" || el.tagName === "SLOT") continue;
|
|
512
|
-
const childNode = cloneElement(el, node);
|
|
513
|
-
if (childNode) {
|
|
514
|
-
node.children.push(childNode);
|
|
515
|
-
clone.appendChild(childNode.clone);
|
|
516
|
-
}
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
if (isTextSegment && !hasTextNode) clone.appendChild(document.createTextNode(""));
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
const lightChildren = srcEl.childNodes;
|
|
523
|
-
const lightLen = lightChildren.length;
|
|
524
|
-
for (let i = 0; i < lightLen; i++) {
|
|
525
|
-
const child = lightChildren[i];
|
|
526
|
-
if (child.nodeType === Node.TEXT_NODE) {
|
|
527
|
-
const text = child.textContent?.trim();
|
|
528
|
-
if (text) clone.appendChild(document.createTextNode(text));
|
|
529
|
-
} else if (child.nodeType === Node.ELEMENT_NODE) {
|
|
530
|
-
const childNode = cloneElement(child, node);
|
|
531
|
-
if (childNode) {
|
|
532
|
-
node.children.push(childNode);
|
|
533
|
-
clone.appendChild(childNode.clone);
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
return node;
|
|
538
|
-
}
|
|
539
|
-
const root = cloneElement(source, null);
|
|
540
|
-
if (root) container.appendChild(root.clone);
|
|
541
|
-
const syncState = {
|
|
542
|
-
tree: { root },
|
|
543
|
-
nodeCount,
|
|
544
|
-
canvasSourceMap,
|
|
545
|
-
previousVisibleSet: /* @__PURE__ */ new Set(),
|
|
546
|
-
currentVisibleSet: /* @__PURE__ */ new Set()
|
|
547
|
-
};
|
|
548
|
-
if (timeMs !== void 0 && root) syncStylesWithIndex(syncState, timeMs);
|
|
549
|
-
return {
|
|
550
|
-
container,
|
|
551
|
-
syncState
|
|
552
|
-
};
|
|
553
|
-
}
|
|
554
|
-
/**
|
|
555
|
-
* Sync a single node's styles (extracted for reuse).
|
|
556
|
-
* Now uses unified style syncing with clear separation of concerns:
|
|
557
|
-
* 1. Canvas pixel refresh (if canvas clone)
|
|
558
|
-
* 2. Unified CSS property sync (all elements)
|
|
559
|
-
* 3. Content sync (text, input values)
|
|
560
|
-
*/
|
|
561
|
-
function syncNodeStyles(node) {
|
|
562
|
-
const { source, clone, isCanvasClone } = node;
|
|
563
|
-
if (isCanvasClone) refreshCanvasPixels(node);
|
|
564
|
-
syncElementStyles(source, clone, isCanvasClone ? source.shadowRoot?.querySelector("canvas") || source.shadowRoot?.querySelector("img") || void 0 : void 0);
|
|
565
|
-
syncTextContent(source, clone);
|
|
566
|
-
syncInputValue(source, clone);
|
|
567
|
-
}
|
|
568
|
-
let syncStats = {
|
|
569
|
-
nodesVisited: 0,
|
|
570
|
-
nodesCulledByParent: 0,
|
|
571
|
-
nodesCulledByTemporal: 0,
|
|
572
|
-
nodesProcessed: 0,
|
|
573
|
-
nodesFullSync: 0,
|
|
574
|
-
nodesIncrementalSync: 0,
|
|
575
|
-
nodesHidden: 0,
|
|
576
|
-
indexQueryTimeMs: 0,
|
|
577
|
-
syncTimeMs: 0
|
|
578
|
-
};
|
|
579
|
-
/**
|
|
580
|
-
* Compute visibility delta between previous and current frame.
|
|
581
|
-
*/
|
|
582
|
-
function computeVisibilityDelta(previousSet, currentSet) {
|
|
583
|
-
const nowVisible = /* @__PURE__ */ new Set();
|
|
584
|
-
const stillVisible = /* @__PURE__ */ new Set();
|
|
585
|
-
const nowHidden = /* @__PURE__ */ new Set();
|
|
586
|
-
for (const node of currentSet) if (previousSet.has(node)) stillVisible.add(node);
|
|
587
|
-
else nowVisible.add(node);
|
|
588
|
-
for (const node of previousSet) if (!currentSet.has(node)) nowHidden.add(node);
|
|
589
|
-
return {
|
|
590
|
-
nowVisible,
|
|
591
|
-
stillVisible,
|
|
592
|
-
nowHidden
|
|
593
|
-
};
|
|
594
|
-
}
|
|
595
|
-
/**
|
|
596
|
-
* Build visible set by recursive traversal with bounds checking.
|
|
597
|
-
* Queries fresh bounds from source elements each time - bounds are computed
|
|
598
|
-
* dynamically by timegroups based on composition mode.
|
|
599
|
-
*/
|
|
600
|
-
function buildVisibleSetRecursive(node, timeMs, visibleSet) {
|
|
601
|
-
const { children, source } = node;
|
|
602
|
-
const bounds = getTemporalBounds(source);
|
|
603
|
-
if (timeMs >= bounds.startMs && timeMs <= bounds.endMs) {
|
|
604
|
-
visibleSet.add(node);
|
|
605
|
-
for (const child of children) buildVisibleSetRecursive(child, timeMs, visibleSet);
|
|
606
|
-
}
|
|
607
|
-
}
|
|
608
|
-
/**
|
|
609
|
-
* Sync styles with recursive visibility check and delta tracking.
|
|
610
|
-
*
|
|
611
|
-
* DELTA TRACKING: Tracks visibility changes between frames to minimize work:
|
|
612
|
-
* - nowVisible nodes: Full style sync + show
|
|
613
|
-
* - stillVisible nodes: Incremental sync (source DOM may have changed)
|
|
614
|
-
* - nowHidden nodes: Just hide (display:none)
|
|
615
|
-
*/
|
|
616
|
-
function syncStylesWithIndex(state, timeMs) {
|
|
617
|
-
const queryStart = performance.now();
|
|
618
|
-
const visibleSet = /* @__PURE__ */ new Set();
|
|
619
|
-
if (state.tree.root) buildVisibleSetRecursive(state.tree.root, timeMs, visibleSet);
|
|
620
|
-
const delta = computeVisibilityDelta(state.previousVisibleSet, visibleSet);
|
|
621
|
-
syncStats.indexQueryTimeMs = performance.now() - queryStart;
|
|
622
|
-
const syncStart = performance.now();
|
|
623
|
-
if (state.tree.root) syncNodeWithDelta(state.tree.root, visibleSet, delta);
|
|
624
|
-
syncStats.syncTimeMs = performance.now() - syncStart;
|
|
625
|
-
state.previousVisibleSet = visibleSet;
|
|
626
|
-
state.currentVisibleSet = visibleSet;
|
|
627
|
-
}
|
|
628
|
-
/**
|
|
629
|
-
* Sync a node using visibility delta for incremental updates.
|
|
630
|
-
*
|
|
631
|
-
* DELTA TRACKING optimization:
|
|
632
|
-
* - nowVisible: Full style sync (element just appeared)
|
|
633
|
-
* - stillVisible: Incremental sync (source DOM may have changed)
|
|
634
|
-
* - nowHidden: Just hide the element
|
|
635
|
-
* - Not in any set: Skip entirely (was already hidden)
|
|
636
|
-
*/
|
|
637
|
-
function syncNodeWithDelta(node, visibleSet, delta) {
|
|
638
|
-
syncStats.nodesVisited++;
|
|
639
|
-
if (!visibleSet.has(node)) {
|
|
640
|
-
node.clone.style.display = "none";
|
|
641
|
-
if (delta.nowHidden.has(node)) syncStats.nodesHidden++;
|
|
642
|
-
syncStats.nodesCulledByTemporal++;
|
|
643
|
-
return;
|
|
644
|
-
}
|
|
645
|
-
if (delta.nowVisible.has(node)) {
|
|
646
|
-
syncNodeStyles(node);
|
|
647
|
-
syncStats.nodesFullSync++;
|
|
648
|
-
} else if (delta.stillVisible.has(node)) {
|
|
649
|
-
syncNodeStyles(node);
|
|
650
|
-
syncStats.nodesIncrementalSync++;
|
|
651
|
-
}
|
|
652
|
-
syncStats.nodesProcessed++;
|
|
653
|
-
for (const child of node.children) syncNodeWithDelta(child, visibleSet, delta);
|
|
654
|
-
}
|
|
655
|
-
/**
|
|
656
|
-
* Collect document styles for shadow DOM injection.
|
|
657
|
-
*/
|
|
658
|
-
function collectDocumentStyles() {
|
|
659
|
-
const rules = [];
|
|
660
|
-
try {
|
|
661
|
-
for (const sheet of document.styleSheets) try {
|
|
662
|
-
if (sheet.cssRules) for (const rule of sheet.cssRules) rules.push(rule.cssText);
|
|
663
|
-
} catch {}
|
|
664
|
-
} catch {}
|
|
665
|
-
return rules.join("\n");
|
|
666
|
-
}
|
|
667
|
-
/**
|
|
668
|
-
* Override clip-path, opacity, and optionally transform on the root clone element.
|
|
669
|
-
* The source may have these properties set for proxy mode or workbench scaling.
|
|
670
|
-
*
|
|
671
|
-
* @param syncState - The sync state containing the clone tree
|
|
672
|
-
* @param fullReset - If true, also resets opacity and transform (for capture operations)
|
|
673
|
-
*/
|
|
674
|
-
function overrideRootCloneStyles(syncState, fullReset = false) {
|
|
675
|
-
const rootClone = syncState.tree.root?.clone;
|
|
676
|
-
if (!rootClone) return;
|
|
677
|
-
rootClone.style.clipPath = "none";
|
|
678
|
-
if (fullReset) {
|
|
679
|
-
rootClone.style.opacity = "1";
|
|
680
|
-
rootClone.style.transform = "none";
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
|
-
|
|
684
|
-
//#endregion
|
|
685
|
-
export { buildCloneStructure, collectDocumentStyles, overrideRootCloneStyles, removeHiddenNodesForSerialization, restoreHiddenNodes };
|
|
686
|
-
//# sourceMappingURL=renderTimegroupPreview.js.map
|