@@ -24,6 +24,8 @@ import { remapBitfield } from './remap-bitfield.js'
24
24
* @property {bigint } variants Dynamic size. 1 bit per registered variant. 0n means no variants
25
25
* @property {bigint } parallelIndex Rule index for the parallel variant. 0 if not applicable.
26
26
* @property {bigint } index Index of the rule / utility in its given *parent* layer. Monotonically increasing.
27
+ * @property {bigint } propertyOffset Offset for the arbitrary property. Only valid after sorting.
28
+ * @property {string } property Name/Value of the arbitrary property.
27
29
* @property {VariantOption[] } options Some information on how we can sort arbitrary variants
28
30
*/
29
31
@@ -88,17 +90,21 @@ export class Offsets {
88
90
variants : 0n ,
89
91
parallelIndex : 0n ,
90
92
index : this . offsets [ layer ] ++ ,
93
+ propertyOffset : 0n ,
94
+ property : '' ,
91
95
options : [ ] ,
92
96
}
93
97
}
94
98
95
99
/**
100
+ * @param {string } name
96
101
* @returns {RuleOffset }
97
102
*/
98
- arbitraryProperty ( ) {
103
+ arbitraryProperty ( name ) {
99
104
return {
100
105
...this . create ( 'utilities' ) ,
101
106
arbitrary : 1n ,
107
+ property : name ,
102
108
}
103
109
}
104
110
@@ -262,6 +268,11 @@ export class Offsets {
262
268
return a . arbitrary - b . arbitrary
263
269
}
264
270
271
+ // Always sort arbitrary properties alphabetically
272
+ if ( a . propertyOffset !== b . propertyOffset ) {
273
+ return a . propertyOffset - b . propertyOffset
274
+ }
275
+
265
276
// Sort utilities, components, etc… in the order they were registered
266
277
return a . index - b . index
267
278
}
@@ -320,14 +331,62 @@ export class Offsets {
320
331
} )
321
332
}
322
333
334
+ /**
335
+ * @template T
336
+ * @param {[RuleOffset, T][] } list
337
+ * @returns {[RuleOffset, T][] }
338
+ */
339
+ sortArbitraryProperties ( list ) {
340
+ // Collect all known arbitrary properties
341
+ let known = new Set ( )
342
+
343
+ for ( let [ offset ] of list ) {
344
+ if ( offset . arbitrary === 1n ) {
345
+ known . add ( offset . property )
346
+ }
347
+ }
348
+
349
+ // No arbitrary properties? Nothing to do.
350
+ if ( known . size === 0 ) {
351
+ return list
352
+ }
353
+
354
+ // Sort the properties alphabetically
355
+ let properties = Array . from ( known ) . sort ( )
356
+
357
+ // Create a map from the property name to its offset
358
+ let offsets = new Map ( )
359
+
360
+ let offset = 1n
361
+ for ( let property of properties ) {
362
+ offsets . set ( property , offset ++ )
363
+ }
364
+
365
+ // Apply the sorted offsets to the list
366
+ return list . map ( ( item ) => {
367
+ let [ offset , rule ] = item
368
+
369
+ offset = {
370
+ ...offset ,
371
+ propertyOffset : offsets . get ( offset . property ) ?? 0n ,
372
+ }
373
+
374
+ return [ offset , rule ]
375
+ } )
376
+ }
377
+
323
378
/**
324
379
* @template T
325
380
* @param {[RuleOffset, T][] } list
326
381
* @returns {[RuleOffset, T][] }
327
382
*/
328
383
sort ( list ) {
384
+ // Sort arbitrary variants so they're in alphabetical order
329
385
list = this . remapArbitraryVariantOffsets ( list )
330
386
387
+ // Sort arbitrary properties so they're in alphabetical order
388
+ list = this . sortArbitraryProperties ( list )
389
+
331
390
return list . sort ( ( [ a ] , [ b ] ) => bigSign ( this . compare ( a , b ) ) )
332
391
}
333
392
}
0 commit comments