Coding 2024-09-21
Breaking things down now, very carefully:
- When I'm specifying the classes in a tag, I want to have access to a "typed subset" kind of construction. This is what the current Flag usage gets me.
- When I'm specifying the classes in a CSS selector, I care very strongly about the ordering.
There are, fundamentally, three different cases to consider:
- Unmodified block/element
- Modified block/element
- Element descendant of modified block
For a given block, the unmodified selectors should go before the modified ones, and the descendant tags can go anywhere because they have the highest specificity.
As such, let's try harmonizing ordering with how SCSS or suchlike would do it.
- Unmodified block
- Modified block
- Descendants of modified block
- Unmodified element
- Modified element
My inclination right now is to do this with a partial ordering where only selectors with the same base block are comparable. To deal with the incompatible orderings, we need to sort them into an unordered collection of ordered bins, or rather, maps where we sort the keys before iterating. Regardless, they must be sorted by base type.
:)
You're bringing back dependent mappings again, aren't you?
To be fair, there's only any actual code there if I bother trying to make it pass type checking.
Anyway, to get ordering working, I could try to coordinate stuff across multiple classes, or I could punt on that and just come up with some slightly strange ordering logic:
@attrs.frozen
class Selector[B]:
block: B # Require length of zero or one
element: Element[B] | None # Require length of zero or one
# Define an ordering thus:
# 0, None (bucket 0)
# 1, None
# 1, A0 (bucket 1)
# 1, A1
# 1, B0
# 1, B1
# 0, A0 (bucket 2)
# 0, A1
# 0, B0
# 0, B1
It's a little funky that the block part has this alternation in the sort order, but I think it makes things work out aesthetically. Sorting happens first by bucket, and within buckets, sorts by tag name.
...
Okay, I did all of that, and maybe a few other things besides. I need to get away from this for a bit, rest and let the dust settle, before I work out if anything I just did actually made sense.
Good night.