Skip to content

Commit 0d3ea25

Browse files
authored
Add support for the supports() function (#2535)
1 parent ddd4b23 commit 0d3ea25

File tree

5 files changed

+100
-3
lines changed

5 files changed

+100
-3
lines changed

pkg/sass-parser/CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
* Add support for parsing selector expressions.
88

9+
* Add support for parsing the `supports()` function in `@import` modifiers.
10+
911
## 0.4.15
1012

1113
* Add support for parsing list expressions.

pkg/sass-parser/lib/src/expression/__snapshots__/string.test.ts.snap

+54-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3-
exports[`a string expression toJSON 1`] = `
3+
exports[`a string expression toJSON a quoted string 1`] = `
44
{
55
"inputs": [
66
{
@@ -16,3 +16,56 @@ exports[`a string expression toJSON 1`] = `
1616
"text": <foo>,
1717
}
1818
`;
19+
20+
exports[`a string expression toJSON a string with interpolation 1`] = `
21+
{
22+
"inputs": [
23+
{
24+
"css": "@#{f#{o}o}",
25+
"hasBOM": false,
26+
"id": "<input css _____>",
27+
},
28+
],
29+
"quotes": false,
30+
"raws": {},
31+
"sassType": "string",
32+
"source": <1:4-1:10 in 0>,
33+
"text": <f#{o}o>,
34+
}
35+
`;
36+
37+
exports[`a string expression toJSON an unquoted string 1`] = `
38+
{
39+
"inputs": [
40+
{
41+
"css": "@#{foo}",
42+
"hasBOM": false,
43+
"id": "<input css _____>",
44+
},
45+
],
46+
"quotes": false,
47+
"raws": {},
48+
"sassType": "string",
49+
"source": <1:4-1:7 in 0>,
50+
"text": <foo>,
51+
}
52+
`;
53+
54+
exports[`a string expression toJSON supports() 1`] = `
55+
{
56+
"inputs": [
57+
{
58+
"css": "@import "foo" supports(width: 1 + 1)",
59+
"hasBOM": false,
60+
"id": "<input css _____>",
61+
},
62+
],
63+
"nodes": [
64+
"supports",
65+
<(width: #{1 + 1})>,
66+
],
67+
"raws": {},
68+
"sassType": "interpolation",
69+
"source": <1:15-1:37 in 0>,
70+
}
71+
`;

pkg/sass-parser/lib/src/expression/convert.ts

+11
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import * as sassInternal from '../sass-internal';
66

77
import {ArgumentList} from '../argument-list';
8+
import {Interpolation} from '../interpolation';
9+
import {LazySource} from '../lazy-source';
810
import {Expression} from '.';
911
import {BinaryOperationExpression} from './binary-operation';
1012
import {BooleanExpression} from './boolean';
@@ -41,6 +43,15 @@ const visitor = sassInternal.createExpressionVisitor<Expression>({
4143
new ParenthesizedExpression(undefined, inner),
4244
visitSelectorExpression: inner => new SelectorExpression(undefined, inner),
4345
visitStringExpression: inner => new StringExpression(undefined, inner),
46+
visitSupportsExpression: inner =>
47+
new StringExpression({
48+
text: new Interpolation([
49+
'(',
50+
new Interpolation(undefined, inner.condition.toInterpolation()),
51+
')',
52+
]),
53+
source: new LazySource(inner),
54+
}),
4455
});
4556

4657
/** Converts an internal expression AST node into an external one. */

pkg/sass-parser/lib/src/expression/string.test.ts

+27-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,13 @@
22
// MIT-style license that can be found in the LICENSE file or at
33
// https://opensource.org/licenses/MIT.
44

5-
import {Interpolation, StringExpression} from '../..';
5+
import {
6+
ImportRule,
7+
Interpolation,
8+
StaticImport,
9+
StringExpression,
10+
scss,
11+
} from '../..';
612
import * as utils from '../../../test/utils';
713

814
describe('a string expression', () => {
@@ -284,5 +290,24 @@ describe('a string expression', () => {
284290
});
285291
});
286292

287-
it('toJSON', () => expect(utils.parseExpression('"foo"')).toMatchSnapshot());
293+
describe('toJSON', () => {
294+
it('a quoted string', () =>
295+
expect(utils.parseExpression('"foo"')).toMatchSnapshot());
296+
297+
it('an unquoted string', () =>
298+
expect(utils.parseExpression('foo')).toMatchSnapshot());
299+
300+
it('a string with interpolation', () =>
301+
expect(utils.parseExpression('f#{o}o')).toMatchSnapshot());
302+
303+
it('supports()', () =>
304+
expect(
305+
(
306+
(
307+
scss.parse('@import "foo" supports(width: 1 + 1)')
308+
.nodes[0] as ImportRule
309+
).imports.nodes[0] as StaticImport
310+
).modifiers,
311+
).toMatchSnapshot());
312+
});
288313
});

pkg/sass-parser/lib/src/sass-internal.ts

+6
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,10 @@ declare namespace SassInternal {
384384
readonly text: Interpolation;
385385
readonly hasQuotes: boolean;
386386
}
387+
388+
class SupportsExpression extends Expression {
389+
readonly condition: SupportsCondition;
390+
}
387391
}
388392

389393
const sassInternal = (
@@ -446,6 +450,7 @@ export type NumberExpression = SassInternal.NumberExpression;
446450
export type ParenthesizedExpression = SassInternal.ParenthesizedExpression;
447451
export type SelectorExpression = SassInternal.SelectorExpression;
448452
export type StringExpression = SassInternal.StringExpression;
453+
export type SupportsExpression = SassInternal.SupportsExpression;
449454

450455
export interface StatementVisitorObject<T> {
451456
visitAtRootRule(node: AtRootRule): T;
@@ -489,6 +494,7 @@ export interface ExpressionVisitorObject<T> {
489494
visitParenthesizedExpression(node: ParenthesizedExpression): T;
490495
visitSelectorExpression(node: SelectorExpression): T;
491496
visitStringExpression(node: StringExpression): T;
497+
visitSupportsExpression(node: SupportsExpression): T;
492498
}
493499

494500
export const createExpressionVisitor = sassInternal.createExpressionVisitor;

0 commit comments

Comments
 (0)