postcss-normalize-positions 8.0.2 → 8.0.3

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 +6 -3
  2. package/src/index.js +87 -46
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "postcss-normalize-positions",
3
- "version": "8.0.2",
3
+ "version": "8.0.3",
4
4
  "description": "Normalize keyword values for position into length values.",
5
5
  "exports": {
6
6
  ".": {
@@ -43,9 +43,12 @@
43
43
  "node": "^22.11.0 || ^24.11.0 || >=26.0"
44
44
  },
45
45
  "devDependencies": {
46
- "postcss": "^8.5.25"
46
+ "postcss": "^8.5.26"
47
47
  },
48
48
  "peerDependencies": {
49
- "postcss": "^8.5.25"
49
+ "postcss": "^8.5.26"
50
+ },
51
+ "scripts": {
52
+ "test": "node --test"
50
53
  }
51
54
  }
package/src/index.js CHANGED
@@ -16,6 +16,7 @@ const mathFunctions = new Set(['calc', 'min', 'max', 'clamp']);
16
16
  const variableFunctions = new Set(['var', 'env', 'constant']);
17
17
  const propFilterRegex =
18
18
  /^(background(-position)?|(-\w+-)?perspective-origin)$/i;
19
+
19
20
  /**
20
21
  * @param {valueParser.Node} node
21
22
  * @return {boolean}
@@ -85,22 +86,36 @@ function isDimensionNode(node) {
85
86
  */
