feat(css/parser): Parse more math functions in @media (#5904)

This commit is contained in:
Alexander Akait 2022-09-20 04:45:49 +03:00 committed by GitHub
parent 8c112c371b
commit 2bf24195f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 3004 additions and 15 deletions

View File

@ -350,6 +350,9 @@ pub enum MediaFeatureValue {
#[tag("Ratio")]
Ratio(Ratio),
#[tag("Function")]
Function(Function),
}
#[ast_node("MediaFeaturePlain")]

View File

@ -538,6 +538,7 @@ where
MediaFeatureValue::Dimension(n) => emit!(self, n),
MediaFeatureValue::Ident(n) => emit!(self, n),
MediaFeatureValue::Ratio(n) => emit!(self, n),
MediaFeatureValue::Function(n) => emit!(self, n),
}
}

View File

@ -69,3 +69,7 @@
@media not (((resolution: -300dpi))) { body { background: green; } }
@media (grid) and (max-width: 15em) { body { background: green; } }
@media (max-width: calc(5px + 1rem)) { body { color: red; } }
@media (-webkit-calc(10px + 100px) < width <= calc(1000px + 10px)) { body { color: red; } }

View File

@ -1 +1 @@
@media print{body{font-size:10pt}}@media print{body{font-size:10pt}}@media(min-width:900px){a{color:red}}@media only screen and (min-width:320px){body{line-height:1.4}}@media(400px<=width<=700px){body{line-height:1.4}}@media screen and (min-width:900px){article{padding:1rem 3rem}}@media(height>600px){body{line-height:1.4}}@media(400px<=width<=700px){body{line-height:1.4}}@media(foo:bar){body{line-height:1.4}}@media(min-width:30em)and (orientation:landscape){.test{color:red}}@media screen and (min-width:30em)and (orientation:landscape){.test{color:red}}@media screen and (min-width:30em)and (max-width:300px)and (orientation:landscape){.test{color:red}}@media(min-height:680px),screen and (orientation:portrait){.test{color:red}}@media(not (color))or (hover){.test{color:red}}@media only screen and ((min-width:320px)and (max-width:1480px)){body{background:red}}@media((min-width:320px)and (max-width:1480px)){body{background:red}}@media((min-width:320px)or (max-width:1480px)){body{background:red}}@media(min-width:320px)and (max-width:1480px)and (orientation:landscape){body{background:red}}@media(min-width:320px)and (max-width:1480px)and (orientation:landscape){body{background:red}}@media(min-width:320px)or (max-width:1480px)or (orientation:landscape){body{background:red}}@media(min-width:320px)or (max-width:1480px)or (orientation:landscape){body{background:red}}@media screen and (min-width:320px)and (max-width:1480px)and (orientation:landscape){body{background:red}}@media screen and (min-width:320px)and (max-width:1480px)and (orientation:landscape){body{background:red}}@media not (resolution:-300dpi){body{background:green}}@media(grid)and (max-width:15em){body{background:green}}
@media print{body{font-size:10pt}}@media print{body{font-size:10pt}}@media(min-width:900px){a{color:red}}@media only screen and (min-width:320px){body{line-height:1.4}}@media(400px<=width<=700px){body{line-height:1.4}}@media screen and (min-width:900px){article{padding:1rem 3rem}}@media(height>600px){body{line-height:1.4}}@media(400px<=width<=700px){body{line-height:1.4}}@media(foo:bar){body{line-height:1.4}}@media(min-width:30em)and (orientation:landscape){.test{color:red}}@media screen and (min-width:30em)and (orientation:landscape){.test{color:red}}@media screen and (min-width:30em)and (max-width:300px)and (orientation:landscape){.test{color:red}}@media(min-height:680px),screen and (orientation:portrait){.test{color:red}}@media(not (color))or (hover){.test{color:red}}@media only screen and ((min-width:320px)and (max-width:1480px)){body{background:red}}@media((min-width:320px)and (max-width:1480px)){body{background:red}}@media((min-width:320px)or (max-width:1480px)){body{background:red}}@media(min-width:320px)and (max-width:1480px)and (orientation:landscape){body{background:red}}@media(min-width:320px)and (max-width:1480px)and (orientation:landscape){body{background:red}}@media(min-width:320px)or (max-width:1480px)or (orientation:landscape){body{background:red}}@media(min-width:320px)or (max-width:1480px)or (orientation:landscape){body{background:red}}@media screen and (min-width:320px)and (max-width:1480px)and (orientation:landscape){body{background:red}}@media screen and (min-width:320px)and (max-width:1480px)and (orientation:landscape){body{background:red}}@media not (resolution:-300dpi){body{background:green}}@media(grid)and (max-width:15em){body{background:green}}@media(max-width:calc(5px + 1rem)){body{color:red}}@media(-webkit-calc(10px + 100px)<width<=calc(1000px + 10px)){body{color:red}}

