use crate::tree::Document;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Tier {
Structure,
Semantics,
Rendering,
Interaction,
}
impl Tier {
pub fn as_str(self) -> &'static str {
match self {
Tier::Structure => "structure",
Tier::Semantics => "semantics",
Tier::Rendering => "rendering",
Tier::Interaction => "interaction",
}
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct Caps {
pub semantics: bool,
pub rendering: bool,
pub interaction: bool,
}
impl Caps {
pub const STRUCTURE_ONLY: Caps = Caps {
semantics: false,
rendering: false,
interaction: false,
};
pub fn has(self, tier: Tier) -> bool {
match tier {
Tier::Structure => true,
Tier::Semantics => self.semantics,
Tier::Rendering => self.rendering,
Tier::Interaction => self.interaction,
}
}
pub fn with_semantics(mut self) -> Self {
self.semantics = true;
self
}
pub fn with_rendering(mut self) -> Self {
self.rendering = true;
self
}
pub fn with_interaction(mut self) -> Self {
self.interaction = true;
self
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum NameSource {
AriaLabel,
AriaLabelledBy,
Label,
Title,
Alt,
Placeholder,
Contents,
Value,
}
pub trait Semantics: Document {
fn role<'n>(&'n self, node: Self::N<'n>) -> Option<String>;
fn accessible_name<'n>(&'n self, node: Self::N<'n>) -> Option<String>;
fn name_source<'n>(&'n self, _node: Self::N<'n>) -> Option<NameSource> {
None
}
fn is_ignored<'n>(&'n self, _node: Self::N<'n>) -> bool {
false
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Rect {
pub x: f32,
pub y: f32,
pub width: f32,
pub height: f32,
}
impl Rect {
pub fn area(&self) -> f32 {
self.width * self.height
}
pub fn is_empty(&self) -> bool {
self.width <= 0.0 || self.height <= 0.0
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Color {
pub r: u8,
pub g: u8,
pub b: u8,
pub a: u8,
}
#[derive(Debug, Clone, PartialEq)]
pub struct ComputedStyle {
pub color: Option<Color>,
pub background_color: Option<Color>,
pub font_size_px: Option<f32>,
pub font_weight: Option<u16>,
pub display: Option<String>,
pub visibility: Option<String>,
}
pub trait Rendering: Document {
fn computed_style<'n>(&'n self, node: Self::N<'n>) -> Option<ComputedStyle>;
fn bounds<'n>(&'n self, node: Self::N<'n>) -> Option<Rect>;
fn is_rendered<'n>(&'n self, node: Self::N<'n>) -> bool {
self.bounds(node).is_some_and(|b| !b.is_empty())
}
}
pub trait Interaction: Document {
fn tab_order(&self) -> Vec<crate::NodeId>;
fn has_visible_focus<'n>(&'n self, _node: Self::N<'n>) -> Option<bool> {
None
}
}