Issue #3620123: Add the image and media image shapes

Two shapes, one assembly. A site keeps a picture either in an image field or in a reference to a media item that holds one, the choice was made years ago by whoever built the bundle, and it differs between the sites this module runs on. Both shapes therefore build the fragment with the same code, on the same settings: the media shape resolves the media item, asks the media source plugin where its source field is, and hands that to the assembly. A front end cannot tell which of the two it got, and the test that matters asserts exactly that, on one file reached both ways.

What the fragment carries is the union of what the forks of this module answer with today, measured from their code rather than designed: urls, alt, title, image_id and svg, with the URLs of the original and of every derivative whose style exists on the site. An intersection would take a key away from a site whose front end reads it; a key a front end ignores costs it nothing. The derivatives are named by suffix from the one style a structure names, a style that is not on the site produces no key rather than the original file under a name that says it was resized, and an SVG produces no derivatives at all.

The empty-value contract gains its one seam, and the first real shape is what found it: an image field may name a default image, and Drupal renders it, so "empty means no key" is not true for every field type. buildEmpty() is where a shape says so. build() is still final, the seam is inside it, the return type and the meaning of an absent result do not move.

The existing image builder is untouched, so the endpoints it serves answer exactly as before; what the shapes reuse from it is the part that is not assembly - whether a style exists, the URL of a file, the source of an SVG. The SVG sanitizer is a suggested library rather than a required one, so its absence answers with an empty svg value instead of a fatal error.

Closes #3620123

Merge request reports

Loading
Loading