From e2746ef39f5f2ca2d45ab3a081edf4f7200a5b98 Mon Sep 17 00:00:00 2001
From: Ben McCann <322311+benmccann@users.noreply.github.com>
Date: Mon, 9 Dec 2024 11:14:58 -0800
Subject: [PATCH] feat: set intrinsic width and height for SVGs (#13126)
---
.changeset/tricky-squids-provide.md | 5 +
packages/enhanced-img/package.json | 1 +
packages/enhanced-img/src/preprocessor.js | 74 +++---
packages/enhanced-img/test/Input.svelte | 2 -
packages/enhanced-img/test/Output.svelte | 6 +-
.../enhanced-img/test/preprocessor.spec.js | 2 +-
playgrounds/basic/package.json | 1 +
playgrounds/basic/src/routes/+page.svelte | 6 +
.../basic/src/routes/about/+page.svelte | 1 -
.../basic/src/routes/images/+page.svelte | 11 +
.../src/routes/images/state-of-js-chart.png | Bin 0 -> 190480 bytes
.../basic/src/routes/images/svelte-logo.svg | 1 +
playgrounds/basic/vite.config.js | 3 +-
pnpm-lock.yaml | 216 +++++++++---------
14 files changed, 169 insertions(+), 160 deletions(-)
create mode 100644 .changeset/tricky-squids-provide.md
delete mode 100644 playgrounds/basic/src/routes/about/+page.svelte
create mode 100644 playgrounds/basic/src/routes/images/+page.svelte
create mode 100644 playgrounds/basic/src/routes/images/state-of-js-chart.png
create mode 100644 playgrounds/basic/src/routes/images/svelte-logo.svg
diff --git a/.changeset/tricky-squids-provide.md b/.changeset/tricky-squids-provide.md
new file mode 100644
index 000000000000..d15da40874d9
--- /dev/null
+++ b/.changeset/tricky-squids-provide.md
@@ -0,0 +1,5 @@
+---
+'@sveltejs/enhanced-img': patch
+---
+
+feat: set intrinsic width and height for SVGs
diff --git a/packages/enhanced-img/package.json b/packages/enhanced-img/package.json
index 4fc2bbc76dcb..41157706762f 100644
--- a/packages/enhanced-img/package.json
+++ b/packages/enhanced-img/package.json
@@ -37,6 +37,7 @@
"types": "types/index.d.ts",
"dependencies": {
"magic-string": "^0.30.5",
+ "sharp": "^0.33.5",
"svelte-parse-markup": "^0.1.5",
"vite-imagetools": "^7.0.1",
"zimmerframe": "^1.1.2"
diff --git a/packages/enhanced-img/src/preprocessor.js b/packages/enhanced-img/src/preprocessor.js
index 7331cff18e11..de800b653734 100644
--- a/packages/enhanced-img/src/preprocessor.js
+++ b/packages/enhanced-img/src/preprocessor.js
@@ -4,8 +4,9 @@ import { existsSync } from 'node:fs';
import * as path from 'node:path';
import MagicString from 'magic-string';
-import { walk } from 'zimmerframe';
+import sharp from 'sharp';
import { parse } from 'svelte-parse-markup';
+import { walk } from 'zimmerframe';
// TODO: expose this in vite-imagetools rather than duplicating it
const OPTIMIZABLE = /^[^?]+\.(avif|heif|gif|jpeg|jpg|png|tiff|webp)(\?.*)?$/;
@@ -70,33 +71,36 @@ export function image(opts) {
const original_url = src_attribute.raw.trim();
let url = original_url;
- const sizes = get_attr_value(node, 'sizes');
- const width = get_attr_value(node, 'width');
- url += url.includes('?') ? '&' : '?';
- if (sizes && 'raw' in sizes) {
- url += 'imgSizes=' + encodeURIComponent(sizes.raw) + '&';
- }
- if (width && 'raw' in width) {
- url += 'imgWidth=' + encodeURIComponent(width.raw) + '&';
+ if (OPTIMIZABLE.test(url)) {
+ const sizes = get_attr_value(node, 'sizes');
+ const width = get_attr_value(node, 'width');
+ url += url.includes('?') ? '&' : '?';
+ if (sizes && 'raw' in sizes) {
+ url += 'imgSizes=' + encodeURIComponent(sizes.raw) + '&';
+ }
+ if (width && 'raw' in width) {
+ url += 'imgWidth=' + encodeURIComponent(width.raw) + '&';
+ }
+ url += 'enhanced';
}
- url += 'enhanced';
- if (OPTIMIZABLE.test(url)) {
- // resolves the import so that we can build the entire picture template string and don't
- // need any logic blocks
- const resolved_id = (await opts.plugin_context.resolve(url, filename))?.id;
- if (!resolved_id) {
- const file_path = url.substring(0, url.indexOf('?'));
- if (existsSync(path.resolve(opts.vite_config.publicDir, file_path))) {
- throw new Error(
- `Could not locate ${file_path}. Please move it to be located relative to the page in the routes directory or reference it beginning with /static/. See https://vitejs.dev/guide/assets for more details on referencing assets.`
- );
- }
+ // resolves the import so that we can build the entire picture template string and don't
+ // need any logic blocks
+ const resolved_id = (await opts.plugin_context.resolve(url, filename))?.id;
+ if (!resolved_id) {
+ const query_index = url.indexOf('?');
+ const file_path = query_index >= 0 ? url.substring(0, query_index) : url;
+ if (existsSync(path.resolve(opts.vite_config.publicDir, file_path))) {
throw new Error(
- `Could not locate ${file_path}. See https://vitejs.dev/guide/assets for more details on referencing assets.`
+ `Could not locate ${file_path}. Please move it to be located relative to the page in the routes directory or reference it beginning with /static/. See https://vitejs.dev/guide/assets for more details on referencing assets.`
);
}
+ throw new Error(
+ `Could not locate ${file_path}. See https://vitejs.dev/guide/assets for more details on referencing assets.`
+ );
+ }
+ if (OPTIMIZABLE.test(url)) {
let image = images.get(resolved_id);
if (!image) {
image = await process(resolved_id, opts);
@@ -104,17 +108,14 @@ export function image(opts) {
}
s.update(node.start, node.end, img_to_picture(content, node, image));
} else {
- // e.g. =>
const name = '__IMPORTED_ASSET_' + imports.size + '__';
- const { start, end } = src_attribute;
- // update src with reference to imported asset
- s.update(
- is_quote(content, start - 1) ? start - 1 : start,
- is_quote(content, end) ? end + 1 : end,
- `{${name}}`
- );
- // update `enhanced:img` to `img`
- s.update(node.start + 1, node.start + 1 + 'enhanced:img'.length, 'img');
+ const metadata = await sharp(resolved_id).metadata();
+ const new_markup = ``;
+ s.update(node.start, node.end, new_markup);
imports.set(original_url, name);
}
}
@@ -175,15 +176,6 @@ export function image(opts) {
};
}
-/**
- * @param {string} content
- * @param {number} index
- * @returns {boolean}
- */
-function is_quote(content, index) {
- return content.charAt(index) === '"' || content.charAt(index) === "'";
-}
-
/**
* @param {string} resolved_id
* @param {{
diff --git a/packages/enhanced-img/test/Input.svelte b/packages/enhanced-img/test/Input.svelte
index 3a29902d0930..35fd9c59901d 100644
--- a/packages/enhanced-img/test/Input.svelte
+++ b/packages/enhanced-img/test/Input.svelte
@@ -45,8 +45,6 @@
-
-
{#each images as image}
{/each}
diff --git a/packages/enhanced-img/test/Output.svelte b/packages/enhanced-img/test/Output.svelte
index 4d8bcc402272..d8c18c1ad88f 100644
--- a/packages/enhanced-img/test/Output.svelte
+++ b/packages/enhanced-img/test/Output.svelte
@@ -1,6 +1,4 @@
-