Skip to content

Commit 2ff457a

Browse files
committed
support var and calc for plain colors
1 parent 2c148c7 commit 2ff457a

File tree

11 files changed

+21798
-82
lines changed

11 files changed

+21798
-82
lines changed

src/main/javacc/CSS3Parser.jj

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2037,6 +2037,9 @@ LexicalUnit rgbColor(LexicalUnit prev) :
20372037
<NONE> { param = LexicalUnitImpl.createNone(null); }
20382038
| param = number(null, op)
20392039
| param = percentage(null, op)
2040+
2041+
| param = calc(null)
2042+
| param = var(null)
20402043
)
20412044
)
20422045
{ op = ' '; next = param; }
@@ -2053,6 +2056,9 @@ LexicalUnit rgbColor(LexicalUnit prev) :
20532056
<NONE> { next = LexicalUnitImpl.createNone(next); }
20542057
| next = number(next, op)
20552058
| next = percentage(next, op)
2059+
2060+
| next = calc(next)
2061+
| next = var(next)
20562062
)
20572063
)
20582064
{ op = ' '; }
@@ -2069,6 +2075,9 @@ LexicalUnit rgbColor(LexicalUnit prev) :
20692075
<NONE> { next = LexicalUnitImpl.createNone(next); }
20702076
| next = number(next, op)
20712077
| next = percentage(next, op)
2078+
2079+
| next = calc(next)
2080+
| next = var(next)
20722081
)
20732082
)
20742083
{ op = ' '; }
@@ -2088,6 +2097,9 @@ LexicalUnit rgbColor(LexicalUnit prev) :
20882097
<NONE> { next = LexicalUnitImpl.createNone(next); }
20892098
| next = number(next, op)
20902099
| next = percentage(next, op)
2100+
2101+
| next = calc(next)
2102+
| next = var(next)
20912103
)
20922104

20932105
( <S> )*
@@ -2207,6 +2219,9 @@ LexicalUnit hslColor(LexicalUnit prev) :
22072219
| t = <ANGLE_RAD> { param = LexicalUnitImpl.createRadian(null, doubleValue(op, t.image)); }
22082220
| t = <ANGLE_GRAD> { param = LexicalUnitImpl.createGradian(null, doubleValue(op, t.image)); }
22092221
| t = <ANGLE_TURN> { param = LexicalUnitImpl.createTurn(null, doubleValue(op, t.image)); }
2222+
2223+
| param = calc(null)
2224+
| param = var(null)
22102225
)
22112226
)
22122227
{ op = ' '; next = param; }
@@ -2222,6 +2237,9 @@ LexicalUnit hslColor(LexicalUnit prev) :
22222237
(
22232238
<NONE> { next = LexicalUnitImpl.createNone(next); }
22242239
| next = percentage(next, op)
2240+
2241+
| next = calc(next)
2242+
| next = var(next)
22252243
)
22262244
)
22272245
{ op = ' '; }
@@ -2237,6 +2255,9 @@ LexicalUnit hslColor(LexicalUnit prev) :
22372255
(
22382256
<NONE> { next = LexicalUnitImpl.createNone(next); }
22392257
| next = percentage(next, op)
2258+
2259+
| next = calc(next)
2260+
| next = var(next)
22402261
)
22412262
)
22422263
{ op = ' '; }
@@ -2256,6 +2277,9 @@ LexicalUnit hslColor(LexicalUnit prev) :
22562277
<NONE> { next = LexicalUnitImpl.createNone(next); }
22572278
| next = number(next, op)
22582279
| next = percentage(next, op)
2280+
2281+
| next = calc(next)
2282+
| next = var(next)
22592283
)
22602284

