@@ -215,6 +215,9 @@ private void _computeResultingTypeOneNum(boolean is_final)
215215 valtype = values .get (0 ).getType ();
216216 if (valtype == CssTypes .CSS_NUMBER ) {
217217 computed_type = CssTypes .CSS_NUMBER ;
218+ } else if (valtype == CssTypes .CSS_VARIABLE ) {
219+ markCssVariable ();
220+ computed_type = valtype ;
218221 } else {
219222 throw new InvalidParamException ("incompatibletypes" , toString (), ac );
220223 }
@@ -230,6 +233,19 @@ private void _computeResultingTypeTwoNum(boolean is_final)
230233 valtype2 = values .get (1 ).getType ();
231234 if ((valtype1 == CssTypes .CSS_NUMBER ) && (valtype2 == CssTypes .CSS_NUMBER )) {
232235 computed_type = CssTypes .CSS_NUMBER ;
236+ } else if ((valtype1 == CssTypes .CSS_VARIABLE ) || (valtype2 == CssTypes .CSS_VARIABLE )) {
237+ if (valtype1 == CssTypes .CSS_VARIABLE ) {
238+ if ((valtype2 == CssTypes .CSS_NUMBER ) || (valtype2 == CssTypes .CSS_VARIABLE )) {
239+ computed_type = valtype2 ;
240+ } else {
241+ // one type is not NUMBER
242+ throw new InvalidParamException ("incompatibletypes" , toString (), ac );
243+ }
244+ } else if (valtype1 == CssTypes .CSS_NUMBER ) {
245+ computed_type = valtype1 ;
246+ } else {
247+ throw new InvalidParamException ("incompatibletypes" , toString (), ac );
248+ }
233249 } else {
234250 throw new InvalidParamException ("incompatibletypes" , toString (), ac );
235251 }
@@ -243,16 +259,29 @@ private void _computeResultingTypeTwoNumOpt(boolean is_final)
243259 throw new InvalidParamException ("unrecognize" , ac );
244260 }
245261 valtype = values .get (0 ).getType ();
246- if (valtype != CssTypes .CSS_NUMBER ) {
247- throw new InvalidParamException ("incompatibletypes" , toString (), ac );
262+ if (valtype == CssTypes .CSS_NUMBER ) {
263+ computed_type = valtype ;
264+ } else {
265+ if (valtype == CssTypes .CSS_VARIABLE ) {
266+ markCssVariable ();
267+ computed_type = CssTypes .CSS_VARIABLE ;
268+ } else {
269+ throw new InvalidParamException ("incompatibletypes" , toString (), ac );
270+ }
248271 }
249272 if (values .size () > 1 ) {
250273 valtype = values .get (1 ).getType ();
274+ // computed type is set, just verify that it matches
251275 if (valtype != CssTypes .CSS_NUMBER ) {
252- throw new InvalidParamException ("incompatibletypes" , toString (), ac );
276+ if (valtype == CssTypes .CSS_VARIABLE ) {
277+ if (computed_type != valtype ) {
278+ markCssVariable ();
279+ }
280+ } else {
281+ throw new InvalidParamException ("incompatibletypes" , toString (), ac );
282+ }
253283 }
254284 }
255- computed_type = CssTypes .CSS_NUMBER ;
256285 }
257286
258287 private void _computeResultingTypeAtan2 (boolean is_final )
@@ -263,6 +292,32 @@ private void _computeResultingTypeAtan2(boolean is_final)
263292 }
264293 valtype1 = values .get (0 ).getType ();
265294 valtype2 = values .get (1 ).getType ();
295+ if ((valtype1 == CssTypes .CSS_VARIABLE ) || (valtype2 == CssTypes .CSS_VARIABLE )) {
296+ markCssVariable ();
297+ if (valtype1 != CssTypes .CSS_VARIABLE ) {
298+ if (valtype1 != CssTypes .CSS_PERCENTAGE &&
299+ valtype1 != CssTypes .CSS_LENGTH &&
300+ valtype1 != CssTypes .CSS_NUMBER ) {
301+ throw new InvalidParamException ("incompatibletypes" , toString (), ac );
302+ }
303+ } else if (valtype2 != CssTypes .CSS_VARIABLE ) {
304+ if (valtype2 != CssTypes .CSS_PERCENTAGE &&
305+ valtype2 != CssTypes .CSS_LENGTH &&
306+ valtype2 != CssTypes .CSS_NUMBER ) {
307+ throw new InvalidParamException ("incompatibletypes" , toString (), ac );
308+ }
309+ } else {
310+ // both are variables.
311+ computed_type = valtype1 ;
312+ }
313+ computed_type = CssTypes .CSS_ANGLE ;
314+ return ;
315+ }
316+ if (valtype1 != CssTypes .CSS_PERCENTAGE &&
317+ valtype1 != CssTypes .CSS_LENGTH &&
318+ valtype1 != CssTypes .CSS_NUMBER ) {
319+ throw new InvalidParamException ("incompatibletypes" , toString (), ac );
320+ }
266321 if (valtype1 == valtype2 ) {
267322 computed_type = CssTypes .CSS_ANGLE ;
268323 } else {
@@ -287,10 +342,30 @@ private void _computeResultingTypeRound(boolean is_final)
287342 valtype1 = CssTypes .CSS_NUMBER ;
288343 } catch (Exception ignored ) {
289344 }
345+ } else if (valtype1 == CssTypes .CSS_VARIABLE ) {
346+ markCssVariable ();
347+ valtype2 = values .get (1 ).getType ();
348+ if (valtype2 == CssTypes .CSS_VARIABLE ) {
349+ computed_type = valtype1 ;
350+ return ;
351+ } else {
352+ if (valtype2 != CssTypes .CSS_PERCENTAGE &&
353+ valtype2 != CssTypes .CSS_LENGTH &&
354+ valtype2 != CssTypes .CSS_NUMBER ) {
355+ throw new InvalidParamException ("incompatibletypes" , toString (), ac );
356+ }
357+ computed_type = valtype2 ;
358+ return ;
359+ }
360+ } else if (valtype1 != CssTypes .CSS_PERCENTAGE &&
361+ valtype1 != CssTypes .CSS_LENGTH &&
362+ valtype1 != CssTypes .CSS_NUMBER ) {
363+ throw new InvalidParamException ("incompatibletypes" , toString (), ac );
290364 }
291365 valtype2 = values .get (1 ).getType ();
292366 } else { // 3 values
293367 CssValue v = values .get (0 );
368+ // FIXME TODO need to care about rounding type being an unresolved var() ?
294369 if (v .getType () != CssTypes .CSS_IDENT ) {
295370 throw new InvalidParamException ("incompatibletypes" , toString (), ac );
296371 }
@@ -300,19 +375,47 @@ private void _computeResultingTypeRound(boolean is_final)
300375 valtype1 = values .get (1 ).getType ();
301376 valtype2 = values .get (2 ).getType ();
302377 }
303- if (valtype1 == valtype2 ) {
378+ if (valtype1 == CssTypes .CSS_VARIABLE ) {
379+ markCssVariable ();
380+ if (valtype2 == CssTypes .CSS_VARIABLE ) {
381+ computed_type = valtype1 ;
382+ return ;
383+ } else {
384+ if (valtype2 != CssTypes .CSS_PERCENTAGE &&
385+ valtype2 != CssTypes .CSS_LENGTH &&
386+ valtype2 != CssTypes .CSS_NUMBER ) {
387+ throw new InvalidParamException ("incompatibletypes" , toString (), ac );
388+ }
389+ computed_type = valtype2 ;
390+ return ;
391+ }
392+ } else if (valtype2 == CssTypes .CSS_VARIABLE ) {
393+ markCssVariable ();
394+ if (valtype1 != CssTypes .CSS_PERCENTAGE &&
395+ valtype1 != CssTypes .CSS_LENGTH &&
396+ valtype1 != CssTypes .CSS_NUMBER ) {
397+ throw new InvalidParamException ("incompatibletypes" , toString (), ac );
398+ }
399+ computed_type = valtype1 ;
400+ return ;
401+ }
402+ if ((valtype1 == valtype2 ) && (valtype1 == CssTypes .CSS_PERCENTAGE ||
403+ valtype1 == CssTypes .CSS_LENGTH ||
404+ valtype1 == CssTypes .CSS_NUMBER )) {
304405 computed_type = valtype1 ;
305406 } else {
306407 throw new InvalidParamException ("incompatibletypes" , toString (), ac );
307408 }
308-
309409 }
310410
311411 private void _computeResultingTypeSign (boolean is_final )
312412 throws InvalidParamException {
313413 if (values .size () > 1 ) {
314414 throw new InvalidParamException ("unrecognize" , ac );
315415 }
416+ if (values .get (0 ).getType () == CssTypes .CSS_VARIABLE ) {
417+ markCssVariable ();
418+ }
316419 computed_type = CssTypes .CSS_NUMBER ;
317420 }
318421
@@ -323,6 +426,9 @@ private void _computeResultingTypeOneAny(boolean is_final)
323426 throw new InvalidParamException ("unrecognize" , ac );
324427 }
325428 valtype = values .get (0 ).getType ();
429+ if (valtype == CssTypes .CSS_VARIABLE ) {
430+ markCssVariable ();
431+ }
326432 computed_type = valtype ;
327433 }
328434
@@ -334,6 +440,18 @@ private void _computeResultingTypeTwoAny(boolean is_final)
334440 }
335441 valtype1 = values .get (0 ).getType ();
336442 valtype2 = values .get (1 ).getType ();
443+ if ((valtype1 == CssTypes .CSS_VARIABLE ) || (valtype2 == CssTypes .CSS_VARIABLE )) {
444+ markCssVariable ();
445+ if (valtype1 != CssTypes .CSS_VARIABLE ) {
446+ computed_type = valtype1 ;
447+ } else if (valtype2 != CssTypes .CSS_VARIABLE ) {
448+ computed_type = valtype2 ;
449+ } else {
450+ // default to CssVariable
451+ computed_type = valtype1 ;
452+ }
453+ return ;
454+ }
337455 if (valtype1 == valtype2 ) {
338456 computed_type = valtype1 ;
339457 } else {
@@ -348,7 +466,15 @@ private void _computeResultingTypeTrig(boolean is_final)
348466 throw new InvalidParamException ("unrecognize" , ac );
349467 }
350468 valtype = values .get (0 ).getType ();
351- if ((valtype == CssTypes .CSS_NUMBER ) || (valtype == CssTypes .CSS_ANGLE )) {
469+ if (valtype == CssTypes .CSS_VARIABLE ) {
470+ markCssVariable ();
471+ if (prefix .startsWith ("a" )) {
472+ computed_type = CssTypes .CSS_ANGLE ;
473+ } else {
474+ computed_type = CssTypes .CSS_NUMBER ;
475+ }
476+ } else if ((valtype == CssTypes .CSS_NUMBER ) || (valtype == CssTypes .CSS_ANGLE )) {
477+ // FIXME should check cos(angle | 0) and acos(number) to be more precise
352478 if (prefix .startsWith ("a" )) {
353479 computed_type = CssTypes .CSS_ANGLE ;
354480 } else {
@@ -368,6 +494,11 @@ private void _computeResultingTypeList(boolean is_final)
368494 for (CssValue v : values ) {
369495 if (firstVal ) {
370496 valtype = v .getType ();
497+ // Variable? defer to the next type
498+ if (valtype == CssTypes .CSS_VARIABLE ) {
499+ markCssVariable ();
500+ continue ;
501+ }
371502 _checkAcceptableType (valtype );
372503 computed_type = valtype ;
373504 firstVal = false ;
@@ -393,6 +524,11 @@ private void _computeResultingTypeList(boolean is_final)
393524 if (v .getType () == CssTypes .CSS_NUMBER && v .getNumber ().isZero ()) {
394525 continue ;
395526 }
527+ // if it is a variable without a computed type, skip it
528+ if ((v .getType () == CssTypes .CSS_VARIABLE ) || (v .getRawType () == CssTypes .CSS_VARIABLE )) {
529+ markCssVariable ();
530+ continue ;
531+ }
396532 throw new InvalidParamException ("incompatibletypes" , toStringUnprefixed (), ac );
397533 }
398534 }
0 commit comments