///|
/// CSS Media Query Types
/// Represents parsed media queries for @media rules
///|
/// Media type (screen, print, all, etc.)
pub enum MediaType {
All
Screen
Print
Speech
} derive(Eq, Debug)
///|
/// Comparison operator for range queries
pub enum RangeOp {
Eq // =
Lt // <
Le // <=
Gt // >
Ge // >=
} derive(Eq, Debug)
///|
/// Media feature value
pub enum MediaValue {
Number(Double)
Dimension(Double, String) // value and unit (e.g., 768px, 2dppx)
Ratio(Int, Int) // e.g., 16/9
Ident(String) // e.g., landscape, portrait
} derive(Eq, Debug)
///|
/// Media feature (e.g., width, height, color, etc.)
pub enum MediaFeature {
// Boolean features (no value)
Color
ColorGamut
ColorIndex
Grid
Hover
Monochrome
Pointer
Scripting
Update
// Range features with optional min/max prefix
Width(MediaValue?)
MinWidth(MediaValue)
MaxWidth(MediaValue)
Height(MediaValue?)
MinHeight(MediaValue)
MaxHeight(MediaValue)
AspectRatio(MediaValue?)
MinAspectRatio(MediaValue)
MaxAspectRatio(MediaValue)
Resolution(MediaValue?)
MinResolution(MediaValue)
MaxResolution(MediaValue)
// Range syntax (CSS Media Queries Level 4)
WidthRange(RangeOp, MediaValue)
HeightRange(RangeOp, MediaValue)
// Discrete features with value
Orientation(String) // portrait | landscape
DisplayMode(String) // fullscreen | standalone | minimal-ui | browser
PrefersColorScheme(String) // light | dark
PrefersReducedMotion(String) // reduce | no-preference
// Generic feature for unknown features
Custom(String, MediaValue?)
} derive(Eq, Debug)
///|
/// A complete media query
pub struct MediaQuery {
/// "not" modifier
negated : Bool
/// "only" modifier
only : Bool
/// The media type (if any)
media_type : MediaType?
/// The conditions (features)
conditions : Array[MediaFeature]
} derive(Eq, Debug)
///|
/// Create a default media query (matches all)
pub fn MediaQuery::default() -> MediaQuery {
{ negated: false, only: false, media_type: None, conditions: [] }
}
///|
/// A list of media queries (comma-separated in CSS)
pub struct MediaQueryList {
queries : Array[MediaQuery]
} derive(Eq, Debug)
///|
/// Create an empty media query list
pub fn MediaQueryList::new() -> MediaQueryList {
{ queries: [] }
}
///|
/// Check if a media query list is empty
pub fn MediaQueryList::is_empty(self : MediaQueryList) -> Bool {
self.queries.is_empty()
}
///|
/// Get the number of queries
pub fn MediaQueryList::length(self : MediaQueryList) -> Int {
self.queries.length()
}
///|
pub impl Show for MediaType with fn output(self, logger) {
let name = match self {
All => "All"
Screen => "Screen"
Print => "Print"
Speech => "Speech"
}
logger.write_string(name)
}
///|
pub impl Show for RangeOp with fn output(self, logger) {
let name = match self {
Eq => "Eq"
Lt => "Lt"
Le => "Le"
Gt => "Gt"
Ge => "Ge"
}
logger.write_string(name)
}
///|
pub impl Show for MediaValue with fn output(self, logger) {
match self {
Number(v) => logger.write_string("Number(\{v})")
Dimension(v, unit) => {
logger.write_string("Dimension(")
logger.write_string(v.to_string())
logger.write_string(", ")
logger.write_string("\"")
logger.write_string(unit)
logger.write_string("\"")
logger.write_string(")")
}
Ratio(left, right) => logger.write_string("Ratio(\{left}, \{right})")
Ident(value) => {
logger.write_string("Ident(")
logger.write_string("\"")
logger.write_string(value)
logger.write_string("\"")
logger.write_string(")")
}
}
}
///|
pub impl Show for MediaFeature with fn output(self, logger) {
match self {
Color => logger.write_string("Color")
ColorGamut => logger.write_string("ColorGamut")
ColorIndex => logger.write_string("ColorIndex")
Grid => logger.write_string("Grid")
Hover => logger.write_string("Hover")
Monochrome => logger.write_string("Monochrome")
Pointer => logger.write_string("Pointer")
Scripting => logger.write_string("Scripting")
Update => logger.write_string("Update")
Width(value) => {
logger.write_string("Width(")
logger.write_object(to_repr(value))
logger.write_string(")")
}
MinWidth(value) => logger.write_string("MinWidth(\{value})")
MaxWidth(value) => logger.write_string("MaxWidth(\{value})")
Height(value) => {
logger.write_string("Height(")
logger.write_object(to_repr(value))
logger.write_string(")")
}
MinHeight(value) => logger.write_string("MinHeight(\{value})")
MaxHeight(value) => logger.write_string("MaxHeight(\{value})")
AspectRatio(value) => {
logger.write_string("AspectRatio(")
logger.write_object(to_repr(value))
logger.write_string(")")
}
MinAspectRatio(value) => logger.write_string("MinAspectRatio(\{value})")
MaxAspectRatio(value) => logger.write_string("MaxAspectRatio(\{value})")
Resolution(value) => {
logger.write_string("Resolution(")
logger.write_object(to_repr(value))
logger.write_string(")")
}
MinResolution(value) => logger.write_string("MinResolution(\{value})")
MaxResolution(value) => logger.write_string("MaxResolution(\{value})")
WidthRange(op, value) => logger.write_string("WidthRange(\{op}, \{value})")
HeightRange(op, value) =>
logger.write_string("HeightRange(\{op}, \{value})")
Orientation(value) => {
logger.write_string("Orientation(")
logger.write_string("\"")
logger.write_string(value)
logger.write_string("\"")
logger.write_string(")")
}
DisplayMode(value) => {
logger.write_string("DisplayMode(")
logger.write_string("\"")
logger.write_string(value)
logger.write_string("\"")
logger.write_string(")")
}
PrefersColorScheme(value) => {
logger.write_string("PrefersColorScheme(")
logger.write_string("\"")
logger.write_string(value)
logger.write_string("\"")
logger.write_string(")")
}
PrefersReducedMotion(value) => {
logger.write_string("PrefersReducedMotion(")
logger.write_string("\"")
logger.write_string(value)
logger.write_string("\"")
logger.write_string(")")
}
Custom(name, value) => {
logger.write_string("Custom(")
logger.write_string("\"")
logger.write_string(name)
logger.write_string("\"")
logger.write_string(", ")
logger.write_object(to_repr(value))
logger.write_string(")")
}
}
}
///|
pub impl Show for MediaQuery with fn output(self, logger) {
logger.write_string("{negated: ")
logger.write_string(self.negated.to_string())
logger.write_string(", only: ")
logger.write_string(self.only.to_string())
logger.write_string(", media_type: ")
logger.write_object(to_repr(self.media_type))
logger.write_string(", conditions: ")
logger.write_object(to_repr(self.conditions))
logger.write_string("}")
}
///|
pub impl Show for MediaQueryList with fn output(self, logger) {
logger.write_string("{queries: ")
logger.write_object(to_repr(self.queries))
logger.write_string("}")
}