@thejaredwilcurt/csslop 0.0.24 → 0.0.26
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.
- package/README.md +5 -1
- package/package.json +5 -3
- package/src/declarations/background.js +26 -1
- package/src/declarations/config.js +156 -2
- package/src/declarations/css-wide-keywords.js +29 -60
- package/src/declarations/fold.js +342 -0
- package/src/declarations/lookup.js +78 -0
- package/src/declarations/merge.js +59 -54
- package/src/declarations/order.js +45 -6
- package/src/declarations/process.js +148 -55
- package/src/declarations/shorthand-values.js +23 -0
- package/src/index.js +29 -5
- package/src/position-try.js +3 -1
- package/src/rules/optimize.js +198 -78
- package/src/rules/property.js +177 -0
- package/src/rules/stringify.js +13 -30
- package/src/value/gradients.js +87 -46
- package/src/value/math.js +17 -2
- package/src/value/minify.js +110 -14
|
@@ -7,8 +7,16 @@ import { hasInvalidQuotesCount } from '../value/quotes.js';
|
|
|
7
7
|
|
|
8
8
|
import { absorbBackgroundLonghandsIntoShorthand } from './background.js';
|
|
9
9
|
import { collapseBorderTrioWithPerEdgeColor } from './border.js';
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
getLonghandsOf,
|
|
12
|
+
shorthandMap
|
|
13
|
+
} from './config.js';
|
|
11
14
|
import { hoistCssWideKeywordsIntoShorthands } from './css-wide-keywords.js';
|
|
15
|
+
import { foldLonghandOverridesIntoShorthands } from './fold.js';
|
|
16
|
+
import {
|
|
17
|
+
collectDeclaredProperties,
|
|
18
|
+
indexFirstDeclarationByProperty
|
|
19
|
+
} from './lookup.js';
|
|
12
20
|
import {
|
|
13
21
|
getMergeProps,
|
|
14
22
|
tryMergeToShorthand
|
|
@@ -49,17 +57,95 @@ function usesModernSyntax (value) {
|
|
|
49
57
|
}
|
|
50
58
|
|
|
51
59
|
/**
|
|
52
|
-
*
|
|
53
|
-
*
|
|
60
|
+
* Creates the bookkeeping for the declarations that survive deduplication.
|
|
61
|
+
*
|
|
62
|
+
* A dropped declaration leaves an empty slot behind instead of being spliced
|
|
63
|
+
* out, so that every position already recorded stays valid. Two indexes then
|
|
64
|
+
* answer the questions the deduplication loop asks about the survivors: which
|
|
65
|
+
* declaration last set a given property, and which vendor-prefixed
|
|
66
|
+
* declarations are still standing.
|
|
67
|
+
*
|
|
68
|
+
* @return {object} The surviving-declaration bookkeeping.
|
|
69
|
+
*/
|
|
70
|
+
function createSurvivingDeclarations () {
|
|
71
|
+
return {
|
|
72
|
+
slots: [],
|
|
73
|
+
positionsByProperty: new Map(),
|
|
74
|
+
vendorPrefixedPositions: []
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Records a declaration as surviving, at the end of the output so far.
|
|
54
80
|
*
|
|
55
|
-
* @param
|
|
56
|
-
* @param
|
|
57
|
-
* @return {number} The index of the matching declaration, or -1 when absent.
|
|
81
|
+
* @param {object} survivors The surviving-declaration bookkeeping.
|
|
82
|
+
* @param {object} declaration The declaration to keep.
|
|
58
83
|
*/
|
|
59
|
-
function
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
84
|
+
function keepDeclaration (survivors, declaration) {
|
|
85
|
+
const position = survivors.slots.length;
|
|
86
|
+
survivors.slots.push(declaration);
|
|
87
|
+
if (!declaration.property) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const positions = survivors.positionsByProperty.get(declaration.property);
|
|
91
|
+
if (positions) {
|
|
92
|
+
positions.push(position);
|
|
93
|
+
} else {
|
|
94
|
+
survivors.positionsByProperty.set(declaration.property, [position]);
|
|
95
|
+
}
|
|
96
|
+
if (declaration.property.startsWith('-')) {
|
|
97
|
+
survivors.vendorPrefixedPositions.push(position);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Drops a declaration that a later one made redundant. Only the last surviving
|
|
103
|
+
* declaration of a property is ever dropped, which is the one at the end of
|
|
104
|
+
* that property's position list.
|
|
105
|
+
*
|
|
106
|
+
* @param {object} survivors The surviving-declaration bookkeeping.
|
|
107
|
+
* @param {number} position The position of the declaration to drop.
|
|
108
|
+
*/
|
|
109
|
+
function dropDeclaration (survivors, position) {
|
|
110
|
+
const { property } = survivors.slots[position];
|
|
111
|
+
survivors.slots[position] = null;
|
|
112
|
+
survivors.positionsByProperty.get(property).pop();
|
|
113
|
+
const vendorPrefixedEntry = survivors.vendorPrefixedPositions.lastIndexOf(position);
|
|
114
|
+
if (vendorPrefixedEntry !== -1) {
|
|
115
|
+
survivors.vendorPrefixedPositions.splice(vendorPrefixedEntry, 1);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Finds the surviving declaration that last set a property, which is the one
|
|
121
|
+
* that currently wins the cascade within the rule.
|
|
122
|
+
*
|
|
123
|
+
* @param {object} survivors The surviving-declaration bookkeeping.
|
|
124
|
+
* @param {string} property The property name to look for.
|
|
125
|
+
* @return {number} The position of the matching declaration, or -1 when absent.
|
|
126
|
+
*/
|
|
127
|
+
function findLastPositionOfProperty (survivors, property) {
|
|
128
|
+
const positions = survivors.positionsByProperty.get(property);
|
|
129
|
+
if (!positions?.length) {
|
|
130
|
+
return -1;
|
|
131
|
+
}
|
|
132
|
+
return positions[positions.length - 1];
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Finds the surviving vendor-prefixed declaration that last set the prefixed
|
|
137
|
+
* form of a property, such as `-webkit-transform` for `transform`. Only the
|
|
138
|
+
* prefixed declarations are visited, rather than every survivor.
|
|
139
|
+
*
|
|
140
|
+
* @param {object} survivors The surviving-declaration bookkeeping.
|
|
141
|
+
* @param {string} property The unprefixed property name.
|
|
142
|
+
* @return {number} The position of the matching declaration, or -1 when absent.
|
|
143
|
+
*/
|
|
144
|
+
function findLastVendorPrefixedPosition (survivors, property) {
|
|
145
|
+
for (let entry = survivors.vendorPrefixedPositions.length - 1; entry >= 0; entry--) {
|
|
146
|
+
const position = survivors.vendorPrefixedPositions[entry];
|
|
147
|
+
if (survivors.slots[position].property.endsWith(property)) {
|
|
148
|
+
return position;
|
|
63
149
|
}
|
|
64
150
|
}
|
|
65
151
|
return -1;
|
|
@@ -74,11 +160,11 @@ function findLastIndex (declarations, predicate) {
|
|
|
74
160
|
* @return {Array} The surviving declarations, in source order.
|
|
75
161
|
*/
|
|
76
162
|
function deduplicateDeclarations (declarations) {
|
|
77
|
-
const
|
|
163
|
+
const survivors = createSurvivingDeclarations();
|
|
78
164
|
|
|
79
165
|
for (const declaration of declarations) {
|
|
80
166
|
if (declaration.type === 'rule' || declaration.type === 'media') {
|
|
81
|
-
|
|
167
|
+
keepDeclaration(survivors, declaration);
|
|
82
168
|
continue;
|
|
83
169
|
}
|
|
84
170
|
|
|
@@ -93,35 +179,23 @@ function deduplicateDeclarations (declarations) {
|
|
|
93
179
|
|
|
94
180
|
const minifiedValue = minifyValue(declaration);
|
|
95
181
|
|
|
96
|
-
|
|
97
|
-
return candidate.property === propertyName;
|
|
98
|
-
});
|
|
182
|
+
const previousPosition = findLastPositionOfProperty(survivors, propertyName);
|
|
99
183
|
|
|
100
184
|
// An unprefixed property with the same value also replaces its prefixed form
|
|
101
|
-
let
|
|
185
|
+
let prefixedPosition = -1;
|
|
102
186
|
if (!propertyName.startsWith('-')) {
|
|
103
|
-
|
|
104
|
-
return (
|
|
105
|
-
candidate.property &&
|
|
106
|
-
candidate.property.endsWith(propertyName) &&
|
|
107
|
-
candidate.property.startsWith('-')
|
|
108
|
-
);
|
|
109
|
-
});
|
|
187
|
+
prefixedPosition = findLastVendorPrefixedPosition(survivors, propertyName);
|
|
110
188
|
}
|
|
111
189
|
|
|
112
|
-
if (
|
|
113
|
-
const prefixedValue = minifyValue(
|
|
190
|
+
if (prefixedPosition !== -1) {
|
|
191
|
+
const prefixedValue = minifyValue(survivors.slots[prefixedPosition]);
|
|
114
192
|
if (minifiedValue === prefixedValue) {
|
|
115
|
-
|
|
116
|
-
// Re-adjust previousIndex if we removed an item before it
|
|
117
|
-
if (previousIndex > prefixedIndex) {
|
|
118
|
-
previousIndex--;
|
|
119
|
-
}
|
|
193
|
+
dropDeclaration(survivors, prefixedPosition);
|
|
120
194
|
}
|
|
121
195
|
}
|
|
122
196
|
|
|
123
|
-
if (
|
|
124
|
-
const previousValue = minifyValue(
|
|
197
|
+
if (previousPosition !== -1) {
|
|
198
|
+
const previousValue = minifyValue(survivors.slots[previousPosition]);
|
|
125
199
|
|
|
126
200
|
if (previousValue.includes('!important') && !minifiedValue.includes('!important')) {
|
|
127
201
|
continue;
|
|
@@ -129,18 +203,37 @@ function deduplicateDeclarations (declarations) {
|
|
|
129
203
|
|
|
130
204
|
// Fallbacks for custom variables or older browser functions should be kept
|
|
131
205
|
if (usesModernSyntax(minifiedValue) && !usesModernSyntax(previousValue)) {
|
|
132
|
-
|
|
206
|
+
keepDeclaration(survivors, declaration);
|
|
133
207
|
continue;
|
|
134
208
|
}
|
|
135
209
|
|
|
136
210
|
// Otherwise override previous identical property
|
|
137
|
-
|
|
211
|
+
dropDeclaration(survivors, previousPosition);
|
|
138
212
|
}
|
|
139
213
|
|
|
140
|
-
|
|
214
|
+
keepDeclaration(survivors, declaration);
|
|
141
215
|
}
|
|
142
216
|
|
|
143
|
-
return
|
|
217
|
+
return survivors.slots.filter((slot) => {
|
|
218
|
+
return slot !== null;
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Indexes the position of the first declaration of each property, which is the
|
|
224
|
+
* earliest position a property can occupy within the rule.
|
|
225
|
+
*
|
|
226
|
+
* @param {Array} declarations The declarations of a single rule, in source order.
|
|
227
|
+
* @return {Map} Map of property name to its first index.
|
|
228
|
+
*/
|
|
229
|
+
function indexFirstDeclarationOfEachProperty (declarations) {
|
|
230
|
+
const firstIndexByProperty = new Map();
|
|
231
|
+
declarations.forEach((declaration, index) => {
|
|
232
|
+
if (declaration.property && !firstIndexByProperty.has(declaration.property)) {
|
|
233
|
+
firstIndexByProperty.set(declaration.property, index);
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
return firstIndexByProperty;
|
|
144
237
|
}
|
|
145
238
|
|
|
146
239
|
/**
|
|
@@ -152,6 +245,9 @@ function deduplicateDeclarations (declarations) {
|
|
|
152
245
|
*/
|
|
153
246
|
function removeLonghandsOverriddenByShorthands (declarations) {
|
|
154
247
|
const propertiesToRemove = new Set();
|
|
248
|
+
// A longhand precedes the shorthand exactly when its first occurrence does,
|
|
249
|
+
// so one index of first positions answers every shorthand's question.
|
|
250
|
+
const firstIndexByProperty = indexFirstDeclarationOfEachProperty(declarations);
|
|
155
251
|
|
|
156
252
|
declarations.forEach((declaration, shorthandIndex) => {
|
|
157
253
|
if (!declaration.property || !shorthandMap[declaration.property]) {
|
|
@@ -159,10 +255,8 @@ function removeLonghandsOverriddenByShorthands (declarations) {
|
|
|
159
255
|
}
|
|
160
256
|
const overridden = getOverriddenLonghands(declaration.property);
|
|
161
257
|
for (const longhandProperty of overridden) {
|
|
162
|
-
const longhandIndex =
|
|
163
|
-
|
|
164
|
-
});
|
|
165
|
-
if (longhandIndex !== -1) {
|
|
258
|
+
const longhandIndex = firstIndexByProperty.get(longhandProperty);
|
|
259
|
+
if (longhandIndex !== undefined && longhandIndex < shorthandIndex) {
|
|
166
260
|
propertiesToRemove.add(longhandProperty);
|
|
167
261
|
}
|
|
168
262
|
}
|
|
@@ -194,10 +288,9 @@ function getReplacedLonghands (shorthandName, mergeableProperties, relevantDecla
|
|
|
194
288
|
if (!hasMixedImportant || !MIXED_IMPORTANT_SHORTHANDS.has(shorthandName)) {
|
|
195
289
|
return mergeableProperties;
|
|
196
290
|
}
|
|
291
|
+
const declarationByProperty = indexFirstDeclarationByProperty(relevantDeclarations);
|
|
197
292
|
return mergeableProperties.filter((property) => {
|
|
198
|
-
const declaration =
|
|
199
|
-
return candidate.property === property;
|
|
200
|
-
});
|
|
293
|
+
const declaration = declarationByProperty.get(property);
|
|
201
294
|
return declaration && !minifyValue(declaration).includes('!important');
|
|
202
295
|
});
|
|
203
296
|
}
|
|
@@ -217,15 +310,12 @@ function removeSubsumedShorthands (builtDeclarations) {
|
|
|
217
310
|
return true;
|
|
218
311
|
}
|
|
219
312
|
const isSubsumedByOtherShorthand = builtDeclarations.some((other) => {
|
|
220
|
-
if (other === declaration) {
|
|
221
|
-
return false;
|
|
222
|
-
}
|
|
223
|
-
const otherLonghands = shorthandMap[other.property];
|
|
224
|
-
if (!otherLonghands) {
|
|
313
|
+
if (other === declaration || !shorthandMap[other.property]) {
|
|
225
314
|
return false;
|
|
226
315
|
}
|
|
316
|
+
const otherLonghands = getLonghandsOf(other.property);
|
|
227
317
|
return longhands.every((longhand) => {
|
|
228
|
-
return otherLonghands.
|
|
318
|
+
return otherLonghands.has(longhand);
|
|
229
319
|
});
|
|
230
320
|
});
|
|
231
321
|
return !isSubsumedByOtherShorthand;
|
|
@@ -249,21 +339,23 @@ function mergeLonghandsIntoShorthands (declarations, context) {
|
|
|
249
339
|
builtShorthand = false;
|
|
250
340
|
const replacedProperties = new Set();
|
|
251
341
|
const builtDeclarations = [];
|
|
342
|
+
// Every shorthand asks the same questions of the same declarations, so the
|
|
343
|
+
// set of declared properties is gathered once per pass rather than rescanned
|
|
344
|
+
// for each of the dozens of shorthand families.
|
|
345
|
+
const declaredProperties = collectDeclaredProperties(result);
|
|
252
346
|
|
|
253
347
|
for (const [shorthand, longhands] of Object.entries(shorthandMap)) {
|
|
254
|
-
|
|
255
|
-
return declaration.property === shorthand;
|
|
256
|
-
});
|
|
257
|
-
if (shorthandAlreadyExists) {
|
|
348
|
+
if (declaredProperties.has(shorthand)) {
|
|
258
349
|
continue;
|
|
259
350
|
}
|
|
260
351
|
|
|
261
|
-
const mergeableProperties = getMergeProps(shorthand, longhands,
|
|
352
|
+
const mergeableProperties = getMergeProps(shorthand, longhands, declaredProperties);
|
|
262
353
|
if (!mergeableProperties) {
|
|
263
354
|
continue;
|
|
264
355
|
}
|
|
356
|
+
const mergeablePropertySet = new Set(mergeableProperties);
|
|
265
357
|
const relevantDeclarations = result.filter((declaration) => {
|
|
266
|
-
return
|
|
358
|
+
return mergeablePropertySet.has(declaration.property);
|
|
267
359
|
});
|
|
268
360
|
const mergedValue = tryMergeToShorthand(mergeableProperties, relevantDeclarations, shorthand, context);
|
|
269
361
|
if (!mergedValue) {
|
|
@@ -305,6 +397,7 @@ function processDeclarations (declarations, context) {
|
|
|
305
397
|
result = removeLonghandsOverriddenByShorthands(result);
|
|
306
398
|
result = absorbBackgroundLonghandsIntoShorthand(result);
|
|
307
399
|
result = mergeLonghandsIntoShorthands(result, context);
|
|
400
|
+
result = foldLonghandOverridesIntoShorthands(result, context);
|
|
308
401
|
result = hoistCssWideKeywordsIntoShorthands(result);
|
|
309
402
|
result = collapseBorderTrioWithPerEdgeColor(result);
|
|
310
403
|
|
|
@@ -6,6 +6,7 @@ import { collapseShorthandParts } from '../value/shared.js';
|
|
|
6
6
|
import { splitTopLevelComponents } from '../value/syntax.js';
|
|
7
7
|
|
|
8
8
|
import { buildBackgroundShorthandValue } from './background.js';
|
|
9
|
+
import { UNIFORM_VALUE_SHORTHANDS } from './config.js';
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* @typedef {object} ShorthandComponents
|
|
@@ -275,6 +276,25 @@ function buildFlexValue ({ valueMap, importantSuffix }) {
|
|
|
275
276
|
return [grow, shrink, basis].join(' ') + importantSuffix;
|
|
276
277
|
}
|
|
277
278
|
|
|
279
|
+
/**
|
|
280
|
+
* Builds the value of a shorthand that applies one value to every longhand it
|
|
281
|
+
* sets, such as `marker` or the bidirectional gap decoration rules. Such a
|
|
282
|
+
* shorthand cannot express longhands that differ, so the group only collapses
|
|
283
|
+
* when every longhand already holds the same value.
|
|
284
|
+
*
|
|
285
|
+
* @param {ShorthandComponents} components The collected longhand values.
|
|
286
|
+
* @return {string|null} The shorthand value, or null when it cannot be built.
|
|
287
|
+
*/
|
|
288
|
+
function buildUniformValue ({ cleanValues, importantSuffix }) {
|
|
289
|
+
const isSharedByAll = cleanValues.every((value) => {
|
|
290
|
+
return value === cleanValues[0];
|
|
291
|
+
});
|
|
292
|
+
if (!isSharedByAll) {
|
|
293
|
+
return null;
|
|
294
|
+
}
|
|
295
|
+
return cleanValues[0] + importantSuffix;
|
|
296
|
+
}
|
|
297
|
+
|
|
278
298
|
/**
|
|
279
299
|
* Determines whether a shorthand takes a single width, style, and color, as
|
|
280
300
|
* `border` and `outline` do.
|
|
@@ -364,6 +384,9 @@ const NAMED_SHORTHAND_BUILDERS = {
|
|
|
364
384
|
* @return {string|null} The shorthand value, or null when it cannot be built.
|
|
365
385
|
*/
|
|
366
386
|
function buildShorthandValue (shorthandName, components) {
|
|
387
|
+
if (UNIFORM_VALUE_SHORTHANDS.has(shorthandName)) {
|
|
388
|
+
return buildUniformValue(components);
|
|
389
|
+
}
|
|
367
390
|
const namedBuilder = NAMED_SHORTHAND_BUILDERS[shorthandName];
|
|
368
391
|
if (namedBuilder) {
|
|
369
392
|
return namedBuilder(components);
|
package/src/index.js
CHANGED
|
@@ -41,7 +41,10 @@ import {
|
|
|
41
41
|
removeRedundantLayerStatementSemicolon,
|
|
42
42
|
stringifyRule
|
|
43
43
|
} from './rules/stringify.js';
|
|
44
|
-
import {
|
|
44
|
+
import {
|
|
45
|
+
clearMinifiedValueCache,
|
|
46
|
+
minifyValue
|
|
47
|
+
} from './value/minify.js';
|
|
45
48
|
|
|
46
49
|
/**
|
|
47
50
|
* Splits a minified CSS selector list at top-level commas, respecting
|
|
@@ -175,6 +178,27 @@ function mergeAdjacentRulesWithIdenticalBodies (ruleStrings) {
|
|
|
175
178
|
return result;
|
|
176
179
|
}
|
|
177
180
|
|
|
181
|
+
/**
|
|
182
|
+
* Prepares the module-level state a single minification pass relies on: the
|
|
183
|
+
* active charset, and an empty value cache, since a value memoized under a
|
|
184
|
+
* different charset may no longer minify the same way.
|
|
185
|
+
*
|
|
186
|
+
* @param {string} charset The `@charset` value detected in the source.
|
|
187
|
+
*/
|
|
188
|
+
function beginMinificationPass (charset) {
|
|
189
|
+
setActiveCharset(charset);
|
|
190
|
+
clearMinifiedValueCache();
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Releases the module-level state a minification pass built up, so a cache
|
|
195
|
+
* filled by a large stylesheet is not retained until the next pass runs.
|
|
196
|
+
*/
|
|
197
|
+
function endMinificationPass () {
|
|
198
|
+
clearActiveCharset();
|
|
199
|
+
clearMinifiedValueCache();
|
|
200
|
+
}
|
|
201
|
+
|
|
178
202
|
/**
|
|
179
203
|
* Parses, optimizes, and minifies a CSS string by applying rule merging, declaration deduplication, value compression, and dead-code elimination.
|
|
180
204
|
*
|
|
@@ -192,7 +216,7 @@ export const minifyCSS = function (input) {
|
|
|
192
216
|
const output = [];
|
|
193
217
|
|
|
194
218
|
const detectedCharset = detectCharset(source);
|
|
195
|
-
|
|
219
|
+
beginMinificationPass(detectedCharset);
|
|
196
220
|
|
|
197
221
|
try {
|
|
198
222
|
ast = parse(
|
|
@@ -200,7 +224,7 @@ export const minifyCSS = function (input) {
|
|
|
200
224
|
{ preserveFormatting: true, silent: true }
|
|
201
225
|
);
|
|
202
226
|
} catch {
|
|
203
|
-
|
|
227
|
+
endMinificationPass();
|
|
204
228
|
return source;
|
|
205
229
|
}
|
|
206
230
|
|
|
@@ -248,10 +272,10 @@ export const minifyCSS = function (input) {
|
|
|
248
272
|
|
|
249
273
|
const mergedOutput = removeRedundantLayerStatementSemicolon(mergeAdjacentRulesWithIdenticalBodies(output));
|
|
250
274
|
|
|
251
|
-
|
|
275
|
+
endMinificationPass();
|
|
252
276
|
return restoreEscapeSequences(mergedOutput.join(''));
|
|
253
277
|
}
|
|
254
278
|
|
|
255
|
-
|
|
279
|
+
endMinificationPass();
|
|
256
280
|
return source;
|
|
257
281
|
};
|
package/src/position-try.js
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
* @file Handles `@position-try` rule analysis, usage tracking, and dead-rule elimination during CSS minification.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
import { registersCustomProperty } from './rules/property.js';
|
|
6
|
+
|
|
5
7
|
/**
|
|
6
8
|
* Scans top-level rules to register `@property` custom properties in the context and collect `@position-try` rule declarations and initial usage counts.
|
|
7
9
|
*
|
|
@@ -14,7 +16,7 @@ function collectRuleMetadata (rules, context) {
|
|
|
14
16
|
const positionTryUsage = new Map();
|
|
15
17
|
|
|
16
18
|
for (const rule of rules) {
|
|
17
|
-
if (rule.type === 'property' && rule.name) {
|
|
19
|
+
if (rule.type === 'property' && rule.name && registersCustomProperty(rule)) {
|
|
18
20
|
context.registeredCustomProperties.add(rule.name);
|
|
19
21
|
const syntaxDeclaration = (rule.declarations || []).find((declaration) => {
|
|
20
22
|
return declaration.type !== 'whitespace' && declaration.property === 'syntax';
|