86
87
  function transform(value) {
87
88
  const parsed = valueParser(value);
88
- /** @type {({start: number, end: number} | {start: null, end: null})[]} */
89
+ const ranges = collectRanges(parsed.nodes);
90
+
91
+ for (const range of ranges) {
92
+ normalizeRange(parsed, range);
93
+ }
94
+
95
+ return parsed.toString();
96
+ }
97
+
98
+ /**
99
+ * @param {valueParser.Node[]} nodes
100
+ * @return {{start: number | null, end: number | null}[]}
101
+ */
102
+ function collectRanges(nodes) {
103
+ /** @type {{start: number | null, end: number | null}[]} */
89
104
  const ranges = [];
90
105
  let rangeIndex = 0;
91
106
  let shouldContinue = true;
92
107
 
93
- parsed.nodes.forEach((node, index) => {
108
+ for (const [index, node] of nodes.entries()) {
94
109
  // After comma (`,`) follows next background
95
110
  if (isCommaNode(node)) {
96
111
  rangeIndex += 1;
97
112
  shouldContinue = true;
98
113
 
99
- return;
114
+ continue;
100
115
  }
101
116
 
102
117
  if (!shouldContinue) {
103
- return;
118
+ continue;
104
119
  }
105
120
 
106
121
  // After separator (`/`) follows `background-size` values
@@ -108,7 +123,7 @@ function transform(value) {
108
123
  if (node.type === 'div' && node.value === '/') {
109
124
  shouldContinue = false;
110
125
 
111
- return;
126
+ continue;
112
127
  }
113
128
 
114
129
  if (!ranges[rangeIndex]) {
@@ -124,7 +139,7 @@ function transform(value) {
124
139
  ranges[rangeIndex].start = null;
125
140
  ranges[rangeIndex].end = null;
126
141
 
127
- return;
142
+ continue;
128
143
  }
129
144
 
130
145
  const isPositionKeyword =
@@ -138,7 +153,7 @@ function transform(value) {
138
153
  ranges[rangeIndex].start = index;
139
154
  ranges[rangeIndex].end = index;
140
155
 
141
- return;
156
+ continue;
142
157
  }
143
158
 
144
159
  if (ranges[rangeIndex].start !== null) {
@@ -146,58 +161,84 @@ function transform(value) {
146
161
  ranges[rangeIndex].end = index;
147
162
  }
148
163
  }
149
- });
164
+ }
150
165
 
151
- ranges.forEach((range) => {
152
- if (range.start === null) {
153
- return;
154
- }
166
+ return ranges;
167
+ }
155
168
 
156
- const nodes = parsed.nodes.slice(range.start, range.end + 1);
169
+ /**
170
+ * @param {{nodes: valueParser.Node[]}} parsed
171
+ * @param {{start: number | null, end: number | null}} range
172
+ * @return {void}
173
+ */
174
+ function normalizeRange(parsed, range) {
175
+ if (range.start === null || range.end === null) {
176
+ return;
177
+ }
157
178
 
158
- if (nodes.length > 3) {
159
- return;
160
- }
179
+ const nodes = parsed.nodes.slice(range.start, range.end + 1);
180
+
181
+ if (nodes.length > 3) {
182
+ return;
183
+ }
161
184
 
162
- const firstNode = nodes[0].value.toLowerCase();
163
- const secondNode =
164
- nodes[2] && nodes[2].value ? nodes[2].value.toLowerCase() : null;
185
+ const firstNode = nodes[0].value.toLowerCase();
186
+ const secondNode =
187
+ nodes[2] && nodes[2].value ? nodes[2].value.toLowerCase() : null;
165
188
 
166
- if (nodes.length === 1 || secondNode === 'center') {
167
- if (secondNode) {
168
- nodes[2].value = nodes[1].value = '';
169
- }
189
+ if (nodes.length === 1 || secondNode === 'center') {
190
+ normalizeSinglePosition(nodes, firstNode, secondNode);
191
+ return;
192
+ }
170
193
 
171
- const map = new Map([...horizontal, ['center', center]]);
194
+ normalizePairPosition(nodes, firstNode, secondNode);
195
+ }
172
196
 
173
- if (map.has(firstNode)) {
174
- nodes[0].value = /** @type {string}*/ (map.get(firstNode));
175
- }
197
+ /**
198
+ * @param {valueParser.Node[]} nodes
199
+ * @param {string} firstNode
200
+ * @param {string | null} secondNode
201
+ * @return {void}
202
+ */
203
+ function normalizeSinglePosition(nodes, firstNode, secondNode) {
204
+ if (secondNode) {
205
+ nodes[2].value = nodes[1].value = '';
206
+ }
176
207
 
177
- return;
178
- }
208
+ const map = new Map([...horizontal, ['center', center]]);
179
209
 
180
- if (secondNode !== null) {
181
- if (firstNode === 'center' && directionKeywords.has(secondNode)) {
182
- nodes[0].value = nodes[1].value = '';
210
+ if (map.has(firstNode)) {
211
+ nodes[0].value = /** @type {string}*/ (map.get(firstNode));
212
+ }
213
+ }
183
214
 
184
- if (horizontal.has(secondNode)) {
185
- nodes[2].value = /** @type {string} */ (horizontal.get(secondNode));
186
- }
187
- return;
188
- }
215
+ /**
216
+ * @param {valueParser.Node[]} nodes
217
+ * @param {string} firstNode
218
+ * @param {string | null} secondNode
219
+ * @return {void}
220
+ */
221
+ function normalizePairPosition(nodes, firstNode, secondNode) {
222
+ if (secondNode === null) {
223
+ return;
224
+ }
189
225
 
190
- if (horizontal.has(firstNode) && verticalValue.has(secondNode)) {
191
- nodes[0].value = /** @type {string} */ (horizontal.get(firstNode));
192
- nodes[2].value = /** @type {string} */ (verticalValue.get(secondNode));
193
- } else if (verticalValue.has(firstNode) && horizontal.has(secondNode)) {
194
- nodes[0].value = /** @type {string} */ (horizontal.get(secondNode));
195
- nodes[2].value = /** @type {string} */ (verticalValue.get(firstNode));
196
- }
226
+ if (firstNode === 'center' && directionKeywords.has(secondNode)) {
227
+ nodes[0].value = nodes[1].value = '';
228
+
229
+ if (horizontal.has(secondNode)) {
230
+ nodes[2].value = /** @type {string} */ (horizontal.get(secondNode));
197
231
  }
198
- });
232
+ return;
233
+ }
199
234
 
200
- return parsed.toString();
235
+ if (horizontal.has(firstNode) && verticalValue.has(secondNode)) {
236
+ nodes[0].value = /** @type {string} */ (horizontal.get(firstNode));
237
+ nodes[2].value = /** @type {string} */ (verticalValue.get(secondNode));
238
+ } else if (verticalValue.has(firstNode) && horizontal.has(secondNode)) {
239
+ nodes[0].value = /** @type {string} */ (horizontal.get(secondNode));
240
+ nodes[2].value = /** @type {string} */ (verticalValue.get(firstNode));
241
+ }
201
242
  }
202
243
 
203
244
  /**