Skip to content

Plugin Directory: server-render screenshots gallery + Gallery Lightbox Enhancements polyfill#622

Open
dan-zakirov wants to merge 7 commits into
WordPress:trunkfrom
dan-zakirov:add/gallery-lightbox-enhancements-and-screenshots-migration
Open

Plugin Directory: server-render screenshots gallery + Gallery Lightbox Enhancements polyfill#622
dan-zakirov wants to merge 7 commits into
WordPress:trunkfrom
dan-zakirov:add/gallery-lightbox-enhancements-and-screenshots-migration

Conversation

@dan-zakirov
Copy link
Copy Markdown

@dan-zakirov dan-zakirov commented May 7, 2026

Replaces the bespoke wporg-plugins-2024 theme JS screenshots gallery with a server-rendered [wporg-plugins-screenshots] shortcode in the Plugin Directory plugin, and adds a small polyfill plugin (Gallery Lightbox Enhancements) that restores two long-standing Gutenberg gaps locally so the wp.org migration can ship without waiting on core.

Visual evidence

Layout cases — counts 1 to 9

Case Screenshot
N=1 — single tile, max-width 720 px one-no-caption
N=2 — 2-col row-aligned grid two-with-captions
N=4 — 3-up grid + last figure as full-width anchor four-was-two-col-bug
N=5 — 3+2 row-aligned grid five-screenshots
N=6 — 3×2 grid six-no-captions
N=6 — 3×2 grid six-with-captions
N=7, mixed aspect — brick masonry, natural ratios preserved seven-mixed-aspect
N=8 — brick masonry eight-screenshots
N=9 (reveal threshold edge) — full grid, no Show-all button nine-edge-no-button

Reveal flow (N≥10)

State Screenshot
Show-all button + fade overlay — collapsed wrap clipped at 32rem button-hover
After Show-all click — wrap unfolds to full content, fade and button removed after-reveal

Mobile (≤599 px)

Case Screenshot
Collapse suppressed — every figure rendered, no fade or Show-all button on small viewports mobile-collapse-suppressed
N=33 mobile — full gallery, vertical scroll only mobile-thirty-three

What changes

  • wp-content/plugins/plugin-directory/shortcodes/class-screenshots.php — new shortcode that renders every screenshot through core/gallery + core/image blocks, lightbox enabled per tile. Galleries up to 9 figures show the full grid; larger ones get a Show all N screenshots reveal button. Layout is deterministic: N=1 single tile, N=2-4 row-aligned grid, N≥5 brick masonry by default with a row-aligned grid upgrade when every screenshot shares an aspect ratio.
  • wp-content/plugins/gallery-lightbox-enhancements/ — polyfill plugin that adds a is-style-masonry block style for core/gallery and renders figcaption text inside the lightbox overlay. Both behaviours are gated behind Version_Guard::should_load(), which lets the plugin self-disable once core ships the features.
  • wp-content/themes/pub/wporg-plugins-2024/ — removes the legacy theme implementation: client/screenshots/, the dedicated theme.js entry, the matching SCSS partials, and the build:old:js npm script.

Why

Server-side rendering makes the gallery cacheable by Varnish, works without JS, and gives third-party scrapers and SEO crawlers the full markup. Every <img> ships with loading="eager", intrinsic width / height attributes, and fetchpriority="high" on the cap-window thumbnails, so CLS stays at 0 while screenshots decode. Aspect ratios and pixel dimensions come from a single Memcached-cached probe (md5-keyed by URL list, so a screenshot revision auto-invalidates).

Closes / refs

Meta Trac (the long-standing screenshot UX gaps this PR addresses):

  • Closes meta#2273 — Screenshot UI redesign (open ~9 years, primary tracking ticket)
  • Closes meta#8083 — Add lightbox for plugin screenshots
  • Closes meta#8204 — Chrome 146 table-cell layout bug (the new shortcode renders through CSS Grid / columns, the legacy table-cell path is dropped)
  • Refs meta#5190 — Lazy loading screenshots (we go the opposite way: eager + fetchpriority, see "Why" above)
  • Refs meta#7878 — Screenshot navigation (handled by the core lightbox arrows)

