Skip to content

Commit b72d7c9

Browse files
committed
fix math functions containing variables, this fixes #412
1 parent fbe43c5 commit b72d7c9

File tree

3 files changed

+152
-17
lines changed

3 files changed

+152
-17
lines changed

org/w3c/css/values/CssCalc.java

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,6 @@ public final int getType() {
3939
boolean hasParen = false;
4040
String _toString = null;
4141
boolean implicit_function = true;
42-
boolean contains_variable = false;
43-
4442

4543
/**
4644
* Create a new CssCalc
@@ -72,14 +70,6 @@ public CssCalc(ApplContext ac, CssValue value) {
7270
val1 = value;
7371
}
7472

75-
public boolean hasCssVariable() {
76-
return contains_variable;
77-
}
78-
79-
public void markCssVariable() {
80-
contains_variable = true;
81-
}
82-
8373
public void setImplicitFunction(boolean v) {
8474
implicit_function = v;
8575
_toString = null;

org/w3c/css/values/CssCheckableValue.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,15 @@ public abstract class CssCheckableValue extends CssValue {
2121

2222
abstract public boolean isZero();
2323

24+
boolean contains_variable = false;
25+
26+
public boolean hasCssVariable() {
27+
return contains_variable;
28+
}
29+
30+
public void markCssVariable() {
31+
contains_variable = true;
32+
}
2433

2534
/**
2635
* check if the value is positive or null

org/w3c/css/values/CssMathFunction.java

Lines changed: 143 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)