View File

@ -4,7 +4,7 @@ use swc_css_ast::*;
use super::{input::ParserInput, PResult, Parser};
use crate::{
error::{Error, ErrorKind},
parser::{BlockContentsGrammar, Ctx},
parser::{value::is_math_function, BlockContentsGrammar, Ctx},
Parse,
};
@ -1716,9 +1716,12 @@ where
}
tok!("ident") => Ok(MediaFeatureValue::Ident(self.parse()?)),
tok!("dimension") => Ok(MediaFeatureValue::Dimension(self.parse()?)),
Token::Function { value, .. } if is_math_function(value) => {
Ok(MediaFeatureValue::Function(self.parse()?))
}
_ => Err(Error::new(
span,
ErrorKind::Expected("number, ident or dimension token"),
ErrorKind::Expected("number, ident, dimension or function token"),
)),
}
}

View File

@ -6,7 +6,6 @@ use crate::{
error::{Error, ErrorKind},
Parse,
};
#[cfg(test)]
mod tests;
@ -3034,10 +3033,12 @@ where
}
}
fn is_math_function(name: &str) -> bool {
pub(crate) fn is_math_function(name: &str) -> bool {
matches!(
&*name.to_ascii_lowercase(),
"calc"
| "-moz-calc"
| "-webkit-calc"
| "sin"
| "cos"
| "tan"

View File

@ -129,3 +129,10 @@
}
@media (NOT (color)) OR (hover) {}
@media (width > calc(5px + 1rem)) {}
@media (width < calc(Infinity * 1px)) {}
@media (max-width: calc(5px + 1rem)) {}
@media (width: calc(5px + 1rem)) {}
@media (calc(100px + 10px) < width <= calc(1000px + 10px)) {}
@media (-webkit-calc(10px + 100px) < width <= calc(1000px + 10px)) {}

File diff suppressed because it is too large Load Diff

View File

@ -135,3 +135,9 @@
background: yellow;
}
}
@supports (width: calc(100px + 100px)) {
div {
background: red;
}
}

View File

