Skip to content
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
47c3dc6
feat: support parsing the grid-template-rows/columns CSS property
TtTRz Oct 11, 2025
7de41f4
feat: support parsing the grid-auto-flow CSS property
TtTRz Oct 11, 2025
5fb3d9b
feat: impl grid layout
TtTRz Oct 22, 2025
bd64d0a
feat: impl grid layout
TtTRz Oct 23, 2025
476c79b
feat: impl grid layout
TtTRz Oct 23, 2025
4f752e0
feat: impl grid layout
Oct 23, 2025
f87e120
feat: update grid layout
TtTRz Oct 27, 2025
c0f13d4
fix: update grid impl
TtTRz Oct 28, 2025
d134e21
fix: min-content for grid
TtTRz Nov 12, 2025
3808770
feat: impl min-content
TtTRz Nov 13, 2025
4cca438
Merge remote-tracking branch 'origin/master' into feat-grid
Jan 29, 2026
d1a6049
feat: update grid impl & add docs
TtTRz Jan 30, 2026
18665f3
docs: udpate grid doc
TtTRz Jan 30, 2026
7c7d8d9
clippy: fix
TtTRz Jan 30, 2026
61345c3
feat: impl dynamic grid
TtTRz Jan 30, 2026
dc23a59
feat: impl dynamic grid
TtTRz Jan 30, 2026
bc6b5ef
docs: udpate grid doc
TtTRz Feb 2, 2026
c8c7813
docs: udpate grid doc
TtTRz Feb 2, 2026
b79186d
feat: update grid impl
TtTRz Feb 2, 2026
5db0863
feat: update grid impl
TtTRz Feb 3, 2026
50bc301
feat: update grid impl
TtTRz Feb 3, 2026
8ad6109
feat: update grid track impl
TtTRz Feb 3, 2026
821bfaa
feat: update grid impl
TtTRz Feb 3, 2026
72eef8a
feat: update grid impl
TtTRz Feb 4, 2026
4c45a07
feat: update grid impl
TtTRz Feb 4, 2026
5d67394
feat: impl direction for grid
TtTRz Feb 4, 2026
fcda52d
docs: update grid doc
TtTRz Feb 4, 2026
b6d1913
feat: impl grid-auto-columns/row
TtTRz Feb 5, 2026
9bf7f08
feat: impl grid-auto-columns/row
TtTRz Feb 5, 2026
d0f6fd7
clippy: fix
TtTRz Feb 12, 2026
b6c65e3
fix: impl no_std
TtTRz Feb 12, 2026
b6bd6ac
Merge remote-tracking branch 'origin/master' into feat-grid
TtTRz Feb 13, 2026
fc8e0d1
feat: init grid matrix with capacity
TtTRz Feb 16, 2026
1aa88fc
Merge remote-tracking branch 'origin/master' into feat-grid
TtTRz Feb 16, 2026
7e78a10
feat: update expand flexible tracks impl
TtTRz Feb 16, 2026
eaeaba6
fix: update track height impl
TtTRz Feb 16, 2026
9103d1d
fix: update dense impl
TtTRz Feb 25, 2026
66c31b4
fix: shortcut of min-content
TtTRz Feb 25, 2026
1a944ec
docs: update grid doc
TtTRz Feb 25, 2026
a1ee1e5
docs: update grid doc
TtTRz Feb 26, 2026
198e683
docs: update grid doc
TtTRz Feb 26, 2026
480e14a
feat: impl bitMap for grid matrix
TtTRz Feb 26, 2026
deb3ea0
docs: update doc
TtTRz Feb 26, 2026
771bd19
fix: initial value of grid auto rows/columns
TtTRz Feb 28, 2026
2f44827
fix: rtl for grid
TtTRz Feb 28, 2026
adcd7ef
tests: add grid margin test cases
TtTRz Feb 28, 2026
e21fda7
chore: update comment
TtTRz Feb 28, 2026
3c1a764
fix: min-content impl
TtTRz Feb 28, 2026
40f8b54
feat(doc): Update CSS Grid spec refs and clarify sizing logic
TtTRz Feb 28, 2026
43b77f5
fix: remove unsafe impl
TtTRz Feb 28, 2026
3ad1c32
fix: update grid impl
TtTRz Feb 28, 2026
e153388
fix: update grid impl
TtTRz Feb 28, 2026
ab29189
fix: remove dead code
TtTRz Feb 28, 2026
ede8228
feat: update OccupiedBitmap impl
TtTRz Mar 2, 2026
2fb5bc8
feat: update OccupiedBitmap impl
TtTRz Mar 2, 2026
424b12d
feat: update OccupiedBitmap impl
TtTRz Mar 2, 2026
1f54aea
test: add test cases for OccupiedBitmap
TtTRz Mar 2, 2026
65e3768
fix: remove min_content_size from ComputeResult
TtTRz Mar 2, 2026
6d32147
fix: update min-content impl
TtTRz Mar 2, 2026
a781487
feat: update grid impl
TtTRz Mar 3, 2026
99b7754
feat: update grid impl
TtTRz Mar 3, 2026
ee61e16
docs: update grid doc
TtTRz Mar 3, 2026
3891b29
refactor: refactor grid track classification logic to reduce code dup…
TtTRz Mar 4, 2026
08c2b46
fix: track sizing function
TtTRz Mar 4, 2026
06a4875
docs: update docs
TtTRz Mar 4, 2026
6b1465d
fix: initial value of align-content
TtTRz Mar 4, 2026
3b21b02
docs: update doc
TtTRz Mar 4, 2026
6a63bc3
fix: resolve fr track sizes
TtTRz Mar 5, 2026
87961bc
Merge remote-tracking branch 'origin/master' into feat-grid
TtTRz Mar 5, 2026
d8ea23f
fix: guarantees stride at least 1
TtTRz Mar 10, 2026
17d715a
fix: bug
TtTRz Mar 10, 2026
a927b52
fix: remove TrackSizingResult
TtTRz Mar 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

