@editframe/elements 0.33.0-beta → 0.34.5-beta
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 +5 -3
- package/dist/EF_FRAMEGEN.js.map +1 -1
- package/dist/_virtual/{_@oxc-project_runtime@0.94.0 → _@oxc-project_runtime@0.95.0}/helpers/decorate.js +1 -1
- package/dist/canvas/EFCanvas.d.ts +7 -4
- package/dist/canvas/EFCanvas.js +1 -1
- package/dist/canvas/EFCanvasItem.d.ts +4 -4
- package/dist/canvas/EFCanvasItem.js +1 -1
- package/dist/canvas/overlays/SelectionOverlay.d.ts +95 -0
- package/dist/canvas/overlays/SelectionOverlay.js +1 -1
- package/dist/canvas/selection/SelectionController.js +7 -11
- package/dist/canvas/selection/SelectionController.js.map +1 -1
- package/dist/elements/EFAudio.d.ts +25 -7
- package/dist/elements/EFAudio.js +31 -61
- package/dist/elements/EFAudio.js.map +1 -1
- package/dist/elements/EFCaptions.d.ts +65 -52
- package/dist/elements/EFCaptions.js +186 -400
- package/dist/elements/EFCaptions.js.map +1 -1
- package/dist/elements/EFImage.d.ts +34 -6
- package/dist/elements/EFImage.js +114 -79
- package/dist/elements/EFImage.js.map +1 -1
- package/dist/elements/EFMedia/AssetIdMediaEngine.js +17 -17
- package/dist/elements/EFMedia/AssetIdMediaEngine.js.map +1 -1
- package/dist/elements/EFMedia/AssetMediaEngine.js +41 -25
- package/dist/elements/EFMedia/AssetMediaEngine.js.map +1 -1
- package/dist/elements/EFMedia/BaseMediaEngine.js +4 -4
- package/dist/elements/EFMedia/BaseMediaEngine.js.map +1 -1
- package/dist/elements/EFMedia/BufferedSeekingInput.js +1 -1
- package/dist/elements/EFMedia/BufferedSeekingInput.js.map +1 -1
- package/dist/elements/EFMedia/JitMediaEngine.js +31 -17
- 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/videoTasks/ScrubInputCache.js +17 -9
- package/dist/elements/EFMedia/videoTasks/ScrubInputCache.js.map +1 -1
- package/dist/elements/EFMedia.d.ts +66 -20
- package/dist/elements/EFMedia.js +412 -30
- package/dist/elements/EFMedia.js.map +1 -1
- package/dist/elements/EFPanZoom.d.ts +4 -4
- package/dist/elements/EFPanZoom.js +1 -1
- package/dist/elements/EFSourceMixin.js +43 -15
- package/dist/elements/EFSourceMixin.js.map +1 -1
- package/dist/elements/EFSurface.d.ts +23 -10
- package/dist/elements/EFSurface.js +64 -22
- package/dist/elements/EFSurface.js.map +1 -1
- package/dist/elements/EFTemporal.d.ts +8 -2
- package/dist/elements/EFTemporal.js +42 -31
- package/dist/elements/EFTemporal.js.map +1 -1
- package/dist/elements/EFText.d.ts +5 -4
- package/dist/elements/EFText.js +11 -2
- package/dist/elements/EFText.js.map +1 -1
- package/dist/elements/EFTextSegment.d.ts +4 -4
- package/dist/elements/EFTextSegment.js +1 -1
- package/dist/elements/EFThumbnailStrip.d.ts +4 -4
- package/dist/elements/EFThumbnailStrip.js +1 -1
- package/dist/elements/EFTimegroup.d.ts +22 -8
- package/dist/elements/EFTimegroup.js +203 -115
- package/dist/elements/EFTimegroup.js.map +1 -1
- package/dist/elements/EFVideo.d.ts +57 -20
- package/dist/elements/EFVideo.js +324 -72
- package/dist/elements/EFVideo.js.map +1 -1
- package/dist/elements/EFWaveform.d.ts +33 -7
- package/dist/elements/EFWaveform.js +103 -59
- package/dist/elements/EFWaveform.js.map +1 -1
- package/dist/elements/renderTemporalAudio.js +14 -3
- package/dist/elements/renderTemporalAudio.js.map +1 -1
- package/dist/getRenderInfo.d.ts +2 -2
- package/dist/gui/ContextMixin.js +1 -1
- package/dist/gui/Controllable.d.ts +2 -0
- package/dist/gui/EFActiveRootTemporal.d.ts +4 -4
- package/dist/gui/EFActiveRootTemporal.js +1 -1
- package/dist/gui/EFConfiguration.d.ts +4 -4
- package/dist/gui/EFConfiguration.js +1 -1
- package/dist/gui/EFControls.d.ts +2 -2
- package/dist/gui/EFControls.js +1 -1
- package/dist/gui/EFDial.d.ts +4 -4
- package/dist/gui/EFDial.js +1 -1
- package/dist/gui/EFFilmstrip.d.ts +3 -2
- package/dist/gui/EFFilmstrip.js +1 -1
- package/dist/gui/EFFitScale.js +1 -1
- package/dist/gui/EFFocusOverlay.d.ts +4 -4
- package/dist/gui/EFFocusOverlay.js +1 -1
- package/dist/gui/EFOverlayItem.d.ts +4 -4
- package/dist/gui/EFOverlayItem.js +1 -1
- package/dist/gui/EFOverlayLayer.d.ts +4 -4
- package/dist/gui/EFOverlayLayer.js +1 -1
- 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.d.ts +4 -4
- package/dist/gui/EFPreview.js +1 -1
- package/dist/gui/EFResizableBox.d.ts +4 -4
- package/dist/gui/EFResizableBox.js +1 -1
- package/dist/gui/EFScrubber.d.ts +4 -4
- package/dist/gui/EFScrubber.js +1 -1
- package/dist/gui/EFTimeDisplay.d.ts +4 -4
- package/dist/gui/EFTimeDisplay.js +1 -1
- package/dist/gui/EFTimelineRuler.d.ts +4 -4
- package/dist/gui/EFTimelineRuler.js +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 +1 -1
- package/dist/gui/EFWorkbench.d.ts +5 -4
- package/dist/gui/EFWorkbench.js +1 -1
- package/dist/gui/PlaybackController.d.ts +10 -2
- package/dist/gui/PlaybackController.js +52 -30
- 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 +1 -1
- package/dist/gui/hierarchy/EFHierarchy.d.ts +4 -4
- package/dist/gui/hierarchy/EFHierarchy.js +1 -1
- package/dist/gui/hierarchy/EFHierarchyItem.d.ts +3 -3
- package/dist/gui/hierarchy/EFHierarchyItem.js +1 -1
- package/dist/gui/timeline/EFTimeline.d.ts +6 -2
- package/dist/gui/timeline/EFTimeline.js +1 -1
- package/dist/gui/timeline/EFTimelineRow.d.ts +57 -0
- package/dist/gui/timeline/EFTimelineRow.js +1 -1
- package/dist/gui/timeline/TrimHandles.d.ts +4 -4
- package/dist/gui/timeline/TrimHandles.js +1 -1
- package/dist/gui/timeline/tracks/AudioTrack.d.ts +2 -0
- package/dist/gui/timeline/tracks/AudioTrack.js +1 -1
- package/dist/gui/timeline/tracks/CaptionsTrack.d.ts +58 -0
- package/dist/gui/timeline/tracks/CaptionsTrack.js +1 -1
- package/dist/gui/timeline/tracks/HTMLTrack.d.ts +13 -0
- package/dist/gui/timeline/tracks/HTMLTrack.js +1 -1
- package/dist/gui/timeline/tracks/ImageTrack.d.ts +14 -0
- package/dist/gui/timeline/tracks/ImageTrack.js +1 -1
- package/dist/gui/timeline/tracks/TextTrack.d.ts +26 -0
- package/dist/gui/timeline/tracks/TextTrack.js +1 -1
- package/dist/gui/timeline/tracks/TimegroupTrack.d.ts +47 -0
- package/dist/gui/timeline/tracks/TimegroupTrack.js +4 -12
- package/dist/gui/timeline/tracks/TimegroupTrack.js.map +1 -1
- package/dist/gui/timeline/tracks/TrackItem.d.ts +81 -0
- package/dist/gui/timeline/tracks/TrackItem.js +1 -1
- package/dist/gui/timeline/tracks/VideoTrack.d.ts +25 -0
- package/dist/gui/timeline/tracks/VideoTrack.js +1 -1
- package/dist/gui/timeline/tracks/WaveformTrack.d.ts +14 -0
- package/dist/gui/timeline/tracks/WaveformTrack.js +1 -1
- package/dist/gui/timeline/tracks/ensureTrackItemInit.d.ts +1 -0
- package/dist/gui/timeline/tracks/preloadTracks.d.ts +9 -0
- package/dist/gui/tree/EFTree.d.ts +5 -4
- package/dist/gui/tree/EFTree.js +1 -1
- package/dist/gui/tree/EFTreeItem.d.ts +4 -4
- package/dist/gui/tree/EFTreeItem.js +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/preview/AdaptiveResolutionTracker.js +6 -14
- package/dist/preview/AdaptiveResolutionTracker.js.map +1 -1
- package/dist/preview/FrameController.d.ts +123 -0
- package/dist/preview/FrameController.js +216 -0
- package/dist/preview/FrameController.js.map +1 -0
- package/dist/preview/RenderContext.d.ts +1 -0
- package/dist/preview/RenderContext.js +193 -0
- package/dist/preview/RenderContext.js.map +1 -0
- package/dist/preview/encoding/canvasEncoder.js +166 -0
- package/dist/preview/encoding/canvasEncoder.js.map +1 -0
- package/dist/preview/encoding/mainThreadEncoder.js +39 -0
- package/dist/preview/encoding/mainThreadEncoder.js.map +1 -0
- package/dist/preview/encoding/types.d.ts +1 -0
- package/dist/preview/encoding/workerEncoder.js +58 -0
- package/dist/preview/encoding/workerEncoder.js.map +1 -0
- package/dist/preview/logger.js +41 -0
- package/dist/preview/logger.js.map +1 -0
- package/dist/preview/previewTypes.js +11 -10
- package/dist/preview/previewTypes.js.map +1 -1
- package/dist/preview/renderTimegroupPreview.js +259 -236
- package/dist/preview/renderTimegroupPreview.js.map +1 -1
- package/dist/preview/renderTimegroupToCanvas.d.ts +5 -0
- package/dist/preview/renderTimegroupToCanvas.js +99 -489
- package/dist/preview/renderTimegroupToCanvas.js.map +1 -1
- package/dist/preview/renderTimegroupToVideo.d.ts +1 -0
- package/dist/preview/renderTimegroupToVideo.js +80 -22
- package/dist/preview/renderTimegroupToVideo.js.map +1 -1
- package/dist/preview/renderers.js.map +1 -1
- package/dist/preview/rendering/inlineImages.js +56 -0
- package/dist/preview/rendering/inlineImages.js.map +1 -0
- package/dist/preview/rendering/renderToImage.d.ts +1 -0
- package/dist/preview/rendering/renderToImage.js +120 -0
- package/dist/preview/rendering/renderToImage.js.map +1 -0
- package/dist/preview/rendering/renderToImageForeignObject.js +135 -0
- package/dist/preview/rendering/renderToImageForeignObject.js.map +1 -0
- package/dist/preview/rendering/renderToImageNative.d.ts +1 -0
- package/dist/preview/rendering/renderToImageNative.js +129 -0
- package/dist/preview/rendering/renderToImageNative.js.map +1 -0
- package/dist/preview/rendering/svgSerializer.js +43 -0
- package/dist/preview/rendering/svgSerializer.js.map +1 -0
- package/dist/preview/rendering/types.d.ts +2 -0
- package/dist/preview/statsTrackingStrategy.js +3 -1
- package/dist/preview/statsTrackingStrategy.js.map +1 -1
- package/dist/preview/workers/WorkerPool.js +8 -57
- package/dist/preview/workers/WorkerPool.js.map +1 -1
- package/dist/render/EFRenderAPI.d.ts +35 -0
- package/dist/render/EFRenderAPI.js +1 -0
- package/dist/render/EFRenderAPI.js.map +1 -1
- package/dist/sandbox/PlaybackControls.d.ts +1 -0
- package/dist/sandbox/ScenarioRunner.d.ts +1 -0
- package/dist/sandbox/defineSandbox.d.ts +1 -0
- package/dist/sandbox/index.d.ts +3 -0
- package/dist/style.css +3 -0
- package/dist/transcoding/types/index.d.ts +6 -3
- package/package.json +2 -3
- package/test/EFVideo.framegen.browsertest.ts +8 -1
- package/test/profilingPlugin.ts +1 -3
- package/test/setup.ts +23 -1
- package/dist/EF_INTERACTIVE.js +0 -7
- package/dist/EF_INTERACTIVE.js.map +0 -1
- package/dist/elements/EFMedia/BufferedSeekingInput.d.ts +0 -50
- package/dist/elements/EFMedia/audioTasks/makeAudioBufferTask.d.ts +0 -12
- package/dist/elements/EFMedia/audioTasks/makeAudioBufferTask.js +0 -104
- package/dist/elements/EFMedia/audioTasks/makeAudioBufferTask.js.map +0 -1
- package/dist/elements/EFMedia/audioTasks/makeAudioFrequencyAnalysisTask.js +0 -168
- package/dist/elements/EFMedia/audioTasks/makeAudioFrequencyAnalysisTask.js.map +0 -1
- package/dist/elements/EFMedia/audioTasks/makeAudioInitSegmentFetchTask.js +0 -46
- package/dist/elements/EFMedia/audioTasks/makeAudioInitSegmentFetchTask.js.map +0 -1
- package/dist/elements/EFMedia/audioTasks/makeAudioInputTask.js +0 -49
- package/dist/elements/EFMedia/audioTasks/makeAudioInputTask.js.map +0 -1
- package/dist/elements/EFMedia/audioTasks/makeAudioSeekTask.js +0 -30
- package/dist/elements/EFMedia/audioTasks/makeAudioSeekTask.js.map +0 -1
- package/dist/elements/EFMedia/audioTasks/makeAudioSegmentFetchTask.js +0 -49
- package/dist/elements/EFMedia/audioTasks/makeAudioSegmentFetchTask.js.map +0 -1
- package/dist/elements/EFMedia/audioTasks/makeAudioSegmentIdTask.js +0 -47
- package/dist/elements/EFMedia/audioTasks/makeAudioSegmentIdTask.js.map +0 -1
- package/dist/elements/EFMedia/audioTasks/makeAudioTimeDomainAnalysisTask.js +0 -140
- package/dist/elements/EFMedia/audioTasks/makeAudioTimeDomainAnalysisTask.js.map +0 -1
- package/dist/elements/EFMedia/shared/BufferUtils.d.ts +0 -13
- package/dist/elements/EFMedia/shared/BufferUtils.js +0 -86
- package/dist/elements/EFMedia/shared/BufferUtils.js.map +0 -1
- package/dist/elements/EFMedia/shared/MediaTaskUtils.d.ts +0 -17
- package/dist/elements/EFMedia/tasks/makeMediaEngineTask.js +0 -90
- package/dist/elements/EFMedia/tasks/makeMediaEngineTask.js.map +0 -1
- package/dist/elements/EFMedia/videoTasks/makeScrubVideoBufferTask.js +0 -80
- package/dist/elements/EFMedia/videoTasks/makeScrubVideoBufferTask.js.map +0 -1
- package/dist/elements/EFMedia/videoTasks/makeScrubVideoInitSegmentFetchTask.js +0 -49
- package/dist/elements/EFMedia/videoTasks/makeScrubVideoInitSegmentFetchTask.js.map +0 -1
- package/dist/elements/EFMedia/videoTasks/makeScrubVideoInputTask.js +0 -58
- package/dist/elements/EFMedia/videoTasks/makeScrubVideoInputTask.js.map +0 -1
- package/dist/elements/EFMedia/videoTasks/makeScrubVideoSeekTask.js +0 -71
- package/dist/elements/EFMedia/videoTasks/makeScrubVideoSeekTask.js.map +0 -1
- package/dist/elements/EFMedia/videoTasks/makeScrubVideoSegmentFetchTask.js +0 -52
- package/dist/elements/EFMedia/videoTasks/makeScrubVideoSegmentFetchTask.js.map +0 -1
- package/dist/elements/EFMedia/videoTasks/makeScrubVideoSegmentIdTask.js +0 -50
- package/dist/elements/EFMedia/videoTasks/makeScrubVideoSegmentIdTask.js.map +0 -1
- package/dist/elements/EFMedia/videoTasks/makeUnifiedVideoSeekTask.js +0 -109
- package/dist/elements/EFMedia/videoTasks/makeUnifiedVideoSeekTask.js.map +0 -1
- package/dist/elements/EFMedia/videoTasks/makeVideoBufferTask.d.ts +0 -12
- package/dist/elements/EFMedia/videoTasks/makeVideoBufferTask.js +0 -97
- package/dist/elements/EFMedia/videoTasks/makeVideoBufferTask.js.map +0 -1
- package/dist/elements/SampleBuffer.d.ts +0 -19
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { logger } from "./logger.js";
|
|
1
2
|
import { getTemporalBounds, isTemporal, isVisibleAtTime } from "./previewTypes.js";
|
|
2
3
|
|
|
3
4
|
//#region src/preview/renderTimegroupPreview.ts
|
|
@@ -77,15 +78,6 @@ const SYNC_PROPERTIES = [
|
|
|
77
78
|
"userSelect",
|
|
78
79
|
"overflow"
|
|
79
80
|
];
|
|
80
|
-
/** Set version of SYNC_PROPERTIES for O(1) validation lookups */
|
|
81
|
-
const SYNC_PROPERTIES_SET = new Set(SYNC_PROPERTIES);
|
|
82
|
-
/**
|
|
83
|
-
* Validation state for property change detection.
|
|
84
|
-
* Reset via resetPropertyValidation() at start of export.
|
|
85
|
-
*/
|
|
86
|
-
let _propertyValidationEnabled = false;
|
|
87
|
-
let _validationFrameCount = 0;
|
|
88
|
-
let _baselineSnapshot = null;
|
|
89
81
|
/**
|
|
90
82
|
* Kebab-case versions for computedStyleMap.get() - pre-computed for speed.
|
|
91
83
|
*/
|
|
@@ -162,24 +154,90 @@ function isDefaultValue(prop, value) {
|
|
|
162
154
|
return defaults === value;
|
|
163
155
|
}
|
|
164
156
|
/**
|
|
157
|
+
* Remove hidden nodes from the clone DOM for serialization.
|
|
158
|
+
* Returns info needed to restore them afterward.
|
|
159
|
+
*
|
|
160
|
+
* This physically removes non-visible nodes so they won't be serialized,
|
|
161
|
+
* avoiding the cost of serializing hidden elements and their resources.
|
|
162
|
+
*/
|
|
163
|
+
function removeHiddenNodesForSerialization(state) {
|
|
164
|
+
const removed = [];
|
|
165
|
+
const visibleSet = state.currentVisibleSet;
|
|
166
|
+
function visit(node) {
|
|
167
|
+
for (const child of node.children) visit(child);
|
|
168
|
+
if (!visibleSet.has(node)) {
|
|
169
|
+
const parent = node.clone.parentNode;
|
|
170
|
+
if (parent) {
|
|
171
|
+
const nextSibling = node.clone.nextSibling;
|
|
172
|
+
parent.removeChild(node.clone);
|
|
173
|
+
removed.push({
|
|
174
|
+
node,
|
|
175
|
+
parent,
|
|
176
|
+
nextSibling
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
if (state.tree.root) visit(state.tree.root);
|
|
182
|
+
return removed;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Restore previously removed hidden nodes to the clone DOM.
|
|
186
|
+
* Must be called after serialization to maintain tree integrity for next frame.
|
|
187
|
+
*/
|
|
188
|
+
function restoreHiddenNodes(removed) {
|
|
189
|
+
for (let i = removed.length - 1; i >= 0; i--) {
|
|
190
|
+
const { node, parent, nextSibling } = removed[i];
|
|
191
|
+
if (nextSibling) parent.insertBefore(node.clone, nextSibling);
|
|
192
|
+
else parent.appendChild(node.clone);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Helper to copy styles from host and content elements to a canvas clone.
|
|
197
|
+
* Reduces code duplication for shadow canvas and shadow img cases.
|
|
198
|
+
*/
|
|
199
|
+
function copyCanvasCloneStyles(clone, hostCs, contentCs) {
|
|
200
|
+
const s = clone.style;
|
|
201
|
+
s.position = hostCs.position;
|
|
202
|
+
s.top = hostCs.top;
|
|
203
|
+
s.right = hostCs.right;
|
|
204
|
+
s.bottom = hostCs.bottom;
|
|
205
|
+
s.left = hostCs.left;
|
|
206
|
+
s.margin = hostCs.margin;
|
|
207
|
+
s.zIndex = hostCs.zIndex;
|
|
208
|
+
s.transform = hostCs.transform;
|
|
209
|
+
s.transformOrigin = hostCs.transformOrigin;
|
|
210
|
+
s.opacity = hostCs.opacity;
|
|
211
|
+
s.visibility = hostCs.visibility;
|
|
212
|
+
s.width = contentCs.width;
|
|
213
|
+
s.height = contentCs.height;
|
|
214
|
+
s.display = "block";
|
|
215
|
+
s.animation = "none";
|
|
216
|
+
s.transition = "none";
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
165
219
|
* Build clone tree structure with minimal overhead.
|
|
220
|
+
* Caches temporal bounds on each node for visibility checks.
|
|
166
221
|
* Optionally syncs styles in the same pass if timeMs is provided.
|
|
167
222
|
*/
|
|
168
223
|
function buildCloneStructure(source, timeMs) {
|
|
169
224
|
const container = document.createElement("div");
|
|
170
225
|
container.style.cssText = "position:absolute;top:0;left:0;width:100%;height:100%";
|
|
171
|
-
|
|
172
|
-
|
|
226
|
+
let nodeCount = 0;
|
|
227
|
+
const canvasSourceMap = /* @__PURE__ */ new WeakMap();
|
|
228
|
+
function cloneElement(srcEl, parentNode) {
|
|
173
229
|
if (SKIP_TAGS.has(srcEl.tagName)) return null;
|
|
230
|
+
const bounds = getTemporalBounds(srcEl);
|
|
174
231
|
if (srcEl instanceof SVGElement) {
|
|
175
232
|
const node$1 = {
|
|
176
233
|
source: srcEl,
|
|
177
234
|
clone: srcEl.cloneNode(true),
|
|
178
235
|
children: [],
|
|
179
236
|
isCanvasClone: false,
|
|
180
|
-
|
|
237
|
+
bounds,
|
|
238
|
+
parent: parentNode
|
|
181
239
|
};
|
|
182
|
-
|
|
240
|
+
nodeCount++;
|
|
183
241
|
return node$1;
|
|
184
242
|
}
|
|
185
243
|
if (srcEl instanceof HTMLCanvasElement) {
|
|
@@ -204,33 +262,18 @@ function buildCloneStructure(source, timeMs) {
|
|
|
204
262
|
ctx.drawImage(shadowCanvas, 0, 0);
|
|
205
263
|
} catch {}
|
|
206
264
|
try {
|
|
207
|
-
|
|
208
|
-
const hostCs = getComputedStyle(srcEl);
|
|
209
|
-
clone$1.style.position = hostCs.position;
|
|
210
|
-
clone$1.style.top = hostCs.top;
|
|
211
|
-
clone$1.style.right = hostCs.right;
|
|
212
|
-
clone$1.style.bottom = hostCs.bottom;
|
|
213
|
-
clone$1.style.left = hostCs.left;
|
|
214
|
-
clone$1.style.margin = hostCs.margin;
|
|
215
|
-
clone$1.style.zIndex = hostCs.zIndex;
|
|
216
|
-
clone$1.style.transform = hostCs.transform;
|
|
217
|
-
clone$1.style.transformOrigin = hostCs.transformOrigin;
|
|
218
|
-
clone$1.style.opacity = hostCs.opacity;
|
|
219
|
-
clone$1.style.visibility = hostCs.visibility;
|
|
220
|
-
clone$1.style.width = canvasCs.width;
|
|
221
|
-
clone$1.style.height = canvasCs.height;
|
|
222
|
-
clone$1.style.display = "block";
|
|
223
|
-
clone$1.style.animation = "none";
|
|
224
|
-
clone$1.style.transition = "none";
|
|
265
|
+
copyCanvasCloneStyles(clone$1, getComputedStyle(srcEl), getComputedStyle(shadowCanvas));
|
|
225
266
|
} catch {}
|
|
267
|
+
canvasSourceMap.set(clone$1, srcEl);
|
|
226
268
|
const node$1 = {
|
|
227
269
|
source: srcEl,
|
|
228
270
|
clone: clone$1,
|
|
229
271
|
children: [],
|
|
230
272
|
isCanvasClone: true,
|
|
231
|
-
|
|
273
|
+
bounds,
|
|
274
|
+
parent: parentNode
|
|
232
275
|
};
|
|
233
|
-
|
|
276
|
+
nodeCount++;
|
|
234
277
|
return node$1;
|
|
235
278
|
}
|
|
236
279
|
const shadowImg = srcEl.shadowRoot.querySelector("img");
|
|
@@ -244,38 +287,26 @@ function buildCloneStructure(source, timeMs) {
|
|
|
244
287
|
ctx.drawImage(shadowImg, 0, 0);
|
|
245
288
|
} catch {}
|
|
246
289
|
try {
|
|
247
|
-
|
|
248
|
-
const hostCs = getComputedStyle(srcEl);
|
|
249
|
-
clone$1.style.position = hostCs.position;
|
|
250
|
-
clone$1.style.top = hostCs.top;
|
|
251
|
-
clone$1.style.right = hostCs.right;
|
|
252
|
-
clone$1.style.bottom = hostCs.bottom;
|
|
253
|
-
clone$1.style.left = hostCs.left;
|
|
254
|
-
clone$1.style.margin = hostCs.margin;
|
|
255
|
-
clone$1.style.zIndex = hostCs.zIndex;
|
|
256
|
-
clone$1.style.transform = hostCs.transform;
|
|
257
|
-
clone$1.style.transformOrigin = hostCs.transformOrigin;
|
|
258
|
-
clone$1.style.opacity = hostCs.opacity;
|
|
259
|
-
clone$1.style.visibility = hostCs.visibility;
|
|
260
|
-
clone$1.style.width = imgCs.width;
|
|
261
|
-
clone$1.style.height = imgCs.height;
|
|
262
|
-
clone$1.style.display = "block";
|
|
263
|
-
clone$1.style.animation = "none";
|
|
264
|
-
clone$1.style.transition = "none";
|
|
290
|
+
copyCanvasCloneStyles(clone$1, getComputedStyle(srcEl), getComputedStyle(shadowImg));
|
|
265
291
|
} catch {}
|
|
292
|
+
canvasSourceMap.set(clone$1, srcEl);
|
|
266
293
|
const node$1 = {
|
|
267
294
|
source: srcEl,
|
|
268
295
|
clone: clone$1,
|
|
269
296
|
children: [],
|
|
270
297
|
isCanvasClone: true,
|
|
271
|
-
|
|
298
|
+
bounds,
|
|
299
|
+
parent: parentNode
|
|
272
300
|
};
|
|
273
|
-
|
|
301
|
+
nodeCount++;
|
|
274
302
|
return node$1;
|
|
275
303
|
}
|
|
276
304
|
}
|
|
277
305
|
const clone = document.createElement(isCustom ? "div" : srcEl.tagName.toLowerCase());
|
|
278
|
-
|
|
306
|
+
const attrs = srcEl.attributes;
|
|
307
|
+
const attrLen = attrs.length;
|
|
308
|
+
if (attrLen > 0) for (let i = 0; i < attrLen; i++) {
|
|
309
|
+
const attr = attrs[i];
|
|
279
310
|
const name = attr.name.toLowerCase();
|
|
280
311
|
if (name === "id" || name.startsWith("on")) continue;
|
|
281
312
|
if (isCustom && name !== "class" && !name.startsWith("data-")) continue;
|
|
@@ -290,51 +321,65 @@ function buildCloneStructure(source, timeMs) {
|
|
|
290
321
|
clone,
|
|
291
322
|
children: [],
|
|
292
323
|
isCanvasClone: false,
|
|
293
|
-
|
|
324
|
+
bounds,
|
|
325
|
+
parent: parentNode
|
|
294
326
|
};
|
|
295
|
-
|
|
327
|
+
nodeCount++;
|
|
296
328
|
if (srcEl.shadowRoot) {
|
|
297
|
-
const
|
|
298
|
-
const
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
329
|
+
const shadowChildren = srcEl.shadowRoot.childNodes;
|
|
330
|
+
const shadowLen = shadowChildren.length;
|
|
331
|
+
if (shadowLen > 0) {
|
|
332
|
+
const isTextSegment = srcEl.tagName === "EF-TEXT-SEGMENT";
|
|
333
|
+
let hasTextNode = false;
|
|
334
|
+
for (let i = 0; i < shadowLen; i++) {
|
|
335
|
+
const child = shadowChildren[i];
|
|
336
|
+
if (child.nodeType === Node.TEXT_NODE) {
|
|
337
|
+
if (child.textContent?.trim() || isTextSegment) {
|
|
338
|
+
clone.appendChild(document.createTextNode(child.textContent || ""));
|
|
339
|
+
hasTextNode = true;
|
|
340
|
+
}
|
|
341
|
+
} else if (child.nodeType === Node.ELEMENT_NODE) {
|
|
342
|
+
const el = child;
|
|
343
|
+
if (el.tagName === "STYLE" || el.tagName === "SLOT") continue;
|
|
344
|
+
const childNode = cloneElement(el, node);
|
|
345
|
+
if (childNode) {
|
|
346
|
+
node.children.push(childNode);
|
|
347
|
+
clone.appendChild(childNode.clone);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
304
350
|
}
|
|
351
|
+
if (isTextSegment && !hasTextNode) clone.appendChild(document.createTextNode(""));
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
const lightChildren = srcEl.childNodes;
|
|
355
|
+
const lightLen = lightChildren.length;
|
|
356
|
+
for (let i = 0; i < lightLen; i++) {
|
|
357
|
+
const child = lightChildren[i];
|
|
358
|
+
if (child.nodeType === Node.TEXT_NODE) {
|
|
359
|
+
const text = child.textContent?.trim();
|
|
360
|
+
if (text) clone.appendChild(document.createTextNode(text));
|
|
305
361
|
} else if (child.nodeType === Node.ELEMENT_NODE) {
|
|
306
|
-
const
|
|
307
|
-
if (el.tagName === "STYLE" || el.tagName === "SLOT") continue;
|
|
308
|
-
const childNode = cloneElement(el);
|
|
362
|
+
const childNode = cloneElement(child, node);
|
|
309
363
|
if (childNode) {
|
|
310
364
|
node.children.push(childNode);
|
|
311
365
|
clone.appendChild(childNode.clone);
|
|
312
366
|
}
|
|
313
367
|
}
|
|
314
|
-
if (isCaptionElement && !hasTextNode) clone.appendChild(document.createTextNode(""));
|
|
315
|
-
}
|
|
316
|
-
for (const child of srcEl.childNodes) if (child.nodeType === Node.TEXT_NODE) {
|
|
317
|
-
const text = child.textContent?.trim();
|
|
318
|
-
if (text) clone.appendChild(document.createTextNode(text));
|
|
319
|
-
} else if (child.nodeType === Node.ELEMENT_NODE) {
|
|
320
|
-
const childNode = cloneElement(child);
|
|
321
|
-
if (childNode) {
|
|
322
|
-
node.children.push(childNode);
|
|
323
|
-
clone.appendChild(childNode.clone);
|
|
324
|
-
}
|
|
325
368
|
}
|
|
326
369
|
return node;
|
|
327
370
|
}
|
|
328
|
-
const root = cloneElement(source);
|
|
371
|
+
const root = cloneElement(source, null);
|
|
329
372
|
if (root) container.appendChild(root.clone);
|
|
330
373
|
const syncState = {
|
|
331
374
|
tree: { root },
|
|
332
|
-
nodeCount
|
|
375
|
+
nodeCount,
|
|
376
|
+
canvasSourceMap,
|
|
377
|
+
previousVisibleSet: /* @__PURE__ */ new Set(),
|
|
378
|
+
currentVisibleSet: /* @__PURE__ */ new Set()
|
|
333
379
|
};
|
|
334
|
-
if (timeMs !== void 0 && root)
|
|
380
|
+
if (timeMs !== void 0 && root) syncStylesWithIndex(syncState, timeMs);
|
|
335
381
|
return {
|
|
336
382
|
container,
|
|
337
|
-
pairs: legacyPairs,
|
|
338
383
|
syncState
|
|
339
384
|
};
|
|
340
385
|
}
|
|
@@ -355,42 +400,27 @@ function syncNodeStyles(node) {
|
|
|
355
400
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
356
401
|
ctx.drawImage(shadowCanvas, 0, 0);
|
|
357
402
|
} catch (e) {
|
|
358
|
-
|
|
403
|
+
logger.warn("[syncNodeStyles] Canvas draw failed:", e);
|
|
359
404
|
}
|
|
360
405
|
try {
|
|
361
406
|
const canvasCs = getComputedStyle(shadowCanvas);
|
|
362
407
|
const hostCs = getComputedStyle(source);
|
|
363
408
|
const s = canvas.style;
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
if (s.position !== srcPosition) s.position = srcPosition;
|
|
380
|
-
if (s.top !== srcTop) s.top = srcTop;
|
|
381
|
-
if (s.left !== srcLeft) s.left = srcLeft;
|
|
382
|
-
if (s.right !== srcRight) s.right = srcRight;
|
|
383
|
-
if (s.bottom !== srcBottom) s.bottom = srcBottom;
|
|
384
|
-
if (s.margin !== srcMargin) s.margin = srcMargin;
|
|
385
|
-
if (s.transform !== srcTransform) s.transform = srcTransform;
|
|
386
|
-
if (s.transformOrigin !== srcTransformOrigin) s.transformOrigin = srcTransformOrigin;
|
|
387
|
-
if (s.opacity !== srcOpacity) s.opacity = srcOpacity;
|
|
388
|
-
if (s.visibility !== srcVisibility) s.visibility = srcVisibility;
|
|
389
|
-
if (s.zIndex !== srcZIndex) s.zIndex = srcZIndex;
|
|
390
|
-
if (s.width !== srcWidth) s.width = srcWidth;
|
|
391
|
-
if (s.height !== srcHeight) s.height = srcHeight;
|
|
392
|
-
if (s.backfaceVisibility !== srcBackfaceVisibility) s.backfaceVisibility = srcBackfaceVisibility;
|
|
393
|
-
if (s.transformStyle !== srcTransformStyle) s.transformStyle = srcTransformStyle;
|
|
409
|
+
s.position = hostCs.position;
|
|
410
|
+
s.top = hostCs.top;
|
|
411
|
+
s.left = hostCs.left;
|
|
412
|
+
s.right = hostCs.right;
|
|
413
|
+
s.bottom = hostCs.bottom;
|
|
414
|
+
s.margin = hostCs.margin;
|
|
415
|
+
s.transform = hostCs.transform;
|
|
416
|
+
s.transformOrigin = hostCs.transformOrigin;
|
|
417
|
+
s.opacity = hostCs.opacity;
|
|
418
|
+
s.visibility = hostCs.visibility;
|
|
419
|
+
s.zIndex = hostCs.zIndex;
|
|
420
|
+
s.width = canvasCs.width;
|
|
421
|
+
s.height = canvasCs.height;
|
|
422
|
+
s.backfaceVisibility = hostCs.backfaceVisibility;
|
|
423
|
+
s.transformStyle = hostCs.transformStyle;
|
|
394
424
|
} catch {}
|
|
395
425
|
} else if (shadowImg?.complete && shadowImg.naturalWidth > 0) {
|
|
396
426
|
if (canvas.width !== shadowImg.naturalWidth) canvas.width = shadowImg.naturalWidth;
|
|
@@ -406,42 +436,27 @@ function syncNodeStyles(node) {
|
|
|
406
436
|
const imgCs = getComputedStyle(shadowImg);
|
|
407
437
|
const hostCs = getComputedStyle(source);
|
|
408
438
|
const s = canvas.style;
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
if (s.position !== srcPosition) s.position = srcPosition;
|
|
425
|
-
if (s.top !== srcTop) s.top = srcTop;
|
|
426
|
-
if (s.left !== srcLeft) s.left = srcLeft;
|
|
427
|
-
if (s.right !== srcRight) s.right = srcRight;
|
|
428
|
-
if (s.bottom !== srcBottom) s.bottom = srcBottom;
|
|
429
|
-
if (s.margin !== srcMargin) s.margin = srcMargin;
|
|
430
|
-
if (s.transform !== srcTransform) s.transform = srcTransform;
|
|
431
|
-
if (s.transformOrigin !== srcTransformOrigin) s.transformOrigin = srcTransformOrigin;
|
|
432
|
-
if (s.opacity !== srcOpacity) s.opacity = srcOpacity;
|
|
433
|
-
if (s.visibility !== srcVisibility) s.visibility = srcVisibility;
|
|
434
|
-
if (s.zIndex !== srcZIndex) s.zIndex = srcZIndex;
|
|
435
|
-
if (s.width !== srcWidth) s.width = srcWidth;
|
|
436
|
-
if (s.height !== srcHeight) s.height = srcHeight;
|
|
437
|
-
if (s.backfaceVisibility !== srcBackfaceVisibility) s.backfaceVisibility = srcBackfaceVisibility;
|
|
438
|
-
if (s.transformStyle !== srcTransformStyle) s.transformStyle = srcTransformStyle;
|
|
439
|
+
s.position = hostCs.position;
|
|
440
|
+
s.top = hostCs.top;
|
|
441
|
+
s.left = hostCs.left;
|
|
442
|
+
s.right = hostCs.right;
|
|
443
|
+
s.bottom = hostCs.bottom;
|
|
444
|
+
s.margin = hostCs.margin;
|
|
445
|
+
s.transform = hostCs.transform;
|
|
446
|
+
s.transformOrigin = hostCs.transformOrigin;
|
|
447
|
+
s.opacity = hostCs.opacity;
|
|
448
|
+
s.visibility = hostCs.visibility;
|
|
449
|
+
s.zIndex = hostCs.zIndex;
|
|
450
|
+
s.width = imgCs.width;
|
|
451
|
+
s.height = imgCs.height;
|
|
452
|
+
s.backfaceVisibility = hostCs.backfaceVisibility;
|
|
453
|
+
s.transformStyle = hostCs.transformStyle;
|
|
439
454
|
} catch {}
|
|
440
455
|
}
|
|
441
456
|
}
|
|
442
457
|
const cloneStyle = clone.style;
|
|
443
|
-
const { styleCache } = node;
|
|
444
458
|
const propLen = SYNC_PROPERTIES.length;
|
|
459
|
+
const tagName = source.tagName;
|
|
445
460
|
if (HAS_COMPUTED_STYLE_MAP) {
|
|
446
461
|
let srcMap;
|
|
447
462
|
try {
|
|
@@ -455,10 +470,8 @@ function syncNodeStyles(node) {
|
|
|
455
470
|
const srcVal = srcMap.get(kebab);
|
|
456
471
|
if (!srcVal) continue;
|
|
457
472
|
const strVal = srcVal.toString();
|
|
458
|
-
if (styleCache.get(camel) === strVal) continue;
|
|
459
|
-
styleCache.set(camel, strVal);
|
|
460
473
|
if (camel === "display") {
|
|
461
|
-
cloneStyle.display = strVal === "none" ? "block" : strVal;
|
|
474
|
+
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;
|
|
462
475
|
continue;
|
|
463
476
|
}
|
|
464
477
|
if (camel === "clipPath") continue;
|
|
@@ -478,10 +491,8 @@ function syncNodeStyles(node) {
|
|
|
478
491
|
const srcStyle = cs;
|
|
479
492
|
for (const prop of SYNC_PROPERTIES) {
|
|
480
493
|
const srcVal = srcStyle[prop];
|
|
481
|
-
if (styleCache.get(prop) === srcVal) continue;
|
|
482
|
-
styleCache.set(prop, srcVal);
|
|
483
494
|
if (prop === "display") {
|
|
484
|
-
cloneStyle.display = srcVal === "none" ? "block" : srcVal;
|
|
495
|
+
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;
|
|
485
496
|
continue;
|
|
486
497
|
}
|
|
487
498
|
if (prop === "clipPath") continue;
|
|
@@ -492,30 +503,15 @@ function syncNodeStyles(node) {
|
|
|
492
503
|
cloneStyle[prop] = srcVal;
|
|
493
504
|
}
|
|
494
505
|
}
|
|
495
|
-
|
|
496
|
-
|
|
506
|
+
cloneStyle.animation = "none";
|
|
507
|
+
cloneStyle.transition = "none";
|
|
497
508
|
const srcTextNode = source.childNodes[0];
|
|
498
|
-
|
|
499
|
-
if (srcTextNode?.nodeType === Node.TEXT_NODE && cloneTextNode?.nodeType === Node.TEXT_NODE) {
|
|
509
|
+
if (srcTextNode?.nodeType === Node.TEXT_NODE) {
|
|
500
510
|
const srcText = srcTextNode.textContent || "";
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
const srcShadowRoot = source.shadowRoot;
|
|
506
|
-
if (srcShadowRoot && !srcTextNode) {
|
|
507
|
-
let srcShadowText = "";
|
|
508
|
-
for (const srcChild of srcShadowRoot.childNodes) if (srcChild.nodeType === Node.TEXT_NODE) srcShadowText += srcChild.textContent || "";
|
|
509
|
-
let cloneTextNode$1 = null;
|
|
510
|
-
for (const cloneChild of clone.childNodes) if (cloneChild.nodeType === Node.TEXT_NODE) {
|
|
511
|
-
cloneTextNode$1 = cloneChild;
|
|
512
|
-
break;
|
|
513
|
-
}
|
|
514
|
-
if (!cloneTextNode$1) {
|
|
515
|
-
cloneTextNode$1 = document.createTextNode(srcShadowText);
|
|
516
|
-
clone.appendChild(cloneTextNode$1);
|
|
517
|
-
} else if (cloneTextNode$1.textContent !== srcShadowText) cloneTextNode$1.textContent = srcShadowText;
|
|
518
|
-
}
|
|
511
|
+
const cloneTextNode = clone.childNodes[0];
|
|
512
|
+
if (cloneTextNode?.nodeType === Node.TEXT_NODE) {
|
|
513
|
+
if (cloneTextNode.textContent !== srcText) cloneTextNode.textContent = srcText;
|
|
514
|
+
} else if (!clone.childNodes.length) clone.appendChild(document.createTextNode(srcText));
|
|
519
515
|
}
|
|
520
516
|
if (source instanceof HTMLInputElement) {
|
|
521
517
|
const srcVal = source.value;
|
|
@@ -526,84 +522,111 @@ function syncNodeStyles(node) {
|
|
|
526
522
|
}
|
|
527
523
|
}
|
|
528
524
|
}
|
|
525
|
+
let syncStats = {
|
|
526
|
+
nodesVisited: 0,
|
|
527
|
+
nodesCulledByParent: 0,
|
|
528
|
+
nodesCulledByTemporal: 0,
|
|
529
|
+
nodesProcessed: 0,
|
|
530
|
+
nodesFullSync: 0,
|
|
531
|
+
nodesIncrementalSync: 0,
|
|
532
|
+
nodesHidden: 0,
|
|
533
|
+
indexQueryTimeMs: 0,
|
|
534
|
+
syncTimeMs: 0
|
|
535
|
+
};
|
|
529
536
|
/**
|
|
530
|
-
*
|
|
531
|
-
* Returns early if the node is temporally culled, skipping ALL descendants.
|
|
537
|
+
* Compute visibility delta between previous and current frame.
|
|
532
538
|
*/
|
|
533
|
-
function
|
|
534
|
-
const
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
539
|
+
function computeVisibilityDelta(previousSet, currentSet) {
|
|
540
|
+
const nowVisible = /* @__PURE__ */ new Set();
|
|
541
|
+
const stillVisible = /* @__PURE__ */ new Set();
|
|
542
|
+
const nowHidden = /* @__PURE__ */ new Set();
|
|
543
|
+
for (const node of currentSet) if (previousSet.has(node)) stillVisible.add(node);
|
|
544
|
+
else nowVisible.add(node);
|
|
545
|
+
for (const node of previousSet) if (!currentSet.has(node)) nowHidden.add(node);
|
|
546
|
+
return {
|
|
547
|
+
nowVisible,
|
|
548
|
+
stillVisible,
|
|
549
|
+
nowHidden
|
|
550
|
+
};
|
|
545
551
|
}
|
|
546
552
|
/**
|
|
547
|
-
*
|
|
548
|
-
*
|
|
553
|
+
* Build visible set by recursive traversal with bounds checking.
|
|
554
|
+
* Queries fresh bounds from source elements each time - bounds are computed
|
|
555
|
+
* dynamically by timegroups based on composition mode.
|
|
549
556
|
*/
|
|
550
|
-
function
|
|
551
|
-
|
|
552
|
-
|
|
557
|
+
function buildVisibleSetRecursive(node, timeMs, visibleSet) {
|
|
558
|
+
const { children, source } = node;
|
|
559
|
+
const bounds = getTemporalBounds(source);
|
|
560
|
+
if (timeMs >= bounds.startMs && timeMs <= bounds.endMs) {
|
|
561
|
+
visibleSet.add(node);
|
|
562
|
+
for (const child of children) buildVisibleSetRecursive(child, timeMs, visibleSet);
|
|
563
|
+
}
|
|
553
564
|
}
|
|
554
565
|
/**
|
|
555
|
-
*
|
|
566
|
+
* Sync styles with recursive visibility check and delta tracking.
|
|
567
|
+
*
|
|
568
|
+
* DELTA TRACKING: Tracks visibility changes between frames to minimize work:
|
|
569
|
+
* - nowVisible nodes: Full style sync + show
|
|
570
|
+
* - stillVisible nodes: Incremental sync (source DOM may have changed)
|
|
571
|
+
* - nowHidden nodes: Just hide (display:none)
|
|
556
572
|
*/
|
|
557
|
-
function
|
|
558
|
-
const
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
if (state.tree.root) captureNode(state.tree.root);
|
|
569
|
-
return snapshot;
|
|
573
|
+
function syncStylesWithIndex(state, timeMs) {
|
|
574
|
+
const queryStart = performance.now();
|
|
575
|
+
const visibleSet = /* @__PURE__ */ new Set();
|
|
576
|
+
if (state.tree.root) buildVisibleSetRecursive(state.tree.root, timeMs, visibleSet);
|
|
577
|
+
const delta = computeVisibilityDelta(state.previousVisibleSet, visibleSet);
|
|
578
|
+
syncStats.indexQueryTimeMs = performance.now() - queryStart;
|
|
579
|
+
const syncStart = performance.now();
|
|
580
|
+
if (state.tree.root) syncNodeWithDelta(state.tree.root, visibleSet, delta);
|
|
581
|
+
syncStats.syncTimeMs = performance.now() - syncStart;
|
|
582
|
+
state.previousVisibleSet = visibleSet;
|
|
583
|
+
state.currentVisibleSet = visibleSet;
|
|
570
584
|
}
|
|
571
585
|
/**
|
|
572
|
-
*
|
|
573
|
-
*
|
|
586
|
+
* Sync a node using visibility delta for incremental updates.
|
|
587
|
+
*
|
|
588
|
+
* DELTA TRACKING optimization:
|
|
589
|
+
* - nowVisible: Full style sync (element just appeared)
|
|
590
|
+
* - stillVisible: Incremental sync (source DOM may have changed)
|
|
591
|
+
* - nowHidden: Just hide the element
|
|
592
|
+
* - Not in any set: Skip entirely (was already hidden)
|
|
574
593
|
*/
|
|
575
|
-
function
|
|
576
|
-
|
|
577
|
-
if (
|
|
578
|
-
|
|
594
|
+
function syncNodeWithDelta(node, visibleSet, delta) {
|
|
595
|
+
syncStats.nodesVisited++;
|
|
596
|
+
if (!visibleSet.has(node)) {
|
|
597
|
+
node.clone.style.display = "none";
|
|
598
|
+
if (delta.nowHidden.has(node)) syncStats.nodesHidden++;
|
|
599
|
+
syncStats.nodesCulledByTemporal++;
|
|
579
600
|
return;
|
|
580
601
|
}
|
|
581
|
-
if (
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
for (const [prop, baselineValue] of baselineProps) {
|
|
588
|
-
const currentValue = currentProps.get(prop) ?? "";
|
|
589
|
-
if (baselineValue === currentValue) continue;
|
|
590
|
-
if (!SYNC_PROPERTIES_SET.has(prop)) {
|
|
591
|
-
const elementId = element.id || element.tagName;
|
|
592
|
-
violations.push(`[${elementId}] ${prop}: "${baselineValue}" → "${currentValue}"`);
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
if (violations.length > 0) {
|
|
597
|
-
const message = [
|
|
598
|
-
`\n⚠️ UNEXPECTED PROPERTY CHANGES at frame ${_validationFrameCount}:`,
|
|
599
|
-
`Properties not in SYNC_PROPERTIES changed during export.`,
|
|
600
|
-
``,
|
|
601
|
-
`Violations (${violations.length}):`,
|
|
602
|
-
...violations.slice(0, 20).map((v) => ` ${v}`),
|
|
603
|
-
violations.length > 20 ? ` ... and ${violations.length - 20} more` : ""
|
|
604
|
-
].join("\n");
|
|
605
|
-
throw new Error(message);
|
|
602
|
+
if (delta.nowVisible.has(node)) {
|
|
603
|
+
syncNodeStyles(node);
|
|
604
|
+
syncStats.nodesFullSync++;
|
|
605
|
+
} else if (delta.stillVisible.has(node)) {
|
|
606
|
+
syncNodeStyles(node);
|
|
607
|
+
syncStats.nodesIncrementalSync++;
|
|
606
608
|
}
|
|
609
|
+
syncStats.nodesProcessed++;
|
|
610
|
+
for (const child of node.children) syncNodeWithDelta(child, visibleSet, delta);
|
|
611
|
+
}
|
|
612
|
+
/**
|
|
613
|
+
* Sync all CSS properties from source elements to their clones.
|
|
614
|
+
* Uses interval index for O(log n + k) visibility queries instead of O(n) traversal.
|
|
615
|
+
* Uses delta tracking for incremental updates between frames.
|
|
616
|
+
*/
|
|
617
|
+
function syncStyles(state, timeMs) {
|
|
618
|
+
syncStats = {
|
|
619
|
+
nodesVisited: 0,
|
|
620
|
+
nodesCulledByParent: 0,
|
|
621
|
+
nodesCulledByTemporal: 0,
|
|
622
|
+
nodesProcessed: 0,
|
|
623
|
+
nodesFullSync: 0,
|
|
624
|
+
nodesIncrementalSync: 0,
|
|
625
|
+
nodesHidden: 0,
|
|
626
|
+
indexQueryTimeMs: 0,
|
|
627
|
+
syncTimeMs: 0
|
|
628
|
+
};
|
|
629
|
+
syncStylesWithIndex(state, timeMs);
|
|
607
630
|
}
|
|
608
631
|
/**
|
|
609
632
|
* Collect document styles for shadow DOM injection.
|
|
@@ -652,5 +675,5 @@ function renderTimegroupPreview(source) {
|
|
|
652
675
|
}
|
|
653
676
|
|
|
654
677
|
//#endregion
|
|
655
|
-
export { buildCloneStructure, collectDocumentStyles, overrideRootCloneStyles, renderTimegroupPreview, syncStyles };
|
|
678
|
+
export { buildCloneStructure, collectDocumentStyles, overrideRootCloneStyles, removeHiddenNodesForSerialization, renderTimegroupPreview, restoreHiddenNodes, syncStyles };
|
|
656
679
|
//# sourceMappingURL=renderTimegroupPreview.js.map
|