From 480df3857d1492cbd7f80b7890cbd9f387456ffc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Sat, 16 Jul 2022 18:27:34 +0800 Subject: [PATCH] feat: add `dppx` when the browser does not support the `x` unit in resolution media queries --- lib/resolution.js | 27 +++++++++++++++++---- test/autoprefixer.test.js | 6 +++++ test/cases/resolution-dppx-fallback.css | 1 + test/cases/resolution-dppx-fallback.out.css | 1 + test/cases/resolution.css | 2 +- test/cases/resolution.out.css | 2 +- 6 files changed, 32 insertions(+), 7 deletions(-) create mode 100644 test/cases/resolution-dppx-fallback.css create mode 100644 test/cases/resolution-dppx-fallback.out.css diff --git a/lib/resolution.js b/lib/resolution.js index ee04d6d99..2b920864b 100644 --- a/lib/resolution.js +++ b/lib/resolution.js @@ -4,7 +4,7 @@ let Prefixer = require('./prefixer') let utils = require('./utils') const REGEXP = /(min|max)-resolution\s*:\s*\d*\.?\d+(dppx|dpcm|dpi|x)/gi -const SPLIT = /(min|max)-resolution(\s*:\s*)(\d*\.?\d+)(dppx|dpcm|dpi|x)/i +const SPLIT = /((min|max)-resolution)(\s*:\s*)(\d*\.?\d+)(dppx|dpcm|dpi|x)/i class Resolution extends Prefixer { /** @@ -73,19 +73,36 @@ class Resolution extends Prefixer { continue } + let fallbackExpression + let addFallbackExpression = false for (let prefix of prefixes) { let processed = query.replace(REGEXP, str => { let parts = str.match(SPLIT) + let fallbackName = parts[1] + let colon = parts[3] + let value = parts[4] + let units = parts[5] + + // Add `ddpx` for browsers that do not support `x` unit. + // `x` unit: Chrome 68+, Edge 79+, Opera 55+, Safari 16+, Firefox 62+ + // See: https://developer.mozilla.org/en-US/docs/Web/CSS/resolution#browser_compatibility + if (units === 'x') { + fallbackExpression = '(' + fallbackName + colon + value + 'dppx' + ')' + addFallbackExpression = true + } + return this.prefixQuery( prefix, - parts[1], - parts[2], - parts[3], - parts[4] + parts[2], // min- or max- + colon, + value, + units ) }) prefixed.push(processed) } + + if (addFallbackExpression) prefixed.push(fallbackExpression) prefixed.push(query) } diff --git a/test/autoprefixer.test.js b/test/autoprefixer.test.js index 4496564a7..38a3932ca 100644 --- a/test/autoprefixer.test.js +++ b/test/autoprefixer.test.js @@ -231,6 +231,7 @@ const COMMONS = [ 'supports', 'viewport', 'resolution', + 'resolution-dppx-fallback', 'logical', 'appearance', 'advanced-filter', @@ -505,6 +506,11 @@ test('removes unnecessary prefixes', () => { if (i === 'grid-template-areas') continue let input = read(i + '.out') let output = read(i) + + if (i === 'resolution-dppx-fallback') { + output = '@media (min-resolution: 2dppx), (min-resolution: 2x) { }\n' + } + equal(processor.process(input).css, output) } }) diff --git a/test/cases/resolution-dppx-fallback.css b/test/cases/resolution-dppx-fallback.css new file mode 100644 index 000000000..43994b214 --- /dev/null +++ b/test/cases/resolution-dppx-fallback.css @@ -0,0 +1 @@ +@media (min-resolution: 2x) { } diff --git a/test/cases/resolution-dppx-fallback.out.css b/test/cases/resolution-dppx-fallback.out.css new file mode 100644 index 000000000..e2bf9a8a4 --- /dev/null +++ b/test/cases/resolution-dppx-fallback.out.css @@ -0,0 +1 @@ +@media (-webkit-min-device-pixel-ratio: 2), (-o-min-device-pixel-ratio: 2/1), (min-resolution: 2dppx), (min-resolution: 2x) { } diff --git a/test/cases/resolution.css b/test/cases/resolution.css index 18d357d97..2f7e71cf0 100644 --- a/test/cases/resolution.css +++ b/test/cases/resolution.css @@ -5,7 +5,7 @@ @media (min-resolution: 144dpi) { } -@media (min-resolution: 2x) { } +@media (min-resolution: 2dppx), (min-resolution: 2x) { } @media (min-resolution: 120dpi) { } diff --git a/test/cases/resolution.out.css b/test/cases/resolution.out.css index 708e4703f..e779833bc 100644 --- a/test/cases/resolution.out.css +++ b/test/cases/resolution.out.css @@ -8,7 +8,7 @@ @media (-webkit-min-device-pixel-ratio: 1.5), (min--moz-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3/2), (min-resolution: 144dpi) { } -@media (-webkit-min-device-pixel-ratio: 2), (min--moz-device-pixel-ratio: 2), (-o-min-device-pixel-ratio: 2/1), (min-resolution: 2x) { } +@media (-webkit-min-device-pixel-ratio: 2), (min--moz-device-pixel-ratio: 2), (-o-min-device-pixel-ratio: 2/1), (min-resolution: 2dppx), (min-resolution: 2x) { } @media (-webkit-min-device-pixel-ratio: 1.25), (min--moz-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 5/4), (min-resolution: 120dpi) { }