fix(studio): a text edit's gesture mark draws nothing, so an undo under it reverts

This commit is contained in:
Miguel Angel Simon Sierra
2026-10-01 11:51:41 -07:00
parent 07813687d6
commit e185c116ba
2 changed files with 28 additions and 1 deletions
@@ -5,6 +5,7 @@ import { createRoot } from "react-dom/client";
import { afterEach, describe, expect, it, vi } from "vitest";
import { PreviewReadOnlyProvider } from "../components/editor/previewReadOnlyContext";
import { useInlineTextEdit, type InlineTextEditControls } from "./useInlineTextEdit";
import { applyUndoRestoreToPreview } from "../utils/gsapUndoRestore";
(globalThis as unknown as { IS_REACT_ACT_ENVIRONMENT: boolean }).IS_REACT_ACT_ENVIRONMENT = true;
@@ -643,3 +644,29 @@ describe("useInlineTextEdit with styled runs", () => {
act(() => root.unmount());
});
});
describe("an undo that lands while a text edit is open", () => {
it("marks the edit as drawing nothing, so the undo reverts the move and keeps the edit", () => {
const wrap = (body: string) => `<html><body>${body}</body></html>`;
const moved = `<h1 id="t" style="translate: 90px 60px">Title</h1>`;
document.body.innerHTML = moved;
const element = document.getElementById("t")!;
const { controls, root } = mount();
act(() => {
controls().start(element);
});
const contentWindow = { __player: { seek: vi.fn() }, __hfStudioManualEditsApply: vi.fn() };
const iframe = { contentWindow, contentDocument: document } as unknown as HTMLIFrameElement;
const files = {
"index.html": { previous: wrap(moved), restored: wrap(`<h1 id="t">Title</h1>`) },
};
expect(element.getAttribute("data-hf-studio-manual-edit-gesture")).toMatch(/:edit$/);
expect(applyUndoRestoreToPreview(iframe, "index.html", files, 0, vi.fn())).toBe("soft");
expect(element.style.getPropertyValue("translate")).toBe("");
expect(element.getAttribute("contenteditable")).toBe("true");
expect(element.style.getPropertyValue("outline")).not.toBe("");
act(() => root.unmount());
});
});
@@ -141,7 +141,7 @@ export function useInlineTextEdit({
original: element.innerHTML,
outline: element.style.outline,
outlineOffset: element.style.outlineOffset,
gesture: beginStudioManualEditGesture(element),
gesture: beginStudioManualEditGesture(element, "edit"),
};
// Drawn on the element itself, not in Studio's overlay above it. This is
// the only mark that says the caret is in the TEXT rather than the