From 67cfae2587e15b0dd6a064d9fdbd4790831905cf Mon Sep 17 00:00:00 2001 From: Miguel Angel Simon Sierra Date: Sat, 11 Jul 2026 14:58:21 -0400 Subject: [PATCH] refactor: address review nits - merge gsapResizeIntercept's duplicate module imports - move the core-constant imports to the file headers (picker, domEditingDom) - justify the cross-realm HTMLElement casts (iframe-realm nodes fail instanceof; access is duck-typed) --- packages/core/src/runtime/picker.ts | 2 +- packages/studio/src/components/editor/domEditingDom.ts | 3 +-- packages/studio/src/hooks/gsapResizeIntercept.ts | 9 +++++---- packages/studio/src/utils/gsapSoftReload.ts | 6 ++++-- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/packages/core/src/runtime/picker.ts b/packages/core/src/runtime/picker.ts index e9ced66c2..52921fb82 100644 --- a/packages/core/src/runtime/picker.ts +++ b/packages/core/src/runtime/picker.ts @@ -1,4 +1,5 @@ import type { RuntimeJson, RuntimeOutboundMessage, RuntimePickerElementInfo } from "./types"; +import { COLOR_GRADING_SOURCE_HIDDEN_ATTR } from "../colorGrading"; import { swallow } from "./diagnostics"; type PickerModuleDeps = { @@ -17,7 +18,6 @@ const PICKER_BLOCK_SELECTOR = [ "[data-hyperframes-picker-block]", "[data-hyper-shader-loading]", ].join(","); -import { COLOR_GRADING_SOURCE_HIDDEN_ATTR } from "../colorGrading"; export type PickerModule = { enablePickMode: () => void; diff --git a/packages/studio/src/components/editor/domEditingDom.ts b/packages/studio/src/components/editor/domEditingDom.ts index 82b564978..b1f341ca7 100644 --- a/packages/studio/src/components/editor/domEditingDom.ts +++ b/packages/studio/src/components/editor/domEditingDom.ts @@ -3,6 +3,7 @@ * selector utilities, and composition source resolution. * No imports from other domEditing* modules — safe to import from anywhere. */ +import { COLOR_GRADING_SOURCE_HIDDEN_ATTR } from "@hyperframes/core/color-grading"; import { CURATED_STYLE_PROPERTIES } from "./domEditingTypes"; // ─── Type guard ─────────────────────────────────────────────────────────────── @@ -28,8 +29,6 @@ export function isTextBearingTag(tagName: string): boolean { return ["div", "span", "p", "strong", "h1", "h2", "h3", "h4", "h5", "h6"].includes(tagName); } -import { COLOR_GRADING_SOURCE_HIDDEN_ATTR } from "@hyperframes/core/color-grading"; - export function isElementVisibleThroughAncestors(el: HTMLElement): boolean { const win = el.ownerDocument.defaultView; if (!win) return true; diff --git a/packages/studio/src/hooks/gsapResizeIntercept.ts b/packages/studio/src/hooks/gsapResizeIntercept.ts index aee92be6f..9396384f2 100644 --- a/packages/studio/src/hooks/gsapResizeIntercept.ts +++ b/packages/studio/src/hooks/gsapResizeIntercept.ts @@ -16,19 +16,18 @@ import { commitStaticGsapSize, commitKeyframedSizeFromResize, computeCurrentPercentage, + findExistingPositionWrite, findSizeSetAnimation, materializeIfDynamic, } from "./gsapDragCommit"; import type { GsapDragCommitCallbacks } from "./gsapDragCommit"; -import { pickClosestToPlayhead } from "./gsapPositionDetection"; +import { pickClosestToPlayhead, readGsapPositionFromIframe } from "./gsapPositionDetection"; +import { commitWholePropertyOffset } from "./gsapWholePropertyOffsetCommit"; import { resolveTweenStart, resolveTweenDuration } from "../utils/globalTimeCompiler"; import { selectorFromSelection } from "./gsapShared"; import { roundTo3 } from "../utils/rounding"; import { resolveGroupTween, POSITION_CHANNELS } from "./gsapRuntimeBridge"; import { hasNonHoldTweenForElement } from "./gsapRuntimeKeyframes"; -import { readGsapPositionFromIframe } from "./gsapPositionDetection"; -import { findExistingPositionWrite } from "./gsapDragCommit"; -import { commitWholePropertyOffset } from "./gsapWholePropertyOffsetCommit"; const IDENTITY_ONE_PROPS = new Set(["opacity", "autoAlpha", "scale", "scaleX", "scaleY"]); @@ -114,6 +113,8 @@ export async function tryGsapResizeIntercept( let scaleDraftDropPoint: { x: number; y: number } | null = null; let nonUniformScale = false; if (resizeGroup === "scale") { + // Iframe-realm element — instanceof HTMLElement fails across realms; the + // selector targets composition elements, and every use below is duck-typed. const el = iframe?.contentDocument?.querySelector(selector ?? "") as HTMLElement | null; // The resize draft modifies el.style.width/height, so read the ORIGINAL // dimensions saved by the draft system before it ran. diff --git a/packages/studio/src/utils/gsapSoftReload.ts b/packages/studio/src/utils/gsapSoftReload.ts index a5f08eea3..f9f051fa8 100644 --- a/packages/studio/src/utils/gsapSoftReload.ts +++ b/packages/studio/src/utils/gsapSoftReload.ts @@ -319,8 +319,10 @@ export function applySoftReload( if (allTargets.length > 0 && win.gsap?.set) { const saved: Array<[HTMLElement, string]> = []; for (const el of allTargets) { - const s = (el as HTMLElement).style; - if (s?.cssText != null) saved.push([el as HTMLElement, s.cssText]); + // Iframe-realm node: instanceof HTMLElement fails across realms, and + // gsap targets() only yields elements here — style access is duck-typed. + const styled = el as HTMLElement; + if (styled.style?.cssText != null) saved.push([styled, styled.style.cssText]); } try { win.gsap.set(allTargets, { clearProps: "all" });