diff --git a/kayle_innate/kayle_innate/src/engine/audit/tree.rs b/kayle_innate/kayle_innate/src/engine/audit/tree.rs index 7ad0255..4dc3b67 100644 --- a/kayle_innate/kayle_innate/src/engine/audit/tree.rs +++ b/kayle_innate/kayle_innate/src/engine/audit/tree.rs @@ -1,3 +1,4 @@ +use crate::console_log; use scraper_forky::selector::Simple; use scraper_forky::ElementRef; use scraper_forky::Html; @@ -5,14 +6,88 @@ use selectors::matching::MatchingContext; use slotmap::DefaultKey; use std::collections::BTreeMap; use std::collections::HashSet; +use std::sync::Arc; use taffy::prelude::*; -use victor_tree::style::values::Direction; -use victor_tree::style::values::WritingMode; +use victor_tree::style::ComputedValues; use victor_tree::style::StyleSet; lazy_static! { static ref NODE_IGNORE: HashSet<&'static str> = - HashSet::from(["meta", "style", "link", "script", "head", "html"]); + HashSet::from(["meta", "style", "link", "script", "head", "html", "body"]); +} + +/// layout style +pub fn node_layout_style(style: Arc) -> Style { + let physical_size = style.box_size().size_to_physical(style.writing_mode()); + // todo: determine if all children at the top level have floats set to use flex-row + Style { + // compute the default layout from CDP + size: Size { + width: if physical_size.x.non_auto().is_none() { + Dimension::Auto + } else { + Dimension::Points(physical_size.x.inner_px()) + }, + height: if physical_size.y.non_auto().is_none() { + Dimension::Auto + } else { + Dimension::Points(physical_size.x.inner_px()) + }, + }, + border: points(style.border_width().inner_px()), + padding: points(style.padding().inner_px()), + margin: points(style.margin().inner_px()), + ..Default::default() + } +} + +/// get a layout leaf a new leaf +pub fn leaf<'a, 'b, 'c>( + element: &ElementRef, + author: &StyleSet, + document: &'a Html, + mut matching_context: &mut MatchingContext<'c, Simple>, + taffy: &mut Taffy, +) -> DefaultKey { + let mut l_leafs: Vec = vec![]; + + for child in element.children() { + match ElementRef::wrap(child) { + Some(element) => { + let name = element.value().name(); + + if !NODE_IGNORE.contains(name) { + let style = victor_tree::style::cascade::style_for_element_ref( + &element, + &author, + &document, + &mut matching_context, + ); + let leaf = taffy.new_leaf(node_layout_style(style)); + + l_leafs.push(leaf.unwrap()) + } + } + _ => (), + } + } + + let style = victor_tree::style::cascade::style_for_element_ref( + &element, + &author, + &document, + &mut matching_context, + ); + + let leaf_style = node_layout_style(style); + + // build leaf with children + if l_leafs.len() > 0 { + taffy.new_with_children(leaf_style, &l_leafs) + } else { + taffy.new_leaf(leaf_style) + } + .unwrap() } /// try to fix all possible issues using a spec against the tree. @@ -25,91 +100,34 @@ pub fn parse_accessibility_tree<'a, 'b, 'c>( Taffy, MatchingContext<'c, Simple>, ) { - // // todo: use optional variable for clips or layout creation + // TODO: make layout optional let mut taffy = Taffy::new(); - - // let header_node: DefaultKey = taffy - // .new_leaf(Style { - // size: Size { - // width: points(800.0), - // height: points(100.0), - // }, - // ..Default::default() - // }) - // .unwrap(); - - // let body_node = taffy - // .new_leaf(Style { - // size: Size { - // width: points(800.0), - // height: auto(), - // }, - // flex_grow: 1.0, - // ..Default::default() - // }) - // .unwrap(); - - // We can get the x,y, and height, width of the element on proper tree insert - - // parse doc will start from html downwards - // accessibility tree for ordered element mappings let mut accessibility_tree: BTreeMap<&str, Vec<(ElementRef<'_>, DefaultKey)>> = BTreeMap::from([("title".into(), Default::default())]); - - let mut layout_leafs: Vec = vec![]; - - // let mut _match_context = match_context; - let mut matching_context = match_context; - let writing_direction = (WritingMode::HorizontalTb, Direction::Ltr); + let mut layout_leafs: Vec = vec![]; // push taffy layout in order from elements for node in document.tree.nodes() { - match scraper_forky::element_ref::ElementRef::wrap(node) { + match ElementRef::wrap(node) { Some(element) => { let name = element.value().name(); // TODO: determine if children are found to get entire layout of children to vector first - let layout_leaf = taffy - .new_leaf(Style { - // make nodes optional but, for now max out perf drawbacks - size: if NODE_IGNORE.contains(name) { - Size { - width: points(0.0), - height: points(0.0), - } - } else { - let style = victor_tree::style::cascade::style_for_element_ref( - &element, - &author, - &document, - &mut matching_context, - ); - let style = style.as_ref(); - let _physical_size = - style.box_size().size_to_physical(writing_direction); - // TODO: Build physical styles of each element as needed - // crate::console_log!("{name} {:?}", physical_size); - // crate::console_log!("{name} Margin {:?}", style.margin()); - // crate::console_log!("{name} Padding {:?}", style.padding()); - let padding_insent = style.padding().block_start; - // todo: make method to get entire size - let _padding_pxs = padding_insent.inner_px(); - // crate::console_log!("{name} Padding Top {:?}", padding_pxs); - // IF the x and y is empty get the height based on the padding. - // If img has no height get the inherited from style width - // We may have to build the width/height if empty from paddings and margins - // TODO: use flex if element has a x or y but, not both to flex out entire layout. - - Size { - width: points(800.0), - height: points(100.0), - } - }, - // todo: get entire styles up front - flex_grow: if name == "body" { 1.0 } else { 0.0 }, - ..Default::default() - }) - .unwrap(); + let layout_leaf = { + if NODE_IGNORE.contains(name) { + taffy.new_leaf(Default::default()).unwrap() + } else { + // all leafs created must be put into the body node at the end + console_log!("{name}"); + leaf( + &element, + &author, + document, + &mut matching_context, + &mut taffy, + ) + } + }; layout_leafs.push(layout_leaf.clone()); @@ -122,7 +140,6 @@ pub fn parse_accessibility_tree<'a, 'b, 'c>( }; } - // this is slow at the moment for large leafs being mocked let root_node = taffy .new_with_children( Style { @@ -138,8 +155,14 @@ pub fn parse_accessibility_tree<'a, 'b, 'c>( ) .unwrap(); + console_log!("Layout leafs {:?}", layout_leafs.len()); + + // TODO: set the root node to html, body in the accessibility_tree taffy.compute_layout(root_node, Size::MAX_CONTENT).unwrap(); - // crate::console_log!("Last Element Position {:?}", taffy.layout(layout_leafs[layout_leafs.len() - 1]).unwrap()); + + for lea in layout_leafs { + crate::console_log!("Leaf Position {:?}", taffy.layout(lea).unwrap()); + } // console_log!("Getting tree links {:?}", accessibility_tree.get("a")); // console_log!("Tree {:?}", accessibility_tree); diff --git a/kayle_innate/kayle_victor/victor/src/geom.rs b/kayle_innate/kayle_victor/victor/src/geom.rs index 710ee5b..5d5afd2 100644 --- a/kayle_innate/kayle_victor/victor/src/geom.rs +++ b/kayle_innate/kayle_victor/victor/src/geom.rs @@ -2,6 +2,8 @@ pub use crate::style::values::Length; use crate::style::values::{LengthOrAuto, LengthOrPercentage, LengthOrPercentageOrAuto}; pub mod physical { + use crate::style::values::LengthOrPercentage; + #[derive(Debug, Clone)] pub struct Vec2 { pub x: T, @@ -21,6 +23,24 @@ pub mod physical { pub bottom: T, pub right: T, } + + impl Sides { + pub fn inner_px(&self) -> f32 { + let b = Self::get_px::(self.bottom); + let t = Self::get_px::(self.top); + let l = Self::get_px::(self.left); + let r = Self::get_px::(self.left); + + b + t + l + r + } + + pub fn get_px(v: LengthOrPercentage) -> f32 { + match v { + LengthOrPercentage::Length(l) => l.px, + LengthOrPercentage::Percentage(l) => l.unit_value, + } + } + } } pub mod flow_relative { @@ -43,6 +63,30 @@ pub mod flow_relative { pub block_start: T, pub block_end: T, } + + impl Sides { + /// inner pxs added up + pub fn inner_px(&self) -> f32 { + let is = self.inline_start.inner_px(); + let ie = self.inline_end.inner_px(); + let bs = self.block_start.inner_px(); + let be = self.block_end.inner_px(); + + is + ie + bs + be + } + } + + impl Sides { + /// inner pxs added up + pub fn inner_px(&self) -> f32 { + let is = self.inline_start.inner_px(); + let ie = self.inline_end.inner_px(); + let bs = self.block_start.inner_px(); + let be = self.block_end.inner_px(); + + is + ie + bs + be + } + } } use crate::style::values::{Direction, WritingMode}; diff --git a/kayle_innate/kayle_victor/victor/src/style/values/length.rs b/kayle_innate/kayle_victor/victor/src/style/values/length.rs index 5b6df14..27d57d9 100644 --- a/kayle_innate/kayle_victor/victor/src/style/values/length.rs +++ b/kayle_innate/kayle_victor/victor/src/style/values/length.rs @@ -14,7 +14,7 @@ pub struct Length { #[repr(transparent)] #[derive(Copy, Clone, SpecifiedAsComputed)] pub struct Percentage { - unit_value: f32, + pub unit_value: f32, } /// @@ -235,6 +235,14 @@ impl From for LengthOrPercentageOrAuto { } impl LengthOrPercentageOrAuto { + pub fn inner_px(&self) -> f32 { + match self { + LengthOrPercentageOrAuto::Length(l) => l.px, + LengthOrPercentageOrAuto::Percentage(l) => l.unit_value, + LengthOrPercentageOrAuto::Auto => 0.0, + } + } + pub fn non_auto(&self) -> Option { match *self { LengthOrPercentageOrAuto::Length(l) => Some(LengthOrPercentage::Length(l)),