#[allow(unused_imports)]
pub use super::*;
#[cfg(test)]
mod extract_tests {
use super::*;
use crate::{
dom::{Dom, NodeData, NodeType},
styled_dom::StyledDom,
};
#[test]
fn extracts_exactly_the_subtree_re_rooted_as_a_div() {
let popup = Dom::create_from_data(NodeData::create_node(NodeType::TransientWindow(
TransientWindowConfig::opened(),
)))
.with_child(Dom::create_p_with_text("inside"));
let full = Dom::create_body()
.with_child(Dom::create_p_with_text("outside"))
.with_child(Dom::create_div().with_child(popup));
let styled = StyledDom::create_from_dom(full);
let nodes = styled.node_data.as_container();
let tw = nodes
.linear_iter()
.find(|n| {
matches!(
nodes.get(*n).map(NodeData::get_node_type),
Some(NodeType::TransientWindow(_))
)
})
.expect("the transient node");
let out = extract_subtree_as_dom(&styled, tw).expect("extracts");
assert!(
matches!(out.root.get_node_type(), NodeType::Div),
"the popup's own root must be a plain container in its window"
);
let out_styled = StyledDom::create_from_dom(out);
let texts: Vec<String> = out_styled
.node_data
.as_ref()
.iter()
.filter_map(|n| match n.get_node_type() {
NodeType::Text(t) => Some(t.as_str().to_string()),
_ => None,
})
.collect();
assert_eq!(texts, vec!["inside".to_string()]);
}
#[test]
fn refuses_a_non_transient_root() {
let styled = StyledDom::create_from_dom(Dom::create_body().with_child(Dom::create_div()));
assert!(extract_subtree_as_dom(&styled, crate::id::NodeId::new(1)).is_none());
}
#[test]
fn resolved_style_travels_with_the_extracted_subtree() {
use azul_css::props::{
basic::{ColorU, PixelValue},
layout::LayoutWidth,
property::{CssProperty, CssPropertyType},
style::StyleTextColor,
};
let popup = Dom::create_from_data(NodeData::create_node(NodeType::TransientWindow(
TransientWindowConfig::opened(),
)))
.with_child(Dom::create_div().with_css("width: 240px;"));
let full = Dom::create_body()
.with_css("color: #123456;") .with_child(Dom::create_div().with_child(popup));
let styled = StyledDom::create_from_dom(full);
let nodes = styled.node_data.as_container();
let tw = nodes
.linear_iter()
.find(|n| {
matches!(
nodes.get(*n).map(NodeData::get_node_type),
Some(NodeType::TransientWindow(_))
)
})
.expect("the transient node");
let out = extract_subtree_as_dom(&styled, tw).expect("extracts");
let root_color = out
.root
.style
.iter_inline_properties()
.find_map(|(p, _)| match p {
CssProperty::TextColor(c) => c.get_property().copied(),
_ => None,
});
assert_eq!(
root_color,
Some(StyleTextColor {
inner: ColorU {
r: 0x12,
g: 0x34,
b: 0x56,
a: 255
}
}),
"the root must carry what it inherited from outside the subtree"
);
let child = out.children.as_ref().first().expect("the sized child");
let width = child
.root
.style
.iter_inline_properties()
.find_map(|(p, _)| match p {
CssProperty::Width(w) => w.get_property().cloned(),
_ => None,
});
assert_eq!(
width,
Some(LayoutWidth::Px(PixelValue::px(240.0))),
"a scoped `with_css` rule must survive extraction"
);
assert!(
child
.root
.style
.iter_inline_properties()
.all(|(p, _)| p.get_type() != CssPropertyType::TextColor),
"a non-root node carries only its OWN matched rules; inheritance is re-derived"
);
}
}