22612285
( <S> )*
@@ -2376,6 +2400,9 @@ LexicalUnit hwbColor(LexicalUnit prev) :
23762400
| t = <ANGLE_RAD> { param = LexicalUnitImpl.createRadian(null, doubleValue(op, t.image)); }
23772401
| t = <ANGLE_GRAD> { param = LexicalUnitImpl.createGradian(null, doubleValue(op, t.image)); }
23782402
| t = <ANGLE_TURN> { param = LexicalUnitImpl.createTurn(null, doubleValue(op, t.image)); }
2403+
2404+
| param = calc(null)
2405+
| param = var(null)
23792406
)
23802407
)
23812408
{ op = ' '; next = param; }
@@ -2387,6 +2414,9 @@ LexicalUnit hwbColor(LexicalUnit prev) :
23872414
(
23882415
<NONE> { next = LexicalUnitImpl.createNone(next); }
23892416
| next = percentage(next, op)
2417+
2418+
| next = calc(next)
2419+
| next = var(next)
23902420
)
23912421
)
23922422
{ op = ' '; }
@@ -2398,6 +2428,9 @@ LexicalUnit hwbColor(LexicalUnit prev) :
23982428
(
23992429
<NONE> { next = LexicalUnitImpl.createNone(next); }
24002430
| next = percentage(next, op)
2431+
2432+
| next = calc(next)
2433+
| next = var(next)
24012434
)
24022435
)
24032436
{ op = ' '; }
@@ -2414,6 +2447,9 @@ LexicalUnit hwbColor(LexicalUnit prev) :
24142447
<NONE> { next = LexicalUnitImpl.createNone(next); }
24152448
| next = number(next, op)
24162449
| next = percentage(next, op)
2450+
2451+
| next = calc(next)
2452+
| next = var(next)
24172453
)
24182454

24192455
( <S> )*
@@ -2532,6 +2568,9 @@ LexicalUnit labColor(LexicalUnit prev) :
25322568
<NONE> { param = LexicalUnitImpl.createNone(null); }
25332569
| param = number(null, op)
25342570
| param = percentage(null, op)
2571+
2572+
| param = calc(null)
2573+
| param = var(null)
25352574
)
25362575
)
25372576
{ op = ' '; next = param; }
@@ -2544,6 +2583,9 @@ LexicalUnit labColor(LexicalUnit prev) :
25442583
<NONE> { next = LexicalUnitImpl.createNone(next); }
25452584
| next = number(next, op)
25462585
| next = percentage(next, op)
2586+
2587+
| next = calc(next)
2588+
| next = var(next)
25472589
)
25482590
)
25492591
{ op = ' '; }
@@ -2556,6 +2598,9 @@ LexicalUnit labColor(LexicalUnit prev) :
25562598
<NONE> { next = LexicalUnitImpl.createNone(next); }
25572599
| next = number(next, op)
25582600
| next = percentage(next, op)
2601+
2602+
| next = calc(next)
2603+
| next = var(next)
25592604
)
25602605
)
25612606
{ op = ' '; }
@@ -2572,6 +2617,9 @@ LexicalUnit labColor(LexicalUnit prev) :
25722617
<NONE> { next = LexicalUnitImpl.createNone(next); }
25732618
| next = number(next, op)
25742619
| next = percentage(next, op)
2620+
2621+
| next = calc(next)
2622+
| next = var(next)
25752623
)
25762624

25772625
( <S> )*
@@ -2691,6 +2739,9 @@ LexicalUnit lchColor(LexicalUnit prev) :
26912739
<NONE> { param = LexicalUnitImpl.createNone(null); }
26922740
| param = number(null, op)
26932741
| param = percentage(null, op)
2742+
2743+
| param = calc(null)
2744+
| param = var(null)
26942745
)
26952746
)
26962747
{ op = ' '; next = param; }
@@ -2703,6 +2754,9 @@ LexicalUnit lchColor(LexicalUnit prev) :
27032754
<NONE> { next = LexicalUnitImpl.createNone(next); }
27042755
| next = number(next, op)
27052756
| next = percentage(next, op)
2757+
2758+
| next = calc(next)
2759+
| next = var(next)
27062760
)
27072761
)
27082762
{ op = ' '; }
@@ -2717,6 +2771,9 @@ LexicalUnit lchColor(LexicalUnit prev) :
27172771
| t = <ANGLE_RAD> { next = LexicalUnitImpl.createRadian(next, doubleValue(op, t.image)); }
27182772
| t = <ANGLE_GRAD> { next = LexicalUnitImpl.createGradian(next, doubleValue(op, t.image)); }
27192773
| t = <ANGLE_TURN> { next = LexicalUnitImpl.createTurn(next, doubleValue(op, t.image)); }
2774+
2775+
| next = calc(next)
2776+
| next = var(next)
27202777
)
27212778
)
27222779
{ op = ' '; }
@@ -2733,6 +2790,9 @@ LexicalUnit lchColor(LexicalUnit prev) :
27332790
<NONE> { next = LexicalUnitImpl.createNone(next); }
27342791
| next = number(next, op)
27352792
| next = percentage(next, op)
2793+
2794+
| next = calc(next)
2795+
| next = var(next)
27362796
)
27372797

