refactor(studio): single-source timeline id-resolution and resize-clamp math

Extract resolveTimelineIdForSelection so DOM-to-timeline id mapping lives in one place
with a single sourceFile / activeCompPath / index.html fallback, fixing a sub-composition
selection that previously diverged between callers.

Extract shared start-trim delta helpers used by both single-clip and group resize, and
remove the never-called refreshDomEditGroupSelectionsFromPreview.
This commit is contained in:
Miguel Angel Simon Sierra
2026-07-09 16:54:34 -04:00
parent 95ded6c026
commit 3c6c1d3f27
6 changed files with 149 additions and 129 deletions
@@ -4,6 +4,7 @@ import { describe, expect, it } from "vitest";
import {
findMatchingTimelineElementId,
findTimelineIdByAncestor,
resolveTimelineIdForSelection,
resolveTimelineSelectionSeekTime,
} from "./studioHelpers";
@@ -72,3 +73,33 @@ describe("findTimelineIdByAncestor", () => {
expect(findTimelineIdByAncestor(child, [], "index.html")).toBe(null);
});
});
describe("resolveTimelineIdForSelection", () => {
const el = (over: Record<string, unknown>) =>
({ id: "x", start: 0, duration: 1, track: 0, tag: "div", ...over }) as never;
it("resolves an ancestor clip against activeCompPath when the selection has no sourceFile", () => {
// #card (a clip in a sub-composition) > .leaf (selected, not itself a clip)
const card = document.createElement("div");
card.id = "card";
const leaf = document.createElement("span");
leaf.className = "leaf";
card.appendChild(leaf);
const els = [
el({
id: "card",
domId: "card",
key: "comps/panel.html#card",
sourceFile: "comps/panel.html",
}),
];
const selection = { element: leaf } as never;
// Falling back to the active comp matches; the old index.html-only fallback would miss.
expect(resolveTimelineIdForSelection(selection, els, "comps/panel.html")).toBe(
"comps/panel.html#card",
);
expect(resolveTimelineIdForSelection(selection, els, null)).toBe(null);
});
});