Skip to content
Prev Previous commit
Next Next commit
track total order and total property count
  • Loading branch information
RobinMalfait committed Feb 21, 2025
commit c5f21f896fe5e87d9f3ed7cb1c6173baa9102a0e
48 changes: 31 additions & 17 deletions packages/tailwindcss/src/compile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export function compileCandidates(
) {
let nodeSorting = new Map<
AstNode,
{ properties: number[]; variants: bigint; candidate: string }
{ properties: { order: number[]; count: number }; variants: bigint; candidate: string }
>()
let astNodes: AstNode[] = []
let matches = new Map<string, Candidate[]>()
Expand Down Expand Up @@ -95,18 +95,19 @@ export function compileCandidates(
// Find the first property that is different between the two rules
let offset = 0
while (
aSorting.properties.length < offset &&
zSorting.properties.length < offset &&
aSorting.properties[offset] === zSorting.properties[offset]
aSorting.properties.order.length < offset &&
zSorting.properties.order.length < offset &&
aSorting.properties.order[offset] === zSorting.properties.order[offset]
) {
offset += 1
}

return (
// Sort by lowest property index first
(aSorting.properties[offset] ?? Infinity) - (zSorting.properties[offset] ?? Infinity) ||
(aSorting.properties.order[offset] ?? Infinity) -
(zSorting.properties.order[offset] ?? Infinity) ||
// Sort by most properties first, then by least properties
zSorting.properties.length - aSorting.properties.length ||
zSorting.properties.count - aSorting.properties.count ||
// Sort alphabetically
compare(aSorting.candidate, zSorting.candidate)
)
Expand All @@ -124,7 +125,10 @@ export function compileAstNodes(candidate: Candidate, designSystem: DesignSystem

let rules: {
node: AstNode
propertySort: number[]
propertySort: {
order: number[]
count: number
}
}[] = []

let selector = `.${escape(candidate.raw)}`
Expand Down Expand Up @@ -310,30 +314,40 @@ function applyImportant(ast: AstNode[]): void {

function getPropertySort(nodes: AstNode[]) {
// Determine sort order based on properties used
let propertySort = new Set<number>()
let order = new Set<number>()
let count = 0
let q: AstNode[] = nodes.slice()

let seenTwSort = false

while (q.length > 0) {
// SAFETY: At this point it is safe to use TypeScript's non-null assertion
// operator because we guarded against `q.length > 0` above.
let node = q.shift()!
if (node.kind === 'declaration') {
if (node.property === '--tw-sort') {
let idx = GLOBAL_PROPERTY_ORDER.indexOf(node.value ?? '')
if (idx !== -1) {
propertySort.add(idx)
break
count++

if (!seenTwSort) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We were using a break before once we noticed a --tw-sort, but now we want to make sure we count all properties. So once we notice a --tw-sort we don't want to collect new properties in the order set anymore, but we still want to keep walking to count other properties.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we invert this condition so we reduce the level of nesting here?

Suggested change
if (!seenTwSort) {
if (teenTwSort) continue;

if (node.property === '--tw-sort') {
let idx = GLOBAL_PROPERTY_ORDER.indexOf(node.value ?? '')
if (idx !== -1) {
order.add(idx)
seenTwSort = true
}
}
}

let idx = GLOBAL_PROPERTY_ORDER.indexOf(node.property)
if (idx !== -1) propertySort.add(idx)
let idx = GLOBAL_PROPERTY_ORDER.indexOf(node.property)
if (idx !== -1) order.add(idx)
}
} else if (node.kind === 'rule' || node.kind === 'at-rule') {
for (let child of node.nodes) {
q.push(child)
}
}
}

return Array.from(propertySort).sort((a, z) => a - z)
return {
order: Array.from(order).sort((a, z) => a - z),
count,
}
}