@hyperframes/studio 0.8.32 → 0.8.34
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/assets/{hyperframes-player-CroojEG1.js → hyperframes-player-D4aSRr_M.js} +1 -1
- package/dist/assets/{index-PVOehm7h.js → index-CkxPQxLJ.js} +182 -172
- package/dist/assets/{index-CSyaU1m2.js → index-aNyQBoJv.js} +1 -1
- package/dist/assets/{index-D0AjUHNT.js → index-hch4ktcC.js} +1 -1
- package/dist/{chunk-A7S5SGNA.js → chunk-7BP32G62.js} +294 -53
- package/dist/chunk-7BP32G62.js.map +1 -0
- package/dist/{domEditingLayers-JMMVOGTO.js → domEditingLayers-UKMVYXT6.js} +2 -2
- package/dist/index.html +1 -1
- package/dist/index.js +354 -206
- package/dist/index.js.map +1 -1
- package/package.json +8 -8
- package/src/App.tsx +6 -4
- package/src/captions/components/CaptionOverlay.sender.test.tsx +47 -0
- package/src/captions/components/CaptionOverlay.tsx +1 -0
- package/src/captions/generator.test.ts +30 -0
- package/src/captions/generator.ts +5 -3
- package/src/captions/hooks/useCaptionSync.ts +3 -2
- package/src/components/MediaPreview.tsx +2 -1
- package/src/components/editor/AnimationCard.test.tsx +3 -3
- package/src/components/editor/PropertyPanel.test.tsx +18 -14
- package/src/components/editor/SnapGuideOverlay.tsx +2 -6
- package/src/components/editor/domEditLayerWalkCache.test.ts +284 -0
- package/src/components/editor/domEditLayerWalkCache.ts +327 -0
- package/src/components/editor/domEditOverlayBasis.ts +72 -0
- package/src/components/editor/domEditOverlayGeometry.ts +78 -83
- package/src/components/editor/domEditOverlayMeasurePass.ts +60 -0
- package/src/components/editor/domEditOverlayTransform.ts +47 -9
- package/src/components/editor/domEditingDom.ts +63 -14
- package/src/components/editor/domEditingElement.ts +56 -14
- package/src/components/editor/domEditingLayers.test.ts +48 -0
- package/src/components/editor/domEditingLayers.ts +22 -35
- package/src/components/editor/offCanvasIndicatorGeometry.complexity.test.ts +373 -0
- package/src/components/editor/offCanvasIndicatorGeometry.ts +50 -11
- package/src/components/editor/offCanvasIndicatorRefresh.ts +43 -16
- package/src/components/editor/overlayFrameLoop.test.ts +246 -0
- package/src/components/editor/overlayFrameLoop.ts +204 -0
- package/src/components/editor/probeSourceElement.ts +29 -0
- package/src/components/editor/propertyPanelFill.tsx +2 -1
- package/src/components/editor/propertyPanelFlatEffectsSection.test.tsx +2 -2
- package/src/components/editor/useDomEditCompositionRect.ts +2 -4
- package/src/components/editor/useDomEditOverlayRects.ts +15 -9
- package/src/components/editor/useMotionPathData.ts +2 -4
- package/src/components/feedback/projectProvenance.ts +4 -1
- package/src/components/nle/NLEContext.tsx +2 -1
- package/src/components/nle/PreviewOverlays.tsx +1 -1
- package/src/components/nle/useCompositionStack.ts +11 -4
- package/src/components/renders/RenderQueue.test.tsx +2 -2
- package/src/components/renders/RenderQueueItem.tsx +2 -1
- package/src/components/renders/useRenderQueue.ts +3 -2
- package/src/components/sidebar/AssetsTab.tsx +2 -1
- package/src/components/sidebar/CompositionsTab.tsx +2 -1
- package/src/components/storyboard/FramePoster.tsx +2 -1
- package/src/hooks/useAskAgentModal.ts +2 -1
- package/src/hooks/useCaptionDetection.sender.test.tsx +54 -0
- package/src/hooks/useCaptionDetection.ts +3 -1
- package/src/hooks/useCompositionContentLoader.ts +3 -1
- package/src/hooks/useCompositionDimensions.test.tsx +47 -0
- package/src/hooks/useCompositionDimensions.ts +3 -2
- package/src/hooks/useDomEditCommits.ts +5 -4
- package/src/hooks/useElementLifecycleOps.ts +5 -1
- package/src/hooks/useFileTree.ts +5 -4
- package/src/hooks/useGroupCommits.ts +2 -1
- package/src/hooks/useGsapInteractionFailureTelemetry.test.tsx +2 -2
- package/src/hooks/useLintModal.ts +2 -1
- package/src/hooks/useRenderClipContent.ts +6 -5
- package/src/hooks/useTimelineDeleteOps.ts +5 -1
- package/src/player/components/Player.tsx +6 -4
- package/src/player/components/TimelineAutomationLane.test.tsx +9 -9
- package/src/player/components/thumbnailUtils.ts +6 -2
- package/src/player/components/timelineDragDrop.test.tsx +3 -3
- package/src/player/lib/timelineIframeHelpers.test.ts +36 -0
- package/src/player/lib/timelineIframeHelpers.ts +17 -1
- package/src/test-setup.ts +8 -0
- package/src/utils/blockInstaller.ts +2 -1
- package/src/utils/projectRouting.test.ts +9 -0
- package/src/utils/projectRouting.ts +18 -1
- package/src/utils/razorSplitTransaction.test.ts +3 -3
- package/src/utils/sourceScopedSelectorIndex.test.ts +148 -0
- package/src/utils/sourceScopedSelectorIndex.ts +64 -6
- package/src/utils/studioFileHistory.ts +2 -1
- package/src/utils/studioHelpers.test.ts +5 -1
- package/src/utils/studioHelpers.ts +3 -2
- package/src/utils/timelineCompositionInsert.test.ts +3 -3
- package/dist/chunk-A7S5SGNA.js.map +0 -1
- /package/dist/{domEditingLayers-JMMVOGTO.js.map → domEditingLayers-UKMVYXT6.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
import{g as P}from"./index-
|
|
1
|
+
import{g as P}from"./index-CkxPQxLJ.js";function j(c,d){for(var s=0;s<d.length;s++){const a=d[s];if(typeof a!="string"&&!Array.isArray(a)){for(const i in a)if(i!=="default"&&!(i in c)){const l=Object.getOwnPropertyDescriptor(a,i);l&&Object.defineProperty(c,i,l.get?l:{enumerable:!0,get:()=>a[i]})}}}return Object.freeze(Object.defineProperty(c,Symbol.toStringTag,{value:"Module"}))}var v={},w;function k(){if(w)return v;w=1,Object.defineProperty(v,"__esModule",{value:!0}),v.default=d;var c=window.OfflineAudioContext||window.webkitOfflineAudioContext;function d(e){var r=a(e);return r.start(0),[i,y,O(e.sampleRate),s].reduce(function(t,o){return o(t)},r.buffer.getChannelData(0))}function s(e){return e.sort(function(r,t){return t.count-r.count}).splice(0,5)[0].tempo}function a(e){var r=e.length,t=e.numberOfChannels,o=e.sampleRate,n=new c(t,r,o),u=n.createBufferSource();u.buffer=e;var f=n.createBiquadFilter();return f.type="lowpass",u.connect(f),f.connect(n.destination),u}function i(e){for(var r=[],t=.9,o=.3,n=15;r.length<n&&t>=o;)r=l(e,t),t-=.05;if(r.length<n)throw new Error("Could not find enough samples for a reliable detection.");return r}function l(e,r){for(var t=[],o=0,n=e.length;o<n;o+=1)e[o]>r&&(t.push(o),o+=1e4);return t}function y(e){var r=[];return e.forEach(function(t,o){for(var n=function(x){var g=e[o+x]-t,_=r.some(function(h){if(h.interval===g)return h.count+=1});_||r.push({interval:g,count:1})},u=0;u<10;u+=1)n(u)}),r}function O(e){return function(r){var t=[];return r.forEach(function(o){if(o.interval!==0){for(var n=60/(o.interval/e);n<90;)n*=2;for(;n>180;)n/=2;n=Math.round(n);var u=t.some(function(f){if(f.tempo===n)return f.count+=o.count});u||t.push({tempo:n,count:o.count})}}),t}}return v}var p,b;function q(){return b||(b=1,p=k().default),p}var m=q();const A=P(m),D=j({__proto__:null,default:A},[m]);export{D as i};
|
|
@@ -1,3 +1,80 @@
|
|
|
1
|
+
// src/utils/projectRouting.ts
|
|
2
|
+
var PROJECT_HASH_PREFIX = "#project/";
|
|
3
|
+
function isValidProjectId(value) {
|
|
4
|
+
return value.length > 0 && value !== "." && value !== ".." && !value.includes(":") && !value.includes("/") && !value.includes("\\") && !Array.from(value).some((char) => char.charCodeAt(0) < 32);
|
|
5
|
+
}
|
|
6
|
+
function decodeHashProjectId(value) {
|
|
7
|
+
try {
|
|
8
|
+
return decodeURIComponent(value);
|
|
9
|
+
} catch {
|
|
10
|
+
return value;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
function normalizeHashParams(params) {
|
|
14
|
+
if (!params) return new URLSearchParams();
|
|
15
|
+
if (params instanceof URLSearchParams) return params;
|
|
16
|
+
const next = new URLSearchParams();
|
|
17
|
+
for (const [key, value] of Object.entries(params)) {
|
|
18
|
+
if (!key || value == null || value === "") continue;
|
|
19
|
+
next.set(key, value);
|
|
20
|
+
}
|
|
21
|
+
return next;
|
|
22
|
+
}
|
|
23
|
+
function encodeProjectId(projectId) {
|
|
24
|
+
if (!isValidProjectId(projectId)) throw new Error("Invalid project ID");
|
|
25
|
+
return encodeURIComponent(projectId);
|
|
26
|
+
}
|
|
27
|
+
function buildProjectHash(projectId, params) {
|
|
28
|
+
const search = normalizeHashParams(params).toString();
|
|
29
|
+
return `${PROJECT_HASH_PREFIX}${encodeProjectId(projectId)}${search ? `?${search}` : ""}`;
|
|
30
|
+
}
|
|
31
|
+
function parseProjectHashRoute(hash) {
|
|
32
|
+
if (!hash.startsWith(PROJECT_HASH_PREFIX)) return null;
|
|
33
|
+
const route = hash.slice(PROJECT_HASH_PREFIX.length);
|
|
34
|
+
const queryIndex = route.indexOf("?");
|
|
35
|
+
const encodedProjectId = queryIndex >= 0 ? route.slice(0, queryIndex) : route;
|
|
36
|
+
if (!encodedProjectId || encodedProjectId.includes("/")) return null;
|
|
37
|
+
const projectId = decodeHashProjectId(encodedProjectId);
|
|
38
|
+
if (!isValidProjectId(projectId)) return null;
|
|
39
|
+
const rawParams = queryIndex >= 0 ? route.slice(queryIndex + 1) : "";
|
|
40
|
+
return {
|
|
41
|
+
projectId,
|
|
42
|
+
params: new URLSearchParams(rawParams)
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function parseProjectIdFromHash(hash) {
|
|
46
|
+
return parseProjectHashRoute(hash)?.projectId ?? null;
|
|
47
|
+
}
|
|
48
|
+
function buildProjectApiPath(projectId, suffix = "") {
|
|
49
|
+
const normalizedSuffix = suffix && !suffix.startsWith("/") ? `/${suffix}` : suffix;
|
|
50
|
+
return `/api/projects/${encodeProjectId(projectId)}${normalizedSuffix}`;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// src/components/editor/probeSourceElement.ts
|
|
54
|
+
async function probeSourceElement(projectId, sourceFile, target) {
|
|
55
|
+
try {
|
|
56
|
+
const response = await fetch(
|
|
57
|
+
buildProjectApiPath(
|
|
58
|
+
projectId,
|
|
59
|
+
`/file-mutations/probe-element/${encodeURIComponent(sourceFile)}`
|
|
60
|
+
),
|
|
61
|
+
{
|
|
62
|
+
method: "POST",
|
|
63
|
+
headers: { "Content-Type": "application/json" },
|
|
64
|
+
body: JSON.stringify({ target })
|
|
65
|
+
}
|
|
66
|
+
);
|
|
67
|
+
if (!response.ok) return true;
|
|
68
|
+
const data = await response.json();
|
|
69
|
+
if (data && typeof data === "object" && "exists" in data && data.exists === false) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
return true;
|
|
73
|
+
} catch {
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
1
78
|
// src/components/editor/domEditingLayers.ts
|
|
2
79
|
import {
|
|
3
80
|
resolveEditingAffordances,
|
|
@@ -8,17 +85,40 @@ import {
|
|
|
8
85
|
import { COLOR_GRADING_SOURCE_HIDDEN_ATTR } from "@hyperframes/core/color-grading";
|
|
9
86
|
|
|
10
87
|
// src/utils/sourceScopedSelectorIndex.ts
|
|
88
|
+
var activePass = null;
|
|
89
|
+
function withSelectorIndexPass(doc, run) {
|
|
90
|
+
const previous = activePass;
|
|
91
|
+
activePass = { doc, bySelector: /* @__PURE__ */ new Map() };
|
|
92
|
+
try {
|
|
93
|
+
return run();
|
|
94
|
+
} finally {
|
|
95
|
+
activePass = previous;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function buildOccurrences(doc, selector, resolveSourceFile) {
|
|
99
|
+
const occurrences = /* @__PURE__ */ new Map();
|
|
100
|
+
const counts = /* @__PURE__ */ new Map();
|
|
101
|
+
for (const candidate of doc.querySelectorAll(selector)) {
|
|
102
|
+
const scope = resolveSourceFile(candidate) ?? "index.html";
|
|
103
|
+
const index = counts.get(scope) ?? 0;
|
|
104
|
+
counts.set(scope, index + 1);
|
|
105
|
+
occurrences.set(candidate, { scope, index });
|
|
106
|
+
}
|
|
107
|
+
return occurrences;
|
|
108
|
+
}
|
|
11
109
|
function getSourceScopedSelectorIndex(doc, el, selector, sourceFile, resolveSourceFile) {
|
|
12
110
|
if (!selector || selector.startsWith("#") || selector.startsWith("[data-composition-id=")) {
|
|
13
111
|
return void 0;
|
|
14
112
|
}
|
|
15
113
|
try {
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
114
|
+
const pass = activePass?.doc === doc ? activePass : null;
|
|
115
|
+
let occurrences = pass?.bySelector.get(selector);
|
|
116
|
+
if (!occurrences) {
|
|
117
|
+
occurrences = buildOccurrences(doc, selector, resolveSourceFile);
|
|
118
|
+
pass?.bySelector.set(selector, occurrences);
|
|
119
|
+
}
|
|
120
|
+
const hit = occurrences.get(el);
|
|
121
|
+
return hit && hit.scope === (sourceFile ?? "index.html") ? hit.index : void 0;
|
|
22
122
|
} catch {
|
|
23
123
|
return void 0;
|
|
24
124
|
}
|
|
@@ -79,19 +179,31 @@ function isHtmlElement(value) {
|
|
|
79
179
|
function isTextBearingTag(tagName) {
|
|
80
180
|
return ["div", "span", "p", "strong", "h1", "h2", "h3", "h4", "h5", "h6"].includes(tagName);
|
|
81
181
|
}
|
|
82
|
-
function
|
|
182
|
+
function elementRendersItself(win, el) {
|
|
183
|
+
const computed = win.getComputedStyle(el);
|
|
184
|
+
if (computed.display === "none" || computed.visibility === "hidden") return false;
|
|
185
|
+
const opacity = Number.parseFloat(computed.opacity);
|
|
186
|
+
return !(Number.isFinite(opacity) && opacity <= 0.01 && !el.hasAttribute(COLOR_GRADING_SOURCE_HIDDEN_ATTR));
|
|
187
|
+
}
|
|
188
|
+
function isElementVisibleThroughAncestors(el, memo) {
|
|
83
189
|
const win = el.ownerDocument.defaultView;
|
|
84
190
|
if (!win) return true;
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
191
|
+
const pending = [];
|
|
192
|
+
let inherited = true;
|
|
193
|
+
for (let node = el; node; node = node.parentElement) {
|
|
194
|
+
const answered = memo?.get(node);
|
|
195
|
+
if (answered !== void 0) {
|
|
196
|
+
inherited = answered;
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
pending.push(node);
|
|
93
200
|
}
|
|
94
|
-
|
|
201
|
+
for (let i = pending.length - 1; i >= 0; i -= 1) {
|
|
202
|
+
const node = pending[i];
|
|
203
|
+
inherited = inherited && elementRendersItself(win, node);
|
|
204
|
+
memo?.set(node, inherited);
|
|
205
|
+
}
|
|
206
|
+
return inherited;
|
|
95
207
|
}
|
|
96
208
|
function getCuratedComputedStyles(el) {
|
|
97
209
|
const styles = {};
|
|
@@ -132,8 +244,13 @@ function findClosestByAttribute(el, attributeNames) {
|
|
|
132
244
|
return null;
|
|
133
245
|
}
|
|
134
246
|
var compositionSourceMap = /* @__PURE__ */ new Map();
|
|
247
|
+
var compositionSourceMapRevision = 0;
|
|
135
248
|
function setCompositionSourceMap(map) {
|
|
136
249
|
compositionSourceMap = map;
|
|
250
|
+
compositionSourceMapRevision += 1;
|
|
251
|
+
}
|
|
252
|
+
function getCompositionSourceMapRevision() {
|
|
253
|
+
return compositionSourceMapRevision;
|
|
137
254
|
}
|
|
138
255
|
function sourceFromCompositionId(ownerRoot) {
|
|
139
256
|
if (!ownerRoot || compositionSourceMap.size === 0) return void 0;
|
|
@@ -279,8 +396,8 @@ function resolveGroupCapture(startEl, activeGroupElement) {
|
|
|
279
396
|
}
|
|
280
397
|
|
|
281
398
|
// src/components/editor/domEditingElement.ts
|
|
282
|
-
function isElementComputedVisible(el) {
|
|
283
|
-
return isElementVisibleThroughAncestors(el);
|
|
399
|
+
function isElementComputedVisible(el, memo) {
|
|
400
|
+
return isElementVisibleThroughAncestors(el, memo);
|
|
284
401
|
}
|
|
285
402
|
var VISUAL_LEAF_TAGS = /* @__PURE__ */ new Set(["img", "video", "canvas", "svg", "audio"]);
|
|
286
403
|
function hasVisualPresence(el) {
|
|
@@ -337,10 +454,12 @@ function isInspectableLayerElement(el) {
|
|
|
337
454
|
if (computed?.display === "none" || computed?.visibility === "hidden") return false;
|
|
338
455
|
return true;
|
|
339
456
|
}
|
|
340
|
-
function
|
|
341
|
-
if (
|
|
342
|
-
|
|
343
|
-
|
|
457
|
+
function resolveLayerSelector(el) {
|
|
458
|
+
if (el.hasAttribute("data-composition-id")) return void 0;
|
|
459
|
+
return buildStableSelector(el);
|
|
460
|
+
}
|
|
461
|
+
function resolveDomLayerIdentity(el, activeCompositionPath) {
|
|
462
|
+
const selector = resolveLayerSelector(el);
|
|
344
463
|
if (!selector) return null;
|
|
345
464
|
const { sourceFile } = getSourceFileForElement(el, activeCompositionPath);
|
|
346
465
|
return {
|
|
@@ -357,6 +476,12 @@ function getDomLayerPatchTarget(el, activeCompositionPath) {
|
|
|
357
476
|
sourceFile
|
|
358
477
|
};
|
|
359
478
|
}
|
|
479
|
+
function getDomLayerPatchTarget(el, activeCompositionPath) {
|
|
480
|
+
return isInspectableLayerElement(el) ? resolveDomLayerIdentity(el, activeCompositionPath) : null;
|
|
481
|
+
}
|
|
482
|
+
function isDomLayerElement(el) {
|
|
483
|
+
return isInspectableLayerElement(el) && resolveLayerSelector(el) !== void 0;
|
|
484
|
+
}
|
|
360
485
|
function getPreferredClipAncestor(startEl) {
|
|
361
486
|
let current = startEl;
|
|
362
487
|
while (current) {
|
|
@@ -442,9 +567,9 @@ function findElementForTimelineElement(doc, element, options) {
|
|
|
442
567
|
if (!isHtmlElement(root)) return null;
|
|
443
568
|
return getSourceFileForElement(root, options.activeCompositionPath).sourceFile === sourceFile ? root : null;
|
|
444
569
|
}
|
|
445
|
-
function getDirectLayerChildren(el
|
|
570
|
+
function getDirectLayerChildren(el) {
|
|
446
571
|
return Array.from(el.children).filter(
|
|
447
|
-
(child) => isHtmlElement(child) &&
|
|
572
|
+
(child) => isHtmlElement(child) && isDomLayerElement(child)
|
|
448
573
|
);
|
|
449
574
|
}
|
|
450
575
|
|
|
@@ -488,6 +613,131 @@ function isCompositionRootLayer(element, doc, computedStyles) {
|
|
|
488
613
|
);
|
|
489
614
|
}
|
|
490
615
|
|
|
616
|
+
// src/components/editor/domEditLayerWalkCache.ts
|
|
617
|
+
var SELECTOR_IDENTITY_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
618
|
+
"id",
|
|
619
|
+
"class",
|
|
620
|
+
"data-hf-group",
|
|
621
|
+
"data-composition-id",
|
|
622
|
+
"data-composition-file",
|
|
623
|
+
"data-composition-src",
|
|
624
|
+
"data-hf-original-composition-id"
|
|
625
|
+
]);
|
|
626
|
+
var DOM_EDIT_LAYER_OBSERVER_INIT = {
|
|
627
|
+
attributes: true,
|
|
628
|
+
characterData: true,
|
|
629
|
+
childList: true,
|
|
630
|
+
subtree: true
|
|
631
|
+
};
|
|
632
|
+
var lastInlineVisibility = /* @__PURE__ */ new WeakMap();
|
|
633
|
+
function inlineVisibilityChanged(el) {
|
|
634
|
+
const next = el.style.visibility;
|
|
635
|
+
if (lastInlineVisibility.get(el) === next) return false;
|
|
636
|
+
lastInlineVisibility.set(el, next);
|
|
637
|
+
return true;
|
|
638
|
+
}
|
|
639
|
+
function createDomEditLayerWalkCache() {
|
|
640
|
+
let presence = /* @__PURE__ */ new WeakMap();
|
|
641
|
+
let identities = /* @__PURE__ */ new WeakMap();
|
|
642
|
+
let scope = null;
|
|
643
|
+
const invalidateAll = () => {
|
|
644
|
+
presence = /* @__PURE__ */ new WeakMap();
|
|
645
|
+
identities = /* @__PURE__ */ new WeakMap();
|
|
646
|
+
};
|
|
647
|
+
const drop = (el) => {
|
|
648
|
+
if (el) presence.delete(el);
|
|
649
|
+
};
|
|
650
|
+
const dropSubtree = (el) => {
|
|
651
|
+
for (const descendant of el.querySelectorAll("*")) {
|
|
652
|
+
if (isHtmlElement(descendant)) presence.delete(descendant);
|
|
653
|
+
}
|
|
654
|
+
};
|
|
655
|
+
const ingestOne = (record) => {
|
|
656
|
+
if (record.type === "childList") return false;
|
|
657
|
+
if (record.type === "characterData") {
|
|
658
|
+
for (let ancestor = record.target.parentElement; ancestor; ancestor = ancestor.parentElement) {
|
|
659
|
+
identities.delete(ancestor);
|
|
660
|
+
}
|
|
661
|
+
return true;
|
|
662
|
+
}
|
|
663
|
+
const target = record.target;
|
|
664
|
+
if (!isHtmlElement(target)) return true;
|
|
665
|
+
if (record.attributeName && SELECTOR_IDENTITY_ATTRIBUTES.has(record.attributeName))
|
|
666
|
+
return false;
|
|
667
|
+
drop(target);
|
|
668
|
+
drop(target.parentElement);
|
|
669
|
+
if (record.attributeName === "style" && inlineVisibilityChanged(target)) dropSubtree(target);
|
|
670
|
+
return true;
|
|
671
|
+
};
|
|
672
|
+
return {
|
|
673
|
+
beginWalk(activeCompositionPath) {
|
|
674
|
+
const nextScope = `${activeCompositionPath ?? ""}|${getCompositionSourceMapRevision()}`;
|
|
675
|
+
if (nextScope === scope) return;
|
|
676
|
+
scope = nextScope;
|
|
677
|
+
invalidateAll();
|
|
678
|
+
},
|
|
679
|
+
readInspectable(el, compute) {
|
|
680
|
+
const memo = presence.get(el) ?? {};
|
|
681
|
+
if (memo.inspectable === void 0) {
|
|
682
|
+
memo.inspectable = compute();
|
|
683
|
+
presence.set(el, memo);
|
|
684
|
+
}
|
|
685
|
+
return memo.inspectable;
|
|
686
|
+
},
|
|
687
|
+
readChildCount(el, compute) {
|
|
688
|
+
const memo = presence.get(el) ?? {};
|
|
689
|
+
if (memo.childCount === void 0) {
|
|
690
|
+
memo.childCount = compute();
|
|
691
|
+
presence.set(el, memo);
|
|
692
|
+
}
|
|
693
|
+
return memo.childCount;
|
|
694
|
+
},
|
|
695
|
+
readIdentity(el, compute) {
|
|
696
|
+
const memo = identities.get(el) ?? {};
|
|
697
|
+
if (memo.identity === void 0) {
|
|
698
|
+
memo.identity = compute();
|
|
699
|
+
identities.set(el, memo);
|
|
700
|
+
}
|
|
701
|
+
return memo.identity;
|
|
702
|
+
},
|
|
703
|
+
readLabel(el, compute) {
|
|
704
|
+
const memo = identities.get(el) ?? {};
|
|
705
|
+
if (memo.label === void 0) {
|
|
706
|
+
memo.label = compute();
|
|
707
|
+
identities.set(el, memo);
|
|
708
|
+
}
|
|
709
|
+
return memo.label;
|
|
710
|
+
},
|
|
711
|
+
ingest(records) {
|
|
712
|
+
for (const record of records) {
|
|
713
|
+
if (!ingestOne(record)) {
|
|
714
|
+
invalidateAll();
|
|
715
|
+
return;
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
},
|
|
719
|
+
invalidateAll
|
|
720
|
+
};
|
|
721
|
+
}
|
|
722
|
+
function readDomEditLayerWalkEntry(el, activeCompositionPath, cache) {
|
|
723
|
+
const inspectable = cache ? cache.readInspectable(el, () => isInspectableLayerElement(el)) : isInspectableLayerElement(el);
|
|
724
|
+
if (!inspectable) return null;
|
|
725
|
+
const identity = () => resolveDomLayerIdentity(el, activeCompositionPath);
|
|
726
|
+
const target = cache ? cache.readIdentity(el, identity) : identity();
|
|
727
|
+
if (!target) return null;
|
|
728
|
+
const label = () => buildElementLabel(el);
|
|
729
|
+
const childCount = () => getDirectLayerChildren(el).length;
|
|
730
|
+
return {
|
|
731
|
+
target,
|
|
732
|
+
label: cache ? cache.readLabel(el, label) : label(),
|
|
733
|
+
childCount: cache ? cache.readChildCount(el, childCount) : childCount()
|
|
734
|
+
};
|
|
735
|
+
}
|
|
736
|
+
function drainPendingLayerMutations(observer, cache) {
|
|
737
|
+
if (!observer) return;
|
|
738
|
+
cache.ingest(observer.takeRecords());
|
|
739
|
+
}
|
|
740
|
+
|
|
491
741
|
// src/components/editor/domEditingLayers.ts
|
|
492
742
|
function isEditableTextLeaf(el) {
|
|
493
743
|
return isTextBearingTag(el.tagName.toLowerCase()) && el.children.length === 0;
|
|
@@ -652,26 +902,6 @@ function resolveDomEditCapabilities(args) {
|
|
|
652
902
|
})
|
|
653
903
|
).capabilities;
|
|
654
904
|
}
|
|
655
|
-
async function probeSourceElement(projectId, sourceFile, target) {
|
|
656
|
-
try {
|
|
657
|
-
const response = await fetch(
|
|
658
|
-
`/api/projects/${projectId}/file-mutations/probe-element/${encodeURIComponent(sourceFile)}`,
|
|
659
|
-
{
|
|
660
|
-
method: "POST",
|
|
661
|
-
headers: { "Content-Type": "application/json" },
|
|
662
|
-
body: JSON.stringify({ target })
|
|
663
|
-
}
|
|
664
|
-
);
|
|
665
|
-
if (!response.ok) return true;
|
|
666
|
-
const data = await response.json();
|
|
667
|
-
if (data && typeof data === "object" && "exists" in data && data.exists === false) {
|
|
668
|
-
return false;
|
|
669
|
-
}
|
|
670
|
-
return true;
|
|
671
|
-
} catch {
|
|
672
|
-
return true;
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
905
|
async function resolveDomEditSelection(startEl, options) {
|
|
676
906
|
if (!startEl) return null;
|
|
677
907
|
const doc = startEl.ownerDocument;
|
|
@@ -768,7 +998,7 @@ function countDomEditChildLayers(root, options, maxCount = 99) {
|
|
|
768
998
|
const visit = (el) => {
|
|
769
999
|
for (const child of Array.from(el.children)) {
|
|
770
1000
|
if (!isHtmlElement(child)) continue;
|
|
771
|
-
if (
|
|
1001
|
+
if (isDomLayerElement(child)) {
|
|
772
1002
|
count += 1;
|
|
773
1003
|
if (count >= maxCount) return;
|
|
774
1004
|
}
|
|
@@ -779,20 +1009,22 @@ function countDomEditChildLayers(root, options, maxCount = 99) {
|
|
|
779
1009
|
visit(root);
|
|
780
1010
|
return count;
|
|
781
1011
|
}
|
|
782
|
-
function collectDomEditLayerItems(root, options, maxItems = Number.POSITIVE_INFINITY) {
|
|
1012
|
+
function collectDomEditLayerItems(root, options, maxItems = Number.POSITIVE_INFINITY, cache) {
|
|
783
1013
|
if (!root) return [];
|
|
1014
|
+
cache?.beginWalk(options.activeCompositionPath);
|
|
784
1015
|
const items = [];
|
|
785
1016
|
const visit = (el, depth) => {
|
|
786
1017
|
if (items.length >= maxItems) return;
|
|
787
|
-
const
|
|
788
|
-
if (
|
|
1018
|
+
const entry = readDomEditLayerWalkEntry(el, options.activeCompositionPath, cache);
|
|
1019
|
+
if (entry) {
|
|
1020
|
+
const { target } = entry;
|
|
789
1021
|
items.push({
|
|
790
1022
|
key: getDomEditLayerKey(target),
|
|
791
1023
|
element: el,
|
|
792
|
-
label:
|
|
1024
|
+
label: entry.label,
|
|
793
1025
|
tagName: el.tagName.toLowerCase(),
|
|
794
1026
|
depth,
|
|
795
|
-
childCount:
|
|
1027
|
+
childCount: entry.childCount,
|
|
796
1028
|
id: target.id ?? void 0,
|
|
797
1029
|
hfId: target.hfId ?? void 0,
|
|
798
1030
|
selector: target.selector ?? void 0,
|
|
@@ -800,14 +1032,16 @@ function collectDomEditLayerItems(root, options, maxItems = Number.POSITIVE_INFI
|
|
|
800
1032
|
sourceFile: target.sourceFile
|
|
801
1033
|
});
|
|
802
1034
|
}
|
|
803
|
-
const nextDepth =
|
|
1035
|
+
const nextDepth = entry ? depth + 1 : depth;
|
|
804
1036
|
for (const child of Array.from(el.children)) {
|
|
805
1037
|
if (!isHtmlElement(child)) continue;
|
|
806
1038
|
visit(child, nextDepth);
|
|
807
1039
|
if (items.length >= maxItems) return;
|
|
808
1040
|
}
|
|
809
1041
|
};
|
|
810
|
-
|
|
1042
|
+
withSelectorIndexPass(root.ownerDocument, () => {
|
|
1043
|
+
for (const el of groupScopedLayerRoots(root, options.activeGroupElement ?? null)) visit(el, 0);
|
|
1044
|
+
});
|
|
811
1045
|
return items;
|
|
812
1046
|
}
|
|
813
1047
|
function buildDomEditStylePatchOperation(property, value, childLocator) {
|
|
@@ -864,6 +1098,10 @@ function buildDomEditPatchTarget(selection) {
|
|
|
864
1098
|
}
|
|
865
1099
|
|
|
866
1100
|
export {
|
|
1101
|
+
buildProjectHash,
|
|
1102
|
+
parseProjectHashRoute,
|
|
1103
|
+
parseProjectIdFromHash,
|
|
1104
|
+
buildProjectApiPath,
|
|
867
1105
|
getSourceScopedSelectorIndex,
|
|
868
1106
|
isHtmlElement,
|
|
869
1107
|
isElementVisibleThroughAncestors,
|
|
@@ -876,6 +1114,9 @@ export {
|
|
|
876
1114
|
resolveAllVisualDomEditTargets,
|
|
877
1115
|
findElementForSelection,
|
|
878
1116
|
findElementForTimelineElement,
|
|
1117
|
+
DOM_EDIT_LAYER_OBSERVER_INIT,
|
|
1118
|
+
createDomEditLayerWalkCache,
|
|
1119
|
+
drainPendingLayerMutations,
|
|
879
1120
|
isEditableTextLeaf,
|
|
880
1121
|
collectDomEditTextFields,
|
|
881
1122
|
serializeDomEditTextFields,
|
|
@@ -897,4 +1138,4 @@ export {
|
|
|
897
1138
|
readHfId,
|
|
898
1139
|
buildDomEditPatchTarget
|
|
899
1140
|
};
|
|
900
|
-
//# sourceMappingURL=chunk-
|
|
1141
|
+
//# sourceMappingURL=chunk-7BP32G62.js.map
|