diff --git a/Cargo.toml b/Cargo.toml index 6354e317..a58859a0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,10 +7,10 @@ members = ["packages/blitz", "packages/dom", "packages/dioxus-blitz"] resolver = "2" [workspace.dependencies] -style = { git = "https://github.com/servo/stylo", rev = "039959d" } # 2024-05-15 -style_config = { git = "https://github.com/servo/stylo", rev = "039959d" } # 2024-05-15 -style_traits = { git = "https://github.com/servo/stylo", rev = "039959d" } # 2024-05-15 -selectors = { git = "https://github.com/servo/stylo", rev = "039959d" } # 2024-05-15 +style = { git = "https://github.com/dioxuslabs/stylo", rev = "10767f4" } # 2024-05-15 + dioxus patches +style_config = { git = "https://github.com/dioxuslabs/stylo", rev = "10767f4" } # 2024-05-15 + dioxus patches +style_traits = { git = "https://github.com/dioxuslabs/stylo", rev = "10767f4" } # 2024-05-15 + dioxus patches +selectors = { git = "https://github.com/dioxuslabs/stylo", rev = "10767f4" } # 2024-05-15 + dioxus patches html5ever = "0.27" # needs to match stylo markup5ever version taffy = { version = "0.5.1" } parley = { git = "https://github.com/nicoburns/parley", rev = "482d0fbd59eceaa68cc879e0102a7a9a87636a0d" } diff --git a/README.md b/README.md index a25e640c..ac2a9753 100644 --- a/README.md +++ b/README.md @@ -98,7 +98,9 @@ Blitz is currently **experimental**. We are actively working on bringing into a - [x] Inline (partial support - implementation still immature) - [x] Block - [x] Flexbox -- [ ] Grid (implemented, but needs to be enabled in Stylo) +- [x] Grid + - [ ] Named grid lines + - [ ] Subgrid - [ ] Table - [ ] Z-index - [ ] Additional CSS features diff --git a/packages/dioxus-blitz/src/window.rs b/packages/dioxus-blitz/src/window.rs index f7fa1448..3f5f9d0d 100644 --- a/packages/dioxus-blitz/src/window.rs +++ b/packages/dioxus-blitz/src/window.rs @@ -342,7 +342,6 @@ pub fn init_menu(#[cfg(target_os = "windows")] window: &Window) -> Menu { #[cfg(target_os = "macos")] { - use winit::platform::macos::WindowExtMacOS; menu.init_for_nsapp(); } diff --git a/packages/dom/src/stylo.rs b/packages/dom/src/stylo.rs index 10e99f6e..9e5684eb 100644 --- a/packages/dom/src/stylo.rs +++ b/packages/dom/src/stylo.rs @@ -67,26 +67,45 @@ impl crate::document::Document { right, bottom, left, - // z_index, - flex_direction, - flex_wrap, - justify_content, - align_content, - align_items, - flex_grow, - flex_shrink, - 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(); @@ -119,18 +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::justify_content(*justify_content), - align_content: stylo_to_taffy::align_content(*align_content), - align_items: stylo_to_taffy::align_items(*align_items), - align_self: stylo_to_taffy::align_self(*align_self), - 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), @@ -143,39 +159,55 @@ 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), }, - // TODO: Enable CSS Grid properties in servo configuration of stylo - // - // justify_items - // justify_self - // grid_template_rows - // grid_template_columns - // grid_auto_rows - // grid_auto_columns - // grid_auto_flow - // grid_row - // grid_column - ..Style::DEFAULT + // 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), + }, }; node.display_outer = match stylo_display.outside() { diff --git a/packages/dom/src/stylo_to_taffy.rs b/packages/dom/src/stylo_to_taffy.rs index c99b254c..3a07e490 100644 --- a/packages/dom/src/stylo_to_taffy.rs +++ b/packages/dom/src/stylo_to_taffy.rs @@ -2,29 +2,34 @@ // Module of type aliases so we can refer to stylo types with nicer names mod stylo { - pub(crate) use style::computed_values::align_content::T as AlignContent; - pub(crate) use style::computed_values::align_items::T as AlignItems; - pub(crate) use style::computed_values::align_self::T as AlignSelf; 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::justify_content::T as JustifyContent; - // pub(crate) use style::computed_values::justify_items::T as JustifyItems; - // pub(crate) use style::computed_values::justify_self::T as JustifySelf; + 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; pub(crate) use style::values::generics::length::GenericSize; pub(crate) use style::values::generics::position::PreferredRatio; pub(crate) use style::values::generics::NonNegative; + pub(crate) use style::values::specified::align::AlignFlags; + pub(crate) use style::values::specified::align::ContentDistribution; pub(crate) use style::values::specified::box_::Display; 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>; @@ -103,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 @@ -194,72 +200,154 @@ pub(crate) fn flex_wrap(input: stylo::FlexWrap) -> taffy::FlexWrap { } } -pub(crate) fn justify_content(input: stylo::JustifyContent) -> Option { +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_size).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_size).collect() +} + +pub(crate) fn track_repeat(input: stylo::RepeatCount) -> taffy::GridTrackRepetition { match input { - stylo::JustifyContent::Start => Some(taffy::JustifyContent::Start), - stylo::JustifyContent::End => Some(taffy::JustifyContent::End), - stylo::JustifyContent::FlexStart => Some(taffy::JustifyContent::FlexStart), - stylo::JustifyContent::Stretch => Some(taffy::JustifyContent::Stretch), - stylo::JustifyContent::FlexEnd => Some(taffy::JustifyContent::FlexEnd), - stylo::JustifyContent::Center => Some(taffy::JustifyContent::Center), - stylo::JustifyContent::SpaceBetween => Some(taffy::JustifyContent::SpaceBetween), - stylo::JustifyContent::SpaceAround => Some(taffy::JustifyContent::SpaceAround), - stylo::JustifyContent::SpaceEvenly => Some(taffy::JustifyContent::SpaceEvenly), + 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 align_content(input: stylo::AlignContent) -> Option { +pub(crate) fn track_size( + input: &stylo::TrackSize, +) -> taffy::NonRepeatedTrackSizingFunction { match input { - stylo::AlignContent::Start => Some(taffy::AlignContent::Start), - stylo::AlignContent::End => Some(taffy::AlignContent::End), - stylo::AlignContent::FlexStart => Some(taffy::AlignContent::FlexStart), - stylo::AlignContent::Stretch => Some(taffy::AlignContent::Stretch), - stylo::AlignContent::FlexEnd => Some(taffy::AlignContent::FlexEnd), - stylo::AlignContent::Center => Some(taffy::AlignContent::Center), - stylo::AlignContent::SpaceBetween => Some(taffy::AlignContent::SpaceBetween), - stylo::AlignContent::SpaceAround => Some(taffy::AlignContent::SpaceAround), - stylo::AlignContent::SpaceEvenly => Some(taffy::AlignContent::SpaceEvenly), + 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(_) => unreachable!(), + stylo::TrackBreadth::Auto => unreachable!(), + stylo::TrackBreadth::MinContent => unreachable!(), + stylo::TrackBreadth::MaxContent => unreachable!(), + }), + }, } } -pub(crate) fn align_items(input: stylo::AlignItems) -> Option { +pub(crate) fn min_track( + input: &stylo::TrackBreadth, +) -> taffy::MinTrackSizingFunction { match input { - stylo::AlignItems::Stretch => Some(taffy::AlignItems::Stretch), - stylo::AlignItems::FlexStart => Some(taffy::AlignItems::FlexStart), - stylo::AlignItems::FlexEnd => Some(taffy::AlignItems::FlexEnd), - stylo::AlignItems::Center => Some(taffy::AlignItems::Center), - stylo::AlignItems::Baseline => Some(taffy::AlignItems::Baseline), + 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 align_self(input: stylo::AlignSelf) -> Option { +pub(crate) fn max_track( + input: &stylo::TrackBreadth, +) -> taffy::MaxTrackSizingFunction { match input { - stylo::AlignSelf::Auto => None, - stylo::AlignSelf::Stretch => Some(taffy::AlignSelf::Stretch), - stylo::AlignSelf::FlexStart => Some(taffy::AlignSelf::FlexStart), - stylo::AlignSelf::FlexEnd => Some(taffy::AlignSelf::FlexEnd), - stylo::AlignSelf::Center => Some(taffy::AlignSelf::Center), - stylo::AlignSelf::Baseline => Some(taffy::AlignSelf::Baseline), + 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, + stylo::AlignFlags::AUTO => None, + stylo::AlignFlags::START => Some(taffy::AlignContent::Start), + stylo::AlignFlags::END => Some(taffy::AlignContent::End), + stylo::AlignFlags::FLEX_START => Some(taffy::AlignContent::FlexStart), + stylo::AlignFlags::STRETCH => Some(taffy::AlignContent::Stretch), + stylo::AlignFlags::FLEX_END => Some(taffy::AlignContent::FlexEnd), + stylo::AlignFlags::CENTER => Some(taffy::AlignContent::Center), + stylo::AlignFlags::SPACE_BETWEEN => Some(taffy::AlignContent::SpaceBetween), + stylo::AlignFlags::SPACE_AROUND => Some(taffy::AlignContent::SpaceAround), + stylo::AlignFlags::SPACE_EVENLY => Some(taffy::AlignContent::SpaceEvenly), + // Should never be hit. But no real reason to panic here. + _ => None, } } -// pub(crate) fn justify_items(input: stylo::JustifyItems) -> Option { -// match input { -// stylo::JustifyItems::Stretch => Some(taffy::JustifyItems::Stretch), -// stylo::JustifyItems::FlexStart => Some(taffy::JustifyItems::FlexStart), -// stylo::JustifyItems::FlexEnd => Some(taffy::JustifyItems::FlexEnd), -// stylo::JustifyItems::Center => Some(taffy::JustifyItems::Center), -// stylo::JustifyItems::Baseline => Some(taffy::JustifyItems::Baseline), -// } -// } - -// pub(crate) fn justify_self(input: stylo::JustifySelf) -> Option { -// match input { -// stylo::JustifySelf::Auto => None, -// stylo::JustifySelf::Stretch => Some(taffy::JustifySelf::Stretch), -// stylo::JustifySelf::FlexStart => Some(taffy::JustifySelf::FlexStart), -// stylo::JustifySelf::FlexEnd => Some(taffy::JustifySelf::FlexEnd), -// stylo::JustifySelf::Center => Some(taffy::JustifySelf::Center), -// stylo::JustifySelf::Baseline => Some(taffy::JustifySelf::Baseline), -// } -// } +pub(crate) fn item_alignment(input: stylo::AlignFlags) -> Option { + match input.value() { + stylo::AlignFlags::NORMAL => None, + stylo::AlignFlags::AUTO => None, + stylo::AlignFlags::STRETCH => Some(taffy::AlignItems::Stretch), + stylo::AlignFlags::FLEX_START => Some(taffy::AlignItems::FlexStart), + stylo::AlignFlags::FLEX_END => Some(taffy::AlignItems::FlexEnd), + stylo::AlignFlags::START => Some(taffy::AlignItems::Start), + stylo::AlignFlags::END => Some(taffy::AlignItems::End), + stylo::AlignFlags::CENTER => Some(taffy::AlignItems::Center), + stylo::AlignFlags::BASELINE => Some(taffy::AlignItems::Baseline), + // Should never be hit. But no real reason to panic here. + _ => None, + } +}