Skip to content

Commit 85938bc

Browse files
authored
improve detection of calc expressions (#919)
* improve detection of calc expressions * simplify * remove unwanted mutations
1 parent 5312616 commit 85938bc

33 files changed

Lines changed: 419 additions & 36 deletions

File tree

packages/css-calc/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changes to CSS Calc
22

3+
### Unreleased (minor)
4+
5+
- Expose the list of supported math functions.
6+
37
### 1.0.1 (March 25, 2023)
48

59
- Improve case insensitive string matching.

packages/css-calc/dist/index.cjs

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

packages/css-calc/dist/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ import type { conversionOptions } from './options';
33
import { ComponentValue } from '@csstools/css-parser-algorithms';
44
export declare function calc(css: string, options?: conversionOptions): string;
55
export declare function calcFromComponentValues(componentValuesList: Array<Array<ComponentValue>>, options?: conversionOptions): ComponentValue[][];
6+
export declare const mathFunctionNames: Set<string>;

packages/css-calc/dist/index.mjs

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

packages/css-calc/src/functions/cos.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,28 +14,29 @@ export function solveCos(cosNode: FunctionNode, a: TokenNode): Calculation | -1
1414
return - 1;
1515
}
1616

17+
let result = aToken[4].value;
1718
if (aToken[0] === TokenType.Dimension) {
1819
switch (toLowerCaseAZ(aToken[4].unit)) {
1920
case 'rad':
2021
break;
2122
case 'deg':
2223
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
23-
aToken[4].value = convert_deg.get('rad')!(aToken[4].value);
24+
result = convert_deg.get('rad')!(aToken[4].value);
2425
break;
2526
case 'grad':
2627
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
27-
aToken[4].value = convert_grad.get('rad')!(aToken[4].value);
28+
result = convert_grad.get('rad')!(aToken[4].value);
2829
break;
2930
case 'turn':
3031
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
31-
aToken[4].value = convert_turn.get('rad')!(aToken[4].value);
32+
result = convert_turn.get('rad')!(aToken[4].value);
3233
break;
3334
default:
3435
return -1;
3536
}
3637
}
3738

38-
const result = Math.cos(aToken[4].value);
39+
result = Math.cos(result);
3940

4041
return numberToCalculation(cosNode, result);
4142
}

packages/css-calc/src/functions/sin.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,28 +14,29 @@ export function solveSin(sinNode: FunctionNode, a: TokenNode): Calculation | -1
1414
return -1;
1515
}
1616

17+
let result = aToken[4].value;
1718
if (aToken[0] === TokenType.Dimension) {
1819
switch (toLowerCaseAZ(aToken[4].unit)) {
1920
case 'rad':
2021
break;
2122
case 'deg':
2223
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
23-
aToken[4].value = convert_deg.get('rad')!(aToken[4].value);
24+
result = convert_deg.get('rad')!(aToken[4].value);
2425
break;
2526
case 'grad':
2627
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
27-
aToken[4].value = convert_grad.get('rad')!(aToken[4].value);
28+
result = convert_grad.get('rad')!(aToken[4].value);
2829
break;
2930
case 'turn':
3031
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
31-
aToken[4].value = convert_turn.get('rad')!(aToken[4].value);
32+
result = convert_turn.get('rad')!(aToken[4].value);
3233
break;
3334
default:
3435
return -1;
3536
}
3637
}
3738

38-
const result = Math.sin(aToken[4].value);
39+
result = Math.sin(result);
3940

4041
return numberToCalculation(sinNode, result);
4142
}

packages/css-calc/src/functions/tan.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export function solveTan(tanNode: FunctionNode, a: TokenNode): Calculation | -1
1818
const startingValue = aToken[4].value;
1919

2020
let degrees = 0;
21+
let result = aToken[4].value;
2122
if (aToken[0] === TokenType.Dimension) {
2223
switch (toLowerCaseAZ(aToken[4].unit)) {
2324
case 'rad':
@@ -27,19 +28,19 @@ export function solveTan(tanNode: FunctionNode, a: TokenNode): Calculation | -1
2728
case 'deg':
2829
degrees = startingValue;
2930
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
30-
aToken[4].value = convert_deg.get('rad')!(startingValue);
31+
result = convert_deg.get('rad')!(startingValue);
3132
break;
3233
case 'grad':
3334
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
3435
degrees = convert_grad.get('deg')!(startingValue);
3536
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
36-
aToken[4].value = convert_grad.get('rad')!(startingValue);
37+
result = convert_grad.get('rad')!(startingValue);
3738
break;
3839
case 'turn':
3940
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
4041
degrees = convert_turn.get('deg')!(startingValue);
4142
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
42-
aToken[4].value = convert_turn.get('rad')!(startingValue);
43+
result = convert_turn.get('rad')!(startingValue);
4344
break;
4445
default:
4546
return -1;
@@ -50,11 +51,10 @@ export function solveTan(tanNode: FunctionNode, a: TokenNode): Calculation | -1
5051
const timesNinety = degrees / 90;
5152
const isAsymptote = isNinetyMultiple && timesNinety % 2 !== 0;
5253

53-
let result;
5454
if (isAsymptote) {
5555
result = timesNinety > 0 ? Infinity : -Infinity;
5656
} else {
57-
result = Math.tan(aToken[4].value);
57+
result = Math.tan(result);
5858
}
5959

6060
return numberToCalculation(tanNode, result);

packages/css-calc/src/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,6 @@ export function calcFromComponentValues(componentValuesList: Array<Array<Compone
3232
}
3333
});
3434
}
35+
36+
// Exposed so upstream dependents can use the same set of math functions.
37+
export const mathFunctionNames = new Set(mathFunctions.keys());

packages/css-calc/test/basic/test.mjs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,3 +151,8 @@ assert.strictEqual(
151151
calc('calc(10hz + 0.01khz)', { toCanonicalUnits: false }),
152152
'20hz',
153153
);
154+
155+
assert.strictEqual(
156+
calc('sin(90deg)', { toCanonicalUnits: false }),
157+
'1',
158+
);

packages/css-color-parser/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changes to CSS Color Parser
22

3+
### Unreleased (patch)
4+
5+
- Improve the detection of math function in color notations.
6+
37
### 1.1.0 (March 28, 2023)
48

59
- Add a flag to `serializeP3` and `serializeRGB` to skip gamut mapping.

0 commit comments

Comments
 (0)