Tiled Gallery: fix infinite resize loop inside Row/Stack blocks#50016
Tiled Gallery: fix infinite resize loop inside Row/Stack blocks#50016dhasilva wants to merge 5 commits into
Conversation
The mosaic layout reserved two gutters per column gap (GUTTER_WIDTH * 2) while the DOM renders only one. Inside a content-sized flex container (Row/Stack) the block's width is driven by its own content, so each ResizeObserver pass laid the content out one gutter narrower than it measured — spiraling the gallery toward zero width and snapping back, forever. Reserve a single gutter per gap, matching the rendered DOM and every deprecated layout copy. Add a unit test asserting the laid-out columns plus their rendered gutters fill the measured width. Fixes JETPACK-1726. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Defense in depth on top of the gutter accounting fix: track the width of the last layout pass and ignore sub-pixel changes, which are the signature of a ResizeObserver feedback loop rather than a real resize. triggerResize() clears the tracked width so genuine content/layout changes always recompute. Refs JETPACK-1726. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Are you an Automattician? Please test your changes on all WordPress.com environments to help mitigate accidental explosions.
Interested in more tips and information?
|
|
Thank you for your PR! When contributing to Jetpack, we have a few suggestions that can help us test and review your patch:
This comment will be updated as you work on your PR and make changes. If you think that some of those checks are not needed for your PR, please explain why you think so. Thanks for cooperation 🤖 Follow this PR Review Process:
If you have questions about anything, reach out in #jetpack-developers for guidance! Jetpack plugin: The Jetpack plugin has different release cadences depending on the platform:
If you have any questions about the release process, please ask in the #jetpack-releases channel on Slack. |
|
@coder-karen Asking for your review as this was introduced in #43345 and you might see something that was missed here 🙇♂️ |
Code Coverage SummaryCoverage changed in 2 files.
|
Firefox follow-up: gallery settles to a non-deterministic size inside Row/StackTesting this branch on a Jurassic Ninja site, a Tiled Gallery placed inside a Row/Stack with Root cause
Every width is a fixed point — the layout just preserves whatever width it measured first. So the final size is decided by whatever width the The Reproduction (headless Playwright, same post)Both engines are internally stable but converge to different sizes for identical content, and Chrome's values overflow the ~620px container:
Suggested fixDrive the layout from a width that doesn't depend on the gallery's own content: anchor to the nearest flex container's available width (sized by the surrounding layout) when the gallery is a flex item, and fall back to the gallery's own width otherwise. The Prototype diff (against this branch): replaces Known limitation of the prototypeAnchoring to Happy to push the prototype branch / open a follow-up PR if useful. |
Update: multi-gallery-per-row case resolvedThe earlier prototype's known limitation (multiple galleries in one Row each claiming the full container width and overflowing) is fixed by only anchoring to the container when the gallery is the sole flex item: // Only anchor to the container when the gallery is the SOLE flex item. A lone
// content-sized item has no well-defined width (it is circularly defined by our
// own layout). With several flex items the browser already distributes width
// across them, so the gallery's own measured width is the correct per-item share.
if ( container && 1 === container.children.length ) {
return container.clientWidth;
}
return this.gallery.current ? this.gallery.current.clientWidth : 0;The single-item case had Verified on both Chrome and Firefox against a post with single- and double-gallery Rows:
Single galleries fill the container deterministically; two-in-a-row each take ~half and sum to the container width with no overflow. Existing tiled-gallery tests pass (17/17) including added coverage for the lone-item, multi-item, and no-flex-container paths. |
…split rows between multiple galleries
|
Pushed What it does (
The Verified on a post with single- and double-gallery Rows + a Stack, 8/8 reloads in Chrome: every gallery (Headless Firefox couldn't be used to confirm reload-stability because the block intermittently renders as an unsupported-block placeholder in automation — a registration race unrelated to this change — but the new width is content-independent, so the result is browser-agnostic.) |
|
Thanks for the fix, @enejb! |
enejb
left a comment
There was a problem hiding this comment.
This works as expected for me now.
Fixes #49564
Fixes JETPACK-1726
Proposed changes
GUTTER_WIDTH * 2) while the DOM renders only one. Inside a content-sized flex container (Row/Stack) the block's width is driven by its own content, so eachResizeObserverpass laid the content out one gutter narrower than it measured — spiralling the gallery toward zero width and snapping back, forever. It now reserves a single gutter per gap, matching the rendered DOM (and every deprecated layout copy).ResizeObserver: it tracks the width of the last layout pass and ignores sub-pixel changes (the signature of a feedback loop rather than a real resize).triggerResize()clears the tracked width so genuine content/layout changes still recompute.This is editor/front-end runtime layout only;
save()output is unchanged for any given attributes, so no block deprecation is required and existing galleries continue to validate.Related product discussion/links
Does this pull request change what data or activity we track or use?
No.
Testing instructions
Before:
Screenshare.-.2026-06-26.6_22_33.PM.mp4
After:
Screenshare.-.2026-06-26.6_58_25.PM.mp4