Skip to content

Commit

Permalink
fix(postcss-ordered-values): incorrect order when using calc for anim…
Browse files Browse the repository at this point in the history
…ation property (#1629)
  • Loading branch information
ota-meshi committed Jun 10, 2024
1 parent edc002b commit f16db94
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 10 deletions.
26 changes: 26 additions & 0 deletions packages/cssnano/test/issue1527.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
'use strict';
const { test } = require('node:test');
const assert = require('node:assert/strict');
const postcss = require('postcss');
const preset = require('cssnano-preset-default');
const nano = require('..');

const fixture = `
.b {
animation: opacity 0ms calc(1000ms);
}
`;

const expected = '.b{animation:opacity 0ms calc(1s)}';

test('it should keep quote', () => {
const processor = postcss([
nano({
preset: preset({ calc: false }),
}),
]);

return processor
.process(fixture, { from: undefined })
.then((r) => assert.strictEqual(r.css, expected));
});
47 changes: 37 additions & 10 deletions packages/postcss-ordered-values/src/rules/animation.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ const { unit } = require('postcss-value-parser');
const { getArguments } = require('cssnano-utils');
const addSpace = require('../lib/addSpace');
const getValue = require('../lib/getValue');
const mathFunctions = require('../lib/mathfunctions.js');

// animation: [ none | <keyframes-name> ] || <time> || <single-timing-function> || <time> || <single-animation-iteration-count> || <single-animation-direction> || <single-animation-fill-mode> || <single-animation-play-state>
const functions = new Set(['steps', 'cubic-bezier', 'frames']);
const keywords = new Set([
const timingFunctions = new Set(['steps', 'cubic-bezier', 'frames']);
const timingKeywords = new Set([
'ease',
'ease-in',
'ease-in-out',
Expand All @@ -28,11 +29,35 @@ const timeUnits = new Set(['ms', 's']);

/**
* @param {string} value
* @param {string} type
* @param {import('postcss-value-parser').Node} node
* @return {false | import('postcss-value-parser').Dimension}
*/
function unitFromNode(value, node) {
if (node.type !== 'function') {
return unit(value);
}
if (mathFunctions.has(value)) {
// If it is a math function, it checks the unit of the parameter and returns it.
for (const param of node.nodes) {
const paramUnit = unitFromNode(param.value.toLowerCase(), param);
if (paramUnit && paramUnit.unit && paramUnit.unit !== '%') {
return paramUnit;
}
}
}
return false;
}

/**
* @param {string} value
* @param {import('postcss-value-parser').Node} node
* @return {boolean}
*/
const isTimingFunction = (value, type) => {
return (type === 'function' && functions.has(value)) || keywords.has(value);
const isTimingFunction = (value, { type }) => {
return (
(type === 'function' && timingFunctions.has(value)) ||
timingKeywords.has(value)
);
};
/**
* @param {string} value
Expand All @@ -57,19 +82,21 @@ const isPlayState = (value) => {
};
/**
* @param {string} value
* @param {import('postcss-value-parser').Node} node
* @return {boolean}
*/
const isTime = (value) => {
const quantity = unit(value);
const isTime = (value, node) => {
const quantity = unitFromNode(value, node);

return quantity && timeUnits.has(quantity.unit);
};
/**
* @param {string} value
* @param {import('postcss-value-parser').Node} node
* @return {boolean}
*/
const isIterationCount = (value) => {
const quantity = unit(value);
const isIterationCount = (value, node) => {
const quantity = unitFromNode(value, node);

return value === 'infinite' || (quantity && !quantity.unit);
};
Expand Down Expand Up @@ -113,7 +140,7 @@ function normalize(args) {
value = value.toLowerCase();

const hasMatch = stateConditions.some(({ property, delegate }) => {
if (delegate(value, type) && !state[property].length) {
if (delegate(value, node) && !state[property].length) {
state[property] = [node, addSpace()];
return true;
}
Expand Down
15 changes: 15 additions & 0 deletions packages/postcss-ordered-values/test/rules.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const assert = require('node:assert/strict');
const valueParser = require('postcss-value-parser');
const normalizeBorder = require('../src/rules/border.js');
const normalizeBoxShadow = require('../src/rules/boxShadow.js');
const normalizeAnimation = require('../src/rules/animation.js');

test('border order handles max', () => {
assert.strictEqual(
Expand All @@ -27,3 +28,17 @@ test('ordering box shadows handles functions in box shadows', () => {
'inset 0 min(1em, 1px) 0 1px red'
);
});

test('animation order handles calc', () => {
assert.strictEqual(
normalizeAnimation(valueParser('0ms opacity calc(1ms)')),
'opacity 0ms calc(1ms)'
);
});

test('animation order handles max', () => {
assert.strictEqual(
normalizeAnimation(valueParser('0ms opacity max(-1 * 1ms, 1ms)')),
'opacity 0ms max(-1 * 1ms, 1ms)'
);
});

0 comments on commit f16db94

Please sign in to comment.