Skip to content

Commit

Permalink
Merge pull request #482 from cawa-93/responsive-images
Browse files Browse the repository at this point in the history
feat(picture): support `sizes` attribute
  • Loading branch information
oscarotero authored Sep 5, 2023
2 parents 4236511 + c3433ab commit 8cc1dfe
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 4 deletions.
30 changes: 26 additions & 4 deletions plugins/picture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,23 +90,35 @@ export default function (): Plugin {
basePath: string,
) {
const src = img.getAttribute("src") as string;
const sizes = img.getAttribute("sizes");
const sourceFormats = saveTransform(basePath, src, imagick);

for (const sourceFormat of sourceFormats) {
const source = createSource(img.ownerDocument!, src, sourceFormat);
const source = createSource(
img.ownerDocument!,
src,
sourceFormat,
sizes,
);
picture.insertBefore(source, img);
}
}

function handleImg(imagick: string, img: Element, basePath: string) {
const src = img.getAttribute("src") as string;
const sizes = img.getAttribute("sizes");
const sourceFormats = saveTransform(basePath, src, imagick);
const picture = img.ownerDocument!.createElement("picture");

img.replaceWith(picture);

for (const sourceFormat of sourceFormats) {
const source = createSource(img.ownerDocument!, src, sourceFormat);
const source = createSource(
img.ownerDocument!,
src,
sourceFormat,
sizes,
);
picture.append(source);
}

Expand Down Expand Up @@ -194,19 +206,29 @@ function createSource(
document: Document,
src: string,
srcFormat: SourceFormat,
sizes?: string | null | undefined,
) {
const source = document.createElement("source");
const { scales, format } = srcFormat;
const { scales, format, width } = srcFormat;
const path = encodeURI(getPathAndExtension(src)[0]);
const srcset: string[] = [];

for (const [suffix, scale] of Object.entries(scales)) {
const scaleSuffix = scale === 1 ? "" : ` ${scale}x`;
const scaleSuffix = sizes
? ` ${scale * width}w`
: scale === 1
? ""
: ` ${scale}x`;
srcset.push(`${path}${suffix}.${format}${scaleSuffix}`);
}

source.setAttribute("srcset", srcset.join(", "));
source.setAttribute("type", typeByExtension(format));

if (sizes) {
source.setAttribute("sizes", sizes);
}

return source;
}

Expand Down
48 changes: 48 additions & 0 deletions tests/__snapshots__/picture.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ snapshot[`imagick plugin 3`] = `
</head>
<body>
<!-- without sizes -->
<div>
<picture><source srcset="/kevin%20schmid%20unsplash-600w.png, /kevin%20schmid%20unsplash-600w@2.png 2x" type="image/png"><img src="/kevin schmid unsplash.jpg"></picture>
</div>
Expand All @@ -125,6 +127,20 @@ snapshot[`imagick plugin 3`] = `
<picture><source srcset="/kevin%20schmid%20unsplash-300w.avif, /kevin%20schmid%20unsplash-300w@2.avif 2x" type="image/avif"><source srcset="/kevin%20schmid%20unsplash-300w.webp, /kevin%20schmid%20unsplash-300w@2.webp 2x" type="image/webp"><source srcset="/kevin%20schmid%20unsplash-300w.jpg, /kevin%20schmid%20unsplash-300w@2.jpg 2x" type="image/jpeg"><img src="/kevin schmid unsplash.jpg"></picture>
<!-- with sizes -->
<div>
<picture><source srcset="/kevin%20schmid%20unsplash-600w.png 600w, /kevin%20schmid%20unsplash-600w@2.png 1200w" type="image/png" sizes="600px"><img src="/kevin schmid unsplash.jpg" sizes="600px"></picture>
</div>
<picture>
<source srcset="/kevin%20schmid%20unsplash-600w.avif 600w, /kevin%20schmid%20unsplash-600w@2.avif 1200w" type="image/avif" sizes="600px"><source srcset="/kevin%20schmid%20unsplash-600w.webp 600w, /kevin%20schmid%20unsplash-600w@2.webp 1200w" type="image/webp" sizes="600px"><source srcset="/kevin%20schmid%20unsplash-600w.jpg 600w, /kevin%20schmid%20unsplash-600w@2.jpg 1200w" type="image/jpeg" sizes="600px"><img src="/kevin schmid unsplash.jpg" sizes="600px">
</picture>
<!-- This image will be converted to a picture -->
<picture><source srcset="/kevin%20schmid%20unsplash-300w.avif 300w, /kevin%20schmid%20unsplash-300w@2.avif 600w" type="image/avif" sizes="600px"><source srcset="/kevin%20schmid%20unsplash-300w.webp 300w, /kevin%20schmid%20unsplash-300w@2.webp 600w" type="image/webp" sizes="600px"><source srcset="/kevin%20schmid%20unsplash-300w.jpg 300w, /kevin%20schmid%20unsplash-300w@2.jpg 600w" type="image/jpeg" sizes="600px"><img src="/kevin schmid unsplash.jpg" sizes="600px"></picture>
</body></html>',
data: {
children: '<!doctype html>
Expand All @@ -134,6 +150,8 @@ snapshot[`imagick plugin 3`] = `
</head>
<body>
<!-- without sizes -->
<div imagick="png 600@2">
<img src="/kevin schmid unsplash.jpg">
</div>
Expand All @@ -145,6 +163,20 @@ snapshot[`imagick plugin 3`] = `
<!-- This image will be converted to a picture -->
<img src="/kevin schmid unsplash.jpg" imagick="avif webp jpg 300@2">
<!-- with sizes -->
<div imagick="png 600@2">
<img src="/kevin schmid unsplash.jpg" sizes="600px">
</div>
<picture imagick="avif webp jpg 600@2">
<img src="/kevin schmid unsplash.jpg" sizes="600px">
</picture>
<!-- This image will be converted to a picture -->
<img src="/kevin schmid unsplash.jpg" imagick="avif webp jpg 300@2" sizes="600px">
</body>
</html>
',
Expand All @@ -155,6 +187,8 @@ snapshot[`imagick plugin 3`] = `
</head>
<body>
<!-- without sizes -->
<div imagick="png 600@2">
<img src="/kevin schmid unsplash.jpg">
</div>
Expand All @@ -166,6 +200,20 @@ snapshot[`imagick plugin 3`] = `
<!-- This image will be converted to a picture -->
<img src="/kevin schmid unsplash.jpg" imagick="avif webp jpg 300@2">
<!-- with sizes -->
<div imagick="png 600@2">
<img src="/kevin schmid unsplash.jpg" sizes="600px">
</div>
<picture imagick="avif webp jpg 600@2">
<img src="/kevin schmid unsplash.jpg" sizes="600px">
</picture>
<!-- This image will be converted to a picture -->
<img src="/kevin schmid unsplash.jpg" imagick="avif webp jpg 300@2" sizes="600px">
</body>
</html>
',
Expand Down
16 changes: 16 additions & 0 deletions tests/assets/picture/index.njk
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
</head>

<body>

<!-- without sizes -->
<div imagick="png 600@2">
<img src="/kevin schmid unsplash.jpg">
</div>
Expand All @@ -16,5 +18,19 @@

<!-- This image will be converted to a picture -->
<img src="/kevin schmid unsplash.jpg" imagick="avif webp jpg 300@2">


<!-- with sizes -->
<div imagick="png 600@2">
<img src="/kevin schmid unsplash.jpg" sizes="600px">
</div>


<picture imagick="avif webp jpg 600@2">
<img src="/kevin schmid unsplash.jpg" sizes="600px">
</picture>

<!-- This image will be converted to a picture -->
<img src="/kevin schmid unsplash.jpg" imagick="avif webp jpg 300@2" sizes="600px">
</body>
</html>

0 comments on commit 8cc1dfe

Please sign in to comment.