@ -2,7 +2,7 @@
"type": "Stylesheet",
"span": {
"start": 1,
"end": 3019,
"end": 3104,
"ctxt": 0
},
"rules": [
@ -8141,6 +8141,288 @@
}
]
}
},
{
"type": "AtRule",
"span": {
"start": 3020,
"end": 3103,
"ctxt": 0
},
"name": {
"type": "Ident",
"span": {
"start": 3021,
"end": 3029,
"ctxt": 0
},
"value": "supports",
"raw": "supports"
},
"prelude": {
"type": "SupportsCondition",
"span": {
"start": 3030,
"end": 3058,
"ctxt": 0
},
"conditions": [
{
"type": "Declaration",
"span": {
"start": 3031,
"end": 3057,
"ctxt": 0
},
"name": {
"type": "Ident",
"span": {
"start": 3031,
"end": 3036,
"ctxt": 0
},
"value": "width",
"raw": "width"
},
"value": [
{
"type": "Function",
"span": {
"start": 3038,
"end": 3057,
"ctxt": 0
},
"name": {
"type": "Ident",
"span": {
"start": 3038,
"end": 3042,
"ctxt": 0
},
"value": "calc",
"raw": "calc"
},
"value": [
{
"type": "CalcSum",
"span": {
"start": 3043,
"end": 3056,
"ctxt": 0
},
"expressions": [
{
"type": "CalcProduct",
"span": {
"start": 3043,
"end": 3048,
"ctxt": 0
},
"expressions": [
{
"type": "Length",
"span": {
"start": 3043,
"end": 3048,
"ctxt": 0
},
"value": {
"type": "Number",
"span": {
"start": 3043,
"end": 3046,
"ctxt": 0
},
"value": 100.0,
"raw": "100"
},
"unit": {
"type": "Ident",
"span": {
"start": 3046,
"end": 3048,
"ctxt": 0
},
"value": "px",
"raw": "px"
}
}
]
},
{
"type": "CalcOperator",
"span": {
"start": 3049,
"end": 3050,
"ctxt": 0
},
"value": "+"
},
{
"type": "CalcProduct",
"span": {
"start": 3051,
"end": 3056,
"ctxt": 0
},
"expressions": [
{
"type": "Length",
"span": {
"start": 3051,
"end": 3056,
"ctxt": 0
},
"value": {
"type": "Number",
"span": {
"start": 3051,
"end": 3054,
"ctxt": 0
},
"value": 100.0,
"raw": "100"
},
"unit": {
"type": "Ident",
"span": {
"start": 3054,
"end": 3056,
"ctxt": 0
},
"value": "px",
"raw": "px"
}
}
]
}
]
}
]
}
],
"important": null
}
]
},
"block": {
"type": "SimpleBlock",
"span": {
"start": 3059,
"end": 3103,
"ctxt": 0
},
"name": "{",
"value": [
{
"type": "QualifiedRule",
"span": {
"start": 3065,
"end": 3101,
"ctxt": 0
},
"prelude": {
"type": "SelectorList",
"span": {
"start": 3065,
"end": 3068,
"ctxt": 0
},
"children": [
{
"type": "ComplexSelector",
"span": {
"start": 3065,
"end": 3068,
"ctxt": 0
},
"children": [
{
"type": "CompoundSelector",
"span": {
"start": 3065,
"end": 3068,
"ctxt": 0
},
"nestingSelector": null,
"typeSelector": {
"type": "TagNameSelector",
"span": {
"start": 3065,
"end": 3068,
"ctxt": 0
},
"name": {
"type": "WqName",
"span": {
"start": 3065,
"end": 3068,
"ctxt": 0
},
"prefix": null,
"value": {
"type": "Ident",
"span": {
"start": 3065,
"end": 3068,
"ctxt": 0
},
"value": "div",
"raw": "div"
}
}
},
"subclassSelectors": []
}
]
}
]
},
"block": {
"type": "SimpleBlock",
"span": {
"start": 3069,
"end": 3101,
"ctxt": 0
},
"name": "{",
"value": [
{
"type": "Declaration",
"span": {
"start": 3079,
"end": 3094,
"ctxt": 0
},
"name": {
"type": "Ident",
"span": {
"start": 3079,
"end": 3089,
"ctxt": 0
},
"value": "background",
"raw": "background"
},
"value": [
{
"type": "Ident",
"span": {
"start": 3091,
"end": 3094,
"ctxt": 0
},
"value": "red",
"raw": "red"
}
],
"important": null
}
]
}
}
]
}
}
]
}

View File

