|
@@ -1,7 +1,7 @@
|
|
/*
|
|
/*
|
|
- [ ] pub display: Display,
|
|
- [ ] pub display: Display,
|
|
- [x] pub position_type: PositionType, --> kinda, taffy doesnt support everything
|
|
- [x] pub position_type: PositionType, --> kinda, taffy doesnt support everything
|
|
-- [ ] pub direction: Direction,
|
|
|
|
|
|
+- [x] pub direction: Direction,
|
|
|
|
|
|
- [x] pub flex_direction: FlexDirection,
|
|
- [x] pub flex_direction: FlexDirection,
|
|
- [x] pub flex_wrap: FlexWrap,
|
|
- [x] pub flex_wrap: FlexWrap,
|
|
@@ -19,7 +19,7 @@
|
|
- [x] pub padding: Rect<Dimension>,
|
|
- [x] pub padding: Rect<Dimension>,
|
|
|
|
|
|
- [x] pub justify_content: JustifyContent,
|
|
- [x] pub justify_content: JustifyContent,
|
|
-- [ ] pub position: Rect<Dimension>,
|
|
|
|
|
|
+- [x] pub position: Rect<Dimension>,
|
|
- [x] pub border: Rect<Dimension>,
|
|
- [x] pub border: Rect<Dimension>,
|
|
|
|
|
|
- [ ] pub size: Size<Dimension>, ----> ??? seems to only be relevant for input?
|
|
- [ ] pub size: Size<Dimension>, ----> ??? seems to only be relevant for input?
|
|
@@ -29,6 +29,14 @@
|
|
- [ ] pub aspect_ratio: Number,
|
|
- [ ] pub aspect_ratio: Number,
|
|
*/
|
|
*/
|
|
|
|
|
|
|
|
+use lightningcss::{
|
|
|
|
+ properties::{align::GapValue, border::BorderSideWidth, Property, PropertyId},
|
|
|
|
+ stylesheet::ParserOptions,
|
|
|
|
+ values::{
|
|
|
|
+ length::{Length, LengthPercentageOrAuto, LengthValue},
|
|
|
|
+ percentage::DimensionPercentage,
|
|
|
|
+ },
|
|
|
|
+};
|
|
use taffy::{
|
|
use taffy::{
|
|
prelude::*,
|
|
prelude::*,
|
|
style::{FlexDirection, PositionType},
|
|
style::{FlexDirection, PositionType},
|
|
@@ -36,556 +44,367 @@ use taffy::{
|
|
|
|
|
|
/// applies the entire html namespace defined in dioxus-html
|
|
/// applies the entire html namespace defined in dioxus-html
|
|
pub fn apply_layout_attributes(name: &str, value: &str, style: &mut Style) {
|
|
pub fn apply_layout_attributes(name: &str, value: &str, style: &mut Style) {
|
|
- match name {
|
|
|
|
- "align-content"
|
|
|
|
- | "align-items"
|
|
|
|
- | "align-self" => apply_align(name, value, style),
|
|
|
|
-
|
|
|
|
- "animation"
|
|
|
|
- | "animation-delay"
|
|
|
|
- | "animation-direction"
|
|
|
|
- | "animation-duration"
|
|
|
|
- | "animation-fill-mode"
|
|
|
|
- | "animation-iteration-count"
|
|
|
|
- | "animation-name"
|
|
|
|
- | "animation-play-state"
|
|
|
|
- | "animation-timing-function" => apply_animation(name, value, style),
|
|
|
|
-
|
|
|
|
- "backface-visibility" => {}
|
|
|
|
-
|
|
|
|
- "border"
|
|
|
|
- | "border-bottom"
|
|
|
|
- | "border-bottom-color"
|
|
|
|
- | "border-bottom-left-radius"
|
|
|
|
- | "border-bottom-right-radius"
|
|
|
|
- | "border-bottom-style"
|
|
|
|
- | "border-bottom-width"
|
|
|
|
- | "border-collapse"
|
|
|
|
- | "border-color"
|
|
|
|
- | "border-image"
|
|
|
|
- | "border-image-outset"
|
|
|
|
- | "border-image-repeat"
|
|
|
|
- | "border-image-slice"
|
|
|
|
- | "border-image-source"
|
|
|
|
- | "border-image-width"
|
|
|
|
- | "border-left"
|
|
|
|
- | "border-left-color"
|
|
|
|
- | "border-left-style"
|
|
|
|
- | "border-left-width"
|
|
|
|
- | "border-radius"
|
|
|
|
- | "border-right"
|
|
|
|
- | "border-right-color"
|
|
|
|
- | "border-right-style"
|
|
|
|
- | "border-right-width"
|
|
|
|
- | "border-spacing"
|
|
|
|
- | "border-style"
|
|
|
|
- | "border-top"
|
|
|
|
- | "border-top-color"
|
|
|
|
- | "border-top-left-radius"
|
|
|
|
- | "border-top-right-radius"
|
|
|
|
- | "border-top-style"
|
|
|
|
- | "border-top-width"
|
|
|
|
- | "border-width" => apply_border(name, value, style),
|
|
|
|
-
|
|
|
|
- "bottom" => {}
|
|
|
|
- "box-shadow" => {}
|
|
|
|
- "box-sizing" => {}
|
|
|
|
- "caption-side" => {}
|
|
|
|
- "clear" => {}
|
|
|
|
- "clip" => {}
|
|
|
|
-
|
|
|
|
- "column-count"
|
|
|
|
- | "column-fill"
|
|
|
|
- | "column-gap"
|
|
|
|
- | "column-rule"
|
|
|
|
- | "column-rule-color"
|
|
|
|
- | "column-rule-style"
|
|
|
|
- | "column-rule-width"
|
|
|
|
- | "column-span"
|
|
|
|
- // add column-width
|
|
|
|
- | "column-width" => apply_column(name, value, style),
|
|
|
|
-
|
|
|
|
- "columns" => {}
|
|
|
|
-
|
|
|
|
- "content" => {}
|
|
|
|
- "counter-increment" => {}
|
|
|
|
- "counter-reset" => {}
|
|
|
|
-
|
|
|
|
- "cursor" => {}
|
|
|
|
- "direction" => {}
|
|
|
|
-
|
|
|
|
- "display" => apply_display(name, value, style),
|
|
|
|
-
|
|
|
|
- "empty-cells" => {}
|
|
|
|
-
|
|
|
|
- "flex"
|
|
|
|
- | "flex-basis"
|
|
|
|
- | "flex-direction"
|
|
|
|
- | "flex-flow"
|
|
|
|
- | "flex-grow"
|
|
|
|
- | "flex-shrink"
|
|
|
|
- | "flex-wrap" => apply_flex(name, value, style),
|
|
|
|
-
|
|
|
|
- "float" => {},
|
|
|
|
-
|
|
|
|
- "font-style"
|
|
|
|
- | "font-variant"
|
|
|
|
- | "font-weight"
|
|
|
|
- | "font-size"
|
|
|
|
- | "line-height"
|
|
|
|
- | "font-family" => apply_font(name, value, style),
|
|
|
|
-
|
|
|
|
- "height" => {
|
|
|
|
- if let Some(v) = parse_value(value){
|
|
|
|
- style.size.height = v;
|
|
|
|
|
|
+ if let Ok(property) =
|
|
|
|
+ Property::parse_string(PropertyId::from(name), value, ParserOptions::default())
|
|
|
|
+ {
|
|
|
|
+ match property {
|
|
|
|
+ Property::Display(display) => match display {
|
|
|
|
+ lightningcss::properties::display::Display::Keyword(_) => todo!(),
|
|
|
|
+ lightningcss::properties::display::Display::Pair(pair) => {
|
|
|
|
+ match pair.outside {
|
|
|
|
+ lightningcss::properties::display::DisplayOutside::Block => {
|
|
|
|
+ style.display = Display::None
|
|
|
|
+ }
|
|
|
|
+ lightningcss::properties::display::DisplayOutside::Inline => todo!(),
|
|
|
|
+ lightningcss::properties::display::DisplayOutside::RunIn => todo!(),
|
|
|
|
+ }
|
|
|
|
+ match pair.inside {
|
|
|
|
+ lightningcss::properties::display::DisplayInside::Flow => todo!(),
|
|
|
|
+ lightningcss::properties::display::DisplayInside::FlowRoot => todo!(),
|
|
|
|
+ lightningcss::properties::display::DisplayInside::Table => todo!(),
|
|
|
|
+ lightningcss::properties::display::DisplayInside::Flex(_) => {
|
|
|
|
+ style.display = Display::Flex
|
|
|
|
+ }
|
|
|
|
+ lightningcss::properties::display::DisplayInside::Box(_) => todo!(),
|
|
|
|
+ lightningcss::properties::display::DisplayInside::Grid => todo!(),
|
|
|
|
+ lightningcss::properties::display::DisplayInside::Ruby => todo!(),
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ Property::Position(position) => {
|
|
|
|
+ style.position_type = match position {
|
|
|
|
+ lightningcss::properties::position::Position::Static => todo!(),
|
|
|
|
+ lightningcss::properties::position::Position::Relative => {
|
|
|
|
+ PositionType::Relative
|
|
|
|
+ }
|
|
|
|
+ lightningcss::properties::position::Position::Absolute => {
|
|
|
|
+ PositionType::Absolute
|
|
|
|
+ }
|
|
|
|
+ lightningcss::properties::position::Position::Sticky(_) => todo!(),
|
|
|
|
+ lightningcss::properties::position::Position::Fixed => todo!(),
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- }
|
|
|
|
- "justify-content" => {
|
|
|
|
- use JustifyContent::*;
|
|
|
|
- style.justify_content = match value {
|
|
|
|
- "flex-start" => FlexStart,
|
|
|
|
- "flex-end" => FlexEnd,
|
|
|
|
- "center" => Center,
|
|
|
|
- "space-between" => SpaceBetween,
|
|
|
|
- "space-around" => SpaceAround,
|
|
|
|
- "space-evenly" => SpaceEvenly,
|
|
|
|
- _ => FlexStart,
|
|
|
|
- };
|
|
|
|
- }
|
|
|
|
- "left" => {}
|
|
|
|
- "letter-spacing" => {}
|
|
|
|
-
|
|
|
|
- "list-style"
|
|
|
|
- | "list-style-image"
|
|
|
|
- | "list-style-position"
|
|
|
|
- | "list-style-type" => {}
|
|
|
|
-
|
|
|
|
- "margin"
|
|
|
|
- | "margin-bottom"
|
|
|
|
- | "margin-left"
|
|
|
|
- | "margin-right"
|
|
|
|
- | "margin-top" => apply_margin(name, value, style),
|
|
|
|
-
|
|
|
|
- "max-height" => {}
|
|
|
|
- "max-width" => {}
|
|
|
|
- "min-height" => {}
|
|
|
|
- "min-width" => {}
|
|
|
|
-
|
|
|
|
- "opacity" => {}
|
|
|
|
- "order" => {}
|
|
|
|
- "outline" => {}
|
|
|
|
-
|
|
|
|
- "outline-color"
|
|
|
|
- | "outline-offset"
|
|
|
|
- | "outline-style"
|
|
|
|
- | "outline-width" => {}
|
|
|
|
-
|
|
|
|
- "overflow"
|
|
|
|
- | "overflow-x"
|
|
|
|
- | "overflow-y" => apply_overflow(name, value, style),
|
|
|
|
-
|
|
|
|
- "padding"
|
|
|
|
- | "padding-bottom"
|
|
|
|
- | "padding-left"
|
|
|
|
- | "padding-right"
|
|
|
|
- | "padding-top" => apply_padding(name, value, style),
|
|
|
|
-
|
|
|
|
- "page-break-after"
|
|
|
|
- | "page-break-before"
|
|
|
|
- | "page-break-inside" => {}
|
|
|
|
-
|
|
|
|
- "perspective"
|
|
|
|
- | "perspective-origin" => {}
|
|
|
|
-
|
|
|
|
- "position" => {
|
|
|
|
- match value {
|
|
|
|
- "static" => {}
|
|
|
|
- "relative" => style.position_type = PositionType::Relative,
|
|
|
|
- "fixed" => {}
|
|
|
|
- "absolute" => style.position_type = PositionType::Absolute,
|
|
|
|
- "sticky" => {}
|
|
|
|
- _ => {}
|
|
|
|
|
|
+ Property::Top(top) => style.position.top = convert_length_percentage_or_auto(top),
|
|
|
|
+ Property::Bottom(bottom) => {
|
|
|
|
+ style.position.bottom = convert_length_percentage_or_auto(bottom)
|
|
}
|
|
}
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- "pointer-events" => {}
|
|
|
|
-
|
|
|
|
- "quotes" => {}
|
|
|
|
- "resize" => {}
|
|
|
|
- "right" => {}
|
|
|
|
- "tab-size" => {}
|
|
|
|
- "table-layout" => {}
|
|
|
|
-
|
|
|
|
- "top" => {}
|
|
|
|
-
|
|
|
|
- "transform"
|
|
|
|
- | "transform-origin"
|
|
|
|
- | "transform-style" => apply_transform(name, value, style),
|
|
|
|
-
|
|
|
|
- "transition"
|
|
|
|
- | "transition-delay"
|
|
|
|
- | "transition-duration"
|
|
|
|
- | "transition-property"
|
|
|
|
- | "transition-timing-function" => apply_transition(name, value, style),
|
|
|
|
-
|
|
|
|
- "vertical-align" => {}
|
|
|
|
- "visibility" => {}
|
|
|
|
- "white-space" => {}
|
|
|
|
- "width" => {
|
|
|
|
- if let Some(v) = parse_value(value){
|
|
|
|
- style.size.width = v;
|
|
|
|
|
|
+ Property::Left(left) => style.position.left = convert_length_percentage_or_auto(left),
|
|
|
|
+ Property::Right(right) => {
|
|
|
|
+ style.position.right = convert_length_percentage_or_auto(right)
|
|
}
|
|
}
|
|
- }
|
|
|
|
- "word-break" => {}
|
|
|
|
- "word-spacing" => {}
|
|
|
|
- "word-wrap" => {}
|
|
|
|
- "z-index" => {}
|
|
|
|
- _ => {}
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-fn apply_font(name: &str, value: &str, style: &mut Style) {
|
|
|
|
- match name {
|
|
|
|
- "font-style" => {}
|
|
|
|
- "font-variant" => {}
|
|
|
|
- "font-weight" => {}
|
|
|
|
- "font-size" => {}
|
|
|
|
- "line-height" => {
|
|
|
|
- style.size = Size {
|
|
|
|
- width: style.size.width,
|
|
|
|
- height: parse_value(value).unwrap_or(Dimension::Points(12.0)),
|
|
|
|
|
|
+ Property::BorderTopWidth(width) => {
|
|
|
|
+ style.border.top = convert_border_side_width(width);
|
|
}
|
|
}
|
|
- }
|
|
|
|
- "font-family" => {}
|
|
|
|
- _ => {}
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/// parse relative or absolute value
|
|
|
|
-pub fn parse_value(value: &str) -> Option<Dimension> {
|
|
|
|
- if value.ends_with("px") {
|
|
|
|
- if let Ok(px) = value.trim_end_matches("px").parse::<f32>() {
|
|
|
|
- Some(Dimension::Points(px))
|
|
|
|
- } else {
|
|
|
|
- None
|
|
|
|
- }
|
|
|
|
- } else if value.ends_with('%') {
|
|
|
|
- if let Ok(pct) = value.trim_end_matches('%').parse::<f32>() {
|
|
|
|
- Some(Dimension::Percent(pct / 100.0))
|
|
|
|
- } else {
|
|
|
|
- None
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- None
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-fn apply_overflow(_name: &str, _value: &str, _style: &mut Style) {
|
|
|
|
- // todo: add overflow support to taffy
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-fn apply_display(_name: &str, value: &str, style: &mut Style) {
|
|
|
|
- style.display = match value {
|
|
|
|
- "flex" => Display::Flex,
|
|
|
|
- "block" => Display::None,
|
|
|
|
- _ => Display::Flex,
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // TODO: there are way more variants
|
|
|
|
- // taffy needs to be updated to handle them
|
|
|
|
- //
|
|
|
|
- // "block" => Display::Block,
|
|
|
|
- // "inline" => Display::Inline,
|
|
|
|
- // "inline-block" => Display::InlineBlock,
|
|
|
|
- // "inline-table" => Display::InlineTable,
|
|
|
|
- // "list-item" => Display::ListItem,
|
|
|
|
- // "run-in" => Display::RunIn,
|
|
|
|
- // "table" => Display::Table,
|
|
|
|
- // "table-caption" => Display::TableCaption,
|
|
|
|
- // "table-cell" => Display::TableCell,
|
|
|
|
- // "table-column" => Display::TableColumn,
|
|
|
|
- // "table-column-group" => Display::TableColumnGroup,
|
|
|
|
- // "table-footer-group" => Display::TableFooterGroup,
|
|
|
|
- // "table-header-group" => Display::TableHeaderGroup,
|
|
|
|
- // "table-row" => Display::TableRow,
|
|
|
|
- // "table-row-group" => Display::TableRowGroup,
|
|
|
|
- // "none" => Display::None,
|
|
|
|
- // _ => Display::Inline,
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-fn apply_border(name: &str, value: &str, style: &mut Style) {
|
|
|
|
- match name {
|
|
|
|
- "border" => {}
|
|
|
|
- "border-bottom" => {}
|
|
|
|
- "border-bottom-color" => {}
|
|
|
|
- "border-bottom-left-radius" => {}
|
|
|
|
- "border-bottom-right-radius" => {}
|
|
|
|
- "border-bottom-style" => {
|
|
|
|
- if style.border.bottom == Dimension::default() {
|
|
|
|
- let v = Dimension::Points(1.0);
|
|
|
|
- style.border.bottom = v;
|
|
|
|
|
|
+ Property::BorderBottomWidth(width) => {
|
|
|
|
+ style.border.bottom = convert_border_side_width(width);
|
|
}
|
|
}
|
|
- }
|
|
|
|
- "border-bottom-width" => {
|
|
|
|
- if let Some(v) = parse_value(value) {
|
|
|
|
- style.border.bottom = v;
|
|
|
|
|
|
+ Property::BorderLeftWidth(width) => {
|
|
|
|
+ style.border.left = convert_border_side_width(width);
|
|
}
|
|
}
|
|
- }
|
|
|
|
- "border-collapse" => {}
|
|
|
|
- "border-color" => {}
|
|
|
|
- "border-image" => {}
|
|
|
|
- "border-image-outset" => {}
|
|
|
|
- "border-image-repeat" => {}
|
|
|
|
- "border-image-slice" => {}
|
|
|
|
- "border-image-source" => {}
|
|
|
|
- "border-image-width" => {}
|
|
|
|
- "border-left" => {}
|
|
|
|
- "border-left-color" => {}
|
|
|
|
- "border-left-style" => {
|
|
|
|
- if style.border.left == Dimension::default() {
|
|
|
|
- let v = Dimension::Points(1.0);
|
|
|
|
- style.border.left = v;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- "border-left-width" => {
|
|
|
|
- if let Some(v) = parse_value(value) {
|
|
|
|
- style.border.left = v;
|
|
|
|
|
|
+ Property::BorderRightWidth(width) => {
|
|
|
|
+ style.border.right = convert_border_side_width(width);
|
|
}
|
|
}
|
|
- }
|
|
|
|
- "border-radius" => {}
|
|
|
|
- "border-right" => {}
|
|
|
|
- "border-right-color" => {}
|
|
|
|
- "border-right-style" => {
|
|
|
|
- let v = Dimension::Points(1.0);
|
|
|
|
- style.border.right = v;
|
|
|
|
- }
|
|
|
|
- "border-right-width" => {
|
|
|
|
- if let Some(v) = parse_value(value) {
|
|
|
|
- style.border.right = v;
|
|
|
|
|
|
+ Property::BorderWidth(width) => {
|
|
|
|
+ style.border.top = convert_border_side_width(width.top);
|
|
|
|
+ style.border.bottom = convert_border_side_width(width.bottom);
|
|
|
|
+ style.border.left = convert_border_side_width(width.left);
|
|
|
|
+ style.border.right = convert_border_side_width(width.right);
|
|
}
|
|
}
|
|
- }
|
|
|
|
- "border-spacing" => {}
|
|
|
|
- "border-style" => {
|
|
|
|
- if style.border.top == Dimension::default() {
|
|
|
|
- let v = Dimension::Points(1.0);
|
|
|
|
- style.border.top = v;
|
|
|
|
|
|
+ Property::Border(border) => {
|
|
|
|
+ let width = convert_border_side_width(border.width);
|
|
|
|
+ style.border.top = width;
|
|
|
|
+ style.border.bottom = width;
|
|
|
|
+ style.border.left = width;
|
|
|
|
+ style.border.right = width;
|
|
}
|
|
}
|
|
- if style.border.bottom == Dimension::default() {
|
|
|
|
- let v = Dimension::Points(1.0);
|
|
|
|
- style.border.bottom = v;
|
|
|
|
|
|
+ Property::BorderTop(top) => {
|
|
|
|
+ style.border.top = convert_border_side_width(top.width);
|
|
}
|
|
}
|
|
- if style.border.left == Dimension::default() {
|
|
|
|
- let v = Dimension::Points(1.0);
|
|
|
|
- style.border.left = v;
|
|
|
|
|
|
+ Property::BorderBottom(bottom) => {
|
|
|
|
+ style.border.bottom = convert_border_side_width(bottom.width);
|
|
}
|
|
}
|
|
- if style.border.right == Dimension::default() {
|
|
|
|
- let v = Dimension::Points(1.0);
|
|
|
|
- style.border.right = v;
|
|
|
|
|
|
+ Property::BorderLeft(left) => {
|
|
|
|
+ style.border.left = convert_border_side_width(left.width);
|
|
}
|
|
}
|
|
- }
|
|
|
|
- "border-top" => {}
|
|
|
|
- "border-top-color" => {}
|
|
|
|
- "border-top-left-radius" => {}
|
|
|
|
- "border-top-right-radius" => {}
|
|
|
|
- "border-top-style" => {
|
|
|
|
- if style.border.top == Dimension::default() {
|
|
|
|
- let v = Dimension::Points(1.0);
|
|
|
|
- style.border.top = v;
|
|
|
|
|
|
+ Property::BorderRight(right) => {
|
|
|
|
+ style.border.right = convert_border_side_width(right.width);
|
|
}
|
|
}
|
|
- }
|
|
|
|
- "border-top-width" => {
|
|
|
|
- if let Some(v) = parse_value(value) {
|
|
|
|
- style.border.top = v;
|
|
|
|
|
|
+ Property::FlexDirection(flex_direction, _) => {
|
|
|
|
+ use FlexDirection::*;
|
|
|
|
+ style.flex_direction = match flex_direction {
|
|
|
|
+ lightningcss::properties::flex::FlexDirection::Row => Row,
|
|
|
|
+ lightningcss::properties::flex::FlexDirection::RowReverse => RowReverse,
|
|
|
|
+ lightningcss::properties::flex::FlexDirection::Column => Column,
|
|
|
|
+ lightningcss::properties::flex::FlexDirection::ColumnReverse => ColumnReverse,
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- }
|
|
|
|
- "border-width" => {
|
|
|
|
- let values: Vec<_> = value.split(' ').collect();
|
|
|
|
- if values.len() == 1 {
|
|
|
|
- if let Some(dim) = parse_value(values[0]) {
|
|
|
|
- style.border = Rect {
|
|
|
|
- right: dim,
|
|
|
|
- left: dim,
|
|
|
|
- top: dim,
|
|
|
|
- bottom: dim,
|
|
|
|
- };
|
|
|
|
|
|
+ Property::FlexWrap(wrap, _) => {
|
|
|
|
+ use FlexWrap::*;
|
|
|
|
+ style.flex_wrap = match wrap {
|
|
|
|
+ lightningcss::properties::flex::FlexWrap::NoWrap => NoWrap,
|
|
|
|
+ lightningcss::properties::flex::FlexWrap::Wrap => Wrap,
|
|
|
|
+ lightningcss::properties::flex::FlexWrap::WrapReverse => WrapReverse,
|
|
}
|
|
}
|
|
- } else {
|
|
|
|
- let border_widths = [
|
|
|
|
- &mut style.border.top,
|
|
|
|
- &mut style.border.bottom,
|
|
|
|
- &mut style.border.left,
|
|
|
|
- &mut style.border.right,
|
|
|
|
- ];
|
|
|
|
- for (v, width) in values.into_iter().zip(border_widths) {
|
|
|
|
- if let Some(w) = parse_value(v) {
|
|
|
|
- *width = w;
|
|
|
|
|
|
+ }
|
|
|
|
+ Property::FlexGrow(grow, _) => {
|
|
|
|
+ style.flex_grow = grow;
|
|
|
|
+ }
|
|
|
|
+ Property::FlexShrink(shrink, _) => {
|
|
|
|
+ style.flex_shrink = shrink;
|
|
|
|
+ }
|
|
|
|
+ Property::FlexBasis(basis, _) => {
|
|
|
|
+ style.flex_basis = convert_length_percentage_or_auto(basis);
|
|
|
|
+ }
|
|
|
|
+ Property::Flex(flex, _) => {
|
|
|
|
+ style.flex_grow = flex.grow;
|
|
|
|
+ style.flex_shrink = flex.shrink;
|
|
|
|
+ style.flex_basis = convert_length_percentage_or_auto(flex.basis);
|
|
|
|
+ }
|
|
|
|
+ Property::AlignContent(align, _) => {
|
|
|
|
+ use AlignContent::*;
|
|
|
|
+ style.align_content = match align {
|
|
|
|
+ lightningcss::properties::align::AlignContent::Normal => todo!(),
|
|
|
|
+ lightningcss::properties::align::AlignContent::BaselinePosition(_) => {
|
|
|
|
+ todo!()
|
|
}
|
|
}
|
|
- }
|
|
|
|
|
|
+ lightningcss::properties::align::AlignContent::ContentDistribution(
|
|
|
|
+ distribution,
|
|
|
|
+ ) => match distribution {
|
|
|
|
+ lightningcss::properties::align::ContentDistribution::SpaceBetween => {
|
|
|
|
+ SpaceBetween
|
|
|
|
+ }
|
|
|
|
+ lightningcss::properties::align::ContentDistribution::SpaceAround => {
|
|
|
|
+ SpaceAround
|
|
|
|
+ }
|
|
|
|
+ lightningcss::properties::align::ContentDistribution::SpaceEvenly => {
|
|
|
|
+ SpaceEvenly
|
|
|
|
+ }
|
|
|
|
+ lightningcss::properties::align::ContentDistribution::Stretch => Stretch,
|
|
|
|
+ },
|
|
|
|
+ lightningcss::properties::align::AlignContent::ContentPosition(_, position) => {
|
|
|
|
+ match position {
|
|
|
|
+ lightningcss::properties::align::ContentPosition::Center => Center,
|
|
|
|
+ lightningcss::properties::align::ContentPosition::Start => todo!(),
|
|
|
|
+ lightningcss::properties::align::ContentPosition::End => todo!(),
|
|
|
|
+ lightningcss::properties::align::ContentPosition::FlexStart => {
|
|
|
|
+ FlexStart
|
|
|
|
+ }
|
|
|
|
+ lightningcss::properties::align::ContentPosition::FlexEnd => FlexEnd,
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
+ }
|
|
|
|
+ Property::JustifyContent(justify, _) => {
|
|
|
|
+ use JustifyContent::*;
|
|
|
|
+ style.justify_content = match justify {
|
|
|
|
+ lightningcss::properties::align::JustifyContent::Normal => todo!(),
|
|
|
|
+ lightningcss::properties::align::JustifyContent::ContentDistribution(
|
|
|
|
+ distribution,
|
|
|
|
+ ) => match distribution {
|
|
|
|
+ lightningcss::properties::align::ContentDistribution::SpaceBetween => {
|
|
|
|
+ SpaceBetween
|
|
|
|
+ }
|
|
|
|
+ lightningcss::properties::align::ContentDistribution::SpaceAround => {
|
|
|
|
+ SpaceAround
|
|
|
|
+ }
|
|
|
|
+ lightningcss::properties::align::ContentDistribution::SpaceEvenly => {
|
|
|
|
+ SpaceEvenly
|
|
|
|
+ }
|
|
|
|
+ lightningcss::properties::align::ContentDistribution::Stretch => todo!(),
|
|
|
|
+ },
|
|
|
|
+ lightningcss::properties::align::JustifyContent::ContentPosition(
|
|
|
|
+ _,
|
|
|
|
+ position,
|
|
|
|
+ ) => match position {
|
|
|
|
+ lightningcss::properties::align::ContentPosition::Center => Center,
|
|
|
|
+ lightningcss::properties::align::ContentPosition::Start => todo!(),
|
|
|
|
+ lightningcss::properties::align::ContentPosition::End => todo!(),
|
|
|
|
+ lightningcss::properties::align::ContentPosition::FlexStart => FlexStart,
|
|
|
|
+ lightningcss::properties::align::ContentPosition::FlexEnd => FlexEnd,
|
|
|
|
+ },
|
|
|
|
+ lightningcss::properties::align::JustifyContent::Left(_) => todo!(),
|
|
|
|
+ lightningcss::properties::align::JustifyContent::Right(_) => todo!(),
|
|
|
|
+ };
|
|
|
|
+ }
|
|
|
|
+ Property::AlignSelf(align, _) => {
|
|
|
|
+ use AlignSelf::*;
|
|
|
|
+ style.align_self = match align {
|
|
|
|
+ lightningcss::properties::align::AlignSelf::Auto => Auto,
|
|
|
|
+ lightningcss::properties::align::AlignSelf::Normal => todo!(),
|
|
|
|
+ lightningcss::properties::align::AlignSelf::Stretch => Stretch,
|
|
|
|
+ lightningcss::properties::align::AlignSelf::BaselinePosition(_) => Baseline,
|
|
|
|
+ lightningcss::properties::align::AlignSelf::SelfPosition(
|
|
|
|
+ _overflow,
|
|
|
|
+ position,
|
|
|
|
+ ) => match position {
|
|
|
|
+ lightningcss::properties::align::SelfPosition::Center => Center,
|
|
|
|
+ lightningcss::properties::align::SelfPosition::Start => todo!(),
|
|
|
|
+ lightningcss::properties::align::SelfPosition::End => todo!(),
|
|
|
|
+ lightningcss::properties::align::SelfPosition::SelfStart => todo!(),
|
|
|
|
+ lightningcss::properties::align::SelfPosition::SelfEnd => todo!(),
|
|
|
|
+ lightningcss::properties::align::SelfPosition::FlexStart => FlexStart,
|
|
|
|
+ lightningcss::properties::align::SelfPosition::FlexEnd => FlexEnd,
|
|
|
|
+ },
|
|
|
|
+ };
|
|
|
|
+ }
|
|
|
|
+ Property::AlignItems(align, _) => {
|
|
|
|
+ use AlignItems::*;
|
|
|
|
+ style.align_items = match align {
|
|
|
|
+ lightningcss::properties::align::AlignItems::Normal => todo!(),
|
|
|
|
+ lightningcss::properties::align::AlignItems::BaselinePosition(_) => Baseline,
|
|
|
|
+ lightningcss::properties::align::AlignItems::Stretch => Stretch,
|
|
|
|
+ lightningcss::properties::align::AlignItems::SelfPosition(
|
|
|
|
+ _overflow,
|
|
|
|
+ position,
|
|
|
|
+ ) => match position {
|
|
|
|
+ lightningcss::properties::align::SelfPosition::Center => Center,
|
|
|
|
+ lightningcss::properties::align::SelfPosition::Start => todo!(),
|
|
|
|
+ lightningcss::properties::align::SelfPosition::End => todo!(),
|
|
|
|
+ lightningcss::properties::align::SelfPosition::SelfStart => todo!(),
|
|
|
|
+ lightningcss::properties::align::SelfPosition::SelfEnd => todo!(),
|
|
|
|
+ lightningcss::properties::align::SelfPosition::FlexStart => FlexStart,
|
|
|
|
+ lightningcss::properties::align::SelfPosition::FlexEnd => FlexEnd,
|
|
|
|
+ },
|
|
|
|
+ };
|
|
|
|
+ }
|
|
|
|
+ Property::RowGap(row_gap) => {
|
|
|
|
+ style.gap.width = convert_gap_value(row_gap);
|
|
|
|
+ }
|
|
|
|
+ Property::ColumnGap(column_gap) => {
|
|
|
|
+ style.gap.height = convert_gap_value(column_gap);
|
|
|
|
+ }
|
|
|
|
+ Property::Gap(gap) => {
|
|
|
|
+ style.gap = Size {
|
|
|
|
+ width: convert_gap_value(gap.row),
|
|
|
|
+ height: convert_gap_value(gap.column),
|
|
|
|
+ };
|
|
|
|
+ }
|
|
|
|
+ Property::MarginTop(margin) => {
|
|
|
|
+ style.margin.top = convert_length_percentage_or_auto(margin);
|
|
|
|
+ }
|
|
|
|
+ Property::MarginBottom(margin) => {
|
|
|
|
+ style.margin.bottom = convert_length_percentage_or_auto(margin);
|
|
|
|
+ }
|
|
|
|
+ Property::MarginLeft(margin) => {
|
|
|
|
+ style.margin.left = convert_length_percentage_or_auto(margin);
|
|
|
|
+ }
|
|
|
|
+ Property::MarginRight(margin) => {
|
|
|
|
+ style.margin.right = convert_length_percentage_or_auto(margin);
|
|
|
|
+ }
|
|
|
|
+ Property::Margin(margin) => {
|
|
|
|
+ style.margin = Rect {
|
|
|
|
+ top: convert_length_percentage_or_auto(margin.top),
|
|
|
|
+ bottom: convert_length_percentage_or_auto(margin.bottom),
|
|
|
|
+ left: convert_length_percentage_or_auto(margin.left),
|
|
|
|
+ right: convert_length_percentage_or_auto(margin.right),
|
|
|
|
+ };
|
|
|
|
+ }
|
|
|
|
+ Property::PaddingTop(padding) => {
|
|
|
|
+ style.padding.top = convert_length_percentage_or_auto(padding);
|
|
|
|
+ }
|
|
|
|
+ Property::PaddingBottom(padding) => {
|
|
|
|
+ style.padding.bottom = convert_length_percentage_or_auto(padding);
|
|
}
|
|
}
|
|
|
|
+ Property::PaddingLeft(padding) => {
|
|
|
|
+ style.padding.left = convert_length_percentage_or_auto(padding);
|
|
|
|
+ }
|
|
|
|
+ Property::PaddingRight(padding) => {
|
|
|
|
+ style.padding.right = convert_length_percentage_or_auto(padding);
|
|
|
|
+ }
|
|
|
|
+ Property::Padding(padding) => {
|
|
|
|
+ style.padding = Rect {
|
|
|
|
+ top: convert_length_percentage_or_auto(padding.top),
|
|
|
|
+ bottom: convert_length_percentage_or_auto(padding.bottom),
|
|
|
|
+ left: convert_length_percentage_or_auto(padding.left),
|
|
|
|
+ right: convert_length_percentage_or_auto(padding.right),
|
|
|
|
+ };
|
|
|
|
+ }
|
|
|
|
+ Property::Width(width) => {
|
|
|
|
+ style.size.width = convert_size(width);
|
|
|
|
+ }
|
|
|
|
+ Property::Height(height) => {
|
|
|
|
+ style.size.height = convert_size(height);
|
|
|
|
+ }
|
|
|
|
+ _ => (),
|
|
}
|
|
}
|
|
- _ => (),
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-fn apply_animation(name: &str, _value: &str, _style: &mut Style) {
|
|
|
|
- match name {
|
|
|
|
- "animation" => {}
|
|
|
|
- "animation-delay" => {}
|
|
|
|
- "animation-direction =>{}" => {}
|
|
|
|
- "animation-duration" => {}
|
|
|
|
- "animation-fill-mode" => {}
|
|
|
|
- "animation-itera =>{}tion-count" => {}
|
|
|
|
- "animation-name" => {}
|
|
|
|
- "animation-play-state" => {}
|
|
|
|
- "animation-timing-function" => {}
|
|
|
|
- _ => {}
|
|
|
|
|
|
+fn convert_length_value(length_value: LengthValue) -> Dimension {
|
|
|
|
+ match length_value {
|
|
|
|
+ LengthValue::Px(value) => Dimension::Points(value),
|
|
|
|
+ _ => todo!(),
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-fn apply_column(name: &str, _value: &str, _style: &mut Style) {
|
|
|
|
- match name {
|
|
|
|
- "column-count" => {}
|
|
|
|
- "column-fill" => {}
|
|
|
|
- "column-gap" => {}
|
|
|
|
- "column-rule" => {}
|
|
|
|
- "column-rule-color" => {}
|
|
|
|
- "column-rule-style" => {}
|
|
|
|
- "column-rule-width" => {}
|
|
|
|
- "column-span" => {}
|
|
|
|
- "column-width" => {}
|
|
|
|
- _ => {}
|
|
|
|
|
|
+fn convert_dimention_percentage(
|
|
|
|
+ dimension_percentage: DimensionPercentage<LengthValue>,
|
|
|
|
+) -> Dimension {
|
|
|
|
+ match dimension_percentage {
|
|
|
|
+ DimensionPercentage::Dimension(value) => convert_length_value(value),
|
|
|
|
+ DimensionPercentage::Percentage(percentage) => Dimension::Percent(percentage.0),
|
|
|
|
+ _ => todo!(),
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-fn apply_flex(name: &str, value: &str, style: &mut Style) {
|
|
|
|
- // - [x] pub flex_direction: FlexDirection,
|
|
|
|
- // - [x] pub flex_wrap: FlexWrap,
|
|
|
|
- // - [x] pub flex_grow: f32,
|
|
|
|
- // - [x] pub flex_shrink: f32,
|
|
|
|
- // - [x] pub flex_basis: Dimension,
|
|
|
|
-
|
|
|
|
- match name {
|
|
|
|
- "flex" => {}
|
|
|
|
- "flex-direction" => {
|
|
|
|
- use FlexDirection::*;
|
|
|
|
- style.flex_direction = match value {
|
|
|
|
- "row" => Row,
|
|
|
|
- "row-reverse" => RowReverse,
|
|
|
|
- "column" => Column,
|
|
|
|
- "column-reverse" => ColumnReverse,
|
|
|
|
- _ => Row,
|
|
|
|
- };
|
|
|
|
- }
|
|
|
|
- "flex-basis" => {
|
|
|
|
- if let Some(v) = parse_value(value) {
|
|
|
|
- style.flex_basis = v;
|
|
|
|
- }
|
|
|
|
|
|
+fn convert_length_percentage_or_auto(
|
|
|
|
+ length_percentage_or_auto: LengthPercentageOrAuto,
|
|
|
|
+) -> Dimension {
|
|
|
|
+ match length_percentage_or_auto {
|
|
|
|
+ LengthPercentageOrAuto::Auto => Dimension::Auto,
|
|
|
|
+ LengthPercentageOrAuto::LengthPercentage(percentage) => {
|
|
|
|
+ convert_dimention_percentage(percentage)
|
|
}
|
|
}
|
|
- "flex-flow" => {}
|
|
|
|
- "flex-grow" => {
|
|
|
|
- if let Ok(val) = value.parse::<f32>() {
|
|
|
|
- style.flex_grow = val;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- "flex-shrink" => {
|
|
|
|
- if let Ok(px) = value.parse::<f32>() {
|
|
|
|
- style.flex_shrink = px;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- "flex-wrap" => {
|
|
|
|
- use FlexWrap::*;
|
|
|
|
- style.flex_wrap = match value {
|
|
|
|
- "nowrap" => NoWrap,
|
|
|
|
- "wrap" => Wrap,
|
|
|
|
- "wrap-reverse" => WrapReverse,
|
|
|
|
- _ => NoWrap,
|
|
|
|
- };
|
|
|
|
- }
|
|
|
|
- _ => {}
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-fn apply_padding(name: &str, value: &str, style: &mut Style) {
|
|
|
|
- if let Some(v) = parse_value(value) {
|
|
|
|
- match name {
|
|
|
|
- "padding" => {
|
|
|
|
- style.padding.top = v;
|
|
|
|
- style.padding.bottom = v;
|
|
|
|
- style.padding.left = v;
|
|
|
|
- style.padding.right = v;
|
|
|
|
- }
|
|
|
|
- "padding-bottom" => style.padding.bottom = v,
|
|
|
|
- "padding-left" => style.padding.left = v,
|
|
|
|
- "padding-right" => style.padding.right = v,
|
|
|
|
- "padding-top" => style.padding.top = v,
|
|
|
|
- _ => {}
|
|
|
|
- }
|
|
|
|
|
|
+fn convert_border_side_width(border_side_width: BorderSideWidth) -> Dimension {
|
|
|
|
+ match border_side_width {
|
|
|
|
+ BorderSideWidth::Length(Length::Value(value)) => convert_length_value(value),
|
|
|
|
+ BorderSideWidth::Thick => Dimension::Points(5.0),
|
|
|
|
+ BorderSideWidth::Medium => Dimension::Points(3.0),
|
|
|
|
+ BorderSideWidth::Thin => Dimension::Points(1.0),
|
|
|
|
+ _ => todo!(),
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-fn apply_transform(_name: &str, _value: &str, _style: &mut Style) {
|
|
|
|
- todo!()
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-fn apply_transition(_name: &str, _value: &str, _style: &mut Style) {
|
|
|
|
- todo!()
|
|
|
|
|
|
+fn convert_gap_value(gap_value: GapValue) -> Dimension {
|
|
|
|
+ match gap_value {
|
|
|
|
+ GapValue::LengthPercentage(dim) => convert_dimention_percentage(dim),
|
|
|
|
+ GapValue::Normal => Dimension::Auto,
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
-fn apply_align(name: &str, value: &str, style: &mut Style) {
|
|
|
|
- match name {
|
|
|
|
- "align-items" => {
|
|
|
|
- use AlignItems::*;
|
|
|
|
- style.align_items = match value {
|
|
|
|
- "flex-start" => FlexStart,
|
|
|
|
- "flex-end" => FlexEnd,
|
|
|
|
- "center" => Center,
|
|
|
|
- "baseline" => Baseline,
|
|
|
|
- "stretch" => Stretch,
|
|
|
|
- _ => FlexStart,
|
|
|
|
- };
|
|
|
|
|
|
+fn convert_size(size: lightningcss::properties::size::Size) -> Dimension {
|
|
|
|
+ match size {
|
|
|
|
+ lightningcss::properties::size::Size::Auto => Dimension::Auto,
|
|
|
|
+ lightningcss::properties::size::Size::LengthPercentage(length) => {
|
|
|
|
+ convert_dimention_percentage(length)
|
|
}
|
|
}
|
|
- "align-content" => {
|
|
|
|
- use AlignContent::*;
|
|
|
|
- style.align_content = match value {
|
|
|
|
- "flex-start" => FlexStart,
|
|
|
|
- "flex-end" => FlexEnd,
|
|
|
|
- "center" => Center,
|
|
|
|
- "space-between" => SpaceBetween,
|
|
|
|
- "space-around" => SpaceAround,
|
|
|
|
- _ => FlexStart,
|
|
|
|
- };
|
|
|
|
- }
|
|
|
|
- "align-self" => {
|
|
|
|
- use AlignSelf::*;
|
|
|
|
- style.align_self = match value {
|
|
|
|
- "auto" => Auto,
|
|
|
|
- "flex-start" => FlexStart,
|
|
|
|
- "flex-end" => FlexEnd,
|
|
|
|
- "center" => Center,
|
|
|
|
- "baseline" => Baseline,
|
|
|
|
- "stretch" => Stretch,
|
|
|
|
- _ => Auto,
|
|
|
|
- };
|
|
|
|
- }
|
|
|
|
- _ => {}
|
|
|
|
|
|
+ lightningcss::properties::size::Size::MinContent(_) => todo!(),
|
|
|
|
+ lightningcss::properties::size::Size::MaxContent(_) => todo!(),
|
|
|
|
+ lightningcss::properties::size::Size::FitContent(_) => todo!(),
|
|
|
|
+ lightningcss::properties::size::Size::FitContentFunction(_) => todo!(),
|
|
|
|
+ lightningcss::properties::size::Size::Stretch(_) => todo!(),
|
|
|
|
+ lightningcss::properties::size::Size::Contain => todo!(),
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-fn apply_margin(name: &str, value: &str, style: &mut Style) {
|
|
|
|
- if let Some(dim) = parse_value(value) {
|
|
|
|
- match name {
|
|
|
|
- "margin" => {
|
|
|
|
- style.margin.top = dim;
|
|
|
|
- style.margin.bottom = dim;
|
|
|
|
- style.margin.left = dim;
|
|
|
|
- style.margin.right = dim;
|
|
|
|
- }
|
|
|
|
- "margin-top" => style.margin.top = dim,
|
|
|
|
- "margin-bottom" => style.margin.bottom = dim,
|
|
|
|
- "margin-left" => style.margin.left = dim,
|
|
|
|
- "margin-right" => style.margin.right = dim,
|
|
|
|
- _ => {}
|
|
|
|
|
|
+/// parse relative or absolute value
|
|
|
|
+pub fn parse_value(value: &str) -> Option<Dimension> {
|
|
|
|
+ if value.ends_with("px") {
|
|
|
|
+ if let Ok(px) = value.trim_end_matches("px").parse::<f32>() {
|
|
|
|
+ Some(Dimension::Points(px))
|
|
|
|
+ } else {
|
|
|
|
+ None
|
|
}
|
|
}
|
|
|
|
+ } else if value.ends_with('%') {
|
|
|
|
+ if let Ok(pct) = value.trim_end_matches('%').parse::<f32>() {
|
|
|
|
+ Some(Dimension::Percent(pct / 100.0))
|
|
|
|
+ } else {
|
|
|
|
+ None
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ None
|
|
}
|
|
}
|
|
}
|
|
}
|