27382798
( <S> )*

src/test/java/org/htmlunit/cssparser/parser/CSS3ParserRealWorldTest.java

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -286,8 +286,8 @@ public void bootstrap_5_2_0() throws Exception {
286286
+ "(prefers-reduced-motion: no-preference);"
287287
+ "(prefers-reduced-motion: reduce);"
288288
+ "print;";
289-
realWorld("realworld/bootstrap_5_2_0.css", 1198, 3033, media, 40, 0);
290-
realWorld("realworld/bootstrap_5_2_0.min.css", 1198, 3033, media, 40, 0);
289+
realWorld("realworld/bootstrap_5_2_0.css", 1198, 3041, media, 32, 0);
290+
realWorld("realworld/bootstrap_5_2_0.min.css", 1198, 3041, media, 32, 0);
291291
}
292292

293293
/**
@@ -388,6 +388,29 @@ public void semantic_2_5_0() throws Exception {
388388
realWorld("realworld/semantic_2_5_0.min.css", 5490, 10072, media, 3, 0);
389389
}
390390

391+
/**
392+
* @throws Exception if any error occurs
393+
*/
394+
@Test
395+
public void bulma_1_0_2() throws Exception {
396+
final String media = "(prefers-color-scheme: dark);"
397+
+ "(prefers-color-scheme: light);"
398+
+ "print;"
399+
+ "screen and (max-width: 1023px);"
400+
+ "screen and (max-width: 1215px);"
401+
+ "screen and (max-width: 1407px);"
402+
+ "screen and (max-width: 768px);"
403+
+ "screen and (min-width: 1024px);"
404+
+ "screen and (min-width: 1024px) and (max-width: 1215px);"
405+
+ "screen and (min-width: 1216px);"
406+
+ "screen and (min-width: 1216px) and (max-width: 1407px);"
407+
+ "screen and (min-width: 1408px);"
408+
+ "screen and (min-width: 769px);"
409+
+ "screen and (min-width: 769px) and (max-width: 1023px);";
410+
realWorld("realworld/bulma_1_0_2.css", 3036, 7226, media, 13, 13);
411+
realWorld("realworld/bulma_1_0_2.min.css", 3011, 7180, media, 13, 13);
412+
}
413+
391414
/**
392415
* @throws Exception if any error occurs
393416
*/

src/test/java/org/htmlunit/cssparser/parser/HSLColorParserTest.java

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ public void hslComma() throws Exception {
4444
color("foreground: hsl(-270, 60%, 70%, 0.1)", "foreground: hsl(-270, 60%, 70%, 0.1)");
4545
color("foreground: hsl(-270, 60%, 70%, 0.1)", "foreground: hsl(-270, 60%, 70%, .1)");
4646
color("foreground: hsl(-270, 60%, 70%, 10%)", "foreground: hsl(-270, 60%, 70%, 10%)");
47+
48+
// var
49+
color("foreground: hsl(var(--v-h), var(--v-s), var(--v-l), var(--v-alpha))", "foreground: hsl(var(--v-h), var(--v-s), var(--v-l), var(--v-alpha))");
50+
51+
// calc
52+
color("foreground: hsl(calc(270), calc(60%), calc(70%), calc(0.1))", "foreground: hsl(calc(270), calc(60%), calc(70%), calc(0.1))");
4753
}
4854

