Skip to content

Commit

Permalink
Allow progressive enhancement using @supports
Browse files Browse the repository at this point in the history
  • Loading branch information
marek-saji committed Jul 3, 2024
1 parent 8a1c1bd commit a626c3d
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 0 deletions.
33 changes: 33 additions & 0 deletions lib/DoIUse.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import multimatch from 'multimatch';

import postcss from 'postcss';
import BrowserSelection from './BrowserSelection.js';
import Detector from './Detector.js';

Expand Down Expand Up @@ -101,6 +102,38 @@ export default class DoIUse {
if (overwritees.length > 0) {
return;
}

// find the closest @supports parent
/** @type {any} TODO Type this */
let supports = usage.parent;
while (supports && supports.type !== 'atrule' && supports.name !== 'supports') {
supports = supports.parent;
}
if (supports) {
// FIXME This is a very, VERY dirty hack
// FIXME Handle e.g. `@supporst (content: ') and ('`)
// TODO Report an warning if condition is too complex for us to understand
// TODO Support `or`?
// TODO Support nested brackets?
const temporaryDeclarations = supports.params
.split(/(?<=\))\s*and\s*(?=\()/g)
.map((part) => part.trim().replaceAll(/^\(|\)$/g, ''))
.filter((part) => !/^\s*not\s+/i.test(part));

const temporaryCss = `i { ${temporaryDeclarations.join(';\n')} }`;
const temporaryCssTree = postcss.parse(temporaryCss);
const supportsDetector = new Detector([feature]);
const safeToUseFeatures = [];
supportsDetector.process(
temporaryCssTree,
({ feature: supportsFeature }) => {
safeToUseFeatures.push(supportsFeature);
},
);
if (safeToUseFeatures.includes(feature)) {
return;
}
}
}

const messages = [];
Expand Down
48 changes: 48 additions & 0 deletions test/postcss-progressive-enhancement.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,51 @@ test('Progressive enhancement using repeated CSS properties', (t) => {

t.end();
});

test('Progressive enhancement using @supports', (t) => {
const css = `
p {
display: block;
}
@supports (display: grid) {
p {
display: grid;
flex-wrap: wrap;
}
}
`;

const result = postcss(new DoIUse({
browsers: ['safari >= 9'],
})).process(css);
const warnings = result.warnings();

t.equal(warnings.length, 0, 'No warnings');

t.end();
});

test('Progressive enhancement using @supports with multiple conditions', (t) => {
const css = `
p {
display: block;
}
@supports (display: flex) and (color: hsl(0, 0%, 0%)) {
p {
display: flex;
background-color: hsl(0, 0%, 0%);
}
}
`;

const result = postcss(new DoIUse({
browsers: ['safari >= 9'],
})).process(css);
const warnings = result.warnings();

t.equal(warnings.length, 0, 'No warnings');

t.end();
});

0 comments on commit a626c3d

Please sign in to comment.