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
pull/15956/head
Paolo Ricciuti 4 months ago committed by GitHub
parent b7b393d50f
commit a2ddca1aa1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: avoid auto-parenthesis for special-keywords-only `MediaQuery`

@ -3,6 +3,19 @@ import { ReactiveValue } from './reactive-value.js';
const parenthesis_regex = /\(.+\)/;
// 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 parenthesis
//
// 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,12 @@ 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) ||
// 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);
super(
() => q.matches,

@ -5,5 +5,10 @@ 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');
expect(window.matchMedia).toHaveBeenCalledWith('screen,print');
expect(window.matchMedia).toHaveBeenCalledWith('screen, print');
expect(window.matchMedia).toHaveBeenCalledWith('screen, random');
}
});

@ -3,4 +3,9 @@
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");
const mq5 = new MediaQuery("screen,print");
const mq6 = new MediaQuery("screen, print");
const mq7 = new MediaQuery("screen, random");
</script>

Loading…
Cancel
Save