Fix table rendering layout and alignment
This commit is contained in:
@@ -77,6 +77,9 @@ pub fn layout_dom(tree: &DomTree, viewport: (f32, f32)) -> DomLayout {
|
|||||||
crate::style::apply_inline(style, &format!("width: {}", width));
|
crate::style::apply_inline(style, &format!("width: {}", width));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if let Some(align) = node.get_attribute("align") {
|
||||||
|
crate::style::apply_inline(style, &format!("text-align: {}", align));
|
||||||
|
}
|
||||||
if let Some(height) = node.get_attribute("height") {
|
if let Some(height) = node.get_attribute("height") {
|
||||||
if height.chars().all(|c| c.is_ascii_digit()) {
|
if height.chars().all(|c| c.is_ascii_digit()) {
|
||||||
crate::style::apply_inline(style, &format!("height: {}px", height));
|
crate::style::apply_inline(style, &format!("height: {}px", height));
|
||||||
@@ -84,6 +87,16 @@ pub fn layout_dom(tree: &DomTree, viewport: (f32, f32)) -> DomLayout {
|
|||||||
crate::style::apply_inline(style, &format!("height: {}", height));
|
crate::style::apply_inline(style, &format!("height: {}", height));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// For table cells with right alignment, make them grow to push content to the right
|
||||||
|
if let Some(elem) = node.as_element() {
|
||||||
|
let local = elem.local.as_ref();
|
||||||
|
if local == "td" || local == "th" {
|
||||||
|
let is_title = node.get_attribute("class").unwrap_or_default().contains("title");
|
||||||
|
if !is_title && style.justify_content == Some(taffy::JustifyContent::FlexEnd) {
|
||||||
|
style.flex_grow = Some(1.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -234,7 +247,28 @@ fn build(
|
|||||||
|
|
||||||
let _name = node.as_element()?;
|
let _name = node.as_element()?;
|
||||||
let style = styles.get(&id)?;
|
let style = styles.get(&id)?;
|
||||||
let taffy_style = to_taffy_style(style);
|
let mut taffy_style = to_taffy_style(style);
|
||||||
|
|
||||||
|
// Emulate HTML table layout by giving the last td in a tr all remaining space
|
||||||
|
if _name.local.as_ref() == "td" || _name.local.as_ref() == "th" {
|
||||||
|
if let Some(parent_id) = node.parent {
|
||||||
|
if let Some(parent) = tree.get_node(parent_id) {
|
||||||
|
if parent.as_element().map_or(false, |e| e.local.as_ref() == "tr") {
|
||||||
|
let mut last_td = None;
|
||||||
|
for cid in tree.children(parent_id) {
|
||||||
|
if let Some(child) = tree.get_node(cid) {
|
||||||
|
if child.as_element().map_or(false, |e| e.local.as_ref() == "td" || e.local.as_ref() == "th") {
|
||||||
|
last_td = Some(cid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if last_td == Some(id) {
|
||||||
|
taffy_style.flex_grow = 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let child_ids: Vec<taffy::NodeId> = tree
|
let child_ids: Vec<taffy::NodeId> = tree
|
||||||
.children(id)
|
.children(id)
|
||||||
|
|||||||
@@ -79,6 +79,8 @@ pub struct LayoutStyle {
|
|||||||
pub font_size: Option<f32>,
|
pub font_size: Option<f32>,
|
||||||
pub align_items: Option<taffy::AlignItems>,
|
pub align_items: Option<taffy::AlignItems>,
|
||||||
pub flex_direction: Option<taffy::FlexDirection>,
|
pub flex_direction: Option<taffy::FlexDirection>,
|
||||||
|
pub justify_content: Option<taffy::JustifyContent>,
|
||||||
|
pub flex_grow: Option<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A node in the input layout tree. `text` is carried for the paint phase; it
|
/// A node in the input layout tree. `text` is carried for the paint phase; it
|
||||||
@@ -159,10 +161,13 @@ pub(crate) fn to_taffy_style(style: &LayoutStyle) -> Style {
|
|||||||
};
|
};
|
||||||
if let Some(fd) = style.flex_direction {
|
if let Some(fd) = style.flex_direction {
|
||||||
s.flex_direction = fd;
|
s.flex_direction = fd;
|
||||||
|
s.flex_wrap = taffy::FlexWrap::NoWrap;
|
||||||
} else if style.display == Display::Inline {
|
} else if style.display == Display::Inline {
|
||||||
s.flex_direction = taffy::FlexDirection::Row;
|
s.flex_direction = taffy::FlexDirection::Row;
|
||||||
|
s.flex_wrap = taffy::FlexWrap::Wrap;
|
||||||
|
} else {
|
||||||
|
s.flex_wrap = taffy::FlexWrap::NoWrap;
|
||||||
}
|
}
|
||||||
s.flex_wrap = taffy::FlexWrap::Wrap;
|
|
||||||
s.size = taffy::Size {
|
s.size = taffy::Size {
|
||||||
width: dimension(style.width),
|
width: dimension(style.width),
|
||||||
height: dimension(style.height),
|
height: dimension(style.height),
|
||||||
@@ -170,6 +175,12 @@ pub(crate) fn to_taffy_style(style: &LayoutStyle) -> Style {
|
|||||||
if let Some(ai) = style.align_items {
|
if let Some(ai) = style.align_items {
|
||||||
s.align_items = Some(ai);
|
s.align_items = Some(ai);
|
||||||
}
|
}
|
||||||
|
if let Some(jc) = style.justify_content {
|
||||||
|
s.justify_content = Some(jc);
|
||||||
|
}
|
||||||
|
if let Some(fg) = style.flex_grow {
|
||||||
|
s.flex_grow = fg;
|
||||||
|
}
|
||||||
s.margin = rect_auto(style.margin);
|
s.margin = rect_auto(style.margin);
|
||||||
s.padding = rect_lp(style.padding);
|
s.padding = rect_lp(style.padding);
|
||||||
s.border = rect_lp(style.border);
|
s.border = rect_lp(style.border);
|
||||||
|
|||||||
@@ -127,12 +127,15 @@ fn paint_text_node(
|
|||||||
) -> Option<()> {
|
) -> Option<()> {
|
||||||
let node = tree.get_node(nid)?;
|
let node = tree.get_node(nid)?;
|
||||||
let text = match &node.data {
|
let text = match &node.data {
|
||||||
obscura_dom::tree::NodeData::Text { contents } => contents.trim(),
|
obscura_dom::tree::NodeData::Text { contents } => {
|
||||||
|
if contents.trim().is_empty() {
|
||||||
|
" "
|
||||||
|
} else {
|
||||||
|
contents
|
||||||
|
}
|
||||||
|
},
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
if text.is_empty() {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let parent = node.parent?;
|
let parent = node.parent?;
|
||||||
let style = laid.styles.get(&parent)?;
|
let style = laid.styles.get(&parent)?;
|
||||||
|
|||||||
@@ -35,6 +35,15 @@ pub fn ua_style(tag: &str) -> LayoutStyle {
|
|||||||
style.align_items = Some(taffy::AlignItems::Center);
|
style.align_items = Some(taffy::AlignItems::Center);
|
||||||
} else if tag == "body" {
|
} else if tag == "body" {
|
||||||
style.margin = Edges { top: 8.0, right: 8.0, bottom: 8.0, left: 8.0 };
|
style.margin = Edges { top: 8.0, right: 8.0, bottom: 8.0, left: 8.0 };
|
||||||
|
} else if tag == "table" || tag == "tbody" {
|
||||||
|
style.display = Display::Flex;
|
||||||
|
style.flex_direction = Some(taffy::FlexDirection::Column);
|
||||||
|
style.align_items = Some(taffy::AlignItems::Stretch); // stretch rows to fill table width
|
||||||
|
} else if tag == "td" || tag == "th" {
|
||||||
|
style.display = Display::Flex;
|
||||||
|
style.flex_direction = Some(taffy::FlexDirection::Column);
|
||||||
|
style.align_items = Some(taffy::AlignItems::FlexStart);
|
||||||
|
style.padding = Edges { top: 0.0, right: 5.0, bottom: 0.0, left: 0.0 };
|
||||||
}
|
}
|
||||||
style
|
style
|
||||||
}
|
}
|
||||||
@@ -88,6 +97,13 @@ fn apply_value(style: &mut LayoutStyle, name: &str, value: &str) {
|
|||||||
"color" => style.color = parse_color(value),
|
"color" => style.color = parse_color(value),
|
||||||
"border-color" => style.border_color = parse_color(value),
|
"border-color" => style.border_color = parse_color(value),
|
||||||
"font-size" => style.font_size = px(value),
|
"font-size" => style.font_size = px(value),
|
||||||
|
"text-align" => {
|
||||||
|
if value == "right" {
|
||||||
|
style.justify_content = Some(taffy::JustifyContent::FlexEnd);
|
||||||
|
} else if value == "center" {
|
||||||
|
style.justify_content = Some(taffy::JustifyContent::Center);
|
||||||
|
}
|
||||||
|
},
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user