azul_core/dom_table.rs
1// Table layout support for generating anonymous table elements
2// Based on CSS 2.1 Section 17.2.1: Anonymous table objects
3
4use alloc::vec::Vec;
5
6use azul_css::props::layout::LayoutDisplay;
7
8use crate::{
9 dom::{NodeData, NodeType},
10 id::NodeId,
11 styled_dom::StyledDom,
12};
13
14/// Error type for table anonymous element generation
15#[derive(Debug, Clone, PartialEq, Eq)]
16pub enum TableAnonymousError {
17 /// Invalid node ID provided
18 InvalidNodeId,
19 /// No display property found for node
20 NoDisplayProperty,
21}
22
23/// Generates anonymous table elements according to CSS table layout rules.
24///
25/// This function works on StyledDom (not Dom) because it needs access to computed
26/// CSS display property values to determine which elements need wrapping.
27///
28/// This function ensures that:
29/// - Table elements have proper table-row and table-cell children
30/// - Non-table children of tables are wrapped in anonymous table-row and table-cell boxes
31/// - The resulting DOM tree is suitable for table layout algorithms
32/// - All generated anonymous nodes are marked with is_anonymous=true
33///
34/// Must be called after CSS cascade but before layout calculation.
35///
36/// Implementation follows CSS 2.2 Section 17.2.1:
37/// - Stage 1: Remove irrelevant whitespace
38/// - Stage 2: Generate missing child wrappers
39/// - Stage 3: Generate missing parents
40pub fn generate_anonymous_table_elements(
41 styled_dom: &mut StyledDom,
42) -> Result<(), TableAnonymousError> {
43 // TODO: Implement the full 3-stage algorithm
44 // This is a complex task that requires:
45 // 1. Traversing the entire tree
46 // 2. Identifying nodes with table display values
47 // 3. Checking if their children have correct display values
48 // 4. Inserting anonymous wrapper nodes where needed
49 // 5. Marking all generated nodes with is_anonymous=true
50 //
51 // For now, this is a placeholder that returns Ok(())
52 // The actual implementation will need to:
53 // - Access styled_dom.node_hierarchy for tree structure
54 // - Access styled_dom.node_data for node information
55 // - Access styled_dom.css_property_cache for display properties
56 // - Insert new nodes into both hierarchy and data containers
57 // - Update parent-child-sibling relationships
58 //
59 // This is left for future implementation as it requires careful
60 // manipulation of the arena-based data structures.
61
62 Ok(())
63}
64
65/// Helper function to check if a display value represents a proper table child
66fn is_proper_table_child(display: &LayoutDisplay) -> bool {
67 matches!(
68 display,
69 LayoutDisplay::TableRowGroup
70 | LayoutDisplay::TableHeaderGroup
71 | LayoutDisplay::TableFooterGroup
72 | LayoutDisplay::TableRow
73 | LayoutDisplay::TableCaption
74 | LayoutDisplay::TableColumn
75 | LayoutDisplay::TableColumnGroup
76 )
77}
78
79/// Helper function to check if a display value represents a table row
80fn is_table_row(display: &LayoutDisplay) -> bool {
81 matches!(display, LayoutDisplay::TableRow)
82}
83
84/// Helper function to check if a display value represents a table cell
85fn is_table_cell(display: &LayoutDisplay) -> bool {
86 matches!(display, LayoutDisplay::TableCell)
87}
88
89/// Helper function to check if a display value represents a table or inline-table
90fn is_table_element(display: &LayoutDisplay) -> bool {
91 matches!(display, LayoutDisplay::Table | LayoutDisplay::InlineTable)
92}
93
94/// Helper function to get the computed display property for a node
95fn get_node_display(styled_dom: &StyledDom, node_id: NodeId) -> Option<LayoutDisplay> {
96 // Get display property from CSS property cache
97 let cache = styled_dom.get_css_property_cache();
98 let node_data = &styled_dom.node_data.as_ref()[node_id.index()];
99 let node_state = &styled_dom.styled_nodes.as_container()[node_id].styled_node_state;
100
101 cache
102 .get_display(node_data, &node_id, node_state)
103 .and_then(|value| value.get_property().cloned())
104}