Skip to content

Commit a2ddca1

Browse files
fix: avoid auto-parenthesis for special-keywords-only MediaQuery (#15937)
* fix: avoid auto-parenthesis for special keywords only `MediaQuery` * chore: update changeset * chore: i has english knowledge * fix: fix media queries with commas
1 parent b7b393d commit a2ddca1

File tree

4 files changed

+34
-1
lines changed

4 files changed

+34
-1
lines changed

.changeset/sweet-islands-sell.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: avoid auto-parenthesis for special-keywords-only `MediaQuery`

packages/svelte/src/reactivity/media-query.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,19 @@ import { ReactiveValue } from './reactive-value.js';
33

44
const parenthesis_regex = /\(.+\)/;
55

6+
// these keywords are valid media queries but they need to be without parenthesis
7+
//
8+
// eg: new MediaQuery('screen')
9+
//
10+
// however because of the auto-parenthesis logic in the constructor since there's no parentehesis
11+
// in the media query they'll be surrounded by parenthesis
12+
//
13+
// however we can check if the media query is only composed of these keywords
14+
// and skip the auto-parenthesis
15+
//
16+
// https://github.com/sveltejs/svelte/issues/15930
17+
const non_parenthesized_keywords = new Set(['all', 'print', 'screen', 'and', 'or', 'not', 'only']);
18+
619
/**
720
* Creates a media query and provides a `current` property that reflects whether or not it matches.
821
*
@@ -27,7 +40,12 @@ export class MediaQuery extends ReactiveValue {
2740
* @param {boolean} [fallback] Fallback value for the server
2841
*/
2942
constructor(query, fallback) {
30-
let final_query = parenthesis_regex.test(query) ? query : `(${query})`;
43+
let final_query =
44+
parenthesis_regex.test(query) ||
45+
// we need to use `some` here because technically this `window.matchMedia('random,screen')` still returns true
46+
query.split(/[\s,]+/).some((keyword) => non_parenthesized_keywords.has(keyword.trim()))
47+
? query
48+
: `(${query})`;
3149
const q = window.matchMedia(final_query);
3250
super(
3351
() => q.matches,

packages/svelte/tests/runtime-runes/samples/media-query/_config.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,10 @@ export default test({
55
async test({ window }) {
66
expect(window.matchMedia).toHaveBeenCalledWith('(max-width: 599px), (min-width: 900px)');
77
expect(window.matchMedia).toHaveBeenCalledWith('(min-width: 900px)');
8+
expect(window.matchMedia).toHaveBeenCalledWith('screen');
9+
expect(window.matchMedia).toHaveBeenCalledWith('not print');
10+
expect(window.matchMedia).toHaveBeenCalledWith('screen,print');
11+
expect(window.matchMedia).toHaveBeenCalledWith('screen, print');
12+
expect(window.matchMedia).toHaveBeenCalledWith('screen, random');
813
}
914
});

packages/svelte/tests/runtime-runes/samples/media-query/main.svelte

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,9 @@
33
44
const mq = new MediaQuery("(max-width: 599px), (min-width: 900px)");
55
const mq2 = new MediaQuery("min-width: 900px");
6+
const mq3 = new MediaQuery("screen");
7+
const mq4 = new MediaQuery("not print");
8+
const mq5 = new MediaQuery("screen,print");
9+
const mq6 = new MediaQuery("screen, print");
10+
const mq7 = new MediaQuery("screen, random");
611
</script>

0 commit comments

Comments
 (0)