From 65668c0e1c73c88cb076e26e9b03fc51dbafbd32 Mon Sep 17 00:00:00 2001 From: paoloricciuti Date: Fri, 16 May 2025 11:53:38 +0200 Subject: [PATCH 1/4] fix: avoid auto-parenthesis for special keywords only `MediaQuery` --- .changeset/sweet-islands-sell.md | 5 +++++ packages/svelte/src/reactivity/media-query.js | 19 ++++++++++++++++++- .../samples/media-query/_config.js | 2 ++ .../samples/media-query/main.svelte | 2 ++ 4 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 .changeset/sweet-islands-sell.md diff --git a/.changeset/sweet-islands-sell.md b/.changeset/sweet-islands-sell.md new file mode 100644 index 000000000000..80402594b3eb --- /dev/null +++ b/.changeset/sweet-islands-sell.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: avoid auto-parenthesis for special keywords only `MediaQuery` diff --git a/packages/svelte/src/reactivity/media-query.js b/packages/svelte/src/reactivity/media-query.js index 22310df18d53..cb569f85c6c5 100644 --- a/packages/svelte/src/reactivity/media-query.js +++ b/packages/svelte/src/reactivity/media-query.js @@ -3,6 +3,19 @@ import { ReactiveValue } from './reactive-value.js'; const parenthesis_regex = /\(.+\)/; +// this keyworks are valid media queries but they need to be without parenthesis +// +// eg: new MediaQuery('screen') +// +// however because of the auto-parenthesis logic in the constructor since there's no parentehesis +// in the media query they'll be surrounded by parentehesis +// +// however we can check if the media query is only composed of these keywords +// and skip the auto-parenthesis +// +// https://github.com/sveltejs/svelte/issues/15930 +const non_parenthesized_keywords = new Set(['all', 'print', 'screen', 'and', 'or', 'not', 'only']); + /** * Creates a media query and provides a `current` property that reflects whether or not it matches. * @@ -27,7 +40,11 @@ export class MediaQuery extends ReactiveValue { * @param {boolean} [fallback] Fallback value for the server */ constructor(query, fallback) { - let final_query = parenthesis_regex.test(query) ? query : `(${query})`; + let final_query = + parenthesis_regex.test(query) || + query.split(' ').every((keyword) => non_parenthesized_keywords.has(keyword)) + ? query + : `(${query})`; const q = window.matchMedia(final_query); super( () => q.matches, diff --git a/packages/svelte/tests/runtime-runes/samples/media-query/_config.js b/packages/svelte/tests/runtime-runes/samples/media-query/_config.js index f7a4ca05f570..60a9d123625e 100644 --- a/packages/svelte/tests/runtime-runes/samples/media-query/_config.js +++ b/packages/svelte/tests/runtime-runes/samples/media-query/_config.js @@ -5,5 +5,7 @@ export default test({ async test({ window }) { expect(window.matchMedia).toHaveBeenCalledWith('(max-width: 599px), (min-width: 900px)'); expect(window.matchMedia).toHaveBeenCalledWith('(min-width: 900px)'); + expect(window.matchMedia).toHaveBeenCalledWith('screen'); + expect(window.matchMedia).toHaveBeenCalledWith('not print'); } }); diff --git a/packages/svelte/tests/runtime-runes/samples/media-query/main.svelte b/packages/svelte/tests/runtime-runes/samples/media-query/main.svelte index 446a9213dda2..0b9f0cc3ea93 100644 --- a/packages/svelte/tests/runtime-runes/samples/media-query/main.svelte +++ b/packages/svelte/tests/runtime-runes/samples/media-query/main.svelte @@ -3,4 +3,6 @@ const mq = new MediaQuery("(max-width: 599px), (min-width: 900px)"); const mq2 = new MediaQuery("min-width: 900px"); + const mq3 = new MediaQuery("screen"); + const mq4 = new MediaQuery("not print"); From 0046ed87d8fd40c9c363248c04e0355149aeeb06 Mon Sep 17 00:00:00 2001 From: Paolo Ricciuti Date: Fri, 16 May 2025 11:54:46 +0200 Subject: [PATCH 2/4] chore: update changeset --- .changeset/sweet-islands-sell.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/sweet-islands-sell.md b/.changeset/sweet-islands-sell.md index 80402594b3eb..b4fbbf182c4e 100644 --- a/.changeset/sweet-islands-sell.md +++ b/.changeset/sweet-islands-sell.md @@ -2,4 +2,4 @@ 'svelte': patch --- -fix: avoid auto-parenthesis for special keywords only `MediaQuery` +fix: avoid auto-parenthesis for special-keywords-only `MediaQuery` From aace747669fe10c79db6e4209c89168317de63ff Mon Sep 17 00:00:00 2001 From: Paolo Ricciuti Date: Fri, 16 May 2025 13:15:15 +0200 Subject: [PATCH 3/4] chore: i has english knowledge --- packages/svelte/src/reactivity/media-query.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/svelte/src/reactivity/media-query.js b/packages/svelte/src/reactivity/media-query.js index cb569f85c6c5..4e3f11c1459e 100644 --- a/packages/svelte/src/reactivity/media-query.js +++ b/packages/svelte/src/reactivity/media-query.js @@ -3,12 +3,12 @@ import { ReactiveValue } from './reactive-value.js'; const parenthesis_regex = /\(.+\)/; -// this keyworks are valid media queries but they need to be without parenthesis +// these keywords are valid media queries but they need to be without parenthesis // // eg: new MediaQuery('screen') // // however because of the auto-parenthesis logic in the constructor since there's no parentehesis -// in the media query they'll be surrounded by parentehesis +// in the media query they'll be surrounded by parenthesis // // however we can check if the media query is only composed of these keywords // and skip the auto-parenthesis From 7eef30ee028d8d7679398b55b81c64db694a8aaa Mon Sep 17 00:00:00 2001 From: paoloricciuti Date: Mon, 19 May 2025 19:47:02 +0200 Subject: [PATCH 4/4] fix: fix media queries with commas --- packages/svelte/src/reactivity/media-query.js | 3 ++- .../svelte/tests/runtime-runes/samples/media-query/_config.js | 3 +++ .../svelte/tests/runtime-runes/samples/media-query/main.svelte | 3 +++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/svelte/src/reactivity/media-query.js b/packages/svelte/src/reactivity/media-query.js index 4e3f11c1459e..d2867097195c 100644 --- a/packages/svelte/src/reactivity/media-query.js +++ b/packages/svelte/src/reactivity/media-query.js @@ -42,7 +42,8 @@ export class MediaQuery extends ReactiveValue { constructor(query, fallback) { let final_query = parenthesis_regex.test(query) || - query.split(' ').every((keyword) => non_parenthesized_keywords.has(keyword)) + // we need to use `some` here because technically this `window.matchMedia('random,screen')` still returns true + query.split(/[\s,]+/).some((keyword) => non_parenthesized_keywords.has(keyword.trim())) ? query : `(${query})`; const q = window.matchMedia(final_query); diff --git a/packages/svelte/tests/runtime-runes/samples/media-query/_config.js b/packages/svelte/tests/runtime-runes/samples/media-query/_config.js index 60a9d123625e..d8b202955aae 100644 --- a/packages/svelte/tests/runtime-runes/samples/media-query/_config.js +++ b/packages/svelte/tests/runtime-runes/samples/media-query/_config.js @@ -7,5 +7,8 @@ export default test({ expect(window.matchMedia).toHaveBeenCalledWith('(min-width: 900px)'); expect(window.matchMedia).toHaveBeenCalledWith('screen'); expect(window.matchMedia).toHaveBeenCalledWith('not print'); + expect(window.matchMedia).toHaveBeenCalledWith('screen,print'); + expect(window.matchMedia).toHaveBeenCalledWith('screen, print'); + expect(window.matchMedia).toHaveBeenCalledWith('screen, random'); } }); diff --git a/packages/svelte/tests/runtime-runes/samples/media-query/main.svelte b/packages/svelte/tests/runtime-runes/samples/media-query/main.svelte index 0b9f0cc3ea93..fe07ed8ab0d0 100644 --- a/packages/svelte/tests/runtime-runes/samples/media-query/main.svelte +++ b/packages/svelte/tests/runtime-runes/samples/media-query/main.svelte @@ -5,4 +5,7 @@ const mq2 = new MediaQuery("min-width: 900px"); const mq3 = new MediaQuery("screen"); const mq4 = new MediaQuery("not print"); + const mq5 = new MediaQuery("screen,print"); + const mq6 = new MediaQuery("screen, print"); + const mq7 = new MediaQuery("screen, random");