Upstream Gutenberg gaps that the polyfill plugin addresses on the user side:

  • gutenberg#28247 — Gallery masonry layout (open since January 2021)
  • gutenberg#60469 — Lightbox captions excluded from overlay (regression since WP 6.5)

Prior art on this task

Earlier attempts at the same migration that fed into this PR's design:

Safety / scope

The change is additive on the Plugin Directory side and isolated for the polyfill, with one purposeful subtraction in the theme. Map of every touched path:

Path Risk
wp-content/plugins/gallery-lightbox-enhancements/ (new plugin, 9 files) None on its own. Self-disables via Version_Guard::should_load() once core ships the features. Activation lives outside this PR (mu-plugin loader on production).
wp-content/plugins/plugin-directory/shortcodes/class-screenshots.php Rewritten body, same registration hook. Shortcode tag, file name and class FQN are unchanged, so anything that already calls do_shortcode( '[wporg-plugins-screenshots]' ) keeps working.
wp-content/plugins/plugin-directory/shortcodes/assets/screenshots.css, screenshots.js New files. Enqueued only inside the shortcode's render path, so other pages on wp.org/plugins do not load them.
wp-content/plugins/plugin-directory/class-plugin-directory.php (+1) One add_filter( 'wp_resource_hints', [ Screenshots::class, 'add_resource_hints' ] ) that contributes preconnect / dns-prefetch URLs for the Photon host on single-plugin pages. Hint only, no blocking behaviour.
wp-content/themes/pub/wporg-plugins-2024/client/screenshots/ (deleted) Main subtraction. A repo-wide grep finds no external imports of these modules; happy to add a shim if a downstream consumer is missed.
wp-content/themes/pub/wporg-plugins-2024/css/style.css, style-rtl.css Regenerated build artefacts after dropping the screenshot SCSS partials and the build:old:js script. No theme JS or CSS for screenshots remains — the shortcode owns the whole flow.

The migration does not touch DB schema, post types, taxonomies, REST endpoints, or any sibling shortcode in plugin-directory/shortcodes/.

Notes for reviewers

  • All PHP passes the project phpcs.xml.dist ruleset (WordPress-Core / Docs / Extra, PHP 8.4 compat).
  • No theme JS or CSS left for screenshots — the shortcode owns the whole flow.
  • Polyfill is fully self-contained: drop in, drop out once core ships the features.
  • cc @dd32 — would value your eyes on the Version_Guard placeholder strategy and on the deletion of the old client/screenshots/ modules.
  • cc @ryelle — this picks up the direction from Plugin Directory: Try using core Gallery & Image blocks for screenshots #524; happy to align further on the layout decisions if you have feedback.

Copilot AI review requested due to automatic review settings May 7, 2026 13:22
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 7, 2026

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props alexodiy, dd32.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@dan-zakirov
Copy link
Copy Markdown
Author

A bit of context on how we got here: we first proposed an upstream Gutenberg fix for lightbox captions and, separately, a masonry block style for core/gallery. The masonry proposal was declined upstream and the captions one has not had movement; rather than block the wp.org migration on either, we ship the same behaviour as a self-disabling polyfill plugin so the gallery on wordpress.org/plugins/{slug}/ can move forward today. If either fix lands in core later, flip Version_Guard::CORE_VERSION_WITH_FEATURES to that release tag and the plugin steps aside.

On captions specifically: every figure ships its caption text, but it surfaces only inside the lightbox overlay and never on the gallery itself. Plugin authors routinely write multi-sentence captions, and rendering those under each thumbnail would tear the brick layout apart with uneven figure heights. The lightbox is the right surface for that copy - it has room for it without compromising the grid.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Replaces the wporg-plugins-2024 theme’s bespoke React screenshot gallery with a server-rendered [wporg-plugins-screenshots] shortcode in the Plugin Directory plugin, and introduces a small “Gallery Lightbox Enhancements” polyfill plugin to fill Gutenberg lightbox caption + gallery masonry gaps during the wp.org migration.

Changes:

  • Added a new server-rendered screenshots shortcode that outputs core/gallery + core/image blocks, includes reveal behavior for large galleries, and adds Photon preconnect + responsive srcset handling.
  • Added a new polyfill plugin that registers an is-style-masonry Gallery style and restores lightbox caption rendering.
  • Removed the legacy theme JS + SCSS screenshot/gallery implementation and updated built CSS artifacts accordingly.

