Skip to content

Commit 5bc7fa3

Browse files
committed
feat(studio): wire hfId through DOM-edit patch targets, activate hfId lookup path (R7, T5a)
1 parent 2071c85 commit 5bc7fa3

4 files changed

Lines changed: 45 additions & 17 deletions

File tree

packages/studio/src/components/editor/domEditing.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export {
2626
// Layers, text fields, capabilities, selection, patch ops
2727
export {
2828
buildDefaultDomEditTextField,
29+
buildDomEditPatchTarget,
2930
buildDomEditStylePatchOperation,
3031
buildDomEditTextPatchOperation,
3132
collectDomEditLayerItems,

packages/studio/src/components/editor/domEditingLayers.test.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,32 @@
11
// @vitest-environment jsdom
22
import { describe, expect, it } from "vitest";
3-
import { resolveDomEditSelection } from "./domEditingLayers";
3+
import { resolveDomEditSelection, buildDomEditPatchTarget } from "./domEditingLayers";
44

55
const opts = { activeCompositionPath: "index.html", isMasterView: true, skipSourceProbe: true };
66

7+
describe("buildDomEditPatchTarget", () => {
8+
it("includes hfId when selection has hfId", () => {
9+
const target = buildDomEditPatchTarget({
10+
id: undefined,
11+
hfId: "hf-abc",
12+
selector: ".foo",
13+
selectorIndex: 0,
14+
});
15+
expect(target.hfId).toBe("hf-abc");
16+
});
17+
18+
it("includes id and selector when hfId absent", () => {
19+
const target = buildDomEditPatchTarget({
20+
id: "hero",
21+
hfId: undefined,
22+
selector: "#hero",
23+
selectorIndex: undefined,
24+
});
25+
expect(target.id).toBe("hero");
26+
expect(target.hfId).toBeUndefined();
27+
});
28+
});
29+
730
describe("resolveDomEditSelection — hfId from data-hf-id", () => {
831
it("populates hfId from the element data-hf-id attribute", async () => {
932
const el = document.createElement("div");

packages/studio/src/components/editor/domEditingLayers.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,3 +555,14 @@ export function isTextEditableSelection(selection: DomEditSelection): boolean {
555555
}
556556

557557
// buildElementAgentPrompt is in domEditingAgentPrompt.ts
558+
559+
export function buildDomEditPatchTarget(
560+
selection: Pick<DomEditSelection, "id" | "hfId" | "selector" | "selectorIndex">,
561+
): { id?: string | null; hfId?: string; selector?: string; selectorIndex?: number } {
562+
return {
563+
id: selection.id,
564+
hfId: selection.hfId,
565+
selector: selection.selector,
566+
selectorIndex: selection.selectorIndex,
567+
};
568+
}

packages/studio/src/hooks/useDomEditCommits.ts

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ import type { PatchOperation } from "../utils/sourcePatcher";
55
import { trackStudioEvent } from "../utils/studioTelemetry";
66
import { saveProjectFilesWithHistory } from "../utils/studioFileHistory";
77
import { primaryFontFamilyValue } from "../utils/studioFontHelpers";
8-
import { getDomEditTargetKey, type DomEditSelection } from "../components/editor/domEditing";
8+
import {
9+
buildDomEditPatchTarget,
10+
getDomEditTargetKey,
11+
type DomEditSelection,
12+
} from "../components/editor/domEditing";
913
import {
1014
applyStudioPathOffset,
1115
applyStudioBoxSize,
@@ -182,11 +186,7 @@ export function useDomEditCommits({
182186

183187
if (options?.shouldSave && !options.shouldSave()) return;
184188

185-
const patchTarget: { id?: string | null; selector?: string; selectorIndex?: number } = {
186-
id: selection.id,
187-
selector: selection.selector,
188-
selectorIndex: selection.selectorIndex,
189-
};
189+
const patchTarget = buildDomEditPatchTarget(selection);
190190

191191
// Mark the save timestamp before the file write so the SSE file-change
192192
// handler suppresses the reload even if the event arrives before the
@@ -471,16 +471,8 @@ export function useDomEditCommits({
471471
if (typeof originalContent !== "string")
472472
throw new Error(`Missing file contents for ${targetPath}`);
473473

474-
const patchTarget: { id?: string; selector?: string; selectorIndex?: number } = selection.id
475-
? {
476-
id: selection.id,
477-
selector: selection.selector,
478-
selectorIndex: selection.selectorIndex,
479-
}
480-
: selection.selector
481-
? { selector: selection.selector, selectorIndex: selection.selectorIndex }
482-
: ({} as never);
483-
if (!patchTarget.id && !patchTarget.selector) {
474+
const patchTarget = buildDomEditPatchTarget(selection);
475+
if (!patchTarget.id && !patchTarget.selector && !patchTarget.hfId) {
484476
throw new Error("Selected element has no patchable target");
485477
}
486478

@@ -561,6 +553,7 @@ export function useDomEditCommits({
561553
{
562554
element: entry.element,
563555
id: entry.id ?? null,
556+
hfId: entry.element.getAttribute("data-hf-id") ?? undefined,
564557
selector: entry.selector,
565558
selectorIndex: entry.selectorIndex,
566559
sourceFile: entry.sourceFile,

0 commit comments

Comments
 (0)