103 changes: 103 additions & 0 deletions float-pigment-css/src/parser/property_value/grid.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
use cssparser::{ParseError, Parser, Token};

use crate::{
parser::{property_value::custom_ident_repr, CustomError, ParseState},
sheet::PropertyMeta,
typing::GridAutoFlow,
};

#[inline(never)]
pub(crate) fn line_names<'a, 't: 'a, 'i: 't>(
parser: &'a mut Parser<'i, 't>,
properties: &mut [PropertyMeta],
st: &mut ParseState,
) -> Result<Vec<String>, ParseError<'i, CustomError>> {
let next = parser.next()?;
if let Token::SquareBracketBlock = next {
let line_names = parser.parse_nested_block(|parser| {
let mut line_names = Vec::with_capacity(1);
while !parser.is_exhausted() {
let line_name = custom_ident_repr(parser, properties, st)?;
line_names.push(line_name);
}
Ok(line_names)
})?;
return Ok(line_names);
}
let next = next.clone();
Err(parser.new_unexpected_token_error(next))
}

#[inline(never)]
pub(crate) fn fr_repr<'a, 't: 'a, 'i: 't>(
parser: &'a mut Parser<'i, 't>,
_properties: &mut [PropertyMeta],
_st: &mut ParseState,
) -> Result<f32, ParseError<'i, CustomError>> {
let next = parser.next()?;
match next {
Token::Dimension { value, unit, .. } => match unit as &str {
"fr" => return Ok(*value),
_ => {}
},
_ => {}
}
let next = next.clone();
Err(parser.new_unexpected_token_error(next))
}

#[inline(never)]
pub(crate) fn grid_auto_flow_repr<'a, 't: 'a, 'i: 't>(
parser: &'a mut Parser<'i, 't>,
_properties: &mut [PropertyMeta],
_st: &mut ParseState,
) -> Result<GridAutoFlow, ParseError<'i, CustomError>> {
#[derive(PartialEq, Clone, Copy)]
enum FlowDirection {
Row,
Column,
}
let mut flow_direction = None;
let mut dense = false;
let check_flow_direction = move |target: FlowDirection| {
if flow_direction.is_none() {
return true;
}
flow_direction.unwrap() != target
Comment thread
TtTRz marked this conversation as resolved.
Outdated
};
while !parser.is_exhausted() {
let next = parser.next()?;
match next {
Token::Ident(ident) => {
let ident: &str = ident;
match ident {
"row" if check_flow_direction(FlowDirection::Row) => {
flow_direction.replace(FlowDirection::Row);
}
"column" if check_flow_direction(FlowDirection::Column) => {
flow_direction.replace(FlowDirection::Column);
}
"dense" if !dense => {
dense = true;
}
_ => {
let next = next.clone();
return Err(parser.new_unexpected_token_error(next));
}
}
}
_ => {
let next = next.clone();
return Err(parser.new_unexpected_token_error(next));
}
}
}
match (flow_direction, dense) {
(Some(FlowDirection::Row), true) => Ok(GridAutoFlow::RowDense),
(Some(FlowDirection::Column), true) => Ok(GridAutoFlow::ColumnDense),
(Some(FlowDirection::Row), false) => Ok(GridAutoFlow::Row),
(Some(FlowDirection::Column), false) => Ok(GridAutoFlow::Column),
(None, true) => Ok(GridAutoFlow::RowDense),
(None, _) => Err(parser.new_custom_error(CustomError::Unmatched)),
}
}
31 changes: 15 additions & 16 deletions float-pigment-css/src/parser/property_value/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ pub(crate) mod background;
pub(crate) mod filter;
pub(crate) mod font;
pub(crate) mod gradient;
pub(crate) mod grid;
pub(crate) use grid::*;