Reviewed changes

Copilot reviewed 25 out of 25 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/package.json Removes legacy JS build script for the old screenshot UI.
wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/js/build/theme.js Deletes built legacy React screenshot bundle.
wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/js/build/theme.asset.php Deletes asset metadata for the removed legacy bundle.
wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/functions.php Stops enqueuing the legacy React bundle on single plugin pages.
wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/css/style.css Regenerated theme CSS after removing screenshot/gallery SCSS.
wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/css/style-rtl.css Regenerated RTL theme CSS after removing screenshot/gallery SCSS.
wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/client/theme.js Removes legacy screenshot initialization entrypoint.
wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/client/styles/components/_components.scss Stops importing the old screenshot/gallery component styles.
wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/client/screenshots/index.js Removes old Screenshots component.
wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/client/screenshots/image-gallery.js Removes old ImageGallery implementation.
wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/client/components/plugin/_sections-screenshots.scss Removes legacy screenshots section styles.
wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/client/components/plugin/_sections-image-gallery.scss Removes legacy image gallery styles.
wordpress.org/public_html/wp-content/plugins/plugin-directory/shortcodes/class-screenshots.php New SSR shortcode: block markup generation, reveal wrapper, Photon hints, and dimension probing.
wordpress.org/public_html/wp-content/plugins/plugin-directory/shortcodes/assets/screenshots.js Adds client-side reveal behavior + broken-image handling for large galleries.
wordpress.org/public_html/wp-content/plugins/plugin-directory/shortcodes/assets/screenshots.css Adds shortcode-scoped masonry/grid styling and reveal UI styles.
wordpress.org/public_html/wp-content/plugins/plugin-directory/class-plugin-directory.php Emits Photon preconnect hints on plugin singular pages.
wordpress.org/public_html/wp-content/plugins/gallery-lightbox-enhancements/readme.txt New plugin readme describing the Gutenberg polyfills.
wordpress.org/public_html/wp-content/plugins/gallery-lightbox-enhancements/LICENSE Adds GPL license file for the new plugin.
wordpress.org/public_html/wp-content/plugins/gallery-lightbox-enhancements/includes/class-version-guard.php Adds a guard to self-disable the polyfill when core ships the features.
wordpress.org/public_html/wp-content/plugins/gallery-lightbox-enhancements/includes/class-masonry-style.php Registers/enqueues a masonry style variation for core/gallery.
wordpress.org/public_html/wp-content/plugins/gallery-lightbox-enhancements/includes/class-lightbox-captions.php Adds caption text to interactivity state and enqueues runtime assets.
wordpress.org/public_html/wp-content/plugins/gallery-lightbox-enhancements/gallery-lightbox-enhancements.php Plugin bootstrap: loads guarded features.
wordpress.org/public_html/wp-content/plugins/gallery-lightbox-enhancements/assets/masonry.css CSS for the is-style-masonry Gallery variation.
wordpress.org/public_html/wp-content/plugins/gallery-lightbox-enhancements/assets/lightbox-captions.js Runtime augmentation to render captions inside the lightbox overlay.
wordpress.org/public_html/wp-content/plugins/gallery-lightbox-enhancements/assets/lightbox-captions.css Caption + scrim styling for the lightbox overlay.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +716 to +746
while ( $offset + 8 < $length ) {
if ( "\xFF" !== $bytes[ $offset ] ) {
return false;
}
$marker = ord( $bytes[ $offset + 1 ] );
++$offset;
// Skip 0xFF padding bytes between segments.
while ( 0xFF === $marker && $offset < $length ) {
$marker = ord( $bytes[ $offset ] );
++$offset;
}
$is_sof = (
( $marker >= 0xC0 && $marker <= 0xC3 ) ||
( $marker >= 0xC5 && $marker <= 0xC7 ) ||
( $marker >= 0xC9 && $marker <= 0xCB ) ||
( $marker >= 0xCD && $marker <= 0xCF )
);
if ( $is_sof && $offset + 7 < $length ) {
$dim = unpack( 'nheight/nwidth', substr( $bytes, $offset + 3, 4 ) );
if ( $dim && $dim['width'] > 0 && $dim['height'] > 0 ) {
return array( $dim['width'], $dim['height'] );
}
return false;
}
if ( $offset + 1 >= $length ) {
return false;
}
$segment_length = unpack( 'nlen', substr( $bytes, $offset, 2 ) );
if ( ! $segment_length || $segment_length['len'] < 2 ) {
return false;
}
Comment on lines +8 to +13
* - On init, measure the natural bottom of the ninth figure across
* the columns and write it into `--collapse-height` so the wrap
* clips at exactly the right line.
* - On click, measure the wrap's full `scrollHeight` and write it
* into `--full-height`, then flip the `is-revealed` class so the
* CSS transition animates from collapse-height to full-height.
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Done in 814a32d - removed the unused COMPACT_VISIBLE constant, documented the $dimensions param on build_gallery_markup(), and refreshed the CSS/JS/class-header comments that still described the dropped dynamic --collapse-height measurement.

Comment on lines +248 to +251
* `--collapse-height` is set inline by the JS on init (it measures the
* natural bottom edge of the ninth figure across all three columns).
* If JS hasn't run yet, the fallback value of 36rem covers the typical
* "three rows of 16:10 landscape thumbs" footprint.
Comment on lines +233 to +246
/**
* Builds the block markup string for the Gallery + Image blocks.
*
* Every screenshot renders into the markup — collapse / expand is
* a CSS `max-height` clip on the gallery wrap, not a DOM hide. This
* keeps the masonry balanced across columns once and prevents the
* "figures reshuffle" effect the user saw on click previously.
*
* @param array $screenshots Screenshots returned by Template::get_screenshots().
* @param int $count Total screenshot count, used to size columns.
* @return string Block markup ready for do_blocks().
*/
protected static function build_gallery_markup( $screenshots, $count, $dimensions = array() ) {
$inner = '';
@dan-zakirov dan-zakirov changed the title FEAT: replaced theme screenshots with shortcode Plugin Directory: server-render screenshots gallery + Gallery Lightbox Enhancements polyfill May 7, 2026
@dan-zakirov dan-zakirov force-pushed the add/gallery-lightbox-enhancements-and-screenshots-migration branch from 2dcc0b6 to ebb5f7a Compare May 7, 2026 14:14
Replaced the wporg-plugins-2024 theme JS gallery with a server-rendered [wporg-plugins-screenshots] shortcode in the Plugin Directory plugin, and added the Gallery Lightbox Enhancements polyfill that ports two pending Gutenberg pull requests (lightbox captions #77477 and the masonry block style #77615). The screenshot UX is now server-side, cacheable by Varnish, works with JS disabled, and renders through core/gallery + core/image blocks instead of bespoke theme JS.

The shortcode renders every figure upfront with eager loading, intrinsic width and height attributes, and fetchpriority="high" on the cap-window thumbnails so there is zero layout shift while screenshots decode. Galleries up to nine figures show the full grid; larger ones render a "Show all N screenshots" reveal button that animates max-height on the wrap to full size with a setTimeout fallback so the cap always releases. Layout is deterministic: N=1 single tile, N=2-4 row-aligned grid, N>=5 brick masonry by default with a row-aligned grid upgrade when every screenshot shares an aspect ratio. Aspect ratios and pixel dimensions come from a single Memcached-cached probe over the screenshot URLs (md5-keyed so a revision bump auto-invalidates). Lightbox captions and a generic Masonry block style ship through the polyfill plugin so they self-disable once core lands the upstream PRs.

Removed the legacy theme implementation: client/screenshots/, the dedicated theme.js entry, the build:old:js npm script, and the matching SCSS partials. The theme no longer carries any screenshot-specific JavaScript or stylesheets - the shortcode owns the entire flow.

Affected: wordpress.org/public_html/wp-content/plugins/gallery-lightbox-enhancements/, wordpress.org/public_html/wp-content/plugins/plugin-directory/shortcodes/, wordpress.org/public_html/wp-content/plugins/plugin-directory/class-plugin-directory.php, wordpress.org/public_html/wp-content/themes/pub/wporg-plugins-2024/
@dan-zakirov dan-zakirov force-pushed the add/gallery-lightbox-enhancements-and-screenshots-migration branch from ebb5f7a to 9d889d8 Compare May 7, 2026 14:16
Copy link
Copy Markdown
Member

@dd32 dd32 left a comment

Choose a reason for hiding this comment

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

@dan-zakirov Thanks for the PR! I've added some commentary below, I've only code reviewed, not actually tried running it, but it looks like a strong start!

I'm going to fire up a PR to extract the resolution of assets at import time, and backfill them, to make the code cleaner and allow such improvements to also be used for the WordPress.org plugins API.

I haven't checked, but I think I recall the output of this is used in the WordPress.org plugins api somewhere, somehow..

Comment on lines +674 to +683
/**
* Reads the width and height from an image's header bytes, without
* touching GD or the PHP warning surface that `getimagesizefromstring`
* emits on partial / malformed input. Supports PNG, JPEG, and GIF —
* the formats Plugin Directory accepts as screenshots.
*
* @param string $bytes Raw image bytes (the first 32 KB is enough).
* @return array|false `[ $width, $height ]` on success, false otherwise.
*/
private static function parse_image_dimensions( $bytes ) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think I'd still prefer to use getimagesize() here, but instead of having it within the Screenshots handler, fetch the resolutions during the plugin import process.

If the file has malformed image headers, we can also skip importing those images... Although I'm betting this would exclude soem animated images (..what a shame...)

We can backfill the existing image metadata, such that we can have this as assuming all data is stored.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Initial swipe at it #628 (untested..)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Waiting on #628 to land - once it does I'll drop the parser here and read width/height straight from the assets_screenshots post meta.

Switched the screenshot count placeholder from %d to %s and ran $count
through number_format_i18n() so locales with non-Latin digit grouping
render the value correctly. Keeps the same _n() pluralisation and the
same translator comment, with %s in both.

Addresses dd32's review comment on lines 423-425 (PR WordPress#622).
Copilot AI review requested due to automatic review settings May 11, 2026 14:00
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 25 out of 25 changed files in this pull request and generated 9 comments.

* @return string Image block markup.
*/
protected static function build_image_block( $screenshot, $id, $above_fold = false, $dimensions = null ) {
$src = isset( $screenshot['src'] ) ? esc_url( $screenshot['src'] ) : '';
)
);

$srcset = self::photon_srcset( $src );
// and `height` attributes — the browser reserves slot height
// from the intrinsic aspect ratio, so the gallery has zero
// layout shift no matter how slowly the screenshots decode.
$dimensions = self::get_dimensions( $screenshots );
Comment on lines +306 to +308
if ( self::is_uniform_aspect( $screenshots ) ) {
$layout_class .= ' has-uniform-aspect';
}
return true;
}

$dimensions = self::get_dimensions( $screenshots );
Comment thread wordpress.org/public_html/wp-content/plugins/plugin-directory/css/screenshots.css Outdated
Replaced the hand-rolled emit_preconnect() that printed <link> tags
straight into wp_head with a wp_resource_hints filter callback. The
filter is the native WordPress integration point for preconnect and
dns-prefetch hints, lets other code dedupe and reorder, and reads more
naturally next to the rest of the plugin-directory hooks.

Hint now runs on every singular plugin page (production or local) —
the previous production-only guard with function_exists fallback was
dropped: the hint is harmless in any environment and we target modern
WP without backcompat shims.

Addresses dd32's review comment on lines 192-193 (PR WordPress#622).
Moved screenshots.css and screenshots.js from
shortcodes/assets/ to the plugin's existing css/ and js/
directories, alongside edit-form.css and edit-form.js. The shortcode
no longer creates a one-off asset folder under itself — versioning
through filemtime() is now inlined directly in plugins_url() / filemtime()
calls without the file_exists() fallback and the helper variables.

Addresses dd32's review comments on lines 208-230 (PR WordPress#622).
Copilot AI review requested due to automatic review settings May 11, 2026 14:21
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 25 out of 25 changed files in this pull request and generated 6 comments.

Comment on lines +726 to +756
while ( $offset + 8 < $length ) {
if ( "\xFF" !== $bytes[ $offset ] ) {
return false;
}
$marker = ord( $bytes[ $offset + 1 ] );
++$offset;
// Skip 0xFF padding bytes between segments.
while ( 0xFF === $marker && $offset < $length ) {
$marker = ord( $bytes[ $offset ] );
++$offset;
}
$is_sof = (
( $marker >= 0xC0 && $marker <= 0xC3 ) ||
( $marker >= 0xC5 && $marker <= 0xC7 ) ||
( $marker >= 0xC9 && $marker <= 0xCB ) ||
( $marker >= 0xCD && $marker <= 0xCF )
);
if ( $is_sof && $offset + 7 < $length ) {
$dim = unpack( 'nheight/nwidth', substr( $bytes, $offset + 3, 4 ) );
if ( $dim && $dim['width'] > 0 && $dim['height'] > 0 ) {
return array( $dim['width'], $dim['height'] );
}
return false;
}
if ( $offset + 1 >= $length ) {
return false;
}
$segment_length = unpack( 'nlen', substr( $bytes, $offset, 2 ) );
if ( ! $segment_length || $segment_length['len'] < 2 ) {
return false;
}
Comment on lines +49 to +58
/**
* Visible figure count when collapse is active.
*
* Eight figures across three columns settles into a 3+3+2 brick — the
* partial bottom row reads as "more below" under the fade overlay.
*
* @var int
*/
const COMPACT_VISIBLE = 8;

Comment on lines +243 to +251
* Reveal wrap. Clips the gallery via `max-height` while collapsed; the
* fade overlay and the Show-all button are absolutely positioned over
* the clipped area so their position adapts to the column heights —
* no dead band beneath the shortest column.
*
* `--collapse-height` is set inline by the JS on init (it measures the
* natural bottom edge of the ninth figure across all three columns).
* If JS hasn't run yet, the fallback value of 36rem covers the typical
* "three rows of 16:10 landscape thumbs" footprint.
str_contains() requires PHP 8.0+, but the plugin header declares
Requires PHP: 7.4. Switched the lightbox-container detection check to
strpos() so the plugin loads cleanly on the minimum supported PHP
version instead of fatal-erroring on first hook fire.
Previously the guard only watched GUTENBERG_VERSION, so on vanilla
WordPress installs that never load the Gutenberg plugin the polyfill
ran forever even after the upstream features landed in core. Added
WP_VERSION_WITH_FEATURES alongside the Gutenberg constant: should_load()
now steps aside when either core or the Gutenberg plugin ships the
features, and falls back to "load" only while both constants are still
sentinels.

This covers the two real-world paths: wordpress.org runs trunk + the
latest Gutenberg release (so the Gutenberg check fires first), and
plain sites pick up the features through core (so the WP check fires).
Copilot AI review requested due to automatic review settings May 11, 2026 17:33
Three documentation-only cleanups in the screenshots shortcode:

- Removed the COMPACT_VISIBLE constant. It was a leftover from an
  earlier "render only N tiles in the collapsed state" design; the
  current implementation renders every figure into the DOM and clips
  the wrap with CSS max-height, so the constant has no callers.
- Updated the class header docblock to match: it now describes the
  fixed max-height collapse cap instead of the removed per-tile cap.
- Updated the screenshots.css and js/screenshots.js header comments
  the same way: they used to describe a JS measurement that wrote
  --collapse-height inline. The measurement was already gone, only
  the comments lagged behind.
- Documented the new $dimensions parameter on build_gallery_markup().
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 25 out of 25 changed files in this pull request and generated 6 comments.

Comment on lines +213 to +220

wp_enqueue_script(
'wporg-plugins-screenshots',
plugins_url( 'js/screenshots.js', __DIR__ . '/../plugin-directory.php' ),
array(),
(string) filemtime( __DIR__ . '/../js/screenshots.js' ),
true
);
Comment on lines +726 to +735
);
if ( $is_sof && $offset + 7 < $length ) {
$dim = unpack( 'nheight/nwidth', substr( $bytes, $offset + 3, 4 ) );
if ( $dim && $dim['width'] > 0 && $dim['height'] > 0 ) {
return array( $dim['width'], $dim['height'] );
}
return false;
}
if ( $offset + 1 >= $length ) {
return false;
Comment on lines +248 to +252
* The collapse height is a fixed `max-height: 32rem` cap on the wrap
* (about three rows of typical landscape thumbs). We don't measure
* dynamically: lazy figures past the fold report `naturalWidth: 0`
* until they decode, which would make the measured height equal to
* the unclipped natural height and defeat the collapse entirely.
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.

3 participants