@ -137,7 +137,13 @@
134 | | a:focus-visible {
135 | | background: yellow;
136 | | }
137 | `-> }
137 | | }
138 | |
139 | | @supports (width: calc(100px + 100px)) {
140 | | div {
141 | | background: red;
142 | | }
143 | `-> }
`----
x Rule
@ -9081,3 +9087,334 @@
135 | background: yellow;
: ^^^^^^
`----
x Rule
,-[$DIR/tests/fixture/at-rule/supports/input.css:139:1]
139 | ,-> @supports (width: calc(100px + 100px)) {
140 | | div {
141 | | background: red;
142 | | }
143 | `-> }
`----
x AtRule
,-[$DIR/tests/fixture/at-rule/supports/input.css:139:1]
139 | ,-> @supports (width: calc(100px + 100px)) {
140 | | div {
141 | | background: red;
142 | | }
143 | `-> }
`----
x AtRuleName
,-[$DIR/tests/fixture/at-rule/supports/input.css:139:1]
139 | @supports (width: calc(100px + 100px)) {
: ^^^^^^^^
`----
x Ident
,-[$DIR/tests/fixture/at-rule/supports/input.css:139:1]
139 | @supports (width: calc(100px + 100px)) {
: ^^^^^^^^
`----
x SupportsCondition
,-[$DIR/tests/fixture/at-rule/supports/input.css:139:1]
139 | @supports (width: calc(100px + 100px)) {
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
`----
x SupportsConditionType
,-[$DIR/tests/fixture/at-rule/supports/input.css:139:1]
139 | @supports (width: calc(100px + 100px)) {
: ^^^^^^^^^^^^^^^^^^^^^^^^^^
`----
x SupportsInParens
,-[$DIR/tests/fixture/at-rule/supports/input.css:139:1]
139 | @supports (width: calc(100px + 100px)) {
: ^^^^^^^^^^^^^^^^^^^^^^^^^^
`----
x SupportsFeature
,-[$DIR/tests/fixture/at-rule/supports/input.css:139:1]
139 | @supports (width: calc(100px + 100px)) {
: ^^^^^^^^^^^^^^^^^^^^^^^^^^
`----
x Declaration
,-[$DIR/tests/fixture/at-rule/supports/input.css:139:1]
139 | @supports (width: calc(100px + 100px)) {
: ^^^^^^^^^^^^^^^^^^^^^^^^^^
`----
x DeclarationName
,-[$DIR/tests/fixture/at-rule/supports/input.css:139:1]
139 | @supports (width: calc(100px + 100px)) {
: ^^^^^
`----
x Ident
,-[$DIR/tests/fixture/at-rule/supports/input.css:139:1]
139 | @supports (width: calc(100px + 100px)) {
: ^^^^^
`----
x ComponentValue
,-[$DIR/tests/fixture/at-rule/supports/input.css:139:1]
139 | @supports (width: calc(100px + 100px)) {
: ^^^^^^^^^^^^^^^^^^^
`----
x Function
,-[$DIR/tests/fixture/at-rule/supports/input.css:139:1]
139 | @supports (width: calc(100px + 100px)) {
: ^^^^^^^^^^^^^^^^^^^
`----
x Ident
,-[$DIR/tests/fixture/at-rule/supports/input.css:139:1]
139 | @supports (width: calc(100px + 100px)) {
: ^^^^
`----
x ComponentValue
,-[$DIR/tests/fixture/at-rule/supports/input.css:139:1]
139 | @supports (width: calc(100px + 100px)) {
: ^^^^^^^^^^^^^
`----
x CalcSum
,-[$DIR/tests/fixture/at-rule/supports/input.css:139:1]
139 | @supports (width: calc(100px + 100px)) {
: ^^^^^^^^^^^^^
`----
x CalcProductOrOperator
,-[$DIR/tests/fixture/at-rule/supports/input.css:139:1]
139 | @supports (width: calc(100px + 100px)) {
: ^^^^^
`----
x CalcProduct
,-[$DIR/tests/fixture/at-rule/supports/input.css:139:1]
139 | @supports (width: calc(100px + 100px)) {
: ^^^^^
`----
x CalcValueOrOperator
,-[$DIR/tests/fixture/at-rule/supports/input.css:139:1]
139 | @supports (width: calc(100px + 100px)) {
: ^^^^^
`----
x CalcValue
,-[$DIR/tests/fixture/at-rule/supports/input.css:139:1]
139 | @supports (width: calc(100px + 100px)) {
: ^^^^^
`----
x Dimension
,-[$DIR/tests/fixture/at-rule/supports/input.css:139:1]
139 | @supports (width: calc(100px + 100px)) {
: ^^^^^
`----
x Length
,-[$DIR/tests/fixture/at-rule/supports/input.css:139:1]
139 | @supports (width: calc(100px + 100px)) {
: ^^^^^
`----
x Number
,-[$DIR/tests/fixture/at-rule/supports/input.css:139:1]
139 | @supports (width: calc(100px + 100px)) {
: ^^^
`----
x Ident
,-[$DIR/tests/fixture/at-rule/supports/input.css:139:1]
139 | @supports (width: calc(100px + 100px)) {
: ^^
`----
x CalcProductOrOperator
,-[$DIR/tests/fixture/at-rule/supports/input.css:139:1]
139 | @supports (width: calc(100px + 100px)) {
: ^
`----
x CalcOperator
,-[$DIR/tests/fixture/at-rule/supports/input.css:139:1]
139 | @supports (width: calc(100px + 100px)) {
: ^
`----
x CalcProductOrOperator
,-[$DIR/tests/fixture/at-rule/supports/input.css:139:1]
139 | @supports (width: calc(100px + 100px)) {
: ^^^^^
`----
x CalcProduct
,-[$DIR/tests/fixture/at-rule/supports/input.css:139:1]
139 | @supports (width: calc(100px + 100px)) {
: ^^^^^
`----
x CalcValueOrOperator
,-[$DIR/tests/fixture/at-rule/supports/input.css:139:1]
139 | @supports (width: calc(100px + 100px)) {
: ^^^^^
`----
x CalcValue
,-[$DIR/tests/fixture/at-rule/supports/input.css:139:1]
139 | @supports (width: calc(100px + 100px)) {
: ^^^^^
`----
x Dimension
,-[$DIR/tests/fixture/at-rule/supports/input.css:139:1]
139 | @supports (width: calc(100px + 100px)) {
: ^^^^^
`----
x Length
,-[$DIR/tests/fixture/at-rule/supports/input.css:139:1]
139 | @supports (width: calc(100px + 100px)) {
: ^^^^^
`----
x Number
,-[$DIR/tests/fixture/at-rule/supports/input.css:139:1]
139 | @supports (width: calc(100px + 100px)) {
: ^^^
`----
x Ident
,-[$DIR/tests/fixture/at-rule/supports/input.css:139:1]
139 | @supports (width: calc(100px + 100px)) {
: ^^
`----
x SimpleBlock
,-[$DIR/tests/fixture/at-rule/supports/input.css:139:1]
139 | ,-> @supports (width: calc(100px + 100px)) {
140 | | div {
141 | | background: red;
142 | | }
143 | `-> }
`----
x ComponentValue
,-[$DIR/tests/fixture/at-rule/supports/input.css:140:5]
140 | ,-> div {
141 | | background: red;
142 | `-> }
`----
x Rule
,-[$DIR/tests/fixture/at-rule/supports/input.css:140:5]
140 | ,-> div {
141 | | background: red;
142 | `-> }
`----
x QualifiedRule
,-[$DIR/tests/fixture/at-rule/supports/input.css:140:5]
140 | ,-> div {
141 | | background: red;
142 | `-> }
`----
x SelectorList
,-[$DIR/tests/fixture/at-rule/supports/input.css:140:5]
140 | div {
: ^^^
`----
x ComplexSelector
,-[$DIR/tests/fixture/at-rule/supports/input.css:140:5]
140 | div {
: ^^^
`----
x CompoundSelector
,-[$DIR/tests/fixture/at-rule/supports/input.css:140:5]
140 | div {
: ^^^
`----
x TypeSelector
,-[$DIR/tests/fixture/at-rule/supports/input.css:140:5]
140 | div {
: ^^^
`----
x TagNameSelector
,-[$DIR/tests/fixture/at-rule/supports/input.css:140:5]
140 | div {
: ^^^
`----
x WqName
,-[$DIR/tests/fixture/at-rule/supports/input.css:140:5]
140 | div {
: ^^^
`----
x Ident
,-[$DIR/tests/fixture/at-rule/supports/input.css:140:5]
140 | div {
: ^^^
`----
x SimpleBlock
,-[$DIR/tests/fixture/at-rule/supports/input.css:140:5]
140 | ,-> div {
141 | | background: red;
142 | `-> }
`----
x ComponentValue
,-[$DIR/tests/fixture/at-rule/supports/input.css:141:9]
141 | background: red;
: ^^^^^^^^^^^^^^^
`----
x StyleBlock
,-[$DIR/tests/fixture/at-rule/supports/input.css:141:9]
141 | background: red;
: ^^^^^^^^^^^^^^^
`----
x Declaration
,-[$DIR/tests/fixture/at-rule/supports/input.css:141:9]
141 | background: red;
: ^^^^^^^^^^^^^^^
`----
x DeclarationName
,-[$DIR/tests/fixture/at-rule/supports/input.css:141:9]
141 | background: red;
: ^^^^^^^^^^
`----
x Ident
,-[$DIR/tests/fixture/at-rule/supports/input.css:141:9]
141 | background: red;
: ^^^^^^^^^^
`----
x ComponentValue
,-[$DIR/tests/fixture/at-rule/supports/input.css:141:9]
141 | background: red;
: ^^^
`----
x Ident
,-[$DIR/tests/fixture/at-rule/supports/input.css:141:9]
141 | background: red;
: ^^^
`----

View File

@ -1,5 +1,5 @@
x Expected number, ident or dimension token
x Expected number, ident, dimension or function token
,-[$DIR/tests/recovery/at-rule/media/feature-name-2/input.css:1:1]
1 | @media ("string") {}
: ^^^^^^^^

View File

@ -1,5 +1,5 @@
x Expected number, ident or dimension token
x Expected number, ident, dimension or function token
,-[$DIR/tests/recovery/at-rule/media/feature-name/input.css:1:1]
1 | @media ("min-width": 20px) {}
: ^^^^^^^^^^^

View File

@ -1,5 +1,5 @@
x Expected number, ident or dimension token
x Expected number, ident, dimension or function token
,-[$DIR/tests/recovery/at-rule/media/feature-range-1/input.css:1:1]
1 | @media (height << 600px) {}
: ^

View File

@ -1,5 +1,5 @@
x Expected number, ident or dimension token
x Expected number, ident, dimension or function token
,-[$DIR/tests/recovery/at-rule/media/feature-range-2/input.css:1:1]
1 | @media (400px > "width" > 700px) {}
: ^^^^^^^

View File

@ -1,5 +1,5 @@
x Expected number, ident or dimension token
x Expected number, ident, dimension or function token
,-[$DIR/tests/recovery/at-rule/media/feature-range-3/input.css:1:1]
1 | @media (400px > = width > = 700px) {}
: ^

View File

@ -5,7 +5,7 @@
: ^^^
`----
x Expected number, ident or dimension token
x Expected number, ident, dimension or function token
,-[$DIR/tests/recovery/at-rule/media/feature-value-missing/input.css:1:1]
1 | @media screen and (min-width: ) {}
: ^

View File

@ -733,6 +733,7 @@ define!({
Dimension(Dimension),
Ident(Ident),
Ratio(Ratio),
Function(Function),
}
pub struct MediaFeaturePlain {