Skip to content

Commit 9dd1ecb

Browse files
committed
fix: warn rather than crash when non-enhanced image dynamically passed to enhanced:img
1 parent 9425c38 commit 9dd1ecb

File tree

4 files changed

+47
-29
lines changed

4 files changed

+47
-29
lines changed

.changeset/poor-heads-fix.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@sveltejs/enhanced-img': patch
3+
---
4+
5+
fix: warn rather than crash when non-enhanced image dynamically passed to `enhanced:img`

documentation/docs/40-best-practices/07-images.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ You can also use [Vite's `import.meta.glob`](https://vitejs.dev/guide/features.h
8484
```svelte
8585
<script>
8686
const imageModules = import.meta.glob(
87-
'/path/to/assets/*.{avif,gif,heif,jpeg,jpg,png,tiff,webp,svg}',
87+
'/path/to/assets/*.{avif,gif,heif,jpeg,jpg,png,tiff,webp}',
8888
{
8989
eager: true,
9090
query: {
@@ -99,6 +99,8 @@ You can also use [Vite's `import.meta.glob`](https://vitejs.dev/guide/features.h
9999
{/each}
100100
```
101101

102+
> [!NOTE] svg images are currently only supported statically
103+
102104
### Intrinsic Dimensions
103105

104106
`width` and `height` are optional as they can be inferred from the source image and will be automatically added when the `<enhanced:img>` tag is preprocessed. With these attributes, the browser can reserve the correct amount of space, preventing [layout shift](https://web.dev/articles/cls). If you'd like to use a different `width` and `height` you can style the image with CSS. Because the preprocessor adds a `width` and `height` for you, if you'd like one of the dimensions to be automatically calculated then you will need to specify that:

packages/enhanced-img/src/vite-plugin.js

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,8 @@ export function image_plugin(imagetools_plugin) {
130130
const name = imports.get(original_url) || '__IMPORTED_ASSET_' + imports.size + '__';
131131
const new_markup = `<img ${serialize_img_attributes(content, node.attributes, {
132132
src: `{${name}}`,
133-
width: metadata.width || 0,
134-
height: metadata.height || 0
133+
width: metadata.width,
134+
height: metadata.height
135135
})} />`;
136136
s.update(node.start, node.end, new_markup);
137137
imports.set(original_url, name);
@@ -258,8 +258,8 @@ function get_attr_value(node, attr) {
258258
* @param {import('../types/internal.js').Attribute[]} attributes
259259
* @param {{
260260
* src: string,
261-
* width: string | number,
262-
* height: string | number
261+
* width?: string | number,
262+
* height?: string | number
263263
* }} details
264264
*/
265265
function serialize_img_attributes(content, attributes, details) {
@@ -283,21 +283,27 @@ function serialize_img_attributes(content, attributes, details) {
283283
}
284284
}
285285
}
286-
if (!user_width && !user_height) {
287-
attribute_strings.push(`width=${details.width}`);
288-
attribute_strings.push(`height=${details.height}`);
289-
} else if (!user_width && user_height) {
290-
attribute_strings.push(
291-
`width=${Math.round(
292-
(stringToNumber(details.width) * user_height) / stringToNumber(details.height)
293-
)}`
294-
);
295-
} else if (!user_height && user_width) {
296-
attribute_strings.push(
297-
`height=${Math.round(
298-
(stringToNumber(details.height) * user_width) / stringToNumber(details.width)
299-
)}`
300-
);
286+
if (details.width && details.height) {
287+
if (!user_width && !user_height) {
288+
attribute_strings.push(`width=${details.width}`);
289+
attribute_strings.push(`height=${details.height}`);
290+
} else if (!user_width && user_height) {
291+
attribute_strings.push(
292+
`width=${Math.round(
293+
(stringToNumber(details.width) * user_height) / stringToNumber(details.height)
294+
)}`
295+
);
296+
} else if (!user_height && user_width) {
297+
attribute_strings.push(
298+
`height=${Math.round(
299+
(stringToNumber(details.height) * user_width) / stringToNumber(details.width)
300+
)}`
301+
);
302+
}
303+
} else {
304+
if (!user_width || !user_height) {
305+
console.warn(`Could not determine dimensions for ${content}. Was it enhanced?`);
306+
}
301307
}
302308

303309
return attribute_strings.join(' ');
@@ -367,20 +373,20 @@ function dynamic_img_to_picture(content, node, src_var_name) {
367373
attributes.splice(index, 1);
368374
}
369375

370-
const details = {
371-
src: `{${src_var_name}.img.src}`,
372-
width: `{${src_var_name}.img.w}`,
373-
height: `{${src_var_name}.img.h}`
374-
};
375-
376376
return `{#if typeof ${src_var_name} === 'string'}
377-
<img ${serialize_img_attributes(content, attributes, details)} />
377+
<img ${serialize_img_attributes(content, attributes, {
378+
src: `{${src_var_name}}`
379+
})} />
378380
{:else}
379381
<picture>
380382
{#each Object.entries(${src_var_name}.sources) as [format, srcset]}
381383
<source {srcset}${sizes_string} type={'image/' + format} />
382384
{/each}
383-
<img ${serialize_img_attributes(content, attributes, details)} />
385+
<img ${serialize_img_attributes(content, attributes, {
386+
src: `{${src_var_name}.img.src}`,
387+
width: `{${src_var_name}.img.w}`,
388+
height: `{${src_var_name}.img.h}`
389+
})} />
384390
</picture>
385391
{/if}`;
386392
}

packages/enhanced-img/test/apps/basics/src/routes/+page.svelte

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
import logo from './logo.png?enhanced';
33
</script>
44

5-
<enhanced:img id="playwright" src="./playwright-logo.svg" alt="Playwright logo" />
5+
<!-- standard image -->
66
<enhanced:img id="birds" src="./birds.jpg" alt="birds" />
7+
8+
<!-- svg over inline size -->
9+
<enhanced:img id="playwright" src="./playwright-logo.svg" alt="Playwright logo" />
10+
11+
<!-- dynamic image -->
712
<enhanced:img id="logo" src={logo} alt="Svelte logo" />

0 commit comments

Comments
 (0)