mod apply;
mod content;
mod inherit;
mod masks;
mod walk;
#[cfg(test)]
mod tests;
use rdom_core::{Dom, NodeId};
use crate::ext::TuiExt;
use crate::style::{ComputedStyle, Stylesheet};
pub use masks::{INHERITS_MASK, LAYOUT_MASK, PropMask};
pub trait CascadeExt {
fn cascade(&mut self, stylesheet: &Stylesheet);
fn cascade_all(&mut self, stylesheets: &[&Stylesheet]);
fn cascade_subtrees(&mut self, stylesheet: &Stylesheet, roots: &[NodeId]);
fn cascade_subtrees_all(&mut self, stylesheets: &[&Stylesheet], roots: &[NodeId]);
}
impl CascadeExt for Dom<TuiExt> {
fn cascade(&mut self, stylesheet: &Stylesheet) {
self.cascade_all(&[stylesheet]);
}
fn cascade_all(&mut self, stylesheets: &[&Stylesheet]) {
let merged_vars = walk::merge_root_vars(stylesheets);
let root = self.root();
let parent = ComputedStyle::initial();
let _ = walk::cascade_subtree(self, stylesheets, &merged_vars, root, &parent);
}
fn cascade_subtrees(&mut self, stylesheet: &Stylesheet, roots: &[NodeId]) {
self.cascade_subtrees_all(&[stylesheet], roots);
}
fn cascade_subtrees_all(&mut self, stylesheets: &[&Stylesheet], roots: &[NodeId]) {
let merged_vars = walk::merge_root_vars(stylesheets);
for &root in roots {
let parent_computed = self
.node(root)
.parent_node()
.and_then(|p| p.ext().and_then(|e| e.computed.clone()))
.unwrap_or_else(ComputedStyle::initial);
let flags =
walk::cascade_subtree(self, stylesheets, &merged_vars, root, &parent_computed);
if flags.has_positioned_pseudo || flags.has_collapse {
let mut cur = self.node(root).parent_node().map(|p| p.id());
while let Some(p) = cur {
if let Some(ext) = self.node_mut(p).ext_mut() {
if flags.has_positioned_pseudo {
ext.tree_has_positioned_pseudo = true;
}
if flags.has_collapse {
ext.tree_has_collapse = true;
}
}
cur = self.node(p).parent_node().map(|n| n.id());
}
}
}
}
}
pub fn computed_of(dom: &Dom<TuiExt>, id: NodeId) -> ComputedStyle {
dom.node(id)
.ext()
.and_then(|e| e.computed.clone())
.unwrap_or_else(ComputedStyle::initial)
}