Skip to content

fix(studio): replacing an image's fill on an img changes its picture - #5170

Merged
miguel-heygen merged 2 commits into
mainfrom
fix/studio-img-fill-src
Oct 7, 2026
Merged

miguel-heygen merged 2 commits into
mainfrom
fix/studio-img-fill-src

Conversation

@miguel-heygen

@miguel-heygen miguel-heygen commented Oct 7, 2026 •

Copy link
Copy Markdown
Collaborator

Replacing an image through Fill → Image previously wrote a CSS background behind the existing opaque picture. The shared image field now uses the existing HTML attribute writer to replace an img's src, shows its current source, and preserves that source when cleared. Other elements retain background-image replacement and clearing. Both classic and flat inspectors use the fix; assets selected in nested compositions keep source-relative paths.

Fixes #5167.

Validation: the new control regressions fail on main because replacement leaves src unchanged. The focused 16-test suite passes three consecutive runs, the existing flat style suite passes 37 tests, and Studio typecheck passes. Real Studio fixture proof reproduces the old red image after replacement on main and shows the replacement blue image after the fix, including reload, a fresh document loaded from persisted HTML, and the producer-rendered frame. Raw-percent filenames and inline SVG sources are covered by regressions that fail before the path-decoding fix.

Before

Studio on main after replacement still shows the old red image.

Before in Studio on main: old red raster after replacing Fill

After

The settled Studio preview and timeline both show the blue replacement, and Fill shows its current source. The producer frame renders the same replacement from saved HTML.

After in Studio: settled blue preview, Fill source, and timeline thumbnail

Producer-rendered frame from saved HTML: replacement blue raster without Studio UI

@miguel-heygen
miguel-heygen marked this pull request as ready for review October 7, 2026 07:51
@github-actions

github-actions Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Edit accuracy: accurate 2059 (base branch 2059), smooth 1609 of those

The gate passes.
Smoothness is reported in the artifact, not gated. A case fails only if it fails 2 of 3 runs.

Quarantined, measured but not gated (0)

@jrusso1020 jrusso1020 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving. Replacing an <img> through Fill now changes its picture instead of writing a background behind it.

What I checked

  • propertyPanelFill.tsx: for an img, every write (upload, project asset, external URL) goes through commitImage, which writes src with the existing attribute writer. Other elements still get background-image, unchanged. Both inspectors pass the writer through, and both now show Image mode for an img.
  • The write path is the same one the loop and link controls already use (handleDomHtmlAttributeCommit → html-attribute op). src is on the allow list in htmlAttrSafety.ts, and the commit reloads the preview after it saves.
  • In a nested composition, src is written relative to the source file (../assets/new.png). That matches how a timeline asset drop writes src (resolveTimelineAssetSrc), and the runtime rewrites sub-composition paths against the file's URL. So the saved file and the render agree.
  • The decodeURIComponent guard fixes a real crash: a literal % in a source (100%.png, an inline SVG with width="100%") used to throw while rendering the panel.
  • Locally, propertyPanelImageFill.test.tsx and propertyPanelFlatStyleSections.test.tsx pass, 53/53.

Nits (optional)

  1. If an img has a srcset, the browser keeps showing the srcset choice after src changes, so the picture still won't change. That's rare in compositions. A one-line fix is to clear srcset (and sizes) when replacing.
  2. In a nested composition, the preview gets the raw relative path before it reloads, so it resolves against the main document and shows a broken image for a moment. The reload fixes it. I'm only mentioning it in case anyone sees the flash.
  3. An img that already has a stray background-image from the old behaviour can't have it cleared from Fill any more, because clearing now leaves src alone. It's hidden behind the picture, so it's harmless.

Verdict: APPROVE
Reasoning: The fix uses the existing attribute writer and the existing source-relative path rule, the img and non-img paths are both tested in both inspectors, and nothing here blocks.

— Rames

@miguel-heygen
miguel-heygen added this pull request to the merge queue Oct 7, 2026
Merged via the queue into main with commit 17c699d Oct 7, 2026
249 of 261 checks passed
@miguel-heygen
miguel-heygen deleted the fix/studio-img-fill-src branch October 7, 2026 09:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fill → Image replacement has no visual effect on <img> elements (commits background-image instead of src)

2 participants