@hyperframes/sdk 0.6.113
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/LICENSE +190 -0
- package/dist/adapters/fs.d.ts +9 -0
- package/dist/adapters/fs.d.ts.map +1 -0
- package/dist/adapters/fs.js +122 -0
- package/dist/adapters/fs.js.map +1 -0
- package/dist/adapters/headless.d.ts +3 -0
- package/dist/adapters/headless.d.ts.map +1 -0
- package/dist/adapters/headless.js +17 -0
- package/dist/adapters/headless.js.map +1 -0
- package/dist/adapters/iframe.d.ts +102 -0
- package/dist/adapters/iframe.d.ts.map +1 -0
- package/dist/adapters/iframe.js +569 -0
- package/dist/adapters/iframe.js.map +1 -0
- package/dist/adapters/memory.d.ts +5 -0
- package/dist/adapters/memory.d.ts.map +1 -0
- package/dist/adapters/memory.js +54 -0
- package/dist/adapters/memory.js.map +1 -0
- package/dist/adapters/types.d.ts +65 -0
- package/dist/adapters/types.d.ts.map +1 -0
- package/dist/adapters/types.js +2 -0
- package/dist/adapters/types.js.map +1 -0
- package/dist/document.d.ts +25 -0
- package/dist/document.d.ts.map +1 -0
- package/dist/document.js +238 -0
- package/dist/document.js.map +1 -0
- package/dist/engine/apply-patches.d.ts +20 -0
- package/dist/engine/apply-patches.d.ts.map +1 -0
- package/dist/engine/apply-patches.js +284 -0
- package/dist/engine/apply-patches.js.map +1 -0
- package/dist/engine/cssWriter.d.ts +18 -0
- package/dist/engine/cssWriter.d.ts.map +1 -0
- package/dist/engine/cssWriter.js +139 -0
- package/dist/engine/cssWriter.js.map +1 -0
- package/dist/engine/keyframeBackfill.d.ts +17 -0
- package/dist/engine/keyframeBackfill.d.ts.map +1 -0
- package/dist/engine/keyframeBackfill.js +43 -0
- package/dist/engine/keyframeBackfill.js.map +1 -0
- package/dist/engine/model.d.ts +55 -0
- package/dist/engine/model.d.ts.map +1 -0
- package/dist/engine/model.js +256 -0
- package/dist/engine/model.js.map +1 -0
- package/dist/engine/mutate.d.ts +26 -0
- package/dist/engine/mutate.d.ts.map +1 -0
- package/dist/engine/mutate.js +1243 -0
- package/dist/engine/mutate.js.map +1 -0
- package/dist/engine/patches.d.ts +71 -0
- package/dist/engine/patches.d.ts.map +1 -0
- package/dist/engine/patches.js +197 -0
- package/dist/engine/patches.js.map +1 -0
- package/dist/engine/serialize.d.ts +15 -0
- package/dist/engine/serialize.d.ts.map +1 -0
- package/dist/engine/serialize.js +20 -0
- package/dist/engine/serialize.js.map +1 -0
- package/dist/engine/variableModel.d.ts +29 -0
- package/dist/engine/variableModel.d.ts.map +1 -0
- package/dist/engine/variableModel.js +81 -0
- package/dist/engine/variableModel.js.map +1 -0
- package/dist/history.d.ts +39 -0
- package/dist/history.d.ts.map +1 -0
- package/dist/history.js +116 -0
- package/dist/history.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/persist-queue.d.ts +24 -0
- package/dist/persist-queue.d.ts.map +1 -0
- package/dist/persist-queue.js +62 -0
- package/dist/persist-queue.js.map +1 -0
- package/dist/session.d.ts +38 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +514 -0
- package/dist/session.js.map +1 -0
- package/dist/types.d.ts +521 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +16 -0
- package/dist/types.js.map +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1,569 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Same-origin iframe PreviewAdapter — WS-A1 (hit-test + selection) +
|
|
3
|
+
* WS-A2 (applyDraft / commitPreview / cancelPreview → moveElement) +
|
|
4
|
+
* WS-G (image-alpha hit-test, phase 1).
|
|
5
|
+
*
|
|
6
|
+
* Requirements:
|
|
7
|
+
* - The iframe MUST be same-origin (srcdoc / blob URL). Cross-origin access to
|
|
8
|
+
* contentDocument throws a DOMException; this adapter does not guard that —
|
|
9
|
+
* the caller is responsible for ensuring same-origin.
|
|
10
|
+
*
|
|
11
|
+
* Image-alpha (phase 1):
|
|
12
|
+
* - Replaces elementFromPoint with elementsFromPoint (z-stack) so transparent
|
|
13
|
+
* image hits fall through to the element behind.
|
|
14
|
+
* - For <img> hits, maps the client point to the natural-pixel coordinate
|
|
15
|
+
* (object-fit/object-position aware), draws to an offscreen canvas (cached
|
|
16
|
+
* by src + natural dimensions, so a srcset re-render gets a fresh canvas),
|
|
17
|
+
* samples alpha. Transparent pixel → miss, continue the stack.
|
|
18
|
+
* - Cross-origin images taint the canvas → getImageData throws SecurityError
|
|
19
|
+
* → falls back to treating the pixel as OPAQUE (never drop an unverifiable
|
|
20
|
+
* hit) and warns once per src. Callers must ensure CORS or accept the fallback.
|
|
21
|
+
* - A CSS rotation/skew on the image or an ancestor also falls back to opaque
|
|
22
|
+
* (the axis-aligned rect mapping can't sample a rotated image correctly);
|
|
23
|
+
* transform-inverse mapping is phase 2.
|
|
24
|
+
* - Images above a pixel budget skip alpha-testing (opaque) to bound canvas
|
|
25
|
+
* memory. Limitation: animated <img> (gif) or src swaps invalidate the cache
|
|
26
|
+
* only when currentSrc/dimensions change. Phase 1 is optimized for static images.
|
|
27
|
+
* - Phase 2 (full per-pixel alpha via drawElement rasterization) is NOT built
|
|
28
|
+
* here — gated on a perf spike.
|
|
29
|
+
*/
|
|
30
|
+
// ─── CSS var names written onto elements during drag ─────────────────────────
|
|
31
|
+
const VAR_DX = "--hf-studio-dx";
|
|
32
|
+
const VAR_DY = "--hf-studio-dy";
|
|
33
|
+
// ─── Pure resolver (testable without a browser) ───────────────────────────────
|
|
34
|
+
/**
|
|
35
|
+
* Walk from `el` upward through parentElement, looking for the nearest node
|
|
36
|
+
* that carries `[data-hf-id]` and is NOT `[data-hf-root]`.
|
|
37
|
+
*
|
|
38
|
+
* Returns null when:
|
|
39
|
+
* - The walk exits the tree without finding `[data-hf-id]`
|
|
40
|
+
* - The matching node is `[data-hf-root]` (transparent to hit-testing)
|
|
41
|
+
* - `isVisible(node)` returns false for the matching node
|
|
42
|
+
*
|
|
43
|
+
* Keeping this a pure function (no elementFromPoint, no window access) makes
|
|
44
|
+
* it unit-testable in a plain Node environment.
|
|
45
|
+
*/
|
|
46
|
+
export function resolveNearestHfElement(el, isVisible) {
|
|
47
|
+
let node = el;
|
|
48
|
+
while (node !== null) {
|
|
49
|
+
const id = node.getAttribute("data-hf-id");
|
|
50
|
+
if (id !== null) {
|
|
51
|
+
if (node.hasAttribute("data-hf-root"))
|
|
52
|
+
return null;
|
|
53
|
+
if (!isVisible(node))
|
|
54
|
+
return null;
|
|
55
|
+
return { id, tag: node.tagName.toLowerCase() };
|
|
56
|
+
}
|
|
57
|
+
node = node.parentElement;
|
|
58
|
+
}
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
// ─── Draft position math (pure — testable without a browser) ─────────────────
|
|
62
|
+
/**
|
|
63
|
+
* Compute the new absolute x/y for a moveElement op given:
|
|
64
|
+
* - the element's current `data-x` / `data-y` string values (may be null)
|
|
65
|
+
* - the accumulated drag delta (dx, dy) from applyDraft calls
|
|
66
|
+
*
|
|
67
|
+
* `data-x` / `data-y` default to 0 when absent or non-numeric.
|
|
68
|
+
*/
|
|
69
|
+
export function computeDraftPosition(dataX, dataY, dx, dy) {
|
|
70
|
+
const baseX = parseFloat(dataX ?? "0") || 0;
|
|
71
|
+
const baseY = parseFloat(dataY ?? "0") || 0;
|
|
72
|
+
return { x: baseX + dx, y: baseY + dy };
|
|
73
|
+
}
|
|
74
|
+
// ─── Image-alpha pure helpers (WS-G phase 1) ──────────────────────────────────
|
|
75
|
+
/**
|
|
76
|
+
* Returns true when the first pixel in `imageData` has alpha >= threshold.
|
|
77
|
+
*
|
|
78
|
+
* Pure — no DOM access; unit-testable with a plain Uint8ClampedArray.
|
|
79
|
+
* threshold defaults to 1 so a fully-transparent pixel (a=0) is a miss.
|
|
80
|
+
*/
|
|
81
|
+
export function alphaIsOpaque(imageData, threshold = 1) {
|
|
82
|
+
// ImageData.data is [R, G, B, A, R, G, B, A, ...]
|
|
83
|
+
const alpha = imageData.data[3] ?? 0;
|
|
84
|
+
return alpha >= threshold;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Map a client-space point to the natural-pixel coordinates of the image.
|
|
88
|
+
*
|
|
89
|
+
* Handles object-fit: fill | cover | contain (default=fill when unset).
|
|
90
|
+
* object-position is parsed as two percentage/px values (default "50% 50%").
|
|
91
|
+
*
|
|
92
|
+
* Returns null when the point falls outside the rendered image area (e.g.
|
|
93
|
+
* the letterbox region of a contain-fitted image). A null result means the
|
|
94
|
+
* image does not own this pixel — the caller should continue the z-stack.
|
|
95
|
+
*
|
|
96
|
+
* Pure — no DOM/window access; unit-testable with plain objects.
|
|
97
|
+
*/
|
|
98
|
+
// fallow-ignore-next-line complexity
|
|
99
|
+
export function mapPointToImagePixel(rect, natural, objectFit, objectPosition, point) {
|
|
100
|
+
// Local coords within the CSS box
|
|
101
|
+
const lx = point.x - rect.left;
|
|
102
|
+
const ly = point.y - rect.top;
|
|
103
|
+
if (lx < 0 || ly < 0 || lx > rect.width || ly > rect.height)
|
|
104
|
+
return null;
|
|
105
|
+
const fit = objectFit || "fill";
|
|
106
|
+
// For fill (or unrecognized values): the natural image is stretched to the
|
|
107
|
+
// box; direct linear mapping.
|
|
108
|
+
if (fit !== "cover" && fit !== "contain" && fit !== "none") {
|
|
109
|
+
if (rect.width === 0 || rect.height === 0)
|
|
110
|
+
return null;
|
|
111
|
+
const px = Math.floor((lx / rect.width) * natural.width);
|
|
112
|
+
const py = Math.floor((ly / rect.height) * natural.height);
|
|
113
|
+
return { px: clamp(px, 0, natural.width - 1), py: clamp(py, 0, natural.height - 1) };
|
|
114
|
+
}
|
|
115
|
+
// For none: image is drawn at its natural size; no scaling.
|
|
116
|
+
if (fit === "none") {
|
|
117
|
+
const pos = parseObjectPosition(objectPosition, rect, natural);
|
|
118
|
+
const ox = pos.x;
|
|
119
|
+
const oy = pos.y;
|
|
120
|
+
const px = Math.floor(lx - ox);
|
|
121
|
+
const py = Math.floor(ly - oy);
|
|
122
|
+
if (px < 0 || py < 0 || px >= natural.width || py >= natural.height)
|
|
123
|
+
return null;
|
|
124
|
+
return { px, py };
|
|
125
|
+
}
|
|
126
|
+
// cover: scale uniformly so the image covers the box; may clip edges.
|
|
127
|
+
// contain: scale uniformly so the image fits within the box; may letterbox.
|
|
128
|
+
if (natural.width === 0 || natural.height === 0)
|
|
129
|
+
return null;
|
|
130
|
+
const scaleX = rect.width / natural.width;
|
|
131
|
+
const scaleY = rect.height / natural.height;
|
|
132
|
+
const scale = fit === "cover" ? Math.max(scaleX, scaleY) : Math.min(scaleX, scaleY);
|
|
133
|
+
const renderedW = natural.width * scale;
|
|
134
|
+
const renderedH = natural.height * scale;
|
|
135
|
+
const pos = parseObjectPosition(objectPosition, rect, {
|
|
136
|
+
width: renderedW,
|
|
137
|
+
height: renderedH,
|
|
138
|
+
});
|
|
139
|
+
// Offset of the rendered image's top-left within the CSS box
|
|
140
|
+
const imgLeft = pos.x;
|
|
141
|
+
const imgTop = pos.y;
|
|
142
|
+
// Local coords relative to the rendered image's top-left
|
|
143
|
+
const rx = lx - imgLeft;
|
|
144
|
+
const ry = ly - imgTop;
|
|
145
|
+
if (rx < 0 || ry < 0 || rx > renderedW || ry > renderedH)
|
|
146
|
+
return null;
|
|
147
|
+
if (scale === 0)
|
|
148
|
+
return null;
|
|
149
|
+
const px = Math.floor(rx / scale);
|
|
150
|
+
const py = Math.floor(ry / scale);
|
|
151
|
+
return { px: clamp(px, 0, natural.width - 1), py: clamp(py, 0, natural.height - 1) };
|
|
152
|
+
}
|
|
153
|
+
// ─── object-position parser (pure) ───────────────────────────────────────────
|
|
154
|
+
/**
|
|
155
|
+
* Parse a CSS object-position value into x/y offsets (top-left of the
|
|
156
|
+
* rendered content relative to the CSS box top-left).
|
|
157
|
+
*
|
|
158
|
+
* Supports the common subset: keyword pairs, percentage pairs, pixel pairs,
|
|
159
|
+
* and single-value shorthand. Mixed units (e.g. "50% 10px") are supported.
|
|
160
|
+
*
|
|
161
|
+
* Pure — no DOM access.
|
|
162
|
+
*/
|
|
163
|
+
function parseObjectPosition(objectPosition, box, content) {
|
|
164
|
+
const raw = (objectPosition || "50% 50%").trim();
|
|
165
|
+
const parts = raw.split(/\s+/);
|
|
166
|
+
// Resolve a single token into a pixel offset along the given axis.
|
|
167
|
+
// `available` is the "slack" (box dimension - content dimension).
|
|
168
|
+
// fallow-ignore-next-line complexity
|
|
169
|
+
function resolveToken(token, available) {
|
|
170
|
+
if (token === "left" || token === "top")
|
|
171
|
+
return 0;
|
|
172
|
+
if (token === "right" || token === "bottom")
|
|
173
|
+
return available;
|
|
174
|
+
if (token === "center")
|
|
175
|
+
return available / 2;
|
|
176
|
+
if (token.endsWith("%")) {
|
|
177
|
+
const pct = parseFloat(token) / 100;
|
|
178
|
+
return isNaN(pct) ? available / 2 : pct * available;
|
|
179
|
+
}
|
|
180
|
+
if (token.endsWith("px")) {
|
|
181
|
+
const px = parseFloat(token);
|
|
182
|
+
return isNaN(px) ? available / 2 : px;
|
|
183
|
+
}
|
|
184
|
+
// Bare number — treat as px
|
|
185
|
+
const n = parseFloat(token);
|
|
186
|
+
return isNaN(n) ? available / 2 : n;
|
|
187
|
+
}
|
|
188
|
+
const availX = box.width - content.width;
|
|
189
|
+
const availY = box.height - content.height;
|
|
190
|
+
const isVert = (t) => t === "top" || t === "bottom";
|
|
191
|
+
const isHoriz = (t) => t === "left" || t === "right";
|
|
192
|
+
if (parts.length === 1) {
|
|
193
|
+
const tokenX = parts[0] ?? "50%";
|
|
194
|
+
// Single value: if it's a vertical keyword the x defaults to center
|
|
195
|
+
if (isVert(tokenX)) {
|
|
196
|
+
return { x: availX / 2, y: resolveToken(tokenX, availY) };
|
|
197
|
+
}
|
|
198
|
+
return { x: resolveToken(tokenX, availX), y: availY / 2 };
|
|
199
|
+
}
|
|
200
|
+
// Keyword pairs may be given vertical-first ("bottom left"); normalize so the
|
|
201
|
+
// first token addresses the x-axis and the second the y-axis.
|
|
202
|
+
let xToken = parts[0] ?? "50%";
|
|
203
|
+
let yToken = parts[1] ?? "50%";
|
|
204
|
+
if (isVert(xToken) || isHoriz(yToken)) {
|
|
205
|
+
[xToken, yToken] = [yToken, xToken];
|
|
206
|
+
}
|
|
207
|
+
return {
|
|
208
|
+
x: resolveToken(xToken, availX),
|
|
209
|
+
y: resolveToken(yToken, availY),
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
function clamp(v, min, max) {
|
|
213
|
+
return v < min ? min : v > max ? max : v;
|
|
214
|
+
}
|
|
215
|
+
// ─── Visibility check ─────────────────────────────────────────────────────────
|
|
216
|
+
/**
|
|
217
|
+
* Returns true when no element in the ancestor chain (inclusive) has
|
|
218
|
+
* computed opacity === 0. Checks ancestors because a parent at opacity:0
|
|
219
|
+
* makes the child invisible even if the child's own opacity is 1.
|
|
220
|
+
*
|
|
221
|
+
* This reflects the current GSAP timeline state (whatever the player has
|
|
222
|
+
* seeked to). For atTime values matching the live playhead this is always
|
|
223
|
+
* accurate. For speculative times this is NOT seeked — WS-A1 does not mutate
|
|
224
|
+
* the timeline; accurate out-of-band opacity queries are WS-G follow-on.
|
|
225
|
+
*/
|
|
226
|
+
function isOpacityVisible(el, win) {
|
|
227
|
+
let node = el;
|
|
228
|
+
while (node !== null) {
|
|
229
|
+
const style = win.getComputedStyle(node);
|
|
230
|
+
if (parseFloat(style.opacity) === 0)
|
|
231
|
+
return false;
|
|
232
|
+
node = node.parentElement;
|
|
233
|
+
}
|
|
234
|
+
return true;
|
|
235
|
+
}
|
|
236
|
+
// ─── Image-alpha canvas cache (WS-G phase 1) ─────────────────────────────────
|
|
237
|
+
/**
|
|
238
|
+
* Cache of offscreen canvases keyed by image currentSrc.
|
|
239
|
+
*
|
|
240
|
+
* Canvases are drawn once; the same canvas is reused across hit-tests.
|
|
241
|
+
* Animated images (gif) or dynamic src swaps are NOT tracked — this is a
|
|
242
|
+
* phase-1 static-image optimization. A tainted entry stores null to record
|
|
243
|
+
* that the image is cross-origin and all pixels should be treated as opaque.
|
|
244
|
+
*
|
|
245
|
+
* Exported for tests that need to reset the cache between runs.
|
|
246
|
+
*/
|
|
247
|
+
export const _imgCanvasCache = new Map();
|
|
248
|
+
/**
|
|
249
|
+
* Bounded cap so a long session can't accumulate one full-resolution
|
|
250
|
+
* OffscreenCanvas per image src indefinitely.
|
|
251
|
+
* ponytail: FIFO eviction, upgrade to LRU if cache hit-rate matters.
|
|
252
|
+
*/
|
|
253
|
+
const _IMG_CANVAS_CACHE_MAX = 64;
|
|
254
|
+
function cacheCanvas(key, value) {
|
|
255
|
+
if (!_imgCanvasCache.has(key) && _imgCanvasCache.size >= _IMG_CANVAS_CACHE_MAX) {
|
|
256
|
+
const oldest = _imgCanvasCache.keys().next().value;
|
|
257
|
+
if (oldest !== undefined)
|
|
258
|
+
_imgCanvasCache.delete(oldest);
|
|
259
|
+
}
|
|
260
|
+
_imgCanvasCache.set(key, value);
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Skip alpha-testing images above this pixel budget — allocating a full-res
|
|
264
|
+
* OffscreenCanvas for one hit-test is memory-prohibitive (a 4000×3000 image is
|
|
265
|
+
* ~46 MB). Above the cap we fail safe to opaque.
|
|
266
|
+
* ponytail: per-image pixel cap; a byte-budget cache is phase 2.
|
|
267
|
+
*/
|
|
268
|
+
const _MAX_ALPHA_TEST_PIXELS = 16_000_000;
|
|
269
|
+
/**
|
|
270
|
+
* Srcs we've already warned about taint for — keeps the cross-origin warning to
|
|
271
|
+
* once per image instead of once per hit-test. Cleared with `_imgCanvasCache`
|
|
272
|
+
* is not necessary; suppressing duplicate warnings across resets is harmless.
|
|
273
|
+
*/
|
|
274
|
+
const _warnedTaintSrcs = new Set();
|
|
275
|
+
function warnTaintOnce(src) {
|
|
276
|
+
if (_warnedTaintSrcs.has(src))
|
|
277
|
+
return;
|
|
278
|
+
_warnedTaintSrcs.add(src);
|
|
279
|
+
// Visibility for the silent-failure path: a cross-origin / uncorsed image
|
|
280
|
+
// taints the canvas, so alpha hit-test is unavailable and we fall back to
|
|
281
|
+
// opaque. Without this, the fall-back is invisible ("hit-test feels wrong").
|
|
282
|
+
console.warn(`[hyperframes] image-alpha hit-test unavailable for cross-origin/tainted image; treating as opaque: ${src}`);
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* True when the element or any ancestor carries a CSS rotation or skew. Such a
|
|
286
|
+
* transform makes getBoundingClientRect() return the axis-aligned bounding box,
|
|
287
|
+
* so the rect→natural-pixel mapping would sample the wrong pixel. Pure translate
|
|
288
|
+
* / scale keep the matrix b and c components at 0 and map correctly. No-op
|
|
289
|
+
* (returns false) when DOMMatrix is unavailable (e.g. the test env), preserving
|
|
290
|
+
* existing behavior there.
|
|
291
|
+
*/
|
|
292
|
+
function hasRotationOrSkew(el, win) {
|
|
293
|
+
if (typeof win.DOMMatrix !== "function")
|
|
294
|
+
return false;
|
|
295
|
+
for (let node = el; node; node = node.parentElement) {
|
|
296
|
+
const t = win.getComputedStyle(node).transform;
|
|
297
|
+
if (!t || t === "none")
|
|
298
|
+
continue;
|
|
299
|
+
try {
|
|
300
|
+
const m = new win.DOMMatrix(t);
|
|
301
|
+
if (Math.abs(m.b) > 1e-6 || Math.abs(m.c) > 1e-6)
|
|
302
|
+
return true;
|
|
303
|
+
}
|
|
304
|
+
catch {
|
|
305
|
+
return true; // unparseable transform — fail safe (treat as non-axis-aligned)
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
return false;
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Sample the alpha at (clientX, clientY) for an <img> element.
|
|
312
|
+
*
|
|
313
|
+
* Returns true (opaque) when:
|
|
314
|
+
* - The image has not finished loading (naturalWidth/naturalHeight === 0)
|
|
315
|
+
* - The point maps outside the rendered image area (not this image's pixel)
|
|
316
|
+
* - The canvas is tainted (cross-origin, SecurityError) — fallback: opaque
|
|
317
|
+
* - Alpha >= 1
|
|
318
|
+
*
|
|
319
|
+
* Returns false (transparent/miss) only when the canvas is readable AND the
|
|
320
|
+
* alpha at the mapped pixel is 0. A click on the element's border/padding maps
|
|
321
|
+
* outside the content box → also false (the click falls through to the layer
|
|
322
|
+
* behind), since border/padding pixels aren't part of the image — intentional.
|
|
323
|
+
*
|
|
324
|
+
* `win` is the iframe's contentWindow, used to call getComputedStyle on the
|
|
325
|
+
* element which lives in the iframe's document.
|
|
326
|
+
*/
|
|
327
|
+
// fallow-ignore-next-line complexity
|
|
328
|
+
function imageAlphaOpaqueAt(img, clientX, clientY, win) {
|
|
329
|
+
// Not loaded yet — treat as opaque (safe fallback)
|
|
330
|
+
if (img.naturalWidth === 0 || img.naturalHeight === 0)
|
|
331
|
+
return true;
|
|
332
|
+
const src = img.currentSrc || img.src;
|
|
333
|
+
if (!src)
|
|
334
|
+
return true;
|
|
335
|
+
// CSS rotation/skew on the image or an ancestor breaks the axis-aligned
|
|
336
|
+
// rect→natural-pixel mapping below (getBoundingClientRect returns the AABB),
|
|
337
|
+
// so we'd sample the wrong pixel. Fail safe to opaque rather than guess.
|
|
338
|
+
// Full transform-inverse mapping is phase 2.
|
|
339
|
+
if (hasRotationOrSkew(img, win))
|
|
340
|
+
return true;
|
|
341
|
+
// Pathological-size guard: don't allocate a huge canvas for one hit-test.
|
|
342
|
+
if (img.naturalWidth * img.naturalHeight > _MAX_ALPHA_TEST_PIXELS)
|
|
343
|
+
return true;
|
|
344
|
+
// object-fit/object-position lay the image out within the CONTENT box, not
|
|
345
|
+
// the border box that getBoundingClientRect() returns. Inset by border +
|
|
346
|
+
// padding so the mapping is correct for an <img> that has a border or padding.
|
|
347
|
+
const rect = img.getBoundingClientRect();
|
|
348
|
+
const style = win.getComputedStyle(img);
|
|
349
|
+
const borderL = parseFloat(style.borderLeftWidth) || 0;
|
|
350
|
+
const borderT = parseFloat(style.borderTopWidth) || 0;
|
|
351
|
+
const borderR = parseFloat(style.borderRightWidth) || 0;
|
|
352
|
+
const borderB = parseFloat(style.borderBottomWidth) || 0;
|
|
353
|
+
const padL = parseFloat(style.paddingLeft) || 0;
|
|
354
|
+
const padT = parseFloat(style.paddingTop) || 0;
|
|
355
|
+
const padR = parseFloat(style.paddingRight) || 0;
|
|
356
|
+
const padB = parseFloat(style.paddingBottom) || 0;
|
|
357
|
+
const objectFit = style.objectFit || "fill";
|
|
358
|
+
const objectPosition = style.objectPosition || "50% 50%";
|
|
359
|
+
const mapped = mapPointToImagePixel({
|
|
360
|
+
left: rect.left + borderL + padL,
|
|
361
|
+
top: rect.top + borderT + padT,
|
|
362
|
+
width: rect.width - borderL - borderR - padL - padR,
|
|
363
|
+
height: rect.height - borderT - borderB - padT - padB,
|
|
364
|
+
}, { width: img.naturalWidth, height: img.naturalHeight }, objectFit, objectPosition, { x: clientX, y: clientY });
|
|
365
|
+
// Point is outside the rendered image area — not this image's pixel.
|
|
366
|
+
// Continue the z-stack (return false = miss on this element).
|
|
367
|
+
if (mapped === null)
|
|
368
|
+
return false;
|
|
369
|
+
// Retrieve or build the offscreen canvas. Key on src + natural dimensions: a
|
|
370
|
+
// srcset/responsive layout can serve the same URL at a different natural size,
|
|
371
|
+
// and keying on src alone would reuse a canvas drawn at the prior dimensions.
|
|
372
|
+
const cacheKey = `${src}@${img.naturalWidth}x${img.naturalHeight}`;
|
|
373
|
+
let canvas = _imgCanvasCache.get(cacheKey);
|
|
374
|
+
if (canvas === undefined) {
|
|
375
|
+
// First time: draw to an offscreen canvas and cache.
|
|
376
|
+
try {
|
|
377
|
+
const oc = new OffscreenCanvas(img.naturalWidth, img.naturalHeight);
|
|
378
|
+
const ctx = oc.getContext("2d");
|
|
379
|
+
if (!ctx) {
|
|
380
|
+
// OffscreenCanvas 2D unavailable — treat as opaque.
|
|
381
|
+
cacheCanvas(cacheKey, null);
|
|
382
|
+
return true;
|
|
383
|
+
}
|
|
384
|
+
ctx.drawImage(img, 0, 0, img.naturalWidth, img.naturalHeight);
|
|
385
|
+
cacheCanvas(cacheKey, oc);
|
|
386
|
+
canvas = oc;
|
|
387
|
+
}
|
|
388
|
+
catch {
|
|
389
|
+
// SecurityError from tainted canvas — record null and fall back opaque.
|
|
390
|
+
warnTaintOnce(src);
|
|
391
|
+
cacheCanvas(cacheKey, null);
|
|
392
|
+
return true;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
// null means we already know this src is tainted — treat as opaque.
|
|
396
|
+
if (canvas === null)
|
|
397
|
+
return true;
|
|
398
|
+
try {
|
|
399
|
+
const ctx = canvas.getContext("2d");
|
|
400
|
+
if (!ctx)
|
|
401
|
+
return true;
|
|
402
|
+
// The mapped-pixel read also surfaces lazy canvas taint (SecurityError),
|
|
403
|
+
// so no separate taint probe is needed.
|
|
404
|
+
const data = ctx.getImageData(mapped.px, mapped.py, 1, 1);
|
|
405
|
+
return alphaIsOpaque(data);
|
|
406
|
+
}
|
|
407
|
+
catch {
|
|
408
|
+
// Taint discovered on getImageData — update cache and fall back opaque.
|
|
409
|
+
warnTaintOnce(src);
|
|
410
|
+
cacheCanvas(cacheKey, null);
|
|
411
|
+
return true;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
// ─── IframePreviewAdapter ─────────────────────────────────────────────────────
|
|
415
|
+
/**
|
|
416
|
+
* The hit-test z-stack at (x, y): the full elementsFromPoint stack, or a
|
|
417
|
+
* single-element fallback for hosts that lack elementsFromPoint.
|
|
418
|
+
*/
|
|
419
|
+
function hitStack(doc, x, y) {
|
|
420
|
+
if (typeof doc.elementsFromPoint === "function")
|
|
421
|
+
return doc.elementsFromPoint(x, y);
|
|
422
|
+
const top = doc.elementFromPoint(x, y);
|
|
423
|
+
return top ? [top] : [];
|
|
424
|
+
}
|
|
425
|
+
class IframePreviewAdapter {
|
|
426
|
+
iframe;
|
|
427
|
+
_dispatch;
|
|
428
|
+
_selection = [];
|
|
429
|
+
_handlers = [];
|
|
430
|
+
/** Tracked id and element for the in-progress drag. */
|
|
431
|
+
_draftId = null;
|
|
432
|
+
_draftEl = null;
|
|
433
|
+
constructor(iframe, dispatch) {
|
|
434
|
+
this.iframe = iframe;
|
|
435
|
+
this._dispatch = dispatch;
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Synchronous hit-test. Returns the nearest `[data-hf-id]` element under
|
|
439
|
+
* (x, y) in the iframe's coordinate space, or null for a transparent hit
|
|
440
|
+
* (root, opacity-0, nothing at all, or a transparent image pixel).
|
|
441
|
+
*
|
|
442
|
+
* WS-G phase 1: uses elementsFromPoint (z-stack) so a transparent-image hit
|
|
443
|
+
* falls through to the layer behind. For <img> elements, the alpha at the
|
|
444
|
+
* mapped natural pixel is sampled from an offscreen canvas. Cross-origin
|
|
445
|
+
* images that taint the canvas are treated as opaque (safe fallback).
|
|
446
|
+
*
|
|
447
|
+
* atTime: reflects the GSAP state at the playhead when this is called.
|
|
448
|
+
* Seeking to a different time to check visibility is WS-G follow-on.
|
|
449
|
+
*/
|
|
450
|
+
elementAtPoint(x, y, _opts) {
|
|
451
|
+
const doc = this.iframe.contentDocument;
|
|
452
|
+
if (!doc)
|
|
453
|
+
return null;
|
|
454
|
+
const win = this.iframe.contentWindow;
|
|
455
|
+
if (!win)
|
|
456
|
+
return null;
|
|
457
|
+
const stack = hitStack(doc, x, y);
|
|
458
|
+
for (const candidate of stack) {
|
|
459
|
+
// One opacity walk per candidate (candidate → root). An opacity:0 element
|
|
460
|
+
// is skipped, so the click falls through to the layer painted behind it.
|
|
461
|
+
if (!isOpacityVisible(candidate, win))
|
|
462
|
+
continue;
|
|
463
|
+
// Image-alpha check: if this is an <img>, verify the pixel is opaque.
|
|
464
|
+
if (win.HTMLImageElement && candidate instanceof win.HTMLImageElement) {
|
|
465
|
+
if (!imageAlphaOpaqueAt(candidate, x, y, win)) {
|
|
466
|
+
// Transparent pixel — fall through to the next element in the stack.
|
|
467
|
+
continue;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
// The candidate's whole ancestor chain is already known visible (the walk
|
|
471
|
+
// above covers it, and the hf node is on that chain), so the resolver
|
|
472
|
+
// needs no second visibility walk.
|
|
473
|
+
const result = resolveNearestHfElement(candidate, () => true);
|
|
474
|
+
if (result !== null)
|
|
475
|
+
return result;
|
|
476
|
+
}
|
|
477
|
+
return null;
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* Write draft CSS custom properties (`--hf-studio-dx`, `--hf-studio-dy`) onto
|
|
481
|
+
* the target element inside the iframe at 60fps. The composition's CSS uses
|
|
482
|
+
* these vars to visually translate the element without touching the model.
|
|
483
|
+
*
|
|
484
|
+
* Calling applyDraft with a new id replaces the tracked element (does not
|
|
485
|
+
* cancel the prior draft — call cancelPreview first if switching targets).
|
|
486
|
+
*
|
|
487
|
+
* width/height in DraftProps are not yet wired (resize → setStyle, future op).
|
|
488
|
+
*/
|
|
489
|
+
applyDraft(id, props) {
|
|
490
|
+
const doc = this.iframe.contentDocument;
|
|
491
|
+
if (!doc)
|
|
492
|
+
return;
|
|
493
|
+
// Reuse the tracked element across the 60fps drag; only re-query when the id
|
|
494
|
+
// changes or the cached node detached (e.g. an iframe reload mid-drag).
|
|
495
|
+
const cached = id === this._draftId && this._draftEl?.isConnected ? this._draftEl : null;
|
|
496
|
+
const el = cached ??
|
|
497
|
+
doc.querySelector(`[data-hf-id="${id.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"]`);
|
|
498
|
+
if (!el)
|
|
499
|
+
return;
|
|
500
|
+
this._draftId = id;
|
|
501
|
+
this._draftEl = el;
|
|
502
|
+
if (props.dx !== undefined)
|
|
503
|
+
el.style.setProperty(VAR_DX, String(props.dx));
|
|
504
|
+
if (props.dy !== undefined)
|
|
505
|
+
el.style.setProperty(VAR_DY, String(props.dy));
|
|
506
|
+
}
|
|
507
|
+
/**
|
|
508
|
+
* Read the accumulated draft deltas, derive a moveElement op, dispatch it,
|
|
509
|
+
* then clear the CSS vars and draft state.
|
|
510
|
+
*
|
|
511
|
+
* No-ops when:
|
|
512
|
+
* - No applyDraft was called (nothing to commit)
|
|
513
|
+
* - No dispatch callback was provided at construction
|
|
514
|
+
*/
|
|
515
|
+
commitPreview() {
|
|
516
|
+
if (!this._draftId || !this._draftEl || !this._dispatch) {
|
|
517
|
+
this._clearDraft();
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
const el = this._draftEl;
|
|
521
|
+
const dx = parseFloat(el.style.getPropertyValue(VAR_DX) || "0") || 0;
|
|
522
|
+
const dy = parseFloat(el.style.getPropertyValue(VAR_DY) || "0") || 0;
|
|
523
|
+
const dataX = el.getAttribute("data-x");
|
|
524
|
+
const dataY = el.getAttribute("data-y");
|
|
525
|
+
const { x, y } = computeDraftPosition(dataX, dataY, dx, dy);
|
|
526
|
+
this._dispatch({ type: "moveElement", target: this._draftId, x, y });
|
|
527
|
+
this._clearDraft();
|
|
528
|
+
}
|
|
529
|
+
/** Revert draft CSS vars without dispatching any op. */
|
|
530
|
+
cancelPreview() {
|
|
531
|
+
this._clearDraft();
|
|
532
|
+
}
|
|
533
|
+
_clearDraft() {
|
|
534
|
+
if (this._draftEl) {
|
|
535
|
+
this._draftEl.style.removeProperty(VAR_DX);
|
|
536
|
+
this._draftEl.style.removeProperty(VAR_DY);
|
|
537
|
+
}
|
|
538
|
+
this._draftId = null;
|
|
539
|
+
this._draftEl = null;
|
|
540
|
+
}
|
|
541
|
+
// Selection -----------------------------------------------------------------
|
|
542
|
+
select(ids, opts) {
|
|
543
|
+
if (opts?.additive) {
|
|
544
|
+
const merged = new Set([...this._selection, ...ids]);
|
|
545
|
+
this._selection = [...merged];
|
|
546
|
+
}
|
|
547
|
+
else {
|
|
548
|
+
this._selection = [...ids];
|
|
549
|
+
}
|
|
550
|
+
this._emit();
|
|
551
|
+
}
|
|
552
|
+
on(event, handler) {
|
|
553
|
+
if (event !== "selection")
|
|
554
|
+
return () => { };
|
|
555
|
+
this._handlers.push(handler);
|
|
556
|
+
return () => {
|
|
557
|
+
this._handlers = this._handlers.filter((h) => h !== handler);
|
|
558
|
+
};
|
|
559
|
+
}
|
|
560
|
+
_emit() {
|
|
561
|
+
const ids = [...this._selection];
|
|
562
|
+
for (const h of this._handlers)
|
|
563
|
+
h(ids);
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
export function createIframePreviewAdapter(iframe, dispatch) {
|
|
567
|
+
return new IframePreviewAdapter(iframe, dispatch);
|
|
568
|
+
}
|
|
569
|
+
//# sourceMappingURL=iframe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"iframe.js","sourceRoot":"","sources":["../../src/adapters/iframe.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/adapters/memory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAuB,MAAM,YAAY,CAAC;AA2DtE,wBAAgB,mBAAmB,IAAI,cAAc,GAAG;IAAE,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAE7F"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
class MemoryAdapter {
|
|
2
|
+
store = new Map();
|
|
3
|
+
history = new Map();
|
|
4
|
+
errorListeners = [];
|
|
5
|
+
versionCounter = 0;
|
|
6
|
+
faultMessage = null;
|
|
7
|
+
async read(path) {
|
|
8
|
+
return this.store.get(path);
|
|
9
|
+
}
|
|
10
|
+
async write(path, content) {
|
|
11
|
+
if (this.faultMessage !== null) {
|
|
12
|
+
const msg = this.faultMessage;
|
|
13
|
+
this.faultMessage = null;
|
|
14
|
+
this.errorListeners.forEach((l) => l({ error: { message: msg } }));
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
this.store.set(path, content);
|
|
18
|
+
const hist = this.history.get(path) ?? [];
|
|
19
|
+
const entry = {
|
|
20
|
+
key: `v${++this.versionCounter}`,
|
|
21
|
+
content,
|
|
22
|
+
};
|
|
23
|
+
hist.unshift(entry);
|
|
24
|
+
this.history.set(path, hist);
|
|
25
|
+
}
|
|
26
|
+
async flush() {
|
|
27
|
+
// Memory adapter writes are synchronous — nothing to drain.
|
|
28
|
+
}
|
|
29
|
+
async listVersions(path) {
|
|
30
|
+
return [...(this.history.get(path) ?? [])];
|
|
31
|
+
}
|
|
32
|
+
async loadFrom(path, versionKey) {
|
|
33
|
+
const hist = this.history.get(path) ?? [];
|
|
34
|
+
return hist.find((v) => v.key === versionKey)?.content;
|
|
35
|
+
}
|
|
36
|
+
on(event, handler) {
|
|
37
|
+
if (event !== "persist:error")
|
|
38
|
+
return () => { };
|
|
39
|
+
this.errorListeners.push(handler);
|
|
40
|
+
return () => {
|
|
41
|
+
const idx = this.errorListeners.indexOf(handler);
|
|
42
|
+
if (idx !== -1)
|
|
43
|
+
this.errorListeners.splice(idx, 1);
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/** Test helper — next write fires persist:error instead of committing */
|
|
47
|
+
injectFault(message) {
|
|
48
|
+
this.faultMessage = message;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
export function createMemoryAdapter() {
|
|
52
|
+
return new MemoryAdapter();
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=memory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/adapters/memory.ts"],"names":[],"mappings":"AAGA,MAAM,aAAa;IACA,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;IAClC,OAAO,GAAG,IAAI,GAAG,EAAiC,CAAC;IACnD,cAAc,GAA0C,EAAE,CAAC;IACpE,cAAc,GAAG,CAAC,CAAC;IACnB,YAAY,GAAkB,IAAI,CAAC;IAE3C,KAAK,CAAC,IAAI,CAAC,IAAY;QACrB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,IAAY,EAAE,OAAe;QACvC,IAAI,IAAI,CAAC,YAAY,KAAK,IAAI,EAAE,CAAC;YAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC;YAC9B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;YACzB,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;YACnE,OAAO;QACT,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAC1C,MAAM,KAAK,GAAwB;YACjC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,cAAc,EAAE;YAChC,OAAO;SACR,CAAC;QACF,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACpB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,KAAK;QACT,4DAA4D;IAC9D,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,IAAY;QAC7B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,IAAY,EAAE,UAAkB;QAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAC1C,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,UAAU,CAAC,EAAE,OAAO,CAAC;IACzD,CAAC;IAED,EAAE,CAAC,KAAsB,EAAE,OAAuC;QAChE,IAAI,KAAK,KAAK,eAAe;YAAE,OAAO,GAAG,EAAE,GAAE,CAAC,CAAC;QAC/C,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAClC,OAAO,GAAG,EAAE;YACV,MAAM,GAAG,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACjD,IAAI,GAAG,KAAK,CAAC,CAAC;gBAAE,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACrD,CAAC,CAAC;IACJ,CAAC;IAED,yEAAyE;IACzE,WAAW,CAAC,OAAe;QACzB,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC;IAC9B,CAAC;CACF;AAED,MAAM,UAAU,mBAAmB;IACjC,OAAO,IAAI,aAAa,EAAE,CAAC;AAC7B,CAAC"}
|