Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions .oxlintrc.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
{
"$schema": "./node_modules/oxlint/configuration_schema.json",
"plugins": ["typescript", "unicorn", "oxc"],
"plugins": ["typescript", "unicorn", "oxc", "promise"],
"categories": {
"correctness": "error"
},
"rules": {
"array-callback-return": "error",
"complexity": ["error", { "max": 25 }],
"guard-for-in": "error",
"no-duplicate-imports": "error",
"no-bitwise": "error",
"no-case-declarations": "error",
"no-empty": "error",
Expand All @@ -17,11 +18,26 @@
"no-prototype-builtins": "error",
"no-redeclare": "error",
"no-regex-spaces": "error",
"no-underscore-dangle": ["error", { "allow": ["_default"] }],
"no-shadow": "error",
"no-throw-literal": "error",
"no-unnecessary-await": "error",
"no-void": "error",
"no-useless-assignment": "error",
"only-throw-error": "error",
"prefer-const": ["error", { "destructuring": "all" }],
"preserve-caught-error": "error",
"promise/always-return": "error",
"promise/prefer-await-to-then": "error",
"unicorn/no-array-for-each": "error",
"unicorn/no-array-reduce": "error",
"unicorn/prefer-array-flat": "error"
"unicorn/prefer-array-flat": "error",
"unicorn/prefer-includes": "error",
"unicorn/prefer-node-protocol": "error",
"unicorn/prefer-regexp-test": "error",
"unicorn/prefer-set-has": "error",
"unicorn/prefer-type-error": "error",
"unicorn/prefer-number-properties": "error"
},
"env": {
"builtin": true
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@
"@rmenke/css-tokenizer-tests": "^1.2.0",
"@types/node": "^26.2.0",
"fast-check": "^4.9.0",
"oxfmt": "^0.63.0",
"oxlint": "^1.78.0",
"oxfmt": "^0.64.0",
"oxlint": "^1.79.0",
"postcss": "^8.5.26",
"typescript": "~7.0.2"
},
Expand Down
326 changes: 163 additions & 163 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion scripts/tokenizer-compat.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export function fromOurs(tokens) {
if (t.type === 'number' || t.type === 'dimension') {
out.push({
type: t.type,
num: parseFloat(t.value),
num: Number.parseFloat(t.value),
unit: t.unit,
raw: `${t.value}${t.unit ?? ''}`,
ws: t.ws,
Expand Down
6 changes: 3 additions & 3 deletions src/lib/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ function foldCalcKeyword(name) {
// form arrives as a single ident because CSS Syntax tokenizes leading
// `-` + ident-start as one ident-token.
if (name === 'NaN' || name === '-NaN') {
return { type: 'Num', value: NaN };
return { type: 'Num', value: Number.NaN };
}
switch (name.toLowerCase()) {
case 'pi':
Expand Down Expand Up @@ -228,12 +228,12 @@ function requireSurroundingWs(p, token) {

/** @type {Record<string, PrefixParselet>} */
const PREFIX = {
number: (_p, t) => ({ type: 'Num', value: parseFloat(t.value) }),
number: (_p, t) => ({ type: 'Num', value: Number.parseFloat(t.value) }),

// Unit case normalization per §10.12: `1PX` serializes as `1px`.
dimension: (_p, t) => ({
type: 'Dim',
value: parseFloat(t.value),
value: Number.parseFloat(t.value),
unit: t.unit === '%' ? '%' : /** @type {string} */ (t.unit).toLowerCase(),
}),

Expand Down
10 changes: 5 additions & 5 deletions src/lib/serialize.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,15 @@ function round(v, prec) {
* @return {boolean}
*/
function isDegenerate(v) {
return !isFinite(v) || isNaN(v);
return !Number.isFinite(v) || Number.isNaN(v);
}

/**
* @param {number} v
* @return {string}
*/
function degenerateKeyword(v) {
if (isNaN(v)) {
if (Number.isNaN(v)) {
return 'NaN';
}
return v > 0 ? 'infinity' : '-infinity';
Expand Down Expand Up @@ -160,13 +160,13 @@ function serializeExpr(node, prec) {
*/
function displaySign(term) {
const { sign, node } = term;
if (node.type === 'Num' && isFinite(node.value) && node.value < 0) {
if (node.type === 'Num' && Number.isFinite(node.value) && node.value < 0) {
return {
sign: /** @type {1 | -1} */ (-sign),
magnitude: { type: 'Num', value: -node.value },
};
}
if (node.type === 'Dim' && isFinite(node.value) && node.value < 0) {
if (node.type === 'Dim' && Number.isFinite(node.value) && node.value < 0) {
return {
sign: /** @type {1 | -1} */ (-sign),
magnitude: { type: 'Dim', value: -node.value, unit: node.unit },
Expand Down Expand Up @@ -219,7 +219,7 @@ function serializeLeadingNeg(node, prec) {
node.factors.length > 0 &&
node.factors[0].exponent === 1 &&
node.factors[0].node.type === 'Num' &&
isFinite(node.factors[0].node.value) &&
Number.isFinite(node.factors[0].node.value) &&
node.factors[0].node.value !== 0
) {
const head = node.factors[0].node;
Expand Down
4 changes: 2 additions & 2 deletions src/lib/simplify/atan2.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ function simplifyAtan2(args) {
}
const [y, x] = /** @type {[number, number]} */ (fold.values);
const radians = Math.atan2(y, x);
if (isNaN(radians)) {
return num(NaN);
if (Number.isNaN(radians)) {
return num(Number.NaN);
}
return dim((radians * 180) / Math.PI, 'deg');
}
Expand Down
4 changes: 2 additions & 2 deletions src/lib/simplify/inverse-trig.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ function simplifyInverseTrig(name, args) {
return call(name, args);
}
const radians = INVERSE_TRIG_OPS[name](a.value);
if (isNaN(radians)) {
return num(NaN);
if (Number.isNaN(radians)) {
return num(Number.NaN);
}
return dim((radians * 180) / Math.PI, 'deg');
}
Expand Down
14 changes: 7 additions & 7 deletions src/lib/simplify/mod-rem.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ function simplifyModRem(name, args) {
const result = applyModRem(name, a, b);
// NaN results drop the unit (`mod(5px, 0px)` → `calc(NaN)`, not
// `calc(NaN * 1px)`). §10.12 unit-preserving form is a known divergence.
if (isNaN(result)) {
return num(NaN);
if (Number.isNaN(result)) {
return num(Number.NaN);
}
return fold.unit === '' ? num(result) : dim(result, fold.unit);
}
Expand All @@ -34,16 +34,16 @@ function simplifyModRem(name, args) {
*/
function applyModRem(name, a, b) {
if (b === 0) {
return NaN;
return Number.NaN;
}
if (!isFinite(a)) {
return NaN;
if (!Number.isFinite(a)) {
return Number.NaN;
}
if (!isFinite(b)) {
if (!Number.isFinite(b)) {
// mod: result is NaN when A has opposite sign to B; otherwise A.
// rem: result is A regardless of signs.
if (name === 'mod' && a !== 0 && Math.sign(a) !== Math.sign(b)) {
return NaN;
return Number.NaN;
}
return a;
}
Expand Down
16 changes: 8 additions & 8 deletions src/lib/simplify/round.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,12 @@ function simplifyRound(args) {
// case folds to ±0 carrying A's sign. Infinite-A / finite-B falls through
// to applyRound, where floor*b===ceil*b===±∞ collapses back to A
// (§10.3.1 "result is the same infinity").
if (isNaN(b)) {
return num(NaN);
if (Number.isNaN(b)) {
return num(Number.NaN);
}
if (!isFinite(b)) {
if (!isFinite(a)) {
return num(NaN);
if (!Number.isFinite(b)) {
if (!Number.isFinite(a)) {
return num(Number.NaN);
}
let result;
if (strategy === 'up' && a > 0) {
Expand All @@ -62,8 +62,8 @@ function simplifyRound(args) {
}

const result = applyRound(strategy, a, b);
if (isNaN(result)) {
return num(NaN);
if (Number.isNaN(result)) {
return num(Number.NaN);
}
return fold.unit === '' ? num(result) : dim(result, fold.unit);
}
Expand All @@ -90,7 +90,7 @@ function argsForRoundFold(args) {
*/
function applyRound(strategy, a, b) {
if (b === 0) {
return NaN;
return Number.NaN;
}
const q = a / b;
const c1 = Math.floor(q) * b;
Expand Down
2 changes: 1 addition & 1 deletion test/conformance/csstools.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ test('csstools pow: pow(2, 3) → 8', () => {
});
test('csstools pow: pow(8, 1 / 3) ≈ 2', () => {
// csstools agrees on the cube-root identity within FP precision.
const got = parseFloat(out('pow(8, 1 / 3)'));
const got = Number.parseFloat(out('pow(8, 1 / 3)'));
assert.ok(Math.abs(got - 2) < 1e-9, `got ${got}`);
});
test('csstools sqrt: sqrt(16) → 4', () => {
Expand Down
4 changes: 2 additions & 2 deletions test/helpers/arbitraries.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ const floatLeafArb = fc.oneof(floatNumLeaf, floatDimLeaf);
// lives in unit tests; mixing them in differential adds noise without
// adding signal.
const degenerateNumLeaf = fc
.constantFrom(Infinity, -Infinity, NaN, 0)
.constantFrom(Infinity, -Infinity, Number.NaN, 0)
.map((v) => ({ type: 'Num', value: v }));
const degenerateDimLeaf = fc
.tuple(
fc.constantFrom(Infinity, -Infinity, NaN),
fc.constantFrom(Infinity, -Infinity, Number.NaN),
fc.constantFrom(...KNOWN_UNITS)
)
.map(([v, u]) => ({ type: 'Dim', value: v, unit: u }));
Expand Down
Loading
Loading