diff --git a/crates/obscura-render/src/css.rs b/crates/obscura-render/src/css.rs index af0923f..aa87e53 100644 --- a/crates/obscura-render/src/css.rs +++ b/crates/obscura-render/src/css.rs @@ -13,12 +13,64 @@ use std::collections::HashMap; use crate::LayoutStyle; +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] +struct ContainerConditionId(u32); + +impl ContainerConditionId { + const NONE: Self = Self(0); +} + +#[derive(Clone, Debug, PartialEq)] +struct ContainerConditionNode { + parent: ContainerConditionId, + /// Comma-separated queries in one prelude are alternatives; parent-linked + /// nodes represent nested `@container` rules that must all match. + alternatives: Vec, +} + +#[derive(Clone, Debug, PartialEq)] +struct ContainerQuery { + name: Option, + condition: Option, +} + +#[derive(Clone, Debug, PartialEq)] +enum ContainerQueryExpr { + Feature(ContainerSizeFeature), + Not(Box), + And(Vec), + Or(Vec), +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +enum ContainerQueryAxis { Width, InlineSize } + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +enum ContainerQueryComparison { Min, Max } + +#[derive(Clone, Copy, Debug, PartialEq)] +struct ContainerSizeFeature { + axis: ContainerQueryAxis, + comparison: ContainerQueryComparison, + length: ContainerQueryLength, +} + +#[derive(Clone, Copy, Debug, PartialEq)] +enum ContainerQueryLength { Px(f32), Em(f32), Rem(f32) } + +struct ParsedRule { + selector: String, + declarations: String, + container_condition_id: ContainerConditionId, +} + struct Rule { sel: CompiledSelector, normal_decls: String, important_decls: String, /// Source order, for breaking specificity ties (later wins). order: usize, + container_condition_id: ContainerConditionId, } struct PseudoRule { @@ -26,11 +78,14 @@ struct PseudoRule { normal_decls: String, important_decls: String, order: usize, + container_condition_id: ContainerConditionId, } /// An indexed set of author rules ready for fast per-element matching. pub struct Stylesheet { rules: Vec, + /// Index zero is the unconditional sentinel. + container_conditions: Vec, /// Final declarations from `@keyframes name { ... 100%/to { ... } }`. /// Static screenshots are taken after the requested settle interval, so a /// finite forwards-filled animation contributes this declaration block. @@ -47,6 +102,13 @@ pub struct Stylesheet { } impl Stylesheet { + /// Until Stage B supplies completed container geometry, preserved + /// conditional rules remain inactive rather than using viewport geometry. + fn container_condition_is_active(&self, id: ContainerConditionId) -> bool { + debug_assert!((id.0 as usize) < self.container_conditions.len()); + id == ContainerConditionId::NONE + } + /// Parse and index a set of raw CSS sources (the text of each `