From 04f96da16967eecff82dfb16e2e0cd238469ffb5 Mon Sep 17 00:00:00 2001 From: ukimsanov Date: Mon, 6 Jul 2026 14:35:41 -0700 Subject: [PATCH] fix(studio): share safe media path cleanup --- .../editor/propertyPanelColorGradingSection.tsx | 9 +-------- .../studio/src/components/editor/propertyPanelHelpers.ts | 8 ++++++++ .../src/components/editor/propertyPanelMediaSection.tsx | 3 ++- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/packages/studio/src/components/editor/propertyPanelColorGradingSection.tsx b/packages/studio/src/components/editor/propertyPanelColorGradingSection.tsx index 2f636086e..14a6cb180 100644 --- a/packages/studio/src/components/editor/propertyPanelColorGradingSection.tsx +++ b/packages/studio/src/components/editor/propertyPanelColorGradingSection.tsx @@ -22,6 +22,7 @@ import { } from "../../utils/studioPendingEdits"; import type { DomEditSelection } from "./domEditing"; import { ColorGradingControls } from "./propertyPanelColorGradingControls"; +import { stripQueryAndHash } from "./propertyPanelHelpers"; import { Section } from "./propertyPanelPrimitives"; const COLOR_GRADING_DATA_KEY = HF_COLOR_GRADING_ATTR.replace(/^data-/, ""); @@ -55,14 +56,6 @@ interface MediaMetadataResponse { metadata: MediaMetadata; } -function stripQueryAndHash(value: string): string { - const queryIndex = value.indexOf("?"); - const hashIndex = value.indexOf("#"); - if (queryIndex < 0) return hashIndex < 0 ? value : value.slice(0, hashIndex); - if (hashIndex < 0) return value.slice(0, queryIndex); - return value.slice(0, Math.min(queryIndex, hashIndex)); -} - function stripPreviewAssetPath(src: string, projectId: string): string | null { let pathname = src; try { diff --git a/packages/studio/src/components/editor/propertyPanelHelpers.ts b/packages/studio/src/components/editor/propertyPanelHelpers.ts index 556a89ee0..9d5cf217b 100644 --- a/packages/studio/src/components/editor/propertyPanelHelpers.ts +++ b/packages/studio/src/components/editor/propertyPanelHelpers.ts @@ -10,6 +10,14 @@ export type { PropertyPanelProps, } from "./propertyPanelTypes"; +export function stripQueryAndHash(value: string): string { + const queryIndex = value.indexOf("?"); + const hashIndex = value.indexOf("#"); + if (queryIndex < 0) return hashIndex < 0 ? value : value.slice(0, hashIndex); + if (hashIndex < 0) return value.slice(0, queryIndex); + return value.slice(0, Math.min(queryIndex, hashIndex)); +} + /* ------------------------------------------------------------------ */ /* Font types & constants (shared by font and section modules) */ /* ------------------------------------------------------------------ */ diff --git a/packages/studio/src/components/editor/propertyPanelMediaSection.tsx b/packages/studio/src/components/editor/propertyPanelMediaSection.tsx index ee9410ac4..d0b1b08cc 100644 --- a/packages/studio/src/components/editor/propertyPanelMediaSection.tsx +++ b/packages/studio/src/components/editor/propertyPanelMediaSection.tsx @@ -9,6 +9,7 @@ import { LABEL, parseNumericValue, RESPONSIVE_GRID, + stripQueryAndHash, } from "./propertyPanelHelpers"; import { Section, SegmentedControl, SelectField, SliderControl } from "./propertyPanelPrimitives"; @@ -77,7 +78,7 @@ export function MediaSection({ projectDir && srcAttr && !srcAttr.startsWith("http") ? `${projectDir}/${srcAttr}` : srcAttr; const projectSrc = srcAttr && !/^(?:https?:|data:|blob:)/i.test(srcAttr) - ? srcAttr.replace(/^\.\//, "").replace(/[?#].*$/, "") + ? stripQueryAndHash(srcAttr.startsWith("./") ? srcAttr.slice(2) : srcAttr) : ""; const canRemoveBackground = Boolean(onRemoveBackground && isVisualMedia && projectSrc); const panelTitle = isImage ? "Image" : isVideo ? "Video" : "Audio";