4955
/**
@@ -75,6 +81,12 @@ public void hslBlank() throws Exception {
7581
color("foreground: hsl(-270 60% 70% / 10%)", "foreground: hsl(-270 60% 70% / 10%)");
7682

7783
color("foreground: hsl(-270 60% 70% / none)", "foreground: hsl(-270 60% 70% / none)");
84+
85+
// var
86+
color("foreground: hsl(var(--v-h) var(--v-s) var(--v-l) / var(--v-alpha))", "foreground: hsl(var(--v-h) var(--v-s) var(--v-l) / var(--v-alpha))");
87+
88+
// calc
89+
color("foreground: hsl(calc(270) calc(60%) calc(70%) / calc(0.1))", "foreground: hsl(calc(270) calc(60%) calc(70%) / calc(0.1))");
7890
}
7991

8092
/**
@@ -130,6 +142,12 @@ public void hslaComma() throws Exception {
130142
color("foreground: hsla(-270, 60%, 70%, 0.1)", "foreground: hsla(-270, 60%, 70%, 0.1)");
131143
color("foreground: hsla(-270, 60%, 70%, 0.1)", "foreground: hsla(-270, 60%, 70%, .1)");
132144
color("foreground: hsla(-270, 60%, 70%, 10%)", "foreground: hsla(-270, 60%, 70%, 10%)");
145+
146+
// var
147+
color("foreground: hsla(var(--v-h), var(--v-s), var(--v-l), var(--v-alpha))", "foreground: hsla(var(--v-h), var(--v-s), var(--v-l), var(--v-alpha))");
148+
149+
// calc
150+
color("foreground: hsla(calc(270), calc(60%), calc(70%), calc(0.1))", "foreground: hsla(calc(270), calc(60%), calc(70%), calc(0.1))");
133151
}
134152

135153
/**
@@ -161,6 +179,12 @@ public void hslaBlank() throws Exception {
161179
color("foreground: hsla(-270 60% 70% / 10%)", "foreground: hsla(-270 60% 70% / 10%)");
162180

163181
color("foreground: hsla(-270 60% 70% / none)", "foreground: hsla(-270 60% 70% / none)");
182+
183+
// var
184+
color("foreground: hsla(var(--v-h) var(--v-s) var(--v-l) / var(--v-alpha))", "foreground: hsla(var(--v-h) var(--v-s) var(--v-l) / var(--v-alpha))");
185+
186+
// calc
187+
color("foreground: hsla(calc(270) calc(60%) calc(70%) / calc(0.1))", "foreground: hsla(calc(270) calc(60%) calc(70%) / calc(0.1))");
164188
}
165189

166190
/**
@@ -193,33 +217,33 @@ public void hslVariousErrors() throws Exception {
193217
color("foreground: hsl(10, 20%, 30%, none)", "foreground: hsl(10, 20%, 30%, none)");
194218

195219
color(1, "Error in expression. (Invalid token \"-none\". Was expecting one of: <S>, <NUMBER>, \"none\", \"from\", \"-\", \"+\", "
196-
+ "<ANGLE_DEG>, <ANGLE_RAD>, <ANGLE_GRAD>, <ANGLE_TURN>.)",
220+
+ "<ANGLE_DEG>, <ANGLE_RAD>, <ANGLE_GRAD>, <ANGLE_TURN>, <FUNCTION_CALC>, <FUNCTION_VAR>.)",
197221
"foreground: hsl(-none 20% 30%)");
198-
color(1, "Error in expression. (Invalid token \"-none\". Was expecting one of: <S>, \"none\", \"-\", \"+\", \",\", <PERCENTAGE>.)",
222+
color(1, "Error in expression. (Invalid token \"-none\". Was expecting one of: <S>, \"none\", \"-\", \"+\", \",\", <PERCENTAGE>, <FUNCTION_CALC>, <FUNCTION_VAR>.)",
199223
"foreground: hsl(10 -none 30%)");
200-
color(1, "Error in expression. (Invalid token \"-none\". Was expecting one of: <S>, \"none\", \"-\", \"+\", \",\", <PERCENTAGE>.)",
224+
color(1, "Error in expression. (Invalid token \"-none\". Was expecting one of: <S>, \"none\", \"-\", \"+\", \",\", <PERCENTAGE>, <FUNCTION_CALC>, <FUNCTION_VAR>.)",
201225
"foreground: hsl(10 20% -none)");
202-
color(1, "Error in expression. (Invalid token \"-none\". Was expecting one of: <S>, <NUMBER>, \"none\", \"-\", \"+\", <PERCENTAGE>.)",
226+
color(1, "Error in expression. (Invalid token \"-none\". Was expecting one of: <S>, <NUMBER>, \"none\", \"-\", \"+\", <PERCENTAGE>, <FUNCTION_CALC>, <FUNCTION_VAR>.)",
203227
"foreground: hsl(10 20% 30% / -none)");
204228

205-
color(1, "Error in expression. (Invalid token \")\". Was expecting one of: <S>, <NUMBER>, \"none\", \"from\", \"-\", \"+\", <ANGLE_DEG>, <ANGLE_RAD>, <ANGLE_GRAD>, <ANGLE_TURN>.)",
229+
color(1, "Error in expression. (Invalid token \")\". Was expecting one of: <S>, <NUMBER>, \"none\", \"from\", \"-\", \"+\", <ANGLE_DEG>, <ANGLE_RAD>, <ANGLE_GRAD>, <ANGLE_TURN>, <FUNCTION_CALC>, <FUNCTION_VAR>.)",
206230
"foreground: hsl()");
207-
color(1, "Error in expression. (Invalid token \")\". Was expecting one of: <S>, \"none\", \"-\", \"+\", \",\", <PERCENTAGE>.)",
231+
color(1, "Error in expression. (Invalid token \")\". Was expecting one of: <S>, \"none\", \"-\", \"+\", \",\", <PERCENTAGE>, <FUNCTION_CALC>, <FUNCTION_VAR>.)",
208232
"foreground: hsl(10)");
209-
color(1, "Error in expression. (Invalid token \")\". Was expecting one of: <S>, \"none\", \"-\", \"+\", \",\", <PERCENTAGE>.)",
233+
color(1, "Error in expression. (Invalid token \")\". Was expecting one of: <S>, \"none\", \"-\", \"+\", \",\", <PERCENTAGE>, <FUNCTION_CALC>, <FUNCTION_VAR>.)",
210234
"foreground: hsl(10 20%)");
211235

212-
color(1, "Error in expression. (Invalid token \")\". Was expecting one of: <S>, <NUMBER>, \"none\", \"-\", \"+\", <PERCENTAGE>.)",
236+
color(1, "Error in expression. (Invalid token \")\". Was expecting one of: <S>, <NUMBER>, \"none\", \"-\", \"+\", <PERCENTAGE>, <FUNCTION_CALC>, <FUNCTION_VAR>.)",
213237
"foreground: hsl(10, 20%, 30%,)");
214-
color(1, "Error in expression. (Invalid token \")\". Was expecting one of: <S>, <NUMBER>, \"none\", \"-\", \"+\", <PERCENTAGE>.)",
238+
color(1, "Error in expression. (Invalid token \")\". Was expecting one of: <S>, <NUMBER>, \"none\", \"-\", \"+\", <PERCENTAGE>, <FUNCTION_CALC>, <FUNCTION_VAR>.)",
215239
"foreground: hsl(10, 20%, 30%/)");
216240

217-
color(1, "Error in expression. (Invalid token \"20\". Was expecting one of: <S>, \"none\", \"-\", \"+\", <PERCENTAGE>.)",
241+
color(1, "Error in expression. (Invalid token \"20\". Was expecting one of: <S>, \"none\", \"-\", \"+\", <PERCENTAGE>, <FUNCTION_CALC>, <FUNCTION_VAR>.)",
218242
"foreground: hsl(10, 20px, 30)");
219-
color(1, "Error in expression. (Invalid token \"20\". Was expecting one of: <S>, \"none\", \"-\", \"+\", \",\", <PERCENTAGE>.)",
243+
color(1, "Error in expression. (Invalid token \"20\". Was expecting one of: <S>, \"none\", \"-\", \"+\", \",\", <PERCENTAGE>, <FUNCTION_CALC>, <FUNCTION_VAR>.)",
220244
"foreground: hsl(10 20px 30)");
221245

222-
color(1, "Error in expression. (Invalid token \"10\". Was expecting one of: <S>, <NUMBER>, \"none\", \"from\", \"-\", \"+\", <ANGLE_DEG>, <ANGLE_RAD>, <ANGLE_GRAD>, <ANGLE_TURN>.)",
246+
color(1, "Error in expression. (Invalid token \"10\". Was expecting one of: <S>, <NUMBER>, \"none\", \"from\", \"-\", \"+\", <ANGLE_DEG>, <ANGLE_RAD>, <ANGLE_GRAD>, <ANGLE_TURN>, <FUNCTION_CALC>, <FUNCTION_VAR>.)",
223247
"foreground: hsl('10', 20, 30,)");
224248
}
225249
}

0 commit comments

Comments
 (0)