Adds single value CSS function support to container query parsing.

pull/8275/head
typhonrt 4 years ago
parent 39fb408c0e
commit 94c22e678f

@ -8,6 +8,7 @@ import * as ContainerFeature from './node/container_feature';
import * as ContainerFeatureRange from './node/container_feature_range'; import * as ContainerFeatureRange from './node/container_feature_range';
import * as ContainerFeatureStyle from './node/container_feature_style'; import * as ContainerFeatureStyle from './node/container_feature_style';
import * as ContainerQuery from './node/container_query'; import * as ContainerQuery from './node/container_query';
import * as QueryCSSFunction from './node/query_css_function';
/** /**
* Extends `css-tree` for container query support by forking and adding new nodes and at-rule support for `@container`. * Extends `css-tree` for container query support by forking and adding new nodes and at-rule support for `@container`.
@ -34,7 +35,8 @@ const cqSyntax = fork({
ContainerFeature, ContainerFeature,
ContainerFeatureRange, ContainerFeatureRange,
ContainerFeatureStyle, ContainerFeatureStyle,
ContainerQuery ContainerQuery,
QueryCSSFunction
} }
}); });

@ -3,7 +3,8 @@ import {
Ident, Ident,
Number, Number,
Dimension, Dimension,
LeftParenthesis, Function,
LeftParenthesis,
RightParenthesis, RightParenthesis,
Colon, Colon,
Delim Delim
@ -12,7 +13,7 @@ import {
export const name = 'ContainerFeature'; export const name = 'ContainerFeature';
export const structure = { export const structure = {
name: String, name: String,
value: ['Identifier', 'Number', 'Dimension', 'Ratio', null] value: ['Identifier', 'Number', 'Dimension', 'QueryCSSFunction', 'Ratio', null]
}; };
export function parse() { export function parse() {
@ -36,19 +37,22 @@ export function parse() {
} else { } else {
value = this.Number(); value = this.Number();
} }
break; break;
case Dimension: case Dimension:
value = this.Dimension(); value = this.Dimension();
break; break;
case Ident: case Function:
value = this.QueryCSSFunction();
break;
case Ident:
value = this.Identifier(); value = this.Identifier();
break; break;
default: default:
this.error('Number, dimension, ratio or identifier is expected'); this.error('Number, dimension, ratio, function, or identifier is expected');
break; break;
} }

@ -4,6 +4,7 @@ import {
Number, Number,
Delim, Delim,
Dimension, Dimension,
Function,
LeftParenthesis, LeftParenthesis,
RightParenthesis, RightParenthesis,
WhiteSpace WhiteSpace
@ -12,7 +13,7 @@ import {
export const name = 'ContainerFeatureRange'; export const name = 'ContainerFeatureRange';
export const structure = { export const structure = {
name: String, name: String,
value: ['Identifier', 'Number', 'Comparison', 'Dimension', 'Ratio', null] value: ['Identifier', 'Number', 'Comparison', 'Dimension', 'QueryCSSFunction', 'Ratio', null]
}; };
function lookupNonWSTypeAndValue(offset, type, referenceStr) { function lookupNonWSTypeAndValue(offset, type, referenceStr) {
@ -53,12 +54,16 @@ export function parse() {
child = this.Dimension(); child = this.Dimension();
break; break;
case Function:
child = this.QueryCSSFunction();
break;
case Ident: case Ident:
child = this.Identifier(); child = this.Identifier();
break; break;
default: default:
this.error('Number, dimension, comparison, ratio or identifier is expected'); this.error('Number, dimension, comparison, ratio, function, or identifier is expected');
break; break;
} }

@ -12,7 +12,7 @@ import {
export const name = 'ContainerFeatureStyle'; export const name = 'ContainerFeatureStyle';
export const structure = { export const structure = {
name: String, name: String,
value: ['Function', 'Identifier', 'Number', 'Dimension', 'Ratio', null] value: ['Function', 'Identifier', 'Number', 'Dimension', 'QueryCSSFunction', 'Ratio', null]
}; };
export function parse() { export function parse() {
@ -40,19 +40,22 @@ export function parse() {
} else { } else {
value = this.Number(); value = this.Number();
} }
break; break;
case Dimension: case Dimension:
value = this.Dimension(); value = this.Dimension();
break; break;
case Ident: case Function:
value = this.QueryCSSFunction();
break;
case Ident:
value = this.Identifier(); value = this.Identifier();
break; break;
default: default:
this.error('Number, dimension, ratio or identifier is expected'); this.error('Number, dimension, ratio, function or identifier is expected');
break; break;
} }

@ -0,0 +1,41 @@
// @ts-nocheck
import {
RightParenthesis
} from 'css-tree/tokenizer';
const QUERY_CSS_FUNCTIONS = new Set(['calc', 'clamp', 'min', 'max']);
export const name = 'QueryCSSFunction';
export const structure = {
name: String,
expression: String
};
export function parse() {
const start = this.tokenStart;
const name = this.consumeFunctionName();
if (!QUERY_CSS_FUNCTIONS.has(name)) {
this.error('Unknown query single value function; expected: "calc", "clamp", "max", min"');
}
const body = this.Raw(this.tokenIndex, null, false);
this.eat(RightParenthesis);
return {
type: 'QueryCSSFunction',
loc: this.getLocation(start, this.tokenStart),
name,
expression: body.value
};
}
export function generate(node) {
this.token(Function, `${node.name}(`);
this.node(node.expression);
this.token(RightParenthesis, ')');
}

@ -1 +1 @@
div.svelte-xyz{container:test-container / inline-size}@container (min-width: 400px){div.svelte-xyz{color:red}}@container test-container (min-width: 410px){div.svelte-xyz{color:green}}@container test-container (width < 400px){div.svelte-xyz{color:blue}}@container test-container (0 <= width < 300px){div.svelte-xyz{color:purple}}@container not (width < 400px){div.svelte-xyz{color:pink}}@container (width > 400px) and (height > 400px){div.svelte-xyz{color:lightgreen}}@container (width > 400px) or (height > 400px){div.svelte-xyz{color:lightblue}}@container (width > 400px) and (width > 800px) or (orientation: portrait){div.svelte-xyz{color:salmon}}@container style(color: blue){div.svelte-xyz{color:salmon}} div.svelte-xyz{container:test-container / inline-size}@container (min-width: 400px){div.svelte-xyz{color:red}}@container test-container (min-width: 410px){div.svelte-xyz{color:green}}@container test-container (width < 400px){div.svelte-xyz{color:blue}}@container test-container (0 <= width < 300px){div.svelte-xyz{color:purple}}@container not (width < 400px){div.svelte-xyz{color:pink}}@container (width > 400px) and (height > 400px){div.svelte-xyz{color:lightgreen}}@container (width > 400px) or (height > 400px){div.svelte-xyz{color:lightblue}}@container (width > 400px) and (width > 800px) or (orientation: portrait){div.svelte-xyz{color:salmon}}@container style(color: blue){div.svelte-xyz{color:tan}}@container test-container (min-width: calc(400px + 1px)){div.svelte-xyz{color:green}}@container test-container (width < clamp(200px, 40%, 400px)){div.svelte-xyz{color:blue}}@container test-container (calc(400px + 1px) <= width < calc(500px + 1px)){div.svelte-xyz{color:purple}}@container style(--var: calc(400px + 1px)){div.svelte-xyz{color:sandybrown}}

@ -57,7 +57,31 @@
@container style(color: blue) { @container style(color: blue) {
div { div {
color: salmon; color: tan;
}
}
@container test-container (min-width: calc(400px + 1px)) {
div {
color: green;
}
}
@container test-container (width < clamp(200px, 40%, 400px)) {
div {
color: blue;
}
}
@container test-container (calc(400px + 1px) <= width < calc(500px + 1px)) {
div {
color: purple;
}
}
@container style(--var: calc(400px + 1px)) {
div {
color: sandybrown;
} }
} }
</style> </style>

Loading…
Cancel
Save