From 0529948d83a735c102f19f78e717a36825e6a6e4 Mon Sep 17 00:00:00 2001 From: Nico Burns Date: Thu, 20 Jun 2024 16:09:56 +1200 Subject: [PATCH] Enable CSS Grid and row-gap styles --- packages/dom/src/stylo.rs | 126 +++++++++++++++++---------- packages/dom/src/stylo_to_taffy.rs | 133 +++++++++++++++++++++++++++++ 2 files changed, 212 insertions(+), 47 deletions(-) diff --git a/packages/dom/src/stylo.rs b/packages/dom/src/stylo.rs index d4cc8906..fed00ea9 100644 --- a/packages/dom/src/stylo.rs +++ b/packages/dom/src/stylo.rs @@ -67,28 +67,45 @@ impl crate::document::Document { right, bottom, left, - // z_index, - flex_direction, - flex_wrap, - justify_content, - align_content, - justify_items, - align_items, - flex_grow, - flex_shrink, - justify_self, - align_self, - // order, - flex_basis, + width, min_width, max_width, height, min_height, max_height, + aspect_ratio, + // box_sizing, + // z_index, + // order, column_gap, - aspect_ratio, + row_gap, + + justify_content, + justify_items, + justify_self, + align_content, + align_items, + align_self, + + flex_direction, + flex_wrap, + flex_basis, + flex_grow, + flex_shrink, + + grid_auto_flow, + + grid_template_columns, + grid_template_rows, + grid_auto_columns, + grid_auto_rows, + + grid_column_start, + grid_column_end, + grid_row_start, + grid_row_end, .. } = style.get_position(); @@ -121,20 +138,15 @@ impl crate::document::Document { node.style = Style { display, position: stylo_to_taffy::position(*position), - margin: stylo_to_taffy::margin(margin), - padding: stylo_to_taffy::padding(padding), - border: stylo_to_taffy::border(border), - flex_direction: stylo_to_taffy::flex_direction(*flex_direction), - flex_wrap: stylo_to_taffy::flex_wrap(*flex_wrap), - justify_content: stylo_to_taffy::content_alignment(justify_content.0), - justify_items: stylo_to_taffy::item_alignment(justify_items.computed.0), - justify_self: stylo_to_taffy::item_alignment((justify_self.0).0), - align_content: stylo_to_taffy::content_alignment(align_content.0), - align_items: stylo_to_taffy::item_alignment(align_items.0), - align_self: stylo_to_taffy::item_alignment((align_self.0).0), - flex_grow: flex_grow.0, - flex_shrink: flex_shrink.0, - flex_basis: stylo_to_taffy::flex_basis(flex_basis), + overflow: taffy::Point { + x: stylo_to_taffy::overflow(*overflow_x), + y: stylo_to_taffy::overflow(*overflow_y), + }, + + // TODO: we'll eventually want to support visible scrollbars + // But we really ought to implement "overflow: auto" first + scrollbar_width: 0.0, + size: taffy::Size { width: stylo_to_taffy::dimension(width), height: stylo_to_taffy::dimension(height), @@ -147,36 +159,56 @@ impl crate::document::Document { width: stylo_to_taffy::max_size_dimension(max_width), height: stylo_to_taffy::max_size_dimension(max_height), }, + aspect_ratio: stylo_to_taffy::aspect_ratio(*aspect_ratio), + + margin: stylo_to_taffy::margin(margin), + padding: stylo_to_taffy::padding(padding), + border: stylo_to_taffy::border(border), inset: taffy::Rect { left: stylo_to_taffy::length_percentage_auto(left), right: stylo_to_taffy::length_percentage_auto(right), top: stylo_to_taffy::length_percentage_auto(top), bottom: stylo_to_taffy::length_percentage_auto(bottom), }, - overflow: taffy::Point { - x: stylo_to_taffy::overflow(*overflow_x), - y: stylo_to_taffy::overflow(*overflow_y), - }, - aspect_ratio: stylo_to_taffy::aspect_ratio(*aspect_ratio), - // TODO: we'll eventually want to support visible scrollbars - // But we really ought to implement "overflow: auto" first - scrollbar_width: 0.0, + // Alignment properties + justify_content: stylo_to_taffy::content_alignment(justify_content.0), + justify_items: stylo_to_taffy::item_alignment(justify_items.computed.0), + justify_self: stylo_to_taffy::item_alignment((justify_self.0).0), + align_content: stylo_to_taffy::content_alignment(align_content.0), + align_items: stylo_to_taffy::item_alignment(align_items.0), + align_self: stylo_to_taffy::item_alignment((align_self.0).0), + + // Gap gap: taffy::Size { width: stylo_to_taffy::gap(column_gap), - // TODO: Enable row-gap in servo configuration of stylo - height: taffy::LengthPercentage::Length(0.0), + height: stylo_to_taffy::gap(row_gap), + }, + + // Flexbox properties + flex_direction: stylo_to_taffy::flex_direction(*flex_direction), + flex_wrap: stylo_to_taffy::flex_wrap(*flex_wrap), + flex_grow: flex_grow.0, + flex_shrink: flex_shrink.0, + flex_basis: stylo_to_taffy::flex_basis(flex_basis), + + // CSS Grid properties + grid_auto_flow: stylo_to_taffy::grid_auto_flow(*grid_auto_flow), + grid_template_rows: stylo_to_taffy::grid_template_tracks(grid_template_rows), + grid_template_columns: stylo_to_taffy::grid_template_tracks( + grid_template_columns, + ), + grid_auto_rows: stylo_to_taffy::grid_auto_tracks(grid_auto_rows), + grid_auto_columns: stylo_to_taffy::grid_auto_tracks(grid_auto_columns), + grid_row: taffy::Line { + start: stylo_to_taffy::grid_line(grid_row_start), + end: stylo_to_taffy::grid_line(grid_row_end), + }, + grid_column: taffy::Line { + start: stylo_to_taffy::grid_line(grid_column_start), + end: stylo_to_taffy::grid_line(grid_column_end), }, - // TODO: Enable CSS Grid properties in servo configuration of stylo - // - // grid_template_rows - // grid_template_columns - // grid_auto_rows - // grid_auto_columns - // grid_auto_flow - // grid_row - // grid_column ..Style::DEFAULT }; diff --git a/packages/dom/src/stylo_to_taffy.rs b/packages/dom/src/stylo_to_taffy.rs index dafc2d55..e307365c 100644 --- a/packages/dom/src/stylo_to_taffy.rs +++ b/packages/dom/src/stylo_to_taffy.rs @@ -4,11 +4,19 @@ mod stylo { pub(crate) use style::computed_values::flex_direction::T as FlexDirection; pub(crate) use style::computed_values::flex_wrap::T as FlexWrap; + pub(crate) use style::computed_values::grid_auto_flow::T as GridAutoFlow; pub(crate) use style::properties::longhands::aspect_ratio::computed_value::T as AspectRatio; pub(crate) use style::properties::longhands::position::computed_value::T as Position; pub(crate) use style::properties::style_structs::{Margin, Padding}; + pub(crate) use style::values::computed::GridLine; + pub(crate) use style::values::computed::GridTemplateComponent; + pub(crate) use style::values::computed::ImplicitGridTracks; pub(crate) use style::values::computed::LengthPercentage; pub(crate) use style::values::generics::flex::GenericFlexBasis; + pub(crate) use style::values::generics::grid::RepeatCount; + pub(crate) use style::values::generics::grid::TrackBreadth; + pub(crate) use style::values::generics::grid::TrackListValue; + pub(crate) use style::values::generics::grid::TrackSize; pub(crate) use style::values::generics::length::GenericLengthPercentageOrAuto; pub(crate) use style::values::generics::length::GenericLengthPercentageOrNormal; pub(crate) use style::values::generics::length::GenericMaxSize; @@ -21,6 +29,7 @@ mod stylo { pub(crate) use style::values::specified::box_::DisplayInside; pub(crate) use style::values::specified::box_::DisplayOutside; pub(crate) use style::values::specified::box_::Overflow; + pub(crate) use style::values::specified::GenericGridTemplateComponent; pub(crate) type LengthPercentageAuto = GenericLengthPercentageOrAuto; pub(crate) type Size = GenericSize>; pub(crate) type MaxSize = GenericMaxSize>; @@ -99,6 +108,7 @@ pub(crate) fn display(input: stylo::Display) -> taffy::Display { let mut display = match input.inside() { stylo::DisplayInside::None => taffy::Display::None, stylo::DisplayInside::Flex => taffy::Display::Flex, + // stylo::DisplayInside::Grid => taffy::Display::Grid, stylo::DisplayInside::Flow => taffy::Display::Block, stylo::DisplayInside::FlowRoot => taffy::Display::Block, // TODO: Support grid layout in servo configuration of stylo @@ -190,6 +200,129 @@ pub(crate) fn flex_wrap(input: stylo::FlexWrap) -> taffy::FlexWrap { } } +pub(crate) fn grid_auto_flow(input: stylo::GridAutoFlow) -> taffy::GridAutoFlow { + let is_row = input.contains(stylo::GridAutoFlow::ROW); + let is_dense = input.contains(stylo::GridAutoFlow::DENSE); + + match (is_row, is_dense) { + (true, false) => taffy::GridAutoFlow::Row, + (true, true) => taffy::GridAutoFlow::RowDense, + (false, false) => taffy::GridAutoFlow::Column, + (false, true) => taffy::GridAutoFlow::ColumnDense, + } +} + +pub(crate) fn grid_line(input: &stylo::GridLine) -> taffy::GridPlacement { + if input.is_auto() { + taffy::GridPlacement::Auto + } else if input.is_span { + taffy::style_helpers::span(input.line_num.try_into().unwrap()) + } else { + taffy::style_helpers::line(input.line_num.try_into().unwrap()) + } +} + +pub(crate) fn grid_template_tracks( + input: &stylo::GridTemplateComponent, +) -> Vec { + match input { + stylo::GenericGridTemplateComponent::None => Vec::new(), + stylo::GenericGridTemplateComponent::TrackList(list) => list + .values + .iter() + .map(|track| match track { + stylo::TrackListValue::TrackSize(size) => { + taffy::TrackSizingFunction::Single(track_size(size)) + } + stylo::TrackListValue::TrackRepeat(repeat) => { + taffy::TrackSizingFunction::Repeat(track_repeat(repeat.count), { + repeat + .track_sizes + .iter() + .map(|track| track_size(track)) + .collect() + }) + } + }) + .collect(), + + // TODO: Implement subgrid and masonry + stylo::GenericGridTemplateComponent::Subgrid(_) => Vec::new(), + stylo::GenericGridTemplateComponent::Masonry => Vec::new(), + } +} + +pub(crate) fn grid_auto_tracks( + input: &stylo::ImplicitGridTracks, +) -> Vec { + input.0.iter().map(|track| track_size(track)).collect() +} + +pub(crate) fn track_repeat(input: stylo::RepeatCount) -> taffy::GridTrackRepetition { + match input { + stylo::RepeatCount::Number(val) => { + taffy::GridTrackRepetition::Count(val.try_into().unwrap()) + } + stylo::RepeatCount::AutoFill => taffy::GridTrackRepetition::AutoFill, + stylo::RepeatCount::AutoFit => taffy::GridTrackRepetition::AutoFit, + } +} + +pub(crate) fn track_size( + input: &stylo::TrackSize, +) -> taffy::NonRepeatedTrackSizingFunction { + match input { + stylo::TrackSize::Breadth(breadth) => taffy::MinMax { + min: min_track(breadth), + max: max_track(breadth), + }, + stylo::TrackSize::Minmax(min, max) => taffy::MinMax { + min: min_track(min), + max: max_track(max), + }, + stylo::TrackSize::FitContent(limit) => taffy::MinMax { + min: taffy::MinTrackSizingFunction::Auto, + max: taffy::MaxTrackSizingFunction::FitContent(match limit { + stylo::TrackBreadth::Breadth(lp) => length_percentage(lp), + + // Are these valid? Taffy doesn't support this in any case + stylo::TrackBreadth::Fr(_) => todo!(), + stylo::TrackBreadth::Auto => todo!(), + stylo::TrackBreadth::MinContent => todo!(), + stylo::TrackBreadth::MaxContent => todo!(), + }), + }, + } +} + +pub(crate) fn min_track( + input: &stylo::TrackBreadth, +) -> taffy::MinTrackSizingFunction { + match input { + stylo::TrackBreadth::Breadth(lp) => { + taffy::MinTrackSizingFunction::Fixed(length_percentage(lp)) + } + stylo::TrackBreadth::Fr(_) => taffy::MinTrackSizingFunction::Auto, + stylo::TrackBreadth::Auto => taffy::MinTrackSizingFunction::Auto, + stylo::TrackBreadth::MinContent => taffy::MinTrackSizingFunction::MinContent, + stylo::TrackBreadth::MaxContent => taffy::MinTrackSizingFunction::MaxContent, + } +} + +pub(crate) fn max_track( + input: &stylo::TrackBreadth, +) -> taffy::MaxTrackSizingFunction { + match input { + stylo::TrackBreadth::Breadth(lp) => { + taffy::MaxTrackSizingFunction::Fixed(length_percentage(lp)) + } + stylo::TrackBreadth::Fr(val) => taffy::MaxTrackSizingFunction::Fraction(*val), + stylo::TrackBreadth::Auto => taffy::MaxTrackSizingFunction::Auto, + stylo::TrackBreadth::MinContent => taffy::MaxTrackSizingFunction::MinContent, + stylo::TrackBreadth::MaxContent => taffy::MaxTrackSizingFunction::MaxContent, + } +} + pub(crate) fn content_alignment(input: stylo::ContentDistribution) -> Option { match input.primary().value() { stylo::AlignFlags::NORMAL => None,