pub(crate) mod var;

#[allow(unused_macros)]
Expand Down Expand Up @@ -866,22 +869,18 @@ pub(crate) fn element_func_repr<'a, 't: 'a, 'i: 't>(
})
}

// pub(crate) fn custom_ident_repr<'a, 't: 'a, 'i: 't>(
// parser: &'a mut Parser<'i, 't>,
// _properties: &mut Vec<PropertyMeta>,
// _st: &mut ParseState,
// ) -> Result<String, ParseError<'i, CustomError>> {
// let next = parser.next()?.clone();
// match &next {
// Token::Ident(name) => {
// return Ok(name.to_string());
// }
// Token::QuotedString(name) => {
// return Ok(name.to_string());
// }
// _ => return Err(parser.new_unexpected_token_error::<CustomError>(next.clone())),
// }
// }
pub(crate) fn custom_ident_repr<'a, 't: 'a, 'i: 't>(
parser: &'a mut Parser<'i, 't>,
_properties: &mut [PropertyMeta],
_st: &mut ParseState,
) -> Result<String, ParseError<'i, CustomError>> {
let next = parser.next()?.clone();
match &next {
Token::Ident(name) => Ok(name.to_string()),
Token::QuotedString(name) => Ok(name.to_string()),
_ => Err(parser.new_unexpected_token_error::<CustomError>(next.clone())),
}
}

#[inline(never)]
pub(crate) fn image_func_repr<'a, 't: 'a, 'i: 't>(
Expand Down
68 changes: 67 additions & 1 deletion float-pigment-css/src/property.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use cssparser::{ParseError, Parser, SourcePosition};
use super::parser::{property_value::*, CustomError, ParseState};
use super::resolve_font_size::ResolveFontSize;
use super::sheet::borrow::Array;
pub use super::sheet::PropertyMeta;
pub use super::sheet::{str_store::StrRef, PropertyMeta};
use super::typing::*;
use float_pigment_css_macro::*;

Expand Down Expand Up @@ -166,6 +166,13 @@ property_list! (PropertyValueWithGlobal, {
0xa3 TextDecorationThickness: TextDecorationThicknessType as Initial default TextDecorationThickness::Auto;
0xa4 FontFeatureSettings: FontFeatureSettingsType as Inherit default FontFeatureSettings::Normal;

// grid
0xa5 GridTemplateRows: GridTemplateType as Initial default GridTemplate::None;
0xa6 GridTemplateColumns: GridTemplateType as Initial default GridTemplate::None;
0xa7 GridAutoFlow: GridAutoFlowType as Initial default GridAutoFlow::Row;
0xa8 JustifySelf: JustifySelfType as Initial default JustifySelf::Auto;


0xd0 ListStyleType: ListStyleTypeType as Inherit default ListStyleType::Disc;
0xd1 ListStyleImage: ListStyleImageType as Inherit default ListStyleImage::None;
0xd2 ListStylePosition: ListStylePositionType as Inherit default ListStylePosition::Outside;
Expand Down Expand Up @@ -198,6 +205,7 @@ property_value_format! (PropertyValueWithGlobal, {
| "grid" => DisplayType::Grid
| "flow-root" => DisplayType::FlowRoot
| "inline-flex" => DisplayType::InlineFlex
| "inline-grid" => DisplayType::InlineGrid
}};
position: {{ Position
= "static" => PositionType::Static
Expand Down Expand Up @@ -330,6 +338,21 @@ property_value_format! (PropertyValueWithGlobal, {
| "self-end" => JustifyItems::SelfEnd
| "left" => JustifyItems::Left
| "right" => JustifyItems::Right
| "normal" => JustifyItems::Normal
}};
justify_self: {{JustifySelf
= "auto" => JustifySelf::Auto
| "normal" => JustifySelf::Normal
| "stretch" => JustifySelf::Stretch
| "center" => JustifySelf::Center
| "flex-start" => JustifySelf::FlexStart
| "flex-end" => JustifySelf::FlexEnd
| "start" => JustifySelf::Start
| "end" => JustifySelf::End
| "self-start" => JustifySelf::SelfStart
| "self-end" => JustifySelf::SelfEnd
| "left" => JustifySelf::Left
| "right" => JustifySelf::Right
}};
order: {{ Order = <number> -> |x: Number| Number::I32(x.to_i32()); }};
<gap_repr: Gap>:
Expand Down Expand Up @@ -1657,6 +1680,49 @@ property_value_format! (PropertyValueWithGlobal, {
)
};
}};

<track_breadth: TrackSize>:
<length> -> |x: Length| TrackSize::Length(x);
| "min-content" -> |_| TrackSize::MinContent;
| "max-content" -> |_| TrackSize::MaxContent;
| <fr_repr> -> |x: f32| TrackSize::Fr(x);
;

<track_size: TrackSize>:
<track_breadth> -> |x: TrackSize| x;
;

<track_list: Vec<TrackListItem>>:
[ [ <line_names>? [ <track_size> ] ]+ <line_names>? ] -> |x: (Vec<(Option<Vec<String>>, TrackSize)>, Option<Vec<String>>)| {
let mut ret = vec![];
for item in x.0.into_iter() {
if let Some(line_names) = item.0 {
ret.push(TrackListItem::LineNames(line_names.iter().map(|x| x.into()).collect::<Vec<StrRef>>().into()));
}
ret.push(TrackListItem::TrackSize(item.1));
}
if let Some(line_names) = x.1 {
ret.push(TrackListItem::LineNames(line_names.iter().map(|x| x.into()).collect::<Vec<StrRef>>().into()));
}
ret
};
;
grid_template_rows: {{ GridTemplateRows
= "none" => GridTemplate::None
| <track_list> -> |x: Vec<TrackListItem>| {
GridTemplate::TrackList(x.into())
};
}};

grid_template_columns: {{ GridTemplateColumns
= "none" => GridTemplate::None
| <track_list> -> |x: Vec<TrackListItem>| {
GridTemplate::TrackList(x.into())
};
}};

grid_auto_flow: {{ GridAutoFlow = <grid_auto_flow_repr> }};

});

