Pull Request Overview
- Opened on September 18, 2026
- Status Merged
- Commit count 1 with first commit September 18, 2026
Total Delta
Open Days
Test Delta
How long has this pull request spent in each phase of its lifecycle?
Data pending calculation for pull request
fix(blockImage): let a broken image reach its file object
Closes JS-9877
The problem
A broken image rendered a π Image is broken strip that offered no way to act on it:
- the hover Download icon was explicitly hidden for that state β
.brokenMedia { .icon.commonDownload { display: none; } } - clicking the strip opened the fullscreen preview, which is equally broken
-
Download and Open as object existed only in the block's right-click menu, invisible from the placeholder
The state was drawn with img::before / img::after, which only render because the image failed, so it could never hold real content.
On the file object's own page the placeholder never appeared at all. That page's own .wrap override (position: static; height: 100%; line-height: 0px) is more specific than .brokenMedia, so the area rendered as a large empty box with a spinner running forever.
The label was also hardcoded English inside a CSS content: property, so it never translated.
The change
- The broken state is a render branch in
BlockImageinstead of a class poked onto the DOM, so it can hold real content. - Clicking the placeholder opens the file object, where name, size and sync state are what actually explain the failure. Modifier-clicks behave normally (cmd β tab, cmd+shift β window) and it fires the same
OpenAsObjectevent the block menu does. - The hover Download icon is visible again.
- On the file object's own page it is label-only β nothing is left to open and the right sidebar already carries a Download button β and it fills the box the page reserves.
- An error can reach the block before anything is listening, leaving it stuck behind the loader. An image that is already
completewith nonaturalWidthis that failure, and is now caught on render. -
"Image is broken"is theblockImageBrokentranslation key.
Geometry is otherwise unchanged: the wrap keeps the same inline styles as the sibling branches, minus the 80px the loader placeholder contributes β nothing is loading in the error state.
Testing
Verified manually against a real broken image (editor block and file object page, light and dark), including the leave-and-reopen path that surfaced the missed-error case. typecheck, lint (0 errors) and build:dev all pass.
Not covered
popup/preview.tsx still uses the CSS pseudo-element approach and its hardcoded English string β which also shows "Image is broken" for broken videos. Converting it means reworking the imperative Image() preloader and galleryMapRef, so it is left for a separate change.
PR was closed without comments.