@@ -1024,3 +1024,143 @@ impl ToCss for GridLine {
10241024 }
10251025 }
10261026}
1027+
1028+ impl GridLine {
1029+ fn default_end_value ( & self ) -> GridLine {
1030+ if matches ! ( self , GridLine :: Ident ( _) ) {
1031+ self . clone ( )
1032+ } else {
1033+ GridLine :: Auto
1034+ }
1035+ }
1036+
1037+ fn can_omit_end ( & self , end : & GridLine ) -> bool {
1038+ if let GridLine :: Ident ( start_id) = & self {
1039+ matches ! ( end, GridLine :: Ident ( end_id) if end_id == start_id)
1040+ } else if matches ! ( end, GridLine :: Auto ) {
1041+ true
1042+ } else {
1043+ false
1044+ }
1045+ }
1046+ }
1047+
1048+ /// https://drafts.csswg.org/css-grid-2/#placement-shorthands
1049+ #[ derive( Debug , Clone , PartialEq ) ]
1050+ pub struct GridPlacement {
1051+ start : GridLine ,
1052+ end : GridLine
1053+ }
1054+
1055+ impl Parse for GridPlacement {
1056+ fn parse < ' i , ' t > ( input : & mut Parser < ' i , ' t > ) -> Result < Self , ParseError < ' i , ( ) > > {
1057+ let start = GridLine :: parse ( input) ?;
1058+ let end = if input. try_parse ( |input| input. expect_delim ( '/' ) ) . is_ok ( ) {
1059+ GridLine :: parse ( input) ?
1060+ } else {
1061+ start. default_end_value ( )
1062+ } ;
1063+
1064+ Ok ( GridPlacement {
1065+ start,
1066+ end
1067+ } )
1068+ }
1069+ }
1070+
1071+ impl ToCss for GridPlacement {
1072+ fn to_css < W > ( & self , dest : & mut Printer < W > ) -> std:: fmt:: Result where W : std:: fmt:: Write {
1073+ self . start . to_css ( dest) ?;
1074+
1075+ if !self . start . can_omit_end ( & self . end ) {
1076+ dest. delim ( '/' , true ) ?;
1077+ self . end . to_css ( dest) ?;
1078+ }
1079+ Ok ( ( ) )
1080+ }
1081+ }
1082+
1083+ /// https://drafts.csswg.org/css-grid-2/#propdef-grid-area
1084+ #[ derive( Debug , Clone , PartialEq ) ]
1085+ pub struct GridArea {
1086+ row_start : GridLine ,
1087+ column_start : GridLine ,
1088+ row_end : GridLine ,
1089+ column_end : GridLine
1090+ }
1091+
1092+ impl Parse for GridArea {
1093+ fn parse < ' i , ' t > ( input : & mut Parser < ' i , ' t > ) -> Result < Self , ParseError < ' i , ( ) > > {
1094+ let row_start = GridLine :: parse ( input) ?;
1095+ let column_start = if input. try_parse ( |input| input. expect_delim ( '/' ) ) . is_ok ( ) {
1096+ GridLine :: parse ( input) ?
1097+ } else {
1098+ let opposite = row_start. default_end_value ( ) ;
1099+ return Ok ( GridArea {
1100+ row_start,
1101+ column_start : opposite. clone ( ) ,
1102+ row_end : opposite. clone ( ) ,
1103+ column_end : opposite
1104+ } )
1105+ } ;
1106+
1107+ let row_end = if input. try_parse ( |input| input. expect_delim ( '/' ) ) . is_ok ( ) {
1108+ GridLine :: parse ( input) ?
1109+ } else {
1110+ let row_end = row_start. default_end_value ( ) ;
1111+ let column_end = column_start. default_end_value ( ) ;
1112+ return Ok ( GridArea {
1113+ row_start,
1114+ column_start,
1115+ row_end,
1116+ column_end
1117+ } )
1118+ } ;
1119+
1120+ let column_end = if input. try_parse ( |input| input. expect_delim ( '/' ) ) . is_ok ( ) {
1121+ GridLine :: parse ( input) ?
1122+ } else {
1123+ let column_end = column_start. default_end_value ( ) ;
1124+ return Ok ( GridArea {
1125+ row_start,
1126+ column_start,
1127+ row_end,
1128+ column_end
1129+ } )
1130+ } ;
1131+
1132+ Ok ( GridArea {
1133+ row_start,
1134+ column_start,
1135+ row_end,
1136+ column_end
1137+ } )
1138+ }
1139+ }
1140+
1141+ impl ToCss for GridArea {
1142+ fn to_css < W > ( & self , dest : & mut Printer < W > ) -> std:: fmt:: Result where W : std:: fmt:: Write {
1143+ self . row_start . to_css ( dest) ?;
1144+
1145+ let can_omit_column_end = self . column_start . can_omit_end ( & self . column_end ) ;
1146+ let can_omit_row_end = can_omit_column_end && self . row_start . can_omit_end ( & self . row_end ) ;
1147+ let can_omit_column_start = can_omit_row_end && self . row_start . can_omit_end ( & self . column_start ) ;
1148+
1149+ if !can_omit_column_start {
1150+ dest. delim ( '/' , true ) ?;
1151+ self . column_start . to_css ( dest) ?;
1152+ }
1153+
1154+ if !can_omit_row_end {
1155+ dest. delim ( '/' , true ) ?;
1156+ self . row_end . to_css ( dest) ?;
1157+ }
1158+
1159+ if !can_omit_column_end {
1160+ dest. delim ( '/' , true ) ?;
1161+ self . column_end . to_css ( dest) ?;
1162+ }
1163+
1164+ Ok ( ( ) )
1165+ }
1166+ }
0 commit comments