pub(crate) fn split_hv<T: Clone>(x: Vec<T>) -> (T, T) {
Expand Down
69 changes: 68 additions & 1 deletion float-pigment-css/src/typing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ pub enum Color {
Specified(u8, u8, u8, u8),
}

/// A length value or an expression that evaluates to a langth value.
/// A length value or an expression that evaluates to a length value.
#[allow(missing_docs)]
#[repr(C)]
#[property_value_type(PropertyValueWithGlobal for LengthType)]
Expand Down Expand Up @@ -445,6 +445,7 @@ pub enum Display {
Grid,
FlowRoot,
InlineFlex,
InlineGrid,
}

#[allow(missing_docs)]
Expand Down Expand Up @@ -654,6 +655,27 @@ pub enum JustifyItems {
SelfEnd,
Left,
Right,
Normal,
}

#[allow(missing_docs)]
#[repr(C)]
#[property_value_type(PropertyValueWithGlobal for JustifySelfType)]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, ResolveFontSize)]
#[cfg_attr(debug_assertions, derive(CompatibilityEnumCheck))]
pub enum JustifySelf {
Auto,
Normal,
Stretch,
Center,
Start,
End,
FlexStart,
FlexEnd,
SelfStart,
SelfEnd,
Left,
Right,
}

#[allow(missing_docs)]
Expand Down Expand Up @@ -1813,3 +1835,48 @@ pub enum Gap {
#[resolve_font_size(Length::resolve_em)]
Length(Length),
}

/// The `grid-template-rows` property defines the line names and track sizing functions of the grid rows.
#[allow(missing_docs)]
#[repr(C)]
#[property_value_type(PropertyValueWithGlobal for GridTemplateType)]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, ResolveFontSize)]
#[cfg_attr(debug_assertions, derive(CompatibilityEnumCheck))]
pub enum GridTemplate {
/// A keyword meaning that there is no explicit grid
None,
TrackList(Array<TrackListItem>),
}

#[allow(missing_docs)]
#[repr(C)]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, ResolveFontSize)]
#[cfg_attr(debug_assertions, derive(CompatibilityEnumCheck))]
pub enum TrackListItem {
LineNames(Array<StrRef>),
TrackSize(TrackSize),
}

#[allow(missing_docs)]
#[repr(C)]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, ResolveFontSize)]
#[cfg_attr(debug_assertions, derive(CompatibilityEnumCheck))]
pub enum TrackSize {
MinContent,
MaxContent,
Fr(f32),
#[resolve_font_size(Length::resolve_em)]
Length(Length),
}

#[allow(missing_docs)]
#[repr(C)]
#[property_value_type(PropertyValueWithGlobal for GridAutoFlowType)]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, ResolveFontSize)]
#[cfg_attr(debug_assertions, derive(CompatibilityEnumCheck))]
pub enum GridAutoFlow {
Row,
Column,
RowDense,
ColumnDense,
}
Loading
Loading