mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 04:38:33 +00:00
fix(studio): address review findings on graded-element editing
Review follow-ups (both reviewers, all findings): - resize captures scope to the resize group: convert-to-keyframes resolvedFromValues and the whole-offset backfill pass the group filter, so an opacity-touching intro tween can't ride into a converted scale tween (the rotation fix's contract, now uniform across intercepts) - commitStaticSet resolves every group's target set BEFORE committing and coalesces groups landing on the same legacy mixed set into one commit — the second commit can no longer chase a stale group-derived id - installAuthoredOpacityCapture also stamps an element the moment it GAINS data-color-grading at runtime (attributeFilter), not just at insertion - both writer twins now share the same emitted-set dedupe shape - applySoftReload's positional tail becomes a SoftReloadOptions object - readAllAnimatedProperties builds the group-filtered key set immutably instead of deleting from the set mid-iteration - applyAuthoredInlineOpacity documents the priority-lossy round-trip - the marquee hit-test reads activeCompositionPathRef like its neighbors New tests: resize intercept (scale route + group filter + non-uniform longhands), after-write-HTML / stamp / empty-stamp opacity restore, the no-op-commit-with-missed-instant-patch soft-reload contract, and the runtime-gained-grading stamp.
This commit is contained in:
@@ -643,4 +643,26 @@ describe("installAuthoredOpacityCapture", () => {
|
||||
expect(el.getAttribute("data-hf-authored-opacity")).toBe("");
|
||||
el.remove();
|
||||
});
|
||||
|
||||
it("stamps an already-inserted element the moment it GAINS grading at runtime", async () => {
|
||||
installAuthoredOpacityCapture();
|
||||
const el = document.createElement("img");
|
||||
el.style.opacity = "0.9";
|
||||
document.body.appendChild(el);
|
||||
await Promise.resolve();
|
||||
expect(el.hasAttribute("data-hf-authored-opacity")).toBe(false);
|
||||
|
||||
// Studio applies a preset to a previously ungraded element — no re-insert.
|
||||
el.setAttribute(HF_COLOR_GRADING_ATTR, serializeHfColorGrading({ adjust: { exposure: 0.5 } }));
|
||||
await Promise.resolve();
|
||||
expect(el.getAttribute("data-hf-authored-opacity")).toBe("0.9");
|
||||
|
||||
// Later attribute rewrites (preset tweaks) never overwrite the stamp,
|
||||
// even if a transient is live by then.
|
||||
el.style.opacity = "0";
|
||||
el.setAttribute(HF_COLOR_GRADING_ATTR, serializeHfColorGrading({ adjust: { exposure: 0.9 } }));
|
||||
await Promise.resolve();
|
||||
expect(el.getAttribute("data-hf-authored-opacity")).toBe("0.9");
|
||||
el.remove();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -239,8 +239,21 @@ export function installAuthoredOpacityCapture(): void {
|
||||
new MutationObserver((mutations) => {
|
||||
for (const mutation of mutations) {
|
||||
for (const node of mutation.addedNodes) scan(node);
|
||||
// An element can also GAIN grading at runtime (studio applies a preset to
|
||||
// a previously ungraded element). Stamp at that moment — strictly earlier
|
||||
// than the engine's hide, so the captured value can never be worse than
|
||||
// the hide-time fallback, and after a soft reload's authored restore it
|
||||
// IS the authored value. stamp() is idempotent: an existing stamp wins.
|
||||
if (mutation.type === "attributes" && mutation.target instanceof Element) {
|
||||
if (mutation.target.hasAttribute(HF_COLOR_GRADING_ATTR)) stamp(mutation.target);
|
||||
}
|
||||
}
|
||||
}).observe(root, { childList: true, subtree: true });
|
||||
}).observe(root, {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
attributes: true,
|
||||
attributeFilter: [HF_COLOR_GRADING_ATTR],
|
||||
});
|
||||
}
|
||||
|
||||
// Map insertion order gives us simple FIFO eviction for authoring sessions that cycle LUTs.
|
||||
|
||||
Reference in New Issue
Block a user