v0.11.0
The major redesign previously settled only in the specs is now implemented in code (#42–#53, plus follow-ups #54).
Added
- Three-rendition model — main / full / thumbnail. Each image is now stored as up to three WebP renditions: the main (the upload width/quality copy, served for download and for copying into the Media Library), a mid-size full image shown in the lightbox and slideshow, and a small thumbnail for the grid; each tier is skipped when the source is no wider, so a small image collapses to a single file. The full and thumbnail width/quality are admin-editable after the collection is established and changing one regenerates the affected renditions for every existing image (regenerate-then-flip: the gallery keeps serving the old renditions until the new batch completes, and an interrupted run is safe). The gallery's
srcsetis now{thumbnail, full}, with the full image as the display ceiling and the main download-only. (ADR-0013) - Gallery overlays replace the former caption and download settings: four overlays — breadcrumbs, download, add-to-media, and trash — each with its own visibility (off / on the thumbnail / in the lightbox / both), a nine-point position, and one shared appearance. Add-to-media copies an image's main rendition into the Media Library as an independent attachment (a copy, never a link); trash permanently deletes an image and its derived renditions behind an inline-popover confirmation. Both act through a new capability-gated REST write-path. (ADR-0015, #51, #52, #53)
- Every capability is filterable. Upload, add-to-media, delete, the editor-only broken-reference notice, listing, and management each read from a
kntnt_photo_drop_*_capabilityfilter with a sensible WordPress-standard default. (ADR-0015) - Drop Zone upload-progress UI: an aggregate progress bar with a "N of T processed" summary and a Cancel control sharing the row directly beneath it, a three-bucket (uploaded / skipped / failed) summary, and a Retry that re-sends the real bytes of failed files. (#44, #68)
- Effective-width help on the Create/Edit forms: the Full width and Thumbnail width fields now carry inline help naming their effective value — the smaller of the entered value and the tier above (full caps to the upload width, thumbnail to the effective full width) — so a width entered above the cap is shown to have no effect, since a tier is skipped when the source is no wider. Presentational only; no change to stored values or rendition behaviour. (#65, ADR-0013)
Changed
- The immutable output contract narrows to upload width + upload quality — the only irreversible pair, because the source is discarded once the main image is encoded. The full and thumbnail settings are no longer frozen at establishment; they are re-derivable and admin-editable (see Added). The admin Create/Edit forms gain the full/thumbnail fields, permanence markers on the immutable upload fields, and an auto-defaulted slug. (ADR-0013, #50)
- Drop Zone placement is now a mutable path-components template (
%year%/%month%/%day%/%uploader%by default), editable per collection and affecting only future uploads, replacing the immutable "uploader folders" boolean. It is expanded server-side —%uploader%from the authenticated user's nicename, so it cannot be spoofed — and flat-at-root placement is retired. (ADR-0014) - Gallery ordering is a pre-order tree traversal — a folder's own images before its subfolders, natural-sorted within each level; descending reverses the sort within each level while keeping the own-images-before-subfolders structure. (ADR-0015, #43)
- The gallery's caption is replaced by the breadcrumbs overlay: the humanised folder path with the collection display name as the first crumb. (ADR-0015)
- Create-collection immutability warning reworked. The plain-language
notice notice-warningopens the create form above every field so its scope is unambiguous, and its body now names the upload width/quality as the irreversible cause without claiming they are the whole ⚠ set (the slug also carries a ⚠ marker). The ⚠ markers render in WordPress's amber/warning hue (#dba617) wherever they appear — both the create form and the edit form's read-only upload contract, which now carries the marker too. (#62, ADR-0013) - Contributor and agent-workflow standards (process docs). The TDD rule now requires the red step to be demonstrated (a test seen failing before the code that satisfies it) and to automate at the lowest layer that meaningfully constrains behaviour; a documented autonomous multi-agent operating model was added to
AGENTS.md(agents never block on the maintainer, resolve ambiguity by recorded assumption, and report upward in three buckets — automatically tested / remaining for a human / assumptions & blockers). ADRs 0002/0003/0005/0008 carry amendment banners pointing to the redesign decisions, and ADR-0002 records the rejection of a "store originals as-is" / lossless-WebP mode (high-quality lossy WebP is the fidelity ceiling). - The collection Create/Edit forms present the three image tiers as one uniform section. The former "Upload contract (immutable)" and "Renditions (re-derivable)" headings are gone; upload, full, and thumbnail now sit together under a single Image settings heading. The upload pair is still immutable — marked on Create, read-only on Edit, and rejected server-side — while the full and thumbnail settings remain editable. (#67)
- The Full and Thumbnail width fields clamp live to the tier above while you type on the Create/Edit forms: Full cannot exceed the upload width (when an upload limit is set) and Thumbnail cannot exceed Full, and lowering a tier pulls the ones below it down to match. Server-side validation remains the source of truth. (#69)
- The integration and end-to-end test harness is now worktree-portable —
@wordpress/envmounts the plugin under the checkout's own directory name and the e2e fixtures derive that slug, with aWP_ENV_PORToverride, so the suites run from a git worktree (and several in parallel) without hand-editing paths. (contributor tooling) - Add-to-media inserts at full resolution. Copying a collection image into the Media Library no longer produces a downscaled
…-scaledmaster for mains wider than WordPress's 2560px big-image threshold; the contract-bounded main is inserted as-is (sub-sizes still generate). (ADR-0015) - Add-to-media is a single click and no longer duplicates. Copying a collection image into the Media Library now takes one click instead of a two-click confirm; an image already copied is detected (by a stamped source identity) and, instead of silently adding a second copy, the gallery offers an inline Overwrite confirm that replaces the existing attachment's file in place (same attachment id). (ADR-0015 amendment)
- Rendition widths have a 320px floor. The Create/Edit forms and the
collection create/collection updateCLI reject an upload, full, or thumbnail width below 320px; blank fields (which fall back to the source dimensions, or collapse to the tier above) are unaffected.
Removed
- The immutable "uploader folders" boolean (replaced by the mutable path-components template) and the standalone caption concept (replaced by the breadcrumbs overlay). Pre-1.0, no migration. (ADR-0014, ADR-0015)
Fixed
- The Drop Zone upload-progress UI now respects the block's default padding. The progress bar, summary, and Cancel control inset by the default padding — as they already did for an explicit inspector padding — instead of rendering flush to the block edges. (#56)
- Equal-width collections upload at full speed again. When a collection's full width/quality equal its upload width/quality (so no separate full image is produced), ingestion no longer performs a redundant full-resolution decode per image, and such a collection uploads in time comparable to the two-tier baseline. (#57)
- Gallery breadcrumbs overflow correctly. A path wider than its box now shows a leading "…" and keeps the tail — the deepest folder — visible inside the right padding, instead of clipping the tail with no ellipsis and running to the image edge; the behaviour is RTL-aware and correct at all nine overlay positions. (#58)
- Gallery breadcrumb default colours survive theme
figcaptionstyling. The breadcrumbs keep their white-on-dark default under a theme that coloursfigcaption, while a Colour-panel foreground/background selection still overrides them. (#60) - The trash confirmation popover text is left-aligned (start-aligned in RTL) regardless of a centred gallery or theme context. (#61)
- The Edit collection form lists Display name above Slug, matching the Create form; the Slug stays read-only. (#63)
- Saving a collection with the default path-components template no longer fails. The default
%year%/%month%/%day%/%uploader%was false-rejected as "Invalid path components" becausesanitize_text_fieldmangled%day%; the%-placeholders now survive submission intact, while genuinely invalid templates (stray%,.., absolute paths, backslashes, NUL) are still rejected. (#64) - Downloading a gallery image no longer opens a stray browser tab or navigates the page away. The download icon now saves a same-origin image — the default — through a direct same-document
<a download>instead of fetching it into a blob: Firefox opens ablob:URL it can render inline (such as WebP) in a new tab even with thedownloadattribute set, so the previous blob-based save downloaded the file and opened a tab. Only a cross-origin (offloaded-media) host still uses the blob path. The fetch-failure fallback was also corrected to a same-tab<a download>rather than a current-tab navigation, so a failed download never sends the gallery's own tab away. (#59, ADR-0015)
Security
- The transitive development dependency
form-datais bumped to 4.0.6 (Dependabot, #55). Build-chain only; nothing shipped to the browser changes. - Three further transitive development-dependency advisories are resolved through npm
overrides:js-yaml→ 4.2.0 andmarkdown-it→ 14.2.0 (both quadratic-complexity DoS), and@babel/core→ 7.29.7 (arbitrary file read via asourceMappingURLcomment). All are build-chain/test tooling only — pulled transitively by@wordpress/envand@wordpress/scripts— so nothing shipped to the browser changes.
Full changelog: https://github.com/Kntnt/kntnt-photo-drop/blob/v0.11.0/CHANGELOG.md