postcss-normalize-timing-functions 8.0.2 → 8.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +7 -4
  2. package/src/index.js +73 -63
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "postcss-normalize-timing-functions",
3
- "version": "8.0.2",
3
+ "version": "8.0.4",
4
4
  "description": "Normalize CSS animation/transition timing functions.",
5
5
  "exports": {
6
6
  ".": {
@@ -28,7 +28,7 @@
28
28
  },
29
29
  "repository": {
30
30
  "type": "git",
31
- "url": "cssnano/cssnano"
31
+ "url": "git+https://github.com/cssnano/cssnano.git"
32
32
  },
33
33
  "bugs": {
34
34
  "url": "https://github.com/cssnano/cssnano/issues"
@@ -38,9 +38,12 @@
38
38
  "node": "^22.11.0 || ^24.11.0 || >=26.0"
39
39
  },
40
40
  "devDependencies": {
41
- "postcss": "^8.5.25"
41
+ "postcss": "^8.5.26"
42
42
  },
43
43
  "peerDependencies": {
44
- "postcss": "^8.5.25"
44
+ "postcss": "^8.5.26"
45
+ },
46
+ "scripts": {
47
+ "test": "node --test"
45
48
  }
46
49
  }
package/src/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  const valueParser = require('postcss-value-parser');
3
3
 
4
4
  /** @type {(node: valueParser.Node) => number} */
5
- const getValue = (node) => parseFloat(node.value);
5
+ const getValue = (node) => Number.parseFloat(node.value);
6
6
  const animationTransitionRegex =
7
7
  /^(-\w+-)?(animation|transition)(-timing-function)?$/i;
8
8
 
@@ -31,76 +31,86 @@ function reduce(node) {
31
31
  const lowerCasedValue = node.value.toLowerCase();
32
32
 
33
33
  if (lowerCasedValue === 'steps') {
34
- // Don't bother checking the step-end case as it has the same length
35
- // as steps(1)
36
- if (
37
- node.nodes[0].type === 'word' &&
38
- getValue(node.nodes[0]) === 1 &&
39
- node.nodes[2] &&
40
- node.nodes[2].type === 'word' &&
41
- (node.nodes[2].value.toLowerCase() === 'start' ||
42
- node.nodes[2].value.toLowerCase() === 'jump-start')
43
- ) {
44
- /** @type string */ (node.type) = 'word';
45
- node.value = 'step-start';
46
-
47
- delete (/** @type Partial<valueParser.FunctionNode> */ (node).nodes);
48
-
49
- return;
50
- }
51
-
52
- if (
53
- node.nodes[0].type === 'word' &&
54
- getValue(node.nodes[0]) === 1 &&
55
- node.nodes[2] &&
56
- node.nodes[2].type === 'word' &&
57
- (node.nodes[2].value.toLowerCase() === 'end' ||
58
- node.nodes[2].value.toLowerCase() === 'jump-end')
59
- ) {
60
- /** @type string */ (node.type) = 'word';
61
- node.value = 'step-end';
62
-
63
- delete (/** @type Partial<valueParser.FunctionNode> */ (node).nodes);
64
-
65
- return;
66
- }
67
-
68
- // The end case is actually the browser default, so it isn't required.
69
- if (
70
- node.nodes[2] &&
71
- node.nodes[2].type === 'word' &&
72
- (node.nodes[2].value.toLowerCase() === 'end' ||
73
- node.nodes[2].value.toLowerCase() === 'jump-end')
74
- ) {
75
- node.nodes = [node.nodes[0]];
76
-
77
- return;
78
- }
79
-
80
- return false;
34
+ return normalizeSteps(node);
81
35
  }
82
36
 
83
37
  if (lowerCasedValue === 'cubic-bezier') {
84
- const values = node.nodes
85
- .filter((list, index) => {
86
- return index % 2 === 0;
87
- })
88
- .map(getValue);
38
+ return normalizeCubicBezier(node);
39
+ }
40
+ }
41
+
42
+ /**
43
+ * @param {valueParser.FunctionNode} node
44
+ * @return {void | false}
45
+ */
46
+ function normalizeSteps(node) {
47
+ const count = node.nodes[0];
48
+ const position = node.nodes[2];
49
+ const isSingleStep = count.type === 'word' && getValue(count) === 1;
89
50
 
90
- if (values.length !== 4) {
91
- return;
92
- }
51
+ if (isSingleStep && isStepPosition(position, 'start', 'jump-start')) {
52
+ /** @type string */ (node.type) = 'word';
53
+ node.value = 'step-start';
93
54
 
94
- const match = conversions.get(values.toString());
55
+ delete (/** @type Partial<valueParser.FunctionNode> */ (node).nodes);
56
+
57
+ return;
58
+ }
59
+
60
+ if (isSingleStep && isStepPosition(position, 'end', 'jump-end')) {
61
+ /** @type string */ (node.type) = 'word';
62
+ node.value = 'step-end';
63
+
64
+ delete (/** @type Partial<valueParser.FunctionNode> */ (node).nodes);
65
+
66
+ return;
67
+ }
68
+
69
+ // The end case is actually the browser default, so it isn't required.
70
+ if (isStepPosition(position, 'end', 'jump-end')) {
71
+ node.nodes = [count];
72
+
73
+ return;
74
+ }
75
+
76
+ return false;
77
+ }
78
+
79
+ /**
80
+ * @param {valueParser.Node | undefined} node
81
+ * @param {string} first
82
+ * @param {string} second
83
+ * @return {boolean}
84
+ */
85
+ function isStepPosition(node, first, second) {
86
+ return (
87
+ node?.type === 'word' &&
88
+ (node.value.toLowerCase() === first || node.value.toLowerCase() === second)
89
+ );
90
+ }
91
+
92
+ /**
93
+ * @param {valueParser.FunctionNode} node
94
+ * @return {void}
95
+ */
96
+ function normalizeCubicBezier(node) {
97
+ const values = node.nodes
98
+ .filter((list, index) => {
99
+ return index % 2 === 0;
100
+ })
101
+ .map(getValue);
102
+
103
+ if (values.length !== 4) {
104
+ return;
105
+ }
95
106
 
96
- if (match) {
97
- /** @type string */ (node.type) = 'word';
98
- node.value = match;
107
+ const match = conversions.get(values.toString());
99
108
 
100
- delete (/** @type Partial<valueParser.FunctionNode> */ (node).nodes);
109
+ if (match) {
110
+ /** @type string */ (node.type) = 'word';
111
+ node.value = match;
101
112
 
102
- return;
103
- }
113
+ delete (/** @type Partial<valueParser.FunctionNode> */ (node).nodes);
104
114
  }
105
115
  }
106
116